Unify module splitting implementation for JSPI#26396
Unify module splitting implementation for JSPI#26396brendandahl wants to merge 1 commit intoemscripten-core:mainfrom
Conversation
Previously, module splitting with JSPI required a special built-in function `__load_secondary_module` and wasm-split setting to coordinate the loading of the secondary module. This change updates the `splitModuleProxyHandler` to support JSPI by wrapping the generated placeholder functions in `WebAssembly.Suspending`. The placeholder will then automatically load the secondary module asynchronously. A standalone `save_profile_data.js` script is extracted from existing tests for reuse, and a new test `test_split_module_embind_jspi` is added to ensure module splitting functions correctly alongside embind and JSPI.
|
For some more context: The old version of JSPI required changes to wasm so this new approach wasn't possible. |
aheejin
left a comment
There was a problem hiding this comment.
Sorry for the delay!
By the way, what made this possible? In other words, why did we have to resort to __load_secondary_module function before and not anymore?
| dbg('instantiated deferred module, continuing'); | ||
| #endif | ||
| return wasmTable.get({{{ toIndexType('base') }}})(...args); | ||
| return wasmTable.get({{{toIndexType('base')}}})(...args); |
There was a problem hiding this comment.
| return wasmTable.get({{{toIndexType('base')}}})(...args); | |
| return wasmTable.get({{{ toIndexType('base') }}})(...args); |
This only seems to remove the whitespaces, right? But the convention in this file seems we have a space after {{{ and before }}}
| @@ -0,0 +1,2 @@ | |||
| deferred_function: [object Promise] | |||
| deferred_function await: 82 No newline at end of file | |||
There was a problem hiding this comment.
And it's a little weird that we have this here as a file and we also check this in the code after the split:
self.assertIn('primary_function: 42\n' +
'Custom handler for loading split module.\n' +
'deferred_function: [object Promise]\n' +
'deferred_function await: 82', result)How about checking both of the cases (before and after the split) in code to be consistent? Also they have a slightly different outputs, so..
| wasm_split_run = [wasm_split, '-g', | ||
| '--enable-mutable-globals', '--enable-bulk-memory', '--enable-nontrapping-float-to-int', | ||
| '--export-prefix=%', 'test_split_module_embind_jspi.wasm.orig', '-o1', 'primary.wasm', '-o2', 'secondary.wasm', '--profile=profile.data'] | ||
| self.run_process(wasm_split_run) | ||
|
|
||
| os.remove('test_split_module_embind_jspi.wasm') | ||
| os.rename('primary.wasm', 'test_split_module_embind_jspi.wasm') | ||
| os.rename('secondary.wasm', 'test_split_module_embind_jspi.deferred.wasm') |
There was a problem hiding this comment.
| wasm_split_run = [wasm_split, '-g', | |
| '--enable-mutable-globals', '--enable-bulk-memory', '--enable-nontrapping-float-to-int', | |
| '--export-prefix=%', 'test_split_module_embind_jspi.wasm.orig', '-o1', 'primary.wasm', '-o2', 'secondary.wasm', '--profile=profile.data'] | |
| self.run_process(wasm_split_run) | |
| os.remove('test_split_module_embind_jspi.wasm') | |
| os.rename('primary.wasm', 'test_split_module_embind_jspi.wasm') | |
| os.rename('secondary.wasm', 'test_split_module_embind_jspi.deferred.wasm') | |
| wasm_split_run = [wasm_split, '-g', | |
| '--enable-mutable-globals', '--enable-bulk-memory', '--enable-nontrapping-float-to-int', | |
| '--export-prefix=%', 'test_split_module_embind_jspi.wasm.orig', '-o1', 'test_split_module_embind_jspi.wasm', '-o2', 'test_split_module_embind_jspi.deferred.wasm', '--profile=profile.data'] | |
| self.run_process(wasm_split_run) |
Why don't we give the outputs the names we want in the first place in wasm-split command?
Previously, module splitting with JSPI required a special built-in function
__load_secondary_moduleand wasm-split setting to coordinate the loading of the secondary module.This change updates the
splitModuleProxyHandlerto support JSPI by wrapping the generated placeholder functions inWebAssembly.Suspending. The placeholder will then automatically load the secondary module asynchronously.A standalone
save_profile_data.jsscript is extracted from existing tests for reuse, and a new testtest_split_module_embind_jspiis added to ensure module splitting functions correctly alongside embind and JSPI.