Skip to content

'j' parameter values are not passed to JavaScript as pair of numbers when WASM_BIGINT disabled #23078

Open
@travbid

Description

@travbid

Probably more of a documentation bug - based on the documentation at https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#function-signatures I expect to be able to call a JS function from C++ with an int64_t and receive a pair of numbers on the JS side when WASM_BIGINT is disabled.

When 'j' is used there are several ways in which the parameter value will be passed to JavaScript. By default, the value will either be passed as a single BigInt or a pair of JavaScript numbers (double) depending on whether the WASM_BIGINT settings is enabled.

Minimal reproduction with GitHub Action: https://github.com/travbid/emscripten-issue-i64

// index.js
import module from './foo.js';
const wasm = await module();
function mycallback(numLow, numHigh) {
    console.log('mycallback', numLow, numHigh);
}
const cbPtr = wasm.addFunction(mycallback, 'vj');
wasm.foo(cbPtr);
// foo.cpp
#include <emscripten/bind.h>

void foo(intptr_t callpack_ptr) {
    auto callback = reinterpret_cast<void(*)(int64_t)>(callpack_ptr);
    int64_t num = 5;
    callback(num);
}

EMSCRIPTEN_BINDINGS(module) {
    emscripten::function("foo", &foo);
}

What I expect to see (based on the documentation)

mycallback 5 0

What I see instead

Aborted(Assertion failed: i64 not permitted in function signatures when WASM_BIGINT is disabled)

If I disable assertions with -sASSERTIONS=0 then I see

mycallback 5n undefined

indicating it was called with a single BigInt.

Version of emscripten/emsdk:
Please include the output emcc -v here

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.73-git
clang version 20.0.0git
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /opt/homebrew/Cellar/emscripten/3.1.73/libexec/llvm/bin

Full link command and output with -v appended:

% emcc \                                           
  --bind \
  -sWASM_BIGINT=0 \
  -sEXPORT_ES6=1 \
  -sENVIRONMENT=node \
  -sUSE_ES6_IMPORT_META=1 \
  -sALLOW_TABLE_GROWTH=1 \
  -sEXPORTED_RUNTIME_METHODS="[addFunction]" \
  -sASSERTIONS=0 \
  -o foo.js \
  -v \
  foo.cpp

 /opt/homebrew/Cellar/emscripten/3.1.73/libexec/llvm/bin/clang -target wasm32-unknown-emscripten -fignore-exceptions -mno-bulk-memory -mno-nontrapping-fptoint -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --sysroot=/opt/homebrew/Cellar/emscripten/3.1.73/libexec/cache/sysroot -DEMSCRIPTEN -Werror=implicit-function-declaration -Xclang -iwithsysroot/include/fakesdl -Xclang -iwithsysroot/include/compat -v foo.cpp -c -o /var/folders/cp/sjfpv8h51xq9fhkrk7lqdrzm0000gn/T/emscripten_temp_v1i2kwom/foo_0.o
clang version 20.0.0git
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /opt/homebrew/Cellar/emscripten/3.1.73/libexec/llvm/bin
 (in-process)
 "/opt/homebrew/Cellar/emscripten/3.1.73/libexec/llvm/bin/clang-20" -cc1 -triple wasm32-unknown-emscripten -emit-obj -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name foo.cpp -mrelocation-model static -mframe-pointer=none -ffp-contract=on -fno-rounding-math -mconstructor-aliases -target-cpu generic -target-feature -bulk-memory -target-feature -nontrapping-fptoint -fvisibility=hidden -debugger-tuning=gdb -fdebug-compilation-dir=/emcc_bigint -target-linker-version 1115.7.3 -v -fcoverage-compilation-dir=/emcc_bigint -resource-dir /opt/homebrew/Cellar/emscripten/3.1.73/libexec/llvm/lib/clang/20 -D EMSCRIPTEN -isysroot /opt/homebrew/Cellar/emscripten/3.1.73/libexec/cache/sysroot -internal-isystem /opt/homebrew/Cellar/emscripten/3.1.73/libexec/cache/sysroot/include/wasm32-emscripten/c++/v1 -internal-isystem /opt/homebrew/Cellar/emscripten/3.1.73/libexec/cache/sysroot/include/c++/v1 -internal-isystem /opt/homebrew/Cellar/emscripten/3.1.73/libexec/llvm/lib/clang/20/include -internal-isystem /opt/homebrew/Cellar/emscripten/3.1.73/libexec/cache/sysroot/include/wasm32-emscripten -internal-isystem /opt/homebrew/Cellar/emscripten/3.1.73/libexec/cache/sysroot/include -Werror=implicit-function-declaration -fdeprecated-macro -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fignore-exceptions -fexceptions -fcolor-diagnostics -iwithsysroot/include/fakesdl -iwithsysroot/include/compat -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr -o /var/folders/cp/sjfpv8h51xq9fhkrk7lqdrzm0000gn/T/emscripten_temp_v1i2kwom/foo_0.o -x c++ foo.cpp
