Skip to content

Commit 62c2b33

Browse files
authored
Fix dyncall() functions on i64 parameters in WASM_BIGINT mode (#19689)
With BigInt support we don't legalize, so a 'j' parameter is just a single value (a BigInt) and not two legalized i32s. The test now works in both BigInt and non-BigInt mode. To make that simple I moved some of the expectations from the text output into assertions.
1 parent cfa864b commit 62c2b33

File tree

4 files changed

+62
-13
lines changed

4 files changed

+62
-13
lines changed

src/library.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3157,8 +3157,15 @@ mergeInto(LibraryManager.library, {
31573157
assert(('dynCall_' + sig) in Module, `bad function pointer type - dynCall function not found for sig '${sig}'`);
31583158
#endif
31593159
if (args && args.length) {
3160+
#if WASM_BIGINT
3161+
// j (64-bit integer) is fine, and is implemented as a BigInt. Without
3162+
// legalization, the number of parameters should match (j is not expanded
3163+
// into two i's).
3164+
assert(args.length === sig.length - 1);
3165+
#else
31603166
// j (64-bit integer) must be passed in as two numbers [low 32, high 32].
31613167
assert(args.length === sig.substring(1).replace(/j/g, '--').length);
3168+
#endif
31623169
} else {
31633170
assert(sig.length == 1);
31643171
}

test/core/dyncall_specific.c

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,60 @@
55
* found in the LICENSE file.
66
*/
77

8+
#include <assert.h>
89
#include <emscripten.h>
910
#include <stdint.h>
1011
#include <stdio.h>
1112

1213
int waka(int w, long long xy, int z) {
14+
#ifdef WASM_BIGINT
15+
// With WASM_BIGINT things are straightforward: the 64-bit value just arrives
16+
// with the expected value of 4.
17+
assert(w == 1);
18+
assert(xy == 4);
19+
assert(z == 9);
20+
#else
1321
// xy should be 0xffff_ffff_0000_0004
14-
int x = (int) xy; // should be 4
15-
int y = xy >> 32; // should be -1
16-
EM_ASM({
17-
out('received ' + [$0, $1, $2, $3] + '.');
18-
}, w, x, y, z);
22+
int x = (int) xy;
23+
int y = xy >> 32;
24+
assert(w == 1);
25+
assert(x == 4);
26+
assert(y == -1);
27+
assert(z == 9);
28+
#endif
1929
return 42;
2030
}
2131

2232
EM_JS_DEPS(main, "$dynCall");
2333

2434
int main() {
2535
EM_ASM({
26-
// Note that these would need to use BigInts if the file were built with
27-
// -sWASM_BIGINT
36+
37+
#ifdef WASM_BIGINT
38+
39+
#if DIRECT
40+
console.log('Received ' + dynCall_iiji($0, 1, BigInt(4), 9));
41+
return;
42+
#endif
43+
#if DYNAMIC_SIG
44+
console.log('Received ' + dynCall('iiji', $0, [1, BigInt(4), 9]));
45+
return;
46+
#endif
47+
#if EXPORTED
48+
console.log('Received ' + Module['dynCall_iiji']($0, 1, BigInt(4), 9));
49+
return;
50+
#endif
51+
#if EXPORTED_DYNAMIC_SIG
52+
console.log('Received ' + Module['dynCall']('iiji', $0, [1, BigInt(4), 9]));
53+
return;
54+
#endif
55+
#if FROM_OUTSIDE
56+
eval("console.log('Received ' + Module['dynCall_iiji'](" + $0 + ", 1, BigInt(4), 9))");
57+
return;
58+
#endif
59+
60+
#else // WASM_BIGINT
61+
2862
#if DIRECT
2963
console.log('Received ' + dynCall_iiji($0, 1, 4, 0xffffffff, 9));
3064
return;
@@ -45,6 +79,10 @@ int main() {
4579
eval("console.log('Received ' + Module['dynCall_iiji'](" + $0 + ", 1, 4, 0xffffffff, 9))");
4680
return;
4781
#endif
82+
83+
#endif
84+
85+
// We should have run the test and returned before we get here.
4886
throw "no test mode";
4987
}, &waka);
5088
}

test/core/dyncall_specific.out

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
received 1,4,-1,9.
2-
Received 42
1+
Received 42

test/test_core.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7209,18 +7209,23 @@ def test_EXPORTED_RUNTIME_METHODS(self):
72097209
'minimal_runtime': ['-sMINIMAL_RUNTIME=1']
72107210
})
72117211
def test_dyncall_specific(self, *args):
7212-
if self.get_setting('WASM_BIGINT') or self.get_setting('MEMORY64'):
7213-
self.skipTest('not compatible with WASM_BIGINT')
7212+
if self.get_setting('MEMORY64'):
7213+
self.skipTest('not compatible with MEMORY64')
7214+
if self.get_setting('WASM_BIGINT'):
7215+
# define DYNCALLS because this test does test calling them directly, and
7216+
# in WASM_BIGINT mode we do not enable them by default (since we can do
7217+
# more without them - we don't need to legalize)
7218+
args = list(args) + ['-sDYNCALLS', '-DWASM_BIGINT']
72147219
cases = [
72157220
('DIRECT', []),
7216-
('DYNAMIC_SIG', ['-sDYNCALLS=1']),
7221+
('DYNAMIC_SIG', ['-sDYNCALLS']),
72177222
]
72187223
if '-sMINIMAL_RUNTIME=1' in args:
72197224
self.emcc_args += ['--pre-js', test_file('minimal_runtime_exit_handling.js')]
72207225
else:
72217226
cases += [
72227227
('EXPORTED', []),
7223-
('EXPORTED_DYNAMIC_SIG', ['-sDYNCALLS=1', '-sEXPORTED_RUNTIME_METHODS=dynCall']),
7228+
('EXPORTED_DYNAMIC_SIG', ['-sDYNCALLS', '-sEXPORTED_RUNTIME_METHODS=dynCall']),
72247229
('FROM_OUTSIDE', ['-sEXPORTED_RUNTIME_METHODS=dynCall_iiji'])
72257230
]
72267231

0 commit comments

Comments
 (0)