Skip to content

Commit

Permalink
Convert createWasm async/await where possible (emscripten-core#23157)
Browse files Browse the repository at this point in the history
The advantage if using `await` in the cases where we can is that it
avoids the generation or wrapper function for each export.

So instead of:

```
var wasmExport = createWasm(); // returns empty object
...
var malloc = (..) => (malloc = wasmExports['malloc'])(..);
```

We can generate:

```
var wasmExport = await createWasm(); // returns actual exports
...
var malloc = wasmExports['malloc'];
```

This only currently works in MODULARIZE mode where the code is running
inside a factory function. Otherwise it would end up using
top-level-await.

One wrinkle here is that this is not currently supported when closure is
enabled because we run closure only on the contents of the factory
function so closure ends up seeing this as a top level await when its
not.

There are two minor observable effects of this change:

1. In `MODULARIZE` mode its no longer possible to call `new Foo()` with
factory function. We already added a debug error for in emscripten-core#23210.
2. Because we now can `await` for createWasm to return, the `run` method
can run on first call, which means it runs `main` on first call, which
means main will now run before `postjs` code, just like it would with
sync instantiation.
  • Loading branch information
sbc100 authored Dec 19, 2024
1 parent adb972c commit b330159
Show file tree
Hide file tree
Showing 88 changed files with 132 additions and 111 deletions.
6 changes: 6 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ See docs/process.md for more on how version tagging works.
`PATH.basename("a/b/..")` returns `".."` instead of `"a"`. This is in line with
the behaviour of both node and coreutils, and is already the case when using
NODERAWFS". (#23180)
- The factory function exposed in `-sMODULARIZE` mode is now marked as `async`
when `WASM_ASYNC_COMPILATION` is enabled (the default). This allows us to use
`await` during module creation. One side effect of this is that code in
`--post-js` files will now be delayed until after module creation and after
`main` runs. This matches the existing behaviour when using sync instantation
(`-sWASM_ASYNC_COMPILATION=0`) but is an observable difference. (#23157)

3.1.74 - 12/14/24
-----------------
Expand Down
13 changes: 6 additions & 7 deletions src/preamble.js
Original file line number Diff line number Diff line change
Expand Up @@ -1036,11 +1036,11 @@ function getWasmImports() {
trueModule = null;
#endif
#if SHARED_MEMORY || RELOCATABLE
receiveInstance(result['instance'], result['module']);
return receiveInstance(result['instance'], result['module']);
#else
// TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line.
// When the regression is fixed, can restore the above PTHREADS-enabled path.
receiveInstance(result['instance']);
return receiveInstance(result['instance']);
#endif
}
#endif // WASM_ASYNC_COMPILATION
Expand Down Expand Up @@ -1076,8 +1076,7 @@ function getWasmImports() {
// Instantiate from the module posted from the main thread.
// We can just use sync instantiation in the worker.
var instance = new WebAssembly.Instance(module, getWasmImports());
receiveInstance(instance, module);
resolve();
resolve(receiveInstance(instance, module));
};
});
}
Expand All @@ -1095,16 +1094,16 @@ function getWasmImports() {
try {
#endif
var result = await instantiateAsync(wasmBinary, wasmBinaryFile, info);
receiveInstantiationResult(result);
var exports = receiveInstantiationResult(result);
#if LOAD_SOURCE_MAP
receiveSourceMapJSON(await getSourceMapAsync());
#endif
return result;
return exports;
#if MODULARIZE
} catch (e) {
// If instantiation fails, reject the module ready promise.
readyPromiseReject(e);
return;
return Promise.reject(e);
}
#endif
#else // WASM_ASYNC_COMPILATION
Expand Down
2 changes: 1 addition & 1 deletion test/browser/test_small_js_flags.js.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4380
4374
8 changes: 4 additions & 4 deletions test/code_size/hello_webgl2_wasm.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.html": 454,
"a.html.gz": 328,
"a.js": 4532,
"a.js.gz": 2315,
"a.js": 4538,
"a.js.gz": 2320,
"a.wasm": 10402,
"a.wasm.gz": 6703,
"total": 15388,
"total_gz": 9346
"total": 15394,
"total_gz": 9351
}
8 changes: 4 additions & 4 deletions test/code_size/hello_webgl2_wasm2js.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"a.html": 346,
"a.html.gz": 262,
"a.js": 22200,
"a.js.gz": 11583,
"total": 22546,
"total_gz": 11845
"a.js": 22206,
"a.js.gz": 11589,
"total": 22552,
"total_gz": 11851
}
8 changes: 4 additions & 4 deletions test/code_size/hello_webgl_wasm.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.html": 454,
"a.html.gz": 328,
"a.js": 4070,
"a.js.gz": 2158,
"a.js": 4076,
"a.js.gz": 2163,
"a.wasm": 10402,
"a.wasm.gz": 6703,
"total": 14926,
"total_gz": 9189
"total": 14932,
"total_gz": 9194
}
8 changes: 4 additions & 4 deletions test/code_size/hello_webgl_wasm2js.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"a.html": 346,
"a.html.gz": 262,
"a.js": 21726,
"a.js.gz": 11413,
"total": 22072,
"total_gz": 11675
"a.js": 21732,
"a.js.gz": 11419,
"total": 22078,
"total_gz": 11681
}
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_cxx_ctors1.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8352
8351
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_cxx_ctors1.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20347
20343
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_cxx_ctors2.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8336
8334
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_cxx_ctors2.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20315
20311
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_cxx_except.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
9358
9356
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_cxx_except.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
24116
24112
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_cxx_except_wasm.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20240
20236
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20240
20236
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_cxx_lto.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8348
8347
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_cxx_lto.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20371
20367
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_cxx_mangle.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
9361
9359
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_cxx_mangle.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
24116
24112
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_cxx_noexcept.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8352
8351
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_cxx_noexcept.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20347
20343
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_cxx_wasmfs.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3653
3651
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_cxx_wasmfs.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7914
7910
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_files_js_fs.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7656
7654
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_files_js_fs.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
18842
18838
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_files_wasmfs.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6202
6198
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_hello_O0.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8017
8012
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_hello_O0.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
21597
21588
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_hello_O1.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2697
2694
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_hello_O1.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6911
6899
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_hello_O2.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2359
2357
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_hello_O2.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4835
4831
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_hello_O3.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2298
2296
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_hello_O3.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4757
4753
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_hello_Os.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2298
2296
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_hello_Os.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4757
4753
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_hello_Oz.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2281
2279
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_hello_Oz.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4724
4720
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_hello_dylink.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6023
6028
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_hello_dylink.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
13300
13317
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1682
1681
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3637
3633
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_hello_wasmfs.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2298
2296
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_hello_wasmfs.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4757
4753
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1876
1873
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4000
3996
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1914
1912
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4048
4044
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_mem_O3.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2328
2327
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_mem_O3.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4892
4888
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_mem_O3_grow.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2478
2476
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_mem_O3_grow.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5177
5172
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2180
2177
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4585
4581
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_mem_O3_standalone.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2143
2140
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_mem_O3_standalone.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4517
4513
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1900
1898
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4047
4043
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1914
1912
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4048
4044
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1914
1912
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4048
4044
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_64.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1439
1441
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_64.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3064
3058
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_O1.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1531
1534
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_O1.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3713
3702
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_O2.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1380
1381
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_O2.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2812
2806
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_O3.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1346
1348
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_O3.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2762
2756
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_Os.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1346
1348
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_Os.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2762
2756
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_Oz-ctors.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2747
2741
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_Oz.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1346
1348
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_Oz.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2762
2756
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_esm.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1496
1509
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_esm.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3138
3157
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_pthreads.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4184
4190
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_pthreads.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8711
8728
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_wasmfs.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1346
1348
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_wasmfs.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2762
2756
2 changes: 1 addition & 1 deletion test/other/test_INCOMING_MODULE_JS_API.js.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3772
3766
2 changes: 1 addition & 1 deletion test/other/test_unoptimized_code_size.js.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
53866
53888
2 changes: 1 addition & 1 deletion test/other/test_unoptimized_code_size_no_asserts.js.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
29065
29087
2 changes: 1 addition & 1 deletion test/other/test_unoptimized_code_size_strict.js.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
52649
52671
2 changes: 1 addition & 1 deletion test/test_unicode_js_library.out
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Unicode postjs: àČšñéáúÍųåêâăščếệüçλληνικάбългарскиPусскийСрпскиУкраїнська한국어中文普通话(中国大陆)普通话(香港)中文(台灣)粵語(香港)日本語हिन्दीภาษาไทย
Unicode snowman ☃ says hello! àČšñéáúÍųåêâăščếệüçλληνικάбългарскиPусскийСрпскиУкраїнська한국어中文普通话(中国大陆)普通话(香港)中文(台灣)粵語(香港)日本語हिन्दीภาษาไทย
Unicode postjs: àČšñéáúÍųåêâăščếệüçλληνικάбългарскиPусскийСрпскиУкраїнська한국어中文普通话(中国大陆)普通话(香港)中文(台灣)粵語(香港)日本語हिन्दीภาษาไทย
18 changes: 16 additions & 2 deletions tools/emscripten.py
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,16 @@ def create_sending(metadata, library_symbols):
return '{\n ' + ',\n '.join(elems) + '\n}'


