Skip to content

Commit dd74679

Browse files
authored
Support using JSPI to load secondary wasm-split module. (#18519)
Passes all the needed arguments to the JSPI pass and the wasm-split run. Changes the current `instantiateAsync` and friends to use arguments instead of globals so they can be reused by the new `emscripten_load_secondary_module` to asynchronously load the secondary module. Depends on WebAssembly/binaryen#5431
1 parent 33a9cf1 commit dd74679

File tree

6 files changed

+195
-139
lines changed

6 files changed

+195
-139
lines changed

emcc.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
'emscripten_idb_store', 'emscripten_idb_delete', 'emscripten_idb_exists',
105105
'emscripten_idb_load_blob', 'emscripten_idb_store_blob', 'SDL_Delay',
106106
'emscripten_scan_registers', 'emscripten_lazy_load_code',
107-
'emscripten_fiber_swap',
107+
'emscripten_fiber_swap', '__load_secondary_module',
108108
'wasi_snapshot_preview1.fd_sync', '__wasi_fd_sync', '_emval_await',
109109
'_dlopen_js', '__asyncjs__*'
110110
]
@@ -706,6 +706,9 @@ def check_human_readable_list(items):
706706
passes += ['--jspi']
707707
passes += ['--pass-arg=jspi-imports@%s' % ','.join(settings.ASYNCIFY_IMPORTS)]
708708
passes += ['--pass-arg=jspi-exports@%s' % ','.join(settings.ASYNCIFY_EXPORTS)]
709+
if settings.SPLIT_MODULE:
710+
passes += ['--pass-arg=jspi-split-module']
711+
709712
if settings.BINARYEN_IGNORE_IMPLICIT_TRAPS:
710713
passes += ['--ignore-implicit-traps']
711714
# normally we can assume the memory, if imported, has not been modified
@@ -751,9 +754,12 @@ def make_js_executable(script):
751754
pass # can fail if e.g. writing the executable to /dev/null
752755

753756

754-
def do_split_module(wasm_file):
757+
def do_split_module(wasm_file, options):
755758
os.rename(wasm_file, wasm_file + '.orig')
756759
args = ['--instrument']
760+
if options.requested_debug:
761+
# Tell wasm-split to preserve function names.
762+
args += ['-g']
757763
building.run_binaryen_command('wasm-split', wasm_file + '.orig', outfile=wasm_file, args=args)
758764

759765

@@ -2527,6 +2533,9 @@ def check_memory_setting(setting):
25272533
if settings.LEGALIZE_JS_FFI:
25282534
settings.REQUIRED_EXPORTS += ['__get_temp_ret', '__set_temp_ret']
25292535

2536+
if settings.SPLIT_MODULE and settings.ASYNCIFY == 2:
2537+
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['_load_secondary_module']
2538+
25302539
# wasm side modules have suffix .wasm
25312540
if settings.SIDE_MODULE and shared.suffix(target) == '.js':
25322541
diagnostics.warning('emcc', 'output suffix .js requested, but wasm side modules are just wasm files; emitting only a .wasm, no .js')
@@ -3192,7 +3201,7 @@ def phase_final_emitting(options, state, target, wasm_target, memfile):
31923201

31933202
if settings.SPLIT_MODULE:
31943203
diagnostics.warning('experimental', 'The SPLIT_MODULE setting is experimental and subject to change')
3195-
do_split_module(wasm_target)
3204+
do_split_module(wasm_target, options)
31963205

31973206
for f in generated_text_files_with_native_eols:
31983207
tools.line_endings.convert_line_endings_in_file(f, os.linesep, options.output_eol)

emscripten.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,11 @@ def add_standard_wasm_imports(send_items_map):
666666
'store_val_f64',
667667
]
668668

669+
if settings.SPLIT_MODULE and settings.ASYNCIFY == 2:
670+
# Calls to this function are generated by binaryen so it must be manually
671+
# imported.
672+
extra_sent_items.append('__load_secondary_module')
673+
669674
for s in extra_sent_items:
670675
send_items_map[s] = s
671676

src/library_async.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,18 @@ mergeInto(LibraryManager.library, {
533533
});
534534
},
535535

536+
_load_secondary_module__sig: 'v',
537+
_load_secondary_module: async function() {
538+
// Mark the module as loading for the wasm module (so it doesn't try to load it again).
539+
Module['asm']['load_secondary_module_status'].value = 1;
540+
var imports = {'primary': Module['asm']};
541+
// Replace '.wasm' suffix with '.deferred.wasm'.
542+
var deferred = wasmBinaryFile.slice(0, -5) + '.deferred.wasm';
543+
await new Promise((resolve) => {
544+
instantiateAsync(null, deferred, imports, resolve);
545+
});
546+
},
547+
536548
$Fibers__deps: ['$Asyncify'],
537549
$Fibers: {
538550
nextFiber: 0,

0 commit comments

Comments
 (0)