|
1 | 1 | mergeInto(LibraryManager.library, {
|
2 |
| - $bindDynCall: function(funcPtr) { |
| 2 | + {{{ (function() { global.wbind = function() { return SHRINK_LEVEL == 0 ? 'wbind' : 'wasmTable.get'; }; return null; })(); }}} |
| 3 | + {{{ (function() { global.getDynCaller = function(sig) { return MINIMAL_RUNTIME ? `dynCalls[${sig}]` : `Module["dynCall_${sig}]`; }; return null; })(); }}} |
| 4 | + |
| 5 | +#if SHRINK_LEVEL == 0 |
| 6 | + // A mirror copy of contents of wasmTable in JS side, to avoid relatively |
| 7 | + // slow wasmTable.get() call. Only used when not compiling with -Os or -Oz. |
| 8 | + _wasmTableMirror: [], |
| 9 | + |
| 10 | + $wbind__deps: ['_wasmTableMirror'], |
| 11 | + $wbind: function(funcPtr) { |
| 12 | + var func = __wasmTableMirror[funcPtr]; |
| 13 | + if (!func) { |
| 14 | + if (funcPtr >= __wasmTableMirror.length) __wasmTableMirror.length = funcPtr + 1; |
| 15 | + __wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr); |
| 16 | + } |
| 17 | + return func; |
| 18 | + }, |
| 19 | + |
| 20 | + $dynCall__deps: ['$wbind'], |
| 21 | + $bindDynCall__deps: ['$wbind'], |
| 22 | + $wbindArray__deps: ['$wbind'], |
| 23 | +#else |
| 24 | + $wbind: function(funcPtr) { |
| 25 | + // In -Os and -Oz builds, do not implement a JS side wasm table mirror for small |
| 26 | + // code size, but directly access wasmTable, which is a bit slower. |
3 | 27 | return wasmTable.get(funcPtr);
|
4 | 28 | },
|
| 29 | +#endif |
5 | 30 |
|
6 |
| - $bindDynCallArray: function(funcPtr) { |
7 |
| - var func = wasmTable.get(funcPtr); |
8 |
| - return func.length ? function(args) { |
9 |
| - return func.apply(null, args); |
10 |
| - } : function() { return func(); } |
| 31 | + // A helper that binds a wasm function into a form that can be called by passing all |
| 32 | + // the parameters in an array, e.g. wbindArray(func)([param1, param2, ..., paramN]). |
| 33 | + $wbindArray: function(funcPtr) { |
| 34 | + var func = {{{wbind()}}}(funcPtr); |
| 35 | + return func.length |
| 36 | + ? function(args) { return func.apply(null, args); } |
| 37 | + : function() { return func(); } |
11 | 38 | },
|
12 | 39 |
|
13 |
| -#if USE_LEGACY_DYNCALLS || !WASM_BIGINT |
14 |
| - $dynCallLegacy: function(sig, ptr, args) { |
15 |
| -#if ASSERTIONS |
16 |
| - assert(('dynCall_' + sig) in Module, 'bad function pointer type - no table for sig \'' + sig + '\''); |
17 |
| - if (args && args.length) { |
18 |
| - // j (64-bit integer) must be passed in as two numbers [low 32, high 32]. |
19 |
| - assert(args.length === sig.substring(1).replace(/j/g, '--').length); |
20 |
| - } else { |
21 |
| - assert(sig.length == 1); |
22 |
| - } |
23 |
| -#endif |
24 |
| - if (args && args.length) { |
25 |
| - return Module['dynCall_' + sig].apply(null, [ptr].concat(args)); |
26 |
| - } |
27 |
| - return Module['dynCall_' + sig].call(null, ptr); |
| 40 | + // A helper that returns a function that can be used to invoke function pointers, i.e. |
| 41 | + // getDynCaller('vi')(funcPtr, myInt); |
| 42 | + $getDynCaller: function(sig, funcPtr) { |
| 43 | + return {{{getDynCaller('sig')}}}; |
28 | 44 | },
|
29 | 45 |
|
30 |
| - // Used in library code to get JS function from wasm function pointer. |
31 |
| - // All callers should use direct table access where possible and only fall |
32 |
| - // back to this function if needed. |
33 |
| - $getDynCaller__deps: ['$dynCall'], |
34 |
| - $getDynCaller: function(sig, ptr) { |
35 |
| -#if !USE_LEGACY_DYNCALLS |
36 |
| - assert(sig.indexOf('j') >= 0, 'getDynCaller should only be called with i64 sigs') |
37 |
| -#endif |
38 |
| - var argCache = []; |
39 |
| - return function() { |
40 |
| - argCache.length = arguments.length; |
41 |
| - for (var i = 0; i < arguments.length; i++) { |
42 |
| - argCache[i] = arguments[i]; |
43 |
| - } |
44 |
| - return dynCall(sig, ptr, argCache); |
45 |
| - }; |
| 46 | + $bindDynCall: function(sig, funcPtr) { |
| 47 | + // For int64 signatures, use the dynCall_sig dispatch mechanism. |
| 48 | + if (sig.includes('j')) return function(args) { |
| 49 | + return {{{getDynCaller('sig')}}}.apply(null, [funcPtr].concat(args)); |
| 50 | + } |
| 51 | + // For non-int64 signatures, invoke via the wasm table. |
| 52 | + var func = {{{wbind()}}}(funcPtr); |
| 53 | + return func.length |
| 54 | + ? function(args) { return func.apply(null, args); } |
| 55 | + : function() { return func(); } |
46 | 56 | },
|
47 |
| -#endif |
48 | 57 |
|
49 |
| -// $dynCall__deps: ['$dynCallLegacy'], |
50 |
| - $dynCall: function(sig, ptr, args) { |
51 |
| -#if USE_LEGACY_DYNCALLS |
52 |
| -#if MINIMAL_RUNTIME |
53 |
| - var func = dynCalls[sig]; |
54 |
| -#else |
55 |
| - var func = Module['dynCall_'+sig]; |
56 |
| -#endif |
57 |
| - return args ? func.apply(null, [ptr].concat(args)) : func(ptr); |
58 |
| -#else |
59 |
| -#if !WASM_BIGINT |
60 |
| - // Without WASM_BIGINT support we cannot directly call function with i64 as |
61 |
| - // part of thier signature, so we rely the dynCall functions generated by |
62 |
| - // wasm-emscripten-finalize |
63 |
| - if (sig.indexOf('j') != -1) { |
64 |
| -#if MINIMAL_RUNTIME |
65 |
| - var func = dynCalls[sig]; |
66 |
| -#else |
67 |
| - var func = Module['dynCall_'+sig]; |
68 |
| -#endif |
69 |
| - return args ? func.apply(null, [ptr].concat(args)) : func(ptr); |
| 58 | + $dynCall: function(sig, funcPtr, args) { |
| 59 | + // For int64 signatures, use the dynCall_sig dispatch mechanism. |
| 60 | + if (sig.includes('j')) { |
| 61 | + return {{{getDynCaller('sig')}}}.apply(null, [funcPtr].concat(args)); |
70 | 62 | }
|
71 |
| -#endif |
72 |
| -#if ASSERTIONS |
73 |
| - assert(wasmTable.get(ptr), 'missing table entry in dynCall: ' + ptr); |
74 |
| -#endif |
75 |
| - return wasmTable.get(ptr).apply(null, args) |
76 |
| -#endif |
| 63 | + |
| 64 | + // For non-int64 signatures, invoke via the wasm table. |
| 65 | + return {{{wbind()}}}(funcPtr).apply(null, args); |
77 | 66 | }
|
78 | 67 | });
|
0 commit comments