refactor: move embedded runtime JS to real .js files (js2c) - #1989
Open
edusperoni wants to merge 1 commit into
Open
refactor: move embedded runtime JS to real .js files (js2c)#1989edusperoni wants to merge 1 commit into
edusperoni wants to merge 1 commit into
Conversation
The runtime's internal JavaScript lived as C++ string literals across eight files, unlintable and invisible to tooling. It now lives in real .js files under test-app/runtime/src/main/cpp/js, embedded into a generated C++ table by tools/js2c.mjs at build time and executed through a new BuiltinLoader. Each file is compiled with v8::ScriptCompiler::CompileFunction as a function body with the fixed parameters `exports`, `module` and `binding` (Node's module wrapper plus its internalBinding idiom): natives arrive as properties of a binding bag built at the C++ call site, results come back through module.exports, and the script origin is internal/<name>.js so runtime frames stay identifiable in stack traces. Compilation goes through a process-wide bytecode cache guarded by a mutex, since worker runtimes initialize on their own threads. Extracted: weak-ref, message-loop-timer, smart-stringify, require-factory, json-helper, events, error-events and blob-url. Each extraction was verified AST-identical to the original literal by byte-comparing esbuild-minified output of both. tools/js2c.mjs is taken from the iOS runtime's feat/ns-util branch, which includes the later `unsigned char` fix for source bytes >= 0x80 (a narrowing error in a plain char array). Its --filelist drift check is adapted to --check-dir, comparing the explicit RUNTIME_BUILTIN_JS list in CMakeLists.txt against the directory contents so a new builtin cannot be silently skipped on incremental builds. Two behavioural notes: - JSONObjectHelper recompiled its JS->org.json serializer on every MetadataNode `from` registration. It is now compiled once per isolate and released via the isolate-dispose hook. - __messageLoopTimerStart/__messageLoopTimerStop are no longer installed on the global object. Nothing outside MessageLoopTimer referenced them, and the timer's start/stop pair now reaches its builtin through the binding bag. Mirrors NativeScript/ios#411.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 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.
Description
Android mirror of NativeScript/ios#411. Stacked on #1987 (
feat/v8-14) — review only the last commit.Moves the runtime JavaScript that was embedded as C++ string literals across eight files into real, version-controlled
.jsfiles undertest-app/runtime/src/main/cpp/js/, compiled into the runtime at build time (Node-style js2c).Extraction & build
tools/js2c.mjs(taken from the iOS runtime, including its laterunsigned charfix for source bytes ≥ 0x80) convertsjs/*.jsinto a generatedRuntimeBuiltins.{h,cpp}table — deterministic output, gitignored generated dir.add_custom_command(node is already a build requirement — the static-binding-generator shells out to it). TheRUNTIME_BUILTIN_JSlist is explicit;--check-dirfails the build loudly if it drifts from the directory contents. Incremental: a no-op rebuild skips codegen, touching a.jsreruns it.Extracted builtins:
weak-ref,message-loop-timer,smart-stringify,require-factory,json-helper,events,error-events,blob-url.Loader
ScriptCompiler::CompileFunctionwith the fixed parametersexports,moduleandbinding— natives arrive as properties of a bag object built by the C++ call site (Node's internalBinding idiom), and results come back throughmodule.exports.BuiltinLoader::RunBuiltincompiles with a properinternal/<name>.jsscript origin (runtime frames are identifiable in stack traces) and a process-wide bytecode cache: the first compile in the process useskEagerCompile+CreateCodeCacheForFunction, later isolates consume viakConsumeCodeCache(with rejected-cache fallback). The cache is mutex-guarded — worker runtimes initialize on their own threads.eslint.config.mjs) declaresexports,module,bindingand the reachable native globals;no-undefis the typo net. Conventions are documented intest-app/runtime/src/main/cpp/js/README.md.Behavior notes
internal/<name>.jsorigins instead of anonymous frames.JSONObjectHelperrecompiled its JS→org.jsonserializer on every registration; it is now compiled once per isolate and released via the isolate-dispose hook (the Android analog of the iOS PR's recompile-per-use perf fixes).__messageLoopTimerStart/__messageLoopTimerStopare no longer installed on the global object — nothing outsideMessageLoopTimerreferenced them; the builtin receives the pair throughbinding.Related Pull Requests
Does your pull request have unit tests?
Covered by the full existing device suite: 605 specs, 0 failures on an emulator (all extracted paths — events, error events, URL/Blob, WeakRef, module require, console stringify, workers — are exercised by existing specs; workers exercise the cross-isolate bytecode cache).