diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c0cb35d4a8..e6bacc1966d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -297,21 +297,6 @@ else() # MSVC 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() - if("${CMAKE_BUILD_TYPE}" MATCHES "Release") # Extra check that cmake has set -O3 in its release flags. # This is really as an assertion that cmake is behaving as we expect. diff --git a/scripts/test/shared.py b/scripts/test/shared.py index 5b49475345b..74a83fcd3d2 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -195,7 +195,7 @@ def is_exe(fpath): which('gcc') or which('clang')) NATIVEXX = (os.environ.get('CXX') or which('mingw32-g++') or which('g++') or which('clang++')) -NODEJS = os.environ.get('NODE') or which('node') or which('nodejs') +NODEJS = os.environ.get('NODE') or os.environ.get('EMSDK_NODE') or which('node') or which('nodejs') MOZJS = which('mozjs') or which('spidermonkey') V8 = os.environ.get('V8') or which('v8') or which('d8') @@ -264,9 +264,8 @@ def has_shell_timeout(): try: if NODEJS is not None: - subprocess.check_call([NODEJS, '--version'], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + version = subprocess.check_output([NODEJS, '--version']) + print(f'Using node ({NODEJS}) version: {version.strip()}') except (OSError, subprocess.CalledProcessError): NODEJS = None if NODEJS is None: diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index bc16fe08db3..877b3f0aad5 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -2763,34 +2763,6 @@ void BinaryenConstSetValueI64(BinaryenExpressionRef expr, int64_t value) { assert(expression->is()); static_cast(expression)->value = Literal(value); } -int32_t BinaryenConstGetValueI64Low(BinaryenExpressionRef expr) { - auto* expression = (Expression*)expr; - assert(expression->is()); - return (int32_t)(static_cast(expression)->value.geti64() & - 0xffffffff); -} -void BinaryenConstSetValueI64Low(BinaryenExpressionRef expr, int32_t valueLow) { - auto* expression = (Expression*)expr; - assert(expression->is()); - auto& value = static_cast(expression)->value; - int64_t valueI64 = value.type == Type::i64 ? value.geti64() : 0; - static_cast(expression)->value = - Literal((valueI64 & ~0xffffffff) | (int64_t(valueLow) & 0xffffffff)); -} -int32_t BinaryenConstGetValueI64High(BinaryenExpressionRef expr) { - auto* expression = (Expression*)expr; - assert(expression->is()); - return (int32_t)(static_cast(expression)->value.geti64() >> 32); -} -void BinaryenConstSetValueI64High(BinaryenExpressionRef expr, - int32_t valueHigh) { - auto* expression = (Expression*)expr; - assert(expression->is()); - auto& value = static_cast(expression)->value; - int64_t valueI64 = value.type == Type::i64 ? value.geti64() : 0; - static_cast(expression)->value = - Literal((int64_t(valueHigh) << 32) | (valueI64 & 0xffffffff)); -} float BinaryenConstGetValueF32(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is()); diff --git a/src/binaryen-c.h b/src/binaryen-c.h index 48f0a4ffc3a..89468c611da 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -1614,20 +1614,6 @@ BINARYEN_API int64_t BinaryenConstGetValueI64(BinaryenExpressionRef expr); // Sets the 64-bit integer value of an `i64.const` expression. BINARYEN_API void BinaryenConstSetValueI64(BinaryenExpressionRef expr, int64_t value); -// Gets the low 32-bits of the 64-bit integer value of an `i64.const` -// expression. -BINARYEN_API int32_t BinaryenConstGetValueI64Low(BinaryenExpressionRef expr); -// Sets the low 32-bits of the 64-bit integer value of an `i64.const` -// expression. -BINARYEN_API void BinaryenConstSetValueI64Low(BinaryenExpressionRef expr, - int32_t valueLow); -// Gets the high 32-bits of the 64-bit integer value of an `i64.const` -// expression. -BINARYEN_API int32_t BinaryenConstGetValueI64High(BinaryenExpressionRef expr); -// Sets the high 32-bits of the 64-bit integer value of an `i64.const` -// expression. -BINARYEN_API void BinaryenConstSetValueI64High(BinaryenExpressionRef expr, - int32_t valueHigh); // Gets the 32-bit float value of a `f32.const` expression. BINARYEN_API float BinaryenConstGetValueF32(BinaryenExpressionRef expr); // Sets the 32-bit float value of a `f32.const` expression. diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index 1743c97388e..90c1b70cda1 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -1,3 +1,5 @@ +#preprocess + // export friendly API methods function preserveStack(func) { try { @@ -1090,10 +1092,17 @@ function wrapModule(module, self = {}) { 'store32'(offset, align, ptr, value, name) { return preserveStack(() => Module['_BinaryenStore'](module, 4, offset, align, ptr, value, Module['i64'], strToStack(name))); }, - 'const'(x, y) { + 'const'(x, y = undefined) { return preserveStack(() => { const tempLiteral = stackAlloc(sizeOfLiteral); +#if WASM_BIGINT + assert(typeof y == 'undefined', 'i64.const now take a single argument (which can be a bigint)'); + // We insert a cast to BigInt here in an attempt to be backwards + // compatible with callers to passed a single number here. + Module['_BinaryenLiteralInt64'](tempLiteral, BigInt(x)); +#else Module['_BinaryenLiteralInt64'](tempLiteral, x, y); +#endif return Module['_BinaryenConst'](module, tempLiteral); }); }, @@ -1507,10 +1516,15 @@ function wrapModule(module, self = {}) { return Module['_BinaryenConst'](module, tempLiteral); }); }, - 'const_bits'(x, y) { + 'const_bits'(x, y = undefined) { return preserveStack(() => { const tempLiteral = stackAlloc(sizeOfLiteral); +#if WASM_BIGINT + assert(typeof y == 'undefined', 'f64.const_bits now take a single argument (which can be a bigint)'); + Module['_BinaryenLiteralFloat64Bits'](tempLiteral, BigInt(x)); +#else Module['_BinaryenLiteralFloat64Bits'](tempLiteral, x, y); +#endif return Module['_BinaryenConst'](module, tempLiteral); }); }, @@ -3063,10 +3077,7 @@ Module['getExpressionInfo'] = function(expr) { case Module['ConstId']: switch (type) { case Module['i32']: info.value = Module['_BinaryenConstGetValueI32'](expr); break; - case Module['i64']: info.value = { - 'low': Module['_BinaryenConstGetValueI64Low'](expr), - 'high': Module['_BinaryenConstGetValueI64High'](expr) - }; break; + case Module['i64']: info.value = Module['_BinaryenConstGetValueI64'](expr); break; case Module['f32']: info.value = Module['_BinaryenConstGetValueF32'](expr); break; case Module['f64']: info.value = Module['_BinaryenConstGetValueF64'](expr); break; case Module['v128']: { @@ -3992,17 +4003,11 @@ Module['Const'] = makeExpressionWrapper(Module['_BinaryenConstId'](), { 'setValueI32'(expr, value) { Module['_BinaryenConstSetValueI32'](expr, value); }, - 'getValueI64Low'(expr) { - return Module['_BinaryenConstGetValueI64Low'](expr); - }, - 'setValueI64Low'(expr, value) { - Module['_BinaryenConstSetValueI64Low'](expr, value); - }, - 'getValueI64High'(expr) { - return Module['_BinaryenConstGetValueI64High'](expr); + 'getValueI64'(expr) { + return Module['_BinaryenConstGetValueI64'](expr); }, - 'setValueI64High'(expr, value) { - Module['_BinaryenConstSetValueI64High'](expr, value); + 'setValueI64'(expr, value) { + Module['_BinaryenConstSetValueI64'](expr, BigInt(value)); }, 'getValueF32'(expr) { return Module['_BinaryenConstGetValueF32'](expr); diff --git a/test/binaryen.js/expressions.js b/test/binaryen.js/expressions.js index c750047c85e..c0a23342e3e 100644 --- a/test/binaryen.js/expressions.js +++ b/test/binaryen.js/expressions.js @@ -832,17 +832,14 @@ console.log("# Const"); assert(info.type === theConst.type); assert(info.value === theConst.valueI32); - theConst.valueI64Low = 3; - assert(theConst.valueI64Low === 3); - theConst.valueI64High = 4; - assert(theConst.valueI64High === 4); + theConst.valueI64 = 3; + assert(theConst.valueI64 == 3); theConst.finalize(); assert(theConst.type == binaryen.i64); info = binaryen.getExpressionInfo(theConst); assert(info.type === theConst.type); - assert(info.value.low === theConst.valueI64Low); - assert(info.value.high === theConst.valueI64High); + assert(info.value === theConst.valueI64); theConst.valueF32 = 5; assert(theConst.valueF32 === 5); diff --git a/test/binaryen.js/kitchen-sink.js b/test/binaryen.js/kitchen-sink.js index 556749059b7..bf56da2798b 100644 --- a/test/binaryen.js/kitchen-sink.js +++ b/test/binaryen.js/kitchen-sink.js @@ -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) { @@ -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(0xffff1234_5678abcdn); var iIfF = binaryen.createType([binaryen.i32, binaryen.i64, binaryen.f32, binaryen.f64]) @@ -233,7 +233,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(-23)), module.i32.popcnt(module.i32.const(-10)), module.f32.neg(module.f32.const(-33.612)), module.f64.abs(module.f64.const(-9005.841)), @@ -245,7 +245,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(-23)), 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)), @@ -268,18 +268,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(-23)), + module.f64.convert_s.i64(module.i64.const(-23)), + module.f32.convert_u.i64(module.i64.const(-23)), + module.f64.convert_u.i64(module.i64.const(-23)), 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(-23)), 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(1_000_000_000_123n)), module.f32x4.splat(module.f32.const(42.0)), module.f64x2.splat(module.f64.const(42.0)), module.v128.not(module.v128.const(v128_bytes)), @@ -337,17 +337,17 @@ 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(-22), module.i64.const(-23)), + module.i64.rem_s(module.i64.const(-22), module.i64.const(-23)), 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(-22), module.i64.const(-23)), 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(-22), module.i64.const(-23)), + module.i64.shr_u(module.i64.const(-22), module.i64.const(-23)), 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(-22), module.i64.const(-23)), 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)), @@ -355,13 +355,13 @@ function test_core() { 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(-22), module.i64.const(-23)), + module.i64.le_s(module.i64.const(-22), module.i64.const(-23)), 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(-23), module.i64.const(-23)), 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(-22), module.i64.const(-23)), 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)), @@ -506,7 +506,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(42)), 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 @@ -698,15 +698,24 @@ 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(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)))); + function infoToString(info) { + // BigInt values cannot be pass through JSON.stringify so convert + // them to strings first. + if (typeof info.value === 'bigint') { + info.value = info.value.toString(); + } + return JSON.stringify(info); + } + + console.log("getExpressionInfo(i32.const)=" + infoToString(binaryen.getExpressionInfo(module.i32.const(5)))); + console.log("getExpressionInfo(i64.const)=" + infoToString(binaryen.getExpressionInfo(module.i64.const(6)))); + console.log("getExpressionInfo(f32.const)=" + infoToString(binaryen.getExpressionInfo(module.f32.const(8.5)))); + console.log("getExpressionInfo(f64.const)=" + infoToString(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) ]) ).operands; for (var i = 0; i < elements.length; i++) { - console.log("getExpressionInfo(tuple[" + i + "])=" + JSON.stringify(binaryen.getExpressionInfo(elements[i]))); + console.log("getExpressionInfo(tuple[" + i + "])=" + infoToString(binaryen.getExpressionInfo(elements[i]))); } // Make the main body of the function. and one block with a return value, one without diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt index 2802300c194..edae36a1435 100644 --- a/test/binaryen.js/kitchen-sink.js.txt +++ b/test/binaryen.js/kitchen-sink.js.txt @@ -117,11 +117,11 @@ getExpressionInfo={"id":15,"type":4,"op":6} ) getExpressionInfo(i32.const)={"id":14,"type":2,"value":5} -getExpressionInfo(i64.const)={"id":14,"type":3,"value":{"low":6,"high":7}} +getExpressionInfo(i64.const)={"id":14,"type":3,"value":"6"} getExpressionInfo(f32.const)={"id":14,"type":4,"value":8.5} getExpressionInfo(f64.const)={"id":14,"type":5,"value":9.5} getExpressionInfo(tuple[0])={"id":14,"type":2,"value":13} -getExpressionInfo(tuple[1])={"id":14,"type":3,"value":{"low":37,"high":0}} +getExpressionInfo(tuple[1])={"id":14,"type":3,"value":"37"} getExpressionInfo(tuple[2])={"id":14,"type":4,"value":1.2999999523162842} getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} (module @@ -162,7 +162,7 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} ) (drop (i64.ctz - (i64.const -22) + (i64.const -23) ) ) (drop @@ -222,7 +222,7 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} ) (drop (i32.wrap_i64 - (i64.const -22) + (i64.const -23) ) ) (drop @@ -337,22 +337,22 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} ) (drop (f32.convert_i64_s - (i64.const -22) + (i64.const -23) ) ) (drop (f64.convert_i64_s - (i64.const -22) + (i64.const -23) ) ) (drop (f32.convert_i64_u - (i64.const -22) + (i64.const -23) ) ) (drop (f64.convert_i64_u - (i64.const -22) + (i64.const -23) ) ) (drop @@ -372,7 +372,7 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} ) (drop (f64.reinterpret_i64 - (i64.const -22) + (i64.const -23) ) ) (drop @@ -392,7 +392,7 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} ) (drop (i64x2.splat - (i64.const 1958505087099) + (i64.const 1000000000123) ) ) (drop @@ -680,14 +680,14 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} ) (drop (i64.div_u - (i64.const 4294967274) - (i64.const 4294967273) + (i64.const -22) + (i64.const -23) ) ) (drop (i64.rem_s - (i64.const 4294967274) - (i64.const 4294967273) + (i64.const -22) + (i64.const -23) ) ) (drop @@ -704,8 +704,8 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} ) (drop (i64.or - (i64.const 4294967274) - (i64.const 4294967273) + (i64.const -22) + (i64.const -23) ) ) (drop @@ -716,14 +716,14 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} ) (drop (i64.shl - (i64.const 4294967274) - (i64.const 4294967273) + (i64.const -22) + (i64.const -23) ) ) (drop (i64.shr_u - (i64.const 4294967274) - (i64.const 4294967273) + (i64.const -22) + (i64.const -23) ) ) (drop @@ -740,8 +740,8 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} ) (drop (i64.rotr - (i64.const 4294967274) - (i64.const 4294967273) + (i64.const -22) + (i64.const -23) ) ) (drop @@ -788,14 +788,14 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} ) (drop (i64.lt_u - (i64.const 4294967274) - (i64.const 4294967273) + (i64.const -22) + (i64.const -23) ) ) (drop (i64.le_s - (i64.const 4294967274) - (i64.const 4294967273) + (i64.const -22) + (i64.const -23) ) ) (drop @@ -806,8 +806,8 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} ) (drop (i64.gt_s - (i64.const 4294967274) - (i64.const 4294967273) + (i64.const -23) + (i64.const -23) ) ) (drop @@ -824,8 +824,8 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} ) (drop (i64.ge_u - (i64.const 4294967274) - (i64.const 4294967273) + (i64.const -22) + (i64.const -23) ) ) (drop @@ -1673,7 +1673,7 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} (drop (i64x2.replace_lane 1 (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) - (i64.const 184683593770) + (i64.const 42) ) ) (drop