Description
We've historically focused on full support of existing C/C++ code by default, which leads to us emitting a bunch of things that increase the default JS code size, like
- longjmp and exceptions support (dynCall/invoke glue)
- atexit support
- Filesystem support
- Various POSIX things (like
/dev/random
). - Ability to run on the web, node.js, various js shells
- ccall, string stuff, etc. utilities for JS convenience
- etc.
As a result the JS emitted for "hello world" is not tiny.
In a medium or large project the compiled code is the large bulk anyhow and we have very good code size optimization there. But people do notice the JS size on small programs, and with wasm increasing the interest in compiling to the web, this has been coming up.
I've been thinking that dynamic linking might get us there, as we emit no JS for a standalone wasm dynamic library (SIDE_MODULE). However, dynamic libraries add relocation (unnecessary for many things) and we don't necessarily want 0 JS, we want "minimal" JS. So dynamic libraries are not the solution here.
Two other possible paths we could go down:
- Audit the current JS output and fix things one by one. That is, look at what we emit, and starting from the larger things, find out if we can't optimize it out or put it behind a flag, etc. To really make progress that way, we may need breaking changes, but e.g. putting longjmp support behind a flag could be ok as long as we issue a clear message for developers (
your program uses longjmp, you need to compile with -s LONGJMP_SUPPORT=1
). - Introduce a new codegen mode,
MINIMAL_JS
perhaps, which we would design from scratch to be minimal - we'd start from nothing and add just the things we want in that mode. It wouldn't support things like a filesystem or POSIX or atexit etc. (and we'd need to decide on exceptions and longjmp, asm.js or just wasm, etc.). We'd point people to the "normal" non-minimal JS for those things.
Thoughts?