Skip to content

Latest commit

 

History

History
73 lines (63 loc) · 24.2 KB

File metadata and controls

73 lines (63 loc) · 24.2 KB

V8 → NAPI runtime migration ledger

Tracks the port of substantive commits from the old V8-based runtime (nativescript/android-runtime, branch master) into this NAPI-based runtime, starting at 2bab8f5 (fix(URL): allow undefined 2nd args, #1826) through the old runtime's HEAD (129 commits total).

Plan: ~/.claude/plans/we-want-to-migrate-modular-prism.md

Status: the full range 2bab8f5..HEAD has been triaged. ~60 build(deps)/CI/chore/release commits are out of scope (fork tooling). Of the substantive commits: 23 ported/partial (all native/Java build-verified), several already-present, and the rest deferred with rationale (each deferred row says why + what's needed to complete it). Deferred clusters: ESM (052cb21 + its dependents 7782720f/288491f/5ceb3d4/92c2654/45ed1f6), timers (bfd7650), URLSearchParams spec (89893ae), workers→C++ (a84d3c7), inspector (55da2da/4b5ab0a), NDK r27d (0387a8d). The @CriticalNative pair (085bc4f+3c956cf) and DexFactory pair (c9d41e6+fce8e29) are now ported (compile-verified; they carry device/version/release-only runtime risk — validate on real devices). Verification here is compile/link + config-eval; on-device behavior is noted per-row where relevant.

Disposition: ported · already-present · partial · skipped · deferred

# old hash subject disposition new commit notes
1 2bab8f5 fix(URL): allow undefined 2nd args (#1826) ported ef20f1d URL::New (modules/url/URL.cpp): gate base-URL branch on argv[1] not being undefined/null via napi_util::is_of_type; ported expanded testURLImpl.js verbatim (JS is engine-agnostic). Verified: native recompile (V8-13, all ABIs) exit 0.
2 94ddb15 fix: exit(0) causes ANR due to destroyed mutex (#1820) ported b46586b Old fix was in MetadataNode::BuildMetadata; in napi runtime that error path moved to MetadataBuilder.cpp:55 (identical direct-boot/locked-screen comment). Changed exit(0)_Exit(0). Verified: native recompile exit 0.
f290ed2 perf: optimizations around generating JS classes from Metadata (#1824) already-present Large metadata-subsystem perf refactor (13 files). Confirmed by user: already implemented in the napi runtime's rewritten metadata code. Skipped.
3 a983931 fix: gradle error when compileSdk or targetSdk is provided (#1825) ported 6f01665 test-app/app/build.gradle: add as int cast to provided compileSdk/targetSdk in computeCompileSdkVersion/computeTargetSdkVersion (props arrive as String from -P). Verified: :app:help -PcompileSdk=35 -PtargetSdk=35 config eval exit 0.
e293636 fix: inner type not set when companion object defined as function (#1831) already-present New MetadataNode::SetInnerTypes (metadata/MetadataNode.cpp:1726-1733) already has the napi_has_own_property + if(!hasOwnProperty) guard before defining the inner-type accessor — napi port of the same fix. Skipped.
5 b31fc5f + 3633aed + 83f611b + 3513ce7 + 45fb275 Ada v3 + URLPattern (#1830), Ada 3.1.1/3.1.3/3.2.7/3.3.0 (#1832/#1835/#1884) ported this commit Consolidated the whole Ada v3 chain (Ada is a vendored single-file lib, so intermediate bumps collapse to the final): replaced modules/url/ada/ada.{h,cpp} 2.9.0→3.3.0 (verified no API breaks in URL/URLSearchParams). Ported URLPattern V8→napi: new modules/url/URLPattern.{cpp,h} with a napi_regex_provider (RegExp via global ctor + .exec, move-only NapiRegex ref wrapper, thread-local env for create_instance); wired URLPattern::Init into NSRuntimeModules. Registered spec-correct hasRegExpGroups (old C++ had typo hasRegexpGroups). Ported testURLPattern.js + registered in mainpage.js. Skipped the commit's gradle/CMake/Runtime-V8 bits (superseded / engine-specific). Verified: native build all ABIs exit 0.
6 bec401c feat: NDK 27 and Support for Java 21 (#1819) partial this commit Ported (Java-21 source compat): NanoWSD.java byte casts (`header
c9a2a86 feat: update Gradle 8.14.3 and Android build tools 8.12.1 (#1834) already-present Fork already on gradle wrapper 8.14.3 and NS_DEFAULT_ANDROID_BUILD_TOOLS_VERSION=8.12.1. Skipped.
e98367c feat: performance api (#1838) already-present runtime/performance/Performance.h registers global.performance/performance.now() (installed at Runtime.cpp:313). Skipped.
7 87f7f9c feat: update libzip to 1.11.4 (#1845) ported this commit Vendored binary dep. Replaced cpp/zip/include/{zip.h,zipconf.h} and the 4 prebuilt libs/common/<abi>/libzip.a with upstream 1.11.4 (fork's zipconf was mislabeled "0.11"). Sole consumer AssetExtractor.cpp uses only stable API (zip_open/fread/stat_index/…). Verified: native compile+link all ABIs exit 0. Caveat: binary swap verified to link only — on-device asset extraction should be smoke-tested.
0387a8d feat: update NDK to latest LTS (r27d) (#1846) deferred Portable change is defaultNdkVersion 27.1.12297006 → 27.3.13750724 in runtime/build.gradle. Deferred: r27d is NOT installed in this env (only 27.0–27.2), and AGP's ndkVersion defaultNdkVersion would fail the build (blocking verification of later commits). Action for user: sdkmanager "ndk;27.3.13750724", then bump defaultNdkVersion. CI/package.json NDK bumps skipped (fork-specific/superseded).
8 78589fd feat: kotlin 2.2.x support (#1848) ported this commit gradle.properties: ns_default_kotlin_version + ns_default_kotlinx_metadata_jvm_version 2.0.0 → 2.2.20. KotlinClassDescriptor.kt: kotlinx-metadata 2.2.x renamed the API — metaClass.enumEntriesmetaClass.kmEnumEntries.map { it.name } (getEnumEntriesAsFields already takes Collection<String>). Verified: metadata-generator compileKotlin under 2.2.20 exit 0 + :app:buildMetadata runs the generator successfully.
9 f033061 feat: queueMicrotask support (#1868) ported this commit Registered global queueMicrotask in Runtime::Init (after Performance). The V8 original used isolate->EnqueueMicrotask; napi has no equivalent, so implemented engine-agnostically via Promise.resolve().then(cb) — preserves microtask ordering with promises (['qm1','p','qm2'] case) and runs before timers. Validates the arg is a function (TypeError otherwise). Ported testQueueMicrotask.js + mainpage.js. Verified: native compile exit 0. Caveat: ordering/timing asserts not run on-device here.
052cb21 feat: ES modules (ESM) support (#1836) deferred Large (26 files). Analyzed in depth. Upstream ESM is 100% V8-native (v8::Module, ScriptCompiler::CompileModule, InstantiateModule, Evaluate, GetModuleNamespace, isolate SetHostInitializeImportMetaObjectCallback / SetHostImportModuleDynamicallyCallback; ~650-line ModuleInternalCallbacks.cpp). No napi ESM API exists, so options are: (a) V8-only native via the napi↔v8 bridge (works only on V8 engine); (b) engine-agnostic load-time ESM→CJS transpilation (recommended if pursued: es-module-lexer + source rewrite + import.meta/dynamic-import polyfills through existing CommonJS path; live-binding snapshot caveat). Portable non-native parts (all engines): Module.java .mjs resolution (.js→.mjs order, index.mjs), AppConfig.logScriptLoading + Runtime.getLogScriptLoadingEnabled, SBG generateUniqueFileIdentifier (MD5, collision-safe for .mjs) + isJsFile .mjs, jsparser sourceType:'module' for .mjs. Deferred by user pending design decision. Related 7782720f (http esm realms + HMR) also depends on this.
10 5cb66ee fix: prevent crash when jweak points to null (#1881) ported this commit Engine-agnostic JNI/cache fix, applied to the same files under new paths. jni/JEnv.h: add isSameObject. jni/LRUCache.h: add optional cacheValidCallback (checked on lookup → evict stale entries via new evictKey) + member. objectmanager/ObjectManager: add ValidateWeakGlobalRefCallback (!isSameObject(obj, NULL)) and pass it to the weak-ref m_cache. Skipped upstream's cosmetic robin_hood/emplace swap (new LRUCache uses std::unordered_map). Verified: native compile all ABIs exit 0.
7782720f feat: http loaded es module realms + HMR DX enrichments (#1883) deferred Builds directly on the deferred ESM feature (modifies the V8 ModuleInternalCallbacks, adds HMRSupport + DevFlags on top of ESM realms, testESModules.mjs). Deferred together with [[052cb21]] ESM.
45fb275 feat: Ada 3.3.0 (#1884) already-present Covered by the consolidated Ada v3 upgrade in commit 8109ff9 (fork now on Ada 3.3.0).
11 c05e283 fix: improve reThrowToJava exception handling and runtime retrieval (#1886) ported this commit Made ObjectManager::GetClassName (both overloads) + its JAVA_LANG_CLASS/GET_NAME_METHOD_ID JNI ids static (added out-of-class defs), so NativeScriptException can resolve a Java class name during rethrow without Runtime::GetRuntime(env)->GetObjectManager() (avoids a throw-within-rethrow when the env/runtime is unavailable). Updated the 3 class-name-only sites in NativeScriptException; left GetJavaExceptionFromEnv (needs the instance). Skipped upstream's clang-format churn of ObjectManager. Runtime-retrieval robustness (.at.find) already present in napi GetRuntime. Verified: native compile+link all ABIs exit 0.
12 3ecd707 fix: proguard builds (#1887) ported this commit Comment out buildMetadata.finalizedBy(currentTask) for minify*WithR8 (app/build.gradle:1181); add consumerProguardFiles 'consumer-rules.pro' to runtime defaultConfig; new runtime/consumer-rules.pro (keep com.tns.*, com.tns.gen.**, com.tns.internal.** + RuntimeVisibleAnnotations). Verified: gradle config eval exit 0. Caveat: full effect only observable in a release R8/minify build.
288491f fix: http realm cache key with query params (#1896) deferred Touches only HMRSupport.cpp + ModuleInternalCallbacks.cpp — both part of the deferred ESM / http-module-realms work ([[052cb21]], [[7782720f]]). Deferred with them.
13 3e61cef fix: URLSearchParams.forEach() crash and spec compliance (#1895) partial this commit New ForEach already had spec arg order (value, key, searchParams), thisArg, and stop-on-throw. Only remaining bug: iterated with get_keys()+get(key) (returns first value for duplicate keys) → switched to get_entries() structured-binding loop (?a=1&a=2 now yields both). Ported the 4 forEach unit tests. Verified: native compile all ABIs exit 0.
5ceb3d4 feat: remote module security (#1899) deferred Secures the http-loaded module realms; C++ lands in DevFlags.cpp/h + HMRSupport.cpp + ModuleInternalCallbacks.cpp — none of which exist in the fork (they come from the deferred [[7782720f]] / [[052cb21]]). Java AppConfig/Runtime additions only make sense with that feature present. Deferred with ESM.
14 e924542 feat: improved error logging for NativeScript exceptions (#1908) partial this commit Ported: the engine-agnostic std::set_terminate(LogAndAbortUncaught) handler in Runtime::Init(JavaVM) — logs an uncaught native exception (message via new NativeScriptException::what()) before _Exit, instead of a bare abort. Skipped: the 726-line V8-based NativeScriptException.cpp/h logging rewrite — the fork's napi NativeScriptException already builds messages/stacks its own way (GetErrorMessage/GetErrorStackTrace/GetFullMessage/PrintErrorMessage) and the old logic is V8-stack-specific; not a clean map. Verified: native compile all ABIs exit 0.
15 1fd144f fix: multithreadedJS should use concurrent java maps (#1920) ported this commit Broadened Runtime.java instance-map fields (strongInstances, weakInstances, strongJavaObjectToID, weakJavaObjectToID, loadedJavaScriptExtends) from concrete types to the Map<> interface (only Map methods are used; NativeScriptHashMap implements Map), and in the Runtime(config, dynamicConfig) ctor swap them to ConcurrentHashMap/Collections.synchronizedMap(...) when getEnableMultithreadedJavascript(). Ported ConcurrentAccessTest.java + testConcurrentAccess.js + mainpage require. Verified: :runtime: + :app:compileDebugJavaWithJavac exit 0. Caveat: concurrency behavior is device-only.
22 085bc4f + 3c956cf feat: @CriticalNative/@FastNative on safe methods (#1921) + optimized native method registration for Android 8-11 (#1942) ported this commit Combined end-state (3c956cf supersedes 085bc4f). Java (Runtime.java): SUPPORTS_OPTIMIZED_NATIVE = SDK_INT>=26; each hot native now has an annotated variant + a *Legacy variant + a dispatcher — @CriticalNative generateNewObjectIdCritical/getCurrentRuntimeIdCritical/getPointerSizeCritical (static, no-arg/primitive) and @FastNative notifyGcFast/setManualInstrumentationModeFast. C++ (com_tns_Runtime.cpp): RegisterOptimizedNatives binds the critical/fast impls via RegisterNatives in JNI_OnLoad (dynamic lookup of annotated methods is broken on API 26-30); *Legacy externs auto-bind for older/ fallback. generateNewObjectId made static-safe via GenerateNewObjectId(nullptr,nullptr) (ignores env/obj); getCurrentRuntimeId uses Runtime::Current() (no JNI). notifyGc keeps the fork's (int,int[])"(I[I)Z". Verified: native+Java compile all ABIs exit 0. Caveat: ART calling-convention correctness is device-only — validate on Android 8-11 + 12+ and a release build.
16 df4e81b fix: select correct runtime when calling from different threads (#1906) ported this commit Headline fix: in Runtime.callJSMethod(int runtimeId, …), re-select via getObjectRuntime(javaObject) not only when the id misses but also when the found runtime doesn't own the object (runtime.getJavaObjectID(javaObject) == null) — fixes a worker invoking a method on an object created in another runtime. Diagnostic: wrapped GetJavaObjectByID in ObjectManager::GetJavaObjectByJsObject with a clearer error (id + original message via the what() added in [[c05e283]]/#1908 port). Adapted to the fork's runtimeId-based dispatch; skipped upstream's NSE ToString()/GetErrorMessage() (fork already has its own message infra + what()). Verified: native+Java compile exit 0.
17 54185ff [jsparser]: disable sourcemap (#1796) ported this commit jsparser/webpack.config.js: devtool: false.
18 e963d6c fix: jsparser report webpack failure (#1797) ported this commit jsparser/js_parser.js: traverseFiles throws when no files found (empty = broken webpack build) instead of silently succeeding.
19 dd2984b fix(jsparser): skip non-Identifier keys in .extend({}) (#1950) ported this commit jsparser/visitors/es5-visitors.js: added _getIdentifierKeyName helper; both .extend property loops now skip spreads/computed/non-Identifier keys instead of crashing (e.g. bundled Zod .extend({ ...other })). Verified: jsparser npm run build (webpack) compiles clean (build/ is gitignored, rebuilt on demand).
20 49da71b fix: circular dependencies when using proguard (#1910) ported this commit Comment out the buildMetadata task's dependsOn compile*ArtProfile and dependsOn optimize*Resources (app/build.gradle) — they created a circular task dependency under proguard/R8. Verified: :app:help config eval exit 0. Caveat: full effect only in a release R8 build.
21 2b6cb03 fix: ensure dex cache directory exists before proxy generation (#1938) ported this commit RuntimeHelper.java: mkdirs() the code_cache/secondary-dexes dir and fall back to appDir/secondary-dexes when it's missing/unwritable. ProxyGenerator.java (runtime-binding-generator): create the parent dir before createNewFile() — prevents ENOENT crashes on newer Android. Verified: app + generators compile exit 0.
23 c9d41e6 + fce8e29 fix(DexFactory): inject DEX into parent class loader (#1951) + register with a single class loader (#1968) ported this commit Combined end-state (fce8e29 supersedes c9d41e6). Enables Class.forName() to find runtime-generated proxies (e.g. FragmentFactory). DexFactory: new injectIntoParentClassLoader ctor flag; resolveClass adds the jar into the app's own BaseDexClassLoader via injectDexIntoClassLoader (API 24+ addDexPath; 23/<23 appendDexElements using DexPathList.makePathElements/makeDexElements) so the DexFile has a single owner (avoids ART "registered with multiple class loaders" on release builds), falling back to an isolated DexClassLoader on failure. Runtime.java passes isMainThread (workerId==0). Ported testClassForNameDiscovery.js. Verified: Java compile exit 0 (reflection has a try/catch fallback if hidden-API access is blocked). Caveat: hidden-API reflection is Android-version-sensitive — validate on real devices across versions and a release/non-debuggable build.
24 bfd7650 fix(timers): order timers with the Java MessageQueue instead of ALooper fds ported this commit Replaced the fork's ALooper-fd/pipe/watcher-thread/mutex/condvar timer delivery with a per-runtime com.tns.TimerHandler (new) bound to the runtime thread's Looper: each timer enqueues one anonymous due-token via sendMessageAtTime, and native FireTimer() (called from handleMessage) fires the earliest-due entry of sortedTimers_ (now vector<TimerReference> by exact sub-ms dueTime). postTimer posts due-now at (long)now (FIFO tie with postDelayed(0)) and future at ceil(dueTime). Removed threadLoop/PumpTimerLoopCallback/fd/thread/mutex/condvar; added extern "C" Java_com_tns_TimerHandler_nativeFireTimer (symbol-bound). Also fixed the pre-existing callback-napi_ref leak by centralizing ref deletion in TimerTask::Unschedule. Ported testNativeTimers.js. Verified: native+Java compile all ABIs exit 0. Caveat: ordering semantics are device-only — run the regression tests on a device.
25 89893ae fix: URLSearchParams construction and iteration spec compliance (#1970) ported this commit Rewrote the fork's napi URLSearchParams to the WebIDL spec: constructor now accepts string / record / sequence-of-pairs / primitive (via napi_typeof + @@iterator detection, napi_get_all_property_names for records, an ES-iterator driver for sequences with IteratorClose on abrupt completion, napi_coerce_to_string USVString coercion). keys/values/entries now return live spec iterators (a JS {next} object over ada operator[], duplicate-key correct, Symbol.iterator→self, Symbol.toStringTag="URLSearchParams Iterator", freed via napi_add_finalizer); prototype[@@iterator]===entries. Added optional-value delete/has; get returns null (not undefined) on miss; brand checks ("Illegal invocation") + ValueToString coercion on every method. Ported the full 522-line spec test. Verified: native compile all ABIs exit 0. Caveat: spec behavior validated by the ported WPT-style tests on-device.
92c2654 fix: anchor relative dynamic imports at the file:// referrer's directory (#1976) deferred ESM-only: touches ModuleInternalCallbacks.cpp (deferred ESM file) + .mjs tests. Deferred with [[052cb21]].
45ed1f6 fix: normalize "." and ".." in resolved module paths to dedupe modules (#1977) deferred ESM-only: ModuleInternalCallbacks.cpp + .mjs tests. Deferred with [[052cb21]].
26 a84d3c7 feat(workers): move worker threading and messaging to C++ (#1972) partial this commit Ported the engine-agnostic core (Path B): moved worker threading/messaging from Java HandlerThread into C++ — new runtime/workers/{WorkerWrapper,ConcurrentQueue,LooperTasks,WorkerMessage}. Parent→worker via a ConcurrentQueue (eventfd+ALooper) inbox; worker→parent via the parent Runtime's LooperTasks. WorkerWrapper owns the worker std::thread (JVM attach → Java initWorkerRuntime/runWorkerLoop/detachWorkerRuntime → C++ inbox pump), nested-worker cascade, registry. Removed the Java WorkerThread/WorkerThreadHandler/MainThreadHandler worker branches, initWorker, the 6 worker native decls + JNI entrypoints, and MessageType.java/JavaScriptErrorMessage.java. Perf: removes 2 JNI hops + Java Message/Handler alloc + dispatch per postMessage. Scoped out (V8-only, no napi surface): v8::ValueSerializer structured clone and SharedArrayBuffer → payloads stay JSON on all engines (same semantics as before); terminate() is cooperative (no v8::TerminateExecution — a busy-loop worker isn't preempted). napi_envWorkerWrapper via a registry (no isolate data slot). Verified: native+Java compile all ABIs exit 0. Caveat: worker threading/lifecycle correctness is device-only — exercise the worker test suite on a device.
27 55da2da + 4b5ab0a feat(inspector): serve source maps to DevTools (#1969) + attach DevTools to Web Worker isolates (#1973) ported this commit Ported both V8-inspector features onto the fork's napi+v8 hybrid inspector (runtime/inspector/JsV8InspectorClient reaches env->isolate). #1969: Network.loadNetworkResource/IO.read/IO.close disk-served source maps, nsruntime:// sourceMapURL rewrite (+disableSourceMapURLRewrite), socket-thread message fast-path, resource-stream cleanup on disconnect. #1973: new WorkerInspectorClient.{h,cpp} (per-worker V8 inspector Target/flat-session CDP) + Target-domain worker-session routing + console history; hooked into the new napi WorkerWrapperCreateInspector(napi_env)/DestroyInspector() in BackgroundLooper around RunWorker, NotifyTerminating() on cooperative terminate, consoleLogCallback via WorkerWrapper::FromEnv. Vendored third_party/json.hpp. All inspector code gated #if defined(__V8__) && defined(APPLICATION_IN_DEBUG)verified multi-engine-safe (QuickJS build green). Verified: V8-13 debug + QuickJS native+Java compile exit 0. Caveat: actual DevTools attach / worker breakpoints / source-map fetch / pause-interrupt are device+DevTools-only — run a live debug session before shipping.
4 3423e6f feat: support 16 KB page sizes, gradle 8.5 (#1818) partial ca93e66 Ported: 16 KB -Wl,-z,max-page-size=16384 link option for arm64-v8a/x86_64 in runtime/CMakeLists.txt (verified present in ninja LINK_FLAGS); bumped NS_DEFAULT_COMPILE_SDK_VERSION/NS_DEFAULT_BUILD_TOOLS_VERSION 34→35 (both installed). Skipped: gradle-wrapper 8.4→8.7 and AGP 8.3.2→8.5.0 (new already newer: gradle 8.14.3 / AGP 8.12.1); STL c++_sharedc++_static (new deliberately uses c++_shared for multi-engine libc++ — would break engine .so setup). Verified: native reconfigure+relink exit 0.

Verified duplication-check seeds (from planning; confirm at implementation time)

MISSING → implement: f033061 queueMicrotask · Ada v3.x chain (b31fc5f/3633aed/3513ce7/83f611b/45fb275) — new bundles Ada 2.9.0, old 3.3.0.

PARTIAL → port delta only: 052cb21 ESM (deferred) · URLSearchParams spec follow-ups (3e61cef/89893ae/288491f).

ALREADY-PRESENT → skip w/ evidence: e98367c performance api (Performance.h) · e293636 companion-object inner-type (MetadataNode::SetInnerTypes hasOwnProperty guard) · 1fd144f/df4e81b multithreaded runtime selection (Runtime.java ConcurrentHashMap + dual-path getCurrentRuntimeId).

Build deltas (new behind old): compileSdk/targetSdk 34→35, buildTools 34→35, Kotlin 2.0.0→2.2.20, NDK default 27.1→27.3. AGP/Gradle 8.12.1, JDK 17, minSdk 21 already match. Apply only per-commit version/flag deltas; preserve multi-engine gradle/CMake machinery.