Unify wasm-bindgen output under -sWASM_BINDGEN, add -sWASM_BINDGEN=auto#27208
Open
guybedford wants to merge 1 commit into
Open
Unify wasm-bindgen output under -sWASM_BINDGEN, add -sWASM_BINDGEN=auto#27208guybedford wants to merge 1 commit into
guybedford wants to merge 1 commit into
Conversation
cddd117 to
b7e9291
Compare
wasm-bindgen 0.2.126 (wasm-bindgen/wasm-bindgen#5210) hoists the clean exported API (functions, classes, enums) into top-level library symbols that self-register into EXPORTED_FUNCTIONS via its `--js-library`. The user-facing API now comes from wasm-bindgen's library in every flow, so emscripten no longer needs to guess or own the export set. This collapses the previous staticlib-only handling into a single -sWASM_BINDGEN path that works whether cargo/rustc drives the link (bin crate, emcc as the linker, rustc supplies -sEXPORTED_FUNCTIONS) or emcc drives it (staticlib, exports discovered locally): - The exports the wasm-bindgen expansion reaches by name - the supplied EXPORTED_FUNCTIONS (method shims, the __wbindgen_* runtime, the marker, main) plus anything its expansion adds - are internal glue, not a user API. They are captured and kept off every export layer: the ESM wrapper (user_requested_exports), the factory Module attachment (EXPORTED_FUNCTIONS, via should_export), and the keepalive pass in finalize_wasm. `main` still runs automatically on init; `_main` isn't surfaced. - A genuine EMSCRIPTEN_KEEPALIVE C/C++ export is not in that internal set and remains surfaced, so a hand-written native export composes with wasm-bindgen's API in the same module. Human-supplied EXPORTED_FUNCTIONS are not preserved through wasm-bindgen linkage yet (the rustc-supplied set is indistinguishable from glue); that can be revisited later. - Strip the placeholder symbols wasm-bindgen consumes (__wbindgen_describe*, __externref_*, ...) so they aren't reported as undefined exports. - Only run nm-based export discovery for explicit -sWASM_BINDGEN when no driver supplied EXPORTED_FUNCTIONS; the rustc-driven link already lists them exactly. - Wire imported JS: feed library_bindgen.extern-pre.js as extern-pre-js and copy the snippets/ dir next to the output so relative imports resolve. - The WASM_ESM_INTEGRATION wrapper re-exports the JS library symbols that were exported (MODULARIZE=instance), and provides wasmExports via a namespace import of the wasm so by-name export access works. Add -sWASM_BINDGEN=auto: run wasm-bindgen only when the linked wasm carries wasm-bindgen's __wasm_bindgen_emscripten_marker custom section, which is how cargo/rustc opts in when driving emcc as the linker (addressing the request to replace implicit marker detection with an explicit flag); otherwise it is a no-op and wasm-bindgen need not be installed. Both output modes then expose only the clean API (e.g. a `Greeter` class). Add an end-to-end test parameterized over the ESM and factory output modes (built via cargo with -sWASM_BINDGEN=auto), a no-marker test asserting auto is a no-op for an ordinary build, extend the staticlib integration test to assert an EMSCRIPTEN_KEEPALIVE export survives alongside the wasm-bindgen API, and install a pinned wasm-bindgen-cli alongside rust in CI so the flow is always exercised.
b7e9291 to
c10cb62
Compare
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 unifies wasm-bindgen output generation under a single
-sWASM_BINDGENpath and adds-sWASM_BINDGEN=auto, building on the wasm-bindgen side change in wasm-bindgen/wasm-bindgen#5210 (shipped in 0.2.126). It supersedes #27179.Previously
-sWASM_BINDGENwas effectively a staticlib-only flow where emcc had to discover and own the export set itself. With #5210, wasm-bindgen hoists its clean exported API (functions, classes, enums) into top-level library symbols that self-register intoEXPORTED_FUNCTIONSvia its--js-library. The user-facing API now comes from wasm-bindgen's own library in every flow, so emscripten no longer needs to guess or own exports — it just surfaces what wasm-bindgen registered. That lets one-sWASM_BINDGENpath serve both whether cargo/rustc drives the link (bin crate, emcc as the linker, rustc supplies-sEXPORTED_FUNCTIONS) or emcc drives it (staticlib, exports discovered locally).The model for a public export is the union across both systems: wasm-bindgen's self-registered API, plus emscripten's own
EMSCRIPTEN_KEEPALIVEexports — minus wasm-bindgen's internal expansion glue, which must not spill into the public surface.What's implemented:
EXPORTED_FUNCTIONS(method shims, the__wbindgen_*runtime, the marker,main) plus anything its expansion adds — are captured as internal glue and kept off every export layer: the ESM wrapper (user_requested_exports), the factoryModuleattachment (EXPORTED_FUNCTIONS, viashould_export), and the keepalive pass infinalize_wasm.mainstill runs automatically on init;_mainisn't surfaced.EMSCRIPTEN_KEEPALIVEC/C++ export is not in that internal set and remains surfaced, so a hand-written native export composes with wasm-bindgen's API in the same module.__wbindgen_describe*,__externref_*, ...) are stripped so they aren't reported as undefined exports.-sWASM_BINDGENwhen no driver suppliedEXPORTED_FUNCTIONS; the rustc-driven link already lists them exactly.library_bindgen.extern-pre.jsis fed as extern-pre-js and thesnippets/dir is copied next to the output so relative imports resolve.WASM_ESM_INTEGRATIONwrapper re-exports the JS library symbols that were exported (MODULARIZE=instance), and provideswasmExportsvia a namespace import of the wasm so by-name export access works.-sWASM_BINDGEN=auto(replacing #27179's implicit marker detection, per review feedback there): runs wasm-bindgen only when the linked wasm carries wasm-bindgen's__wasm_bindgen_emscripten_markercustom section — how cargo/rustc opts in when driving emcc as the linker. Otherwise it's a no-op and wasm-bindgen need not be installed, so rustc can always pass it via-Clink-argwithout affecting ordinary builds.Both output modes then expose only the clean API (e.g. a
Greeterclass).Testing:
-sWASM_ESM_INTEGRATION) and factory (-sMODULARIZE -sEXPORT_ES6) output modes, built viacargo buildwith-sWASM_BINDGEN=auto(marker auto-detected), asserting the cleanGreeterAPI works,mainruns on init, and none of the raw wasm exports leak.-sWASM_BINDGEN=autois a no-op for an ordinaryhello_world.cbuild (doesn't require wasm-bindgen installed).EMSCRIPTEN_KEEPALIVEnative export survives alongside the wasm-bindgen API (fails under a blanket export wipe).wasm-bindgen-clialongside rust so the flow is always exercised.Not in scope (follow-up): preserving human-supplied
EXPORTED_FUNCTIONSthrough wasm-bindgen linkage (the rustc-supplied set is currently indistinguishable from glue, so explicit exports aren't surfaced).