Improve loader function table handling

This commit is contained in:
dcodeIO
2018-10-20 15:40:23 +02:00
parent c4d7764851
commit 4683599a82
5 changed files with 33 additions and 20 deletions

View File

@ -155,8 +155,12 @@ function postInstantiate(baseModule, instance) {
baseModule.freeArray = freeArray;
/** Creates a new function in the module's table and returns its pointer. */
/**
* Creates a new function in the module's table and returns its pointer. Note that only actual
* WebAssembly functions, i.e. as exported by the module, are supported.
*/
function newFunction(fn) {
if (typeof fn.original === "function") fn = fn.original;
var index = table.length;
table.grow(1);
table.set(index, fn);
@ -167,11 +171,7 @@ function postInstantiate(baseModule, instance) {
/** Gets a function by its pointer. */
function getFunction(ptr) {
var fn = table.get(ptr);
return (...args) => {
setargc(args.length);
return fn(...args);
};
return wrapFunction(table.get(ptr), setargc);
}
baseModule.getFunction = getFunction;
@ -191,6 +191,18 @@ function postInstantiate(baseModule, instance) {
}));
}
/** Wraps a WebAssembly function while also taking care of variable arguments. */
function wrapFunction(fn, setargc) {
var wrap = (...args) => {
setargc(args.length);
return fn(...args);
}
// adding a function to the table with `newFunction` is limited to actual WebAssembly functions,
// hence we can't use the wrapper and instead need to provide a reference to the original
wrap.original = fn;
return wrap;
}
/** Instantiates an AssemblyScript module using the specified imports. */
function instantiate(module, imports) {
return postInstantiate(
@ -266,7 +278,7 @@ function demangle(exports, baseModule) {
});
}
} else {
curr[name] = wrapFunction(elem);
curr[name] = wrapFunction(elem, setargc);
}
} else {
if (/^(get|set):/.test(name)) {
@ -278,24 +290,13 @@ function demangle(exports, baseModule) {
});
}
} else if (typeof elem === "function") {
curr[name] = wrapFunction(elem);
curr[name] = wrapFunction(elem, setargc);
} else {
curr[name] = elem;
}
}
}
function wrapFunction(fn) {
var ret = function(...args) {
setargc(args.length);
return fn(...args);
};
// adding a function to the table with `newFunction` is limited to actual exported WebAssembly
// functions, hence we can't use the wrapper for that and instead need to pass a workaround:
ret.constructor = fn;
return ret;
}
return module;
}