Source code

Revision control

Copy as Markdown

Other Tools

// |jit-test| skip-if: !('toResizableBuffer' in WebAssembly.Memory.prototype)
let mem = new WebAssembly.Memory({initial: 20, maximum: 50, shared: true});
// Utils for testing
let ins = wasmEvalText(`(module
(import "" "mem" (memory 20 50 shared))
(func (export "check") (param i32 i32 i32) (result i32)
block
loop
local.get 0
i32.load
local.get 2
i32.eq
i32.eqz
br_if 1
local.get 1
i32.const 1
i32.sub
local.set 1
local.get 0
i32.const 4
i32.add
local.set 0
local.get 1
br_if 0
i32.const 1
return
end
end
i32.const 0
)
(func (export "fill") (param i32 i32 i32)
loop
local.get 0
local.get 2
i32.store
local.get 1
i32.const 1
i32.sub
local.set 1
local.get 0
i32.const 4
i32.add
local.set 0
local.get 1
br_if 0
end
)
)`, {"": {mem,}});
function check(off, count, value) {
const arr = new Int32Array(mem.buffer);
for (let i = 0; i < count; i++) {
assertEq(arr[(off >> 2) + i], value);
}
}
function fill(off, count, value) {
const arr = new Int32Array(mem.buffer);
for (let i = 0; i < count; i++) {
arr[i] = value;
}
}
fill(0, 10, 1);
assertEq(ins.exports.check(0, 10, 1), 1);
// Convert to growable array, back to fixed-length, again to growable,
// and attempt to resize using JS.
let ab = mem.buffer;
assertEq(ab.growable, false);
// Make .buffer growable, detaching the old one.
let rab = mem.toResizableBuffer();
assertEq(rab.growable, true);
assertEq(mem.buffer, rab);
assertEq(rab.maxByteLength, 50 << 16);
assertEq(ins.exports.check(0, 10, 1), 1);
ins.exports.fill(0, 10, 3);
check(0, 10, 3);
// We can go back if we choose.
let ab2 = mem.toFixedLengthBuffer();
assertEq(ab2.growable, false);
assertEq(mem.buffer, ab2);
assertEq(ab2 !== ab, true);
assertEq(ab2.maxByteLength, 20 << 16);
assertEq(ins.exports.check(0, 10, 3), 1);
ins.exports.fill(0, 10, 2);
check(0, 10, 2);
assertThrowsInstanceOf(
() => ins.exports.check(20 * 65536 - 4, 2, 0), WebAssembly.RuntimeError);
ins.exports.fill(20 * 65536 - 4, 1, 20);
// Let's go back to growable. Memory#grow no longer detaches .buffer when it's growable.
rab = mem.toResizableBuffer();
let oldLen = rab.byteLength;
mem.grow(8);
assertEq(rab.byteLength, oldLen + (8 * 65536))
assertEq(rab.maxByteLength, 50 << 16);
ins.exports.check(20 * 65536 - 4, 1, 20);
ins.exports.check(20 * 65536, 1, 0);
assertThrowsInstanceOf(
() => ins.exports.check(28 * 65536 - 4, 2, 0), WebAssembly.RuntimeError);
assertEq(ins.exports.check(0, 10, 2), 1);
ins.exports.fill(0, 10, 5);
check(0, 10, 5);
// Try to resize JS way.
rab.grow(65536 * 30);
assertEq(rab.byteLength, 30 * 65536);
ins.exports.fill(30 * 65536 - 10*4, 10, 6);
check(30 * 65536 - 10 * 4, 10, 6);
// RAB#resize throws when trying to shrink or grow by non-page multiples
// for WebAssembly.Memory-vended RABs.
assertThrowsInstanceOf(() => rab.grow(rab.byteLength - 65536), RangeError);
assertThrowsInstanceOf(() => rab.grow(rab.byteLength + 10), RangeError);