tor-browser

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

current-memory-tls.js (2293B)


      1 // Bug 1341650:
      2 // - when compiled with Ion, pass the TLS register to memory.size;
      3 // - when compiled with Baseline, don't clobber the last stack slot when
      4 // calling into memory.size/memory.grow;
      5 
      6 // This toy module starts with an empty memory, then tries to set values at different
      7 // indexes, automatically growing memory when that would trigger an out of
      8 // bounds access, for the exact right amount of pages. Note it's not made for
      9 // efficiency, but optimizing it doesn't trigger the bugs mentioned above.
     10 
     11 let i = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`
     12 (module
     13    (memory $mem (export "mem") 0 65535)
     14 
     15    (func (export "cur_mem") (result i32) (memory.size))
     16 
     17    (func $maybeGrow (param $i i32) (local $smem i32)
     18     ;; get memory.size in number of bytes, not pages.
     19     memory.size
     20     i64.extend_i32_u
     21     i64.const 65536
     22     i64.mul
     23 
     24     ;; get the last byte index accessed by an int32 access.
     25     local.get $i
     26     i32.const 3
     27     i32.add
     28     local.tee $i
     29     i64.extend_i32_u
     30 
     31     ;; if the memory is too small, grow it.
     32     i64.le_u
     33     if
     34         ;; get the floor of the accessed *page* index.
     35         local.get $i
     36         i64.extend_i32_u
     37         i64.const 65536
     38         i64.div_u
     39 
     40         ;; subtract to that the size of the current memory in pages;
     41         ;; that's the amount of pages we want to grow, minus one.
     42         memory.size
     43         i64.extend_i32_u
     44 
     45         i64.sub
     46 
     47         ;; add 1 to that amount.
     48         i64.const 1
     49         i64.add
     50 
     51         ;; get back to i32 and grow memory.
     52         i32.wrap_i64
     53         memory.grow
     54         drop
     55     end
     56    )
     57 
     58    (func (export "set") (param $i i32) (param $v i32)
     59     local.get $i
     60     call $maybeGrow
     61     local.get $i
     62     local.get $v
     63     i32.store
     64    )
     65 
     66    (func (export "get") (param $i i32) (result i32)
     67     local.get $i
     68     i32.load
     69    )
     70 )
     71 `))).exports;
     72 
     73 assertEq(i.cur_mem(), 0);
     74 
     75 i.set(0, 1);
     76 assertEq(i.get(0), 1);
     77 
     78 assertEq(i.cur_mem(), 1);
     79 
     80 i.set(1234, 1);
     81 assertEq(i.get(1234), 1);
     82 
     83 assertEq(i.cur_mem(), 1);
     84 
     85 i.set(65532, 1);
     86 assertEq(i.get(65532), 1);
     87 
     88 assertErrorMessage(() => i.get(65533), WebAssembly.RuntimeError, /index out of bounds/);
     89 
     90 assertEq(i.cur_mem(), 1);
     91 
     92 i.set(65533, 1);
     93 assertEq(i.get(65533), 1);
     94 
     95 assertEq(i.cur_mem(), 2);