Emscripten: EMULATED_FUNCTION_POINTERS=1 issue with EH and functions returning int64

Created on 27 Oct 2018  路  8Comments  路  Source: emscripten-core/emscripten

Testcase:

#include <cstdio>
#include <cstdint>

int64_t foo (void)
{
    return 5;
}

typedef int64_t (Func) (void);

Func *bar;

int main (void)
{
    bar = foo;

    try {
        printf ("%d\n", bar ());
    } catch (int i) {
    }
}

Compile with:

emsdk_env.sh && emcc -g  -s DISABLE_EXCEPTION_CATCHING=0  -s EMULATED_FUNCTION_POINTERS=1 -s ALIASING_FUNCTION_POINTERS=0 -s EXIT_RUNTIME=1 -s WASM=1 -s BINARYEN=1 foo.cpp

Expected result:

5

Actual result:

exception thrown: TypeError: cannot pass i64 to or from JS
[email protected]:2221:10
[email protected]:2211:12
[email protected] line 1656 > WebAssembly.instantiate:wasm-function[104]:0xbc16
[email protected] line 1656 > WebAssembly.instantiate:wasm-function[29]:0x5a2
[email protected]:2446:10
help wanted

All 8 comments

I can confirm this issue. What happens is we need to do a call to a function type that is not valid in JS, so we need to legalize it. We legalize imports and exports properly, but the invoke/dynCall logic is somewhat special and I guess we need to fix something there.

Also confirming that this should only affect code using exceptions or setjmp, where an invoke ends up necessary to a function type containing an i64.

Can confirm this issue as well. In my own code I can work around it by marking functions like foo in the example above with noexcept, but it also happens when calling functions in SDL that use 64-bit arguments, like https://wiki.libsdl.org/SDL_RWseek

Submitted two 2 PRs to fastcomp/emscripten with a possible fix.

The sample doesn't look legal, but that may be besides the point.
i.e. it is passing int64_t to %d (unless int==int64_t which is possible but unlikely).

Could anyone please suggest a temporary workaround for this issue?

I'm in a scenario where both -s EMULATED_FUNCTION_POINTERS=1 and setjmp/longjmp are necessary, and this causes a direct call to be transformed into a $legalfunc$invoke_iij call (see #8119).

Unfortunately, my codebase is plain C, and I'm unable to set C++11 attributes such as noexcept as @aardappel suggested.

I think this is almost fixed - we legalize invokes now, and #8065 should fix emulated function pointers as well - may be interesting to test your code with that PR.

The testcase above seems to work now.

This is now fixed. Thanks.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

surma picture surma  路  4Comments

hcomere picture hcomere  路  3Comments

answer1103 picture answer1103  路  4Comments

nerddan picture nerddan  路  4Comments

ShawZG picture ShawZG  路  4Comments