wasm-resizablearraybuffer.js (4238B)
1 // |jit-test| skip-if: !('toResizableBuffer' in WebAssembly.Memory.prototype) 2 3 let mem = new WebAssembly.Memory({initial: 20, maximum: 50}); 4 5 // Utils for testing 6 7 let ins = wasmEvalText(`(module 8 (import "" "mem" (memory 20 50)) 9 (func (export "check") (param i32 i32 i32) (result i32) 10 block 11 loop 12 local.get 0 13 i32.load 14 local.get 2 15 i32.eq 16 i32.eqz 17 br_if 1 18 19 local.get 1 20 i32.const 1 21 i32.sub 22 local.set 1 23 local.get 0 24 i32.const 4 25 i32.add 26 local.set 0 27 local.get 1 28 br_if 0 29 i32.const 1 30 return 31 end 32 end 33 i32.const 0 34 ) 35 (func (export "fill") (param i32 i32 i32) 36 loop 37 local.get 0 38 local.get 2 39 i32.store 40 41 local.get 1 42 i32.const 1 43 i32.sub 44 local.set 1 45 local.get 0 46 i32.const 4 47 i32.add 48 local.set 0 49 local.get 1 50 br_if 0 51 end 52 ) 53 )`, {"": {mem,}}); 54 55 function check(off, count, value) { 56 const arr = new Int32Array(mem.buffer); 57 for (let i = 0; i < count; i++) { 58 assertEq(arr[(off >> 2) + i], value); 59 } 60 } 61 function fill(off, count, value) { 62 const arr = new Int32Array(mem.buffer); 63 for (let i = 0; i < count; i++) { 64 arr[i] = value; 65 } 66 } 67 68 fill(0, 10, 1); 69 assertEq(ins.exports.check(0, 10, 1), 1); 70 71 // Convert to resizable array, back to fixed-length, again to resizable, 72 // and attempt to resize using JS. 73 74 let ab = mem.buffer; 75 assertEq(ab.resizable, false); 76 assertEq(ab.maxByteLength, 20 << 16); 77 78 // Make .buffer resizable, detaching the old one. 79 let rab = mem.toResizableBuffer(); 80 assertEq(rab.resizable, true); 81 assertEq(mem.buffer, rab); 82 assertEq(ab.detached, true); 83 assertEq(rab.maxByteLength, 50 << 16); 84 85 assertEq(ins.exports.check(0, 10, 1), 1); 86 ins.exports.fill(0, 10, 3); 87 check(0, 10, 3); 88 89 // We can go back if we choose. 90 let ab2 = mem.toFixedLengthBuffer(); 91 assertEq(ab2.resizable, false); 92 assertEq(mem.buffer, ab2); 93 assertEq(ab2 !== ab, true); 94 assertEq(rab.detached, true); 95 assertEq(ab2.byteLength, 20 << 16); 96 assertEq(ab2.maxByteLength, 20 << 16); 97 98 assertEq(ins.exports.check(0, 10, 3), 1); 99 ins.exports.fill(0, 10, 2); 100 check(0, 10, 2); 101 102 assertThrowsInstanceOf( 103 () => ins.exports.check(20 * 65536 - 4, 2, 0), WebAssembly.RuntimeError); 104 ins.exports.fill(20 * 65536 - 4, 1, 20); 105 106 // Let's go back to resizable. Memory#grow no longer detaches .buffer when it's resizable. 107 rab = mem.toResizableBuffer(); 108 let oldLen = rab.byteLength; 109 mem.grow(8); 110 assertEq(rab.detached, false); 111 assertEq(rab.byteLength, oldLen + (8 * 65536)) 112 assertEq(rab.maxByteLength, 50 << 16); 113 114 ins.exports.check(20 * 65536 - 4, 1, 20); 115 ins.exports.check(20 * 65536, 1, 0); 116 assertThrowsInstanceOf( 117 () => ins.exports.check(28 * 65536 - 4, 2, 0), WebAssembly.RuntimeError); 118 119 assertEq(ins.exports.check(0, 10, 2), 1); 120 ins.exports.fill(0, 10, 5); 121 check(0, 10, 5); 122 123 // Try to resize JS way. 124 rab.resize(65536 * 30); 125 assertEq(rab.byteLength, 30 * 65536); 126 ins.exports.fill(30 * 65536 - 10*4, 10, 6); 127 check(30 * 65536 - 10 * 4, 10, 6); 128 129 // RAB#resize throws when trying to shrink or grow by non-page multiples 130 // for WebAssembly.Memory-vended RABs. 131 assertThrowsInstanceOf(() => rab.resize(rab.byteLength - 65536), RangeError); 132 assertThrowsInstanceOf(() => rab.resize(rab.byteLength + 10), RangeError); 133 134 // No allow to make buffer resizable when max in not specified. 135 136 mem = new WebAssembly.Memory({initial: 20}); 137 assertThrowsInstanceOf(() => mem.toResizableBuffer(), TypeError); 138 139 // Test the JS API with a resizable and shared buffer. 140 a = new WebAssembly.Memory({ 141 initial: 2, 142 maximum: 4, 143 shared: true 144 }) 145 a.toResizableBuffer(); 146 setSharedObject(a); 147 148 // Testing the limits of our implementation. 149 let big_memory = new WebAssembly.Memory({address: 'i64', initial: 0n, maximum: BigInt(MaxMemory64PagesValidation), shared: false}); 150 let buffer = big_memory.toResizableBuffer(); 151 152 // Asserts that buffer.maxByteLength is less than MAX_SAFE_INTEGER. 153 assertEq(buffer.maxByteLength <= Number.MAX_SAFE_INTEGER, true); 154 155 // Create a new Memory without a maximum and accessing maxByteLength. 156 new WebAssembly.Memory({ initial: 10 }).buffer.maxByteLength;