Skip to content

Fix iOS build of method refs needing unbox/box + add Objects.deepEquals#5150

Merged
shai-almog merged 1 commit into
masterfrom
fix-lambda-unbox-and-objects-deepequals
Jun 2, 2026
Merged

Fix iOS build of method refs needing unbox/box + add Objects.deepEquals#5150
shai-almog merged 1 commit into
masterfrom
fix-lambda-unbox-and-objects-deepequals

Conversation

@shai-almog
Copy link
Copy Markdown
Collaborator

Fixes two issues reported building CodeRAD apps for iOS (r/cn1, 7.0.225+: "Cannot build for iOS with CodeRAD on latest versions").

1. Method references needing box/unbox/widen/cast broke the Xcode build

A method reference whose implementation signature differs from the functional interface's failed to compile in the generated Xcode project. The reporter's case — obj::setSomeValue where setSomeValue(double) bound to a Consumer<Double>:

error: passing 'JAVA_OBJECT' to parameter of incompatible type 'JAVA_DOUBLE'

ParparVM consumes invokedynamic directly and synthesizes the lambda adapter class itself in Parser.visitInvokeDynamicInsn. It loaded each SAM argument verbatim and invoked the target method directly, with no adaptation between the SAM signature and the implementation method signature. The real LambdaMetafactory is required to box/unbox/widen/cast there, so a Double reached a primitive double parameter and the generated C did not compile.

The adapter now replicates that adaptation for every argument and the return value:

  • unbox (with a CHECKCAST to the wrapper when the SAM type is erased to Object, e.g. generic functional interfaces),
  • box via valueOf,
  • primitive widening/narrowing,
  • reference checkcast (generic erasure).

Lambdas and same-signature method references hit the identity path and are unchanged.

2. Objects.deepEquals missing from the iOS runtime

CodeRAD's ButtonListPropertyView calls java.util.Objects.deepEquals, which the iOS runtime (vm/JavaAPI) didn't provide, producing call to undeclared function java_util_Objects_deepEquals___.... Added it, faithful to the JDK's deepEquals0 (dispatch to the matching Arrays.equals/Arrays.deepEquals overload by array element type, else a.equals(b)).

Testing

LambdaIntegrationTest gains adaptsBoxingUnboxingInMethodReferences, which compiles Java → translates → builds the generated C with clang → runs it, covering unbox, erased-generic unbox, return boxing, and intlong widening.

  • Pre-fix: reproduces error: passing 'JAVA_OBJECT' ... incompatible type 'JAVA_DOUBLE'.
  • Post-fix: both lambda tests pass (RESULT=73, RESULT=145); StreamApiIntegrationTest (heavy generic-lambda boxing) still passes — no regression.

🤖 Generated with Claude Code

Two issues reported building CodeRAD apps for iOS (r/cn1):

1. Method references whose implementation signature differs from the
   functional interface's failed to compile in the generated Xcode
   project, e.g. `obj::setSomeValue` (setSomeValue(double)) bound to a
   Consumer<Double>:

     error: passing 'JAVA_OBJECT' to parameter of incompatible type
     'JAVA_DOUBLE'

   ParparVM consumes invokedynamic directly and synthesizes the lambda
   adapter class itself in Parser.visitInvokeDynamicInsn. It loaded each
   SAM argument verbatim and invoked the target method directly, with no
   adaptation between the SAM signature and the implementation method
   signature. The real LambdaMetafactory is required to box/unbox/widen/
   cast there, so a Double object reached a primitive double parameter.

   The adapter now replicates that adaptation for every argument and the
   return value: unbox (with a CHECKCAST to the wrapper when the SAM type
   is erased to Object), box via valueOf, primitive widening/narrowing,
   and reference checkcast. Lambdas and same-signature method references
   hit the identity path and are unchanged.

2. java.util.Objects.deepEquals was missing from the iOS runtime, so
   callers such as CodeRAD's ButtonListPropertyView produced a call to an
   undeclared C function. Added it, faithful to the JDK's deepEquals0
   (dispatch to the matching Arrays.equals/deepEquals overload by array
   element type, else a.equals(b)).

LambdaIntegrationTest gains adaptsBoxingUnboxingInMethodReferences, which
compiles -> translates -> builds the generated C with clang -> runs it,
covering unbox, erased-generic unbox, return boxing and int->long
widening. Reproduces the compile error pre-fix; passes post-fix.
StreamApiIntegrationTest (heavy generic-lambda boxing) still passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

