You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In projects that merge files, many of the exports in the intermediate files may be meant for the others they are merged with, and not for the final binary. Having a way to declare the "final/public" exports may be useful.
Some options here, from recent discussions:
The metadce tool can remove exports today, but it would be a separate invocation.
We could add a new wasm-merge flag, perhaps like wasm-merge --final-exports=WILDCARD. Specifying the list at link-time is similar to e.g. Emscripten's EXPORTED_FUNCTIONS, but it might be very long.
We could use custom annotations in the individual files ("X is a final/public export"), and have wasm-merge read and use those. Some questions we'd need to resolve:
We want to annotate exports, not functions - functions can have multiple exports, making this ambiguous otherwise. Custom annotations lacks that atm.
When are the annotations used and discarded? If wasm-merge does this automatically, it would prevent intermediate merges (which may be good for compile times).
We want to annotate exports, not functions - functions can have multiple exports, making this ambiguous otherwise. Custom annotations lacks that atm.
Annotations are allowed anywhere whitespace is allowed in the text format, so we are free to design these annotations however we wish. For example, something like this:
;; All exports are public
(@binaryen.public_export)
(func$f (export"foo1") (export"foo2") ...)
;; Only "foo1" is public
(func$f (@binaryen.public_export) (export"foo1") (export"foo2") (...)
;; "foo2" is public.
(@binaryen.public_export)
(export"foo2" (func$f))
(Similarly we can design the accompanying binary custom section however we want. There are many reasonable options there.)
When are the annotations used and discarded? If wasm-merge does this automatically, it would prevent intermediate merges (which may be good for compile times).
Having wasm-merge discard annotations by default but have a flag to preserve them seems simplest to me.
We could add a new wasm-merge flag, perhaps like wasm-merge --final-exports=WILDCARD. Specifying the list at link-time is similar to e.g. Emscripten's EXPORTED_FUNCTIONS, but it might be very long.
It would be simpler to use a pattern for internal declarations, as we have full control over their names, unlike users' exports.
We want to annotate exports, not functions - functions can have multiple exports, making this ambiguous otherwise. Custom annotations lacks that atm.
I think being able to annotate declarations (functions) would be enough in most cases.
The main benefit of such an annotation is the ability to remove declarations themselves.
If a declaration has both public and non-public exports, this solution will not allow you to mark and remove non-public exports during optimization; however, I believe it's solvable on the producer side.
On the other hand, the ability to annotate exports is more flexible and simpler to use for producers.
I think this is the issue we discussed with @biggs0125 and @aheejin yesterday, right?
Aside from these options, we also discussed name mangling as a way to designate final exports.
Among all those options, I sort of like the idea of annotating the input file, although it would be a weak preference.
We'd want to make sure there's a reasonable binary encoding, in addition to the text annotations. Presumably this would mean a custom section. I feel like we have recently discussed a generic way to tag functions (and other module-level entities?) with attributes for optimization, maybe this could fit into that kind of framework.
Among what I heard from the meeting, naming the internal exports in a special way (like, prefacing them with __) sounded the simplest to me. We can maybe make that a separate pass that we run after wasm-merge, namely, "RemoveExports", and make it take a string pattern with wildcards. The default can be something like __*. This way we don't need to come up with another format for annotations (both in the text format and the custom section).
Activity
tlively commentedon Oct 20, 2025
Annotations are allowed anywhere whitespace is allowed in the text format, so we are free to design these annotations however we wish. For example, something like this:
(Similarly we can design the accompanying binary custom section however we want. There are many reasonable options there.)
Having wasm-merge discard annotations by default but have a flag to preserve them seems simplest to me.
bashor commentedon Oct 27, 2025
It would be simpler to use a pattern for internal declarations, as we have full control over their names, unlike users' exports.
bashor commentedon Oct 27, 2025
I think being able to annotate declarations (functions) would be enough in most cases.
The main benefit of such an annotation is the ability to remove declarations themselves.
If a declaration has both public and non-public exports, this solution will not allow you to mark and remove non-public exports during optimization; however, I believe it's solvable on the producer side.
On the other hand, the ability to annotate exports is more flexible and simpler to use for producers.
dschuff commentedon Jan 7, 2026
I think this is the issue we discussed with @biggs0125 and @aheejin yesterday, right?
Aside from these options, we also discussed name mangling as a way to designate final exports.
Among all those options, I sort of like the idea of annotating the input file, although it would be a weak preference.
We'd want to make sure there's a reasonable binary encoding, in addition to the text annotations. Presumably this would mean a custom section. I feel like we have recently discussed a generic way to tag functions (and other module-level entities?) with attributes for optimization, maybe this could fit into that kind of framework.
aheejin commentedon Jan 8, 2026
Among what I heard from the meeting, naming the internal exports in a special way (like, prefacing them with
__) sounded the simplest to me. We can maybe make that a separate pass that we run after wasm-merge, namely, "RemoveExports", and make it take a string pattern with wildcards. The default can be something like__*. This way we don't need to come up with another format for annotations (both in the text format and the custom section).RemoveExports pass (#8670)
RemoveExports: Support comma separation and a response file (#8674)