tor-browser

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

from-int32.js (2611B)


      1 // Int32 values, including minimum, maximum, and values around zero.
      2 const values = [
      3  [0x8000_0000|0, -0x80000000n],
      4  [0x8000_0001|0, -0x7fffffffn],
      5  [0x8000_0002|0, -0x7ffffffen],
      6  [0x8000_0003|0, -0x7ffffffdn],
      7  [-3, -3n],
      8  [-2, -2n],
      9  [-1, -1n],
     10  [0, 0n],
     11  [1, 1n],
     12  [2, 2n],
     13  [3, 3n],
     14  [0x7fff_fffd, 0x7fff_fffdn],
     15  [0x7fff_fffe, 0x7fff_fffen],
     16  [0x7fff_ffff, 0x7fff_ffffn],
     17 ];
     18 
     19 const m = new WebAssembly.Module(wasmTextToBinary(`(module
     20  (func (export "toInt32") (param i64) (result i32)
     21    local.get 0
     22    i32.wrap_i64
     23  )
     24  (func (export "toInt64") (param i64) (result i64)
     25    local.get 0
     26  )
     27 )`));
     28 
     29 const {
     30  toInt32,
     31  toInt64,
     32 } = new WebAssembly.Instance(m).exports;
     33 
     34 function testSimple() {
     35  for (let i = 0; i < 1000; ++i) {
     36    let vals = values[i % values.length];
     37 
     38    assertEq(toInt32(BigInt(vals[0])), vals[0]);
     39    assertEq(toInt64(BigInt(vals[0])), vals[1]);
     40  }
     41 }
     42 testSimple();
     43 
     44 function testBoxed() {
     45  for (let i = 0; i < 1000; ++i) {
     46    let vals = values[i % values.length];
     47 
     48    // NB: The parser can only fold `if (true) { ... }`. Using an explicit
     49    // variable ensures that only GVN will fold the test-condition.
     50    const True = true;
     51 
     52    // Conditionally set |bi| to create a phi-value. MToInt64's type policy will
     53    // see a boxed input and therefore not apply MTruncateBigIntToInt64.
     54    //
     55    // Later let GVN simplify MToInt64(MInt32ToBigInt(i32)) to just
     56    // MExtendInt32ToInt64(i32).
     57    //
     58    // MBox(MInt32ToBigInt(i32)) is captured by a resume point, so we can't
     59    // recover MInt32ToBigInt(i32), because MBox is not recoverable.
     60    let bi = undefined;
     61    if (True) {
     62      bi = BigInt(vals[0]);
     63    }
     64 
     65    assertEq(toInt32(bi), vals[0]);
     66    assertEq(toInt64(bi), vals[1]);
     67  }
     68 }
     69 testBoxed();
     70 
     71 function testRecover() {
     72  for (let i = 0; i < 1000; ++i) {
     73    let vals = values[i % values.length];
     74 
     75    // NB: The parser can only fold `if (true) { ... }`. Using an explicit
     76    // variable ensures that only GVN will fold the test-condition.
     77    const True = true;
     78 
     79    // Conditionally set |bi| to create a phi-value. MToInt64's type policy will
     80    // see a BigInt input and therefore apply MTruncateBigIntToInt64.
     81    //
     82    // Later let GVN simplify MTruncateBigIntToInt64(MInt32ToBigInt(i32)) to
     83    // just MExtendInt32ToInt64(i32).
     84    //
     85    // MInt32ToBigInt(i32) is captured by a resume point, but since
     86    // MInt32ToBigInt is recoverable, it will be optimized away.
     87    let bi = 0n;
     88    if (True) {
     89      bi = BigInt(vals[0]);
     90    }
     91 
     92    assertEq(toInt32(bi), vals[0]);
     93    assertEq(toInt64(bi), vals[1]);
     94  }
     95 }
     96 testRecover();