Final exports for wasm-merge?
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.
- https://github.com/WebAssembly/binaryen/wiki/Pruning-unneeded-code-in-wasm-files-with-wasm-metadce#example-pruning-exports
- 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).
cc @dschuff @tlively @bashor @biggs0125
- 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.