Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/audio_worklet.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@
// the node constructor's "processorOptions" field, we can share the necessary
// bootstrap information from the main thread to the AudioWorkletGlobalScope.

#if MINIMAL_RUNTIME
var instantiatePromise;
#endif

if (ENVIRONMENT_IS_AUDIO_WORKLET) {

#if AUDIO_WORKLET_SUPPORT_AUDIO_PARAMS
Expand Down
7 changes: 0 additions & 7 deletions src/closure-externs/closure-externs.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,6 @@ var id;
*/
var moduleArg;

/**
* Used in MODULARIZE mode.
* We need to access this after the code we pass to closure so from closure's
* POV this is "extern".
*/
var moduleRtn;

/**
* This was removed from upstream closure compiler in
* https://github.com/google/closure-compiler/commit/f83322c1b.
Expand Down
3 changes: 0 additions & 3 deletions src/lib/libcore.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,6 @@ addToLibrary({
// if exit() was called explicitly, warn the user if the runtime isn't actually being shut down
if (keepRuntimeAlive() && !implicit) {
var msg = `program exited (with status: ${status}), but keepRuntimeAlive() is set (counter=${runtimeKeepaliveCounter}) due to an async operation, so halting execution but not exiting the runtime or preventing further async execution (you can use emscripten_force_exit, if you want to force a true shutdown)`;
#if MODULARIZE
readyPromiseReject?.(msg);
#endif // MODULARIZE
err(msg);
}
#endif // ASSERTIONS
Expand Down
8 changes: 2 additions & 6 deletions src/modularize.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,18 @@ var {{{ EXPORT_NAME }}} = (() => {
var _scriptName = globalThis.document?.currentScript?.src;
#endif
return async function(moduleArg = {}) {
var moduleRtn;

"<<< INNER_JS_CODE >>>"

return moduleRtn;
return Module;
};
})();
#else
// When targeting node and ES6 we use `await import ..` in the generated code
// so the outer function needs to be marked as async.
async function {{{ EXPORT_NAME }}}(moduleArg = {}) {
var moduleRtn;

"<<< INNER_JS_CODE >>>"

return moduleRtn;
return Module;
}
#endif

Expand Down
36 changes: 21 additions & 15 deletions src/parseTools.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,30 @@ export function processMacros(text, filename) {
// `[\s\S]` works like `.` but include newline.
pushCurrentFile(filename);
try {
return text.replace(/{{{([\s\S]+?)}}}/g, (_, str) => {
text = text.replace(/{{{([\s\S]+?)}}}/g, (_, str) => {
const ret = runInMacroContext(str, {filename: filename});
return ret?.toString() ?? '';
});
// Do special keyword replacement after macro processing, so that
// macros can generate keywords (easier to read preprocessed code).
if (EXPORT_ES6) {
// `eval`, Terser and Closure don't support module syntax; to allow it,
// we need to temporarily replace `import.meta` and `await import` usages
// with placeholders during preprocess phase, and back after all the other ops.
// See also: `phase_final_emitting` in emcc.py.
text = text
.replace(/\bimport\.meta\b/g, 'EMSCRIPTEN$IMPORT$META')
.replace(/\bawait import\b/g, 'EMSCRIPTEN$AWAIT$IMPORT');
}
if (MODULARIZE) {
// Same for out use of "top-level-await" which is not actually top level
// in the case of MODULARIZE.
text = text.replace(/\bawait createWasm\(\)/g, 'EMSCRIPTEN$AWAIT(createWasm())');
text = text.replace(/\bawait run\(\)/g, 'EMSCRIPTEN$AWAIT(run())');
text = text.replace(/\bawait instantiatePromise\b/g, 'EMSCRIPTEN$AWAIT(instantiatePromise)');
text = text.replace(/\bawait init\(\)/g, 'EMSCRIPTEN$AWAIT(init())');
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe make this new code into its own named function? Something like mangleUnsupportedSyntax ? or some better name?

I wonder what knock on effects it will have that we now do this in processMacros vs preprocess? IIRC there are times when we do one but not the other.

return text;
} finally {
popCurrentFile();
}
Expand Down Expand Up @@ -73,20 +93,6 @@ function findIncludeFile(filename, currentDir) {
// Also handles #include x.js (similar to C #include <file>)
export function preprocess(filename) {
let text = readFile(filename);
if (EXPORT_ES6) {
// `eval`, Terser and Closure don't support module syntax; to allow it,
// we need to temporarily replace `import.meta` and `await import` usages
// with placeholders during preprocess phase, and back after all the other ops.
// See also: `phase_final_emitting` in emcc.py.
text = text
.replace(/\bimport\.meta\b/g, 'EMSCRIPTEN$IMPORT$META')
.replace(/\bawait import\b/g, 'EMSCRIPTEN$AWAIT$IMPORT');
}
if (MODULARIZE) {
// Same for out use of "top-level-await" which is not actually top level
// in the case of MODULARIZE.
text = text.replace(/\bawait createWasm\(\)/g, 'EMSCRIPTEN$AWAIT(createWasm())');
}
// Remove windows line endings, if any
text = text.replace(/\r\n/g, '\n');

Expand Down
55 changes: 30 additions & 25 deletions src/postamble.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,27 +114,26 @@ function stackCheckInit() {
}
#endif

#if MAIN_READS_PARAMS
function run(args = programArgs) {
#else
function run() {
#endif
{{{ asyncIf(MODULARIZE) }}}function run({{{ MAIN_READS_PARAMS ? 'args = programArgs' : '' }}}) {

#if '$runDependencies' in addedLibraryItems
if (runDependencies > 0) {
#if RUNTIME_DEBUG
dbg('run() called, but dependencies remain, so not running');
#endif
#if MODULARIZE
await new Promise((resolve) => {
dependenciesFulfilled = resolve;
});
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this just be a single line await new Promise((resolve) => dependenciesFulfilled = resolve);?

#else
dependenciesFulfilled = run;
return;
#endif
}
#endif

#if PTHREADS || WASM_WORKERS
if ({{{ ENVIRONMENT_IS_WORKER_THREAD() }}}) {
#if MODULARIZE
readyPromiseResolve?.(Module);
#endif
initRuntime();
return;
}
Expand All @@ -152,8 +151,14 @@ function run() {
#if RUNTIME_DEBUG
dbg('run() called, but dependencies remain, so not running');
#endif
#if MODULARIZE
await new Promise((resolve) => {
dependenciesFulfilled = resolve;
});
#else
dependenciesFulfilled = run;
return;
#endif
}
#endif

Expand All @@ -174,9 +179,6 @@ function run() {
preMain();
#endif

#if MODULARIZE
readyPromiseResolve?.(Module);
#endif
#if expectToReceiveOnModule('onRuntimeInitialized')
Module['onRuntimeInitialized']?.();
#if ASSERTIONS
Expand All @@ -203,10 +205,20 @@ function run() {
#if expectToReceiveOnModule('setStatus')
if (Module['setStatus']) {
Module['setStatus']('Running...');
#if MODULARIZE
await new Promise((resolve) => {
setTimeout(() => {
setTimeout(() => Module['setStatus'](''), 1);
doRun();
resolve();
}, 1);
});
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code looks kind of weird.. perhaps it should have a comment?

#else
setTimeout(() => {
setTimeout(() => Module['setStatus'](''), 1);
doRun();
}, 1);
#endif
} else
#endif
{
Expand Down Expand Up @@ -297,13 +309,12 @@ export default async function init(moduleArg = {}) {
#endif
updateMemoryViews();
#if DYNCALLS && '$dynCalls' in addedLibraryItems

assignDynCalls();
#endif
#else
wasmExports = await createWasm();
#endif
run();
await run();
}

#if ENVIRONMENT_MAY_BE_NODE
Expand All @@ -315,7 +326,7 @@ if (ENVIRONMENT_IS_NODE
)
{
const url = await import('node:url');
const isMainModule = url.pathToFileURL(process.argv[1]).href === import.meta.url;
const isMainModule = process.argv[1] && url.pathToFileURL(process.argv[1]).href === import.meta.url;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I this change related?

if (isMainModule) await init();
}
#endif
Expand All @@ -335,23 +346,17 @@ if ({{{ ENVIRONMENT_IS_MAIN_THREAD() }}}) {
// Worker threads call this once they receive the module via postMessage
#endif

#if WASM_ASYNC_COMPILATION

#if MODULARIZE
// In modularize mode the generated code is within a factory function so we
// can use await here (since it's not top-level-await).
wasmExports = await createWasm();
#else
#if !MODULARIZE && WASM_ASYNC_COMPILATION
// With async instantation wasmExports is assigned asynchronously when the
// instance is received.
createWasm();
#endif

#else
wasmExports = createWasm();
// In modularize mode the generated code is within a factory function so we
// can use await here (since it's not top-level-await).
wasmExports = {{{ awaitIf(MODULARIZE && WASM_ASYNC_COMPILATION) }}}createWasm();
#endif

run();
{{{ awaitIf(MODULARIZE) }}}run();

#if WASM_WORKERS || PTHREADS
}
Expand Down
16 changes: 12 additions & 4 deletions src/postamble_minimal.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ function initRuntime(wasmExports) {

// Initialize wasm (asynchronous)

#if MODULARIZE || AUDIO_WORKLET
var instantiatePromise;
#endif

#if SINGLE_FILE && SINGLE_FILE_BINARY_ENCODE && !WASM2JS
Module['wasm'] = binaryDecode("<<< WASM_BINARY_DATA >>>");
#elif SINGLE_FILE && WASM == 1 && !WASM2JS
Expand Down Expand Up @@ -198,7 +202,7 @@ const moduleUrl = `ENVIRONMENT_IS_AUDIO_WORKLET ? '${TARGET_BASENAME}.wasm' : ne
// precompiled WebAssembly Module.
assert(WebAssembly.instantiateStreaming || Module['wasm'], 'Must load WebAssembly Module in to variable Module.wasm before adding compiled output .js script to the DOM');
#endif
#if AUDIO_WORKLET
#if MODULARIZE || AUDIO_WORKLET
instantiatePromise =
#endif
(WebAssembly.instantiateStreaming
Expand All @@ -209,7 +213,7 @@ instantiatePromise =
? WebAssembly.instantiateStreaming(fetch({{{ moduleUrl }}}), imports)
: WebAssembly.instantiate(Module['wasm'], imports)).then((output) => {
#else
#if AUDIO_WORKLET
#if MODULARIZE || AUDIO_WORKLET
instantiatePromise =
#endif
WebAssembly.instantiateStreaming(fetch({{{ moduleUrl }}}), imports).then((output) => {
Expand All @@ -228,7 +232,7 @@ assert(Module['wasm'], 'Must load WebAssembly Module in to variable Module.wasm

// Add missingProperties supression here because closure compiler doesn't know that
// WebAssembly.instantiate is polymorphic in its return value.
#if AUDIO_WORKLET
#if MODULARIZE || AUDIO_WORKLET
instantiatePromise =
#endif
WebAssembly.instantiate(Module['wasm'], imports).then(/** @suppress {missingProperties} */ (output) => {
Expand Down Expand Up @@ -303,7 +307,7 @@ null;
PThread.loadWasmModuleToAllWorkers();
#endif

{{{ waitOnStartupPromisesAndEmitReady(); }}}
return {{{ waitOnStartupPromisesAndEmitReady(); }}}

}

Expand Down Expand Up @@ -334,3 +338,7 @@ null;
// When running in a background thread we delay module loading until we have
{{{ runIfMainThread('loadModule();') }}}
#endif

#if MODULARIZE
await instantiatePromise;
#endif
13 changes: 0 additions & 13 deletions src/postamble_modularize.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,5 @@
// In MODULARIZE mode we wrap the generated code in a factory function
// and return either the Module itself, or a promise of the module.
//
// We assign to the `moduleRtn` global here and configure closure to see
// this as an extern so it won't get minified.

if (runtimeInitialized) {
moduleRtn = Module;
} else {
// Set up the promise that indicates the Module is initialized
moduleRtn = new Promise((resolve, reject) => {
readyPromiseResolve = resolve;
readyPromiseReject = reject;
});
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome. Since this file doesn't do anything but inject these assertions now I wonder if it should just be removed (perhaps as a followup)?


#if ASSERTIONS
// Assertion for attempting to access module properties on the incoming
Expand Down
3 changes: 0 additions & 3 deletions src/preamble.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,6 @@ function abort(what) {
/** @suppress {checkTypes} */
var e = new WebAssembly.RuntimeError(what);

#if MODULARIZE
readyPromiseReject?.(e);
#endif
// Throw the error whether or not MODULARIZE is set because abort is used
// in code paths apart from instantiation where an exception is expected
// to be thrown when abort is called.
Expand Down
4 changes: 0 additions & 4 deletions src/runtime_common.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ function growMemViews() {
#include "binaryDecode.js"
#endif

#if MODULARIZE
var readyPromiseResolve, readyPromiseReject;
#endif

#if (PTHREADS || WASM_WORKERS) && (ENVIRONMENT_MAY_BE_NODE && !WASM_ESM_INTEGRATION)
if (ENVIRONMENT_IS_NODE && {{{ ENVIRONMENT_IS_WORKER_THREAD() }}}) {
// Create as web-worker-like an environment as we can.
Expand Down
3 changes: 0 additions & 3 deletions src/shell_minimal.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,6 @@ var err = (...args) => console.error(...args);
// compilation is ready. In that callback, call the function run() to start
// the program.
function ready() {
#if MODULARIZE
readyPromiseResolve?.(Module);
#endif // MODULARIZE
#if INVOKE_RUN && HAS_MAIN
{{{ runIfMainThread("run();") }}}
#elif ASSERTIONS
Expand Down
Loading
Loading