Skip to content

Upgrading from emscripten 3.1.74 to 4.0.0 has unexpected effect on JS code due to WASM_BIGINT default change #24007

Closed as not planned
@jrouwe

Description

@jrouwe

Consider the following WebIDL file:

interface Body {
	void Body();
	unsigned long long Function(unsigned long long inV);
};

the following C++ code:

class Body
{
public:
	unsigned long long Function(unsigned long long inV) { return inV + 1; }
};

and the following JS code:

let body = new Jolt.Body();
let input = 1311768465173141112; // a 64-bit value
let ret = body.Function(input);
console.log("Input: " + input + ", ret: " + ret);

In emscripten 3.1.74 with the default -s WASM_BIGINT=0, this would not produce any errors (it would truncate input to an unsigned long though).

After upgrading to 4.0.0 and the default switching to -s WASM_BIGINT=1 that same code fails with:

file:///mnt/c/Users/jrouw/Documents/Code/tmp3/jolt.js:187
    return g(...f);
           ^

TypeError: Cannot convert 1311768465173141000 to a BigInt
    at file:///mnt/c/Users/jrouw/Documents/Code/tmp3/jolt.js:187:12
    at Body.Function.Body.Function (file:///mnt/c/Users/jrouw/Documents/Code/tmp3/jolt.js:473:10)
    at file:///mnt/c/Users/jrouw/Documents/Code/tmp3/Run.js:6:17

In order to make things work again you need to change the JS code to:

let input = BigInt(1311768465173141112);

This code is incompatible with -s WASM_BIGINT=0 as it will trigger the inverse error:

file:///mnt/c/Users/jrouw/Documents/Code/tmp3/jolt.js:187
    return g(...e);
           ^

TypeError: Cannot convert a BigInt value to a number
    at file:///mnt/c/Users/jrouw/Documents/Code/tmp3/jolt.js:187:12
    at Body.Function.Body.Function (file:///mnt/c/Users/jrouw/Documents/Code/tmp3/jolt.js:474:10)
    at file:///mnt/c/Users/jrouw/Documents/Code/tmp3/RunBigInt.js:6:17

From the 4.0.0 release notes:

The WASM_BIGINT feature is enabled by default. This has the effect that Wasm i64 values are passed and returned between Wasm and JS as BigInt values rather than being split by Binaryen into pairs of Numbers. (#22993)

I got the impression that the intention was that this was an internal optimization and would not have any effect on how JS code needs to be written.

I'm not sure if this can be considered a bug or if it was a deliberate change, so my question is: Is this expected behavior?

I've created a MRP that cycles through all permutations of WASM_BIGINT and the permutations of passing parameters as BigInt/normal number:

MRP.zip

Unpack and run ./build.sh.

Version of emscripten/emsdk:
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 4.0.6 (1ddaae4)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions