Conversation
Got a bit tired of opaque error messages coming from JS library processing when I accidentally introduce a syntax error, so here's a simple but effective improvement made possible by replacing `eval` with `vm.runScriptInContext`. I'm actually not sure why Node.js doesn't just use the same error output for eval as well, but at least this helps 🤷♂️ While at it, also added filenames to `load` functions used by compiler.js itself, so the stacktrace contains actual filenames instead of nested evals and did few other minor cleanups to avoid error message duplication. Example preprocessor error message before: ``` parseTools.js preprocessor error in shell_minimal.js:126: "#if MIN_CHROME_VERSION < 45 || MINEDGE_VERSION < 12 || MIN_FIREFOX_VERSION < 34 || MIN_IE_VERSION != TARGET_NOT_SUPPORTED || MIN_SAFARI_VERSION < 90000"! Internal compiler error in src/compiler.js! Please create a bug report at https://github.com/emscripten-core/emscripten/issues/ with a log of the build and the input files used to run. Exception message: "ReferenceError: MINEDGE_VERSION is not defined" | ReferenceError: MINEDGE_VERSION is not defined at eval (eval at preprocess (eval at load (C:\Users\me\Documents\emscripten\src\compiler.js:39:8)), <anonymous>:1:29) at preprocess (eval at load (C:\Users\me\Documents\emscripten\src\compiler.js:39:8), <anonymous>:97:32) at finalCombiner (eval at load (C:\Users\me\Documents\emscripten\src\compiler.js:39:8), <anonymous>:475:25) at runJSify (eval at load (C:\Users\me\Documents\emscripten\src\compiler.js:39:8), <anonymous>:543:3) ... ``` After: ``` Internal compiler error in src/compiler.js! Please create a bug report at https://github.com/emscripten-core/emscripten/issues/ with a log of the build and the input files used to run. Exception message: "shell_minimal.js:126 MIN_CHROME_VERSION < 45 || MINEDGE_VERSION < 12 || MIN_FIREFOX_VERSION < 34 || MIN_IE_VERSION != TARGET_NOT_SUPPORTED || MIN_SAFARI_VERSION < 90000 ^ ReferenceError: MINEDGE_VERSION is not defined at shell_minimal.js:126:32 at Script.runInThisContext (vm.js:134:12) at Object.runInThisContext (vm.js:310:38) at preprocess (C:\Users\me\Documents\emscripten\src\parseTools.js:96:33) at finalCombiner (C:\Users\me\Documents\emscripten\src\jsifier.js:475:25) at runJSify (C:\Users\me\Documents\emscripten\src\jsifier.js:543:3) ... ``` Example post-processed JS error message before: ``` error: failure to execute js library "library_pthread.js": error: use -sVERBOSE to see more details Internal compiler error in src/compiler.js! Please create a bug report at https://github.com/emscripten-core/emscripten/issues/ with a log of the build and the input files used to run. Exception message: "SyntaxError: Unexpected token 'function'" | SyntaxError: Unexpected token 'function' at Object.load (eval at load (C:\Users\me\Documents\emscripten\src\compiler.js:39:8), <anonymous>:215:14) at runJSify (eval at load (C:\Users\me\Documents\emscripten\src\compiler.js:39:8), <anonymous>:78:18) ... ``` After: ``` error: failure to execute js library "library_pthread.js": error: use -sVERBOSE to see more details Internal compiler error in src/compiler.js! Please create a bug report at https://github.com/emscripten-core/emscripten/issues/ with a log of the build and the input files used to run. Exception message: "library_pthread.preprocessed.js:330 $spawnThread function(threadParams) { ^^^^^^^^ SyntaxError: Unexpected token 'function' at new Script (vm.js:102:7) at createScript (vm.js:262:10) at Object.runInThisContext (vm.js:310:10) at Object.load (C:\Users\me\Documents\emscripten\src\modules.js:215:12) at runJSify (C:\Users\me\Documents\emscripten\src\jsifier.js:78:18) ... ```
9e0dade to
d72791f
Compare
sbc100
left a comment
There was a problem hiding this comment.
I love this! Thanks for working on it.
It does kind of seems like 3 seperate changes that all help make the error messages more clear:
- Improve
evalcalls by adding sourceURL - Use vm.runInThisContext rather than eval for library file
- Fairly major re-write of the pre-processor.
I wonder if you could maybe split this up. In particular (3) seems like a much larger change that could be better off being reviewed on it own. WDYT?
Hm, are you viewing with whitespace changes enabled by any chance? The big change is mostly indentation. |
Doh! Thanks for pointing that out. Let me look again. |
sbc100
left a comment
There was a problem hiding this comment.
lgtm!
I do wonder if we should have more test coverage here, but I won't block the landing of this change on that.
|
Huh, this is an interesting one. Looking... |
| */ | ||
|
|
||
| const FOUR_GB = 4 * 1024 * 1024 * 1024; | ||
| globalThis.FOUR_GB = 4 * 1024 * 1024 * 1024; |
There was a problem hiding this comment.
Perhaps we should look at why this change was needed? Presumably it means that some things that were previously available in preprocessor statements might no longer be? I wonder how many such cases there are?
There was a problem hiding this comment.
The only things that should / would become unavailable now are local variables in scope, since now I'm using the safer global eval, as every other place except the preprocessor, already used. All the settings and helper functions are already assigned to the global object so continue working as expected.
This file declared two "global" constants - FOUR_GB and FLOAT_TYPES - and, from my quick grep, only FOUR_GB is actualy used in libraries. It worked before because it happened to be in the same scope as eval, but instead, like other settings, it should be set on the global object to be consistently available everywhere else. Which is what I did here.
In theory it's possible that someone used local variables from preprocessor function too (e.g. i or line or filenameHint) but that would be extremely fragile and I really hope nobody did that...
At least the tests pass now, but with share-everything eval it used before, you can never be sure what external users relied on 🤷♂️ Mandatory https://xkcd.com/1172/ as always applies.
|
BTW, its great to see you back contributing to emscripten! Yours insights and improvements are most welcome. |
Thanks! I've recently started contracting and currently working on a project that allows (in fact, encourages) me to make improvements upstream where possible, so that certainly helps :) |
Got a bit tired of opaque error messages coming from JS library processing when I accidentally introduce a syntax error, so here's a simple but effective improvement made possible by replacing
evalwithvm.runScriptInContext.I'm actually not sure why Node.js doesn't just use the same error output for eval as well, but at least this helps 🤷♂️
While at it, also added filenames to
loadfunctions used by compiler.js itself, so the stacktrace contains actual filenames instead of nested evals and did few other minor cleanups to avoid error message duplication.Example post-processed JS error message before:
After:
Example preprocessor error message before:
After: