mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 15:12:12 +00:00
Improve loader function table handling
This commit is contained in:
parent
c4d7764851
commit
4683599a82
@ -83,6 +83,13 @@ Instances are automatically populated with useful utility:
|
|||||||
* **freeArray**(ptr: `number`): `void`<br />
|
* **freeArray**(ptr: `number`): `void`<br />
|
||||||
Frees a typed array in the module's memory. Must not be accessed anymore afterwards.
|
Frees a typed array in the module's memory. Must not be accessed anymore afterwards.
|
||||||
|
|
||||||
|
* **getFunction**(ptr: `number`): `function`<br />
|
||||||
|
Gets a function by its pointer.
|
||||||
|
|
||||||
|
* **newFunction**(fn: `function`): `number`<br />
|
||||||
|
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.
|
||||||
|
|
||||||
<sup>1</sup> This feature has not yet landed in any VM as of this writing.
|
<sup>1</sup> This feature has not yet landed in any VM as of this writing.
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
|
5
lib/loader/index.d.ts
vendored
5
lib/loader/index.d.ts
vendored
@ -66,6 +66,11 @@ interface ASUtil {
|
|||||||
freeArray(ptr: number): void;
|
freeArray(ptr: number): void;
|
||||||
/** Gets a function by its pointer. */
|
/** Gets a function by its pointer. */
|
||||||
getFunction<R = any>(ptr: number): (...args: any[]) => R;
|
getFunction<R = any>(ptr: number): (...args: any[]) => R;
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
newFunction(fn: (...args: any[]) => any): number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Instantiates an AssemblyScript module using the specified imports. */
|
/** Instantiates an AssemblyScript module using the specified imports. */
|
||||||
|
@ -155,8 +155,12 @@ function postInstantiate(baseModule, instance) {
|
|||||||
|
|
||||||
baseModule.freeArray = freeArray;
|
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) {
|
function newFunction(fn) {
|
||||||
|
if (typeof fn.original === "function") fn = fn.original;
|
||||||
var index = table.length;
|
var index = table.length;
|
||||||
table.grow(1);
|
table.grow(1);
|
||||||
table.set(index, fn);
|
table.set(index, fn);
|
||||||
@ -167,11 +171,7 @@ function postInstantiate(baseModule, instance) {
|
|||||||
|
|
||||||
/** Gets a function by its pointer. */
|
/** Gets a function by its pointer. */
|
||||||
function getFunction(ptr) {
|
function getFunction(ptr) {
|
||||||
var fn = table.get(ptr);
|
return wrapFunction(table.get(ptr), setargc);
|
||||||
return (...args) => {
|
|
||||||
setargc(args.length);
|
|
||||||
return fn(...args);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
baseModule.getFunction = getFunction;
|
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. */
|
/** Instantiates an AssemblyScript module using the specified imports. */
|
||||||
function instantiate(module, imports) {
|
function instantiate(module, imports) {
|
||||||
return postInstantiate(
|
return postInstantiate(
|
||||||
@ -266,7 +278,7 @@ function demangle(exports, baseModule) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
curr[name] = wrapFunction(elem);
|
curr[name] = wrapFunction(elem, setargc);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (/^(get|set):/.test(name)) {
|
if (/^(get|set):/.test(name)) {
|
||||||
@ -278,24 +290,13 @@ function demangle(exports, baseModule) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (typeof elem === "function") {
|
} else if (typeof elem === "function") {
|
||||||
curr[name] = wrapFunction(elem);
|
curr[name] = wrapFunction(elem, setargc);
|
||||||
} else {
|
} else {
|
||||||
curr[name] = elem;
|
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;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Binary file not shown.
@ -57,5 +57,5 @@ assert.strictEqual(fn(2, 3), 5);
|
|||||||
assert.strictEqual(fn(2), 4);
|
assert.strictEqual(fn(2), 4);
|
||||||
|
|
||||||
// should be able to create a new function and call it from WASM
|
// should be able to create a new function and call it from WASM
|
||||||
ptr = module.newFunction(module.varadd.constructor); // must be an actual exported wasm function
|
ptr = module.newFunction(module.varadd);
|
||||||
assert.strictEqual(module.calladd(ptr, 2, 3), 5);
|
assert.strictEqual(module.calladd(ptr, 2, 3), 5);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user