✅ Continuous Quality Report

Test & Coverage

Static Analysis

  • SpotBugs [Report archive]
    • ByteCodeTranslator: 0 findings (no issues)
    • android: 0 findings (no issues)
    • codenameone-maven-plugin: 0 findings (no issues)
    • core-unittests: 0 findings (no issues)
    • ios: 0 findings (no issues)
  • PMD: 0 findings (no issues) [Report archive]
  • Checkstyle: 0 findings (no issues) [Report archive]

Generated automatically by the PR CI workflow.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

✅ ByteCodeTranslator Quality Report

Test & Coverage

  • Tests: 716 total, 0 failed, 3 skipped

Benchmark Results

  • Execution Time: 7327 ms

  • Hotspots (Top 20 sampled methods):

    • 23.81% com.codename1.tools.translator.Parser.isMethodUsed (289 samples)
    • 20.26% java.lang.String.indexOf (246 samples)
    • 6.34% java.lang.Object.hashCode (77 samples)
    • 5.68% com.codename1.tools.translator.Parser.addToConstantPool (69 samples)
    • 5.60% java.util.ArrayList.indexOf (68 samples)
    • 5.02% com.codename1.tools.translator.BytecodeMethod.addToConstantPool (61 samples)
    • 2.64% java.lang.System.identityHashCode (32 samples)
    • 2.39% com.codename1.tools.translator.ByteCodeClass.calcUsedByNative (29 samples)
    • 1.89% com.codename1.tools.translator.ByteCodeClass.updateAllDependencies (23 samples)
    • 1.81% com.codename1.tools.translator.ByteCodeClass.markDependent (22 samples)
    • 1.73% com.codename1.tools.translator.Parser.generateClassAndMethodIndexHeader (21 samples)
    • 1.48% com.codename1.tools.translator.Parser.cullMethods (18 samples)
    • 1.48% java.lang.StringBuilder.append (18 samples)
    • 1.24% com.codename1.tools.translator.BytecodeMethod.appendMethodSignatureSuffixFromDesc (15 samples)
    • 0.99% com.codename1.tools.translator.BytecodeMethod.appendCMethodPrefix (12 samples)
    • 0.82% com.codename1.tools.translator.BytecodeMethod.isMethodUsedByNative (10 samples)
    • 0.74% java.io.FileOutputStream.open0 (9 samples)
    • 0.66% sun.nio.ch.NativeThread.current (8 samples)
    • 0.66% java.lang.StringCoding.encode (8 samples)
    • 0.58% com.codename1.tools.translator.BytecodeMethod.optimize (7 samples)
  • ⚠️ Coverage report not generated.

Static Analysis

  • ✅ SpotBugs: no findings (report was not generated by the build).
  • ⚠️ PMD report not generated.
  • ⚠️ Checkstyle report not generated.

Generated automatically by the PR CI workflow.

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented Jun 2, 2026

