Source code
Revision control
Copy as Markdown
Other Tools
// Int32 values, including minimum, maximum, and values around zero.
const values = [
[0x8000_0000|0, -0x80000000n],
[0x8000_0001|0, -0x7fffffffn],
[0x8000_0002|0, -0x7ffffffen],
[0x8000_0003|0, -0x7ffffffdn],
[-3, -3n],
[-2, -2n],
[-1, -1n],
[0, 0n],
[1, 1n],
[2, 2n],
[3, 3n],
[0x7fff_fffd, 0x7fff_fffdn],
[0x7fff_fffe, 0x7fff_fffen],
[0x7fff_ffff, 0x7fff_ffffn],
];
const m = new WebAssembly.Module(wasmTextToBinary(`(module
(func (export "toInt32") (param i64) (result i32)
local.get 0
i32.wrap_i64
)
(func (export "toInt64") (param i64) (result i64)
local.get 0
)
)`));
const {
toInt32,
toInt64,
} = new WebAssembly.Instance(m).exports;
function testSimple() {
for (let i = 0; i < 1000; ++i) {
let vals = values[i % values.length];
assertEq(toInt32(BigInt(vals[0])), vals[0]);
assertEq(toInt64(BigInt(vals[0])), vals[1]);
}
}
testSimple();
function testBoxed() {
for (let i = 0; i < 1000; ++i) {
let vals = values[i % values.length];
// NB: The parser can only fold `if (true) { ... }`. Using an explicit
// variable ensures that only GVN will fold the test-condition.
const True = true;
// Conditionally set |bi| to create a phi-value. MToInt64's type policy will
// see a boxed input and therefore not apply MTruncateBigIntToInt64.
//
// Later let GVN simplify MToInt64(MInt32ToBigInt(i32)) to just
// MExtendInt32ToInt64(i32).
//
// MBox(MInt32ToBigInt(i32)) is captured by a resume point, so we can't
// recover MInt32ToBigInt(i32), because MBox is not recoverable.
let bi = undefined;
if (True) {
bi = BigInt(vals[0]);
}
assertEq(toInt32(bi), vals[0]);
assertEq(toInt64(bi), vals[1]);
}
}
testBoxed();
function testRecover() {
for (let i = 0; i < 1000; ++i) {
let vals = values[i % values.length];
// NB: The parser can only fold `if (true) { ... }`. Using an explicit
// variable ensures that only GVN will fold the test-condition.
const True = true;
// Conditionally set |bi| to create a phi-value. MToInt64's type policy will
// see a BigInt input and therefore apply MTruncateBigIntToInt64.
//
// Later let GVN simplify MTruncateBigIntToInt64(MInt32ToBigInt(i32)) to
// just MExtendInt32ToInt64(i32).
//
// MInt32ToBigInt(i32) is captured by a resume point, but since
// MInt32ToBigInt is recoverable, it will be optimized away.
let bi = 0n;
if (True) {
bi = BigInt(vals[0]);
}
assertEq(toInt32(bi), vals[0]);
assertEq(toInt64(bi), vals[1]);
}
}
testRecover();