Skip to content

Commit 37fab7d

Browse files
committed
Fix broken JS glue for AUDIO_WORKLETS with EXPORT_ES6
Building to WASM with AUDIO_WORKLETS and EXPORT_ES6 results in: test.js:989 Uncaught (in promise) TypeError: Cannot set property wasmTable of #<Object> which has only a getter at receiveInstance (test.js:989:25) at receiveInstantiationResult (test.js:1011:5) The read-only getter at issue is created only when ASSERTIONS != 0; however, ASSERTIONS defaults to 1. We therefore append wasmTable to EXPORTED_RUNTIME_METHODS if necessary. We also prevent an ES6 Audio Worklet from loading the .wasm binary via `new URL()`, as `URL` is unavailable in AudioWorkletGlobalScope.
1 parent 0e5b3a8 commit 37fab7d

File tree

3 files changed

+10
-3
lines changed

3 files changed

+10
-3
lines changed

src/preamble.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -608,14 +608,14 @@ function instrumentWasmTableWithAbort() {
608608
#endif
609609

610610
var wasmBinaryFile;
611-
#if EXPORT_ES6 && USE_ES6_IMPORT_META && !SINGLE_FILE
611+
#if EXPORT_ES6 && USE_ES6_IMPORT_META && !SINGLE_FILE && !AUDIO_WORKLET // `URL` is undefined in Audio Worklet scope, so we cannot use `new URL()`.
612612
if (Module['locateFile']) {
613613
#endif
614614
wasmBinaryFile = '{{{ WASM_BINARY_FILE }}}';
615615
if (!isDataURI(wasmBinaryFile)) {
616616
wasmBinaryFile = locateFile(wasmBinaryFile);
617617
}
618-
#if EXPORT_ES6 && USE_ES6_IMPORT_META && !SINGLE_FILE // in single-file mode, repeating WASM_BINARY_FILE would emit the contents again
618+
#if EXPORT_ES6 && USE_ES6_IMPORT_META && !SINGLE_FILE && !AUDIO_WORKLET // In single-file mode, repeating WASM_BINARY_FILE would emit the contents again. For an Audio Worklet, we cannot use `new URL()`.
619619
} else {
620620
#if ENVIRONMENT_MAY_BE_SHELL
621621
if (ENVIRONMENT_IS_SHELL)
@@ -1001,7 +1001,7 @@ function createWasm() {
10011001
assert(wasmTable, 'table not found in wasm exports');
10021002
#endif
10031003

1004-
#if AUDIO_WORKLET
1004+
#if AUDIO_WORKLET && !(EXPORT_ES6 && ASSERTIONS) // If EXPORT_ES6, we may have already done this.
10051005
// If we are in the audio worklet environment, we can only access the Module object
10061006
// and not the global scope of the main JS script. Therefore we need to export
10071007
// all functions that the audio worklet scope needs onto the Module object.

test/test_browser.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5759,6 +5759,8 @@ def test_full_js_library_strict(self):
57595759
'pthreads_and_closure': (['-pthread', '--closure', '1', '-Oz'],),
57605760
'minimal_runtime': (['-sMINIMAL_RUNTIME'],),
57615761
'minimal_runtime_pthreads_and_closure': (['-sMINIMAL_RUNTIME', '-pthread', '--closure', '1', '-Oz'],),
5762+
'pthreads_es6': (['-pthread', '-sPTHREAD_POOL_SIZE=2', '-sEXPORT_ES6'],),
5763+
'es6': (['-sEXPORT_ES6'],),
57625764
})
57635765
def test_audio_worklet(self, args):
57645766
if '-sMEMORY64' in args and is_firefox():

tools/link.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,6 +1350,11 @@ def phase_linker_setup(options, state, newargs):
13501350
# MINIMAL_RUNTIME exports these manually, since this export mechanism is placed
13511351
# in global scope that is not suitable for MINIMAL_RUNTIME loader.
13521352
settings.EXPORTED_RUNTIME_METHODS += ['stackSave', 'stackAlloc', 'stackRestore']
1353+
if settings.EXPORT_ES6 and settings.ASSERTIONS:
1354+
# With ASSERTIONS, EXPORT_ES6 assigns a read-only getter that prevents assigning
1355+
# Module['wasmTable'], which will then prevent the Audio Worklet from loading.
1356+
settings.EXPORTED_RUNTIME_METHODS += ['wasmTable']
1357+
13531358

13541359
if settings.FORCE_FILESYSTEM and not settings.MINIMAL_RUNTIME:
13551360
# when the filesystem is forced, we export by default methods that filesystem usage

0 commit comments

Comments
 (0)