Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions emscripten.py
Original file line number Diff line number Diff line change
Expand Up @@ -2206,8 +2206,25 @@ def emscript_wasm_backend(infile, outfile, memfile, compiler_engine,
# * Run wasm-emscripten-finalize to extract metadata and modify the binary
# to use emscripten's wasm<->JS ABI
# * Use the metadata to generate the JS glue that goes with the wasm
if shared.Settings.MAIN_MODULE:
# Run compile_settings here to retrieve all the JS library functions.
# Unfortunately, we need to run it later again to capture the exported functions
# from the Wasm
glue, forwarded_data = compile_settings(compiler_engine, temp_files)
forwarded_json = json.loads(forwarded_data)
library_fns = forwarded_json['Functions']['libraryFunctions']
library_fns_list = []
for name in library_fns:
library_fns_list.append(name)

js_symbols = infile + '.js_symbols'
with open(js_symbols, 'w') as js_symbols_file:
for sym in library_fns_list:
js_symbols_file.write(sym + '\n')
else:
js_symbols = []
Copy link
Collaborator

Choose a reason for hiding this comment

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

I stole this idea/code and made it part of #10350 in a function called get_all_js_library_funcs hopefully that is about to land and we can use that shared function here.


metadata = finalize_wasm(temp_files, infile, outfile, memfile, DEBUG)
metadata = finalize_wasm(temp_files, infile, outfile, memfile, DEBUG, js_symbols)

update_settings_glue(metadata, DEBUG)

Expand Down Expand Up @@ -2318,7 +2335,7 @@ def remove_trailing_zeros(memfile):
f.write(mem_data[:end])


def finalize_wasm(temp_files, infile, outfile, memfile, DEBUG):
def finalize_wasm(temp_files, infile, outfile, memfile, DEBUG, libraryfile):
basename = shared.unsuffixed(outfile.name)
wasm = basename + '.wasm'
base_wasm = infile
Expand Down Expand Up @@ -2365,6 +2382,9 @@ def finalize_wasm(temp_files, infile, outfile, memfile, DEBUG):
args.append('--pass-arg=legalize-js-interface-export-originals')
if shared.Settings.FULL_DWARF:
args.append('--dwarf')

if shared.Settings.MAIN_MODULE and libraryfile:
args.append('--pass-arg=js-symbols@%s' % libraryfile)
stdout = shared.Building.run_binaryen_command('wasm-emscripten-finalize',
infile=base_wasm,
outfile=wasm,
Expand Down
35 changes: 35 additions & 0 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -8559,6 +8559,41 @@ def test_safe_stack_dylink(self):
}
''', ['abort(stack overflow)', '__handle_stack_overflow'], assert_returncode=None)

@no_fastcomp('WASM backend convert imports to indirect calls')
@needs_dlfcn
def test_dylink_imports_to_indirect_calls(self):
# The ImportsToIndirectCalls pass in Binaryen should not allocate a new fp$ for
# imports that are already address taken. Test out both cases whereby the imports
# are either used directly or thru its address.
self.set_setting('EXIT_RUNTIME', 1)
self.dylink_test(main=r'''
#include <stdio.h>
extern int sidey();
extern int sidey2();
typedef int (*func)();
int mainy() {
return 19;
}

int main(int argc, char **argv) {
sidey();
func funcPtr = (0 == argc) ? sidey:sidey2;
funcPtr();
return 0;
}
''', side=r'''
#include <stdio.h>
int sidey() {
printf("sidey says %d ", 17);
return 17;
}

int sidey2() {
printf("sidey2 says %d", 18);
return 18;
}
''', expected='sidey says 17 sidey2 says 18', need_reverse=False)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we somehow verify that this worked by looking at import/exports of the resulting wasm file?


@also_with_standalone_wasm
def test_undefined_main(self):
# By default in emscripten we allow main to be undefined. Its used when
Expand Down