wasm-resizablearraybuffer-shared.js (3234B)
1 // |jit-test| skip-if: !('toResizableBuffer' in WebAssembly.Memory.prototype) 2 3 let mem = new WebAssembly.Memory({initial: 20, maximum: 50, shared: true}); 4 5 // Utils for testing 6 7 let ins = wasmEvalText(`(module 8 (import "" "mem" (memory 20 50 shared)) 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 growable array, back to fixed-length, again to growable, 72 // and attempt to resize using JS. 73 74 let ab = mem.buffer; 75 assertEq(ab.growable, false); 76 77 // Make .buffer growable, detaching the old one. 78 let rab = mem.toResizableBuffer(); 79 assertEq(rab.growable, true); 80 assertEq(mem.buffer, rab); 81 assertEq(rab.maxByteLength, 50 << 16); 82 83 assertEq(ins.exports.check(0, 10, 1), 1); 84 ins.exports.fill(0, 10, 3); 85 check(0, 10, 3); 86 87 // We can go back if we choose. 88 let ab2 = mem.toFixedLengthBuffer(); 89 assertEq(ab2.growable, false); 90 assertEq(mem.buffer, ab2); 91 assertEq(ab2 !== ab, true); 92 assertEq(ab2.maxByteLength, 20 << 16); 93 94 assertEq(ins.exports.check(0, 10, 3), 1); 95 ins.exports.fill(0, 10, 2); 96 check(0, 10, 2); 97 98 assertThrowsInstanceOf( 99 () => ins.exports.check(20 * 65536 - 4, 2, 0), WebAssembly.RuntimeError); 100 ins.exports.fill(20 * 65536 - 4, 1, 20); 101 102 // Let's go back to growable. Memory#grow no longer detaches .buffer when it's growable. 103 rab = mem.toResizableBuffer(); 104 let oldLen = rab.byteLength; 105 mem.grow(8); 106 assertEq(rab.byteLength, oldLen + (8 * 65536)) 107 assertEq(rab.maxByteLength, 50 << 16); 108 109 ins.exports.check(20 * 65536 - 4, 1, 20); 110 ins.exports.check(20 * 65536, 1, 0); 111 assertThrowsInstanceOf( 112 () => ins.exports.check(28 * 65536 - 4, 2, 0), WebAssembly.RuntimeError); 113 114 assertEq(ins.exports.check(0, 10, 2), 1); 115 ins.exports.fill(0, 10, 5); 116 check(0, 10, 5); 117 118 // Try to resize JS way. 119 rab.grow(65536 * 30); 120 assertEq(rab.byteLength, 30 * 65536); 121 ins.exports.fill(30 * 65536 - 10*4, 10, 6); 122 check(30 * 65536 - 10 * 4, 10, 6); 123 124 // RAB#resize throws when trying to shrink or grow by non-page multiples 125 // for WebAssembly.Memory-vended RABs. 126 assertThrowsInstanceOf(() => rab.grow(rab.byteLength - 65536), RangeError); 127 assertThrowsInstanceOf(() => rab.grow(rab.byteLength + 10), RangeError);