From 7fcfbf05d969e10857122c7c59acb6e7724dcf37 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Thu, 8 May 2025 14:21:15 +0100 Subject: [PATCH 01/10] Add failing test for 64-bit Embind limits --- test/embind/test_i64_binding.cpp | 77 +++++++++++++++----------------- 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/test/embind/test_i64_binding.cpp b/test/embind/test_i64_binding.cpp index f4b51fa4bdfbb..6d7bfefb99cbe 100644 --- a/test/embind/test_i64_binding.cpp +++ b/test/embind/test_i64_binding.cpp @@ -13,60 +13,57 @@ using namespace emscripten; using namespace std; -#define assert_js(X) assert(run_js(X)) +#define assert_js_eq(X, Y) run_js(string("const x = ") + X + ", y = " + Y + "; assert(x === y, `" + X + ": actual = ${x}, expected = ${y}`);") void test(string message) { cout << "test:\n" << message << "\n"; } - -void execute_js(string js_code) -{ - js_code.append(";"); - const char* js_code_pointer = js_code.c_str(); - EM_ASM_INT({ - var js_code = UTF8ToString($0); - return eval(js_code); - }, js_code_pointer); -} - int run_js(string js_code) { - js_code.append(";"); - const char* js_code_pointer = js_code.c_str(); - return EM_ASM_INT({ - var js_code = UTF8ToString($0); - return eval(js_code); - }, js_code_pointer); + return emscripten_run_script_int(js_code.c_str()); } EMSCRIPTEN_BINDINGS(tests) { + emscripten::function("int64_min", &numeric_limits::min); + emscripten::function("int64_max", &numeric_limits::max); + emscripten::function("uint64_max", &numeric_limits::max); + register_vector("Int64Vector"); register_vector("UInt64Vector"); } extern "C" void ensure_js_throws_with_assertions_enabled(const char* js_code, const char* error_type); +// Checks that the given value has correctly preserved value and sign. +template +void assert_bigint_preserved(T value) { + val::global().set("bigint", value); + assert_js_eq("bigint", to_string(value) + "n"); +} + int main() { - const int64_t max_int64_t = numeric_limits::max(); - const int64_t min_int64_t = numeric_limits::min(); - const uint64_t max_uint64_t = numeric_limits::max(); + test("limits"); + + assert_js_eq("Module.int64_min()", to_string(numeric_limits::min()) + "n"); + assert_js_eq("Module.int64_max()", to_string(numeric_limits::max()) + "n"); + assert_js_eq("Module.uint64_max()", to_string(numeric_limits::max()) + "n"); printf("start\n"); test("vector"); val myval(std::vector{1, 2, 3, -4}); val::global().set("v64", myval); - assert_js("v64.get(0) === 1n"); - assert_js("v64.get(1) === 2n"); - assert_js("v64.get(2) === 3n"); - assert_js("v64.get(3) === -4n"); + assert_js_eq("v64.get(0)", "1n"); + assert_js_eq("v64.get(1)", "2n"); + assert_js_eq("v64.get(2)", "3n"); + assert_js_eq("v64.get(3)", "-4n"); - execute_js("v64.push_back(1234n)"); - assert_js("v64.size() === 5"); - assert_js("v64.get(4) === 1234n"); + run_js("v64.push_back(1234n)"); + assert_js_eq("v64.size()", "5"); + assert_js_eq("v64.get(4)", "1234n"); test("vector Cannot convert bigint that is too big"); ensure_js_throws_with_assertions_enabled("v64.push_back(12345678901234567890123456n)", "TypeError"); @@ -74,18 +71,18 @@ int main() test("vector"); val myval2(vector{1, 2, 3, 4}); val::global().set("vU64", myval2); - assert_js("vU64.get(0) === 1n"); - assert_js("vU64.get(1) === 2n"); - assert_js("vU64.get(2) === 3n"); - assert_js("vU64.get(3) === 4n"); - - execute_js("vU64.push_back(1234n)"); - assert_js("vU64.size() === 5"); - assert_js("vU64.get(4) === 1234n"); - - execute_js("vU64.push_back(1234)"); - assert_js("vU64.size() === 6"); - assert_js("vU64.get(5) === 1234n"); + assert_js_eq("vU64.get(0)", "1n"); + assert_js_eq("vU64.get(1)", "2n"); + assert_js_eq("vU64.get(2)", "3n"); + assert_js_eq("vU64.get(3)", "4n"); + + run_js("vU64.push_back(1234n)"); + assert_js_eq("vU64.size()", "5"); + assert_js_eq("vU64.get(4)", "1234n"); + + run_js("vU64.push_back(1234)"); + assert_js_eq("vU64.size()", "6"); + assert_js_eq("vU64.get(5)", "1234n"); test("vector Cannot convert bigint that is too big"); ensure_js_throws_with_assertions_enabled("vU64.push_back(12345678901234567890123456n)", "TypeError"); From ac8a2d13e7cdc889d7eaeecac1af1c2b099ac72c Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Thu, 8 May 2025 14:31:04 +0100 Subject: [PATCH 02/10] Fix handling of 64-bit unsigned integers --- src/lib/libembind.js | 76 +++++++++++++++----------------- system/lib/embind/bind.cpp | 7 --- test/embind/test_i64_binding.cpp | 2 +- test/embind/test_i64_binding.out | 2 + 4 files changed, 39 insertions(+), 48 deletions(-) diff --git a/src/lib/libembind.js b/src/lib/libembind.js index 1fd2879990ecf..46b7735d8f01b 100644 --- a/src/lib/libembind.js +++ b/src/lib/libembind.js @@ -329,48 +329,32 @@ var LibraryEmbind = { ], _embind_register_integer: (primitiveType, name, size, minRange, maxRange) => { name = readLatin1String(name); - // LLVM doesn't have signed and unsigned 32-bit types, so u32 literals come - // out as 'i32 -1'. Always treat those as max u32. - if (maxRange === -1) { - maxRange = 4294967295; - } - var fromWireType = (value) => value; + const isUnsignedType = maxRange < minRange; - if (minRange === 0) { + let fromWireType = (value) => value; + if (isUnsignedType) { var bitshift = 32 - 8*size; fromWireType = (value) => (value << bitshift) >>> bitshift; + maxRange = fromWireType(maxRange); } - var isUnsignedType = (name.includes('unsigned')); - var checkAssertions = (value, toTypeName) => { + registerType(primitiveType, { + name, + 'fromWireType': fromWireType, + 'toWireType': (destructors, value) => { #if ASSERTIONS - if (typeof value != "number" && typeof value != "boolean") { - throw new TypeError(`Cannot convert "${embindRepr(value)}" to ${toTypeName}`); - } - if (value < minRange || value > maxRange) { - throw new TypeError(`Passing a number "${embindRepr(value)}" from JS side to C/C++ side to an argument of type "${name}", which is outside the valid range [${minRange}, ${maxRange}]!`); - } -#endif - } - var toWireType; - if (isUnsignedType) { - toWireType = function(destructors, value) { - checkAssertions(value, this.name); - return value >>> 0; - } - } else { - toWireType = function(destructors, value) { - checkAssertions(value, this.name); + if (typeof value != "number" && typeof value != "boolean") { + throw new TypeError(`Cannot convert "${embindRepr(value)}" to ${toTypeName}`); + } + if (value < minRange || value > maxRange) { + throw new TypeError(`Passing a number "${embindRepr(value)}" from JS side to C/C++ side to an argument of type "${name}", which is outside the valid range [${minRange}, ${maxRange}]!`); + } + #endif // The VM will perform JS to Wasm value conversion, according to the spec: // https://www.w3.org/TR/wasm-js-api-1/#towebassemblyvalue return value; - } - } - registerType(primitiveType, { - name, - 'fromWireType': fromWireType, - 'toWireType': toWireType, + }, argPackAdvance: GenericWireTypeSize, 'readValueFromPointer': integerReadValueFromPointer(name, size, minRange !== 0), destructorFunction: null, // This type does not need a destructor @@ -384,24 +368,36 @@ var LibraryEmbind = { _embind_register_bigint: (primitiveType, name, size, minRange, maxRange) => { name = readLatin1String(name); - var isUnsignedType = (name.indexOf('u') != -1); + const isUnsignedType = maxRange < minRange; - // maxRange comes through as -1 for uint64_t (see issue 13902). Work around that temporarily + let fromWireType = (value) => value; if (isUnsignedType) { - maxRange = (1n << 64n) - 1n; + // uint64 get converted to int64 in ABI, fix them up like we do for 32-bit integers. + const bitSize = size * 8; + fromWireType = (value) => { +#if MEMORY64 + // FIXME(https://github.com/emscripten-core/emscripten/issues/16975) + // `size_t` ends up here, but it's transferred in the ABI as a plain number instead of a bigint. + if (typeof value == 'number') { + return value >>> 0; + } +#endif + return BigInt.asUintN(bitSize, value); + } + maxRange = fromWireType(maxRange); } registerType(primitiveType, { name, - 'fromWireType': (value) => value, - 'toWireType': function(destructors, value) { - if (typeof value != "bigint" && typeof value != "number") { - throw new TypeError(`Cannot convert "${embindRepr(value)}" to ${this.name}`); - } + 'fromWireType': fromWireType, + 'toWireType': (destructors, value) => { if (typeof value == "number") { value = BigInt(value); } #if ASSERTIONS + else if (typeof value != "bigint") { + throw new TypeError(`Cannot convert "${embindRepr(value)}" to ${this.name}`); + } if (value < minRange || value > maxRange) { throw new TypeError(`Passing a number "${embindRepr(value)}" from JS side to C/C++ side to an argument of type "${name}", which is outside the valid range [${minRange}, ${maxRange}]!`); } diff --git a/system/lib/embind/bind.cpp b/system/lib/embind/bind.cpp index fa32bd173ca4f..2db20ffea1bd5 100644 --- a/system/lib/embind/bind.cpp +++ b/system/lib/embind/bind.cpp @@ -134,13 +134,6 @@ EMSCRIPTEN_BINDINGS(builtin) { register_integer("unsigned short"); register_integer("int"); register_integer("unsigned int"); -#if __wasm64__ - register_bigint("long"); - register_bigint("unsigned long"); -#else - register_integer("long"); - register_integer("unsigned long"); -#endif register_bigint("int64_t"); register_bigint("uint64_t"); diff --git a/test/embind/test_i64_binding.cpp b/test/embind/test_i64_binding.cpp index 6d7bfefb99cbe..57387cdb748fd 100644 --- a/test/embind/test_i64_binding.cpp +++ b/test/embind/test_i64_binding.cpp @@ -13,7 +13,7 @@ using namespace emscripten; using namespace std; -#define assert_js_eq(X, Y) run_js(string("const x = ") + X + ", y = " + Y + "; assert(x === y, `" + X + ": actual = ${x}, expected = ${y}`);") +#define assert_js_eq(X, Y) run_js(string("const x = ") + X + ", y = " + Y + "; assert(x === y, `" + X + ": actual = ${typeof x} ${x}, expected = ${typeof y} ${y}`);") void test(string message) { diff --git a/test/embind/test_i64_binding.out b/test/embind/test_i64_binding.out index c4ee82573c606..6923065d0c451 100644 --- a/test/embind/test_i64_binding.out +++ b/test/embind/test_i64_binding.out @@ -1,3 +1,5 @@ +test: +limits start test: vector From 160bf62f0582f7ba810ae8065b808d42b6f1693b Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Thu, 8 May 2025 15:44:00 +0100 Subject: [PATCH 03/10] Delete invalid test Test expectations were incorrect: it mixed up int64/uint64 and was returning negative number in uint64 function and expecting the negative sign to be preserved. Now that behaviour of uint64 is fixed, this expectation doesn't hold. Additionally, it was relying on the `n` suffix being printed by `console.log`, which is not portable and is not printed in e.g. latest Node.js. The correct test is now better served by test_i64_binding which correctly checks the type limits, signs, and will also run across more engines. --- test/embind/test_embind_long_long.cpp | 23 ----------------------- test/test_other.py | 8 -------- 2 files changed, 31 deletions(-) delete mode 100644 test/embind/test_embind_long_long.cpp diff --git a/test/embind/test_embind_long_long.cpp b/test/embind/test_embind_long_long.cpp deleted file mode 100644 index 7c1a5dc19764a..0000000000000 --- a/test/embind/test_embind_long_long.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include - -int64_t getInt64() { - return 1000000000000; -} - -uint64_t getUint64() { - return -1000000000000; -} - -int main() { - EM_ASM( - console.log(Module.getInt64()); - console.log(Module.getUint64()); - ); -} - -EMSCRIPTEN_BINDINGS(my_module) { - emscripten::function("getInt64", &getInt64); - emscripten::function("getUint64", &getUint64); -} diff --git a/test/test_other.py b/test/test_other.py index ea2a9cca190ad..1348845f2371f 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -3396,14 +3396,6 @@ def test_embind_return_value_policy(self): self.do_runf('embind/test_return_value_policy.cpp') - @parameterized({ - '': [[]], - 'asyncify': [['-sASYNCIFY=1']], - }) - def test_embind_long_long(self, args): - self.do_runf('embind/test_embind_long_long.cpp', '1000000000000n\n-1000000000000n', - emcc_args=['-lembind', '-sWASM_BIGINT'] + args) - @requires_node_canary def test_embind_resource_management(self): self.node_args.append('--js-explicit-resource-management') From e5dd511331e95a0a962e2e631a8f5d13ebffbc33 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Thu, 8 May 2025 15:48:21 +0100 Subject: [PATCH 04/10] Extract common integer range check --- src/lib/libembind.js | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/lib/libembind.js b/src/lib/libembind.js index 46b7735d8f01b..8dd381707a909 100644 --- a/src/lib/libembind.js +++ b/src/lib/libembind.js @@ -318,6 +318,14 @@ var LibraryEmbind = { } }, +#if ASSERTIONS + $assertIntegerRange: (name, value, minRange, maxRange) => { + if (value < minRange || value > maxRange) { + throw new TypeError(`Passing a number "${embindRepr(value)}" from JS side to C/C++ side to an argument of type "${name}", which is outside the valid range [${minRange}, ${maxRange}]!`); + } + }, +#endif + _embind_register_integer__docs: '/** @suppress {globalThis} */', // When converting a number from JS to C++ side, the valid range of the number is // [minRange, maxRange], inclusive. @@ -325,6 +333,7 @@ var LibraryEmbind = { '$integerReadValueFromPointer', '$readLatin1String', '$registerType', #if ASSERTIONS '$embindRepr', + '$assertIntegerRange', #endif ], _embind_register_integer: (primitiveType, name, size, minRange, maxRange) => { @@ -347,9 +356,7 @@ var LibraryEmbind = { if (typeof value != "number" && typeof value != "boolean") { throw new TypeError(`Cannot convert "${embindRepr(value)}" to ${toTypeName}`); } - if (value < minRange || value > maxRange) { - throw new TypeError(`Passing a number "${embindRepr(value)}" from JS side to C/C++ side to an argument of type "${name}", which is outside the valid range [${minRange}, ${maxRange}]!`); - } + assertIntegerRange(name, value, minRange, maxRange); #endif // The VM will perform JS to Wasm value conversion, according to the spec: // https://www.w3.org/TR/wasm-js-api-1/#towebassemblyvalue @@ -364,7 +371,12 @@ var LibraryEmbind = { #if WASM_BIGINT _embind_register_bigint__docs: '/** @suppress {globalThis} */', _embind_register_bigint__deps: [ - '$embindRepr', '$readLatin1String', '$registerType', '$integerReadValueFromPointer'], + '$readLatin1String', '$registerType', '$integerReadValueFromPointer', +#if ASSERTIONS + '$embindRepr', + '$assertIntegerRange', +#endif + ], _embind_register_bigint: (primitiveType, name, size, minRange, maxRange) => { name = readLatin1String(name); @@ -398,9 +410,7 @@ var LibraryEmbind = { else if (typeof value != "bigint") { throw new TypeError(`Cannot convert "${embindRepr(value)}" to ${this.name}`); } - if (value < minRange || value > maxRange) { - throw new TypeError(`Passing a number "${embindRepr(value)}" from JS side to C/C++ side to an argument of type "${name}", which is outside the valid range [${minRange}, ${maxRange}]!`); - } + assertIntegerRange(name, value, minRange, maxRange); #endif return value; }, From e2d34c407694648a63ecd57140b196dfa361fcb5 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Thu, 8 May 2025 15:54:26 +0100 Subject: [PATCH 05/10] Rebaseline code size --- test/code_size/embind_hello_wasm.json | 8 ++++---- test/code_size/embind_val_wasm.json | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/code_size/embind_hello_wasm.json b/test/code_size/embind_hello_wasm.json index ed05e8ee06b81..6817d8c23164e 100644 --- a/test/code_size/embind_hello_wasm.json +++ b/test/code_size/embind_hello_wasm.json @@ -1,10 +1,10 @@ { "a.html": 552, "a.html.gz": 380, - "a.js": 9005, - "a.js.gz": 3961, + "a.js": 8826, + "a.js.gz": 3896, "a.wasm": 7332, "a.wasm.gz": 3369, - "total": 16889, - "total_gz": 7710 + "total": 16710, + "total_gz": 7645 } diff --git a/test/code_size/embind_val_wasm.json b/test/code_size/embind_val_wasm.json index 0745dd4d3a415..9affed2d8c036 100644 --- a/test/code_size/embind_val_wasm.json +++ b/test/code_size/embind_val_wasm.json @@ -1,10 +1,10 @@ { "a.html": 552, "a.html.gz": 380, - "a.js": 6862, - "a.js.gz": 2965, + "a.js": 6683, + "a.js.gz": 2891, "a.wasm": 9133, "a.wasm.gz": 4710, - "total": 16547, - "total_gz": 8055 + "total": 16368, + "total_gz": 7981 } From 51013cd4c5b3ab0919b733d136760297a5e02581 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Thu, 8 May 2025 16:47:07 +0100 Subject: [PATCH 06/10] Address review feedback --- src/lib/libembind.js | 8 ++++---- test/embind/test_i64_binding.cpp | 26 ++++++++++---------------- test/embind/test_i64_binding.out | 18 ++++++------------ 3 files changed, 20 insertions(+), 32 deletions(-) diff --git a/src/lib/libembind.js b/src/lib/libembind.js index 8dd381707a909..88bcddc839fe9 100644 --- a/src/lib/libembind.js +++ b/src/lib/libembind.js @@ -319,9 +319,9 @@ var LibraryEmbind = { }, #if ASSERTIONS - $assertIntegerRange: (name, value, minRange, maxRange) => { + $assertIntegerRange: (typeName, value, minRange, maxRange) => { if (value < minRange || value > maxRange) { - throw new TypeError(`Passing a number "${embindRepr(value)}" from JS side to C/C++ side to an argument of type "${name}", which is outside the valid range [${minRange}, ${maxRange}]!`); + throw new TypeError(`Passing a number "${embindRepr(value)}" from JS side to C/C++ side to an argument of type "${typeName}", which is outside the valid range [${minRange}, ${maxRange}]!`); } }, #endif @@ -339,7 +339,7 @@ var LibraryEmbind = { _embind_register_integer: (primitiveType, name, size, minRange, maxRange) => { name = readLatin1String(name); - const isUnsignedType = maxRange < minRange; + const isUnsignedType = minRange === 0; let fromWireType = (value) => value; if (isUnsignedType) { @@ -380,7 +380,7 @@ var LibraryEmbind = { _embind_register_bigint: (primitiveType, name, size, minRange, maxRange) => { name = readLatin1String(name); - const isUnsignedType = maxRange < minRange; + const isUnsignedType = minRange === 0n; let fromWireType = (value) => value; if (isUnsignedType) { diff --git a/test/embind/test_i64_binding.cpp b/test/embind/test_i64_binding.cpp index 57387cdb748fd..3e21c17ede0a4 100644 --- a/test/embind/test_i64_binding.cpp +++ b/test/embind/test_i64_binding.cpp @@ -13,16 +13,17 @@ using namespace emscripten; using namespace std; -#define assert_js_eq(X, Y) run_js(string("const x = ") + X + ", y = " + Y + "; assert(x === y, `" + X + ": actual = ${typeof x} ${x}, expected = ${typeof y} ${y}`);") - void test(string message) { - cout << "test:\n" << message << "\n"; + printf("test: %s\n", message.c_str()); } -int run_js(string js_code) -{ - return emscripten_run_script_int(js_code.c_str()); +void assert_js_eq(string X, string Y) { + string js_code; + js_code += "const x = " + X + ";"; + js_code += "const y = " + Y + ";"; + js_code += "assert(x === y, `" + X + ": actual = ${typeof x} ${x}, expected = ${typeof y} ${y}`);"; + emscripten_run_script(js_code.c_str()); } EMSCRIPTEN_BINDINGS(tests) { @@ -36,13 +37,6 @@ EMSCRIPTEN_BINDINGS(tests) { extern "C" void ensure_js_throws_with_assertions_enabled(const char* js_code, const char* error_type); -// Checks that the given value has correctly preserved value and sign. -template -void assert_bigint_preserved(T value) { - val::global().set("bigint", value); - assert_js_eq("bigint", to_string(value) + "n"); -} - int main() { test("limits"); @@ -61,7 +55,7 @@ int main() assert_js_eq("v64.get(2)", "3n"); assert_js_eq("v64.get(3)", "-4n"); - run_js("v64.push_back(1234n)"); + emscripten_run_script("v64.push_back(1234n)"); assert_js_eq("v64.size()", "5"); assert_js_eq("v64.get(4)", "1234n"); @@ -76,11 +70,11 @@ int main() assert_js_eq("vU64.get(2)", "3n"); assert_js_eq("vU64.get(3)", "4n"); - run_js("vU64.push_back(1234n)"); + emscripten_run_script("vU64.push_back(1234n)"); assert_js_eq("vU64.size()", "5"); assert_js_eq("vU64.get(4)", "1234n"); - run_js("vU64.push_back(1234)"); + emscripten_run_script("vU64.push_back(1234)"); assert_js_eq("vU64.size()", "6"); assert_js_eq("vU64.get(5)", "1234n"); diff --git a/test/embind/test_i64_binding.out b/test/embind/test_i64_binding.out index 6923065d0c451..f0aab7996edbb 100644 --- a/test/embind/test_i64_binding.out +++ b/test/embind/test_i64_binding.out @@ -1,14 +1,8 @@ -test: -limits +test: limits start -test: -vector -test: -vector Cannot convert bigint that is too big -test: -vector -test: -vector Cannot convert bigint that is too big -test: -vector Cannot convert bigint that is negative +test: vector +test: vector Cannot convert bigint that is too big +test: vector +test: vector Cannot convert bigint that is too big +test: vector Cannot convert bigint that is negative end From 0ecc9a1e7500c89ddd63c3913d34c7fc57fb3faf Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Thu, 8 May 2025 17:38:33 +0100 Subject: [PATCH 07/10] Revert wasm64 conditional block Not sure why tests pass fine for me locally but not on CI, but it has to be related to RTTI checks... --- system/lib/embind/bind.cpp | 7 +++++++ test/code_size/embind_hello_wasm.json | 8 ++++---- test/code_size/embind_val_wasm.json | 8 ++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/system/lib/embind/bind.cpp b/system/lib/embind/bind.cpp index 2db20ffea1bd5..fa32bd173ca4f 100644 --- a/system/lib/embind/bind.cpp +++ b/system/lib/embind/bind.cpp @@ -134,6 +134,13 @@ EMSCRIPTEN_BINDINGS(builtin) { register_integer("unsigned short"); register_integer("int"); register_integer("unsigned int"); +#if __wasm64__ + register_bigint("long"); + register_bigint("unsigned long"); +#else + register_integer("long"); + register_integer("unsigned long"); +#endif register_bigint("int64_t"); register_bigint("uint64_t"); diff --git a/test/code_size/embind_hello_wasm.json b/test/code_size/embind_hello_wasm.json index 6817d8c23164e..b6bef00083b52 100644 --- a/test/code_size/embind_hello_wasm.json +++ b/test/code_size/embind_hello_wasm.json @@ -1,10 +1,10 @@ { "a.html": 552, "a.html.gz": 380, - "a.js": 8826, - "a.js.gz": 3896, + "a.js": 8831, + "a.js.gz": 3897, "a.wasm": 7332, "a.wasm.gz": 3369, - "total": 16710, - "total_gz": 7645 + "total": 16715, + "total_gz": 7646 } diff --git a/test/code_size/embind_val_wasm.json b/test/code_size/embind_val_wasm.json index 9affed2d8c036..bcb9ad6b35682 100644 --- a/test/code_size/embind_val_wasm.json +++ b/test/code_size/embind_val_wasm.json @@ -1,10 +1,10 @@ { "a.html": 552, "a.html.gz": 380, - "a.js": 6683, - "a.js.gz": 2891, + "a.js": 6688, + "a.js.gz": 2893, "a.wasm": 9133, "a.wasm.gz": 4710, - "total": 16368, - "total_gz": 7981 + "total": 16373, + "total_gz": 7983 } From 99e07279b1900b61f7872e4535d4b9561e62e31f Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Thu, 8 May 2025 17:55:40 +0100 Subject: [PATCH 08/10] Don't use int64 aliases during registration --- src/lib/libembind_gen.js | 4 ++-- system/lib/embind/bind.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/libembind_gen.js b/src/lib/libembind_gen.js index 6513bf87d3488..c55caf2a17db5 100644 --- a/src/lib/libembind_gen.js +++ b/src/lib/libembind_gen.js @@ -367,8 +367,8 @@ var LibraryEmbind = { ['unsigned long', ['bigint']], #endif #if WASM_BIGINT - ['int64_t', ['bigint']], - ['uint64_t', ['bigint']], + ['long long', ['bigint']], + ['unsigned long long', ['bigint']], #endif ['void', ['void']], ['std::string', [jsString, 'string']], diff --git a/system/lib/embind/bind.cpp b/system/lib/embind/bind.cpp index fa32bd173ca4f..3e1336ef9cfb3 100644 --- a/system/lib/embind/bind.cpp +++ b/system/lib/embind/bind.cpp @@ -142,8 +142,8 @@ EMSCRIPTEN_BINDINGS(builtin) { register_integer("unsigned long"); #endif - register_bigint("int64_t"); - register_bigint("uint64_t"); + register_bigint("long long"); + register_bigint("unsigned long long"); register_float("float"); register_float("double"); From 3a2032441856e5d0cece9bae91f8516a0be4db74 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Thu, 8 May 2025 18:38:19 +0100 Subject: [PATCH 09/10] Rebaseline yet again --- test/code_size/embind_hello_wasm.json | 8 ++++---- test/code_size/embind_val_wasm.json | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/code_size/embind_hello_wasm.json b/test/code_size/embind_hello_wasm.json index b6bef00083b52..94d25afddde34 100644 --- a/test/code_size/embind_hello_wasm.json +++ b/test/code_size/embind_hello_wasm.json @@ -3,8 +3,8 @@ "a.html.gz": 380, "a.js": 8831, "a.js.gz": 3897, - "a.wasm": 7332, - "a.wasm.gz": 3369, - "total": 16715, - "total_gz": 7646 + "a.wasm": 7344, + "a.wasm.gz": 3368, + "total": 16727, + "total_gz": 7645 } diff --git a/test/code_size/embind_val_wasm.json b/test/code_size/embind_val_wasm.json index bcb9ad6b35682..7f8e29a6220fd 100644 --- a/test/code_size/embind_val_wasm.json +++ b/test/code_size/embind_val_wasm.json @@ -3,8 +3,8 @@ "a.html.gz": 380, "a.js": 6688, "a.js.gz": 2893, - "a.wasm": 9133, - "a.wasm.gz": 4710, - "total": 16373, - "total_gz": 7983 + "a.wasm": 9137, + "a.wasm.gz": 4700, + "total": 16377, + "total_gz": 7973 } From fb4ccfaa9cd8df293a8027dd52f188dc176073b6 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Thu, 8 May 2025 20:33:44 +0100 Subject: [PATCH 10/10] Test fixes --- src/lib/libembind.js | 7 ++++--- test/test_other.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/lib/libembind.js b/src/lib/libembind.js index 88bcddc839fe9..461dc5a194de1 100644 --- a/src/lib/libembind.js +++ b/src/lib/libembind.js @@ -319,6 +319,7 @@ var LibraryEmbind = { }, #if ASSERTIONS + $assertIntegerRange__deps: ['$embindRepr'], $assertIntegerRange: (typeName, value, minRange, maxRange) => { if (value < minRange || value > maxRange) { throw new TypeError(`Passing a number "${embindRepr(value)}" from JS side to C/C++ side to an argument of type "${typeName}", which is outside the valid range [${minRange}, ${maxRange}]!`); @@ -354,7 +355,7 @@ var LibraryEmbind = { 'toWireType': (destructors, value) => { #if ASSERTIONS if (typeof value != "number" && typeof value != "boolean") { - throw new TypeError(`Cannot convert "${embindRepr(value)}" to ${toTypeName}`); + throw new TypeError(`Cannot convert "${embindRepr(value)}" to ${name}`); } assertIntegerRange(name, value, minRange, maxRange); #endif @@ -1199,7 +1200,7 @@ var LibraryEmbind = { $constNoSmartPtrRawPointerToWireType__docs: '/** @suppress {globalThis} */', // If we know a pointer type is not going to have SmartPtr logic in it, we can // special-case optimize it a bit (compare to genericPointerToWireType) - $constNoSmartPtrRawPointerToWireType__deps: ['$throwBindingError', '$upcastPointer'], + $constNoSmartPtrRawPointerToWireType__deps: ['$throwBindingError', '$upcastPointer', '$embindRepr'], $constNoSmartPtrRawPointerToWireType: function(destructors, handle) { if (handle === null) { if (this.isReference) { @@ -1222,7 +1223,7 @@ var LibraryEmbind = { $nonConstNoSmartPtrRawPointerToWireType__docs: '/** @suppress {globalThis} */', // An optimized version for non-const method accesses - there we must additionally restrict that // the pointer is not a const-pointer. - $nonConstNoSmartPtrRawPointerToWireType__deps: ['$throwBindingError', '$upcastPointer'], + $nonConstNoSmartPtrRawPointerToWireType__deps: ['$throwBindingError', '$upcastPointer', '$embindRepr'], $nonConstNoSmartPtrRawPointerToWireType: function(destructors, handle) { if (handle === null) { if (this.isReference) { diff --git a/test/test_other.py b/test/test_other.py index 1348845f2371f..ffc83109ff681 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -3574,7 +3574,7 @@ def test_embind_tsgen_bigint(self): args = [EMXX, test_file('other/embind_tsgen_bigint.cpp'), '-lembind', '--emit-tsd', 'embind_tsgen_bigint.d.ts'] # Check that TypeScript generation fails when code contains bigints but their support is not enabled stderr = self.expect_fail(args + ['-sWASM_BIGINT=0']) - self.assertContained("Missing primitive type to TS type for 'int64_t", stderr) + self.assertContained("Missing primitive type to TS type for 'long long", stderr) # Check that TypeScript generation works when bigint support is enabled self.run_process(args) self.assertFileContents(test_file('other/embind_tsgen_bigint.d.ts'), read_file('embind_tsgen_bigint.d.ts'))