Repository navigation
Conversation
__const JS library decorator and defineConsts helper__const JS library decorator and defineConsts helpers
guybedford
left a comment
There was a problem hiding this comment.
Nice cleanup. CMD_LOAD reads much better than {{{ CMD_LOAD }}}, and having named consts in -O0 output is a real win for debugging.
I checked this out locally. The pthread / wasm worker / dylink / embind / noderawsockets / jslib tests pass at O0, O2 and wasm64. EGL, OFFSCREENCANVASES_TO_PTHREAD and GL_POOL_TEMP_BUFFERS builds work for wasm32 and wasm64, with and without closure. With closure, the emitted cmd: values are identical to main.
I've left a few findings inline. I also have a broader question about the cDefs follow-up: if every constant needs a hand-written __deps entry, converting the hundreds of {{{ cDefs.X }}} uses means a lot of bookkeeping. A missing dep would also become a runtime ReferenceError in non-closure builds, where today it's a build error. Is the plan to add these deps automatically (e.g. by detecting referenced identifiers in library code), or to keep them as explicit __deps?
Made by AI under my review
| //dbg('msgData: ' + Object.keys(msgData)); | ||
| var cmd = msgData.cmd; | ||
| if (cmd == {{{ CMD_LOAD }}}) { // Preload command that is called once per worker to parse and load the Emscripten code. | ||
| if (cmd == CMD_LOAD) { // Preload command that is called once per worker to parse and load the Emscripten code. |
There was a problem hiding this comment.
Non-closure optimized builds don't get these inlined. The Terser reduce_vars pass from #27949 only inlines a const when its declaration comes before every use in the file, and runtime_pthread.js / runtime_common.js are emitted before the library block. So CMD_LOAD, CMD_LOADED, CMD_RUN, CMD_CHECK_MAILBOX, CMD_CALL_HANDLER and CMD_UNCAUGHT_EXN stay as references. The top-level declarations aren't dropped either, even for CMD_SPAWN_THREAD / CMD_CLEANUP_THREAD, which do get fully inlined.
Sizes for a simple pthread_create / pthread_join program, against this PR's base (bytes / gzip -9 bytes):
| base | this PR | |
|---|---|---|
-pthread -O2 |
21847 / 6733 | 22186 / 6857 |
-pthread -O2 -sMODULARIZE -sEXPORT_ES6 |
22225 / 6826 | 22560 / 6945 |
-pthread -sMAIN_MODULE=2 -O2 |
90465 / 25654 | 91008 / 25907 |
-pthread -O2 --closure=1 |
9460 / 4473 | 9418 / 4452 |
None of the codesize tests cover non-closure pthread builds, so the rebaseline doesn't catch this. Minimal Terser repro, using the same compress options as acorn-optimizer.mjs:
function g(x){return x!=A} const A=5; function f(x){return x!=A}
// output unchanged: neither use is inlinedThere was a problem hiding this comment.
Good catch.. maybe we can always emit all the const's first
|
Regarding the question about the followup. I decided to avoid the need for explicit deps and instead do conservative scanning in |
9cf5075 to
e74514c
Compare
0a03ec7 to
db9f02d
Compare
Previously, pthread and wasm worker message type constants (`CMD_LOAD`, etc., added in emscripten-core#26987) were defined as compile-time constants in `{{{ ... }}}` preprocessor blocks. This adds support for a `__const` JS library decorator (emitting `const` instead of `var` in `jsifier.mjs`) along with `defineConsts` and `defineInternalConsts` helpers, allowing constants to be normal JS library symbols that participate in `__deps` tracking while still being inlined and eliminated by Closure Compiler (`--closure=1`). Also update `autoAddDeps` in `libcore.js` to skip `__const` symbols so that constants defined in libraries using `autoAddDeps` (such as `libpthread.js`) do not gain circular dependencies on the library object itself. The advantage of doing things this way is twofold: 1. It allows better readability of library source code (`MY_CONST` vs `{{{ MY_CONST }}}`). 2. It allows for better readability / debug-ability of debug code since `const MY_CONST = 123;` shows up in the generated code (in debug builds).
kripken
left a comment
There was a problem hiding this comment.
lgtm % @guybedford 's open comments
Previously, pthread and wasm worker message type constants (
CMD_LOAD,etc., added in #26987) were defined as compile-time constants in
{{{ ... }}}preprocessor blocks.This adds support for a
__constJS library decorator (emittingconstinstead of
varinjsifier.mjs) along withdefineConstsanddefineInternalConstshelpers, allowing constants to be normal JSlibrary symbols that participate in
__depstracking while still beinginlined and eliminated by Closure Compiler (
--closure=1).Also update
autoAddDepsinlibcore.jsto skip__constsymbols sothat constants defined in libraries using
autoAddDeps(such aslibpthread.js) do not gain circular dependencies on the library objectitself.
The advantage of doing things this way is twofold:
MY_CONSTvs{{{ MY_CONST }}}).const MY_CONST = 123;shows up in the generated code (in debugbuilds).
As a followup I plan to make all cDefs available in this way. e.g. So you
can just write
EINVALinstead of{{{ cDefs.EINVAL }}}.