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