Compared 122 screenshots: 122 matched.
✅ Native Mac screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 102 seconds

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 852.000 ms
Base64 CN1 encode 1423.000 ms
Base64 encode ratio (CN1/native) 1.670x (67.0% slower)
Base64 native decode 506.000 ms
Base64 CN1 decode 1151.000 ms
Base64 decode ratio (CN1/native) 2.275x (127.5% slower)
Base64 SIMD encode 453.000 ms
Base64 encode ratio (SIMD/native) 0.532x (46.8% faster)
Base64 encode ratio (SIMD/CN1) 0.318x (68.2% faster)
Base64 SIMD decode 431.000 ms
Base64 decode ratio (SIMD/native) 0.852x (14.8% faster)
Base64 decode ratio (SIMD/CN1) 0.374x (62.6% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 69.000 ms
Image createMask (SIMD on) 10.000 ms
Image createMask ratio (SIMD on/off) 0.145x (85.5% faster)
Image applyMask (SIMD off) 192.000 ms
Image applyMask (SIMD on) 100.000 ms
Image applyMask ratio (SIMD on/off) 0.521x (47.9% faster)
Image modifyAlpha (SIMD off) 205.000 ms
Image modifyAlpha (SIMD on) 109.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.532x (46.8% faster)
Image modifyAlpha removeColor (SIMD off) 243.000 ms
Image modifyAlpha removeColor (SIMD on) 113.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.465x (53.5% faster)
Image PNG encode (SIMD off) 1117.000 ms
Image PNG encode (SIMD on) 911.000 ms
Image PNG encode ratio (SIMD on/off) 0.816x (18.4% faster)
Image JPEG encode 1272.000 ms

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented Jun 2, 2026

Compared 122 screenshots: 122 matched.
✅ Native iOS Metal screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 320 seconds

Build and Run Timing

Metric Duration
Simulator Boot 106000 ms
Simulator Boot (Run) 1000 ms
App Install 17000 ms
App Launch 9000 ms
Test Execution 281000 ms

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 1334.000 ms
Base64 CN1 encode 2200.000 ms
Base64 encode ratio (CN1/native) 1.649x (64.9% slower)
Base64 native decode 544.000 ms
Base64 CN1 decode 1494.000 ms
Base64 decode ratio (CN1/native) 2.746x (174.6% slower)
Base64 SIMD encode 564.000 ms
Base64 encode ratio (SIMD/native) 0.423x (57.7% faster)
Base64 encode ratio (SIMD/CN1) 0.256x (74.4% faster)
Base64 SIMD decode 624.000 ms
Base64 decode ratio (SIMD/native) 1.147x (14.7% slower)
Base64 decode ratio (SIMD/CN1) 0.418x (58.2% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 119.000 ms
Image createMask (SIMD on) 15.000 ms
Image createMask ratio (SIMD on/off) 0.126x (87.4% faster)
Image applyMask (SIMD off) 206.000 ms
Image applyMask (SIMD on) 93.000 ms
Image applyMask ratio (SIMD on/off) 0.451x (54.9% faster)
Image modifyAlpha (SIMD off) 201.000 ms
Image modifyAlpha (SIMD on) 188.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.935x (6.5% faster)
Image modifyAlpha removeColor (SIMD off) 273.000 ms
Image modifyAlpha removeColor (SIMD on) 104.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.381x (61.9% faster)
Image PNG encode (SIMD off) 2027.000 ms
Image PNG encode (SIMD on) 1231.000 ms
Image PNG encode ratio (SIMD on/off) 0.607x (39.3% faster)
Image JPEG encode 1122.000 ms

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented Jun 2, 2026

Compared 122 screenshots: 122 matched.
✅ Native iOS screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 158 seconds

Build and Run Timing

Metric Duration
Simulator Boot 57000 ms
Simulator Boot (Run) 1000 ms
App Install 10000 ms
App Launch 3000 ms
Test Execution 288000 ms

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 660.000 ms
Base64 CN1 encode 1201.000 ms
Base64 encode ratio (CN1/native) 1.820x (82.0% slower)
Base64 native decode 300.000 ms
Base64 CN1 decode 873.000 ms
Base64 decode ratio (CN1/native) 2.910x (191.0% slower)
Base64 SIMD encode 372.000 ms
Base64 encode ratio (SIMD/native) 0.564x (43.6% faster)
Base64 encode ratio (SIMD/CN1) 0.310x (69.0% faster)
Base64 SIMD decode 375.000 ms
Base64 decode ratio (SIMD/native) 1.250x (25.0% slower)
Base64 decode ratio (SIMD/CN1) 0.430x (57.0% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 59.000 ms
Image createMask (SIMD on) 27.000 ms
Image createMask ratio (SIMD on/off) 0.458x (54.2% faster)
Image applyMask (SIMD off) 118.000 ms
Image applyMask (SIMD on) 50.000 ms
Image applyMask ratio (SIMD on/off) 0.424x (57.6% faster)
Image modifyAlpha (SIMD off) 114.000 ms
Image modifyAlpha (SIMD on) 55.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.482x (51.8% faster)
Image modifyAlpha removeColor (SIMD off) 152.000 ms
Image modifyAlpha removeColor (SIMD on) 82.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.539x (46.1% faster)
Image PNG encode (SIMD off) 917.000 ms
Image PNG encode (SIMD on) 760.000 ms
Image PNG encode ratio (SIMD on/off) 0.829x (17.1% faster)
Image JPEG encode 405.000 ms

@shai-almog shai-almog merged commit 1326add into master Jun 2, 2026
24 of 26 checks passed
@shai-almog shai-almog deleted the fix-lambda-unbox-and-objects-deepequals branch June 2, 2026 18:30
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