refactor: move embedded runtime JS to real .js files (js2c) + enum eval caching#411
Draft
edusperoni wants to merge 2 commits into
Draft
refactor: move embedded runtime JS to real .js files (js2c) + enum eval caching#411edusperoni wants to merge 2 commits into
edusperoni wants to merge 2 commits into
Conversation
…js2c The ~26KB of JavaScript previously embedded as C++ string literals now lives in NativeScript/runtime/js/*.js. A "Generate RuntimeBuiltins" build phase runs tools/js2c.mjs to emit a generated source table, and call sites go through BuiltinLoader::RunBuiltin, which sets proper internal/<name>.js script origins and shares an in-process bytecode cache across isolates so workers stop re-parsing the builtins. The placeholder-module proxy is now a static builtin parameterized with the error message. The legacy inline proxy source never compiled (the spliced message's quotes made it a guaranteed SyntaxError), so the first require() of a missing optional module always threw via the leaked pending exception; CreatePlaceholderModule now throws an explicit "Cannot find module" error to keep that contract.
Interop::WriteValue recompiled and re-ran an enum wrapper's __tsEnum snippet on every FFI marshal; the value is now memoized on the EnumDataWrapper. GlobalPropertyGetter did the same on every read of a JsCode global; the evaluated result is now defined as a real own property on the global (the interceptor is kNonMasking, so later reads bypass it entirely), with a reentrancy guard because CreateDataProperty re-enters the interceptor before the property exists.
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Moves the ~26KB of JavaScript that was embedded as C++ string literals into real, version-controlled
.jsfiles underNativeScript/runtime/js/, compiled into the framework at build time (Node-style js2c), and adds two steady-state perf fixes for jitless mode.Stacked on #409; draft until that lands.
Extraction & build
tools/js2c.mjs(Node CLI) convertsruntime/js/*.jsinto a generatedRuntimeBuiltins.{h,cpp}table (byte arrays, deterministic output). Supports--minifyvia esbuild (whitespace+syntax only) — implemented but not enabled in any configuration.NativeScript/runtime/generated/is gitignored.Loader
BuiltinLoader::RunBuiltinis the single compile-and-run path: properinternal/<name>.jsscript origins (runtime frames are now identifiable in stack traces) and a process-wide bytecode cache — first isolate compiles withkEagerCompile, workers/subsequent isolates consume viakConsumeCodeCache(with rejected-cache fallback), so the ~26KB is parsed once per process instead of once per isolate.placeholder-module.js) parameterized with the error message instead of splicing it into source text.Perf (jitless steady-state)
Interop::WriteValueno longer recompiles + re-runs an enum's__tsEnumsnippet on every FFI marshal — the numeric value is memoized onEnumDataWrapper.GlobalPropertyGetterno longer recompiles a JsCode global's snippet on every read — the evaluated result is defined as a real own property on the global (interceptor iskNonMasking, so later reads bypass it entirely). Includes a reentrancy guard:CreateDataPropertyre-enters the interceptor before the property exists.Behavior notes
require()of a missing optional module always threw via the leaked pending exception (which the shared require tests rely on).CreatePlaceholderModulenow keeps that contract explicitly with a properError: Cannot find module '<name>'; repeat requires still get the cached placeholder, whose exports now actually throw on access as originally designed.internal/<name>.jsorigins instead of anonymous<eval>frames.Testing
.jsinput is touched.