From 45096790e901e634518a7d0f748831ce9b72bfe6 Mon Sep 17 00:00:00 2001 From: valadaptive Date: Sat, 3 Jan 2026 22:03:29 -0500 Subject: [PATCH 1/5] Use `new URL` pattern in minimal runtime --- src/postamble_minimal.js | 13 +++++++++++-- test/test_other.py | 12 ++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/postamble_minimal.js b/src/postamble_minimal.js index 9472ec752e9f8..e0871e3e6ae96 100644 --- a/src/postamble_minimal.js +++ b/src/postamble_minimal.js @@ -182,6 +182,15 @@ var imports = { }; #if MINIMAL_RUNTIME_STREAMING_WASM_INSTANTIATION +#if EXPORT_ES6 && !ENVIRONMENT_MAY_BE_AUDIO_WORKLET +var moduleUrl = new URL('{{{ TARGET_BASENAME }}}.wasm', import.meta.url); +#elif !EXPORT_ES6 || AUDIO_WORKLET +var moduleUrl = '{{{ TARGET_BASENAME }}}.wasm'; +#else +var moduleUrl = ENVIRONMENT_IS_AUDIO_WORKLET ? + '{{{ TARGET_BASENAME }}}.wasm' : + new URL('{{{ TARGET_BASENAME }}}.wasm', import.meta.url); +#endif // https://caniuse.com/#feat=wasm and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming #if MIN_SAFARI_VERSION < 150000 || ENVIRONMENT_MAY_BE_NODE #if ASSERTIONS && !WASM2JS @@ -197,13 +206,13 @@ instantiatePromise = // Node's fetch API cannot be used for local files, so we cannot use instantiateStreaming && !ENVIRONMENT_IS_NODE #endif - ? WebAssembly.instantiateStreaming(fetch('{{{ TARGET_BASENAME }}}.wasm'), imports) + ? WebAssembly.instantiateStreaming(fetch(moduleUrl), imports) : WebAssembly.instantiate(Module['wasm'], imports)).then((output) => { #else #if AUDIO_WORKLET instantiatePromise = #endif -WebAssembly.instantiateStreaming(fetch('{{{ TARGET_BASENAME }}}.wasm'), imports).then((output) => { +WebAssembly.instantiateStreaming(fetch(moduleUrl), imports).then((output) => { #endif #else // Non-streaming instantiation diff --git a/test/test_other.py b/test/test_other.py index 95eb63179f584..fbaaece081599 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -1702,6 +1702,18 @@ def test_minimal_runtime_errors(self): expected = 'emcc: error: MINIMAL_RUNTIME is not compatible with --preload-file' self.assert_fail([EMCC, test_file('hello_world.c'), '-sMINIMAL_RUNTIME', '--preload-file', 'foo'], expected) + def test_minimal_runtime_esm_streaming_instantiation(self): + self.run_process([EMCC, '-o', 'test.mjs', + '-sMINIMAL_RUNTIME', + '-sMINIMAL_RUNTIME_STREAMING_WASM_INSTANTIATION', + '-sEXPORT_ES6', + '-sENVIRONMENT=web', + test_file('hello_world.c')]) + + src = read_file('test.mjs') + # Verify that the generated code uses import.meta.url for the wasm URL + self.assertContained("new URL('test.wasm', import.meta.url)", src) + def test_export_all_and_exported_functions(self): # EXPORT_ALL should not export library functions by default. # This means that to export library function you also need to explicitly From 4e4093221597f42b452e45424865e6d617635589 Mon Sep 17 00:00:00 2001 From: valadaptive Date: Mon, 12 Jan 2026 04:20:43 -0500 Subject: [PATCH 2/5] Avoid adding moduleUrl variable --- src/postamble_minimal.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/postamble_minimal.js b/src/postamble_minimal.js index e0871e3e6ae96..15f6ffdc4ba9f 100644 --- a/src/postamble_minimal.js +++ b/src/postamble_minimal.js @@ -182,15 +182,15 @@ var imports = { }; #if MINIMAL_RUNTIME_STREAMING_WASM_INSTANTIATION +{{{ #if EXPORT_ES6 && !ENVIRONMENT_MAY_BE_AUDIO_WORKLET -var moduleUrl = new URL('{{{ TARGET_BASENAME }}}.wasm', import.meta.url); +const moduleUrl = `new URL('${TARGET_BASENAME}.wasm', import.meta.url)`; #elif !EXPORT_ES6 || AUDIO_WORKLET -var moduleUrl = '{{{ TARGET_BASENAME }}}.wasm'; +const moduleUrl = `'${TARGET_BASENAME}.wasm'`; #else -var moduleUrl = ENVIRONMENT_IS_AUDIO_WORKLET ? - '{{{ TARGET_BASENAME }}}.wasm' : - new URL('{{{ TARGET_BASENAME }}}.wasm', import.meta.url); +const moduleUrl = `ENVIRONMENT_IS_AUDIO_WORKLET ? '${TARGET_BASENAME}.wasm' : new URL('${TARGET_BASENAME}.wasm', import.meta.url)`; #endif +}}} // https://caniuse.com/#feat=wasm and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming #if MIN_SAFARI_VERSION < 150000 || ENVIRONMENT_MAY_BE_NODE #if ASSERTIONS && !WASM2JS @@ -206,13 +206,13 @@ instantiatePromise = // Node's fetch API cannot be used for local files, so we cannot use instantiateStreaming && !ENVIRONMENT_IS_NODE #endif - ? WebAssembly.instantiateStreaming(fetch(moduleUrl), imports) + ? WebAssembly.instantiateStreaming(fetch({{{ moduleUrl }}}), imports) : WebAssembly.instantiate(Module['wasm'], imports)).then((output) => { #else #if AUDIO_WORKLET instantiatePromise = #endif -WebAssembly.instantiateStreaming(fetch(moduleUrl), imports).then((output) => { +WebAssembly.instantiateStreaming(fetch({{{ moduleUrl }}}), imports).then((output) => { #endif #else // Non-streaming instantiation From 0c9c7fda9873a6ae0bcdf8f9b955ef2f78ca1a6f Mon Sep 17 00:00:00 2001 From: valadaptive Date: Mon, 12 Jan 2026 04:20:49 -0500 Subject: [PATCH 3/5] Add minimal runtime Vite test --- test/test_browser.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/test_browser.py b/test/test_browser.py index 0205bcd2b6580..3b67fc3f8b18b 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -5562,6 +5562,21 @@ def test_vite(self): self.run_process(shared.get_npm_cmd('vite') + ['build']) self.run_browser('dist/index.html', '/report_result?exit:0') + @also_with_threads + @requires_dev_dependency('vite') + def test_vite_minimal_runtime(self): + copytree(test_file('vite'), '.') + self.compile_btest('hello_world.c', [ + '-sEXIT_RUNTIME', + '-sMINIMAL_RUNTIME', + '-sMINIMAL_RUNTIME_STREAMING_WASM_INSTANTIATION', + '-sEXPORT_ES6', + '-sENVIRONMENT=web', + '-o', + 'hello.mjs']) + self.run_process(shared.get_npm_cmd('vite') + ['build']) + self.run_browser('dist/index.html', '/report_result?exit:0') + @also_with_threads @requires_dev_dependency('rollup') def test_rollup(self): From eb4bbbd2e7ce442c12932329da1c91f4a38af43d Mon Sep 17 00:00:00 2001 From: valadaptive Date: Mon, 12 Jan 2026 11:43:11 -0500 Subject: [PATCH 4/5] Use @parameterized --- test/test_browser.py | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/test/test_browser.py b/test/test_browser.py index 3b67fc3f8b18b..fcc8827b3f812 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -5556,24 +5556,13 @@ def test_webpack(self, args): @also_with_threads @requires_dev_dependency('vite') - def test_vite(self): - copytree(test_file('vite'), '.') - self.compile_btest('hello_world.c', ['-sEXIT_RUNTIME', '-sENVIRONMENT=web', '-o', 'hello.mjs']) - self.run_process(shared.get_npm_cmd('vite') + ['build']) - self.run_browser('dist/index.html', '/report_result?exit:0') - - @also_with_threads - @requires_dev_dependency('vite') - def test_vite_minimal_runtime(self): + @parameterized({ + '': ([],), + 'minimal': (['-sMINIMAL_RUNTIME', '-sMINIMAL_RUNTIME_STREAMING_WASM_INSTANTIATION'],), + }) + def test_vite(self, args): copytree(test_file('vite'), '.') - self.compile_btest('hello_world.c', [ - '-sEXIT_RUNTIME', - '-sMINIMAL_RUNTIME', - '-sMINIMAL_RUNTIME_STREAMING_WASM_INSTANTIATION', - '-sEXPORT_ES6', - '-sENVIRONMENT=web', - '-o', - 'hello.mjs']) + self.compile_btest('hello_world.c', ['-sEXIT_RUNTIME', '-sENVIRONMENT=web', '-o', 'hello.mjs'] + args) self.run_process(shared.get_npm_cmd('vite') + ['build']) self.run_browser('dist/index.html', '/report_result?exit:0') From 62edd26493f4a8c0482a446b0496c52e2d281654 Mon Sep 17 00:00:00 2001 From: valadaptive Date: Mon, 12 Jan 2026 11:44:22 -0500 Subject: [PATCH 5/5] Remove unnecessary test --- test/test_other.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/test/test_other.py b/test/test_other.py index fbaaece081599..95eb63179f584 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -1702,18 +1702,6 @@ def test_minimal_runtime_errors(self): expected = 'emcc: error: MINIMAL_RUNTIME is not compatible with --preload-file' self.assert_fail([EMCC, test_file('hello_world.c'), '-sMINIMAL_RUNTIME', '--preload-file', 'foo'], expected) - def test_minimal_runtime_esm_streaming_instantiation(self): - self.run_process([EMCC, '-o', 'test.mjs', - '-sMINIMAL_RUNTIME', - '-sMINIMAL_RUNTIME_STREAMING_WASM_INSTANTIATION', - '-sEXPORT_ES6', - '-sENVIRONMENT=web', - test_file('hello_world.c')]) - - src = read_file('test.mjs') - # Verify that the generated code uses import.meta.url for the wasm URL - self.assertContained("new URL('test.wasm', import.meta.url)", src) - def test_export_all_and_exported_functions(self): # EXPORT_ALL should not export library functions by default. # This means that to export library function you also need to explicitly