clang -cc1 version 20.0.0git based upon LLVM 20.0.0git default target arm64-apple-darwin24.1.0
ignoring nonexistent directory "/opt/homebrew/Cellar/emscripten/3.1.73/libexec/cache/sysroot/include/wasm32-emscripten/c++/v1"
ignoring nonexistent directory "/opt/homebrew/Cellar/emscripten/3.1.73/libexec/cache/sysroot/include/wasm32-emscripten"
#include "..." search starts here:
#include <...> search starts here:
 /opt/homebrew/Cellar/emscripten/3.1.73/libexec/cache/sysroot/include/fakesdl
 /opt/homebrew/Cellar/emscripten/3.1.73/libexec/cache/sysroot/include/compat
 /opt/homebrew/Cellar/emscripten/3.1.73/libexec/cache/sysroot/include/c++/v1
 /opt/homebrew/Cellar/emscripten/3.1.73/libexec/llvm/lib/clang/20/include
 /opt/homebrew/Cellar/emscripten/3.1.73/libexec/cache/sysroot/include
End of search list.
 /opt/homebrew/Cellar/emscripten/3.1.73/libexec/llvm/bin/clang --version
 /opt/homebrew/Cellar/emscripten/3.1.73/libexec/llvm/bin/wasm-ld -o foo.wasm -lembind-rtti -L/opt/homebrew/Cellar/emscripten/3.1.73/libexec/cache/sysroot/lib/wasm32-emscripten /var/folders/cp/sjfpv8h51xq9fhkrk7lqdrzm0000gn/T/emscripten_temp_v1i2kwom/foo_0.o -lGL-getprocaddr -lal -lhtml5 -lstubs -lnoexit -lc -ldlmalloc -lcompiler_rt -lc++-noexcept -lc++abi-noexcept -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr /var/folders/cp/sjfpv8h51xq9fhkrk7lqdrzm0000gn/T/tmptytd0v5wlibemscripten_js_symbols.so --strip-debug --export=_emscripten_stack_alloc --export=__getTypeName --export=__get_temp_ret --export=__set_temp_ret --export=__wasm_call_ctors --export=emscripten_stack_get_current --export=_emscripten_stack_restore --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=main --export-if-defined=__main_argc_argv --export-table --growable-table -z stack-size=65536 --no-growable-memory --initial-heap=16777216 --no-entry --stack-first --table-base=1
 /opt/homebrew/Cellar/emscripten/3.1.73/libexec/llvm/bin/llvm-objcopy foo.wasm foo.wasm --remove-section=.debug* --remove-section=producers
 /opt/homebrew/Cellar/emscripten/3.1.73/libexec/binaryen/bin/wasm-emscripten-finalize --dyncalls-i64 --pass-arg=legalize-js-interface-exported-helpers foo.wasm -o foo.wasm --detect-features
 /opt/homebrew/Cellar/emscripten/3.1.73/libexec/binaryen/bin/wasm-emscripten-finalize --dyncalls-i64 --pass-arg=legalize-js-interface-exported-helpers foo.wasm -o foo.wasm --detect-features
 /opt/homebrew/opt/node/bin/node /opt/homebrew/Cellar/emscripten/3.1.73/libexec/src/compiler.mjs /var/folders/cp/sjfpv8h51xq9fhkrk7lqdrzm0000gn/T/tmpbd927kor.json

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions