mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-05-24 10:22:50 -06:00
extract the list of languages
This commit is contained in:
@@ -4,13 +4,12 @@
|
|||||||
|
|
||||||
async function mkAPI() {
|
async function mkAPI() {
|
||||||
|
|
||||||
var asm = null;
|
const sizeof_GuMapItor = 4;
|
||||||
|
const offsetof_GuMapItor_fn = 0;
|
||||||
|
|
||||||
function createExportWrapper(name) {
|
var asm = null;
|
||||||
return function() {
|
var wasmTable = null;
|
||||||
return asm[name].apply(null, arguments);
|
var freeTableIndexes = [];
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function setErrNo(value) {
|
function setErrNo(value) {
|
||||||
HEAP32[asm.__errno_location() >> 2] = value;
|
HEAP32[asm.__errno_location() >> 2] = value;
|
||||||
@@ -133,6 +132,117 @@ async function mkAPI() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Wraps a JS function as a wasm function with a given signature.
|
||||||
|
function convertJsFunctionToWasm(func, sig) {
|
||||||
|
|
||||||
|
// If the type reflection proposal is available, use the new
|
||||||
|
// "WebAssembly.Function" constructor.
|
||||||
|
// Otherwise, construct a minimal wasm module importing the JS function and
|
||||||
|
// re-exporting it.
|
||||||
|
if (typeof WebAssembly.Function == "function") {
|
||||||
|
var typeNames = {
|
||||||
|
'i': 'i32',
|
||||||
|
'j': 'i64',
|
||||||
|
'f': 'f32',
|
||||||
|
'd': 'f64'
|
||||||
|
};
|
||||||
|
var type = {
|
||||||
|
parameters: [],
|
||||||
|
results: sig[0] == 'v' ? [] : [typeNames[sig[0]]]
|
||||||
|
};
|
||||||
|
for (var i = 1; i < sig.length; ++i) {
|
||||||
|
type.parameters.push(typeNames[sig[i]]);
|
||||||
|
}
|
||||||
|
return new WebAssembly.Function(type, func);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The module is static, with the exception of the type section, which is
|
||||||
|
// generated based on the signature passed in.
|
||||||
|
var typeSection = [
|
||||||
|
0x01, // id: section,
|
||||||
|
0x00, // length: 0 (placeholder)
|
||||||
|
0x01, // count: 1
|
||||||
|
0x60, // form: func
|
||||||
|
];
|
||||||
|
var sigRet = sig.slice(0, 1);
|
||||||
|
var sigParam = sig.slice(1);
|
||||||
|
var typeCodes = {
|
||||||
|
'i': 0x7f, // i32
|
||||||
|
'j': 0x7e, // i64
|
||||||
|
'f': 0x7d, // f32
|
||||||
|
'd': 0x7c, // f64
|
||||||
|
};
|
||||||
|
|
||||||
|
// Parameters, length + signatures
|
||||||
|
typeSection.push(sigParam.length);
|
||||||
|
for (var i = 0; i < sigParam.length; ++i) {
|
||||||
|
typeSection.push(typeCodes[sigParam[i]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return values, length + signatures
|
||||||
|
// With no multi-return in MVP, either 0 (void) or 1 (anything else)
|
||||||
|
if (sigRet == 'v') {
|
||||||
|
typeSection.push(0x00);
|
||||||
|
} else {
|
||||||
|
typeSection = typeSection.concat([0x01, typeCodes[sigRet]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the overall length of the type section back into the section header
|
||||||
|
// (excepting the 2 bytes for the section id and length)
|
||||||
|
typeSection[1] = typeSection.length - 2;
|
||||||
|
|
||||||
|
// Rest of the module is static
|
||||||
|
var bytes = new Uint8Array([
|
||||||
|
0x00, 0x61, 0x73, 0x6d, // magic ("\0asm")
|
||||||
|
0x01, 0x00, 0x00, 0x00, // version: 1
|
||||||
|
].concat(typeSection, [
|
||||||
|
0x02, 0x07, // import section
|
||||||
|
// (import "e" "f" (func 0 (type 0)))
|
||||||
|
0x01, 0x01, 0x65, 0x01, 0x66, 0x00, 0x00,
|
||||||
|
0x07, 0x05, // export section
|
||||||
|
// (export "f" (func 0 (type 0)))
|
||||||
|
0x01, 0x01, 0x66, 0x00, 0x00,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// We can compile this wasm module synchronously because it is very small.
|
||||||
|
// This accepts an import (at "e.f"), that it reroutes to an export (at "f")
|
||||||
|
var module = new WebAssembly.Module(bytes);
|
||||||
|
var instance = new WebAssembly.Instance(module, {
|
||||||
|
'e': {'f': func}
|
||||||
|
});
|
||||||
|
var wrappedFunc = instance.exports['f'];
|
||||||
|
return wrappedFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addFunction(func, sig) {
|
||||||
|
func = convertJsFunctionToWasm(func, sig);
|
||||||
|
|
||||||
|
let index;
|
||||||
|
|
||||||
|
// Reuse a free index if there is one, otherwise grow.
|
||||||
|
if (freeTableIndexes.length) {
|
||||||
|
index = freeTableIndexes.pop();
|
||||||
|
} else {
|
||||||
|
// Grow the table
|
||||||
|
try {
|
||||||
|
wasmTable.grow(1);
|
||||||
|
} catch (err) {
|
||||||
|
if (!(err instanceof RangeError)) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
throw 'Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.';
|
||||||
|
}
|
||||||
|
index = wasmTable.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wasmTable.set(index, func);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeFunction(index) {
|
||||||
|
freeTableIndexes.push(index);
|
||||||
|
}
|
||||||
|
|
||||||
const response = await fetch("pgf.wasm", { credentials: 'same-origin' });
|
const response = await fetch("pgf.wasm", { credentials: 'same-origin' });
|
||||||
|
|
||||||
const info = {
|
const info = {
|
||||||
@@ -148,6 +258,7 @@ async function mkAPI() {
|
|||||||
const result = await WebAssembly.instantiateStreaming(response, info);
|
const result = await WebAssembly.instantiateStreaming(response, info);
|
||||||
|
|
||||||
asm = result["instance"].exports;
|
asm = result["instance"].exports;
|
||||||
|
wasmTable = asm['__indirect_function_table'];
|
||||||
const buf = asm['memory'].buffer;
|
const buf = asm['memory'].buffer;
|
||||||
const HEAP8 = new Int8Array(buf);
|
const HEAP8 = new Int8Array(buf);
|
||||||
const HEAP16 = new Int16Array(buf);
|
const HEAP16 = new Int16Array(buf);
|
||||||
@@ -292,16 +403,22 @@ async function mkAPI() {
|
|||||||
asm.gu_pool_free(pool);
|
asm.gu_pool_free(pool);
|
||||||
});
|
});
|
||||||
|
|
||||||
function PGF(pgf,pool) {
|
function PGF(pgfPtr,pool) {
|
||||||
this.pgf = pgf;
|
this.pgfPtr = pgfPtr;
|
||||||
this.pool = pool;
|
this.pool = pool;
|
||||||
|
this.languages = {};
|
||||||
registry.register(this,pool);
|
registry.register(this,pool);
|
||||||
}
|
}
|
||||||
PGF.prototype.abstractName = function() {
|
PGF.prototype.abstractName = function() {
|
||||||
const namePtr = asm.pgf_abstract_name(this.pgf);
|
const namePtr = asm.pgf_abstract_name(this.pgfPtr);
|
||||||
return UTF8ToString(namePtr);
|
return UTF8ToString(namePtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Concr(pgf,name) {
|
||||||
|
this.pgf = pgf;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
async function readPGF(pgfURL) {
|
async function readPGF(pgfURL) {
|
||||||
const response = await fetch(pgfURL);
|
const response = await fetch(pgfURL);
|
||||||
urlData[pgfURL] = new Int8Array(await response.arrayBuffer());
|
urlData[pgfURL] = new Int8Array(await response.arrayBuffer());
|
||||||
@@ -311,14 +428,29 @@ async function mkAPI() {
|
|||||||
const tmp_pool = asm.gu_new_pool();
|
const tmp_pool = asm.gu_new_pool();
|
||||||
const err = asm.gu_new_exn(tmp_pool);
|
const err = asm.gu_new_exn(tmp_pool);
|
||||||
const strPtr = allocateUTF8(tmp_pool,pgfURL);
|
const strPtr = allocateUTF8(tmp_pool,pgfURL);
|
||||||
const pgf = asm.pgf_read(strPtr,pool,err);
|
const pgfPtr = asm.pgf_read(strPtr,pool,err);
|
||||||
if (checkError(err)) {
|
if (checkError(err)) {
|
||||||
asm.gu_pool_free(tmp_pool);
|
asm.gu_pool_free(tmp_pool);
|
||||||
throw new Error('Cannot read PGF');
|
throw new Error('Cannot read PGF');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pgf = new PGF(pgfPtr,pool);
|
||||||
|
|
||||||
|
const itor = asm.gu_malloc(tmp_pool,sizeof_GuMapItor);
|
||||||
|
const fn =
|
||||||
|
addFunction(
|
||||||
|
(itor,namePtr,ptr,err) => {
|
||||||
|
const name = UTF8ToString(namePtr);
|
||||||
|
pgf.languages[name] = new Concr(pgf,name);
|
||||||
|
},
|
||||||
|
"viiii"
|
||||||
|
);
|
||||||
|
HEAP32[(itor+offsetof_GuMapItor_fn) >> 2] = fn;
|
||||||
|
asm.pgf_iter_languages(pgfPtr,itor,err);
|
||||||
|
removeFunction(fn);
|
||||||
|
|
||||||
asm.gu_pool_free(tmp_pool);
|
asm.gu_pool_free(tmp_pool);
|
||||||
return new PGF(pgf,pool);
|
return pgf;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Expr(expr,pool) {
|
function Expr(expr,pool) {
|
||||||
|
|||||||
Reference in New Issue
Block a user