diff --git a/lib/loader/index.d.ts b/lib/loader/index.d.ts
index e494b13a28..5e2f883c2e 100644
--- a/lib/loader/index.d.ts
+++ b/lib/loader/index.d.ts
@@ -1,5 +1,10 @@
///
+interface ResultObject {
+ module: WebAssembly.Module,
+ instance: WebAssembly.Instance
+};
+
/** WebAssembly imports with two levels of nesting. */
interface ImportsObject extends Record {
env?: {
@@ -92,13 +97,22 @@ interface ASUtil {
}
/** Asynchronously instantiates an AssemblyScript module from anything that can be instantiated. */
-export declare function instantiate(source: WebAssembly.Module | BufferSource | Response | PromiseLike, imports?: ImportsObject): Promise;
+export declare function instantiate(
+ source: WebAssembly.Module | BufferSource | Response | PromiseLike,
+ imports?: ImportsObject
+): Promise;
/** Synchronously instantiates an AssemblyScript module from a WebAssembly.Module or binary buffer. */
-export declare function instantiateSync(source: WebAssembly.Module | BufferSource, imports?: ImportsObject): ASUtil & T;
+export declare function instantiateSync(
+ source: WebAssembly.Module | BufferSource,
+ imports?: ImportsObject
+): ResultObject & { exports: ASUtil & T };
/** Asynchronously instantiates an AssemblyScript module from a response, i.e. as obtained by `fetch`. */
-export declare function instantiateStreaming(source: Response | PromiseLike, imports?: ImportsObject): Promise;
+export declare function instantiateStreaming(
+ source: Response | PromiseLike,
+ imports?: ImportsObject
+): Promise;
/** Demangles an AssemblyScript module's exports to a friendly object structure. */
-export declare function demangle(exports: {}, baseModule?: {}): T;
+export declare function demangle(exports: {}, extendedExports?: {}): T;
diff --git a/lib/loader/index.js b/lib/loader/index.js
index 96312c2a0b..2f9e38e46f 100644
--- a/lib/loader/index.js
+++ b/lib/loader/index.js
@@ -43,8 +43,8 @@ const CHUNKSIZE = 1024;
function getStringImpl(buffer, ptr) {
const U32 = new Uint32Array(buffer);
const U16 = new Uint16Array(buffer);
- var length = U32[(ptr + SIZE_OFFSET) >>> 2] >>> 1;
- var offset = ptr >>> 1;
+ let length = U32[(ptr + SIZE_OFFSET) >>> 2] >>> 1;
+ let offset = ptr >>> 1;
if (length <= CHUNKSIZE) return String.fromCharCode.apply(String, U16.subarray(offset, offset + length));
const parts = [];
do {
@@ -58,7 +58,7 @@ function getStringImpl(buffer, ptr) {
/** Prepares the base module prior to instantiation. */
function preInstantiate(imports) {
- const baseModule = {};
+ const extendedExports = {};
function getString(memory, ptr) {
if (!memory) return "";
@@ -67,13 +67,13 @@ function preInstantiate(imports) {
// add common imports used by stdlib for convenience
const env = (imports.env = imports.env || {});
- env.abort = env.abort || function abort(mesg, file, line, colm) {
- const memory = baseModule.memory || env.memory; // prefer exported, otherwise try imported
- throw Error("abort: " + getString(memory, mesg) + " in " + getString(memory, file) + "(" + line + ":" + colm + ")");
+ env.abort = env.abort || function abort(msg, file, line, colm) {
+ const memory = extendedExports.memory || env.memory; // prefer exported, otherwise try imported
+ throw Error("abort: " + getString(memory, msg) + " at " + getString(memory, file) + ":" + line + ":" + colm);
};
- env.trace = env.trace || function trace(mesg, n) {
- const memory = baseModule.memory || env.memory;
- console.log("trace: " + getString(memory, mesg) + (n ? " " : "") + Array.prototype.slice.call(arguments, 2, 2 + n).join(", "));
+ env.trace = env.trace || function trace(msg, n) {
+ const memory = extendedExports.memory || env.memory;
+ console.log("trace: " + getString(memory, msg) + (n ? " " : "") + Array.prototype.slice.call(arguments, 2, 2 + n).join(", "));
};
env.seed = env.seed || function seed() {
return Date.now();
@@ -81,17 +81,17 @@ function preInstantiate(imports) {
imports.Math = imports.Math || Math;
imports.Date = imports.Date || Date;
- return baseModule;
+ return extendedExports;
}
/** Prepares the final module once instantiation is complete. */
-function postInstantiate(baseModule, instance) {
- const rawExports = instance.exports;
- const memory = rawExports.memory;
- const table = rawExports.table;
- const alloc = rawExports["__alloc"];
- const retain = rawExports["__retain"];
- const rttiBase = rawExports["__rtti_base"] || ~0; // oob if not present
+function postInstantiate(extendedExports, instance) {
+ const exports = instance.exports;
+ const memory = exports.memory;
+ const table = exports.table;
+ const alloc = exports["__alloc"];
+ const retain = exports["__retain"];
+ const rttiBase = exports["__rtti_base"] || ~0; // oob if not present
/** Gets the runtime type info for the given id. */
function getInfo(id) {
@@ -128,7 +128,7 @@ function postInstantiate(baseModule, instance) {
return ptr;
}
- baseModule.__allocString = __allocString;
+ extendedExports.__allocString = __allocString;
/** Reads a string from the module's memory by its pointer. */
function __getString(ptr) {
@@ -138,7 +138,7 @@ function postInstantiate(baseModule, instance) {
return getStringImpl(buffer, ptr);
}
- baseModule.__getString = __getString;
+ extendedExports.__getString = __getString;
/** Gets the view matching the specified alignment, signedness and floatness. */
function getView(alignLog2, signed, float) {
@@ -181,7 +181,7 @@ function postInstantiate(baseModule, instance) {
return arr;
}
- baseModule.__allocArray = __allocArray;
+ extendedExports.__allocArray = __allocArray;
/** Gets a live view on an array's values in the module's memory. Infers the array type from RTTI. */
function __getArrayView(arr) {
@@ -190,7 +190,7 @@ function postInstantiate(baseModule, instance) {
const info = getInfo(id);
if (!(info & ARRAYBUFFERVIEW)) throw Error("not an array: " + id);
const align = getValueAlign(info);
- var buf = U32[arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2];
+ let buf = U32[arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2];
const length = info & ARRAY
? U32[arr + ARRAY_LENGTH_OFFSET >>> 2]
: U32[buf + SIZE_OFFSET >>> 2] >>> align;
@@ -198,7 +198,7 @@ function postInstantiate(baseModule, instance) {
.subarray(buf >>>= align, buf + length);
}
- baseModule.__getArrayView = __getArrayView;
+ extendedExports.__getArrayView = __getArrayView;
/** Copies an array's values from the module's memory. Infers the array type from RTTI. */
function __getArray(arr) {
@@ -209,7 +209,7 @@ function postInstantiate(baseModule, instance) {
return out;
}
- baseModule.__getArray = __getArray;
+ extendedExports.__getArray = __getArray;
/** Copies an ArrayBuffer's value from the module's memory. */
function __getArrayBuffer(ptr) {
@@ -218,7 +218,7 @@ function postInstantiate(baseModule, instance) {
return buffer.slice(ptr, ptr + length);
}
- baseModule.__getArrayBuffer = __getArrayBuffer;
+ extendedExports.__getArrayBuffer = __getArrayBuffer;
/** Copies a typed array's values from the module's memory. */
function getTypedArray(Type, alignLog2, ptr) {
@@ -233,35 +233,35 @@ function postInstantiate(baseModule, instance) {
return new Type(buffer, bufPtr, U32[bufPtr + SIZE_OFFSET >>> 2] >>> alignLog2);
}
- baseModule.__getInt8Array = getTypedArray.bind(null, Int8Array, 0);
- baseModule.__getInt8ArrayView = getTypedArrayView.bind(null, Int8Array, 0);
- baseModule.__getUint8Array = getTypedArray.bind(null, Uint8Array, 0);
- baseModule.__getUint8ArrayView = getTypedArrayView.bind(null, Uint8Array, 0);
- baseModule.__getUint8ClampedArray = getTypedArray.bind(null, Uint8ClampedArray, 0);
- baseModule.__getUint8ClampedArrayView = getTypedArrayView.bind(null, Uint8ClampedArray, 0);
- baseModule.__getInt16Array = getTypedArray.bind(null, Int16Array, 1);
- baseModule.__getInt16ArrayView = getTypedArrayView.bind(null, Int16Array, 1);
- baseModule.__getUint16Array = getTypedArray.bind(null, Uint16Array, 1);
- baseModule.__getUint16ArrayView = getTypedArrayView.bind(null, Uint16Array, 1);
- baseModule.__getInt32Array = getTypedArray.bind(null, Int32Array, 2);
- baseModule.__getInt32ArrayView = getTypedArrayView.bind(null, Int32Array, 2);
- baseModule.__getUint32Array = getTypedArray.bind(null, Uint32Array, 2);
- baseModule.__getUint32ArrayView = getTypedArrayView.bind(null, Uint32Array, 2);
+ extendedExports.__getInt8Array = getTypedArray.bind(null, Int8Array, 0);
+ extendedExports.__getInt8ArrayView = getTypedArrayView.bind(null, Int8Array, 0);
+ extendedExports.__getUint8Array = getTypedArray.bind(null, Uint8Array, 0);
+ extendedExports.__getUint8ArrayView = getTypedArrayView.bind(null, Uint8Array, 0);
+ extendedExports.__getUint8ClampedArray = getTypedArray.bind(null, Uint8ClampedArray, 0);
+ extendedExports.__getUint8ClampedArrayView = getTypedArrayView.bind(null, Uint8ClampedArray, 0);
+ extendedExports.__getInt16Array = getTypedArray.bind(null, Int16Array, 1);
+ extendedExports.__getInt16ArrayView = getTypedArrayView.bind(null, Int16Array, 1);
+ extendedExports.__getUint16Array = getTypedArray.bind(null, Uint16Array, 1);
+ extendedExports.__getUint16ArrayView = getTypedArrayView.bind(null, Uint16Array, 1);
+ extendedExports.__getInt32Array = getTypedArray.bind(null, Int32Array, 2);
+ extendedExports.__getInt32ArrayView = getTypedArrayView.bind(null, Int32Array, 2);
+ extendedExports.__getUint32Array = getTypedArray.bind(null, Uint32Array, 2);
+ extendedExports.__getUint32ArrayView = getTypedArrayView.bind(null, Uint32Array, 2);
if (BIGINT) {
- baseModule.__getInt64Array = getTypedArray.bind(null, BigInt64Array, 3);
- baseModule.__getInt64ArrayView = getTypedArrayView.bind(null, BigInt64Array, 3);
- baseModule.__getUint64Array = getTypedArray.bind(null, BigUint64Array, 3);
- baseModule.__getUint64ArrayView = getTypedArrayView.bind(null, BigUint64Array, 3);
+ extendedExports.__getInt64Array = getTypedArray.bind(null, BigInt64Array, 3);
+ extendedExports.__getInt64ArrayView = getTypedArrayView.bind(null, BigInt64Array, 3);
+ extendedExports.__getUint64Array = getTypedArray.bind(null, BigUint64Array, 3);
+ extendedExports.__getUint64ArrayView = getTypedArrayView.bind(null, BigUint64Array, 3);
}
- baseModule.__getFloat32Array = getTypedArray.bind(null, Float32Array, 2);
- baseModule.__getFloat32ArrayView = getTypedArrayView.bind(null, Float32Array, 2);
- baseModule.__getFloat64Array = getTypedArray.bind(null, Float64Array, 3);
- baseModule.__getFloat64ArrayView = getTypedArrayView.bind(null, Float64Array, 3);
+ extendedExports.__getFloat32Array = getTypedArray.bind(null, Float32Array, 2);
+ extendedExports.__getFloat32ArrayView = getTypedArrayView.bind(null, Float32Array, 2);
+ extendedExports.__getFloat64Array = getTypedArray.bind(null, Float64Array, 3);
+ extendedExports.__getFloat64ArrayView = getTypedArrayView.bind(null, Float64Array, 3);
/** Tests whether an object is an instance of the class represented by the specified base id. */
function __instanceof(ptr, baseId) {
const U32 = new Uint32Array(memory.buffer);
- var id = U32[(ptr + ID_OFFSET) >>> 2];
+ let id = U32[(ptr + ID_OFFSET) >>> 2];
if (id <= U32[rttiBase >>> 2]) {
do if (id == baseId) return true;
while (id = getBase(id));
@@ -269,53 +269,49 @@ function postInstantiate(baseModule, instance) {
return false;
}
- baseModule.__instanceof = __instanceof;
+ extendedExports.__instanceof = __instanceof;
- // Pull basic exports to baseModule so code in preInstantiate can use them
- baseModule.memory = baseModule.memory || memory;
- baseModule.table = baseModule.table || table;
+ // Pull basic exports to extendedExports so code in preInstantiate can use them
+ extendedExports.memory = extendedExports.memory || memory;
+ extendedExports.table = extendedExports.table || table;
// Demangle exports and provide the usual utility on the prototype
- return demangle(rawExports, baseModule);
+ return demangle(exports, extendedExports);
}
-function isResponse(o) {
- return typeof Response !== "undefined" && o instanceof Response;
+function isResponse(src) {
+ return typeof Response !== "undefined" && src instanceof Response;
+}
+
+function isModule(src) {
+ return src instanceof WebAssembly.Module;
}
/** Asynchronously instantiates an AssemblyScript module from anything that can be instantiated. */
-async function instantiate(source, imports) {
+async function instantiate(source, imports = {}) {
if (isResponse(source = await source)) return instantiateStreaming(source, imports);
- return postInstantiate(
- preInstantiate(imports || (imports = {})),
- await WebAssembly.instantiate(
- source instanceof WebAssembly.Module
- ? source
- : await WebAssembly.compile(source),
- imports
- )
- );
+ const module = isModule(source) ? source : await WebAssembly.compile(source);
+ const extended = preInstantiate(imports);
+ const instance = await WebAssembly.instantiate(module, imports);
+ const exports = postInstantiate(extended, instance);
+ return { module, instance, exports };
}
exports.instantiate = instantiate;
/** Synchronously instantiates an AssemblyScript module from a WebAssembly.Module or binary buffer. */
-function instantiateSync(source, imports) {
- return postInstantiate(
- preInstantiate(imports || (imports = {})),
- new WebAssembly.Instance(
- source instanceof WebAssembly.Module
- ? source
- : new WebAssembly.Module(source),
- imports
- )
- )
+function instantiateSync(source, imports = {}) {
+ const module = isModule(source) ? source : new WebAssembly.Module(source);
+ const extended = preInstantiate(imports);
+ const instance = new WebAssembly.Instance(module, imports);
+ const exports = postInstantiate(extended, instance);
+ return { module, instance, exports };
}
exports.instantiateSync = instantiateSync;
/** Asynchronously instantiates an AssemblyScript module from a response, i.e. as obtained by `fetch`. */
-async function instantiateStreaming(source, imports) {
+async function instantiateStreaming(source, imports = {}) {
if (!WebAssembly.instantiateStreaming) {
return instantiate(
isResponse(source = await source)
@@ -324,25 +320,25 @@ async function instantiateStreaming(source, imports) {
imports
);
}
- return postInstantiate(
- preInstantiate(imports || (imports = {})),
- (await WebAssembly.instantiateStreaming(source, imports)).instance
- );
+ const extended = preInstantiate(imports);
+ const result = await WebAssembly.instantiateStreaming(source, imports);
+ const exports = postInstantiate(extended, result.instance);
+ return { ...result, exports };
}
exports.instantiateStreaming = instantiateStreaming;
/** Demangles an AssemblyScript module's exports to a friendly object structure. */
-function demangle(exports, baseModule) {
- var module = baseModule ? Object.create(baseModule) : {};
- var setArgumentsLength = exports["__argumentsLength"]
- ? function(length) { exports["__argumentsLength"].value = length; }
- : exports["__setArgumentsLength"] || exports["__setargc"] || function() {};
+function demangle(exports, extendedExports = {}) {
+ extendedExports = Object.create(extendedExports);
+ const setArgumentsLength = exports["__argumentsLength"]
+ ? length => { exports["__argumentsLength"].value = length; }
+ : exports["__setArgumentsLength"] || exports["__setargc"] || (() => {});
for (let internalName in exports) {
if (!Object.prototype.hasOwnProperty.call(exports, internalName)) continue;
const elem = exports[internalName];
let parts = internalName.split(".");
- let curr = module;
+ let curr = extendedExports;
while (parts.length > 1) {
let part = parts.shift();
if (!Object.prototype.hasOwnProperty.call(curr, part)) curr[part] = {};
@@ -351,10 +347,10 @@ function demangle(exports, baseModule) {
let name = parts[0];
let hash = name.indexOf("#");
if (hash >= 0) {
- let className = name.substring(0, hash);
- let classElem = curr[className];
+ const className = name.substring(0, hash);
+ const classElem = curr[className];
if (typeof classElem === "undefined" || !classElem.prototype) {
- let ctor = function(...args) {
+ const ctor = function(...args) {
return ctor.wrap(ctor.prototype.constructor(0, ...args));
};
ctor.prototype = {
@@ -414,7 +410,7 @@ function demangle(exports, baseModule) {
}
}
}
- return module;
+ return extendedExports;
}
exports.demangle = demangle;
diff --git a/lib/loader/tests/index.js b/lib/loader/tests/index.js
index bef4129e5a..8dee745204 100644
--- a/lib/loader/tests/index.js
+++ b/lib/loader/tests/index.js
@@ -12,44 +12,45 @@ testInstantiate("legacy.wasm");
function test(file) {
var buffer = fs.readFileSync(__dirname + "/build/" + file);
- var module = loader.instantiateSync(buffer, {});
+ var result = loader.instantiateSync(buffer, {});
+ const exports = result.exports;
- console.log(inspect(module, true, 100, true));
+ console.log(inspect(exports, true, 100, true));
// should export memory
- assert(module.memory instanceof WebAssembly.Memory);
- assert(typeof module.memory.copy === "function");
+ assert(exports.memory instanceof WebAssembly.Memory);
+ assert(typeof exports.memory.copy === "function");
// should be able to get an exported string
- assert.strictEqual(module.__getString(module.COLOR), "red");
+ assert.strictEqual(exports.__getString(exports.COLOR), "red");
// should be able to allocate and work with a new string
{
let str = "Hello world!𤭢";
- let ref = module.__retain(module.__allocString(str));
- assert.strictEqual(module.__getString(ref), str);
- assert.strictEqual(module.strlen(ref), str.length);
- module.__release(ref);
+ let ref = exports.__retain(exports.__allocString(str));
+ assert.strictEqual(exports.__getString(ref), str);
+ assert.strictEqual(exports.strlen(ref), str.length);
+ exports.__release(ref);
}
// should be able to allocate a typed array
{
var arr = [1, 2, 3, 4, 5, 0x80000000 | 0];
- let ref = module.__retain(module.__allocArray(module.INT32ARRAY_ID, arr));
- assert(module.__instanceof(ref, module.INT32ARRAY_ID));
+ let ref = exports.__retain(exports.__allocArray(exports.INT32ARRAY_ID, arr));
+ assert(exports.__instanceof(ref, exports.INT32ARRAY_ID));
// should be able to get the values of an array
- assert.deepEqual(module.__getArray(ref), arr);
+ assert.deepEqual(exports.__getArray(ref), arr);
// should be able to get a view on an array
- assert.deepEqual(module.__getArrayView(ref), new Int32Array(arr));
+ assert.deepEqual(exports.__getArrayView(ref), new Int32Array(arr));
// should be able to sum up its values
- assert.strictEqual(module.sum(ref), arr.reduce((a, b) => (a + b) | 0, 0) | 0);
+ assert.strictEqual(exports.sum(ref), arr.reduce((a, b) => (a + b) | 0, 0) | 0);
// should be able to release no longer needed references
- module.__release(ref);
- try { module.__release(ref); assert(false); } catch (e) {};
+ exports.__release(ref);
+ try { exports.__release(ref); assert(false); } catch (e) {};
}
/*
@@ -80,62 +81,62 @@ function test(file) {
// should be able to distinguish between signed and unsigned
{
let arr = new Uint8Array([0, 255, 127]);
- let ref = module.__retain(module.__allocArray(module.UINT8ARRAY_ID, arr));
- assert(module.__instanceof(ref, module.UINT8ARRAY_ID));
- assert.deepEqual(module.__getUint8Array(ref), arr);
- module.__release(ref);
- try { module.__release(ref); assert(false); } catch (e) {};
+ let ref = exports.__retain(exports.__allocArray(exports.UINT8ARRAY_ID, arr));
+ assert(exports.__instanceof(ref, exports.UINT8ARRAY_ID));
+ assert.deepEqual(exports.__getUint8Array(ref), arr);
+ exports.__release(ref);
+ try { exports.__release(ref); assert(false); } catch (e) {};
}
// should be able to distinguish between signed and unsigned
{
let arr = new Int16Array([0, 0xFFFF, -0x00FF]);
- let ref = module.__retain(module.__allocArray(module.INT16ARRAY_ID, arr));
- assert(module.__instanceof(ref, module.INT16ARRAY_ID));
- assert.deepEqual(module.__getInt16Array(ref), arr);
- module.__release(ref);
- try { module.__release(ref); assert(false); } catch (e) {};
+ let ref = exports.__retain(exports.__allocArray(exports.INT16ARRAY_ID, arr));
+ assert(exports.__instanceof(ref, exports.INT16ARRAY_ID));
+ assert.deepEqual(exports.__getInt16Array(ref), arr);
+ exports.__release(ref);
+ try { exports.__release(ref); assert(false); } catch (e) {};
}
// should be able to distinguish between signed and unsigned
{
let arr = [1, -1 >>> 0, 0x80000000];
- let ref = module.__retain(module.__allocArray(module.UINT32ARRAY_ID, arr));
- assert(module.__instanceof(ref, module.UINT32ARRAY_ID));
- assert.deepEqual(module.__getUint32Array(ref), new Uint32Array(arr));
- assert.deepEqual(module.__getUint32ArrayView(ref), new Uint32Array(arr));
- assert.deepEqual(module.__getArray(ref), arr);
- module.__release(ref);
- try { module.__release(ref); assert(false); } catch (e) {};
+ let ref = exports.__retain(exports.__allocArray(exports.UINT32ARRAY_ID, arr));
+ assert(exports.__instanceof(ref, exports.UINT32ARRAY_ID));
+ assert.deepEqual(exports.__getUint32Array(ref), new Uint32Array(arr));
+ assert.deepEqual(exports.__getUint32ArrayView(ref), new Uint32Array(arr));
+ assert.deepEqual(exports.__getArray(ref), arr);
+ exports.__release(ref);
+ try { exports.__release(ref); assert(false); } catch (e) {};
}
// should be able to distinguish between integer and float
{
let arr = [0.0, 1.5, 2.5];
- let ref = module.__retain(module.__allocArray(module.FLOAT32ARRAY_ID, arr));
- assert(module.__instanceof(ref, module.FLOAT32ARRAY_ID));
- assert.deepEqual(module.__getFloat32Array(ref), new Float32Array(arr));
- assert.deepEqual(module.__getFloat32ArrayView(ref), new Float32Array(arr));
- assert.deepEqual(module.__getArray(ref), arr);
- module.__release(ref);
- try { module.__release(ref); assert(false); } catch (e) {};
+ let ref = exports.__retain(exports.__allocArray(exports.FLOAT32ARRAY_ID, arr));
+ assert(exports.__instanceof(ref, exports.FLOAT32ARRAY_ID));
+ assert.deepEqual(exports.__getFloat32Array(ref), new Float32Array(arr));
+ assert.deepEqual(exports.__getFloat32ArrayView(ref), new Float32Array(arr));
+ assert.deepEqual(exports.__getArray(ref), arr);
+ exports.__release(ref);
+ try { exports.__release(ref); assert(false); } catch (e) {};
}
// should be able to work with normal arrays
{
let arr = [1, 2, 3, 4, 5];
- let ref = module.__retain(module.__allocArray(module.ARRAYI32_ID, arr));
- assert(module.__instanceof(ref, module.ARRAYI32_ID));
- module.changeLength(ref, 3);
- assert.deepEqual(module.__getArray(ref), [1, 2, 3]);
- module.__release(ref);
- try { module.__release(ref); assert(false); } catch (e) {};
+ let ref = exports.__retain(exports.__allocArray(exports.ARRAYI32_ID, arr));
+ assert(exports.__instanceof(ref, exports.ARRAYI32_ID));
+ exports.changeLength(ref, 3);
+ assert.deepEqual(exports.__getArray(ref), [1, 2, 3]);
+ exports.__release(ref);
+ try { exports.__release(ref); assert(false); } catch (e) {};
}
// should be able to correctly call a function with variable arguments
- assert.strictEqual(module.varadd(), 3);
- assert.strictEqual(module.varadd(2, 3), 5);
- assert.strictEqual(module.varadd(2), 4);
+ assert.strictEqual(exports.varadd(), 3);
+ assert.strictEqual(exports.varadd(2, 3), 5);
+ assert.strictEqual(exports.varadd(2), 4);
// TBD: table is no more exported by default to allow more optimizations
@@ -150,67 +151,75 @@ function test(file) {
// assert.strictEqual(module.calladd(ref, 2, 3), 5);
// should be able to use a class
- var car = new module.Car(5);
+ var car = new exports.Car(5);
assert.strictEqual(car.numDoors, 5);
assert.strictEqual(car.isDoorsOpen, 0);
car.openDoors();
assert.strictEqual(car.isDoorsOpen, 1);
car.closeDoors();
assert.strictEqual(car.isDoorsOpen, 0);
- module.__release(car); // uses Car.prototype.valueOf to obtain `thisPtr`
+ exports.__release(car); // uses Car.prototype.valueOf to obtain `thisPtr`
// should be able to use trace
- module.dotrace(42);
+ exports.dotrace(42);
// should be able to mutate an array in place using getArrayView
{
- let ptr = module.__retain(module.__allocArray(module.FLOAT32ARRAY_ID, [1, 2, 3]));
- let view = module.__getArrayView(ptr);
+ let ptr = exports.__retain(exports.__allocArray(exports.FLOAT32ARRAY_ID, [1, 2, 3]));
+ let view = exports.__getArrayView(ptr);
assert.deepEqual(view, new Float32Array([1, 2, 3]));
- module.modifyFloat32Array(ptr, 0, 4);
+ exports.modifyFloat32Array(ptr, 0, 4);
assert.deepEqual(view, new Float32Array([4, 2, 3]));
- module.__release(ptr);
+ exports.__release(ptr);
}
// should be able to mutate an array in place using getFloat32Array
{
- let ptr = module.newFloat32Array(3); // returns are pre-retained
- let view = module.__getFloat32ArrayView(ptr);
- let arr = module.__getFloat32Array(ptr);
+ let ptr = exports.newFloat32Array(3); // returns are pre-retained
+ let view = exports.__getFloat32ArrayView(ptr);
+ let arr = exports.__getFloat32Array(ptr);
assert.deepEqual(view, new Float32Array([0, 0, 0]));
assert.deepEqual(arr, new Float32Array([0, 0, 0]));
- module.modifyFloat32Array(ptr, 0, 3);
- module.modifyFloat32Array(ptr, 1, 2);
- module.modifyFloat32Array(ptr, 2, 1);
+ exports.modifyFloat32Array(ptr, 0, 3);
+ exports.modifyFloat32Array(ptr, 1, 2);
+ exports.modifyFloat32Array(ptr, 2, 1);
assert.deepEqual(view, new Float32Array([3, 2, 1]));
assert.deepEqual(arr, new Float32Array([0, 0, 0]));
- module.__release(ptr);
+ exports.__release(ptr);
}
}
function testInstantiate(file) {
// should be able to instantiate from a buffer
(async () => {
- const module = await loader.instantiate(fs.readFileSync(__dirname + "/build/" + file), {});
- assert(module.memory);
+ const { exports, instance, module } = await loader.instantiate(fs.readFileSync(__dirname + "/build/" + file), {});
+ assert(exports.memory);
+ assert(instance && instance instanceof WebAssembly.Instance);
+ assert(module && module instanceof WebAssembly.Module);
})();
// should be able to instantiate from a wasm module
(async () => {
const wasmModule = new WebAssembly.Module(fs.readFileSync(__dirname + "/build/" + file));
- const module = await loader.instantiate(wasmModule, {});
- assert(module.memory);
+ const { exports, instance, module } = await loader.instantiate(wasmModule, {});
+ assert(exports.memory);
+ assert(instance && instance instanceof WebAssembly.Instance);
+ assert(module && module instanceof WebAssembly.Module);
})();
// should be able to instantiate from a promise yielding a buffer
(async () => {
- const module = await loader.instantiate(fs.promises.readFile(__dirname + "/build/" + file), {});
- assert(module.memory);
+ const { exports, instance, module } = await loader.instantiate(fs.promises.readFile(__dirname + "/build/" + file), {});
+ assert(exports.memory);
+ assert(instance && instance instanceof WebAssembly.Instance);
+ assert(module && module instanceof WebAssembly.Module);
})();
// should be able to mimic instantiateStreaming under node (for now)
(async () => {
- const module = await loader.instantiateStreaming(fs.promises.readFile(__dirname + "/build/" + file), {});
- assert(module.memory);
+ const { exports, instance, module } = await loader.instantiateStreaming(fs.promises.readFile(__dirname + "/build/" + file), {});
+ assert(exports.memory);
+ assert(instance && instance instanceof WebAssembly.Instance);
+ assert(module && module instanceof WebAssembly.Module);
})();
}
\ No newline at end of file
diff --git a/tests/bootstrap/index.ts b/tests/bootstrap/index.ts
index 60828f9610..bafb9ff1b7 100644
--- a/tests/bootstrap/index.ts
+++ b/tests/bootstrap/index.ts
@@ -6,17 +6,20 @@ import AssemblyScript from "../../out/assemblyscript";
async function test(build: string): Promise {
await binaryen.ready;
- const assemblyscript = await loader.instantiate(fs.promises.readFile(__dirname + "/../../out/assemblyscript." + build + ".wasm"), { binaryen });
- console.log(util.inspect(assemblyscript, true));
- const optionsPtr = assemblyscript.newOptions();
- const programPtr = assemblyscript.newProgram(optionsPtr);
- const textPtr = assemblyscript.__allocString("export function add(a: i32, b: i32): i32 { return a + b; }\n");
- const pathPtr = assemblyscript.__allocString("index.ts");
- assemblyscript.parse(programPtr, textPtr, pathPtr, true);
- var nextFilePtr = assemblyscript.nextFile(programPtr);
+ const { exports: asc } = await loader.instantiate(
+ fs.promises.readFile(`${ __dirname }/../../out/assemblyscript.${ build }.wasm`),
+ { binaryen }
+ );
+ console.log(util.inspect(asc, true));
+ const optionsPtr = asc.newOptions();
+ const programPtr = asc.newProgram(optionsPtr);
+ const textPtr = asc.__allocString("export function add(a: i32, b: i32): i32 { return a + b; }\n");
+ const pathPtr = asc.__allocString("index.ts");
+ asc.parse(programPtr, textPtr, pathPtr, true);
+ var nextFilePtr = asc.nextFile(programPtr);
while (nextFilePtr) {
- console.log("nextFile: " + assemblyscript.__getString(nextFilePtr));
- nextFilePtr = assemblyscript.nextFile(programPtr);
+ console.log("nextFile: " + asc.__getString(nextFilePtr));
+ nextFilePtr = asc.nextFile(programPtr);
}
// assemblyscript.compile(programPtr);
// ^ abort: missing ArrayBuffer at src/program.ts:1015:18