Skip to content

feat!: upgrade V8 to 14.9.207.39 - #412

Open
edusperoni wants to merge 5 commits into
mainfrom
feat/v8-14
Open

feat!: upgrade V8 to 14.9.207.39#412
edusperoni wants to merge 5 commits into
mainfrom
feat/v8-14

Conversation

@edusperoni

@edusperoni edusperoni commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Upgrades the runtime from V8 10.3.22 → 14.9.207.39. Companion to NativeScript/android#1987.

Status

TestRunner suite (iOS Simulator) 904 tests, 0 failures, 0 errors, 11 skipped
NativeScript.xcframework builds against the released V8
Inspector / CDP verified end to end (7/7 protocol checks)
Vendored headers all 251 match the pinned checkout byte for byte

The eleven skips are the pre-existing xit()s already in the suite.

The libraries are no longer committed

./download_v8.sh installs them from the release pinned in V8_RELEASE, verifying every archive against the SHA256SUMS published with it. It is a no-op once they are in place, V8_SKIP_DOWNLOAD=1 skips it entirely, and build_nativescript.sh calls it — so the vision path is covered by the same call.

It is a standalone script rather than an Xcode build phase, deliberately matching download_llvm.sh: a prerequisite you run once, trivial to skip, and easy to override with a local V8 build. Keeping it out of the build also means a stale or unreachable release cannot wedge an otherwise working build.

Why they cannot stay in git: the full matrix cannot be produced on any single machine. The Apple variants need macOS; the 32-bit Android ABIs need an ia32-capable host, because mksnapshot becomes a 32-bit x86 host binary and v8config.h refuses anything else. Artifacts assembled by hand are therefore stitched together from several machines, and nobody can reproduce or verify them. On Android two of the monoliths now also exceed GitHub's 100 MiB per-file push limit.

fetch_v8.sh and build_v8_source*.sh go for the same reason: producing V8 belongs in v8-buildscripts, which builds all nine targets in CI. A second copy of the gn args here is just two sets that can disagree — and these are args where disagreeing is expensive.

The vendored headers are ignored along with the libraries, not just the binaries. Keeping a copy in git is how it drifts out of step with the libraries it describes, and it already had: third_party/inspector_protocol/crdtp was still on 10.3 while libcrdtp.a was built from 14.9. It compiled and the inspector worked, so it was latent rather than broken — but it is exactly the mismatch this change removes. libffi stays tracked; it is not V8.

tools/v8/vendor_inspector_sources.py re-derives the inspector's internals by closure from the release's src-headers artifact. That also prunes the tree from 164 files to the 66 actually reachable from the glue — verified by compiling all five roots against the closure alone.

The API migration

Mostly mechanical; the full table is in docs/knowledge/v8-14-migration.md. The part that is not:

PropertyCallbackInfo no longer exposes the receiver at all, and SetNativeDataProperty is not a drop-in for SetAccessor on anything inherited from. ClassBuilder's super (on the implementation object) and Reference's value (on a prototype template) both need the receiver and are now function-backed. Static properties on constructor functions matter most: SetNativeDataProperty installs something data-like, so assigning through a derived class shadowed the base with an own property and never reached the native setter — silent, and not covered by any test.

Interceptors now return v8::Intercepted. A path that set a return value or threw becomes kYes; a path that returned without setting one, including falling off the end, becomes kNo. The fall-through case is load-bearing: the swizzling definer depends on V8 still running the real defineProperty, and the setters depend on V8 still performing the store. Getting it backwards is silent in both directions.

Two parity traps, neither covered by a test:

  • Object::SetAccessor defaulted to PropertyAttribute::None, so super's attributes are passed explicitly rather than assumed — DontEnum would have removed it from Object.keys().
  • ArrayBuffer::Detach now returns Maybe<bool> and is warn-unused-result, which invites a .Check() that aborts the process when the buffer has a mismatched detach key. The result is discarded instead, matching the void Detach it replaced.

Isolate::VisitHandlesWithClassIds was removed, so teardown disposal walks an intrusive list of registered wrappers that unlink themselves from their GC finalizer, rather than enumerating V8's handles.

Module resolution now fails loudly

should throw error if cant find node module was the one test the upgrade broke, and the cause was worth more than a patch. An unresolvable specifier resolved to a placeholder module whose exports was meant to be a Proxy that threw on property access, so require() of a missing module succeeded and only failed if you dereferenced it.

That placeholder never worked on any V8 version. The generated script interpolates the module name unquoted into a single-quoted string literal:

new Error('Module 'nonExistingFileName.js' is not available. This is an optional module.')

Always a SyntaxError, so exports was never set. On 10.3 the pending exception left by that failed compile — there is no TryCatch around it — escaped the require callback, and that accident is the only reason the test passed. On 14.9 it no longer escapes, so require returned undefined.

The mechanism is removed rather than repaired: both the CommonJS and ESM paths now throw Cannot find module '<specifier>'. The ESM resolver additionally had debug-mode branches returning an empty MaybeLocal without scheduling an exception, which is not a valid resolve-callback result; those now throw too. node: built-in polyfills are untouched.

Every bare specifier still live in the suite is either inside a try/catch or behind an isV8iOS ? xit skip, so nothing depended on the placeholder.

What is not verified

  • arm64-maccatalyst has no libffi.a and never did — it is missing from build_libffi.sh's ALL_SLICES, which lists the other six. Pre-existing and unrelated to V8, but it means interop on that slice looks unbuildable.

Notes for review

  • The vendored headers were being reflowed by the repo's clang-format pre-commit hook. Harmless in itself, but it made every re-vendor produce a spurious diff and hid whether the copy still matched upstream. Moot now that the trees are ignored.
  • V8_STATIC_ROOTS is deliberately not defined. V8 is built with it and it would let Value::IsUndefined()/IsNull() use the inline static-root comparison, but the root addresses are hardcoded constants in v8-internal.h that must match the library exactly (kBuildDependentTheHoleValue even varies with V8_ENABLE_WEBASSEMBLY). 10.3 had no such fast path, so this is parity; enabling it is a separate, measurable change.

Summary by CodeRabbit

  • New Features

    • Added automated installation of verified, pinned V8 libraries and headers.
    • Added support for the updated V8 14.9 runtime and modern Apple build environments.
    • Improved native JavaScript interoperability, property access, URL handling, and object cleanup.
  • Bug Fixes

    • Improved inspector session and console handling.
    • Missing modules now report clearer errors instead of creating placeholders.
    • Updated CI and simulator coverage for current Xcode and iOS versions.
  • Documentation

    • Added V8 migration and finalizer guidance.
    • Simplified instructions for obtaining or building V8 artifacts.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR migrates NativeScript’s iOS V8 integration to V8 14.9, adds checksum-verified prebuilt artifact installation and inspector vendoring, updates runtime bindings and callbacks, removes obsolete vendored V8 sources, changes module and teardown behavior, and updates CI, documentation, and version metadata.

Changes

V8 14.9 migration

