diff --git a/lib/loader/index.d.ts b/lib/loader/index.d.ts index 3ffc842373..8db7280e14 100644 --- a/lib/loader/index.d.ts +++ b/lib/loader/index.d.ts @@ -92,7 +92,7 @@ export interface ASUtil { /** Allocates a new ArrayBuffer in the module's memory and returns a reference (pointer) to it. */ __newArrayBuffer(buf: ArrayBuffer): number; /** Allocates a new array in the module's memory and returns a reference (pointer) to it. */ - __newArray(id: number, values: ArrayLike): number; + __newArray(id: number, valuesOrCapacity?: Array | ArrayBufferView | number): number; /** Allocates an instance of the class represented by the specified id. */ __new(size: number, id: number): number; diff --git a/lib/loader/index.js b/lib/loader/index.js index f61735b0f9..b76d8a89c3 100644 --- a/lib/loader/index.js +++ b/lib/loader/index.js @@ -195,10 +195,12 @@ function postInstantiate(extendedExports, instance) { } /** Allocates a new array in the module's memory and returns its pointer. */ - function __newArray(id, values) { + function __newArray(id, valuesOrCapacity = 0) { + const input = valuesOrCapacity; const info = getArrayInfo(id); const align = getValueAlign(info); - const length = values.length; + const isArrayLike = typeof input !== "number"; + const length = isArrayLike ? input.length : input; const buf = __new(length << align, info & STATICARRAY ? id : ARRAYBUFFER_ID); let result; if (info & STATICARRAY) { @@ -214,14 +216,16 @@ function postInstantiate(extendedExports, instance) { if (info & ARRAY) U32[arr + ARRAY_LENGTH_OFFSET >>> 2] = length; result = arr; } - const view = getView(align, info & VAL_SIGNED, info & VAL_FLOAT); - if (info & VAL_MANAGED) { - for (let i = 0; i < length; ++i) { - const value = values[i]; - view[(buf >>> align) + i] = value; + if (isArrayLike) { + const view = getView(align, info & VAL_SIGNED, info & VAL_FLOAT); + const start = buf >>> align; + if (info & VAL_MANAGED) { + for (let i = 0; i < length; ++i) { + view[start + i] = input[i]; + } + } else { + view.set(input, start); } - } else { - view.set(values, buf >>> align); } return result; } diff --git a/lib/loader/tests/index.js b/lib/loader/tests/index.js index 2808a24b0e..0d24db2a3a 100644 --- a/lib/loader/tests/index.js +++ b/lib/loader/tests/index.js @@ -186,6 +186,20 @@ function test(file) { assert.deepStrictEqual(exports.__getArray(ref), arr); } + // should be able to create empty arrays + { + let ref = exports.__newArray(exports.ARRAYI32_ID); + assert(exports.__instanceof(ref, exports.ARRAYI32_ID)); + assert.deepStrictEqual(exports.__getArray(ref), []); + } + + // should be able to create arrays with capacity + { + let ref = exports.__newArray(exports.ARRAYI32_ID, 32); + assert(exports.__instanceof(ref, exports.ARRAYI32_ID)); + assert.strictEqual(exports.__getArray(ref).length, 32); + } + // should be able to work with normal arrays { let arr = [1, 2, 3, 4, 5];