Skip to content
21 changes: 17 additions & 4 deletions emscripten.py
Original file line number Diff line number Diff line change
Expand Up @@ -1798,18 +1798,26 @@ def create_fp_accessors(metadata):
'perhaps a side module was not linked in? if this symbol was expected to arrive '
'from a system library, try to build the MAIN_MODULE with '
'EMCC_FORCE_STDLIBS=XX in the environment");')
# the name of the original function is generally the normal function
# name, unless it is legalized, in which case the export is the legalized
# version, and the original provided by orig$X
if shared.Settings.LEGALIZE_JS_FFI and not shared.JS.is_legal_sig(sig):
name = 'orig$' + name

accessors.append('''
Module['%(full)s'] = function() {
%(assert)s
var func = Module['%(mangled)s'];
if (!func)
func = %(mangled)s;
// Use the wasm function itself, for the table.
var func = Module['asm']['%(original)s'];
// If there is no wasm function, this may be a JS library function or
// something from another module.
if (!func) func = Module['%(mangled)s'];
if (!func) func = %(mangled)s;
var fp = addFunction(func, '%(sig)s');
Module['%(full)s'] = function() { return fp };
return fp;
}
''' % {'full': asmjs_mangle(fullname), 'mangled': mangled, 'assert': assertion, 'sig': sig})
''' % {'full': asmjs_mangle(fullname), 'mangled': mangled, 'original': name, 'assert': assertion, 'sig': sig})

return '\n'.join(accessors)

Expand Down Expand Up @@ -2319,6 +2327,11 @@ def debug_copy(src, dst):
args.append('--check-stack-overflow')
if shared.Settings.STANDALONE_WASM:
args.append('--standalone-wasm')
# When we dynamically link our JS loader adds functions from wasm modules to
# the table. It must add the original versions of them, not legalized ones,
# so that indirect calls have the right type, so export those.
if shared.Settings.RELOCATABLE:
args.append('--pass-arg=legalize-js-interface-export-originals')
stdout = shared.Building.run_binaryen_command('wasm-emscripten-finalize',
infile=base_wasm,
outfile=wasm,
Expand Down
8 changes: 6 additions & 2 deletions src/support.js
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,10 @@ function loadWebAssemblyModule(binary, flags) {
// b) Symbols from loaded modules are not always added to the global Module.
var moduleLocal = {};

var resolveSymbol = function(sym, type) {
var resolveSymbol = function(sym, type, legalized) {
if (legalized) {
sym = 'orig$' + sym;
}
#if WASM_BACKEND
sym = '_' + sym;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use asmjs_mangle here? Also does the mangling happen before the orig$ .. i.e. is it _orig$foo or orig$foo. Above it looks like your remove the mangled before pretending orig$.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pre-existing code, but I think asm_mangle in python makes sense (where it checks if the _ is needed or not, which it isn't for dynCall etc.) while here, all we have are exported symbols at the C level, which does not include things like dynCall etc. that are only for JS.

#endif
Expand Down Expand Up @@ -496,10 +499,11 @@ function loadWebAssemblyModule(binary, flags) {
assert(parts.length == 3)
var name = parts[1];
var sig = parts[2];
var legalized = sig.indexOf('j') >= 0; // check for i64s
var fp = 0;
return obj[prop] = function() {
if (!fp) {
var f = resolveSymbol(name, 'function');
var f = resolveSymbol(name, 'function', legalized);
fp = addFunction(f, sig);
}
return fp;
Expand Down
209 changes: 209 additions & 0 deletions tests/other/metadce/hello_world_O3_MAIN_MODULE.exports
Original file line number Diff line number Diff line change
Expand Up @@ -1115,6 +1115,215 @@ opterr
optind
optopt
optreset
orig$__addtf3
orig$__ashldi3
orig$__ashlti3
orig$__ashrdi3
orig$__ashrti3
orig$__atomic_compare_exchange_16
orig$__atomic_compare_exchange_8
orig$__atomic_exchange_16
orig$__atomic_exchange_8
orig$__atomic_fetch_add_16
orig$__atomic_fetch_add_8
orig$__atomic_fetch_and_16
orig$__atomic_fetch_and_8
orig$__atomic_fetch_or_16
orig$__atomic_fetch_or_8
orig$__atomic_fetch_sub_16
orig$__atomic_fetch_sub_8
orig$__atomic_fetch_xor_16
orig$__atomic_fetch_xor_8
orig$__atomic_load_8
orig$__atomic_store_16
orig$__atomic_store_8
orig$__clzti2
orig$__cosl
orig$__divdi3
orig$__divmoddi4
orig$__divtf3
orig$__divti3
orig$__eqtf2
orig$__fixdfdi
orig$__fixtfdi
orig$__fixtfsi
orig$__fixtfti
orig$__fixunsdfdi
orig$__fixunstfdi
orig$__fixunstfsi
orig$__fixunstfti
orig$__floatdidf
orig$__floatditf
orig$__floattidf
orig$__floattisf
orig$__floattitf
orig$__floatunditf
orig$__floatuntidf
orig$__floatuntisf
orig$__fpclassifyl
orig$__fseeko
orig$__fseeko_unlocked
orig$__ftello
orig$__ftello_unlocked
orig$__getf2
orig$__gttf2
orig$__intscan
orig$__invtrigl_R
orig$__letf2
orig$__lgammal_r
orig$__lshrdi3
orig$__lshrti3
orig$__lttf2
orig$__mmap
orig$__moddi3
orig$__modti3
orig$__muldi3
orig$__multc3
orig$__multf3
orig$__multi3
orig$__netf2
orig$__p1evll
orig$__polevll
orig$__rand48_step
orig$__rem_pio2l
orig$__shlim
orig$__signbitl
orig$__sinl
orig$__stdio_seek
orig$__strtoimax_internal
orig$__strtoll_internal
orig$__strtoull_internal
orig$__strtoumax_internal
orig$__subtf3
orig$__tanl
orig$__trunctfdf2
orig$__trunctfsf2
orig$__udivdi3
orig$__udivmoddi4
orig$__udivmodti4
orig$__udivti3
orig$__umoddi3
orig$__umodti3
orig$__unordtf2
orig$__uremdi3
orig$_emscripten_atomic_fetch_and_add_u64
orig$_emscripten_atomic_fetch_and_and_u64
orig$_emscripten_atomic_fetch_and_or_u64
orig$_emscripten_atomic_fetch_and_sub_u64
orig$_emscripten_atomic_fetch_and_xor_u64
orig$acoshl
orig$acosl
orig$asinhl
orig$asinl
orig$atan2l
orig$atanhl
orig$atanl
orig$atoll
orig$cbrtl
orig$copysignl
orig$coshl
orig$cosl
orig$emscripten_atomic_add_u64
orig$emscripten_atomic_and_u64
orig$emscripten_atomic_cas_u64
orig$emscripten_atomic_exchange_u64
orig$emscripten_atomic_load_u64
orig$emscripten_atomic_or_u64
orig$emscripten_atomic_store_u64
orig$emscripten_atomic_sub_u64
orig$emscripten_atomic_xor_u64
orig$erfcl
orig$erfl
orig$exp10l
orig$exp2l
orig$expl
orig$expm1l
orig$fdiml
orig$ffsll
orig$fmal
orig$fmaxl
orig$fminl
orig$fmodl
orig$frexpl
orig$fseeko
orig$fseeko64
orig$ftello
orig$ftello64
orig$ftruncate
orig$ftruncate64
orig$hypotl
orig$ilogbl
orig$imaxabs
orig$imaxdiv
orig$ldexpl
orig$lgammal
orig$lgammal_r
orig$llabs
orig$lldiv
orig$llrint
orig$llrintf
orig$llrintl
orig$llround
orig$llroundf
orig$llroundl
orig$lockf
orig$lockf64
orig$log10l
orig$log1pl
orig$log2l
orig$logbl
orig$logl
orig$lrintl
orig$lroundl
orig$lseek
orig$lseek64
orig$mmap
orig$mmap64
orig$modfl
orig$nearbyintl
orig$nextafterl
orig$nexttoward
orig$nexttowardf
orig$nexttowardl
orig$posix_fadvise
orig$posix_fadvise64
orig$posix_fallocate
orig$posix_fallocate64
orig$pow10l
orig$powl
orig$pread
orig$pread64
orig$preadv
orig$preadv64
orig$pwrite
orig$pwrite64
orig$pwritev
orig$pwritev64
orig$remainderl
orig$remquol
orig$rintl
orig$roundl
orig$scalblnl
orig$scalbnl
orig$sincosl
orig$sinhl
orig$sinl
orig$strtoimax
orig$strtoll
orig$strtoll_l
orig$strtoull
orig$strtoull_l
orig$strtoumax
orig$tanhl
orig$tanl
orig$tgammal
orig$truncate
orig$truncate64
orig$truncl
orig$wcstoimax
orig$wcstoll
orig$wcstoull
orig$wcstoumax
pause
pclose
perror
Expand Down
10 changes: 8 additions & 2 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3893,9 +3893,15 @@ def test_dylink_i64_b(self):
#include <stdio.h>
#include <stdint.h>
extern int64_t sidey();
int64_t testAdd(int64_t a) {
return a + 1;
}
typedef int64_t (*testAddHandler)(int64_t);
testAddHandler h = &testAdd;
int main() {
printf("other says %lld.\n", sidey());
return 0;
int64_t r = h(42);
printf("my fp says: %lld.\n", r);
}
''', '''
#include <stdint.h>
Expand All @@ -3905,7 +3911,7 @@ def test_dylink_i64_b(self):
x = 18 - x;
return x;
}
''', 'other says -1311768467750121224.')
''', 'other says -1311768467750121224.\nmy fp says: 43.')

@needs_dlfcn
def test_dylink_class(self):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -8171,7 +8171,7 @@ def test_metadce_cxx_fastcomp(self, *args):
# don't compare the # of functions in a main module, which changes a lot
# TODO(sbc): Investivate why the number of exports is order of magnitude
# larger for wasm backend.
'main_module_1': (['-O3', '-s', 'MAIN_MODULE=1'], 174, [], [], 517336, None, 1520, None), # noqa
'main_module_1': (['-O3', '-s', 'MAIN_MODULE=1'], 174, [], [], 517336, None, 1729, None), # noqa
'main_module_2': (['-O3', '-s', 'MAIN_MODULE=2'], 12, [], [], 10770, 12, 10, None), # noqa
})
@no_fastcomp()
Expand Down
4 changes: 4 additions & 0 deletions tools/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -3025,6 +3025,10 @@ def legalize_sig(sig):
ret.append('i')
return ''.join(ret)

@staticmethod
def is_legal_sig(sig):
return sig == JS.legalize_sig(sig)

@staticmethod
def make_extcall(sig, named=True):
args = ','.join(['a' + str(i) for i in range(1, len(sig))])
Expand Down