Skip to content

Commit

Permalink
Allow the createWasm function to use async/await where possible
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 just generate:

```
var wasmExport = createWasm(); // returns empty object
...
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.
  • Loading branch information
sbc100 committed Dec 18, 2024
1 parent 669e01a commit a7bb4fa
Show file tree
Hide file tree
Showing 87 changed files with 131 additions and 113 deletions.
5 changes: 5 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ See docs/process.md for more on how version tagging works.
This paves the way for marking the function as `async` which does not allow
`new` to be used. This usage of `new` here was never documented and is
considered and antipattern. (#23210)
- The factory function exposed in `-sMODULARIZE` mode is now marked as `async`,
which allows us to use `await` within it. One side effect of this is that
it is no longer possible to use this function with the `new` keyword. Prior
to this change it was technically possible to do `var m = new Module()`, but
this will not result in `Module is not a constructor`. (#23157)
- `PATH.basename()` no longer calls `PATH.normalize()`, so that
`PATH.basename("a/.")` returns `"."` instead of `"a"` and
`PATH.basename("a/b/..")` returns `".."` instead of `"a"`. This is in line with
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
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 @@
8482
8479
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 @@
20818
20814
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 @@
8466
8464
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 @@
20786
20782
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 @@
9516
9515
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 @@
24663
24659
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_cxx_except_wasm.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8443
8442
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 @@
20711
20707
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8443
8442
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20711
20707
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 @@
20402
20398
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 @@
9523
9520
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 @@
24663
24659
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 @@
8482
8479
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 @@
20818
20814
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 @@
3769
3767
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 @@
8493
8489
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 @@
7621
7619
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 @@
18731
18727
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_files_wasmfs.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2866
2864
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 @@
6140
6136
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 @@
8003
8001
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 @@
21535
21526
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 @@
2713
2710
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 @@
6921
6909
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 @@
2369
2367
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 @@
4844
4840
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 @@
2283
2281
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 @@
4695
4691
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 @@
2283
2281
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 @@
4695
4691
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 @@
2265
2264
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 @@
4662
4658
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 @@
6150
6155
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 @@
13609
13626
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1667
1664
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3575
3571
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 @@
2283
2281
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 @@
4695
4691
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1862
1859
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3938
3934
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1899
1897
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3986
3982
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 @@
4830
4826
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 @@
2461
2459
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 @@
5115
5110
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2164
2161
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4523
4519
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 @@
2128
2125
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 @@
4455
4451
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1885
1883
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3985
3981
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1899
1897
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3986
3982
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1899
1897
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3986
3982
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 @@
1520
1524
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 @@
3664
3653
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 @@
2769
2763
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 @@
1336
1338
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 @@
2719
2713
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 @@
1336
1338
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 @@
2719
2713
2 changes: 1 addition & 1 deletion test/other/codesize/test_codesize_minimal_Oz-ctors.gzsize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1327
1328
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 @@
2704
2698
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 @@
1336
1338
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 @@
2719
2713
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 @@
1487
1500
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 @@
3095
3114
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 @@
4118
4125
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 @@
8556
8572
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 @@
1336
1338
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 @@
2719
2713
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 @@
53709
53731
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 @@
29018
29040
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 @@
52531
52553
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 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 modullize 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 a7bb4fa

Please sign in to comment.