Skip to content

Commit 2f0682b

Browse files
authored
Fix for exception handling + WASM_BIGINT. (emscripten-core#16233)
When WASM_BIGINT is enabled and a function that returns a BigInt throws an exception we need to generate a valid return value. For normal (non-BitInt) types simply not returning anything at all works because undefined gets implicitly coerced to zero. Fixes: emscripten-core#15974
1 parent b1bbec1 commit 2f0682b

3 files changed

Lines changed: 16 additions & 8 deletions

File tree

tests/core/test_i64_invoke_bigint.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
#include <emscripten.h>
32
#include <stdio.h>
43
#include <stdint.h>
@@ -15,15 +14,19 @@ int64_t foobar(int64_t x, int y) {
1514
}
1615
return x + y; // use the int parameter too, to show they are all handled
1716
}
18-
17+
1918
int main() {
2019
int64_t x;
2120
try {
2221
puts("try");
2322
x = foobar(big, 1);
24-
} catch(int) {
25-
puts("caught");
23+
printf("ok: 0x%llx.\n", x);
24+
x = foobar(1337, 1);
25+
printf("should not get here\n");
26+
__builtin_trap();
27+
} catch(int e) {
28+
printf("caught: %d\n", e);
2629
}
27-
printf("ok: 0x%llx.\n", x);
30+
printf("done");
31+
return 0;
2832
}
29-
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
try
22
ok: 0x12345678aabbccde.
3+
caught: 1

tools/js_manipulation.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ def make_invoke(sig):
115115
legal_sig = legalize_sig(sig) # TODO: do this in extcall, jscall?
116116
args = ['index'] + ['a' + str(i) for i in range(1, len(legal_sig))]
117117
ret = 'return ' if sig[0] != 'v' else ''
118+
# For function that needs to return a genuine i64 (i.e. if legal_sig[0] is 'j')
119+
# we need to return an actual BigInt, even in the exceptional case because
120+
# wasm won't implicitly convert undefined to 0 in this case.
121+
exceptional_ret = '\n return BigInt(0);' if legal_sig[0] == 'j' else ''
118122
body = '%s%s;' % (ret, make_dynCall(sig, args))
119123
# C++ exceptions are numbers, and longjmp is a string 'longjmp'
120124
if settings.SUPPORT_LONGJMP:
@@ -130,8 +134,8 @@ def make_invoke(sig):
130134
} catch(e) {
131135
stackRestore(sp);
132136
%s
133-
_setThrew(1, 0);
137+
_setThrew(1, 0);%s
134138
}
135-
}''' % (sig, ','.join(args), body, rethrow)
139+
}''' % (sig, ','.join(args), body, rethrow, exceptional_ret)
136140

137141
return ret

0 commit comments

Comments
 (0)