From 53f67277314e66f89c5ced7bc044f9b994d3dae5 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 23 Jun 2026 16:50:06 +0200 Subject: [PATCH 1/4] Move modularization code into JS compiler Supersedes: #23261. --- src/closure-externs/closure-externs.js | 7 +- src/closure-externs/modularize-externs.js | 19 ---- src/modularize.js | 118 ---------------------- src/parseTools.mjs | 14 --- src/postamble_modularize.js | 14 +++ src/postamble_modularize_worker.js | 57 +++++++++++ src/preamble_modularize.js | 29 ++++++ src/shell.js | 2 + src/shell_minimal.js | 8 +- test/test_other.py | 8 +- tools/acorn-optimizer.mjs | 5 +- tools/building.py | 5 +- tools/link.py | 52 +++++----- tools/unsafe_optimizations.mjs | 36 ------- 14 files changed, 141 insertions(+), 233 deletions(-) delete mode 100644 src/closure-externs/modularize-externs.js delete mode 100644 src/modularize.js create mode 100644 src/postamble_modularize_worker.js create mode 100644 src/preamble_modularize.js diff --git a/src/closure-externs/closure-externs.js b/src/closure-externs/closure-externs.js index 8199fe8460569..b5ace30771253 100644 --- a/src/closure-externs/closure-externs.js +++ b/src/closure-externs/closure-externs.js @@ -11,10 +11,6 @@ * The closure_compiler() method in tools/shared.py refers to this file when calling closure. */ -// Special placeholder for `await import` and `await`. -var EMSCRIPTEN$AWAIT$IMPORT; -var EMSCRIPTEN$AWAIT; - // Don't minify createRequire var createRequire; @@ -124,9 +120,10 @@ var wakaUnknownBefore; // Module loaders externs, for AMD etc. /** + * @param {Object} deps * @param {Function} wrapper */ -var define = function (wrapper) {}; +var define = function (deps, wrapper) {}; /** * @type {Worker} diff --git a/src/closure-externs/modularize-externs.js b/src/closure-externs/modularize-externs.js deleted file mode 100644 index c0471f5ef49a4..0000000000000 --- a/src/closure-externs/modularize-externs.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * In MODULARIZE mode the JS code may be executed later, after `document.currentScript` is gone, so - * we store it to `_scriptName` outside the wrapper function. Therefore, it cannot be minified. - * In EXPORT_ES6 mode we use `import.meta.url` and for Node.js CommonJS builds we use `__filename`. - * @suppress {duplicate, undefinedVars} - */ -var _scriptName; - -/** - * Used in MODULARIZE mode as the name of the incoming module argument. - * This is generated outside of the code we pass to closure so from closure's - * POV this is "extern". - */ -var moduleArg; - -/** - * @suppress {duplicate, undefinedVars} - */ -var Module; diff --git a/src/modularize.js b/src/modularize.js deleted file mode 100644 index 58a3eb6783b49..0000000000000 --- a/src/modularize.js +++ /dev/null @@ -1,118 +0,0 @@ -/** - * @license - * Copyright 2025 The Emscripten Authors - * SPDX-License-Identifier: MIT - */ - -// This code implements the `-sMODULARIZE` settings by taking the generated -// JS program code (INNER_JS_CODE) and wrapping it in a factory function. - -#if STRICT_JS -"use strict"; -#endif - -#if SOURCE_PHASE_IMPORTS -import source wasmModule from './{{{ WASM_BINARY_FILE }}}'; -#endif - -#if ENVIRONMENT_MAY_BE_WEB && !EXPORT_ES6 && !(MINIMAL_RUNTIME && !PTHREADS) -// Single threaded MINIMAL_RUNTIME programs do not need access to -// document.currentScript, so a simple export declaration is enough. -var {{{ EXPORT_NAME }}} = (() => { - // When MODULARIZE this JS may be executed later, - // after document.currentScript is gone, so we save it. - // In EXPORT_ES6 mode we can just use 'import.meta.url'. -#if MIN_FIREFOX_VERSION < 74 || LEGACY_VM_SUPPORT - // This modularize.js script is not Babeled, so manually adapt for old browsers. - var _scriptName = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; -#else - var _scriptName = globalThis.document?.currentScript?.src; -#endif - return async function(moduleArg = {}) { - var Module = moduleArg; -"<<< INNER_JS_CODE >>>" - - 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 Module = moduleArg; -"<<< INNER_JS_CODE >>>" - - return Module; -} -#endif - -// Export using a UMD style export, or ES6 exports if selected -#if EXPORT_ES6 -export default {{{ EXPORT_NAME }}}; -#elif !MINIMAL_RUNTIME -if (typeof exports === 'object' && typeof module === 'object') { - module.exports = {{{ EXPORT_NAME }}}; - // This default export looks redundant, but it allows TS to import this - // commonjs style module. - module.exports.default = {{{ EXPORT_NAME }}}; -} else if (typeof define === 'function' && define['amd']) - define([], () => {{{ EXPORT_NAME }}}); -#endif - -#if PTHREADS - -// Create code for detecting if we are running in a pthread. -// Normally this detection is done when the module is itself run but -// when running in MODULARIZE mode we need use this to know if we should -// run the module constructor on startup (true only for pthreads). -#if ENVIRONMENT_MAY_BE_WEB || ENVIRONMENT_MAY_BE_WORKER -var isPthread = {{{ pthreadDetection() }}}; -#if ENVIRONMENT_MAY_BE_NODE -// In order to support both web and node we also need to detect node here. -var isNode = {{{ nodeDetectionCode() }}}; -if (isNode) isPthread = {{{ nodePthreadDetection() }}} -#endif -#else ENVIRONMENT_MAY_BE_NODE -var isPthread = {{{ nodePthreadDetection() }}} -// When running as a pthread, construct a new instance on startup -#endif - -#if MODULARIZE == 'instance' -isPthread && init(); -#else -isPthread && {{{ EXPORT_NAME }}}(); -#endif - -#endif // PTHREADS - -#if WASM_WORKERS - -// Same as above for for WASM_WORKERS -// Normally this detection is done when the module is itself run but -// when running in MODULARIZE mode we need use this to know if we should -// run the module constructor on startup (true only for pthreads). -#if ENVIRONMENT_MAY_BE_WEB || ENVIRONMENT_MAY_BE_WORKER -var isWW = {{{ wasmWorkerDetection() }}}; -// In order to support both web and node we also need to detect node here. -#if ENVIRONMENT_MAY_BE_NODE -#if !PTHREADS -var isNode = {{{ nodeDetectionCode() }}}; -#endif -if (isNode) isWW = {{{ nodeWWDetection() }}}; -#endif -#elif ENVIRONMENT_MAY_BE_NODE -var isWW = {{{ nodeWWDetection() }}}; -#endif - -#if AUDIO_WORKLET -isWW ||= !!globalThis.AudioWorkletGlobalScope; -// When running as a wasm worker, construct a new instance on startup -#endif - -#if MODULARIZE == 'instance' -isWW && init(); -#else -isWW && {{{ EXPORT_NAME }}}(); -#endif - -#endif // WASM_WORKERS diff --git a/src/parseTools.mjs b/src/parseTools.mjs index 61e4d20565de1..18abd94449df5 100644 --- a/src/parseTools.mjs +++ b/src/parseTools.mjs @@ -41,20 +41,6 @@ function mangleUnsupportedSyntax(text) { // See also: `writeOutput` in jsifier.mjs. text = text.replaceAll('import.meta', 'EMSCRIPTEN$IMPORT$META'); } - if (MODULARIZE && USE_CLOSURE_COMPILER) { - // Closure doesn't support "top-level await" which is not actually the top - // level in case of MODULARIZE. Temporarily replace `await` usages with - // placeholders during preprocess phase, and back after all the other ops. - // See also: `fix_js_mangling` in link.py. - // FIXME: Remove after https://github.com/google/closure-compiler/issues/3835 is fixed. - if (EXPORT_ES6) { - text = text.replaceAll('await import', 'EMSCRIPTEN$AWAIT$IMPORT'); - } - text = text.replaceAll('await createWasm()', 'EMSCRIPTEN$AWAIT(createWasm())'); - text = text.replaceAll('await run()', 'EMSCRIPTEN$AWAIT(run())'); - text = text.replaceAll('await instantiatePromise', 'EMSCRIPTEN$AWAIT(instantiatePromise)'); - text = text.replaceAll('await init()', 'EMSCRIPTEN$AWAIT(init())'); - } return text; } diff --git a/src/postamble_modularize.js b/src/postamble_modularize.js index ab2b4c0658b1f..44394655ff384 100644 --- a/src/postamble_modularize.js +++ b/src/postamble_modularize.js @@ -17,4 +17,18 @@ for (const prop of Object.keys(Module)) { }); } } +#endif + + return Module; +} // End factory function + +// Export using a UMD style export +#if !EXPORT_ES6 && !MINIMAL_RUNTIME +if (typeof exports === 'object' && typeof module === 'object') { + module.exports = {{{ EXPORT_NAME }}}; + // This default export looks redundant, but it allows TS to import this + // commonjs style module. + module.exports.default = {{{ EXPORT_NAME }}}; +} else if (typeof define === 'function' && define['amd']) + define([], () => {{{ EXPORT_NAME }}}); #endif diff --git a/src/postamble_modularize_worker.js b/src/postamble_modularize_worker.js new file mode 100644 index 0000000000000..b20f202e4ee6c --- /dev/null +++ b/src/postamble_modularize_worker.js @@ -0,0 +1,57 @@ +#if PTHREADS + +// Create code for detecting if we are running in a pthread. +// Normally this detection is done when the module is itself run but +// when running in MODULARIZE mode we need use this to know if we should +// run the module constructor on startup (true only for pthreads). +#if ENVIRONMENT_MAY_BE_WEB || ENVIRONMENT_MAY_BE_WORKER +var isPthread = {{{ pthreadDetection() }}}; +#if ENVIRONMENT_MAY_BE_NODE +// In order to support both web and node we also need to detect node here. +var isNode = {{{ nodeDetectionCode() }}}; +if (isNode) isPthread = {{{ nodePthreadDetection() }}} +#endif +#else ENVIRONMENT_MAY_BE_NODE +var isPthread = {{{ nodePthreadDetection() }}} +// When running as a pthread, construct a new instance on startup +#endif + +#if MODULARIZE == 'instance' +isPthread && init(); +#else +isPthread && {{{ EXPORT_NAME }}}(); +#endif + +#endif // PTHREADS + +#if WASM_WORKERS + +// Same as above for WASM_WORKERS +// Normally this detection is done when the module is itself run but +// when running in MODULARIZE mode we need use this to know if we should +// run the module constructor on startup (true only for pthreads). +#if ENVIRONMENT_MAY_BE_WEB || ENVIRONMENT_MAY_BE_WORKER +var isWW = {{{ wasmWorkerDetection() }}}; +// In order to support both web and node we also need to detect node here. +#if ENVIRONMENT_MAY_BE_NODE +#if !PTHREADS +var isNode = {{{ nodeDetectionCode() }}}; +#endif +if (isNode) isWW = {{{ nodeWWDetection() }}}; +#endif +#elif ENVIRONMENT_MAY_BE_NODE +var isWW = {{{ nodeWWDetection() }}}; +#endif + +#if AUDIO_WORKLET +isWW ||= !!globalThis.AudioWorkletGlobalScope; +// When running as a wasm worker, construct a new instance on startup +#endif + +#if MODULARIZE == 'instance' +isWW && init(); +#else +isWW && {{{ EXPORT_NAME }}}(); +#endif + +#endif // WASM_WORKERS diff --git a/src/preamble_modularize.js b/src/preamble_modularize.js new file mode 100644 index 0000000000000..a2884bf0e02f5 --- /dev/null +++ b/src/preamble_modularize.js @@ -0,0 +1,29 @@ +/** + * @license + * Copyright 2026 The Emscripten Authors + * SPDX-License-Identifier: MIT + */ + +#if SOURCE_PHASE_IMPORTS +import source wasmModule from './{{{ WASM_BINARY_FILE }}}'; +#endif + +// In EXPORT_ES6 mode we can just use 'import.meta.url'. +// Single threaded MINIMAL_RUNTIME programs do not need access to +// document.currentScript, so a simple export declaration is enough. +#if ENVIRONMENT_MAY_BE_WEB && !EXPORT_ES6 && !(MINIMAL_RUNTIME && !PTHREADS) +// When MODULARIZE this JS may be executed later, after +// document.currentScript is gone, so we save it. +var _scriptName = globalThis.document?.currentScript?.src; +#endif + +#if USE_CLOSURE_COMPILER +// Ensure Closure recognizes the export. This gets replaced by +// an `export default ...` declaration in the final output. +// See: https://developers.google.com/closure/compiler/docs/externs-and-exports +// See also: `fix_closure` in link.py +globalThis.{{{ EXPORT_NAME }}} = async function(moduleArg = {}) { +#else +{{{ EXPORT_ES6 ? "export default " : "" }}}async function {{{ EXPORT_NAME }}}(moduleArg = {}) { +#endif +var Module = moduleArg; diff --git a/src/shell.js b/src/shell.js index ad4fd53554e63..5609bde486b66 100644 --- a/src/shell.js +++ b/src/shell.js @@ -25,6 +25,8 @@ #if MODULARIZE #if MODULARIZE == 'instance' var Module = {}; +#else +#include "preamble_modularize.js" #endif #elif USE_CLOSURE_COMPILER /** @type{Object} */ diff --git a/src/shell_minimal.js b/src/shell_minimal.js index 9615ea8e7a651..9f3ed84d14d3d 100644 --- a/src/shell_minimal.js +++ b/src/shell_minimal.js @@ -6,8 +6,9 @@ #include "minimum_runtime_check.js" -#if !MODULARIZE -#if USE_CLOSURE_COMPILER +#if MODULARIZE +#include "preamble_modularize.js" +#elif USE_CLOSURE_COMPILER /** @type{Object} */ var Module; // if (!Module) is crucial for Closure Compiler here as it will @@ -28,8 +29,7 @@ var Module = globalThis.{{{ EXPORT_NAME }}} || {}; #else var Module = {{{ EXPORT_NAME }}}; -#endif -#endif // !MODULARIZE +#endif // USE_CLOSURE_COMPILER #if ENVIRONMENT_MAY_BE_NODE var ENVIRONMENT_IS_NODE = {{{ nodeDetectionCode() }}}; diff --git a/test/test_other.py b/test/test_other.py index abb7571fee6f3..eb5634ca98199 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -420,12 +420,14 @@ def test_emcc_generate_config(self, compiler): 'node': (['-sENVIRONMENT=node'],), # load a worker before startup to check ES6 modules there as well 'pthreads': (['-pthread', '-sPTHREAD_POOL_SIZE=1'],), + # i.e., OPT_LEVEL >= 2, minified with tools/acorn-optimizer.mjs + 'optimize': (['-O3'],), }) def test_esm(self, args): self.run_process([EMCC, '-o', 'hello_world.mjs', '--extern-post-js', test_file('modularize_post_js.js'), test_file('hello_world.c')] + args) - self.assertContained('export default Module;', read_file('hello_world.mjs')) + self.assertContained('export default async function Module', read_file('hello_world.mjs')) self.assertContained('Hello, world!', self.run_js('hello_world.mjs')) @requires_node_25 @@ -455,7 +457,7 @@ def test_esm_worker(self, args): src = read_file('subdir/hello_world.mjs') self.assertContained("new URL('hello_world.wasm', import.meta.url)", src) self.assertContained("new Worker(new URL('hello_world.mjs', import.meta.url), {", src) - self.assertContained('export default Module;', src) + self.assertContained('export default async function Module', src) self.assertContained('Hello, world!', self.run_js('subdir/hello_world.mjs')) @requires_pthreads @@ -479,7 +481,7 @@ def test_esm_closure(self): def test_esm_implies_modularize(self): self.run_process([EMCC, test_file('hello_world.c'), '-sEXPORT_ES6']) src = read_file('a.out.js') - self.assertContained('export default Module;', src) + self.assertContained('export default async function Module', src) def test_esm_requires_modularize(self): self.assert_fail([EMCC, test_file('hello_world.c'), '-sEXPORT_ES6', '-sMODULARIZE=0'], 'EXPORT_ES6 requires MODULARIZE to be set') diff --git a/tools/acorn-optimizer.mjs b/tools/acorn-optimizer.mjs index 0f00c63106a0e..f735b22f5c52b 100755 --- a/tools/acorn-optimizer.mjs +++ b/tools/acorn-optimizer.mjs @@ -276,7 +276,8 @@ function JSDCE(ast, aggressive) { } }, FunctionDeclaration(node, _c) { - if (names.has(node.id.name)) { + // FIXME: Check for `EXPORT_NAME` instead of `Module` + if (names.has(node.id.name) && node.id.name != 'Module') { removed++; emptyOut(node); return; @@ -361,7 +362,7 @@ function JSDCE(ast, aggressive) { ensureData(scopes[scopes.length - 1], name).use = 1; }, ExportDefaultDeclaration(node, c) { - const name = node.declaration.id.name; + const name = node.declaration.name; ensureData(scopes[scopes.length - 1], name).use = 1; c(node.declaration); }, diff --git a/tools/building.py b/tools/building.py index ce88d3031d3c5..d613879626fda 100644 --- a/tools/building.py +++ b/tools/building.py @@ -561,9 +561,6 @@ def closure_compiler(filename, advanced=True, extra_closure_args=None): # should not minify these symbol names. CLOSURE_EXTERNS = [path_from_root('src/closure-externs/closure-externs.js')] - if settings.MODULARIZE: - CLOSURE_EXTERNS += [path_from_root('src/closure-externs/modularize-externs.js')] - if settings.AUDIO_WORKLET: CLOSURE_EXTERNS += [path_from_root('src/closure-externs/audio-worklet-externs.js')] @@ -606,6 +603,8 @@ def closure_compiler(filename, advanced=True, extra_closure_args=None): args = ['--compilation_level', 'ADVANCED_OPTIMIZATIONS' if advanced else 'SIMPLE_OPTIMIZATIONS'] args += ['--language_in', 'UNSTABLE'] + if settings.MODULARIZE: + args += ['--assume_function_wrapper'] # Make Closure aware of the ES6 module syntax; # i.e. the `import.meta` and `await import` usages if settings.EXPORT_ES6: diff --git a/tools/link.py b/tools/link.py index 0a01e7544c008..4e11d55d3cc1a 100644 --- a/tools/link.py +++ b/tools/link.py @@ -2107,29 +2107,29 @@ def phase_source_transforms(options): save_intermediate('transformed') -# Unmangle previously mangled `await import` and `await` references in -# both main code and libraries. -# See also: `mangleUnsupportedSyntax` in parseTools.mjs. -def fix_js_mangling(js_file): - # Mangling only takes place under closure in MODULARIZE mode. +def fix_closure(js_file): + # This only takes place under closure in MODULARIZE mode. if not settings.MODULARIZE or not settings.USE_CLOSURE_COMPILER: return src = read_file(js_file) + # Replace `globalThis.Module = async function` with + # `export default async function` + # See also: `preamble_modularize.js` + src = re.sub(f'globalThis.{settings.EXPORT_NAME}\\s*=\\s*async function', + f'{'export default ' if settings.EXPORT_ES6 else ''}' + f'async function {settings.EXPORT_NAME}', src) + if settings.EXPORT_ES6: - # Also remove the line containing `export{};`, which is inserted by + # Remove the line containing `export{};`, which is inserted by # Closure to mark the file as an ES6 module. # https://github.com/google/closure-compiler/issues/4084#issuecomment-1505056519 # https://github.com/google/closure-compiler/blob/v20260401/src/com/google/javascript/jscomp/ConvertChunksToESModules.java#L111-L113 - src = src \ - .replace('EMSCRIPTEN$AWAIT$IMPORT', 'await import') \ - .replace('export{};\n', '') - - src = src.replace('EMSCRIPTEN$AWAIT(', 'await (') + src = src.replace('export{};\n', '') write_file(js_file, src) - save_intermediate('js-mangling') + save_intermediate('js-closure') def node_detection_code(): @@ -2194,9 +2194,10 @@ def phase_final_emitting(options, target, js_target, wasm_target): if shared.SKIP_SUBPROCS: return - if settings.MODULARIZE and settings.MODULARIZE != 'instance': + if settings.MODULARIZE and (settings.PTHREADS or settings.WASM_WORKERS): modularize() - elif settings.USE_CLOSURE_COMPILER: + + if not settings.MODULARIZE and settings.USE_CLOSURE_COMPILER: module_export_name_substitution() # Run a final optimization pass to clean up items that were not possible to @@ -2217,7 +2218,7 @@ def phase_final_emitting(options, target, js_target, wasm_target): shared.run_js_tool(utils.path_from_root('tools/unsafe_optimizations.mjs'), [final_js, '-o', final_js], cwd=utils.path_from_root('.')) save_intermediate('unsafe-optimizations2') - fix_js_mangling(final_js) + fix_closure(final_js) # Apply pre and postjs files if options.extern_pre_js or options.extern_post_js: @@ -2243,7 +2244,7 @@ def phase_final_emitting(options, target, js_target, wasm_target): support_target = unsuffixed(js_target) + '.pthread.mjs' pthread_code = building.read_and_preprocess(utils.path_from_root('src/pthread_esm_startup.mjs'), expand_macros=True) write_file(support_target, pthread_code) - fix_js_mangling(support_target) + fix_closure(support_target) else: move_file(final_js, js_target) @@ -2437,29 +2438,22 @@ def phase_binaryen(target, options, wasm_target): delete_file(wasm_target) write_file(final_js, js) - def modularize(): global final_js - logger.debug(f'Modularizing, creating factory function called `{settings.EXPORT_NAME}`') - modularize_src = building.read_and_preprocess(utils.path_from_root('src/modularize.js'), expand_macros=True) + logger.debug(f'Modularizing for PTHREADS/WASM_WORKERS') + + modularize_src = building.read_and_preprocess(utils.path_from_root('src/postamble_modularize_worker.js'), expand_macros=True) if settings.MINIFY_WHITESPACE: with shared.get_temp_files().get_file(suffix='.js') as tmp: write_file(tmp, modularize_src) minified_file = building.acorn_optimizer(tmp, ['--minify-whitespace']) modularize_src = read_file(minified_file) - # Replace INNER_JS_CODE in the minified code - full_src = do_replace(modularize_src, '"<<< INNER_JS_CODE >>>"', read_file(final_js)) - final_js += '.modular.js' + full_src = read_file(final_js) + modularize_src + final_js += '.modular-worker.js' write_file(final_js, full_src) shared.get_temp_files().note(final_js) - save_intermediate('modularized') - - # FIXME(https://github.com/emscripten-core/emscripten/issues/24558): Running acorn at this - # late phase seems to cause OOM (some kind of infinite loop perhaps) in node. - # Instead we minify src/modularize.js in isolation above. - # if settings.MINIFY_WHITESPACE: - # final_js = building.acorn_optimizer(final_js, ['--minify-whitespace']) + save_intermediate('modular-worker') def module_export_name_substitution(): diff --git a/tools/unsafe_optimizations.mjs b/tools/unsafe_optimizations.mjs index fb10c04a73db0..a55641488673b 100755 --- a/tools/unsafe_optimizations.mjs +++ b/tools/unsafe_optimizations.mjs @@ -33,34 +33,6 @@ function visitNodes(root, types, func) { } } -function optPassSimplifyModularizeFunction(ast) { - visitNodes(ast, ['FunctionExpression'], (node) => { - if (node.params.length == 1 && node.params[0].name == 'Module') { - const body = node.body.body; - // Nuke 'Module = Module || {};' - if ( - body[0].type == 'ExpressionStatement' && - body[0].expression.type == 'AssignmentExpression' && - body[0].expression.left.name == 'Module' - ) { - body.splice(0, 1); - } - // Replace 'function(Module) {var f = Module;' -> 'function(f) {' - if ( - body[0].type == 'VariableDeclaration' && - body[0].declarations[0]?.init?.name == 'Module' - ) { - node.params[0].name = body[0].declarations[0].id.name; - body[0].declarations.splice(0, 1); - if (body[0].declarations.length == 0) { - body.splice(0, 1); - } - } - return false; - } - }); -} - // Finds redundant operator new statements that are not assigned anywhere. // (we aren't interested in side effects of the calls if no assignment) function optPassRemoveRedundantOperatorNews(ast) { @@ -218,8 +190,6 @@ function runOnJsText(js, pretty = false) { progress = progress || optPassMergeEmptyVarDeclarators(ast); } - optPassSimplifyModularizeFunction(ast); - const terserAst = terser.AST_Node.from_mozilla_ast(ast); const output = terserAst.print_to_string({ wrap_func_args: false, @@ -250,12 +220,6 @@ function test(input, expected) { } function runTests() { - // optPassSimplifyModularizeFunction: - test( - 'var Module = function(Module) {Module = Module || {};var f = Module;}', - 'var Module=function(f){};', - ); - // optPassRemoveRedundantOperatorNews: test('new Uint16Array(a);', ''); test('new Uint16Array(a),new Uint16Array(a);', ';'); From 6fb0e219dee3ba64c24d2fda0519e655407ba4e1 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 23 Jun 2026 20:13:59 +0000 Subject: [PATCH 2/4] Automatic rebaseline of codesize expectations. NFC This is an automatic change generated by tools/maint/rebaseline_tests.py. The following (6) test expectation files were updated by running the tests with `--rebaseline`: ``` codesize/test_codesize_minimal_esm.json: 2423 => 2387 [-36 bytes / -1.49%] codesize/test_minimal_runtime_code_size_hello_webgl2_wasm.json: 13161 => 13631 [+470 bytes / +3.57%] codesize/test_minimal_runtime_code_size_hello_webgl2_wasm2js.json: 18534 => 19156 [+622 bytes / +3.36%] codesize/test_minimal_runtime_code_size_hello_webgl2_wasm_singlefile.json: 15015 => 15485 [+470 bytes / +3.13%] codesize/test_minimal_runtime_code_size_hello_webgl_wasm.json: 12699 => 13134 [+435 bytes / +3.43%] codesize/test_minimal_runtime_code_size_hello_webgl_wasm2js.json: 18060 => 18650 [+590 bytes / +3.27%] Average change: +2.54% (-1.49% - +3.57%) ``` --- test/codesize/test_codesize_minimal_esm.json | 8 ++++---- .../test_minimal_runtime_code_size_hello_webgl2_wasm.json | 8 ++++---- ...st_minimal_runtime_code_size_hello_webgl2_wasm2js.json | 8 ++++---- ...al_runtime_code_size_hello_webgl2_wasm_singlefile.json | 4 ++-- .../test_minimal_runtime_code_size_hello_webgl_wasm.json | 8 ++++---- ...est_minimal_runtime_code_size_hello_webgl_wasm2js.json | 8 ++++---- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/test/codesize/test_codesize_minimal_esm.json b/test/codesize/test_codesize_minimal_esm.json index eceee257497fd..c568a5b4dff52 100644 --- a/test/codesize/test_codesize_minimal_esm.json +++ b/test/codesize/test_codesize_minimal_esm.json @@ -1,10 +1,10 @@ { - "a.out.js": 2348, - "a.out.js.gz": 1111, + "a.out.js": 2312, + "a.out.js.gz": 1124, "a.out.nodebug.wasm": 75, "a.out.nodebug.wasm.gz": 87, - "total": 2423, - "total_gz": 1198, + "total": 2387, + "total_gz": 1211, "sent": [], "imports": [], "exports": [ diff --git a/test/codesize/test_minimal_runtime_code_size_hello_webgl2_wasm.json b/test/codesize/test_minimal_runtime_code_size_hello_webgl2_wasm.json index b796ae2e3afb9..a45982921e577 100644 --- a/test/codesize/test_minimal_runtime_code_size_hello_webgl2_wasm.json +++ b/test/codesize/test_minimal_runtime_code_size_hello_webgl2_wasm.json @@ -1,10 +1,10 @@ { "a.html": 450, "a.html.gz": 318, - "a.js": 4398, - "a.js.gz": 2259, + "a.js": 4868, + "a.js.gz": 2446, "a.wasm": 8313, "a.wasm.gz": 5646, - "total": 13161, - "total_gz": 8223 + "total": 13631, + "total_gz": 8410 } diff --git a/test/codesize/test_minimal_runtime_code_size_hello_webgl2_wasm2js.json b/test/codesize/test_minimal_runtime_code_size_hello_webgl2_wasm2js.json index 08ef9b5c54814..f1aa128136145 100644 --- a/test/codesize/test_minimal_runtime_code_size_hello_webgl2_wasm2js.json +++ b/test/codesize/test_minimal_runtime_code_size_hello_webgl2_wasm2js.json @@ -1,8 +1,8 @@ { "a.html": 342, "a.html.gz": 252, - "a.js": 18192, - "a.js.gz": 9813, - "total": 18534, - "total_gz": 10065 + "a.js": 18814, + "a.js.gz": 10064, + "total": 19156, + "total_gz": 10316 } diff --git a/test/codesize/test_minimal_runtime_code_size_hello_webgl2_wasm_singlefile.json b/test/codesize/test_minimal_runtime_code_size_hello_webgl2_wasm_singlefile.json index 57b149f07a2dc..31dfbb413efa7 100644 --- a/test/codesize/test_minimal_runtime_code_size_hello_webgl2_wasm_singlefile.json +++ b/test/codesize/test_minimal_runtime_code_size_hello_webgl2_wasm_singlefile.json @@ -1,4 +1,4 @@ { - "a.html": 15015, - "a.html.gz": 8990 + "a.html": 15485, + "a.html.gz": 9198 } diff --git a/test/codesize/test_minimal_runtime_code_size_hello_webgl_wasm.json b/test/codesize/test_minimal_runtime_code_size_hello_webgl_wasm.json index 9dc6d3a08181b..888c5eb0ea4a1 100644 --- a/test/codesize/test_minimal_runtime_code_size_hello_webgl_wasm.json +++ b/test/codesize/test_minimal_runtime_code_size_hello_webgl_wasm.json @@ -1,10 +1,10 @@ { "a.html": 450, "a.html.gz": 318, - "a.js": 3936, - "a.js.gz": 2095, + "a.js": 4371, + "a.js.gz": 2264, "a.wasm": 8313, "a.wasm.gz": 5646, - "total": 12699, - "total_gz": 8059 + "total": 13134, + "total_gz": 8228 } diff --git a/test/codesize/test_minimal_runtime_code_size_hello_webgl_wasm2js.json b/test/codesize/test_minimal_runtime_code_size_hello_webgl_wasm2js.json index 88b024fee1321..648edf7923dec 100644 --- a/test/codesize/test_minimal_runtime_code_size_hello_webgl_wasm2js.json +++ b/test/codesize/test_minimal_runtime_code_size_hello_webgl_wasm2js.json @@ -1,8 +1,8 @@ { "a.html": 342, "a.html.gz": 252, - "a.js": 17718, - "a.js.gz": 9647, - "total": 18060, - "total_gz": 9899 + "a.js": 18308, + "a.js.gz": 9878, + "total": 18650, + "total_gz": 10130 } From e7dc17ef2b7b6985c77a061e531664d705bea823 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 24 Jun 2026 09:03:18 +0200 Subject: [PATCH 3/4] Small optimization --- src/lib/libstrings.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/lib/libstrings.js b/src/lib/libstrings.js index 9af1429a14dc3..681f57f71e6ec 100644 --- a/src/lib/libstrings.js +++ b/src/lib/libstrings.js @@ -18,6 +18,14 @@ addToLibrary({ $UTF8Decoder: "globalThis.TextDecoder && new TextDecoder()", #endif + $findStringEnd__docs: ` + /** + * heapOrArray is either a regular array, or a JavaScript typed array view. + * @param {number} idx + * @param {number=} maxBytesToRead + * @param {boolean=} ignoreNul + * @return {number} + */`, $findStringEnd: (heapOrArray, idx, maxBytesToRead, ignoreNul) => { var maxIdx = idx + maxBytesToRead; if (ignoreNul) return maxIdx; @@ -357,15 +365,13 @@ addToLibrary({ // maxBytesToWrite<2 does not write any bytes to the // output, not even the null terminator. // Returns the number of bytes written, EXCLUDING the null terminator. - $stringToUTF16: (str, outPtr, maxBytesToWrite) => { + $stringToUTF16: (str, outPtr, maxBytesToWrite = 0x7FFFFFFF) => { #if ASSERTIONS assert(outPtr % 2 == 0, 'pointer passed to stringToUTF16 must be 2-byte aligned'); #endif #if ASSERTIONS assert(typeof maxBytesToWrite == 'number', 'stringToUTF16 requires a third parameter that specifies the length of the output buffer'); #endif - // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. - maxBytesToWrite ??= 0x7FFFFFFF; if (maxBytesToWrite < 2) return 0; maxBytesToWrite -= 2; // Null terminator. var startPtr = outPtr; @@ -416,7 +422,7 @@ addToLibrary({ // maxBytesToWrite<4 does not write any bytes to the // output, not even the null terminator. // Returns the number of bytes written, EXCLUDING the null terminator. - $stringToUTF32: (str, outPtr, maxBytesToWrite) => { + $stringToUTF32: (str, outPtr, maxBytesToWrite = 0x7FFFFFFF) => { #if CAN_ADDRESS_2GB outPtr >>>= 0; #endif @@ -426,8 +432,6 @@ addToLibrary({ #if ASSERTIONS assert(typeof maxBytesToWrite == 'number', 'stringToUTF32 requires a third parameter that specifies the length of the output buffer'); #endif - // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. - maxBytesToWrite ??= 0x7FFFFFFF; if (maxBytesToWrite < 4) return 0; var startPtr = outPtr; var endPtr = startPtr + maxBytesToWrite - 4; From 2627bfae526e7d694ed6207c7e90e88a3726491a Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 24 Jun 2026 08:17:39 +0000 Subject: [PATCH 4/4] Automatic rebaseline of codesize expectations. NFC This is an automatic change generated by tools/maint/rebaseline_tests.py. The following (31) test expectation files were updated by running the tests with `--rebaseline`: ``` test/codesize/audio_worklet_wasm.expected.js updated test/codesize/hello_world_wasm.expected.js updated codesize/test_codesize_cxx_ctors1.json: 151867 => 151864 [-3 bytes / -0.00%] codesize/test_codesize_cxx_ctors2.json: 151270 => 151267 [-3 bytes / -0.00%] codesize/test_codesize_cxx_except.json: 195760 => 195757 [-3 bytes / -0.00%] codesize/test_codesize_cxx_except_wasm.json: 166991 => 166988 [-3 bytes / -0.00%] codesize/test_codesize_cxx_except_wasm_legacy.json: 164875 => 164872 [-3 bytes / -0.00%] codesize/test_codesize_cxx_lto.json: 120708 => 120705 [-3 bytes / -0.00%] codesize/test_codesize_cxx_mangle.json: 262239 => 262236 [-3 bytes / -0.00%] codesize/test_codesize_cxx_noexcept.json: 153867 => 153864 [-3 bytes / -0.00%] codesize/test_codesize_cxx_wasmfs.json: 179724 => 179721 [-3 bytes / -0.00%] test/codesize/test_codesize_file_preload.expected.js updated codesize/test_codesize_file_preload.json: 23823 => 23820 [-3 bytes / -0.01%] codesize/test_codesize_files_js_fs.json: 18247 => 18244 [-3 bytes / -0.02%] codesize/test_codesize_files_wasmfs.json: 63892 => 63889 [-3 bytes / -0.00%] codesize/test_codesize_hello_O0.json: 38598 => 38595 [-3 bytes / -0.01%] codesize/test_codesize_hello_O1.json: 8625 => 8622 [-3 bytes / -0.03%] codesize/test_codesize_hello_O2.json: 6136 => 6133 [-3 bytes / -0.05%] codesize/test_codesize_hello_O3.json: 5832 => 5829 [-3 bytes / -0.05%] codesize/test_codesize_hello_Os.json: 5820 => 5817 [-3 bytes / -0.05%] codesize/test_codesize_hello_Oz.json: 4989 => 4986 [-3 bytes / -0.06%] codesize/test_codesize_hello_single_file.json: 5141 => 5138 [-3 bytes / -0.06%] codesize/test_codesize_hello_wasmfs.json: 5832 => 5829 [-3 bytes / -0.05%] codesize/test_minimal_runtime_code_size_audio_worklet.json: 16399 => 16396 [-3 bytes / -0.02%] codesize/test_minimal_runtime_code_size_hello_embind.json: 14904 => 14896 [-8 bytes / -0.05%] codesize/test_minimal_runtime_code_size_hello_embind_val.json: 11643 => 11635 [-8 bytes / -0.07%] codesize/test_minimal_runtime_code_size_hello_world_wasm.json: 930 => 927 [-3 bytes / -0.32%] codesize/test_minimal_runtime_code_size_random_printf_wasm.json: 11057 => 11054 [-3 bytes / -0.03%] test/codesize/test_small_js_flags.expected.js updated codesize/test_small_js_flags.json: 3891 => 3888 [-3 bytes / -0.08%] codesize/test_unoptimized_code_size.json: 176480 => 177116 [+636 bytes / +0.36%] Average change: -0.02% (-0.32% - +0.36%) ``` --- test/codesize/audio_worklet_wasm.expected.js | 2 +- test/codesize/hello_world_wasm.expected.js | 2 +- test/codesize/test_codesize_cxx_ctors1.json | 4 ++-- test/codesize/test_codesize_cxx_ctors2.json | 8 ++++---- test/codesize/test_codesize_cxx_except.json | 4 ++-- test/codesize/test_codesize_cxx_except_wasm.json | 8 ++++---- .../test_codesize_cxx_except_wasm_legacy.json | 8 ++++---- test/codesize/test_codesize_cxx_lto.json | 8 ++++---- test/codesize/test_codesize_cxx_mangle.json | 4 ++-- test/codesize/test_codesize_cxx_noexcept.json | 4 ++-- test/codesize/test_codesize_cxx_wasmfs.json | 4 ++-- .../test_codesize_file_preload.expected.js | 8 +++++++- test/codesize/test_codesize_file_preload.json | 8 ++++---- test/codesize/test_codesize_files_js_fs.json | 8 ++++---- test/codesize/test_codesize_files_wasmfs.json | 8 ++++---- test/codesize/test_codesize_hello_O0.json | 4 ++-- test/codesize/test_codesize_hello_O1.json | 4 ++-- test/codesize/test_codesize_hello_O2.json | 4 ++-- test/codesize/test_codesize_hello_O3.json | 8 ++++---- test/codesize/test_codesize_hello_Os.json | 8 ++++---- test/codesize/test_codesize_hello_Oz.json | 8 ++++---- .../test_codesize_hello_single_file.json | 4 ++-- test/codesize/test_codesize_hello_wasmfs.json | 8 ++++---- ..._minimal_runtime_code_size_audio_worklet.json | 8 ++++---- ...t_minimal_runtime_code_size_hello_embind.json | 8 ++++---- ...nimal_runtime_code_size_hello_embind_val.json | 8 ++++---- ...nimal_runtime_code_size_hello_world_wasm.json | 8 ++++---- ...mal_runtime_code_size_random_printf_wasm.json | 4 ++-- test/codesize/test_small_js_flags.expected.js | 8 +++++++- test/codesize/test_small_js_flags.json | 8 ++++---- test/codesize/test_unoptimized_code_size.json | 16 ++++++++-------- 31 files changed, 108 insertions(+), 96 deletions(-) diff --git a/test/codesize/audio_worklet_wasm.expected.js b/test/codesize/audio_worklet_wasm.expected.js index 300d33ef23f8e..b872584cc2ba6 100644 --- a/test/codesize/audio_worklet_wasm.expected.js +++ b/test/codesize/audio_worklet_wasm.expected.js @@ -145,7 +145,7 @@ var L = [], M = a => { b = Q[b]; Q[a].connect(b.destination || b, c, k); }, Q = {}, R = 0, S = globalThis.TextDecoder && new TextDecoder, T = (a = 0) => { - for (var b = J, c = a, k = c + void 0; b[c] && !(c >= k); ) ++c; + for (var b = J, c = a, k = c + NaN; b[c] && !(c >= k); ) ++c; if (c - a > 16 && b.buffer && S) return S.decode(b.slice(a, c)); for (k = ""; a < c; ) { var d = b[a++]; diff --git a/test/codesize/hello_world_wasm.expected.js b/test/codesize/hello_world_wasm.expected.js index dd8856ad90787..cb72d2838de31 100644 --- a/test/codesize/hello_world_wasm.expected.js +++ b/test/codesize/hello_world_wasm.expected.js @@ -5,7 +5,7 @@ WebAssembly.instantiate(d.wasm, { a: a => { var c = console, k = c.log; if (a) { - for (var b = a, l = e, m = b + void 0; l[b] && !(b >= m); ) ++b; + for (var b = a, l = e, m = b + NaN; l[b] && !(b >= m); ) ++b; a = f.decode(e.subarray(a, b)); } else a = ""; k.call(c, a); diff --git a/test/codesize/test_codesize_cxx_ctors1.json b/test/codesize/test_codesize_cxx_ctors1.json index 672f9094b3dfa..2433ad1bc7b46 100644 --- a/test/codesize/test_codesize_cxx_ctors1.json +++ b/test/codesize/test_codesize_cxx_ctors1.json @@ -1,9 +1,9 @@ { - "a.out.js": 19218, + "a.out.js": 19215, "a.out.js.gz": 7948, "a.out.nodebug.wasm": 132649, "a.out.nodebug.wasm.gz": 49955, - "total": 151867, + "total": 151864, "total_gz": 57903, "sent": [ "__cxa_throw", diff --git a/test/codesize/test_codesize_cxx_ctors2.json b/test/codesize/test_codesize_cxx_ctors2.json index 5f71c70a3a8b0..85961e420e48e 100644 --- a/test/codesize/test_codesize_cxx_ctors2.json +++ b/test/codesize/test_codesize_cxx_ctors2.json @@ -1,10 +1,10 @@ { - "a.out.js": 19195, - "a.out.js.gz": 7932, + "a.out.js": 19192, + "a.out.js.gz": 7931, "a.out.nodebug.wasm": 132075, "a.out.nodebug.wasm.gz": 49617, - "total": 151270, - "total_gz": 57549, + "total": 151267, + "total_gz": 57548, "sent": [ "__cxa_throw", "_abort_js", diff --git a/test/codesize/test_codesize_cxx_except.json b/test/codesize/test_codesize_cxx_except.json index ef85021a53ff5..2cd0a7dd7eb71 100644 --- a/test/codesize/test_codesize_cxx_except.json +++ b/test/codesize/test_codesize_cxx_except.json @@ -1,9 +1,9 @@ { - "a.out.js": 23191, + "a.out.js": 23188, "a.out.js.gz": 8939, "a.out.nodebug.wasm": 172569, "a.out.nodebug.wasm.gz": 57493, - "total": 195760, + "total": 195757, "total_gz": 66432, "sent": [ "__cxa_begin_catch", diff --git a/test/codesize/test_codesize_cxx_except_wasm.json b/test/codesize/test_codesize_cxx_except_wasm.json index 20422da101057..76c4c4037dab2 100644 --- a/test/codesize/test_codesize_cxx_except_wasm.json +++ b/test/codesize/test_codesize_cxx_except_wasm.json @@ -1,10 +1,10 @@ { - "a.out.js": 19017, - "a.out.js.gz": 7872, + "a.out.js": 19014, + "a.out.js.gz": 7870, "a.out.nodebug.wasm": 147974, "a.out.nodebug.wasm.gz": 55362, - "total": 166991, - "total_gz": 63234, + "total": 166988, + "total_gz": 63232, "sent": [ "_abort_js", "_tzset_js", diff --git a/test/codesize/test_codesize_cxx_except_wasm_legacy.json b/test/codesize/test_codesize_cxx_except_wasm_legacy.json index 9d3ec44cda842..6b4430987903b 100644 --- a/test/codesize/test_codesize_cxx_except_wasm_legacy.json +++ b/test/codesize/test_codesize_cxx_except_wasm_legacy.json @@ -1,10 +1,10 @@ { - "a.out.js": 19095, - "a.out.js.gz": 7894, + "a.out.js": 19092, + "a.out.js.gz": 7895, "a.out.nodebug.wasm": 145780, "a.out.nodebug.wasm.gz": 54985, - "total": 164875, - "total_gz": 62879, + "total": 164872, + "total_gz": 62880, "sent": [ "_abort_js", "_tzset_js", diff --git a/test/codesize/test_codesize_cxx_lto.json b/test/codesize/test_codesize_cxx_lto.json index 453c0080b9c11..404797558c4fa 100644 --- a/test/codesize/test_codesize_cxx_lto.json +++ b/test/codesize/test_codesize_cxx_lto.json @@ -1,10 +1,10 @@ { - "a.out.js": 18557, - "a.out.js.gz": 7638, + "a.out.js": 18554, + "a.out.js.gz": 7641, "a.out.nodebug.wasm": 102151, "a.out.nodebug.wasm.gz": 39561, - "total": 120708, - "total_gz": 47199, + "total": 120705, + "total_gz": 47202, "sent": [ "a (emscripten_resize_heap)", "b (_setitimer_js)", diff --git a/test/codesize/test_codesize_cxx_mangle.json b/test/codesize/test_codesize_cxx_mangle.json index f901453d90ea0..96951c8e404bf 100644 --- a/test/codesize/test_codesize_cxx_mangle.json +++ b/test/codesize/test_codesize_cxx_mangle.json @@ -1,9 +1,9 @@ { - "a.out.js": 23241, + "a.out.js": 23238, "a.out.js.gz": 8961, "a.out.nodebug.wasm": 238998, "a.out.nodebug.wasm.gz": 79846, - "total": 262239, + "total": 262236, "total_gz": 88807, "sent": [ "__cxa_begin_catch", diff --git a/test/codesize/test_codesize_cxx_noexcept.json b/test/codesize/test_codesize_cxx_noexcept.json index e8eb0ae34a69e..f14e0cdd1d62f 100644 --- a/test/codesize/test_codesize_cxx_noexcept.json +++ b/test/codesize/test_codesize_cxx_noexcept.json @@ -1,9 +1,9 @@ { - "a.out.js": 19218, + "a.out.js": 19215, "a.out.js.gz": 7948, "a.out.nodebug.wasm": 134649, "a.out.nodebug.wasm.gz": 50797, - "total": 153867, + "total": 153864, "total_gz": 58745, "sent": [ "__cxa_throw", diff --git a/test/codesize/test_codesize_cxx_wasmfs.json b/test/codesize/test_codesize_cxx_wasmfs.json index f3443fcc4323b..e82ff0ee4ce76 100644 --- a/test/codesize/test_codesize_cxx_wasmfs.json +++ b/test/codesize/test_codesize_cxx_wasmfs.json @@ -1,9 +1,9 @@ { - "a.out.js": 6938, + "a.out.js": 6935, "a.out.js.gz": 3259, "a.out.nodebug.wasm": 172786, "a.out.nodebug.wasm.gz": 63366, - "total": 179724, + "total": 179721, "total_gz": 66625, "sent": [ "__cxa_throw", diff --git a/test/codesize/test_codesize_file_preload.expected.js b/test/codesize/test_codesize_file_preload.expected.js index e480e750f3c58..b91e75ddb21a2 100644 --- a/test/codesize/test_codesize_file_preload.expected.js +++ b/test/codesize/test_codesize_file_preload.expected.js @@ -662,7 +662,13 @@ var PATH_FS = { var UTF8Decoder = globalThis.TextDecoder && new TextDecoder; -var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => { +/** + * heapOrArray is either a regular array, or a JavaScript typed array view. + * @param {number} idx + * @param {number=} maxBytesToRead + * @param {boolean=} ignoreNul + * @return {number} + */ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => { var maxIdx = idx + maxBytesToRead; if (ignoreNul) return maxIdx; // TextDecoder needs to know the byte length in advance, it doesn't stop on diff --git a/test/codesize/test_codesize_file_preload.json b/test/codesize/test_codesize_file_preload.json index 26a8db46e27eb..e69fbda7b3e85 100644 --- a/test/codesize/test_codesize_file_preload.json +++ b/test/codesize/test_codesize_file_preload.json @@ -1,10 +1,10 @@ { - "a.out.js": 22157, - "a.out.js.gz": 9192, + "a.out.js": 22154, + "a.out.js.gz": 9193, "a.out.nodebug.wasm": 1666, "a.out.nodebug.wasm.gz": 945, - "total": 23823, - "total_gz": 10137, + "total": 23820, + "total_gz": 10138, "sent": [ "a (fd_write)" ], diff --git a/test/codesize/test_codesize_files_js_fs.json b/test/codesize/test_codesize_files_js_fs.json index 97f72548b5a09..8b4b54fe139b5 100644 --- a/test/codesize/test_codesize_files_js_fs.json +++ b/test/codesize/test_codesize_files_js_fs.json @@ -1,10 +1,10 @@ { - "a.out.js": 17866, - "a.out.js.gz": 7289, + "a.out.js": 17863, + "a.out.js.gz": 7286, "a.out.nodebug.wasm": 381, "a.out.nodebug.wasm.gz": 260, - "total": 18247, - "total_gz": 7549, + "total": 18244, + "total_gz": 7546, "sent": [ "a (fd_write)", "b (fd_read)", diff --git a/test/codesize/test_codesize_files_wasmfs.json b/test/codesize/test_codesize_files_wasmfs.json index 6ef587b23b45f..466a4f64a722e 100644 --- a/test/codesize/test_codesize_files_wasmfs.json +++ b/test/codesize/test_codesize_files_wasmfs.json @@ -1,10 +1,10 @@ { - "a.out.js": 5372, - "a.out.js.gz": 2527, + "a.out.js": 5369, + "a.out.js.gz": 2525, "a.out.nodebug.wasm": 58520, "a.out.nodebug.wasm.gz": 18225, - "total": 63892, - "total_gz": 20752, + "total": 63889, + "total_gz": 20750, "sent": [ "a (emscripten_date_now)", "b (emscripten_err)", diff --git a/test/codesize/test_codesize_hello_O0.json b/test/codesize/test_codesize_hello_O0.json index 35c3470b5e2e5..226655e8db332 100644 --- a/test/codesize/test_codesize_hello_O0.json +++ b/test/codesize/test_codesize_hello_O0.json @@ -1,9 +1,9 @@ { - "a.out.js": 23483, + "a.out.js": 23480, "a.out.js.gz": 8523, "a.out.nodebug.wasm": 15115, "a.out.nodebug.wasm.gz": 7464, - "total": 38598, + "total": 38595, "total_gz": 15987, "sent": [ "fd_write" diff --git a/test/codesize/test_codesize_hello_O1.json b/test/codesize/test_codesize_hello_O1.json index 6fc1e13f37b50..434cfd0dadeba 100644 --- a/test/codesize/test_codesize_hello_O1.json +++ b/test/codesize/test_codesize_hello_O1.json @@ -1,9 +1,9 @@ { - "a.out.js": 6081, + "a.out.js": 6078, "a.out.js.gz": 2373, "a.out.nodebug.wasm": 2544, "a.out.nodebug.wasm.gz": 1436, - "total": 8625, + "total": 8622, "total_gz": 3809, "sent": [ "fd_write" diff --git a/test/codesize/test_codesize_hello_O2.json b/test/codesize/test_codesize_hello_O2.json index 0faee4aae5e9f..365b5747ee128 100644 --- a/test/codesize/test_codesize_hello_O2.json +++ b/test/codesize/test_codesize_hello_O2.json @@ -1,9 +1,9 @@ { - "a.out.js": 4224, + "a.out.js": 4221, "a.out.js.gz": 2073, "a.out.nodebug.wasm": 1912, "a.out.nodebug.wasm.gz": 1129, - "total": 6136, + "total": 6133, "total_gz": 3202, "sent": [ "fd_write" diff --git a/test/codesize/test_codesize_hello_O3.json b/test/codesize/test_codesize_hello_O3.json index 64fa4e9f093c2..c133fc44b45fc 100644 --- a/test/codesize/test_codesize_hello_O3.json +++ b/test/codesize/test_codesize_hello_O3.json @@ -1,10 +1,10 @@ { - "a.out.js": 4166, - "a.out.js.gz": 2034, + "a.out.js": 4163, + "a.out.js.gz": 2033, "a.out.nodebug.wasm": 1666, "a.out.nodebug.wasm.gz": 945, - "total": 5832, - "total_gz": 2979, + "total": 5829, + "total_gz": 2978, "sent": [ "a (fd_write)" ], diff --git a/test/codesize/test_codesize_hello_Os.json b/test/codesize/test_codesize_hello_Os.json index 08188848925a5..81c02190601de 100644 --- a/test/codesize/test_codesize_hello_Os.json +++ b/test/codesize/test_codesize_hello_Os.json @@ -1,10 +1,10 @@ { - "a.out.js": 4166, - "a.out.js.gz": 2034, + "a.out.js": 4163, + "a.out.js.gz": 2033, "a.out.nodebug.wasm": 1654, "a.out.nodebug.wasm.gz": 953, - "total": 5820, - "total_gz": 2987, + "total": 5817, + "total_gz": 2986, "sent": [ "a (fd_write)" ], diff --git a/test/codesize/test_codesize_hello_Oz.json b/test/codesize/test_codesize_hello_Oz.json index 0e864c65a4e75..264014ee4bf96 100644 --- a/test/codesize/test_codesize_hello_Oz.json +++ b/test/codesize/test_codesize_hello_Oz.json @@ -1,10 +1,10 @@ { - "a.out.js": 3801, - "a.out.js.gz": 1840, + "a.out.js": 3798, + "a.out.js.gz": 1842, "a.out.nodebug.wasm": 1188, "a.out.nodebug.wasm.gz": 731, - "total": 4989, - "total_gz": 2571, + "total": 4986, + "total_gz": 2573, "sent": [ "a (fd_write)" ], diff --git a/test/codesize/test_codesize_hello_single_file.json b/test/codesize/test_codesize_hello_single_file.json index 0e0d8db9e4571..24f2cc3730586 100644 --- a/test/codesize/test_codesize_hello_single_file.json +++ b/test/codesize/test_codesize_hello_single_file.json @@ -1,6 +1,6 @@ { - "a.out.js": 5141, - "a.out.js.gz": 2827, + "a.out.js": 5138, + "a.out.js.gz": 2825, "sent": [ "a (fd_write)" ] diff --git a/test/codesize/test_codesize_hello_wasmfs.json b/test/codesize/test_codesize_hello_wasmfs.json index 64fa4e9f093c2..c133fc44b45fc 100644 --- a/test/codesize/test_codesize_hello_wasmfs.json +++ b/test/codesize/test_codesize_hello_wasmfs.json @@ -1,10 +1,10 @@ { - "a.out.js": 4166, - "a.out.js.gz": 2034, + "a.out.js": 4163, + "a.out.js.gz": 2033, "a.out.nodebug.wasm": 1666, "a.out.nodebug.wasm.gz": 945, - "total": 5832, - "total_gz": 2979, + "total": 5829, + "total_gz": 2978, "sent": [ "a (fd_write)" ], diff --git a/test/codesize/test_minimal_runtime_code_size_audio_worklet.json b/test/codesize/test_minimal_runtime_code_size_audio_worklet.json index f2789f2a8f778..7926e7f357219 100644 --- a/test/codesize/test_minimal_runtime_code_size_audio_worklet.json +++ b/test/codesize/test_minimal_runtime_code_size_audio_worklet.json @@ -1,10 +1,10 @@ { "a.html": 515, "a.html.gz": 355, - "a.js": 4647, - "a.js.gz": 2381, + "a.js": 4644, + "a.js.gz": 2382, "a.wasm": 11237, "a.wasm.gz": 6116, - "total": 16399, - "total_gz": 8852 + "total": 16396, + "total_gz": 8853 } diff --git a/test/codesize/test_minimal_runtime_code_size_hello_embind.json b/test/codesize/test_minimal_runtime_code_size_hello_embind.json index 680ea781c39af..d3f128deb07a6 100644 --- a/test/codesize/test_minimal_runtime_code_size_hello_embind.json +++ b/test/codesize/test_minimal_runtime_code_size_hello_embind.json @@ -1,10 +1,10 @@ { "a.html": 548, "a.html.gz": 371, - "a.js": 7257, - "a.js.gz": 3328, + "a.js": 7249, + "a.js.gz": 3325, "a.wasm": 7099, "a.wasm.gz": 3246, - "total": 14904, - "total_gz": 6945 + "total": 14896, + "total_gz": 6942 } diff --git a/test/codesize/test_minimal_runtime_code_size_hello_embind_val.json b/test/codesize/test_minimal_runtime_code_size_hello_embind_val.json index af722695b21c4..f729802cdd1eb 100644 --- a/test/codesize/test_minimal_runtime_code_size_hello_embind_val.json +++ b/test/codesize/test_minimal_runtime_code_size_hello_embind_val.json @@ -1,10 +1,10 @@ { "a.html": 548, "a.html.gz": 371, - "a.js": 5354, - "a.js.gz": 2519, + "a.js": 5346, + "a.js.gz": 2515, "a.wasm": 5741, "a.wasm.gz": 2690, - "total": 11643, - "total_gz": 5580 + "total": 11635, + "total_gz": 5576 } diff --git a/test/codesize/test_minimal_runtime_code_size_hello_world_wasm.json b/test/codesize/test_minimal_runtime_code_size_hello_world_wasm.json index cbc776e272b48..99c0d29ff9a53 100644 --- a/test/codesize/test_minimal_runtime_code_size_hello_world_wasm.json +++ b/test/codesize/test_minimal_runtime_code_size_hello_world_wasm.json @@ -1,10 +1,10 @@ { "a.html": 548, "a.html.gz": 371, - "a.js": 287, - "a.js.gz": 242, + "a.js": 284, + "a.js.gz": 240, "a.wasm": 95, "a.wasm.gz": 101, - "total": 930, - "total_gz": 714 + "total": 927, + "total_gz": 712 } diff --git a/test/codesize/test_minimal_runtime_code_size_random_printf_wasm.json b/test/codesize/test_minimal_runtime_code_size_random_printf_wasm.json index 66dd10f408dfa..206b2029eedff 100644 --- a/test/codesize/test_minimal_runtime_code_size_random_printf_wasm.json +++ b/test/codesize/test_minimal_runtime_code_size_random_printf_wasm.json @@ -1,4 +1,4 @@ { - "a.html": 11057, - "a.html.gz": 5756 + "a.html": 11054, + "a.html.gz": 5754 } diff --git a/test/codesize/test_small_js_flags.expected.js b/test/codesize/test_small_js_flags.expected.js index 798ff6cc0266a..c52d3df56b18b 100644 --- a/test/codesize/test_small_js_flags.expected.js +++ b/test/codesize/test_small_js_flags.expected.js @@ -288,7 +288,13 @@ var printCharBuffers = [ null, [], [] ]; var UTF8Decoder = globalThis.TextDecoder && new TextDecoder; -var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => { +/** + * heapOrArray is either a regular array, or a JavaScript typed array view. + * @param {number} idx + * @param {number=} maxBytesToRead + * @param {boolean=} ignoreNul + * @return {number} + */ var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => { var maxIdx = idx + maxBytesToRead; if (ignoreNul) return maxIdx; // TextDecoder needs to know the byte length in advance, it doesn't stop on diff --git a/test/codesize/test_small_js_flags.json b/test/codesize/test_small_js_flags.json index e53e68dbca963..7ca0c00f0cfbd 100644 --- a/test/codesize/test_small_js_flags.json +++ b/test/codesize/test_small_js_flags.json @@ -1,10 +1,10 @@ { - "a.out.js": 2225, - "a.out.js.gz": 1232, + "a.out.js": 2222, + "a.out.js.gz": 1230, "a.out.nodebug.wasm": 1666, "a.out.nodebug.wasm.gz": 945, - "total": 3891, - "total_gz": 2177, + "total": 3888, + "total_gz": 2175, "sent": [ "a (fd_write)" ], diff --git a/test/codesize/test_unoptimized_code_size.json b/test/codesize/test_unoptimized_code_size.json index 3e8dbb92eef88..16a8a5a6402ef 100644 --- a/test/codesize/test_unoptimized_code_size.json +++ b/test/codesize/test_unoptimized_code_size.json @@ -1,16 +1,16 @@ { - "hello_world.js": 55305, - "hello_world.js.gz": 17405, + "hello_world.js": 55517, + "hello_world.js.gz": 17423, "hello_world.wasm": 15115, "hello_world.wasm.gz": 7464, - "no_asserts.js": 25683, - "no_asserts.js.gz": 8690, + "no_asserts.js": 25895, + "no_asserts.js.gz": 8711, "no_asserts.wasm": 12229, "no_asserts.wasm.gz": 6004, - "strict.js": 53033, - "strict.js.gz": 16620, + "strict.js": 53245, + "strict.js.gz": 16641, "strict.wasm": 15115, "strict.wasm.gz": 7461, - "total": 176480, - "total_gz": 63644 + "total": 177116, + "total_gz": 63704 }