From cf4b6059a30d7f4d4663f692adfb243e1dbcad08 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 25 Sep 2025 17:10:45 -0700 Subject: [PATCH] Fix `addFunction` in `-sWASM=2` mode Fixes: #25394 --- src/lib/libaddfunction.js | 30 ++++++++++--------- test/codesize/test_codesize_hello_dylink.json | 4 +-- test/test_other.py | 13 ++++---- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/lib/libaddfunction.js b/src/lib/libaddfunction.js index 72121b87edc09..d059e748732e3 100644 --- a/src/lib/libaddfunction.js +++ b/src/lib/libaddfunction.js @@ -77,8 +77,8 @@ addToLibrary({ return code; })), +#if !WASM2JS || WASM == 2 // Wraps a JS function as a wasm function with a given signature. -#if !WASM2JS $convertJsFunctionToWasm__deps: [ '$uleb128EncodeWithLen', #if WASM_JS_TYPES @@ -86,12 +86,7 @@ addToLibrary({ #endif '$generateTypePack' ], -#endif $convertJsFunctionToWasm: (func, sig) => { -#if WASM2JS - // return func; -#else // WASM2JS - #if ASSERTIONS && !WASM_BIGINT assert(!sig.includes('j'), 'i64 not permitted in function signatures when WASM_BIGINT is disabled'); #endif @@ -135,8 +130,8 @@ addToLibrary({ var instance = new WebAssembly.Instance(module, { 'e': { 'f': func } }); var wrappedFunc = instance.exports['f']; return wrappedFunc; -#endif // WASM2JS }, +#endif // !WASM2JS && WASM != 2 $freeTableIndexes: [], @@ -192,18 +187,21 @@ addToLibrary({ * 'sig' parameter is required if the function being added is a JS function. */ $addFunction__docs: '/** @param {string=} sig */', - $addFunction__deps: ['$convertJsFunctionToWasm', '$getFunctionAddress', + $addFunction__deps: ['$getFunctionAddress', '$functionsInTableMap', '$getEmptyTableSlot', '$setWasmTableEntry', +#if !WASM2JS || WASM == 2 + '$convertJsFunctionToWasm', +#endif #if ASSERTIONS >= 2 '$getWasmTableEntry', '$wasmTable', #endif ], $addFunction: (func, sig) => { - #if ASSERTIONS +#if ASSERTIONS assert(typeof func != 'undefined'); - #endif // ASSERTIONS +#endif // ASSERTIONS // Check if the function is already in the table, to ensure each function // gets a unique index. var rtn = getFunctionAddress(func); @@ -213,17 +211,20 @@ addToLibrary({ // It's not in the table, add it now. - #if ASSERTIONS >= 2 +#if ASSERTIONS >= 2 // Make sure functionsInTableMap is actually up to date, that is, that this // function is not actually in the wasm Table despite not being tracked in // functionsInTableMap. for (var i = 0; i < wasmTable.length; i++) { assert(getWasmTableEntry(i) != func, 'function in Table but not functionsInTableMap'); } - #endif +#endif var ret = getEmptyTableSlot(); +#if WASM2JS && WASM != 2 + setWasmTableEntry(ret, func); +#else // Set the new value. try { // Attempting to call this with JS function will cause of table.set() to fail @@ -232,12 +233,13 @@ addToLibrary({ if (!(err instanceof TypeError)) { throw err; } - #if ASSERTIONS +#if ASSERTIONS assert(typeof sig != 'undefined', 'Missing signature argument to addFunction: ' + func); - #endif +#endif var wrapped = convertJsFunctionToWasm(func, sig); setWasmTableEntry(ret, wrapped); } +#endif functionsInTableMap.set(func, ret); diff --git a/test/codesize/test_codesize_hello_dylink.json b/test/codesize/test_codesize_hello_dylink.json index c0b841cf9aca8..8e234836ee9e3 100644 --- a/test/codesize/test_codesize_hello_dylink.json +++ b/test/codesize/test_codesize_hello_dylink.json @@ -1,10 +1,10 @@ { "a.out.js": 26946, - "a.out.js.gz": 11480, + "a.out.js.gz": 11478, "a.out.nodebug.wasm": 18567, "a.out.nodebug.wasm.gz": 9199, "total": 45513, - "total_gz": 20679, + "total_gz": 20677, "sent": [ "__heap_base", "__indirect_function_table", diff --git a/test/test_other.py b/test/test_other.py index 86d4797bfafed..51359ae62637a 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -14638,17 +14638,16 @@ def test_windows_nodefs_execution_permission(self): self.do_run(src) @parameterized({ - 'wasm2js': (True,), - '': (False,), + '': ([],), + 'wasm2js': (['-sWASM=0'],), + 'wasm2js_fallback': (['-sWASM=2'],), }) - def test_add_js_function(self, wasm2js): + def test_add_js_function(self, args): self.set_setting('INVOKE_RUN', 0) self.set_setting('WASM_ASYNC_COMPILATION', 0) self.set_setting('ALLOW_TABLE_GROWTH') self.set_setting('EXPORTED_RUNTIME_METHODS', ['callMain']) - if wasm2js: - self.set_setting('WASM', 0) - self.cflags += ['--post-js', test_file('interop/test_add_function_post.js')] + self.cflags += args + ['--post-js', test_file('interop/test_add_function_post.js')] print('basics') self.do_run_in_out_file_test('interop/test_add_function.cpp') @@ -14656,7 +14655,7 @@ def test_add_js_function(self, wasm2js): print('with ALLOW_TABLE_GROWTH=0') self.set_setting('ALLOW_TABLE_GROWTH', 0) expected = 'Unable to grow wasm table' - if wasm2js: + if '-sWASM=0' in args: # in wasm2js the error message doesn't come from the VM, but from our # emulation code. when ASSERTIONS are enabled we show a clear message, but # in optimized builds we don't waste code size on that, and the JS engine