Skip to content

Commit 8eaa44a

Browse files
authored
feat: add ability to create arrays with capacity for __newArray (#2024)
1 parent b0549e0 commit 8eaa44a

File tree

3 files changed

+28
-10
lines changed

3 files changed

+28
-10
lines changed

lib/loader/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export interface ASUtil {
9292
/** Allocates a new ArrayBuffer in the module's memory and returns a reference (pointer) to it. */
9393
__newArrayBuffer(buf: ArrayBuffer): number;
9494
/** Allocates a new array in the module's memory and returns a reference (pointer) to it. */
95-
__newArray(id: number, values: ArrayLike<number>): number;
95+
__newArray(id: number, valuesOrCapacity?: Array<number> | ArrayBufferView | number): number;
9696

9797
/** Allocates an instance of the class represented by the specified id. */
9898
__new(size: number, id: number): number;

lib/loader/index.js

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,12 @@ function postInstantiate(extendedExports, instance) {
195195
}
196196

197197
/** Allocates a new array in the module's memory and returns its pointer. */
198-
function __newArray(id, values) {
198+
function __newArray(id, valuesOrCapacity = 0) {
199+
const input = valuesOrCapacity;
199200
const info = getArrayInfo(id);
200201
const align = getValueAlign(info);
201-
const length = values.length;
202+
const isArrayLike = typeof input !== "number";
203+
const length = isArrayLike ? input.length : input;
202204
const buf = __new(length << align, info & STATICARRAY ? id : ARRAYBUFFER_ID);
203205
let result;
204206
if (info & STATICARRAY) {
@@ -214,14 +216,16 @@ function postInstantiate(extendedExports, instance) {
214216
if (info & ARRAY) U32[arr + ARRAY_LENGTH_OFFSET >>> 2] = length;
215217
result = arr;
216218
}
217-
const view = getView(align, info & VAL_SIGNED, info & VAL_FLOAT);
218-
if (info & VAL_MANAGED) {
219-
for (let i = 0; i < length; ++i) {
220-
const value = values[i];
221-
view[(buf >>> align) + i] = value;
219+
if (isArrayLike) {
220+
const view = getView(align, info & VAL_SIGNED, info & VAL_FLOAT);
221+
const start = buf >>> align;
222+
if (info & VAL_MANAGED) {
223+
for (let i = 0; i < length; ++i) {
224+
view[start + i] = input[i];
225+
}
226+
} else {
227+
view.set(input, start);
222228
}
223-
} else {
224-
view.set(values, buf >>> align);
225229
}
226230
return result;
227231
}

lib/loader/tests/index.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,20 @@ function test(file) {
186186
assert.deepStrictEqual(exports.__getArray(ref), arr);
187187
}
188188

189+
// should be able to create empty arrays
190+
{
191+
let ref = exports.__newArray(exports.ARRAYI32_ID);
192+
assert(exports.__instanceof(ref, exports.ARRAYI32_ID));
193+
assert.deepStrictEqual(exports.__getArray(ref), []);
194+
}
195+
196+
// should be able to create arrays with capacity
197+
{
198+
let ref = exports.__newArray(exports.ARRAYI32_ID, 32);
199+
assert(exports.__instanceof(ref, exports.ARRAYI32_ID));
200+
assert.strictEqual(exports.__getArray(ref).length, 32);
201+
}
202+
189203
// should be able to work with normal arrays
190204
{
191205
let arr = [1, 2, 3, 4, 5];

0 commit comments

Comments
 (0)