Skip to content

perf(android): build nested UInt64 arrays directly in JNI - #2008

Open
mrousavy wants to merge 1 commit into
mrousavy/v1-kotlin-erased-ulongfrom
mrousavy/v1-kotlin-nested-ulongarray
Open

mrousavy wants to merge 1 commit into
mrousavy/v1-kotlin-erased-ulongfrom
mrousavy/v1-kotlin-nested-ulongarray

Conversation

@mrousavy

@mrousavy mrousavy commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

Fourth of five stacked PRs: #1997 → #1998 → #1999 → #2008 (this one) → #2009.

UInt64[][] is an Array<ULongArray> in Kotlin. Its JVM class names kotlin.ULongArray, which JNI can't name (see #1999), so it crossed as an Array<LongArray> and Kotlin mapped it on every crossing, creating one ULongArray box per row.

JNI now builds it itself. It creates the ULongArray[] with the class from ULongBox, puts each row's long[] into a box with AllocObject and the box's field, and reads rows back the same way, both for C++ values and straight from JS. JNI signatures declare the array as an Object[] (JULongArrays), so the Kotlin bridges take an Array<*> and cast it back with @Suppress("UNCHECKED_CAST"), which always holds since JNI created a ULongArray[]. Struct getters return the field as is. Arrays nested more than two levels deep still map their outer levels in Kotlin.

Generated structs compared these fields through the JNI conversion, which is now a cast. Types give structs an equality value instead (getKotlinEqualityValue() replaces isKotlinEqualityCompatible), so the generated equals() and hashCode() are unchanged.

New TestObject methods pass UInt64[][] as a Promise result and through a callback.

Validation: Kotlin compiles without warnings, and every generated JNI source of nitro-test and nitro-test-external compiles with the NDK. I did not run the runtime tests locally.

🤖 Generated with Claude Code

UInt64[][] is an Array<ULongArray> in Kotlin, and its JVM class names
kotlin.ULongArray, which JNI cannot name. It crossed as an
Array<LongArray>, so Kotlin mapped it on every crossing and created a
ULongArray box for each row.

JNI now creates the ULongArray[] itself with the class from ULongBox,
puts each row's long[] in a box with AllocObject and the box's field,
and reads rows the same way. JNI signatures declare the array as an
Object[], so Kotlin bridges take an Array<*> and cast it back without
copying. Struct getters return the field as it is.

Structs compared these fields through the JNI conversion, which is now
a cast. Types give structs an equality value instead, so the generated
equals() and hashCode() are unchanged.

Arrays nested more than two levels deep still map their outer levels in
Kotlin.

New TestObject methods pass UInt64[][] as a Promise result and through
a callback.
@vercel

vercel Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
nitro-docs Skipped Skipped Oct 23, 2026 6:13pm UTC

Request Review

This branch was previously deployed

1 inactive deployment
Preview — 1619ee71 Deployed Oct 23, 2026 by vercel[bot]
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