Layer / File(s) Summary
Prebuilt artifact installation and CI
download_v8.sh, tools/v8/*, .github/workflows/*, v8ios.xcodeproj/project.pbxproj
Pinned V8 archives are downloaded, verified, installed, and linked; CI uses macOS 15/Xcode 16 and updated simulator targets.
Runtime API adaptation
NativeScript/runtime/*, NativeScript/v8runtime/*
V8 calls use current isolates, explicit external/embedder tags, updated script-origin and string APIs, and revised callback contracts.
Interceptor and accessor migration
NativeScript/runtime/ArgConverter.*, MetadataBuilder.*, Reference.*, URLImpl.*
Property callbacks return v8::Intercepted, use holder receivers, and use updated accessor installation APIs.
Modules and teardown
NativeScript/runtime/ModuleInternal*, ObjectManager.*, Runtime.mm
Optional placeholder modules are removed, dynamic imports use the new callback signature, and wrapper disposal uses an intrusive registry.
Inspector integration
NativeScript/inspector/*
Inspector connections use fully trusted mode, explicit context scopes, tagged callback data, and updated console argument ranges.
Documentation and validation
README.md, docs/knowledge/*, TestRunner/app/tests/*, V8_RELEASE
Build instructions, V8 migration notes, finalizer notes, version metadata, and static-property expectations are updated.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested reviewers: nathanwalker

Poem

A rabbit fetched V8 with care,
Tagged pointers through the air.
Old headers hopped away,
New callbacks learned to stay—
And CI found fresh carrots there.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.25% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately captures the primary change: upgrading V8 to 14.9.207.39.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Base automatically changed from feat/error-handling to main July 27, 2026 19:13
Mechanical, except where noted:

- Context::GetIsolate() removed -> Isolate::GetCurrent()
- External::New/Value() and the aligned internal-field accessors take a
  type tag
- ScriptOrigin no longer takes an isolate; AccessControl is gone
- GetInternalField returns Local<Data>
- GetCreationContext[Checked]() need an isolate
- V8Inspector::connect takes a trust level; createForConsoleAPI takes a
  span; the dynamic-import callback is reshaped
- String::Value -> String::ValueView, remembering that a one-byte V8
  string is Latin-1 rather than UTF-8
- Local is trivially destructible now, so unused locals trip
  -Wunused-variable

Accessors are the part that is not mechanical. PropertyCallbackInfo no
longer exposes the receiver, and SetNativeDataProperty is not a drop-in
for SetAccessor on anything inherited from. ClassBuilder's super (on the
implementation object) and Reference's value (on a prototype template)
both need the receiver, and are now function-backed. Static properties on
constructor functions matter most: SetNativeDataProperty installs
something data-like, so assigning through a derived class shadowed the
base with an own property and never reached the native setter.

Interceptors now return v8::Intercepted. A path that set a return value
or threw becomes kYes; a path that returned without setting one --
including falling off the end -- becomes kNo. The fall-through case is
load-bearing: the swizzling definer depends on V8 still running the real
defineProperty, and the setters depend on V8 still performing the store.

Two parity traps worth recording. Object::SetAccessor defaulted to
PropertyAttribute::None, so super's attributes are passed explicitly
rather than assumed. ArrayBuffer::Detach now returns Maybe<bool> and is
warn-unused-result, which invites a .Check() that aborts the process on a
detach-key mismatch; the result is discarded instead, matching the void
Detach it replaced.

Isolate::VisitHandlesWithClassIds was removed, so teardown disposal walks
an intrusive list of registered wrappers that unlink themselves from
their GC finalizer, rather than enumerating V8's handles.
The libraries and the headers that must match them now come from a pinned
release of NativeScript/v8-buildscripts, installed by ./download_v8.sh
and verified against the SHA256SUMS published with it. V8_RELEASE is the
pin.

The full matrix cannot be produced on any single machine -- the Apple
variants need macOS, the 32-bit Android ABIs need an ia32-capable host --
so hand-assembled binaries are neither reproducible nor verifiable. That
is also why fetch_v8.sh and build_v8_source*.sh go: producing V8 belongs
in the build repo, which can build all of it, and a second copy of the gn
args here is just two sets that can disagree.

The vendored headers are ignored along with the libraries. Keeping a copy
in git is how it drifts out of step with the libraries it describes:
third_party/inspector_protocol/crdtp was still on 10.3 while libcrdtp.a
was built from 14.9. Sourcing both from one verified artifact makes that
impossible. The inspector's internals are re-derived by closure from the
release's src-headers artifact, which also prunes the tree from 164 files
to the 66 actually reachable from the glue.

It is a standalone script rather than an Xcode build phase, matching
download_llvm.sh: a prerequisite you run once, a no-op when the artifacts
are in place, and V8_SKIP_DOWNLOAD=1 to keep a local V8 build.
build_nativescript.sh calls it, so the vision path is covered too.

libffi stays tracked; it is not V8.
Under docs/knowledge rather than the repo root: they are a record of a
completed migration, not instructions, and next to error-handling.md they
would read as the latter.
V8 14.9's v8-memory-span.h defines MemorySpan<T>::Iterator, a nested class
with no element_type. Xcode 15.4's libc++ leaves the primary
__pointer_traits_element_type undefined, so <memory> instantiating it for
that type is a hard error rather than a SFINAE miss; newer libc++ defines
it as an empty struct and the instantiation drops out. The floor is the
standard library, not our code, so the runner and Xcode both move up.

Xcode 16 ships the iOS 18 runtime, so the destination's OS=17.2 pin no
longer resolves -- it is OS=latest on an iPhone 16 Pro now.

download_v8.sh moves into setup-build-env because the test job drives
xcodebuild directly and never reaches build_nativescript.sh, which is what
installs V8 for the build job. Shared setup is the one place both jobs go
through. It is idempotent, so the build job running it twice costs
nothing.
An unresolvable bare specifier resolved to a placeholder module whose
exports was a Proxy that threw on property access, so requiring a missing
module without dereferencing it succeeded silently. The ESM resolver had
the same construct, plus debug-mode branches that returned an empty
MaybeLocal without scheduling an exception, which is not a valid resolve
callback result.

The placeholder never worked in the first place: the module name was
interpolated unquoted into a single-quoted JS string literal, so the
generated proxy script was always a SyntaxError. On V8 10.3 the pending
exception left by that failed compile escaped the require callback, which
is the only reason "should throw error if cant find node module" passed.

Both paths now throw "Cannot find module '<specifier>'".

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
NativeScript/runtime/URLPatternImpl.cpp (1)

142-148: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Reject foreign receivers before reading internal fields.

URLPatternImpl::GetPointer and URLImpl::GetPointer are called by ordinary property accessors, so JS can invoke them with .call()/.apply() on an unrelated object. Guard each receiver with InternalFieldCount() < 1 before GetAlignedPointerFromInternalField(0, ...) to avoid V8 undefined behavior/type confusion.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@NativeScript/runtime/URLPatternImpl.cpp` around lines 142 - 148, Guard both
URLPatternImpl::GetPointer in NativeScript/runtime/URLPatternImpl.cpp (lines
142-148) and URLImpl::GetPointer in NativeScript/runtime/URLImpl.cpp (lines
23-30) by returning nullptr when object->InternalFieldCount() is less than 1,
before calling GetAlignedPointerFromInternalField; preserve the existing
null-pointer handling afterward.
🧹 Nitpick comments (6)
docs/knowledge/v8-14-migration.md (1)

215-227: 🩺 Stability & Availability | 🔵 Trivial

Track the intermittent deadlock as a release risk.

A ten-minute lock-order hang is an availability issue even if it has not reproduced recently. Please attach a tracked issue and add a regression/stress scenario or explicit CI timeout diagnostics before treating the suite as fully green.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/knowledge/v8-14-migration.md` around lines 215 - 227, Update the “An
intermittent worker/notification deadlock” section to reference a tracked issue
and document either a regression/stress scenario or explicit CI timeout
diagnostics for this lock-order hang. Keep the existing reproduction details and
require these safeguards before considering the suite fully green.
NativeScript/runtime/ModuleInternal.mm (1)

403-405: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated "Cannot find module" framing produces a doubly-wrapped message.

ResolvePath already throws the detailed Cannot find module '<name>' error, and LoadImpl catches it and re-wraps it with Failed to resolve module: '<name>' plus the same base-dir context. The user-visible string ends up repeating the specifier and base directory three times. Consider letting the ResolvePath message pass through unwrapped so the thrown text matches the Node-style Cannot find module '<specifier>' the PR advertises.

Also applies to: 1045-1060

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@NativeScript/runtime/ModuleInternal.mm` around lines 403 - 405, Remove the
duplicate “Cannot find module” exception construction in ResolvePath and let its
existing detailed error propagate through LoadImpl without re-wrapping. Update
the LoadImpl catch/error path as needed so the user-visible message remains the
Node-style “Cannot find module '<specifier>'” without repeated module or
base-directory context.
NativeScript/runtime/WorkerWrapper.mm (1)

219-219: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Inconsistent isolate source within functions that already hold the right isolate as a member.

CallOnErrorHandlers/PassUncaughtExceptionFromWorkerToMain/ConstructErrorObject all mix v8::Isolate::GetCurrent() with the already-available this->workerIsolate_ / this->mainIsolate_ members in the same function body. Current call sites all establish the matching Isolate::Scope first, so this works today, but relying on GetCurrent() when the correct isolate is already a class member is a latent trap for future callers.

♻️ Suggested direction
-  Isolate* isolate = v8::Isolate::GetCurrent();
-  tns::Assert(success, isolate);
+  tns::Assert(success, this->workerIsolate_);

Also applies to: 247-247, 380-380

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@NativeScript/runtime/WorkerWrapper.mm` at line 219, Replace the local
v8::Isolate::GetCurrent() usages in CallOnErrorHandlers,
PassUncaughtExceptionFromWorkerToMain, and ConstructErrorObject with the
matching workerIsolate_ or mainIsolate_ member used by each function. Keep the
existing isolate scopes and behavior unchanged.
NativeScript/runtime/MetadataBuilder.mm (1)

904-932: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Minor asymmetry: empty-name struct write is silently swallowed vs. "field not found" falling through.

StructPropertySetterCallback returns Intercepted::kYes for propertyName == "" (blocks the ordinary store) but Intercepted::kNo for "field not found" (allows the ordinary store). Since struct property names are never realistically empty strings, this is unlikely to matter in practice.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@NativeScript/runtime/MetadataBuilder.mm` around lines 904 - 932, Update
StructPropertySetterCallback so an empty propertyName follows the same fallback
behavior as an unknown struct field: return Intercepted::kNo instead of
swallowing the write. Preserve the existing field lookup and
Interop::SetStructPropertyValue flow for recognized fields.
NativeScript/runtime/Timers.cpp (2)

127-130: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Discarded NewFunctionTemplate result.

This call creates a FunctionTemplate and an External that are never used — the actual bindings come from the SetMethod calls below. Since you are already touching these lines for the pointer tag, dropping the dead call removes a per-isolate allocation and some confusion.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@NativeScript/runtime/Timers.cpp` around lines 127 - 130, Remove the unused
tns::NewFunctionTemplate call involving Timers::SetTimeoutCallback and its
v8::External allocation; retain the SetMethod bindings below as the sole
registration path.

171-172: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Prefer the already-scoped isolate local over Isolate::GetCurrent().

isolate (from task->isolate_) is the isolate whose Isolate::Scope/Locker is active here, so passing it directly is both clearer and independent of ambient current-isolate state.

♻️ Use the local isolate
-  v8::Local<v8::Context> context =
-      cb->GetCreationContextChecked(v8::Isolate::GetCurrent());
+  v8::Local<v8::Context> context = cb->GetCreationContextChecked(isolate);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@NativeScript/runtime/Timers.cpp` around lines 171 - 172, Update the context
lookup in the timer callback to pass the already-scoped isolate local from
task->isolate_ to GetCreationContextChecked, replacing the ambient
Isolate::GetCurrent() lookup while preserving the existing callback and context
flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/knowledge/v8-14-migration.md`:
- Around line 193-198: Update the migration documentation’s NativeScript/lib
architecture follow-up to resolve all six remaining V8 10.3 slices before
release: rebuild or remove each supported slice, or explicitly document that
download_v8.sh replaces them. Ensure the documented state no longer permits
packaging older libraries alongside V8 14.9 headers.

In `@docs/knowledge/v8-resurrecting-finalizers.md`:
- Around line 137-140: Renumber the “Resurrect-then-rearm, end to end” checklist
entry from item 3 to item 2 so the test plan numbering is sequential.
- Around line 3-7: Run the finalizer runtime acceptance tests against the
patched V8, covering resurrect/rearm, nested-GC, young-generation, and worker
scenarios. Update the documented Status and test listing in
v8-resurrecting-finalizers.md to record the runtime results, retaining the
compilation status and clearly indicating any failures or unresolved validation.

In `@download_v8.sh`:
- Around line 55-58: Update the V8_SKIP_DOWNLOAD early-exit branch in
download_v8.sh so local builds still synchronize NativeScript/inspector
internals: require the local source and generated paths and rerun the vendoring
step before exiting, or explicitly reject local builds whose V8 revision does
not match. Preserve the existing skip behavior only for compatible,
already-synchronized builds.

In `@NativeScript/runtime/ExtVector.cpp`:
- Around line 55-59: Update the out-of-range branch in the vector getter to
return v8::Intercepted::kNo instead of setting undefined and returning kYes,
preserving V8’s normal own/prototype lookup and matching the setter’s
fall-through behavior.

In `@NativeScript/runtime/ModuleInternalCallbacks.mm`:
- Around line 2406-2413: Remove the unreachable __nsHmrRequestModule fetch-retry
path and its related callbacks, including the code around
ImportModuleDynamicallyCallback and the external-pointer handling at the
referenced sections, or hoist the retry logic before the existing
maybeModule.IsEmpty() early return so it can execute. Ensure the chosen change
eliminates the dead guard and preserves valid dynamic import behavior.

In `@NativeScript/runtime/Pointer.cpp`:
- Around line 159-161: The PointerWrapper retrieval in Pointer.cpp must validate
that info.This() has an internal field containing an External and that the
resulting PointerWrapper* is non-null before accessing its data; throw a
TypeError for invalid receivers. In ObjectManager.mm, validate
superField->IsValue() before calling As<v8::Value>() when reading internal field
1.

In `@NativeScript/runtime/SymbolIterator.mm`:
- Around line 27-29: Update the Symbol.iterator installation in the surrounding
iterator setup to assert the result of Set, matching the other Set calls in
SymbolIterator.mm; do not leave the assigned success value unchecked.

In `@NativeScript/runtime/UnmanagedType.mm`:
- Around line 67-90: Update UnmanagedType::TakeValue to mark the wrapper as
consumed after Interop::GetResult completes, covering both retained and
unretained paths before returning. Preserve the existing ValueTaken guard and
ensure the retained release occurs only once.

In `@NativeScript/runtime/URLImpl.cpp`:
- Around line 76-90: Update URLImpl::Ctor to handle count == 0 before accessing
args[0], and only call tns::ToString after confirming the argument is a string;
preserve the existing TypeError behavior for present non-string values. Apply
the same validation to URLImpl::CanParse for info[0] and info[1], avoiding
unchecked .As<v8::String>() casts and preserving its expected behavior for
omitted arguments.

---

Outside diff comments:
In `@NativeScript/runtime/URLPatternImpl.cpp`:
- Around line 142-148: Guard both URLPatternImpl::GetPointer in
NativeScript/runtime/URLPatternImpl.cpp (lines 142-148) and URLImpl::GetPointer
in NativeScript/runtime/URLImpl.cpp (lines 23-30) by returning nullptr when
object->InternalFieldCount() is less than 1, before calling
GetAlignedPointerFromInternalField; preserve the existing null-pointer handling
afterward.

---

Nitpick comments:
In `@docs/knowledge/v8-14-migration.md`:
- Around line 215-227: Update the “An intermittent worker/notification deadlock”
section to reference a tracked issue and document either a regression/stress
scenario or explicit CI timeout diagnostics for this lock-order hang. Keep the
existing reproduction details and require these safeguards before considering
the suite fully green.

In `@NativeScript/runtime/MetadataBuilder.mm`:
- Around line 904-932: Update StructPropertySetterCallback so an empty
propertyName follows the same fallback behavior as an unknown struct field:
return Intercepted::kNo instead of swallowing the write. Preserve the existing
field lookup and Interop::SetStructPropertyValue flow for recognized fields.

In `@NativeScript/runtime/ModuleInternal.mm`:
- Around line 403-405: Remove the duplicate “Cannot find module” exception
construction in ResolvePath and let its existing detailed error propagate
through LoadImpl without re-wrapping. Update the LoadImpl catch/error path as
needed so the user-visible message remains the Node-style “Cannot find module
'<specifier>'” without repeated module or base-directory context.

In `@NativeScript/runtime/Timers.cpp`:
- Around line 127-130: Remove the unused tns::NewFunctionTemplate call involving
Timers::SetTimeoutCallback and its v8::External allocation; retain the SetMethod
bindings below as the sole registration path.
- Around line 171-172: Update the context lookup in the timer callback to pass
the already-scoped isolate local from task->isolate_ to
GetCreationContextChecked, replacing the ambient Isolate::GetCurrent() lookup
while preserving the existing callback and context flow.

In `@NativeScript/runtime/WorkerWrapper.mm`:
- Line 219: Replace the local v8::Isolate::GetCurrent() usages in
CallOnErrorHandlers, PassUncaughtExceptionFromWorkerToMain, and
ConstructErrorObject with the matching workerIsolate_ or mainIsolate_ member
used by each function. Keep the existing isolate scopes and behavior unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 965742ff-aedf-4dd9-9e33-85af7ef1f02f

📥 Commits

Reviewing files that changed from the base of the PR and between 55ffdef and cd8671e.

📒 Files selected for processing (432)
  • .github/actions/setup-build-env/action.yml
  • .github/workflows/npm_release.yml
  • .github/workflows/pull_request.yml
  • .gitignore
  • NativeScript/NativeScript-Prefix.pch
  • NativeScript/include/APIDesign.md
  • NativeScript/include/DEPS
  • NativeScript/include/DIR_METADATA
  • NativeScript/include/OWNERS
  • NativeScript/include/cppgc/DEPS
  • NativeScript/include/cppgc/OWNERS
  • NativeScript/include/cppgc/README.md
  • NativeScript/include/cppgc/allocation.h
  • NativeScript/include/cppgc/common.h
  • NativeScript/include/cppgc/cross-thread-persistent.h
  • NativeScript/include/cppgc/custom-space.h
  • NativeScript/include/cppgc/default-platform.h
  • NativeScript/include/cppgc/ephemeron-pair.h
  • NativeScript/include/cppgc/explicit-management.h
  • NativeScript/include/cppgc/garbage-collected.h
  • NativeScript/include/cppgc/heap-consistency.h
  • NativeScript/include/cppgc/heap-state.h
  • NativeScript/include/cppgc/heap-statistics.h
  • NativeScript/include/cppgc/heap.h
  • NativeScript/include/cppgc/internal/api-constants.h
  • NativeScript/include/cppgc/internal/atomic-entry-flag.h
  • NativeScript/include/cppgc/internal/caged-heap-local-data.h
  • NativeScript/include/cppgc/internal/compiler-specific.h
  • NativeScript/include/cppgc/internal/finalizer-trait.h
  • NativeScript/include/cppgc/internal/gc-info.h
  • NativeScript/include/cppgc/internal/logging.h
  • NativeScript/include/cppgc/internal/name-trait.h
  • NativeScript/include/cppgc/internal/persistent-node.h
  • NativeScript/include/cppgc/internal/pointer-policies.h
  • NativeScript/include/cppgc/internal/write-barrier.h
  • NativeScript/include/cppgc/liveness-broker.h
  • NativeScript/include/cppgc/macros.h
  • NativeScript/include/cppgc/member.h
  • NativeScript/include/cppgc/name-provider.h
  • NativeScript/include/cppgc/object-size-trait.h
  • NativeScript/include/cppgc/persistent.h
  • NativeScript/include/cppgc/platform.h
  • NativeScript/include/cppgc/prefinalizer.h
  • NativeScript/include/cppgc/process-heap-statistics.h
  • NativeScript/include/cppgc/sentinel-pointer.h
  • NativeScript/include/cppgc/source-location.h
  • NativeScript/include/cppgc/testing.h
  • NativeScript/include/cppgc/trace-trait.h
  • NativeScript/include/cppgc/type-traits.h
  • NativeScript/include/cppgc/visitor.h
  • NativeScript/include/inspector/Debugger.h
  • NativeScript/include/inspector/Runtime.h
  • NativeScript/include/inspector/Schema.h
  • NativeScript/include/js_protocol-1.2.json
  • NativeScript/include/js_protocol-1.3.json
  • NativeScript/include/js_protocol.pdl
  • NativeScript/include/libplatform/DEPS
  • NativeScript/include/libplatform/libplatform-export.h
  • NativeScript/include/libplatform/libplatform.h
  • NativeScript/include/libplatform/v8-tracing.h
  • NativeScript/include/v8-array-buffer.h
  • NativeScript/include/v8-callbacks.h
  • NativeScript/include/v8-container.h
  • NativeScript/include/v8-context.h
  • NativeScript/include/v8-cppgc.h
  • NativeScript/include/v8-data.h
  • NativeScript/include/v8-date.h
  • NativeScript/include/v8-debug.h
  • NativeScript/include/v8-embedder-heap.h
  • NativeScript/include/v8-embedder-state-scope.h
  • NativeScript/include/v8-exception.h
  • NativeScript/include/v8-extension.h
  • NativeScript/include/v8-external.h
  • NativeScript/include/v8-fast-api-calls.h
  • NativeScript/include/v8-forward.h
  • NativeScript/include/v8-function-callback.h
  • NativeScript/include/v8-function.h
  • NativeScript/include/v8-initialization.h
  • NativeScript/include/v8-inspector-protocol.h
  • NativeScript/include/v8-inspector.h
  • NativeScript/include/v8-internal.h
  • NativeScript/include/v8-isolate.h
  • NativeScript/include/v8-json.h
  • NativeScript/include/v8-local-handle.h
  • NativeScript/include/v8-locker.h
  • NativeScript/include/v8-maybe.h
  • NativeScript/include/v8-memory-span.h
  • NativeScript/include/v8-message.h
  • NativeScript/include/v8-metrics.h
  • NativeScript/include/v8-microtask-queue.h
  • NativeScript/include/v8-microtask.h
  • NativeScript/include/v8-object.h
  • NativeScript/include/v8-persistent-handle.h
  • NativeScript/include/v8-platform.h
  • NativeScript/include/v8-primitive-object.h
  • NativeScript/include/v8-primitive.h
  • NativeScript/include/v8-profiler.h
  • NativeScript/include/v8-promise.h
  • NativeScript/include/v8-proxy.h
  • NativeScript/include/v8-regexp.h
  • NativeScript/include/v8-script.h
  • NativeScript/include/v8-snapshot.h
  • NativeScript/include/v8-statistics.h
  • NativeScript/include/v8-template.h
  • NativeScript/include/v8-traced-handle.h
  • NativeScript/include/v8-typed-array.h
  • NativeScript/include/v8-unwinder-state.h
  • NativeScript/include/v8-unwinder.h
  • NativeScript/include/v8-util.h
  • NativeScript/include/v8-value-serializer-version.h
  • NativeScript/include/v8-value-serializer.h
  • NativeScript/include/v8-value.h
  • NativeScript/include/v8-version-string.h
  • NativeScript/include/v8-version.h
  • NativeScript/include/v8-wasm-trap-handler-posix.h
  • NativeScript/include/v8-wasm-trap-handler-win.h
  • NativeScript/include/v8-wasm.h
  • NativeScript/include/v8-weak-callback-info.h
  • NativeScript/include/v8.h
  • NativeScript/include/v8config.h
  • NativeScript/inspector/JsV8InspectorClient.mm
  • NativeScript/inspector/WorkerInspectorClient.mm
  • NativeScript/inspector/src/base/address-region.h
  • NativeScript/inspector/src/base/atomic-utils.h
  • NativeScript/inspector/src/base/atomicops.h
  • NativeScript/inspector/src/base/base-export.h
  • NativeScript/inspector/src/base/bit-field.h
  • NativeScript/inspector/src/base/bits-iterator.h
  • NativeScript/inspector/src/base/bits.h
  • NativeScript/inspector/src/base/bounded-page-allocator.h
  • NativeScript/inspector/src/base/bounds.h
  • NativeScript/inspector/src/base/build_config.h
  • NativeScript/inspector/src/base/compiler-specific.h
  • NativeScript/inspector/src/base/cpu.h
  • NativeScript/inspector/src/base/division-by-constant.h
  • NativeScript/inspector/src/base/emulated-virtual-address-subspace.h
  • NativeScript/inspector/src/base/enum-set.h
  • NativeScript/inspector/src/base/export-template.h
  • NativeScript/inspector/src/base/file-utils.h
  • NativeScript/inspector/src/base/flags.h
  • NativeScript/inspector/src/base/free_deleter.h
  • NativeScript/inspector/src/base/functional.h
  • NativeScript/inspector/src/base/hashmap-entry.h
  • NativeScript/inspector/src/base/hashmap.h
  • NativeScript/inspector/src/base/ieee754.h
  • NativeScript/inspector/src/base/immediate-crash.h
  • NativeScript/inspector/src/base/iterator.h
  • NativeScript/inspector/src/base/lazy-instance.h
  • NativeScript/inspector/src/base/logging.h
  • NativeScript/inspector/src/base/macros.h
  • NativeScript/inspector/src/base/memory.h
  • NativeScript/inspector/src/base/once.h
  • NativeScript/inspector/src/base/optional.h
  • NativeScript/inspector/src/base/overflowing-math.h
  • NativeScript/inspector/src/base/page-allocator.h
  • NativeScript/inspector/src/base/platform/condition-variable.h
  • NativeScript/inspector/src/base/platform/elapsed-timer.h
  • NativeScript/inspector/src/base/platform/mutex.h
  • NativeScript/inspector/src/base/platform/platform-linux.h
  • NativeScript/inspector/src/base/platform/platform-posix-time.h
  • NativeScript/inspector/src/base/platform/platform-posix.h
  • NativeScript/inspector/src/base/platform/platform.h
  • NativeScript/inspector/src/base/platform/semaphore.h
  • NativeScript/inspector/src/base/platform/time.h
  • NativeScript/inspector/src/base/platform/wrappers.h
  • NativeScript/inspector/src/base/platform/yield-processor.h
  • NativeScript/inspector/src/base/pointer-with-payload.h
  • NativeScript/inspector/src/base/qnx-math.h
  • NativeScript/inspector/src/base/region-allocator.h
  • NativeScript/inspector/src/base/ring-buffer.h
  • NativeScript/inspector/src/base/safe_conversions.h
  • NativeScript/inspector/src/base/safe_conversions_arm_impl.h
  • NativeScript/inspector/src/base/safe_conversions_impl.h
  • NativeScript/inspector/src/base/small-vector.h
  • NativeScript/inspector/src/base/strings.h
  • NativeScript/inspector/src/base/sys-info.h
  • NativeScript/inspector/src/base/template-utils.h
  • NativeScript/inspector/src/base/threaded-list.h
  • NativeScript/inspector/src/base/timezone-cache.h
  • NativeScript/inspector/src/base/v8-fallthrough.h
  • NativeScript/inspector/src/base/vector.h
  • NativeScript/inspector/src/base/virtual-address-space-page-allocator.h
  • NativeScript/inspector/src/base/virtual-address-space.h
  • NativeScript/inspector/src/base/vlq-base64.h
  • NativeScript/inspector/src/base/vlq.h
  • NativeScript/inspector/src/base/win32-headers.h
  • NativeScript/inspector/src/common/allow-deprecated.h
  • NativeScript/inspector/src/common/assert-scope.h
  • NativeScript/inspector/src/common/checks.h
  • NativeScript/inspector/src/common/code-memory-access-inl.h
  • NativeScript/inspector/src/common/code-memory-access.h
  • NativeScript/inspector/src/common/globals.h
  • NativeScript/inspector/src/common/high-allocation-throughput-scope.h
  • NativeScript/inspector/src/common/message-template.h
  • NativeScript/inspector/src/common/operation.h
  • NativeScript/inspector/src/common/ptr-compr-inl.h
  • NativeScript/inspector/src/common/ptr-compr.h
  • NativeScript/inspector/src/debug/debug-coverage.h
  • NativeScript/inspector/src/debug/debug-evaluate.h
  • NativeScript/inspector/src/debug/debug-frames.h
  • NativeScript/inspector/src/debug/debug-interface.h
  • NativeScript/inspector/src/debug/debug-property-iterator.h
  • NativeScript/inspector/src/debug/debug-scope-iterator.h
  • NativeScript/inspector/src/debug/debug-scopes.h
  • NativeScript/inspector/src/debug/debug-stack-trace-iterator.h
  • NativeScript/inspector/src/debug/debug-type-profile.h
  • NativeScript/inspector/src/debug/debug-wasm-objects-inl.h
  • NativeScript/inspector/src/debug/debug-wasm-objects.h
  • NativeScript/inspector/src/debug/debug.h
  • NativeScript/inspector/src/debug/interface-types.h
  • NativeScript/inspector/src/debug/liveedit.h
  • NativeScript/inspector/src/inspector/custom-preview.h
  • NativeScript/inspector/src/inspector/injected-script.h
  • NativeScript/inspector/src/inspector/inspected-context.h
  • NativeScript/inspector/src/inspector/inspector_protocol_config.json
  • NativeScript/inspector/src/inspector/protocol/Console.h
  • NativeScript/inspector/src/inspector/protocol/Debugger.h
  • NativeScript/inspector/src/inspector/protocol/Forward.h
  • NativeScript/inspector/src/inspector/protocol/HeapProfiler.h
  • NativeScript/inspector/src/inspector/protocol/Profiler.h
  • NativeScript/inspector/src/inspector/protocol/Protocol.h
  • NativeScript/inspector/src/inspector/protocol/Runtime.h
  • NativeScript/inspector/src/inspector/protocol/Schema.h
  • NativeScript/inspector/src/inspector/protocol/base_string_adapter.h
  • NativeScript/inspector/src/inspector/remote-object-id.h
  • NativeScript/inspector/src/inspector/search-util.h
  • NativeScript/inspector/src/inspector/string-16.h
  • NativeScript/inspector/src/inspector/string-util.h
  • NativeScript/inspector/src/inspector/test-interface.h
  • NativeScript/inspector/src/inspector/v8-console-agent-impl.h
  • NativeScript/inspector/src/inspector/v8-console-message.h
  • NativeScript/inspector/src/inspector/v8-console.h
  • NativeScript/inspector/src/inspector/v8-debugger-agent-impl.h
  • NativeScript/inspector/src/inspector/v8-debugger-id.h
  • NativeScript/inspector/src/inspector/v8-debugger-script.h
  • NativeScript/inspector/src/inspector/v8-debugger.h
  • NativeScript/inspector/src/inspector/v8-heap-profiler-agent-impl.h
  • NativeScript/inspector/src/inspector/v8-inspector-impl.h
  • NativeScript/inspector/src/inspector/v8-inspector-session-impl.h
  • NativeScript/inspector/src/inspector/v8-profiler-agent-impl.h
  • NativeScript/inspector/src/inspector/v8-regex.h
  • NativeScript/inspector/src/inspector/v8-runtime-agent-impl.h
  • NativeScript/inspector/src/inspector/v8-schema-agent-impl.h
  • NativeScript/inspector/src/inspector/v8-stack-trace-impl.h
  • NativeScript/inspector/src/inspector/v8-string-conversions.h
  • NativeScript/inspector/src/inspector/v8-value-utils.h
  • NativeScript/inspector/src/inspector/v8-webdriver-serializer.h
  • NativeScript/inspector/src/inspector/value-mirror.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/cbor.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/dispatch.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/error_support.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/export.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/find_by_first.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/frontend_channel.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/glue.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/json.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/json_platform.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/maybe.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/parser_handler.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/protocol_core.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/serializable.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/span.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/status.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/status_test_support.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/test_platform.h
  • NativeScript/inspector/utils.mm
  • NativeScript/lib/arm64-iphoneos/libcppgc_base.a
  • NativeScript/lib/arm64-iphoneos/libcrdtp.a
  • NativeScript/lib/arm64-iphoneos/libcrdtp_platform.a
  • NativeScript/lib/arm64-iphoneos/libinspector.a
  • NativeScript/lib/arm64-iphoneos/libinspector_string_conversions.a
  • NativeScript/lib/arm64-iphoneos/libtorque_generated_definitions.a
  • NativeScript/lib/arm64-iphoneos/libtorque_generated_initializers.a
  • NativeScript/lib/arm64-iphoneos/libv8_base_without_compiler.a
  • NativeScript/lib/arm64-iphoneos/libv8_bigint.a
  • NativeScript/lib/arm64-iphoneos/libv8_compiler.a
  • NativeScript/lib/arm64-iphoneos/libv8_heap_base.a
  • NativeScript/lib/arm64-iphoneos/libv8_heap_base_headers.a
  • NativeScript/lib/arm64-iphoneos/libv8_libbase.a
  • NativeScript/lib/arm64-iphoneos/libv8_libplatform.a
  • NativeScript/lib/arm64-iphoneos/libv8_snapshot.a
  • NativeScript/lib/arm64-iphoneos/libzip.a
  • NativeScript/lib/arm64-iphonesimulator/libcppgc_base.a
  • NativeScript/lib/arm64-iphonesimulator/libcrdtp.a
  • NativeScript/lib/arm64-iphonesimulator/libcrdtp_platform.a
  • NativeScript/lib/arm64-iphonesimulator/libinspector.a
  • NativeScript/lib/arm64-iphonesimulator/libinspector_string_conversions.a
  • NativeScript/lib/arm64-iphonesimulator/libtorque_generated_definitions.a
  • NativeScript/lib/arm64-iphonesimulator/libtorque_generated_initializers.a
  • NativeScript/lib/arm64-iphonesimulator/libv8_base_without_compiler.a
  • NativeScript/lib/arm64-iphonesimulator/libv8_bigint.a
  • NativeScript/lib/arm64-iphonesimulator/libv8_compiler.a
  • NativeScript/lib/arm64-iphonesimulator/libv8_heap_base.a
  • NativeScript/lib/arm64-iphonesimulator/libv8_heap_base_headers.a
  • NativeScript/lib/arm64-iphonesimulator/libv8_libbase.a
  • NativeScript/lib/arm64-iphonesimulator/libv8_libplatform.a
  • NativeScript/lib/arm64-iphonesimulator/libv8_snapshot.a
  • NativeScript/lib/arm64-iphonesimulator/libzip.a
  • NativeScript/lib/arm64-maccatalyst/libcppgc_base.a
  • NativeScript/lib/arm64-maccatalyst/libcrdtp.a
  • NativeScript/lib/arm64-maccatalyst/libcrdtp_platform.a
  • NativeScript/lib/arm64-maccatalyst/libinspector.a
  • NativeScript/lib/arm64-maccatalyst/libinspector_string_conversions.a
  • NativeScript/lib/arm64-maccatalyst/libtorque_generated_definitions.a
  • NativeScript/lib/arm64-maccatalyst/libtorque_generated_initializers.a
  • NativeScript/lib/arm64-maccatalyst/libv8_base_without_compiler.a
  • NativeScript/lib/arm64-maccatalyst/libv8_bigint.a
  • NativeScript/lib/arm64-maccatalyst/libv8_compiler.a
  • NativeScript/lib/arm64-maccatalyst/libv8_heap_base.a
  • NativeScript/lib/arm64-maccatalyst/libv8_libbase.a
  • NativeScript/lib/arm64-maccatalyst/libv8_libplatform.a
  • NativeScript/lib/arm64-maccatalyst/libv8_snapshot.a
  • NativeScript/lib/arm64-maccatalyst/libzip.a
  • NativeScript/lib/arm64-xros/libcppgc_base.a
  • NativeScript/lib/arm64-xros/libcrdtp.a
  • NativeScript/lib/arm64-xros/libcrdtp_platform.a
  • NativeScript/lib/arm64-xros/libinspector.a
  • NativeScript/lib/arm64-xros/libinspector_string_conversions.a
  • NativeScript/lib/arm64-xros/libtorque_generated_definitions.a
  • NativeScript/lib/arm64-xros/libtorque_generated_initializers.a
  • NativeScript/lib/arm64-xros/libv8_base_without_compiler.a
  • NativeScript/lib/arm64-xros/libv8_bigint.a
  • NativeScript/lib/arm64-xros/libv8_compiler.a
  • NativeScript/lib/arm64-xros/libv8_heap_base.a
  • NativeScript/lib/arm64-xros/libv8_heap_base_headers.a
  • NativeScript/lib/arm64-xros/libv8_libbase.a
  • NativeScript/lib/arm64-xros/libv8_libplatform.a
  • NativeScript/lib/arm64-xros/libv8_snapshot.a
  • NativeScript/lib/arm64-xros/libzip.a
  • NativeScript/lib/arm64-xrsimulator/libcppgc_base.a
  • NativeScript/lib/arm64-xrsimulator/libcrdtp.a
  • NativeScript/lib/arm64-xrsimulator/libcrdtp_platform.a
  • NativeScript/lib/arm64-xrsimulator/libinspector.a
  • NativeScript/lib/arm64-xrsimulator/libinspector_string_conversions.a
  • NativeScript/lib/arm64-xrsimulator/libtorque_generated_definitions.a
  • NativeScript/lib/arm64-xrsimulator/libtorque_generated_initializers.a
  • NativeScript/lib/arm64-xrsimulator/libv8_base_without_compiler.a
  • NativeScript/lib/arm64-xrsimulator/libv8_bigint.a
  • NativeScript/lib/arm64-xrsimulator/libv8_compiler.a
  • NativeScript/lib/arm64-xrsimulator/libv8_heap_base.a
  • NativeScript/lib/arm64-xrsimulator/libv8_heap_base_headers.a
  • NativeScript/lib/arm64-xrsimulator/libv8_libbase.a
  • NativeScript/lib/arm64-xrsimulator/libv8_libplatform.a
  • NativeScript/lib/arm64-xrsimulator/libv8_snapshot.a
  • NativeScript/lib/arm64-xrsimulator/libzip.a
  • NativeScript/lib/x86_64-iphonesimulator/libcppgc_base.a
  • NativeScript/lib/x86_64-iphonesimulator/libcrdtp.a
  • NativeScript/lib/x86_64-iphonesimulator/libcrdtp_platform.a
  • NativeScript/lib/x86_64-iphonesimulator/libinspector.a
  • NativeScript/lib/x86_64-iphonesimulator/libinspector_string_conversions.a
  • NativeScript/lib/x86_64-iphonesimulator/libtorque_generated_definitions.a
  • NativeScript/lib/x86_64-iphonesimulator/libtorque_generated_initializers.a
  • NativeScript/lib/x86_64-iphonesimulator/libv8_base_without_compiler.a
  • NativeScript/lib/x86_64-iphonesimulator/libv8_bigint.a
  • NativeScript/lib/x86_64-iphonesimulator/libv8_compiler.a
  • NativeScript/lib/x86_64-iphonesimulator/libv8_heap_base.a
  • NativeScript/lib/x86_64-iphonesimulator/libv8_heap_base_headers.a
  • NativeScript/lib/x86_64-iphonesimulator/libv8_libbase.a
  • NativeScript/lib/x86_64-iphonesimulator/libv8_libplatform.a
  • NativeScript/lib/x86_64-iphonesimulator/libv8_snapshot.a
  • NativeScript/lib/x86_64-iphonesimulator/libzip.a
  • NativeScript/lib/x86_64-maccatalyst/libcppgc_base.a
  • NativeScript/lib/x86_64-maccatalyst/libtorque_generated_definitions.a
  • NativeScript/lib/x86_64-maccatalyst/libtorque_generated_initializers.a
  • NativeScript/lib/x86_64-maccatalyst/libv8_base_without_compiler.a
  • NativeScript/lib/x86_64-maccatalyst/libv8_bigint.a
  • NativeScript/lib/x86_64-maccatalyst/libv8_compiler.a
  • NativeScript/lib/x86_64-maccatalyst/libv8_heap_base.a
  • NativeScript/lib/x86_64-maccatalyst/libv8_libbase.a
  • NativeScript/lib/x86_64-maccatalyst/libv8_libplatform.a
  • NativeScript/lib/x86_64-maccatalyst/libv8_snapshot.a
  • NativeScript/lib/x86_64-maccatalyst/libzip.a
  • NativeScript/runtime/ArgConverter.h
  • NativeScript/runtime/ArgConverter.mm
  • NativeScript/runtime/Caches.h
  • NativeScript/runtime/ClassBuilder.h
  • NativeScript/runtime/ClassBuilder.mm
  • NativeScript/runtime/Console.cpp
  • NativeScript/runtime/ErrorEvents.cpp
  • NativeScript/runtime/Events.cpp
  • NativeScript/runtime/ExtVector.cpp
  • NativeScript/runtime/ExtVector.h
  • NativeScript/runtime/FunctionReference.cpp
  • NativeScript/runtime/Helpers.h
  • NativeScript/runtime/Helpers.mm
  • NativeScript/runtime/InlineFunctions.cpp
  • NativeScript/runtime/Interop.mm
  • NativeScript/runtime/InteropTypes.mm
  • NativeScript/runtime/Message.cpp
  • NativeScript/runtime/MetadataBuilder.h
  • NativeScript/runtime/MetadataBuilder.mm
  • NativeScript/runtime/ModuleInternal.h
  • NativeScript/runtime/ModuleInternal.mm
  • NativeScript/runtime/ModuleInternalCallbacks.h
  • NativeScript/runtime/ModuleInternalCallbacks.mm
  • NativeScript/runtime/NativeScriptException.mm
  • NativeScript/runtime/ObjectManager.h
  • NativeScript/runtime/ObjectManager.mm
  • NativeScript/runtime/Pointer.cpp
  • NativeScript/runtime/PromiseProxy.cpp
  • NativeScript/runtime/Reference.cpp
  • NativeScript/runtime/Reference.h
  • NativeScript/runtime/Runtime.mm
  • NativeScript/runtime/SymbolIterator.mm
  • NativeScript/runtime/TSHelpers.cpp
  • NativeScript/runtime/Timers.cpp
  • NativeScript/runtime/URLImpl.cpp
  • NativeScript/runtime/URLImpl.h
  • NativeScript/runtime/URLPatternImpl.cpp
  • NativeScript/runtime/URLSearchParamsImpl.cpp
  • NativeScript/runtime/URLSearchParamsImpl.h
  • NativeScript/runtime/UnmanagedType.mm
  • NativeScript/runtime/WeakRef.cpp
  • NativeScript/runtime/Worker.mm
  • NativeScript/runtime/WorkerWrapper.mm
  • NativeScript/v8runtime/HostProxy.cpp
  • NativeScript/v8runtime/HostProxy.h
  • NativeScript/v8runtime/V8Runtime.cpp
  • README.md
  • TestRunner/app/tests/Inheritance/InheritanceTests.js
  • V8_RELEASE
  • build_nativescript.sh
  • build_v8_source.sh
  • build_v8_source_catalyst.sh
  • docs/README.md
  • docs/knowledge/v8-14-migration.md
  • docs/knowledge/v8-resurrecting-finalizers.md
  • download_v8.sh
  • fetch_v8.sh
  • package.json
  • tools/v8/vendor_inspector_sources.py
  • v8ios.xcodeproj/project.pbxproj
💤 Files with no reviewable changes (251)
  • NativeScript/include/cppgc/README.md
  • NativeScript/inspector/src/base/sys-info.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/serializable.h
  • NativeScript/include/DIR_METADATA
  • NativeScript/inspector/src/base/bits.h
  • NativeScript/inspector/src/base/address-region.h
  • NativeScript/inspector/src/base/hashmap.h
  • NativeScript/include/js_protocol-1.3.json
  • NativeScript/inspector/src/base/logging.h
  • NativeScript/include/libplatform/DEPS
  • NativeScript/lib/arm64-iphonesimulator/libv8_heap_base_headers.a
  • NativeScript/include/cppgc/name-provider.h
  • NativeScript/include/cppgc/ephemeron-pair.h
  • NativeScript/include/cppgc/internal/compiler-specific.h
  • NativeScript/include/cppgc/internal/atomic-entry-flag.h
  • NativeScript/include/libplatform/libplatform-export.h
  • NativeScript/include/inspector/Runtime.h
  • NativeScript/include/cppgc/heap-state.h
  • NativeScript/inspector/src/base/v8-fallthrough.h
  • NativeScript/include/cppgc/custom-space.h
  • NativeScript/include/cppgc/internal/api-constants.h
  • NativeScript/include/cppgc/internal/caged-heap-local-data.h
  • NativeScript/inspector/src/inspector/custom-preview.h
  • NativeScript/include/cppgc/testing.h
  • NativeScript/include/cppgc/source-location.h
  • NativeScript/include/v8-embedder-state-scope.h
  • NativeScript/include/v8-json.h
  • NativeScript/include/cppgc/OWNERS
  • NativeScript/inspector/src/base/platform/platform-posix.h
  • NativeScript/lib/arm64-iphoneos/libv8_heap_base_headers.a
  • NativeScript/inspector/src/inspector/v8-debugger.h
  • NativeScript/inspector/src/inspector/protocol/HeapProfiler.h
  • NativeScript/inspector/src/base/bits-iterator.h
  • NativeScript/include/cppgc/platform.h
  • NativeScript/inspector/src/base/platform/yield-processor.h
  • NativeScript/inspector/src/base/enum-set.h
  • NativeScript/inspector/src/base/platform/elapsed-timer.h
  • NativeScript/inspector/src/base/virtual-address-space-page-allocator.h
  • NativeScript/lib/arm64-xrsimulator/libv8_heap_base_headers.a
  • NativeScript/include/OWNERS
  • NativeScript/inspector/src/base/page-allocator.h
  • NativeScript/inspector/src/inspector/v8-webdriver-serializer.h
  • NativeScript/inspector/src/base/file-utils.h
  • NativeScript/include/cppgc/internal/gc-info.h
  • NativeScript/include/v8-date.h
  • NativeScript/inspector/src/base/safe_conversions_impl.h
  • NativeScript/include/v8-microtask.h
  • NativeScript/inspector/src/base/platform/condition-variable.h
  • NativeScript/include/inspector/Debugger.h
  • NativeScript/include/v8-version.h
  • NativeScript/inspector/src/base/bounded-page-allocator.h
  • NativeScript/inspector/src/inspector/string-util.h
  • NativeScript/inspector/src/base/platform/platform-linux.h
  • NativeScript/inspector/src/common/allow-deprecated.h
  • NativeScript/include/cppgc/member.h
  • NativeScript/include/v8-wasm-trap-handler-posix.h
  • NativeScript/lib/x86_64-iphonesimulator/libv8_heap_base_headers.a
  • NativeScript/inspector/src/base/base-export.h
  • NativeScript/inspector/src/common/code-memory-access-inl.h
  • NativeScript/include/v8-debug.h
  • NativeScript/include/cppgc/sentinel-pointer.h
  • NativeScript/include/v8-value-serializer-version.h
  • NativeScript/inspector/src/base/overflowing-math.h
  • NativeScript/inspector/src/base/platform/platform-posix-time.h
  • fetch_v8.sh
  • NativeScript/inspector/src/debug/debug-property-iterator.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/parser_handler.h
  • NativeScript/include/cppgc/internal/finalizer-trait.h
  • NativeScript/inspector/src/base/free_deleter.h
  • NativeScript/include/v8-maybe.h
  • NativeScript/include/v8-external.h
  • NativeScript/include/cppgc/internal/pointer-policies.h
  • NativeScript/inspector/src/base/pointer-with-payload.h
  • NativeScript/inspector/src/debug/liveedit.h
  • NativeScript/include/v8-extension.h
  • NativeScript/include/v8.h
  • NativeScript/include/v8-memory-span.h
  • NativeScript/include/v8-data.h
  • NativeScript/include/cppgc/process-heap-statistics.h
  • NativeScript/include/cppgc/macros.h
  • NativeScript/inspector/src/base/division-by-constant.h
  • NativeScript/inspector/src/base/hashmap-entry.h
  • NativeScript/include/libplatform/v8-tracing.h
  • NativeScript/include/cppgc/liveness-broker.h
  • NativeScript/include/cppgc/heap-statistics.h
  • NativeScript/inspector/src/base/virtual-address-space.h
  • NativeScript/include/cppgc/heap.h
  • NativeScript/include/cppgc/internal/logging.h
  • NativeScript/inspector/src/base/iterator.h
  • NativeScript/inspector/src/base/flags.h
  • NativeScript/inspector/src/inspector/v8-string-conversions.h
  • NativeScript/include/cppgc/garbage-collected.h
  • NativeScript/include/v8-inspector-protocol.h
  • NativeScript/inspector/src/base/qnx-math.h
  • NativeScript/include/DEPS
  • NativeScript/inspector/src/base/threaded-list.h
  • NativeScript/inspector/src/base/memory.h
  • NativeScript/inspector/src/base/safe_conversions_arm_impl.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/test_platform.h
  • NativeScript/inspector/src/base/timezone-cache.h
  • NativeScript/include/v8-message.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/status_test_support.h
  • NativeScript/include/cppgc/explicit-management.h
  • NativeScript/inspector/src/base/atomic-utils.h
  • NativeScript/inspector/src/inspector/inspector_protocol_config.json
  • NativeScript/include/v8-microtask-queue.h
  • NativeScript/include/v8-cppgc.h
  • NativeScript/include/cppgc/DEPS
  • NativeScript/include/cppgc/default-platform.h
  • NativeScript/inspector/src/debug/debug-type-profile.h
  • NativeScript/inspector/src/inspector/protocol/Runtime.h
  • NativeScript/include/cppgc/object-size-trait.h
  • NativeScript/inspector/src/base/ring-buffer.h
  • NativeScript/include/v8-embedder-heap.h
  • NativeScript/inspector/src/inspector/v8-schema-agent-impl.h
  • NativeScript/include/cppgc/prefinalizer.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/frontend_channel.h
  • NativeScript/inspector/src/inspector/v8-console-agent-impl.h
  • NativeScript/inspector/src/inspector/protocol/base_string_adapter.h
  • NativeScript/include/v8-version-string.h
  • build_v8_source.sh
  • NativeScript/inspector/src/base/bit-field.h
  • NativeScript/inspector/src/base/export-template.h
  • NativeScript/include/libplatform/libplatform.h
  • NativeScript/inspector/src/debug/debug-stack-trace-iterator.h
  • NativeScript/inspector/src/inspector/protocol/Schema.h
  • NativeScript/include/v8-unwinder-state.h
  • NativeScript/inspector/src/inspector/v8-inspector-session-impl.h
  • NativeScript/inspector/src/base/template-utils.h
  • NativeScript/inspector/src/base/vlq-base64.h
  • NativeScript/inspector/src/inspector/v8-value-utils.h
  • NativeScript/inspector/src/debug/debug-wasm-objects.h
  • NativeScript/inspector/src/debug/debug-wasm-objects-inl.h
  • NativeScript/include/cppgc/common.h
  • NativeScript/inspector/src/base/bounds.h
  • NativeScript/inspector/src/inspector/v8-runtime-agent-impl.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/glue.h
  • NativeScript/inspector/src/debug/debug-scope-iterator.h
  • NativeScript/inspector/src/inspector/remote-object-id.h
  • NativeScript/inspector/src/inspector/test-interface.h
  • NativeScript/inspector/src/base/compiler-specific.h
  • NativeScript/include/cppgc/visitor.h
  • NativeScript/include/v8-callbacks.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/export.h
  • NativeScript/inspector/src/base/small-vector.h
  • NativeScript/include/v8-isolate.h
  • NativeScript/inspector/src/common/code-memory-access.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/span.h
  • NativeScript/inspector/src/base/build_config.h
  • NativeScript/include/v8config.h
  • NativeScript/inspector/src/base/platform/wrappers.h
  • NativeScript/inspector/src/base/emulated-virtual-address-subspace.h
  • NativeScript/include/v8-inspector.h
  • NativeScript/inspector/src/base/vlq.h
  • NativeScript/lib/arm64-xros/libv8_heap_base_headers.a
  • NativeScript/include/v8-array-buffer.h
  • build_v8_source_catalyst.sh
  • NativeScript/include/v8-wasm-trap-handler-win.h
  • NativeScript/inspector/src/base/lazy-instance.h
  • NativeScript/include/cppgc/allocation.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/json_platform.h
  • NativeScript/include/v8-value.h
  • NativeScript/include/cppgc/type-traits.h
  • NativeScript/inspector/src/common/checks.h
  • NativeScript/inspector/src/base/strings.h
  • NativeScript/inspector/src/base/once.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/maybe.h
  • NativeScript/inspector/src/inspector/v8-heap-profiler-agent-impl.h
  • package.json
  • NativeScript/inspector/src/inspector/v8-regex.h
  • NativeScript/inspector/src/base/vector.h
  • NativeScript/include/v8-snapshot.h
  • NativeScript/include/cppgc/internal/persistent-node.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/json.h
  • NativeScript/inspector/src/inspector/v8-stack-trace-impl.h
  • NativeScript/include/js_protocol.pdl
  • NativeScript/include/v8-unwinder.h
  • NativeScript/include/v8-exception.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/find_by_first.h
  • NativeScript/include/v8-template.h
  • NativeScript/include/cppgc/internal/name-trait.h
  • NativeScript/include/cppgc/trace-trait.h
  • NativeScript/include/v8-object.h
  • NativeScript/inspector/src/base/region-allocator.h
  • NativeScript/include/v8-metrics.h
  • NativeScript/include/cppgc/internal/write-barrier.h
  • NativeScript/include/cppgc/heap-consistency.h
  • NativeScript/include/v8-locker.h
  • NativeScript/include/v8-traced-handle.h
  • NativeScript/inspector/src/base/ieee754.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/cbor.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/protocol_core.h
  • NativeScript/inspector/src/debug/debug.h
  • NativeScript/inspector/src/inspector/v8-console.h
  • NativeScript/inspector/src/inspector/v8-profiler-agent-impl.h
  • NativeScript/inspector/src/inspector/value-mirror.h
  • NativeScript/inspector/src/inspector/v8-console-message.h
  • NativeScript/inspector/src/inspector/protocol/Protocol.h
  • NativeScript/inspector/src/inspector/protocol/Profiler.h
  • NativeScript/include/cppgc/cross-thread-persistent.h
  • NativeScript/inspector/src/inspector/v8-debugger-script.h
  • NativeScript/inspector/src/base/platform/semaphore.h
  • NativeScript/include/v8-initialization.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/error_support.h
  • NativeScript/inspector/src/base/functional.h
  • NativeScript/inspector/src/inspector/v8-debugger-id.h
  • NativeScript/include/cppgc/persistent.h
  • NativeScript/include/inspector/Schema.h
  • NativeScript/inspector/src/inspector/inspected-context.h
  • NativeScript/inspector/src/inspector/string-16.h
  • NativeScript/inspector/src/inspector/protocol/Debugger.h
  • NativeScript/inspector/src/base/safe_conversions.h
  • NativeScript/inspector/src/inspector/protocol/Console.h
  • NativeScript/include/v8-statistics.h
  • NativeScript/inspector/src/debug/debug-scopes.h
  • NativeScript/runtime/ModuleInternal.h
  • NativeScript/include/v8-function.h
  • NativeScript/inspector/src/base/cpu.h
  • NativeScript/inspector/src/base/immediate-crash.h
  • NativeScript/inspector/src/inspector/protocol/Forward.h
  • NativeScript/inspector/src/inspector/search-util.h
  • NativeScript/include/v8-typed-array.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/dispatch.h
  • NativeScript/include/v8-local-handle.h
  • NativeScript/inspector/src/common/assert-scope.h
  • NativeScript/inspector/src/debug/interface-types.h
  • NativeScript/inspector/src/base/optional.h
  • NativeScript/include/v8-context.h
  • NativeScript/include/v8-forward.h
  • NativeScript/inspector/src/inspector/v8-debugger-agent-impl.h
  • NativeScript/include/v8-script.h
  • NativeScript/include/v8-internal.h
  • NativeScript/include/v8-container.h
  • NativeScript/inspector/src/base/platform/mutex.h
  • NativeScript/include/v8-value-serializer.h
  • NativeScript/include/v8-fast-api-calls.h
  • NativeScript/include/v8-weak-callback-info.h
  • NativeScript/include/v8-wasm.h
  • NativeScript/inspector/src/base/win32-headers.h
  • NativeScript/inspector/third_party/inspector_protocol/crdtp/status.h
  • NativeScript/inspector/src/debug/debug-interface.h
  • NativeScript/inspector/src/base/platform/platform.h
  • NativeScript/include/v8-function-callback.h
  • NativeScript/include/js_protocol-1.2.json
  • NativeScript/inspector/src/base/atomicops.h
  • NativeScript/inspector/src/inspector/v8-inspector-impl.h
  • NativeScript/inspector/src/base/macros.h
  • NativeScript/inspector/src/inspector/injected-script.h
  • NativeScript/include/v8-util.h
  • NativeScript/include/APIDesign.md
  • NativeScript/inspector/src/base/platform/time.h

Comment on lines +193 to +198
Nothing blocking. Two follow-ups:

- Only `arm64-iphonesimulator` has been rebuilt; the other six architectures in
`NativeScript/lib` still hold 10.3 libraries.
- `DisposerPHV.{h,mm}` is now dead code -- `Isolate::VisitHandlesWithClassIds` no longer exists,
so the visitor can never be driven. Its logic moved to `ObjectManager::DisposeAllRegistered()`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Repository files of interest:"
git ls-files | rg '(^docs/knowledge/v8-14-migration.md$|download_v8\.sh$|NativeScript/lib|v8-14-migration|NativeScript)' || true

echo
echo "--- docs/knowledge/v8-14-migration.md relevant lines ---"
if [ -f docs/knowledge/v8-14-migration.md ]; then
  nl -ba docs/knowledge/v8-14-migration.md | sed -n '160,220p'
fi

echo
echo "--- NativeScript related files ---"
git ls-files | rg 'NativeScript/(lib|.*\.framework|.*\.dylib|.*\.so)|libNativeScript|NativeScript\.framework|Frameworks' || true

echo
echo "--- download_v8.sh if present ---"
if [ -f download_v8.sh ]; then
  nl -ba download_v8.sh | sed -n '1,220p'
fi

echo
echo "--- v8 version references ---"
rg -n "10\.3|14\.9|NativeScript/lib|arm64-iphonesimulator|iphonesimulator|iphoneos|iphoneos|device" docs/knowledge/v8-14-migration.md download_v8.sh 2>/dev/null || true

Repository: NativeScript/ios

Length of output: 2017


Resolve the remaining NativeScript/lib architecture artifacts before release.

The migration doc still lists six NativeScript/lib slices holding V8 10.3 libraries. If those slices are consumed or packaged, they can mix older 10.3 libraries with the newer V8 14.9 headers; rebuild, remove, or document that download_v8.sh replaces each supported slice.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/knowledge/v8-14-migration.md` around lines 193 - 198, Update the
migration documentation’s NativeScript/lib architecture follow-up to resolve all
six remaining V8 10.3 slices before release: rebuild or remove each supported
slice, or explicitly document that download_v8.sh replaces them. Ensure the
documented state no longer permits packaging older libraries alongside V8 14.9
headers.

Comment on lines +3 to +7
Status: **compiles**; runtime behaviour not yet exercised
Patch: [`v8_resurrecting_finalizers.patch`](v8_resurrecting_finalizers.patch) — 6 files, +175/-3,
against V8 **14.9.207.39** (`branch-heads/14.9`). The patch and the pinned
version live in [NativeScript/v8-buildscripts](https://github.com/NativeScript/v8-buildscripts).
Built clean for `arm64-iphonesimulator` (lite mode, no sandbox, no pointer compression).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Repository files matching target:"
fd -a 'v8-resurrecting-finalizers\.md|v8_resurrecting_finalizers\.patch' . || true

target="$(fd 'v8-resurrecting-finalizers\.md' . | head -n1 || true)"
patch="$(fd 'v8_resurrecting_finalizers\.patch' . | head -n1 || true)"

echo "target=$target"
echo "patch=$patch"

if [ -n "$target" ]; then
  echo "File size:"
  wc -l "$target"
  echo "--- first 80 lines ---"
  sed -n '1,180p' "$target" | nl -ba
fi

echo "--- related mentions ---"
rg -n "worker|teardown|resurrect|rearm|nested|young-generation|v8_resurrecting_finalizers|runtime" . -S \
  --glob '!node_modules' --glob '!dist' --glob '!build' 2>/dev/null | head -n 200

Repository: NativeScript/ios

Length of output: 2017


Run the finalizer runtime acceptance gate before merge.

The documented status and test listing still omit runtime validation. Compilation cannot validate GC invariants here; run the resurrect/rearm, nested-GC, young-generation, and worker tests against the patched V8, then update the status once the results are clear.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/knowledge/v8-resurrecting-finalizers.md` around lines 3 - 7, Run the
finalizer runtime acceptance tests against the patched V8, covering
resurrect/rearm, nested-GC, young-generation, and worker scenarios. Update the
documented Status and test listing in v8-resurrecting-finalizers.md to record
the runtime results, retaining the compilation status and clearly indicating any
failures or unresolved validation.

Comment on lines +137 to +140
3. **Resurrect-then-rearm, end to end.** A finalizer that re-arms N times then resets, across
repeated `--expose-gc` major GCs, under `--verify-heap`. Confirms the callback site, the
un-zapped slot through `MakeWeak`'s `CHECK_NE(object_, kGlobalHandleZapValue)`, and the
`CHECK_WITH_MSG` contract.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix the missing checklist item number.

The test plan jumps from item 1 to item 3; renumber “Resurrect-then-rearm” to item 2.

Proposed fix
-3. **Resurrect-then-rearm, end to end.**
+2. **Resurrect-then-rearm, end to end.**
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
3. **Resurrect-then-rearm, end to end.** A finalizer that re-arms N times then resets, across
repeated `--expose-gc` major GCs, under `--verify-heap`. Confirms the callback site, the
un-zapped slot through `MakeWeak`'s `CHECK_NE(object_, kGlobalHandleZapValue)`, and the
`CHECK_WITH_MSG` contract.
2. **Resurrect-then-rearm, end to end.** A finalizer that re-arms N times then resets, across
repeated `--expose-gc` major GCs, under `--verify-heap`. Confirms the callback site, the
un-zapped slot through `MakeWeak`'s `CHECK_NE(object_, kGlobalHandleZapValue)`, and the
`CHECK_WITH_MSG` contract.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/knowledge/v8-resurrecting-finalizers.md` around lines 137 - 140,
Renumber the “Resurrect-then-rearm, end to end” checklist entry from item 3 to
item 2 so the test plan numbering is sequential.

Comment thread download_v8.sh
Comment on lines +55 to +58
if [ "${V8_SKIP_DOWNLOAD:-0}" != "0" ]; then
echo "V8_SKIP_DOWNLOAD is set; leaving NativeScript/lib and the headers alone."
exit 0
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Keep inspector internals synchronized for local V8 builds.

Line 55 exits before the vendoring step. A local V8 build at another revision therefore compiles against stale NativeScript/inspector internals, despite the documented local-build workflow. Require local source/gen paths and rerun vendoring, or explicitly reject version-mismatched local builds.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@download_v8.sh` around lines 55 - 58, Update the V8_SKIP_DOWNLOAD early-exit
branch in download_v8.sh so local builds still synchronize
NativeScript/inspector internals: require the local source and generated paths
and rerun the vendoring step before exiting, or explicitly reject local builds
whose V8 revision does not match. Preserve the existing skip behavior only for
compatible, already-synchronized builds.

Comment on lines +55 to +59
if (offset >= ffiType->size) {
// Trying to access an element outside of the vector size
info.GetReturnValue().SetUndefined();
return v8::Intercepted::kYes;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Out-of-range reads now swallow ordinary lookup.

The old void getter fell through for offset >= ffiType->size, so V8 continued with the normal own/prototype lookup. Returning kYes with undefined intercepts the read instead — combined with the setter returning kNo (which lets V8 perform the ordinary store), an out-of-range index can be written but never read back. Returning kNo preserves the previous semantics and stays symmetric with the setter.

♻️ Preserve fall-through for out-of-range indices
   ffi_type* ffiType = extVectorWrapper->FFIType();
   if (offset >= ffiType->size) {
-    // Trying to access an element outside of the vector size
-    info.GetReturnValue().SetUndefined();
-    return v8::Intercepted::kYes;
+    // Outside of the vector size: not intercepted, let V8 perform the
+    // ordinary lookup (what the old void-returning callback did).
+    return v8::Intercepted::kNo;
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (offset >= ffiType->size) {
// Trying to access an element outside of the vector size
info.GetReturnValue().SetUndefined();
return v8::Intercepted::kYes;
}
if (offset >= ffiType->size) {
// Outside of the vector size: not intercepted, let V8 perform the
// ordinary lookup (what the old void-returning callback did).
return v8::Intercepted::kNo;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@NativeScript/runtime/ExtVector.cpp` around lines 55 - 59, Update the
out-of-range branch in the vector getter to return v8::Intercepted::kNo instead
of setting undefined and returning kYes, preserving V8’s normal own/prototype
lookup and matching the setter’s fall-through behavior.

Comment on lines 2406 to 2413
v8::Isolate* isolateInner = info.GetIsolate();
v8::HandleScope hs(isolateInner);
if (!info.Data()->IsExternal()) return;
auto* d = static_cast<FetchRetryData*>(info.Data().As<v8::External>()->Value());
auto* d = static_cast<FetchRetryData*>(
info.Data().As<v8::External>()->Value(v8::kExternalPointerTypeTagDefault));
v8::Local<v8::Context> ctx = isolateInner->GetCurrentContext();
v8::Local<v8::Promise::Resolver> res = d->resolver.Get(isolateInner);
v8::Local<v8::String> specLocal = d->spec.Get(isolateInner);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

These external-pointer updates sit in an unreachable block.

ImportModuleDynamicallyCallback already returns at Line 2347 whenever maybeModule.IsEmpty(), so the if (maybeModule.IsEmpty()) guard at Line 2364 — and the whole __nsHmrRequestModule fetch-retry path including the callbacks touched here — can never execute. Either hoist this retry before the early-return at Lines 2347-2360 or delete the dead path; migrating tags inside it gives a false sense of coverage.

Also applies to: 2449-2460, 2462-2475

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@NativeScript/runtime/ModuleInternalCallbacks.mm` around lines 2406 - 2413,
Remove the unreachable __nsHmrRequestModule fetch-retry path and its related
callbacks, including the code around ImportModuleDynamicallyCallback and the
external-pointer handling at the referenced sections, or hoist the retry logic
before the existing maybeModule.IsEmpty() early return so it can execute. Ensure
the chosen change eliminates the dead guard and preserves valid dynamic import
behavior.

Comment on lines +159 to +161
PointerWrapper* wrapper = static_cast<PointerWrapper*>(
info.This()->GetInternalField(0).As<External>()->Value(
v8::kExternalPointerTypeTagDefault));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Unchecked Local<Data> downcasts on internal fields. V8 13+ returns Local<Data> from GetInternalField, and both sites downcast with As<...>() without verifying the field actually holds the expected type — unchecked in release, a CHECK failure in debug.

  • NativeScript/runtime/Pointer.cpp#L159-L161: verify info.This() has an internal field holding an External (and that the resulting PointerWrapper* is non-null) before dereferencing wrapper->Data(); throw a TypeError otherwise, since the prototype methods are callable with an arbitrary receiver.
  • NativeScript/runtime/ObjectManager.mm#L159-L159: check superField->IsValue() before As<v8::Value>() when reading internal field 1.
📍 Affects 2 files
  • NativeScript/runtime/Pointer.cpp#L159-L161 (this comment)
  • NativeScript/runtime/ObjectManager.mm#L159-L159
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@NativeScript/runtime/Pointer.cpp` around lines 159 - 161, The PointerWrapper
retrieval in Pointer.cpp must validate that info.This() has an internal field
containing an External and that the resulting PointerWrapper* is non-null before
accessing its data; throw a TypeError for invalid receivers. In
ObjectManager.mm, validate superField->IsValue() before calling As<v8::Value>()
when reading internal field 1.

Comment on lines +27 to 29
Local<Value> symbolIteratorKey = Symbol::GetIterator(isolate);
success = object.As<Object>()->Set(context, symbolIteratorKey, iterator).FromMaybe(false);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

success is assigned and never checked.

A failed Symbol.iterator install is silently swallowed here, unlike every other Set in this file which asserts. Add the missing assertion.

🐛 Proposed fix
   Local<Value> symbolIteratorKey = Symbol::GetIterator(isolate);
   success = object.As<Object>()->Set(context, symbolIteratorKey, iterator).FromMaybe(false);
+  tns::Assert(success, isolate);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Local<Value> symbolIteratorKey = Symbol::GetIterator(isolate);
success = object.As<Object>()->Set(context, symbolIteratorKey, iterator).FromMaybe(false);
}
Local<Value> symbolIteratorKey = Symbol::GetIterator(isolate);
success = object.As<Object>()->Set(context, symbolIteratorKey, iterator).FromMaybe(false);
tns::Assert(success, isolate);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@NativeScript/runtime/SymbolIterator.mm` around lines 27 - 29, Update the
Symbol.iterator installation in the surrounding iterator setup to assert the
result of Set, matching the other Set calls in SymbolIterator.mm; do not leave
the assigned success value unchecked.

Comment on lines 67 to 90
Local<Value> UnmanagedType::TakeValue(const FunctionCallbackInfo<Value>& info, bool retained) {
Isolate* isolate = info.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
Isolate* isolate = info.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();

BaseDataWrapper* baseWrapper = tns::GetValue(isolate, info.This());
UnmanagedTypeWrapper* wrapper = static_cast<UnmanagedTypeWrapper*>(baseWrapper);

if (wrapper->ValueTaken()) {
throw NativeScriptException("Unmanaged value has already been consumed.");
}
BaseDataWrapper* baseWrapper = tns::GetValue(isolate, info.This());
UnmanagedTypeWrapper* wrapper = static_cast<UnmanagedTypeWrapper*>(baseWrapper);

uint8_t* data = wrapper->Data();
const TypeEncoding* typeEncoding = wrapper->TypeEncoding();
if (wrapper->ValueTaken()) {
throw NativeScriptException("Unmanaged value has already been consumed.");
}

BaseCall call((uint8_t*)&data);
Local<Value> result = Interop::GetResult(context, typeEncoding, &call, false);
uint8_t* data = wrapper->Data();
const TypeEncoding* typeEncoding = wrapper->TypeEncoding();

if (retained) {
id value = static_cast<id>((void*)data);
[value release];
}
BaseCall call((uint8_t*)&data);
Local<Value> result = Interop::GetResult(context, typeEncoding, &call, false);

return result;
}
if (retained) {
id value = static_cast<id>((void*)data);
[value release];
}

return result;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
fd -e h -e mm -e cpp | xargs rg -n 'ValueTaken|UnmanagedTypeWrapper' -A3 -B3

Repository: NativeScript/ios

Length of output: 2046


🏁 Script executed:

#!/bin/bash
set -u

printf 'PWD: %s\n' "$(pwd)"
printf '\nFiles matching UnmanagedType (case-insensitive name):\n'
fd -i 'UnmanagedType' . 2>/dev/null || true

printf '\nMatching symbols (ValueTaken/UnmanagedTypeWrapper) in tracked files:\n'
git ls-files '*.[hmmcpp]' 2>/dev/null | xargs -r rg -n 'ValueTaken|UnmanagedTypeWrapper|takeRetainedValue|SetValueTaken' -A4 -B4 || true

Repository: NativeScript/ios

Length of output: 2017


🌐 Web query:

NativeScript ios UnmanagedTypeWrapper ValueTaken TakeValue SetValueTaken UnmanagedType.mm

💡 Result:

In the NativeScript iOS runtime, UnmanagedTypeWrapper, ValueTaken, TakeValue, and SetValueTaken are internal implementation details related to the handling of unmanaged objects—specifically Core Foundation objects—that lack clear memory management annotations [1][2]. These terms are associated with the C++/Objective-C++ implementation of the NativeScript iOS runtime (specifically within files like UnmanagedType.mm or UnmanagedType.cpp in older versions of the runtime) [2]. The logic is designed to facilitate the conversion between native Core Foundation types and JavaScript-managed objects [1][2]. Key technical aspects include: 1. Handling Unmanaged Objects: When a native function returns a Core Foundation object without annotations indicating how it should be memory managed (e.g., whether it is retained or unretained), NativeScript wraps it in an Unmanaged type [1][3]. This places the responsibility on the developer to manage the object's lifecycle [1][4]. 2. Internal Methods: Methods such as takeValue, takeRetainedValue, and takeUnretainedValue are used to bridge these objects to JavaScript [2]. Specifically, takeRetainedValue returns the object and decrements the reference count (consuming the "unbalanced retain"), while takeUnretainedValue returns the object without altering the reference count [1][4]. 3. Implementation: Internally, logic within the runtime (historically referenced in PRs like #386 in the ios-runtime repository) uses helper methods to distinguish between these two states to ensure proper memory management behavior, such as calling [result release] when a value is "taken" in a retained context [2]. These internal wrappers ensure that NativeScript can safely interact with iOS APIs that do not adhere to standard Objective-C memory management rules, allowing developers to use JavaScript to interact with memory-sensitive C-based frameworks [1][2][4].

Citations:


🌐 Web query:

site:github.com/NativeScript/ios UnmanagedTypeWrapper.cpp SetValueTaken ValueTaken TakeValue

💡 Result:

Based on the available search results, there is no public technical documentation or specific code reference for a file named UnmanagedTypeWrapper.cpp containing the functions SetValueTaken, ValueTaken, or TakeValue. The search results for the NativeScript/ios repository, which frequently uses terms like UnmanagedType, Interop, and ObjectManager, do not reference these specific identifiers [1][2][3][4][5]. It is possible that these identifiers are part of a private codebase, a specific internal utility, or were misnamed in the query.

Citations:


Set the taken flag after consuming the unmanaged value.

TakeValue checks wrapper->ValueTaken() but never sets it in either path, so repeated takeRetainedValue() / takeUnretainedValue() calls would bypass the guard and double-release the retained Objective-C object. Mark the value consumed before returning, or track consumption in a shared path after Interop::GetResult.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@NativeScript/runtime/UnmanagedType.mm` around lines 67 - 90, Update
UnmanagedType::TakeValue to mark the wrapper as consumed after
Interop::GetResult completes, covering both retained and unretained paths before
returning. Preserve the existing ValueTaken guard and ensure the retained
release occurs only once.

Comment on lines +76 to +90
void URLImpl::Ctor(const v8::FunctionCallbackInfo<v8::Value>& args) {
auto count = args.Length();
auto value = args[0];
auto isolate = args.GetIsolate();
auto context = isolate->GetCurrentContext();
if (count >= 1 && !value->IsString()) {
isolate->ThrowException(v8::Exception::TypeError(ToV8String(isolate, "")));
return;
}

url_aggregator url;

auto url_string = tns::ToString(isolate, args[0].As<v8::String>());

if (count > 1) {
if (args[1]->IsString()) {
auto base_string = tns::ToString(isolate, args[1].As<v8::String>());
std::string_view base_string_view(base_string.data(), base_string.length());

if (!can_parse(url_string, &base_string_view)) {
isolate->ThrowException(
v8::Exception::TypeError(ToV8String(isolate, "")));
return;
}
auto base_url = ada::parse<ada::url_aggregator>(base_string_view, nullptr);

auto result = ada::parse<ada::url_aggregator>(url_string, &base_url.value());

if (result) {
url = result.value();
} else {
isolate->ThrowException(
v8::Exception::TypeError(ToV8String(isolate, "")));
return;
}
} else if (args[1]->IsObject()) {
auto base_string = tns::ToString(isolate,
args[1]->ToString(context).ToLocalChecked());
std::string_view base_string_view(base_string.data(), base_string.length());
if (!can_parse(std::string_view(url_string.data(), url_string.length()),
&base_string_view)) {
isolate->ThrowException(
v8::Exception::TypeError(ToV8String(isolate, "")));
return;
}


auto base_url = ada::parse<ada::url_aggregator>(base_string_view, nullptr);

auto result = ada::parse<ada::url_aggregator>(url_string, &base_url.value());

if (result) {
url = result.value();
} else {
isolate->ThrowException(
v8::Exception::TypeError(ToV8String(isolate, "")));
return;
}
} else {
// treat 2nd arg as undefined otherwise.
auto result = ada::parse<ada::url_aggregator>(url_string, nullptr);
if (result) {
url = result.value();
} else {
isolate->ThrowException(
v8::Exception::TypeError(ToV8String(isolate, "")));
return;
}
}
} else {
auto result = ada::parse<ada::url_aggregator>(url_string, nullptr);
if (result) {
url = result.value();
} else {
isolate->ThrowException(
v8::Exception::TypeError(ToV8String(isolate, "")));
return;
}
url_aggregator url;

}
auto url_string = tns::ToString(isolate, args[0].As<v8::String>());

auto ret = args.This();
if (count > 1) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Unchecked .As<v8::String>() cast on missing/non-string arguments.

In Ctor, when count == 0 the count >= 1 && !value->IsString() guard is skipped, so args[0] (Undefined) still gets .As<v8::String>()-cast and passed to tns::ToString. CanParse has the same problem: info[0]/info[1] are cast unconditionally without an IsString() check. .As<T>() performs no runtime type check, so calling String-specific accessors on an Undefined/non-String handle is undefined behavior — reachable via plain new URL() or URL.canParse(). URLPatternImpl::Ctor and URLSearchParamsImpl::Ctor both handle the zero-argument case safely; URLImpl does not.

🐛 Proposed fix
   auto count = args.Length();
   auto value = args[0];
   auto isolate = args.GetIsolate();
   auto context = isolate->GetCurrentContext();
-  if (count >= 1 && !value->IsString()) {
+  if (count < 1 || !value->IsString()) {
     isolate->ThrowException(v8::Exception::TypeError(ToV8String(isolate, "")));
     return;
   }
 void URLImpl::CanParse(const v8::FunctionCallbackInfo<v8::Value>& info) {
   bool value;
   auto count = info.Length();
-
   auto isolate = info.GetIsolate();
-  if (count > 1) {
+  if (count < 1 || !info[0]->IsString() ||
+      (count > 1 && !info[1]->IsString())) {
+    value = false;
+  } else if (count > 1) {
     auto url_string = tns::ToString(isolate, info[0].As<v8::String>());
     auto base_string = tns::ToString(isolate, info[1].As<v8::String>());
     std::string_view base_string_view(base_string.data(), base_string.length());
     value = can_parse(url_string, &base_string_view);
   } else {
     value = can_parse(tns::ToString(isolate, info[0].As<v8::String>()).c_str(),
                       nullptr);
   }

Also applies to: 474-490

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@NativeScript/runtime/URLImpl.cpp` around lines 76 - 90, Update URLImpl::Ctor
to handle count == 0 before accessing args[0], and only call tns::ToString after
confirming the argument is a string; preserve the existing TypeError behavior
for present non-string values. Apply the same validation to URLImpl::CanParse
for info[0] and info[1], avoiding unchecked .As<v8::String>() casts and
preserving its expected behavior for omitted arguments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant