Repository navigation
Conversation
9675b32 to
0a4cfff
Compare
|
This is really great work, and can simplify development a lot. One thing here is that we really need to think about forwards and backwards compatibility here. The behavior
makes it read like every codebase will gain a massive number of new warnings if this lands? That prompts the users to have to remove all the So that means that old Emscripten code will not compile without issuing tons of warnings (I'd argue emitting warnings is like a breakage here), and new code will not compile on old Emscripten versions without breaking. I.e. both directions break. Emscripten does not have good mechanisms for authors to write JS library code that would conditionally be able to target multiple Emscripten versions. So third-party/middleware vendors are in particularly bad situation (e.g. https://github.com/juj/wasm_webgpu) which cannot ship one lib_foo.js that would be able to target multiple Emscripten versions? Developers would have to fork their JS libraries to two before/after the new rule? Another concern here is the false positive rates. It is great to see that in the Emscripten repo, there are no code size regressions. But it's tricky to estimate that for all code. Could we do an opt-in setting first, and find a way to get forwards compatibility? |
- Skip scanning `PRE_JS_FILES`, `POST_JS_FILES`, and `EM_JS_SNIPPETS` in `--symbols-only` mode, and use `getIncludeFile` so preprocessed files are handled consistently. - Avoid mutating `LibraryManager.library[symbol]` when creating stub functions and remove the unused `original` variable. - Add `timer.start`/`timer.stop` around the `symbolHandler` loop. Split out from #27995
I actually already did this. User libraries now do not generated this working except it |
- In `src/lib/libcore.js`, check `t.includes('SYSCALLS.')` instead of
`t.includes('SYSCALLS')` in `wrapSyscallFunction` so comments and
strings mentioning `SYSCALLS_REQUIRE_FILESYSTEM` (such as in
`fd_write`) do not pull in `$SYSCALLS` and `$UTF8ToString` when
`SYSCALLS_REQUIRE_FILESYSTEM=0`.
- In `src/lib/libpthread.js`, guard `'$addOnPreRun'` in `$PThread__deps`
with `#if !MINIMAL_RUNTIME && PTHREAD_POOL_SIZE`.
- Guard or remove other unused and overly-broad `__deps` entries across
`src/lib/*.js` (`libasync.js`, `libbrowser.js`, `libdylink.js`,
`libemval.js`, `libfetch.js`, `libfs.js`, `libglemu.js`, `libglew.js`,
`libglut.js`, `libhtml5.js`, `libnoderawfs.js`, `libsdl.js`,
`libsockfs_node.js`, `libwasmfs.js`, `libwebgl.js`, `libwebgl2.js`).
Split out from emscripten-core#27995
3f60d55 to
64c9f6c
Compare
- In `src/lib/libcore.js`, check `t.includes('SYSCALLS.')` instead of
`t.includes('SYSCALLS')` in `wrapSyscallFunction` so comments and
strings mentioning `SYSCALLS_REQUIRE_FILESYSTEM` (such as in
`fd_write`) do not pull in `$SYSCALLS` and `$UTF8ToString` when
`SYSCALLS_REQUIRE_FILESYSTEM=0`.
- In `src/lib/libpthread.js`, guard `'$addOnPreRun'` in `$PThread__deps`
with `#if !MINIMAL_RUNTIME && PTHREAD_POOL_SIZE`.
- Guard or remove other unused and overly-broad `__deps` entries across
`src/lib/*.js` (`libasync.js`, `libbrowser.js`, `libdylink.js`,
`libemval.js`, `libfetch.js`, `libfs.js`, `libglemu.js`, `libglew.js`,
`libglut.js`, `libhtml5.js`, `libnoderawfs.js`, `libsdl.js`,
`libsockfs_node.js`, `libwasmfs.js`, `libwebgl.js`, `libwebgl2.js`).
Split out from emscripten-core#27995
- In `src/lib/libcore.js`, check `t.includes('SYSCALLS.')` instead of
`t.includes('SYSCALLS')` in `wrapSyscallFunction` so comments and
strings mentioning `SYSCALLS_REQUIRE_FILESYSTEM` (such as in
`fd_write`) do not pull in `$SYSCALLS` and `$UTF8ToString` when
`SYSCALLS_REQUIRE_FILESYSTEM=0`.
- In `src/lib/libpthread.js`, guard `'$addOnPreRun'` in `$PThread__deps`
with `#if !MINIMAL_RUNTIME && PTHREAD_POOL_SIZE`.
- Guard or remove other unused and overly-broad `__deps` entries across
`src/lib/*.js` (`libasync.js`, `libbrowser.js`, `libdylink.js`,
`libemval.js`, `libfetch.js`, `libfs.js`, `libglemu.js`, `libglew.js`,
`libglut.js`, `libhtml5.js`, `libnoderawfs.js`, `libsdl.js`,
`libsockfs_node.js`, `libwasmfs.js`, `libwebgl.js`, `libwebgl2.js`).
Split out from emscripten-core#27995
- In `src/lib/libcore.js`, check `t.includes('SYSCALLS.')` instead of
`t.includes('SYSCALLS')` in `wrapSyscallFunction` so comments and
strings mentioning `SYSCALLS_REQUIRE_FILESYSTEM` (such as in
`fd_write`) do not pull in `$SYSCALLS` and `$UTF8ToString` when
`SYSCALLS_REQUIRE_FILESYSTEM=0`.
- In `src/lib/libpthread.js`, guard `'$addOnPreRun'` in `$PThread__deps`
with `#if !MINIMAL_RUNTIME && PTHREAD_POOL_SIZE`.
- Guard or remove other unused and overly-broad `__deps` entries across
`src/lib/*.js` (`libasync.js`, `libbrowser.js`, `libdylink.js`,
`libemval.js`, `libfetch.js`, `libfs.js`, `libglemu.js`, `libglew.js`,
`libglut.js`, `libhtml5.js`, `libnoderawfs.js`, `libsdl.js`,
`libsockfs_node.js`, `libwasmfs.js`, `libwebgl.js`, `libwebgl2.js`).
Split out from emscripten-core#27995
- In `src/lib/libcore.js`, check `t.includes('SYSCALLS.')` instead of
`t.includes('SYSCALLS')` in `wrapSyscallFunction` so comments and
strings mentioning `SYSCALLS_REQUIRE_FILESYSTEM` (such as in
`fd_write`) do not pull in `$SYSCALLS` and `$UTF8ToString` when
`SYSCALLS_REQUIRE_FILESYSTEM=0`.
- In `src/lib/libpthread.js`, guard `'$addOnPreRun'` in `$PThread__deps`
with `#if !MINIMAL_RUNTIME && PTHREAD_POOL_SIZE`.
- Guard or remove other unused and overly-broad `__deps` entries across
`src/lib/*.js` (`libasync.js`, `libbrowser.js`, `libdylink.js`,
`libemval.js`, `libfetch.js`, `libfs.js`, `libglew.js`,
`libglut.js`, `libhtml5.js`, `libnoderawfs.js`, `libsdl.js`,
`libsockfs_node.js`, `libwasmfs.js`, `libwebgl.js`, `libwebgl2.js`).
Split out from emscripten-core#27995
- In `src/lib/libcore.js`, check `t.includes('SYSCALLS.')` instead of
`t.includes('SYSCALLS')` in `wrapSyscallFunction` so comments and
strings mentioning `SYSCALLS_REQUIRE_FILESYSTEM` (such as in
`fd_write`) do not pull in `$SYSCALLS` and `$UTF8ToString` when
`SYSCALLS_REQUIRE_FILESYSTEM=0`.
- In `src/lib/libpthread.js`, guard `'$addOnPreRun'` in `$PThread__deps`
with `#if !MINIMAL_RUNTIME && PTHREAD_POOL_SIZE`.
- Guard or remove other unused and overly-broad `__deps` entries across
`src/lib/*.js` (`libasync.js`, `libbrowser.js`, `libdylink.js`,
`libemval.js`, `libfetch.js`, `libfs.js`, `libglew.js`,
`libglut.js`, `libhtml5.js`, `libnoderawfs.js`, `libsdl.js`,
`libsockfs_node.js`, `libwasmfs.js`, `libwebgl.js`, `libwebgl2.js`).
Split out from emscripten-core#27995
- In `src/lib/libcore.js`, check `t.includes('SYSCALLS.')` instead of
`t.includes('SYSCALLS')` in `wrapSyscallFunction` so comments and
strings mentioning `SYSCALLS_REQUIRE_FILESYSTEM` (such as in
`fd_write`) do not pull in `$SYSCALLS` and `$UTF8ToString` when
`SYSCALLS_REQUIRE_FILESYSTEM=0`.
- In `src/lib/libpthread.js`, guard `'$addOnPreRun'` in `$PThread__deps`
with `#if !MINIMAL_RUNTIME && PTHREAD_POOL_SIZE`.
- Guard or remove other unused and overly-broad `__deps` entries across
`src/lib/*.js` (`libasync.js`, `libbrowser.js`, `libdylink.js`,
`libemval.js`, `libfetch.js`, `libfs.js`, `libglew.js`,
`libglut.js`, `libhtml5.js`, `libnoderawfs.js`, `libsdl.js`,
`libsockfs_node.js`, `libwasmfs.js`, `libwebgl.js`, `libwebgl2.js`).
Split out from emscripten-core#27995
- In `src/lib/libcore.js`, check `t.includes('SYSCALLS.')` instead of
`t.includes('SYSCALLS')` in `wrapSyscallFunction` so comments and
strings mentioning `SYSCALLS_REQUIRE_FILESYSTEM` (such as in
`fd_write`) do not pull in `$SYSCALLS` and `$UTF8ToString` when
`SYSCALLS_REQUIRE_FILESYSTEM=0`.
- In `src/lib/libpthread.js`, guard `'$addOnPreRun'` in `$PThread__deps`
with `#if !MINIMAL_RUNTIME && PTHREAD_POOL_SIZE`.
- Guard or remove other unused and overly-broad `__deps` entries across
`src/lib/*.js` (`libasync.js`, `libbrowser.js`, `libdylink.js`,
`libemval.js`, `libfetch.js`, `libfs.js`, `libglew.js`,
`libglut.js`, `libhtml5.js`, `libnoderawfs.js`, `libsdl.js`,
`libsockfs_node.js`, `libwasmfs.js`, `libwebgl.js`, `libwebgl2.js`).
Split out from emscripten-core#27995
- In `src/lib/libpthread.js`, guard `'$addOnPreRun'` in `$PThread__deps` with `#if !MINIMAL_RUNTIME && PTHREAD_POOL_SIZE`. - Guard or remove other unused and overly-broad `__deps` entries across `src/lib/*.js` (`libasync.js`, `libbrowser.js`, `libdylink.js`, `libemval.js`, `libfetch.js`, `libfs.js`, `libglew.js`, `libglut.js`, `libhtml5.js`, `libnoderawfs.js`, `libsdl.js`, `libsockfs_node.js`, `libwasmfs.js`, `libwebgl.js`, `libwebgl2.js`). Split out from emscripten-core#27995
When a JS library alias target (e.g. `foo`) is visited first and transitively depends on its own alias (e.g. `foo_alias: 'foo'`), `addedLibraryItems['foo']` is marked as visited before `var _foo = ...` is emitted. Emitting `var _foo_alias = _foo;` inline during dependency traversal causes it to appear before `var _foo = ...`, leaving `_foo_alias` initialized to `undefined` for arrow functions and non-hoisted values. Collect JS library alias assignments in `libraryAliases` and emit them after `libraryItems` (and before `postSets`) so all target symbols are defined before any alias assignment runs. Split out from #27995 where this issue was first spotted.
- In `src/lib/libpthread.js`, guard `'$addOnPreRun'` in `$PThread__deps` with `#if !MINIMAL_RUNTIME && PTHREAD_POOL_SIZE`. - Guard or remove other unused and overly-broad `__deps` entries across `src/lib/*.js` (`libasync.js`, `libbrowser.js`, `libdylink.js`, `libemval.js`, `libfetch.js`, `libfs.js`, `libglew.js`, `libglut.js`, `libhtml5.js`, `libnoderawfs.js`, `libsdl.js`, `libsockfs_node.js`, `libwasmfs.js`, `libwebgl.js`, `libwebgl2.js`). Split out from emscripten-core#27995
- In `src/lib/libpthread.js`, guard `'$addOnPreRun'` in `$PThread__deps` with `#if !MINIMAL_RUNTIME && PTHREAD_POOL_SIZE`. - Guard or remove other unused and overly-broad `__deps` entries across `src/lib/*.js` (`libasync.js`, `libbrowser.js`, `libdylink.js`, `libemval.js`, `libfetch.js`, `libfs.js`, `libglew.js`, `libglut.js`, `libhtml5.js`, `libnoderawfs.js`, `libsdl.js`, `libsockfs_node.js`, `libwasmfs.js`). Split out from emscripten-core#27995
…7999) - In `src/lib/libcore.js`, check `t.includes('SYSCALLS.')` instead of `t.includes('SYSCALLS')` in `wrapSyscallFunction` so comments and strings mentioning `SYSCALLS_REQUIRE_FILESYSTEM` (such as in `fd_write`) do not pull in `$SYSCALLS` and `$UTF8ToString` when `SYSCALLS_REQUIRE_FILESYSTEM=0`. - In `src/lib/libpthread.js`, guard `'$addOnPreRun'` in `$PThread__deps` with `#if !MINIMAL_RUNTIME && PTHREAD_POOL_SIZE`. - Guard or remove other unused and overly-broad `__deps` entries across `src/lib/*.js` (`libasync.js`, `libbrowser.js`, `libdylink.js`, `libemval.js`, `libfetch.js`, `libfs.js`, `libglemu.js`, `libglew.js`, `libglut.js`, `libhtml5.js`, `libnoderawfs.js`, `libsdl.js`, `libsockfs_node.js`, `libwasmfs.js`, `libwebgl.js`, `libwebgl2.js`). Split out from #27995
|
I think this change is ready to go now. We did an emscripten release prior, and all remaining codesize changes are purely the result of the order in which deps are found. |
|
CC @kainino0x who also maintains out-of-tree JS library code. |
|
That's very nice. We won't drop our deps yet because I have no idea how old versions of Emscripten people are using, but nice that we can (and also it might fix some latent missing deps bugs for us :) ) |
4582b86 to
17dba40
Compare
…ols-only` mode. NFC Previously, `getTransitiveDeps` was called inside `addFromLibrary` while `symbolHandler` was still iterating through `symbolsNeeded` and mutating `__deps` (such as adding `setTempRet0` for i64-returning functions without `WASM_BIGINT`). Compute `symbolDeps` in the `if (symbolsOnly)` block after `symbolHandler` completes so that all direct `__deps` are populated before traversing the dependency graph. Split out from emscripten-core#27995.
| $createContext: 'Browser.createContext', | ||
|
|
||
| emscripten_run_preload_plugins__deps: ['$PATH'], | ||
| emscripten_run_preload_plugins__deps: ['$Browser'], |
There was a problem hiding this comment.
All function ins this file used to depend on $Browser due to the audoAddDeps at the end (that this PR removes).
The reason emscripten_run_preload_plugins need to keep this indirect dependency is because the Browser.init function is what registers the preloadPlugins. See preloadPlugins.push(imagePlugin); for example above.
…ols-only` mode. NFC (#28052) Previously, `getTransitiveDeps` was called inside `addFromLibrary` while `symbolHandler` was still iterating through `symbolsNeeded` and mutating `__deps` (such as adding `setTempRet0` for i64-returning functions without `WASM_BIGINT`). Compute `symbolDeps` in the `if (symbolsOnly)` block after `symbolHandler` completes so that all direct `__deps` are populated before traversing the dependency graph. Split out from #27995.
Add missing direct `__deps` declarations for JS library symbols that previously relied on other callers pulling in their dependencies later in the dependency graph. With `__ps` sorted alphabetically (emscripten-core#28059), adding these missing direct edges ensures that automatically computing JS-to-JS dependencies (emscripten-core#27995) produces identical declaration ordering and zero diffs across `test/codesize/`. See: emscripten-core#19098
Add missing direct `__deps` declarations for JS library symbols that previously relied on other callers pulling in their dependencies later in the dependency graph. With `__ps` sorted alphabetically (emscripten-core#28059), adding these missing direct edges ensures that automatically computing JS-to-JS dependencies (emscripten-core#27995) produces identical declaration ordering and zero diffs across `test/codesize/`. See: emscripten-core#19098
|
This change is now made up of 4 commits. The first two are uploaded as separate PRs:
The reason I'm landing (1) and (2) first (or at least uploading them here) is so that we can show that (4) is no-op. No codesize tests changes with (4). |
Add missing direct `__deps` declarations for JS library symbols that previously relied on other callers pulling in their dependencies later in the dependency graph. With `__ps` sorted alphabetically (emscripten-core#28059), adding these missing direct edges ensures that automatically computing JS-to-JS dependencies (emscripten-core#27995) produces identical declaration ordering and zero diffs across `test/codesize/`. See: emscripten-core#19098
Add missing direct `__deps` declarations for JS library symbols that previously relied on other callers pulling in their dependencies later in the dependency graph. With `__ps` sorted alphabetically (emscripten-core#28059), adding these missing direct edges ensures that automatically computing JS-to-JS dependencies (emscripten-core#27995) produces identical declaration ordering and zero diffs across `test/codesize/`. See: emscripten-core#19098
Add missing direct `__deps` declarations for JS library symbols that previously relied on other callers pulling in their dependencies later in the dependency graph. With `__ps` sorted alphabetically (emscripten-core#28059), adding these missing direct edges ensures that automatically computing JS-to-JS dependencies (emscripten-core#27995) produces identical declaration ordering and zero diffs across `test/codesize/`. See: emscripten-core#19098
Add missing direct `__deps` declarations for JS library symbols that previously relied on other callers pulling in their dependencies later in the dependency graph. With `__deps` sorted alphabetically (#28059), adding these missing direct edges ensures that automatically computing JS-to-JS dependencies (#27995) produces identical declaration ordering and zero diffs across `test/codesize/`. See: #19098
Replace `addImplicitDeps` and `checkDependencies` in `src/jsifier.mjs` with `calculateDeps`, which uses `acorn.tokenizer` to automatically detect references to JS library symbols (`$foo` and `_bar`). Because `calculateDeps` uses a flat token scan rather than a full AST and scope analysis pass (both for speed and to support partial JS fragments in `--pre-js`/`--post-js`), this scanning is conservative and can include false positives if local variables or parameters shadow a library symbol name. Keep the `__deps` mechanism in place for dependencies that static JS token scanning cannot detect (such as native Wasm/C symbols, function callbacks in `__deps`, side-effect-only dependencies, and `__postset` dependencies). Also log auto-detected dependencies in debug/verbose mode (`-sVERBOSE`). Performance cost (median of 15 runs on `test/hello_world.c`): - `tools/compiler.mjs` (`INCLUDE_FULL_LIBRARY=0`): 178.8 ms -> 185.1 ms (+6.3 ms, +3.5% slower) - `tools/compiler.mjs` (`INCLUDE_FULL_LIBRARY=1`): 268.2 ms -> 343.1 ms (+74.9 ms, +27.9% slower) - `tools/compiler.mjs --symbols-only`: 181.4 ms -> 254.2 ms (+72.8 ms, +40.1% slower) - Full `emcc` link (`hello.o` -> `out.js`, cold JS cache): - `INCLUDE_FULL_LIBRARY=0`: 661.7 ms -> 740.8 ms (+79.1 ms, +12.0%) - `INCLUDE_FULL_LIBRARY=1`: 758.3 ms -> 906.0 ms (+147.7 ms, +19.5%) - Full `emcc` link (`hello.o` -> `out.js`, warm JS cache): - `INCLUDE_FULL_LIBRARY=0`: 271.8 ms (+0.0 ms, 0% slower) - `INCLUDE_FULL_LIBRARY=1`: 282.4 ms (+0.0 ms, 0% slower) See: emscripten-core#19098
…ibraries Remove all `autoAddDeps` calls and redundant `__deps` entries across `src/lib/*.js` and the test suite. Fixes: emscripten-core#19098
Replace
addImplicitDepsandcheckDependenciesinsrc/jsifier.mjswithcalculateDeps, which usesacorn.tokenizerto automatically detect references to JS library symbols ($fooand_bar).Keep the
__depsmechanism in place for dependencies that static JS token scanning cannot detect (such as native Wasm/C symbols, function callbacks in__deps, side-effect-only dependencies, and__postsetdependencies).For system libraries we emit a warning when a
__depsentry is redundant with an auto-detected dependency. For user JS libraries we only show this warning in-sSTRICTmode.Performance cost (median of 15 runs on
test/hello_world.c):tools/compiler.mjs(INCLUDE_FULL_LIBRARY=0): 178.8 ms -> 185.1 ms (+6.3 ms, +3.5% slower)tools/compiler.mjs(INCLUDE_FULL_LIBRARY=1): 268.2 ms -> 343.1 ms (+74.9 ms, +27.9% slower)tools/compiler.mjs --symbols-only: 181.4 ms -> 254.2 ms (+72.8 ms, +40.1% slower)emcclink (hello.o->out.js, cold JS cache):INCLUDE_FULL_LIBRARY=0: 661.7 ms -> 740.8 ms (+79.1 ms, +12.0%)INCLUDE_FULL_LIBRARY=1: 758.3 ms -> 906.0 ms (+147.7 ms, +19.5%)emcclink (hello.o->out.js, warm JS cache):INCLUDE_FULL_LIBRARY=0: 271.8 ms (+0.0 ms, 0% slower)INCLUDE_FULL_LIBRARY=1: 282.4 ms (+0.0 ms, 0% slower)Because I'm landing a few cleanup first (#27999, #28059, #28060) there are zero codesize changes acossiated with this PR.
Fixes: #19098