Teach metadce about the WASM_ESM_INTEGRATION module boundary#27218
Open
guybedford wants to merge 1 commit into
Open
Teach metadce about the WASM_ESM_INTEGRATION module boundary#27218guybedford wants to merge 1 commit into
guybedford wants to merge 1 commit into
Conversation
Building with -sWASM_ESM_INTEGRATION at -O2 or above failed in the JS
optimizer's metadce pass with 'could not find the assignment to
"wasmImports"'. In this mode the wasm<->JS boundary is expressed with
native ES import/export syntax rather than the wasmImports object and
wasmExports['x'] member uses that metadce pattern-matches.
Teach the three metadce-related acorn-optimizer passes about the ES form:
- emitDCEGraph reads 'import {..} from "./x.wasm"' as wasm export nodes
(collapsing aliases such as memory/wasmMemory to one node) and
'export { js as wasmName }' as wasm import edges, leaving re-exports
(export { _main }) to root naturally.
- applyDCEGraphRemovals prunes unused specifiers from those statements.
- applyImportAndExportNameChanges applies minified names to the
wasm-facing side of each specifier.
building.py also drops dropped exports (including internal ones like the
indirect function table) from the JS import to keep the two interfaces
in sync, and link.py keeps import/export name minification on for ESM
while disabling the now-pointless import module name minification.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This makes
-sWASM_ESM_INTEGRATIONwork at-O2and above. Previously such builds failed in the JS optimizer's metadce (dead code elimination) pass with:The reason is that metadce reconstructs the wasm⇄JS def/use graph by pattern-matching the idioms a normal build emits — the
wasmImportsobject literal andwasmExports['x']member uses. Under ESM integration those don't exist: the boundary is expressed with native ES module syntax instead, which is exactly the simpler, tooling-visible def/use graph this mode was designed to produce:So rather than synthesise the old shapes, metadce now reads the real module bindings directly.
emitDCEGraphrecognisesimport {..} from './x.wasm'as wasm export nodes (collapsing aliases such asmemory/wasmMemoryonto a single node) andexport { js as wasmName }as wasm import edges, while leaving re-exports (export { _main }) to root naturally.applyDCEGraphRemovalsprunes unused specifiers from those sameimport/exportstatements.applyImportAndExportNameChangesapplies binaryen's minified names to the wasm-facing side of each specifier, e.g.becomes
The local binding is preserved (an unaliased
memorybecomesb as memory, not a brokenb).Two supporting changes keep the two module interfaces in sync:
building.py— under ESM integration any export binaryen drops (including internal ones like the indirect function table) is also dropped from the JSimport, so the JS never imports something the wasm no longer exports.link.py— import/export name minification stays on for ESM, but import module name minification is disabled, since every import is rewritten to the single support-module source bycreate_esm_wrapperanyway (and minifyingenv→awould break that rewrite).Test coverage:
js_optimizerfixtures exercising each pass on ESM-shaped input:emitDCEGraph-esm,applyDCEGraphRemovals-esm,applyImportAndExportNameChanges-esm.other.test_metadce_esm_integrationbuildinghello_world.cwith-O3 -sWASM_ESM_INTEGRATION, asserting the dangling table import is removed and names are minified consistently (the run is guarded on Node 25).Resolves #27217.
Made with AI assistance under my review