tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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);