| // META: global=window,dedicatedworker,jsshell,shadowrealm |
| // META: script=/wasm/jsapi/memory/assertions.js |
| |
| test(() => { |
| const argument = { "initial": 0 }; |
| const memory = new WebAssembly.Memory(argument); |
| assert_throws_js(TypeError, () => memory.grow()); |
| }, "Missing arguments"); |
| |
| test(t => { |
| const thisValues = [ |
| undefined, |
| null, |
| true, |
| "", |
| Symbol(), |
| 1, |
| {}, |
| WebAssembly.Memory, |
| WebAssembly.Memory.prototype, |
| ]; |
| |
| const argument = { |
| valueOf: t.unreached_func("Should not touch the argument (valueOf)"), |
| toString: t.unreached_func("Should not touch the argument (toString)"), |
| }; |
| |
| const fn = WebAssembly.Memory.prototype.grow; |
| |
| for (const thisValue of thisValues) { |
| assert_throws_js(TypeError, () => fn.call(thisValue, argument), `this=${format_value(thisValue)}`); |
| } |
| }, "Branding"); |
| |
| test(() => { |
| const argument = { "initial": 0 }; |
| const memory = new WebAssembly.Memory(argument); |
| const oldMemory = memory.buffer; |
| assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing"); |
| |
| const result = memory.grow(2); |
| assert_equals(result, 0); |
| |
| const newMemory = memory.buffer; |
| assert_not_equals(oldMemory, newMemory); |
| assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing"); |
| assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing"); |
| }, "Zero initial"); |
| |
| test(() => { |
| const argument = { "initial": { valueOf() { return 0 } } }; |
| const memory = new WebAssembly.Memory(argument); |
| const oldMemory = memory.buffer; |
| assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing"); |
| |
| const result = memory.grow({ valueOf() { return 2 } }); |
| assert_equals(result, 0); |
| |
| const newMemory = memory.buffer; |
| assert_not_equals(oldMemory, newMemory); |
| assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing"); |
| assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing"); |
| }, "Zero initial with valueOf"); |
| |
| test(() => { |
| const argument = { "initial": 3 }; |
| const memory = new WebAssembly.Memory(argument); |
| const oldMemory = memory.buffer; |
| assert_ArrayBuffer(oldMemory, { "size": 3 }, "Buffer before growing"); |
| |
| const result = memory.grow(2); |
| assert_equals(result, 3); |
| |
| const newMemory = memory.buffer; |
| assert_not_equals(oldMemory, newMemory); |
| assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing"); |
| assert_ArrayBuffer(newMemory, { "size": 5 }, "New buffer after growing"); |
| }, "Non-zero initial"); |
| |
| test(() => { |
| const argument = { "initial": 0, "maximum": 2 }; |
| const memory = new WebAssembly.Memory(argument); |
| const oldMemory = memory.buffer; |
| assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing"); |
| |
| const result = memory.grow(2); |
| assert_equals(result, 0); |
| |
| const newMemory = memory.buffer; |
| assert_not_equals(oldMemory, newMemory); |
| assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing"); |
| assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing"); |
| }, "Zero initial with respected maximum"); |
| |
| test(() => { |
| const argument = { "initial": 0, "maximum": 2 }; |
| const memory = new WebAssembly.Memory(argument); |
| const oldMemory = memory.buffer; |
| assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing"); |
| |
| const result = memory.grow(1); |
| assert_equals(result, 0); |
| |
| const newMemory = memory.buffer; |
| assert_not_equals(oldMemory, newMemory); |
| assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing once"); |
| assert_ArrayBuffer(newMemory, { "size": 1 }, "New buffer after growing once"); |
| |
| const result2 = memory.grow(1); |
| assert_equals(result2, 1); |
| |
| const newestMemory = memory.buffer; |
| assert_not_equals(newMemory, newestMemory); |
| assert_ArrayBuffer(oldMemory, { "detached": true }, "New buffer after growing twice"); |
| assert_ArrayBuffer(newMemory, { "detached": true }, "New buffer after growing twice"); |
| assert_ArrayBuffer(newestMemory, { "size": 2 }, "Newest buffer after growing twice"); |
| }, "Zero initial with respected maximum grown twice"); |
| |
| test(() => { |
| const argument = { "initial": 1, "maximum": 2 }; |
| const memory = new WebAssembly.Memory(argument); |
| const oldMemory = memory.buffer; |
| assert_ArrayBuffer(oldMemory, { "size": 1 }, "Buffer before growing"); |
| |
| assert_throws_js(RangeError, () => memory.grow(2)); |
| assert_equals(memory.buffer, oldMemory); |
| assert_ArrayBuffer(memory.buffer, { "size": 1 }, "Buffer before trying to grow"); |
| }, "Zero initial growing too much"); |
| |
| const outOfRangeValues = [ |
| undefined, |
| NaN, |
| Infinity, |
| -Infinity, |
| -1, |
| 0x100000000, |
| 0x1000000000, |
| "0x100000000", |
| { valueOf() { return 0x100000000; } }, |
| ]; |
| |
| for (const value of outOfRangeValues) { |
| test(() => { |
| const argument = { "initial": 0 }; |
| const memory = new WebAssembly.Memory(argument); |
| assert_throws_js(TypeError, () => memory.grow(value)); |
| }, `Out-of-range argument: ${format_value(value)}`); |
| } |
| |
| test(() => { |
| const argument = { "initial": 0 }; |
| const memory = new WebAssembly.Memory(argument); |
| const oldMemory = memory.buffer; |
| assert_ArrayBuffer(oldMemory, { "size": 0 }, "Buffer before growing"); |
| |
| const result = memory.grow(2, {}); |
| assert_equals(result, 0); |
| |
| const newMemory = memory.buffer; |
| assert_not_equals(oldMemory, newMemory); |
| assert_ArrayBuffer(oldMemory, { "detached": true }, "Old buffer after growing"); |
| assert_ArrayBuffer(newMemory, { "size": 2 }, "New buffer after growing"); |
| }, "Stray argument"); |
| |
| test(() => { |
| const argument = { "initial": 1, "maximum": 2, "shared": true }; |
| const memory = new WebAssembly.Memory(argument); |
| const oldMemory = memory.buffer; |
| assert_ArrayBuffer(oldMemory, { "size": 1, "shared": true }, "Buffer before growing"); |
| |
| const result = memory.grow(1); |
| assert_equals(result, 1); |
| |
| const newMemory = memory.buffer; |
| assert_not_equals(oldMemory, newMemory); |
| assert_ArrayBuffer(oldMemory, { "size": 1, "shared": true }, "Old buffer after growing"); |
| assert_ArrayBuffer(newMemory, { "size": 2, "shared": true }, "New buffer after growing"); |
| |
| // The old and new buffers must have the same value for the |
| // [[ArrayBufferData]] internal slot. |
| const oldArray = new Uint8Array(oldMemory); |
| const newArray = new Uint8Array(newMemory); |
| assert_equals(oldArray[0], 0, "old first element"); |
| assert_equals(newArray[0], 0, "new first element"); |
| oldArray[0] = 1; |
| assert_equals(oldArray[0], 1, "old first element"); |
| assert_equals(newArray[0], 1, "new first element"); |
| |
| }, "Growing shared memory does not detach old buffer"); |