Skip to content

Commit 4f6fe88

Browse files
committed
Add wbind and wbindArray API.
1 parent e642863 commit 4f6fe88

File tree

6 files changed

+110
-3
lines changed

6 files changed

+110
-3
lines changed

src/library.js

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3508,7 +3508,7 @@ LibraryManager.library = {
35083508
#if ASSERTIONS
35093509
assert(wasmTable.get(ptr), 'missing table entry in dynCall: ' + ptr);
35103510
#endif
3511-
return wasmTable.get(ptr).apply(null, args)
3511+
return wasmTable.get(ptr).apply(null, args);
35123512
#endif
35133513
},
35143514

@@ -3532,6 +3532,46 @@ LibraryManager.library = {
35323532
}
35333533
},
35343534

3535+
#if SHRINK_LEVEL == 0
3536+
// A mirror copy of contents of wasmTable in JS side, to avoid relatively
3537+
// slow wasmTable.get() call. Only used when not compiling with -Os or -Oz.
3538+
_wasmTableMirror: [],
3539+
3540+
$wbind__deps: ['_wasmTableMirror'],
3541+
$wbind: function(funcPtr) {
3542+
var func = __wasmTableMirror[funcPtr];
3543+
if (!func) {
3544+
if (funcPtr >= __wasmTableMirror.length) __wasmTableMirror.length = funcPtr + 1;
3545+
__wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
3546+
}
3547+
return func;
3548+
},
3549+
3550+
$wbindArray__deps: ['$wbind'],
3551+
#else
3552+
$wbind: function(funcPtr) {
3553+
// In -Os and -Oz builds, do not implement a JS side wasm table mirror for small
3554+
// code size, but directly access wasmTable, which is a bit slower as uncached.
3555+
return wasmTable.get(funcPtr);
3556+
},
3557+
#endif
3558+
3559+
// A helper that binds a wasm function into a form that can be called by passing all
3560+
// the parameters in an array, e.g. wbindArray(func)([param1, param2, ..., paramN]).
3561+
$wbindArray: function(funcPtr) {
3562+
var func = wbind(funcPtr);
3563+
#if SHRINK_LEVEL == 0
3564+
// In optimized for speed builds, do a micro-optimization for the scenario when the
3565+
// target function does not take in any parameters.
3566+
return func.length
3567+
? function(args) { return func.apply(null, args); }
3568+
: function() { return func(); }
3569+
#else
3570+
// In optimized for size builds, conserve code size.
3571+
return function(args) { return func.apply(null, args); };
3572+
#endif
3573+
},
3574+
35353575
// Callable in pthread without __proxy needed.
35363576
emscripten_exit_with_live_runtime__sig: 'v',
35373577
#if !MINIMAL_RUNTIME

src/parseTools.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,7 @@ Please update to new syntax.`);
10121012
if (DYNCALLS) {
10131013
return `(function(cb, ${args}) { ${returnExpr} getDynCaller("${sig}", cb)(${args}) })`;
10141014
} else {
1015-
return `(function(cb, ${args}) { ${returnExpr} wasmTable.get(cb)(${args}) })`;
1015+
return `(function(cb, ${args}) { ${returnExpr} wbind(cb)(${args}) })`;
10161016
}
10171017
}
10181018

@@ -1024,7 +1024,7 @@ Please update to new syntax.`);
10241024
return `(function() { ${returnExpr} ${dyncall}.call(null, ${funcPtr}); })`;
10251025
}
10261026
} else {
1027-
return `wasmTable.get(${funcPtr})`;
1027+
return `wbind(${funcPtr})`;
10281028
}
10291029
}
10301030

tests/core/test_wbind.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <stdint.h>
2+
#include <assert.h>
3+
#include <stdio.h>
4+
5+
extern void test_wbind_iijdf(int (*test_func)(int, uint64_t, double, float));
6+
extern void test_wbind_ji(uint64_t (*test_func)(int));
7+
8+
int test_func_iijdf(int a, uint64_t b, double d, float f)
9+
{
10+
printf("a: %d\n", a);
11+
printf("b: %llx\n", b);
12+
printf("d: %g\n", d);
13+
printf("f: %f\n", f);
14+
return 42;
15+
}
16+
17+
uint64_t test_func_ji(int a)
18+
{
19+
printf("a: %d\n", a);
20+
return ((uint64_t)a << 32) | (uint64_t)a;
21+
}
22+
23+
int main()
24+
{
25+
test_wbind_iijdf(test_func_iijdf);
26+
test_wbind_ji(test_func_ji);
27+
}

tests/core/test_wbind.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
mergeInto(LibraryManager.library, {
2+
test_wbind_iijdf__deps: ['$wbind', '$wbindArray'],
3+
test_wbind_iijdf: function(funcPtr) {
4+
var ret = wbind(funcPtr)(1, BigInt(0x300000002), 4.2, 5.3);
5+
console.log(ret);
6+
7+
ret = wbindArray(funcPtr)([1, BigInt(0x300000002), 4.2, 5.3]);
8+
console.log(ret);
9+
},
10+
11+
test_wbind_ji__deps: ['$wbind', '$wbindArray'],
12+
test_wbind_ji: function(funcPtr) {
13+
var ret = wbind(funcPtr)(1);
14+
console.log(ret);
15+
16+
ret = wbindArray(funcPtr)([1]);
17+
console.log(ret);
18+
}
19+
});

tests/core/test_wbind.out

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
a: 1
2+
b: 300000002
3+
d: 4.2
4+
f: 5.300000
5+
42
6+
a: 1
7+
b: 300000002
8+
d: 4.2
9+
f: 5.300000
10+
42
11+
a: 1
12+
4294967297n
13+
a: 1
14+
4294967297n

tests/test_core.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,13 @@ def test_i64_invoke_bigint(self):
396396
self.node_args += ['--experimental-wasm-bigint']
397397
self.do_core_test('test_i64_invoke_bigint.cpp', js_engines=[config.NODE_JS])
398398

399+
@no_wasm2js('wasm_bigint')
400+
def test_wbind(self):
401+
self.set_setting('WASM_BIGINT')
402+
self.emcc_args += ['--js-library', test_file('core', 'test_wbind.js')]
403+
self.node_args += ['--experimental-wasm-bigint']
404+
self.do_core_test('test_wbind.c', js_engines=[config.NODE_JS])
405+
399406
def test_vararg_copy(self):
400407
self.do_run_in_out_file_test('va_arg', 'test_va_copy.c')
401408

0 commit comments

Comments
 (0)