Skip to content

Support JS libraries self-registering their exports via EXPORTED_FUNCTIONS - #27436

Open
guybedford wants to merge 2 commits into
emscripten-core:mainfrom
guybedford:jslib-exported-functions
Open

Support JS libraries self-registering their exports via EXPORTED_FUNCTIONS#27436
guybedford wants to merge 2 commits into
emscripten-core:mainfrom
guybedford:jslib-exported-functions

Conversation

@guybedford

Copy link
Copy Markdown
Collaborator

This implements support for JS libraries adding their own symbols to EXPORTED_FUNCTIONS at library load time, split out from #27208 as requested in review there.

JS library code can already mutate the compile-time EXPORTED_FUNCTIONS set (it is exposed to library code as a Set), which under MODULARIZE=instance causes jsifier to emit the symbol with an export declaration. What was missing is the linker knowing about those additions:

  • The final EXPORTED_FUNCTIONS set is now forwarded back from the JS compiler in FORWARDED_DATA, so the linker can derive which JS library symbols were exported.
  • The WASM_ESM_INTEGRATION wrapper re-exports those symbols from the support module.

This is a requirement for wasm-bindgen's binding layers that define a public JS API surface distinct from the wasm export names (e.g. exported JS classes and namespaces), registering it from their generated JS library:

EXPORTED_FUNCTIONS.add('Counter');
addToLibrary({ $Counter: class Counter { /* ... */ } });

Test coverage is included in test_jslib.py for both MODULARIZE=instance and WASM_ESM_INTEGRATION output modes, where the WASM_ESM_INTEGRATION variant fails without this change.

Made with AI assistance under my review

…TIONS

JS library code can already mutate the compile-time EXPORTED_FUNCTIONS set
at library load time, which under MODULARIZE=instance causes jsifier to emit
the symbol with an `export` declaration. This makes that flow fully work by
forwarding the final EXPORTED_FUNCTIONS set back from the JS compiler so the
linker can derive which JS library symbols were exported, and have the
WASM_ESM_INTEGRATION wrapper re-export them.

This is used by binding layers (e.g. wasm-bindgen) that define a public JS
API surface distinct from the wasm export names, registering it from their
generated JS library.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant