extract the list of languages

This commit is contained in:
Krasimir Angelov
2022-09-12 10:55:26 +02:00
parent 6f6f742d01
commit 7492cd52d1

View File

@@ -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) {