tor-browser

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

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;