Skip to content

Commit

Permalink
Fix emulated function pointer cast exporting (#6939)
Browse files Browse the repository at this point in the history
Emulated function pointers is the mode where we do calls from JS using the wasm Table, which is how we currently do dynamic linking in both asm.js and wasm (in asm.js, this mode creates something like a wasm Table on the outside of the asm.js, and calls that). Emulated function pointer casts is where we assume a function pointer type may be cast in a weird way, so we make sure indirect calls work even with the wrong argument number or type, sort of like native platforms do. The "trick" we use for that is to use i64s for all values, and cast as necessary. For this mode, we export every single function's function table index, as we need those from JS - we can't call them as wasm exports, as they return i64. So we call dynCall of the right signature, and then inside wasm we cast the i64 to what we want, and return that to JS.

The bug here is that we mixed those two modes up - we exported all the function pointers for the former mode, when we just need it in the latter. So this just changes up a few ifdefs to the proper mode. Note the effect on the metadce test - a dynamic library now has far fewer exports and is smaller.
  • Loading branch information
kripken authored Aug 3, 2018
1 parent 699d457 commit f15e66a
Show file tree
Hide file tree
Showing 4 changed files with 6 additions and 6 deletions.
2 changes: 1 addition & 1 deletion emscripten.py
Original file line number Diff line number Diff line change
Expand Up @@ -1289,7 +1289,7 @@ def create_exports(exported_implemented_functions, in_table, function_table_data
exports.append(quote(str(k)) + ': ' + str(v))
# shared wasm emulated function pointer mode requires us to know the function pointer for
# each function. export fp$func => function pointer for func
if shared.Settings.WASM and shared.Settings.RELOCATABLE and shared.Settings.EMULATED_FUNCTION_POINTERS:
if shared.Settings.WASM and shared.Settings.RELOCATABLE and shared.Settings.EMULATE_FUNCTION_POINTER_CASTS:
for k, v in metadata['functionPointers'].items():
exports.append(quote('fp$' + str(k)) + ': ' + str(v))
return '{ ' + ', '.join(exports) + ' }'
Expand Down
4 changes: 2 additions & 2 deletions src/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -1865,7 +1865,7 @@ LibraryManager.library = {
var result = lib.module[symbol];
if (typeof result === 'function') {
#if WASM
#if EMULATED_FUNCTION_POINTERS
#if EMULATE_FUNCTION_POINTER_CASTS
// for wasm with emulated function pointers, the i64 ABI is used for all
// function calls, so we can't just call addFunction on something JS
// can call (which does not use that ABI), as the function pointer would
Expand All @@ -1881,7 +1881,7 @@ LibraryManager.library = {
assert(typeof result === 'number', 'could not find function pointer for ' + symbol);
#endif // ASSERTIONS
return result;
#endif // EMULATED_FUNCTION_POINTERS
#endif // EMULATE_FUNCTION_POINTER_CASTS
#endif // WASM
// convert the exported function into a function pointer using our generic
// JS mechanism.
Expand Down
4 changes: 2 additions & 2 deletions src/support.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,14 +229,14 @@ function loadWebAssemblyModule(binary, loadAsync) {
}
if (typeof value === 'number') {
// relocate it - modules export the absolute value, they can't relocate before they export
#if EMULATED_FUNCTION_POINTERS
#if EMULATE_FUNCTION_POINTER_CASTS
// it may be a function pointer
if (e.substr(0, 3) == 'fp$' && typeof instance.exports[e.substr(3)] === 'function') {
value = value + env['tableBase'];
} else {
#endif
value = value + env['memoryBase'];
#if EMULATED_FUNCTION_POINTERS
#if EMULATE_FUNCTION_POINTER_CASTS
}
#endif
}
Expand Down
2 changes: 1 addition & 1 deletion tests/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -8091,7 +8091,7 @@ def test(filename, expectations):
0, [], ['tempDoublePtr', 'waka'], 8, 0, 0), # totally empty!
# but we don't metadce with linkable code! other modules may want it
(['-O3', '-s', 'MAIN_MODULE=1'],
1534, ['invoke_i'], ['waka'], 496958, 163, 2560),
1534, ['invoke_i'], ['waka'], 469663, 163, 1449),
])

print('test on a minimal pure computational thing')
Expand Down

0 comments on commit f15e66a

Please sign in to comment.