Skip to content

Commit

Permalink
Enable BigInt for binaryen.js
Browse files Browse the repository at this point in the history
We previously had a build option for enabling BigInt support when
compiling with Emscripten, but the test suite did not actually pass with
it enabled. The problem was that the binaryen.js glue code assumed that
C API functions that took i64 parameters would be transformed to take a
pair of i32 parameters instead, but this assumption was incorrect when
BigInt support was enabled.

Emscripten has now enabled BigInt by default, so update binaryen.js to
use BigInt as well. Fix the JS API glue code to pass i64s as BigInts
rather than pairs of numbers and fix the tests accordingly. Also fix
some other small problems with the tests that only show up in debug
builds.

Resolves #7163.
  • Loading branch information
tlively committed Dec 20, 2024
1 parent dcec348 commit 2bd1fb6
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 51 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ full changeset diff at the end of each section.
Current Trunk
-------------

- Binaryen.js now builds with BigInt support. The i64.const and f64.const_bits
functions now take BigInt parameters rather than pairs of numbers.

v121
----

Expand Down
17 changes: 3 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -326,20 +326,9 @@ else()
endif()

if(EMSCRIPTEN)
# Note: to debug with DWARF you will usually want to enable BIGINT support, as
# that helps avoid running Binaryen on the wasm after link. Binaryen's DWARF
# rewriting has known limitations, so avoiding it during link is recommended
# where possible (like local debugging).
#
# Note that this is debug info for Binaryen itself, that is, when you are
# debugging Binaryen source code. This flag has no impact on what Binaryen
# does when run on wasm files.
option(ENABLE_BIGINT "Enable wasm BigInt support" OFF)
if(ENABLE_BIGINT)
add_link_flag("-sWASM_BIGINT")
else()
add_link_flag("-sWASM_BIGINT=0")
endif()
# This is now on by default in Emscripten, but set it explicitly to continue
# building correctly on older Emscriptens.
add_link_flag("-sWASM_BIGINT")

