Skip to content

Commit d8a2dd9

Browse files
committed
Optimize makeDynCall to use dynCall_xx function directly where needed
Now the runtime `dynCall` is only used in places where the signature is not known at compile time, such as embind or (the internally unused) `getFuncWrapper`. Move `getDynCaller` into embind.js which is the only place it was used.
1 parent 5dc1e7c commit d8a2dd9

File tree

7 files changed

+39
-36
lines changed

7 files changed

+39
-36
lines changed

emcc.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,7 +1381,6 @@ def filter_out_duplicate_dynamic_libs(inputs):
13811381
# See: https://github.com/emscripten-core/emscripten/issues/12065
13821382
# See: https://github.com/emscripten-core/emscripten/issues/12066
13831383
shared.Settings.USE_LEGACY_DYNCALLS = 1
1384-
shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$getDynCaller']
13851384
shared.Settings.EXPORTED_FUNCTIONS += ['_emscripten_stack_get_base',
13861385
'_emscripten_stack_get_end',
13871386
'_emscripten_stack_set_limits']
@@ -1614,18 +1613,12 @@ def filter_out_duplicate_dynamic_libs(inputs):
16141613
if not shared.Settings.MINIMAL_RUNTIME or shared.Settings.EXIT_RUNTIME:
16151614
# MINIMAL_RUNTIME only needs callRuntimeCallbacks in certain cases, but the normal runtime
16161615
# always does.
1617-
shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$callRuntimeCallbacks', '$dynCall']
1616+
shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$callRuntimeCallbacks']
16181617

16191618
if shared.Settings.USE_PTHREADS:
16201619
# memalign is used to ensure allocated thread stacks are aligned.
16211620
shared.Settings.EXPORTED_FUNCTIONS += ['_memalign']
16221621

1623-
# dynCall is used to call pthread entry points in worker.js (as
1624-
# metadce does not consider worker.js, which is external, we must
1625-
# consider it an export, i.e., one which can never be removed).
1626-
shared.Settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$dynCall']
1627-
shared.Settings.EXPORTED_FUNCTIONS += ['dynCall']
1628-
16291622
if shared.Settings.MINIMAL_RUNTIME:
16301623
building.user_requested_exports += ['exit']
16311624

src/embind/embind.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,6 +1062,26 @@ var LibraryEmbind = {
10621062
#endif
10631063
},
10641064

