mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-09 04:59:31 -06:00
extract the list of languages
This commit is contained in:
@@ -4,13 +4,12 @@
|
||||
|
||||
async function mkAPI() {
|
||||
|
||||
var asm = null;
|
||||
const sizeof_GuMapItor = 4;
|
||||
const offsetof_GuMapItor_fn = 0;
|
||||
|
||||
function createExportWrapper(name) {
|
||||
return function() {
|
||||
return asm[name].apply(null, arguments);
|
||||
};
|
||||
}
|
||||
var asm = null;
|
||||
var wasmTable = null;
|
||||
var freeTableIndexes = [];
|
||||
|
||||
function setErrNo(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 info = {
|
||||
@@ -148,6 +258,7 @@ async function mkAPI() {
|
||||
const result = await WebAssembly.instantiateStreaming(response, info);
|
||||
|
||||
asm = result["instance"].exports;
|
||||
wasmTable = asm['__indirect_function_table'];
|
||||
const buf = asm['memory'].buffer;
|
||||
const HEAP8 = new Int8Array(buf);
|
||||
const HEAP16 = new Int16Array(buf);
|
||||
@@ -292,16 +403,22 @@ async function mkAPI() {
|
||||
asm.gu_pool_free(pool);
|
||||
});
|
||||
|
||||
function PGF(pgf,pool) {
|
||||
this.pgf = pgf;
|
||||
this.pool = pool;
|
||||
function PGF(pgfPtr,pool) {
|
||||
this.pgfPtr = pgfPtr;
|
||||
this.pool = pool;
|
||||
this.languages = {};
|
||||
registry.register(this,pool);
|
||||
}
|
||||
PGF.prototype.abstractName = function() {
|
||||
const namePtr = asm.pgf_abstract_name(this.pgf);
|
||||
const namePtr = asm.pgf_abstract_name(this.pgfPtr);
|
||||
return UTF8ToString(namePtr);
|
||||
}
|
||||
|
||||
function Concr(pgf,name) {
|
||||
this.pgf = pgf;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
async function readPGF(pgfURL) {
|
||||
const response = await fetch(pgfURL);
|
||||
urlData[pgfURL] = new Int8Array(await response.arrayBuffer());
|
||||
@@ -311,14 +428,29 @@ async function mkAPI() {
|
||||
const tmp_pool = asm.gu_new_pool();
|
||||
const err = asm.gu_new_exn(tmp_pool);
|
||||
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)) {
|
||||
asm.gu_pool_free(tmp_pool);
|
||||
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);
|
||||
return new PGF(pgf,pool);
|
||||
return pgf;
|
||||
}
|
||||
|
||||
function Expr(expr,pool) {
|
||||
|
||||
Reference in New Issue
Block a user