if("${CMAKE_BUILD_TYPE}" MATCHES "Release")
# Extra check that cmake has set -O3 in its release flags.
Expand Down
8 changes: 4 additions & 4 deletions src/js/binaryen.js-post.js
Original file line number Diff line number Diff line change
Expand Up @@ -1049,10 +1049,10 @@ function wrapModule(module, self = {}) {
'store32'(offset, align, ptr, value, name) {
return Module['_BinaryenStore'](module, 4, offset, align, ptr, value, Module['i64'], strToStack(name));
},
'const'(x, y) {
'const'(x) {
return preserveStack(() => {
const tempLiteral = stackAlloc(sizeOfLiteral);
Module['_BinaryenLiteralInt64'](tempLiteral, x, y);
Module['_BinaryenLiteralInt64'](tempLiteral, BigInt(x));
return Module['_BinaryenConst'](module, tempLiteral);
});
},
Expand Down Expand Up @@ -1438,10 +1438,10 @@ function wrapModule(module, self = {}) {
return Module['_BinaryenConst'](module, tempLiteral);
});
},
'const_bits'(x, y) {
'const_bits'(x) {
return preserveStack(() => {
const tempLiteral = stackAlloc(sizeOfLiteral);
Module['_BinaryenLiteralFloat64Bits'](tempLiteral, x, y);
Module['_BinaryenLiteralFloat64Bits'](tempLiteral, BigInt(x));
return Module['_BinaryenConst'](module, tempLiteral);
});
},
Expand Down
62 changes: 31 additions & 31 deletions test/binaryen.js/kitchen-sink.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ function makeFloat32(x) {
return module.f32.const(x);
}

function makeInt64(l, h) {
return module.i64.const(l, h);
function makeInt64(x) {
return module.i64.const(x);
}

function makeFloat64(x) {
Expand Down Expand Up @@ -214,7 +214,7 @@ function test_core() {
constF32 = module.f32.const(3.14),
constF64 = module.f64.const(2.1828),
constF32Bits = module.f32.const_bits(0xffff1234),
constF64Bits = module.f64.const_bits(0x5678abcd, 0xffff1234);
constF64Bits = module.f64.const_bits(0xffff12345678ABCDn)

var iIfF = binaryen.createType([binaryen.i32, binaryen.i64, binaryen.f32, binaryen.f64])

Expand All @@ -229,7 +229,7 @@ function test_core() {
var valueList = [
// Unary
module.i32.clz(module.i32.const(-10)),
module.i64.ctz(module.i64.const(-22, -1)),
module.i64.ctz(module.i64.const(295147905179352825834n)),
module.i32.popcnt(module.i32.const(-10)),
module.f32.neg(module.f32.const(-33.612)),
module.f64.abs(module.f64.const(-9005.841)),
Expand All @@ -241,7 +241,7 @@ function test_core() {
module.i32.eqz(module.i32.const(-10)),
module.i64.extend_s(module.i32.const(-10)),
module.i64.extend_u(module.i32.const(-10)),
module.i32.wrap(module.i64.const(-22, -1)),
module.i32.wrap(module.i64.const(295147905179352825834n)),
module.i32.trunc_s.f32(module.f32.const(-33.612)),
module.i64.trunc_s.f32(module.f32.const(-33.612)),
module.i32.trunc_u.f32(module.f32.const(-33.612)),
Expand All @@ -264,18 +264,18 @@ function test_core() {
module.f64.convert_s.i32(module.i32.const(-10)),
module.f32.convert_u.i32(module.i32.const(-10)),
module.f64.convert_u.i32(module.i32.const(-10)),
module.f32.convert_s.i64(module.i64.const(-22, -1)),
module.f64.convert_s.i64(module.i64.const(-22, -1)),
module.f32.convert_u.i64(module.i64.const(-22, -1)),
module.f64.convert_u.i64(module.i64.const(-22, -1)),
module.f32.convert_s.i64(module.i64.const(295147905179352825834n)),
module.f64.convert_s.i64(module.i64.const(295147905179352825834n)),
module.f32.convert_u.i64(module.i64.const(295147905179352825834n)),
module.f64.convert_u.i64(module.i64.const(295147905179352825834n)),
module.f64.promote(module.f32.const(-33.612)),
module.f32.demote(module.f64.const(-9005.841)),
module.f32.reinterpret(module.i32.const(-10)),
module.f64.reinterpret(module.i64.const(-22, -1)),
module.f64.reinterpret(module.i64.const(295147905179352825834n)),
module.i8x16.splat(module.i32.const(42)),
module.i16x8.splat(module.i32.const(42)),
module.i32x4.splat(module.i32.const(42)),
module.i64x2.splat(module.i64.const(123, 456)),
module.i64x2.splat(module.i64.const(1958505087099n)),
module.f32x4.splat(module.f32.const(42.0)),
module.f64x2.splat(module.f64.const(42.0)),
module.v128.not(module.v128.const(v128_bytes)),
Expand Down Expand Up @@ -333,31 +333,31 @@ function test_core() {
module.i32.add(module.i32.const(-10), module.i32.const(-11)),
module.f64.sub(module.f64.const(-9005.841), module.f64.const(-9007.333)),
module.i32.div_s(module.i32.const(-10), module.i32.const(-11)),
module.i64.div_u(module.i64.const(-22, 0), module.i64.const(-23, 0)),
module.i64.rem_s(module.i64.const(-22, 0), module.i64.const(-23, 0)),
module.i64.div_u(module.i64.const(4294967274n), module.i64.const(4294967273n)),
module.i64.rem_s(module.i64.const(4294967274n), module.i64.const(4294967273n)),
module.i32.rem_u(module.i32.const(-10), module.i32.const(-11)),
module.i32.and(module.i32.const(-10), module.i32.const(-11)),
module.i64.or(module.i64.const(-22, 0), module.i64.const(-23, 0)),
module.i64.or(module.i64.const(4294967274n), module.i64.const(4294967273n)),
module.i32.xor(module.i32.const(-10), module.i32.const(-11)),
module.i64.shl(module.i64.const(-22, 0), module.i64.const(-23, 0)),
module.i64.shr_u(module.i64.const(-22, 0), module.i64.const(-23, 0)),
module.i64.shl(module.i64.const(4294967274n), module.i64.const(4294967273n)),
module.i64.shr_u(module.i64.const(4294967274n), module.i64.const(4294967273n)),
module.i32.shr_s(module.i32.const(-10), module.i32.const(-11)),
module.i32.rotl(module.i32.const(-10), module.i32.const(-11)),
module.i64.rotr(module.i64.const(-22, 0), module.i64.const(-23, 0)),
module.i64.rotr(module.i64.const(4294967274n), module.i64.const(4294967273n)),
module.f32.div(module.f32.const(-33.612), module.f32.const(-62.5)),
module.f64.copysign(module.f64.const(-9005.841), module.f64.const(-9007.333)),
module.f32.min(module.f32.const(-33.612), module.f32.const(-62.5)),
module.f64.max(module.f64.const(-9005.841), module.f64.const(-9007.333)),
module.i32.eq(module.i32.const(-10), module.i32.const(-11)),
module.f32.ne(module.f32.const(-33.612), module.f32.const(-62.5)),
module.i32.lt_s(module.i32.const(-10), module.i32.const(-11)),
module.i64.lt_u(module.i64.const(-22, 0), module.i64.const(-23, 0)),
module.i64.le_s(module.i64.const(-22, 0), module.i64.const(-23, 0)),
module.i64.lt_u(module.i64.const(4294967274n), module.i64.const(4294967273n)),
module.i64.le_s(module.i64.const(4294967274n), module.i64.const(4294967273n)),
module.i32.le_u(module.i32.const(-10), module.i32.const(-11)),
module.i64.gt_s(module.i64.const(-22, 0), module.i64.const(-23, 0)),
module.i64.gt_s(module.i64.const(4294967274n), module.i64.const(4294967273n)),
module.i32.gt_u(module.i32.const(-10), module.i32.const(-11)),
module.i32.ge_s(module.i32.const(-10), module.i32.const(-11)),
module.i64.ge_u(module.i64.const(-22, 0), module.i64.const(-23, 0)),
module.i64.ge_u(module.i64.const(4294967274n), module.i64.const(4294967273n)),
module.f32.lt(module.f32.const(-33.612), module.f32.const(-62.5)),
module.f64.le(module.f64.const(-9005.841), module.f64.const(-9007.333)),
module.f64.gt(module.f64.const(-9005.841), module.f64.const(-9007.333)),
Expand Down Expand Up @@ -502,7 +502,7 @@ function test_core() {
module.i16x8.replace_lane(module.v128.const(v128_bytes), 1, module.i32.const(42)),
module.i8x16.replace_lane(module.v128.const(v128_bytes), 1, module.i32.const(42)),
module.i32x4.replace_lane(module.v128.const(v128_bytes), 1, module.i32.const(42)),
module.i64x2.replace_lane(module.v128.const(v128_bytes), 1, module.i64.const(42, 43)),
module.i64x2.replace_lane(module.v128.const(v128_bytes), 1, module.i64.const(184683593770n)),
module.f32x4.replace_lane(module.v128.const(v128_bytes), 1, module.f32.const(42)),
module.f64x2.replace_lane(module.v128.const(v128_bytes), 1, module.f64.const(42)),
// SIMD shift
Expand Down Expand Up @@ -569,15 +569,15 @@ function test_core() {
module.switch([ "the-value" ], "the-value", temp8, temp9),
module.switch([ "the-nothing" ], "the-nothing", makeInt32(2)),
module.i32.eqz( // check the output type of the call node
module.call("kitchen()sinker", [ makeInt32(13), makeInt64(37, 0), makeFloat32(1.3), makeFloat64(3.7) ], binaryen.i32)
module.call("kitchen()sinker", [ makeInt32(13), makeInt64(37), makeFloat32(1.3), makeFloat64(3.7) ], binaryen.i32)
),
module.i32.eqz( // check the output type of the call node
module.i32.trunc_s.f32(
module.call("an-imported", [ makeInt32(13), makeFloat64(3.7) ], binaryen.f32)
)
),
module.i32.eqz( // check the output type of the call node
module.call_indirect("t0", makeInt32(2449), [ makeInt32(13), makeInt64(37, 0), makeFloat32(1.3), makeFloat64(3.7) ], iIfF, binaryen.i32)
module.call_indirect("t0", makeInt32(2449), [ makeInt32(13), makeInt64(37), makeFloat32(1.3), makeFloat64(3.7) ], iIfF, binaryen.i32)
),
module.drop(module.local.get(0, binaryen.i32)),
module.local.set(0, makeInt32(101)),
Expand All @@ -591,8 +591,8 @@ function test_core() {
module.select(temp10, temp11, temp12),
module.return(makeInt32(1337)),
// Tail Call
module.return_call("kitchen()sinker", [ makeInt32(13), makeInt64(37, 0), makeFloat32(1.3), makeFloat64(3.7) ], binaryen.i32),
module.return_call_indirect("t0", makeInt32(2449), [ makeInt32(13), makeInt64(37, 0), makeFloat32(1.3), makeFloat64(3.7) ], iIfF, binaryen.i32),
module.return_call("kitchen()sinker", [ makeInt32(13), makeInt64(37), makeFloat32(1.3), makeFloat64(3.7) ], binaryen.i32),
module.return_call_indirect("t0", makeInt32(2449), [ makeInt32(13), makeInt64(37), makeFloat32(1.3), makeFloat64(3.7) ], iIfF, binaryen.i32),

// Reference types
module.ref.is_null(module.ref.null(binaryen.externref)),
Expand Down Expand Up @@ -636,11 +636,11 @@ function test_core() {

// Tuples
module.tuple.make(
[ makeInt32(13), makeInt64(37, 0), makeFloat32(1.3), makeFloat64(3.7) ]
[ makeInt32(13), makeInt64(37), makeFloat32(1.3), makeFloat64(3.7) ]
),
module.tuple.extract(
module.tuple.make(
[ makeInt32(13), makeInt64(37, 0), makeFloat32(1.3), makeFloat64(3.7) ]
[ makeInt32(13), makeInt64(37), makeFloat32(1.3), makeFloat64(3.7) ]
), 2
),

Expand Down Expand Up @@ -695,11 +695,11 @@ function test_core() {
}

console.log("getExpressionInfo(i32.const)=" + JSON.stringify(binaryen.getExpressionInfo(module.i32.const(5))));
console.log("getExpressionInfo(i64.const)=" + JSON.stringify(binaryen.getExpressionInfo(module.i64.const(6, 7))));
console.log("getExpressionInfo(i64.const)=" + JSON.stringify(binaryen.getExpressionInfo(module.i64.const(30064771078n))));
console.log("getExpressionInfo(f32.const)=" + JSON.stringify(binaryen.getExpressionInfo(module.f32.const(8.5))));
console.log("getExpressionInfo(f64.const)=" + JSON.stringify(binaryen.getExpressionInfo(module.f64.const(9.5))));
var elements = binaryen.getExpressionInfo(
module.tuple.make([ makeInt32(13), makeInt64(37, 0), makeFloat32(1.3), makeFloat64(3.7) ])
module.tuple.make([ makeInt32(13), makeInt64(37), makeFloat32(1.3), makeFloat64(3.7) ])
).operands;
for (var i = 0; i < elements.length; i++) {
console.log("getExpressionInfo(tuple[" + i + "])=" + JSON.stringify(binaryen.getExpressionInfo(elements[i])));
Expand Down Expand Up @@ -1018,7 +1018,7 @@ function test_nonvalid() {
module = new binaryen.Module();

var func = module.addFunction("func", binaryen.none, binaryen.none, [ binaryen.i32 ],
module.local.set(0, makeInt64(1234, 0)) // wrong type!
module.local.set(0, makeInt64(1234)) // wrong type!
);

console.log(module.emitText());
Expand Down
4 changes: 2 additions & 2 deletions test/binaryen.js/validation_errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
)
])
);
mod.addExport("test", func);
mod.addExport("test", "test");
console.log(mod.validate())
})();

Expand All @@ -20,6 +20,6 @@
)
])
);
mod.addFunctionExport("test", "test", func);
mod.addFunctionExport("test", "test");
console.log(mod.validate())
})();

0 comments on commit 2bd1fb6

Please sign in to comment.