def can_use_await():
# In MODULARIZE mode we can use `await` since the factory function itself
# is marked as `async` and the generated code all lives inside that factory
# function.
# However, because closure does not see this (it runs only on the inner code),
# it sees this as a top-level-await, which it does not yet support.
# FIXME(https://github.com/emscripten-core/emscripten/issues/23158)
return settings.MODULARIZE and not settings.USE_CLOSURE_COMPILER


def make_export_wrappers(function_exports):
assert not settings.MINIMAL_RUNTIME

Expand Down Expand Up @@ -932,7 +942,7 @@ def install_wrapper(sym):
# With assertions enabled we create a wrapper that are calls get routed through, for
# the lifetime of the program.
wrapper += f"createExportWrapper('{name}', {nargs});"
elif settings.WASM_ASYNC_COMPILATION or settings.PTHREADS:
elif (settings.WASM_ASYNC_COMPILATION and not can_use_await()) or settings.PTHREADS:
# With WASM_ASYNC_COMPILATION wrapper will replace the global var and Module var on
# first use.
args = [f'a{i}' for i in range(nargs)]
Expand Down Expand Up @@ -998,7 +1008,11 @@ def create_module(receiving, metadata, global_exports, library_symbols):

if not settings.MINIMAL_RUNTIME:
if settings.WASM_ASYNC_COMPILATION:
module.append("var wasmExports;\ncreateWasm();\n")
if can_use_await():
# In modularize mode the generated code is within a factory function.
module.append("var wasmExports = await createWasm();\n")
else:
module.append("var wasmExports;\ncreateWasm();\n")
else:
module.append("var wasmExports = createWasm();\n")

Expand Down
Loading

0 comments on commit b330159

Please sign in to comment.