1065+
#if USE_LEGACY_DYNCALLS || !WASM_BIGINT
1066+
// Used in library code to get JS function from wasm function pointer.
1067+
// All callers should use direct table access where possible and only fall
1068+
// back to this function if needed.
1069+
$getDynCaller__deps: ['$dynCall'],
1070+
$getDynCaller: function(sig, ptr) {
1071+
#if !USE_LEGACY_DYNCALLS
1072+
assert(sig.indexOf('j') >= 0, 'getDynCaller should only be called with i64 sigs')
1073+
#endif
1074+
var argCache = [];
1075+
return function() {
1076+
argCache.length = arguments.length;
1077+
for (var i = 0; i < arguments.length; i++) {
1078+
argCache[i] = arguments[i];
1079+
}
1080+
return dynCall(sig, ptr, argCache);
1081+
};
1082+
},
1083+
#endif
1084+
10651085
$embind__requireFunction__deps: ['$readLatin1String', '$throwBindingError'
10661086
#if USE_LEGACY_DYNCALLS || !WASM_BIGINT
10671087
, '$getDynCaller'

src/library.js

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3707,27 +3707,9 @@ LibraryManager.library = {
37073707
return Module['dynCall_' + sig].call(null, ptr);
37083708
},
37093709
$dynCall__deps: ['$dynCallLegacy'],
3710-
3711-
// Used in library code to get JS function from wasm function pointer.
3712-
// All callers should use direct table access where possible and only fall
3713-
// back to this function if needed.
3714-
$getDynCaller__deps: ['$dynCall'],
3715-
$getDynCaller: function(sig, ptr) {
3716-
#if !USE_LEGACY_DYNCALLS
3717-
assert(sig.indexOf('j') >= 0, 'getDynCaller should only be called with i64 sigs')
3718-
#endif
3719-
var argCache = [];
3720-
return function() {
3721-
argCache.length = arguments.length;
3722-
for (var i = 0; i < arguments.length; i++) {
3723-
argCache[i] = arguments[i];
3724-
}
3725-
return dynCall(sig, ptr, argCache);
3726-
};
3727-
},
37283710
#endif
37293711

3730-
$dynCall: function (sig, ptr, args) {
3712+
$dynCall: function(sig, ptr, args) {
37313713
#if USE_LEGACY_DYNCALLS
37323714
return dynCallLegacy(sig, ptr, args);
37333715
#else

src/library_browser.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,10 +1105,9 @@ var LibraryBrowser = {
11051105
},
11061106

11071107
// TODO: currently not callable from a pthread, but immediately calls onerror() if not on main thread.
1108-
emscripten_async_load_script__deps: ['$getFuncWrapper'],
11091108
emscripten_async_load_script: function(url, onload, onerror) {
1110-
onload = getFuncWrapper(onload, 'v');
1111-
onerror = getFuncWrapper(onerror, 'v');
1109+
onload = {{{ makeDynCall('v', 'onload') }}};
1110+
onerror = {{{ makeDynCall('v', 'onerror') }}};
11121111

11131112
#if USE_PTHREADS
11141113
if (ENVIRONMENT_IS_PTHREAD) {
@@ -1197,7 +1196,7 @@ var LibraryBrowser = {
11971196
emscripten_set_main_loop__deps: ['$setMainLoop'],
11981197
emscripten_set_main_loop__docs: '/** @param {number|boolean=} noSetTiming */',
11991198
emscripten_set_main_loop: function(func, fps, simulateInfiniteLoop, arg, noSetTiming) {
1200-
var browserIterationFunc = function() { {{{ makeDynCall('v', 'func') }}}(); };
1199+
var browserIterationFunc = {{{ makeDynCall('v', 'func') }}};
12011200
setMainLoop(browserIterationFunc, fps, simulateInfiniteLoop, arg, noSetTiming);
12021201
},
12031202

@@ -1519,7 +1518,6 @@ var LibraryBrowser = {
15191518
Browser.workers[id] = null;
15201519
},
15211520

1522-
emscripten_call_worker__deps: ['$getFuncWrapper'],
15231521
emscripten_call_worker__proxy: 'sync',
15241522
emscripten_call_worker__sig: 'viiiiii',
15251523
emscripten_call_worker: function(id, funcName, data, size, callback, arg) {
@@ -1531,7 +1529,7 @@ var LibraryBrowser = {
15311529
if (callback) {
15321530
callbackId = info.callbacks.length;
15331531
info.callbacks.push({
1534-
func: getFuncWrapper(callback, 'viii'),
1532+
func: {{{ makeDynCall('viii', 'callback') }}},
15351533
arg: arg
15361534
});
15371535
info.awaited++;

src/parseTools.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -985,7 +985,17 @@ function makeDynCall(sig, funcPtr) {
985985
}
986986
}
987987
if (USE_LEGACY_DYNCALLS) {
988-
return `getDynCaller("${sig}", ${funcPtr})`;
988+
let dyncall = exportedAsmFunc(`dynCall_${sig}`)
989+
if (sig.length > 1) {
990+
let args = [];
991+
for (let i = 1; i < sig.length; ++i) {
992+
args.push(`a${i}`);
993+
}
994+
args = args.join(', ');
995+
return `(function(${args}) { ${dyncall}.apply(null, [${funcPtr}, ${args}]); })`;
996+
} else {
997+
return `(function() { ${dyncall}.call(null, ${funcPtr}); })`;
998+
}
989999
} else {
9901000
return `wasmTable.get(${funcPtr})`;
9911001
}

src/worker.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ this.onmessage = function(e) {
188188
// enable that to work. If you find the following line to crash, either change the signature
189189
// to "proper" void *ThreadMain(void *arg) form, or try linking with the Emscripten linker
190190
// flag -s EMULATE_FUNCTION_POINTER_CASTS=1 to add in emulation for this x86 ABI extension.
191-
var result = Module['dynCall']('ii', e.data.start_routine, [e.data.arg]);
191+
var result = {{{ makeDynCall('ii', 'e.data.start_routine') }}} (e.data.arg);
192192

193193
#if STACK_OVERFLOW_CHECK
194194
Module['checkStackCookie']();

tools/ports/sdl2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def clear(ports, settings, shared):
9090

9191

9292
def process_dependencies(settings):
93-
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$autoResumeAudioContext']
93+
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$autoResumeAudioContext', '$dynCall']
9494

9595

9696
def process_args(ports):

0 commit comments

Comments
 (0)