Skip to content

Comments

refactor: enhance Java closure return value bridging#103

Merged
marcprux merged 2 commits intoskiptools:mainfrom
theleftbit:fix-protocol-crash
Feb 18, 2026
Merged

refactor: enhance Java closure return value bridging#103
marcprux merged 2 commits intoskiptools:mainfrom
theleftbit:fix-protocol-crash

Conversation

@piercifani
Copy link
Contributor

@piercifani piercifani commented Feb 17, 2026

Improve return value bridging logic in JavaBackedClosure class to better support various Swift types. Add a method to retrieve a protocol bridge implementation type and gracefully handle unbridgeable types with a descriptive fatal error. This change ensures robust bridging of Java closures to their Swift representation, enhancing reliability and handling edge cases more effectively.

Skip Pull Request Checklist:

  • REQUIRED: I have signed the Contributor Agreement
  • REQUIRED: I have tested my change locally with swift test
  • OPTIONAL: I have tested my change on an iOS simulator or device
  • OPTIONAL: I have tested my change on an Android emulator or device

  • AI was used to generate or assist with generating this PR. Please specify below how you used AI to help you, and what steps you have taken to manually verify the changes.

After finding this crash:

18:56:02.972  A  pid: 12453, tid: 12500, name: Thread-24  >>> com.foobar.android.debug <<<
18:56:02.972  A        #00 pc 000000000004c490  /data/app/~~BdRXBaMTPAUBPvI2a0GerQ==/com.foobar.android.debug-Rr3-jrjRXm9QmzCEtT3Ohw==/base.apk (offset 0x1f04000) ($s10SkipBridge17JavaBackedClosureC11returnValue33_ECCB923B676FE01F3F4E3CE54BC9A500LL3forxSvSg_tF+228) (BuildId: 2f2b07b8366f2ad68054dbdd05c0bf1bc104fcd8)
18:56:02.972  A        #01 pc 000000000004cef8  /data/app/~~BdRXBaMTPAUBPvI2a0GerQ==/com.foobar.android.debug-Rr3-jrjRXm9QmzCEtT3Ohw==/base.apk (offset 0x1f04000) ($s10SkipBridge17JavaBackedClosureC6invokeyxypSg_AEtKFxyKXEfU_+224) (BuildId: 2f2b07b8366f2ad68054dbdd05c0bf1bc104fcd8)
18:56:02.972  A        #02 pc 0000000000059400  /data/app/~~BdRXBaMTPAUBPvI2a0GerQ==/com.foobar.android.debug-Rr3-jrjRXm9QmzCEtT3Ohw==/base.apk (offset 0x1f04000) ($s10SkipBridge17JavaBackedClosureC6invokeyxypSg_AEtKFxyKXEfU_TA+16) (BuildId: 2f2b07b8366f2ad68054dbdd05c0bf1bc104fcd8)
18:56:02.972  A        #03 pc 000000000003bfd8  /data/app/~~BdRXBaMTPAUBPvI2a0GerQ==/com.foobar.android.debug-Rr3-jrjRXm9QmzCEtT3Ohw==/base.apk (offset 0x1df4000) ($s8SwiftJNI10jniContextyxxyKXEKlF+196) (BuildId: bf13f0762a1bcecc9b8cd414fd8b4eb6fa669d5a)
18:56:02.972  A        #04 pc 000000000004f0e8  /data/app/~~BdRXBaMTPAUBPvI2a0GerQ==/com.foobar.android.debug-Rr3-jrjRXm9QmzCEtT3Ohw==/base.apk (offset 0x1f04000) ($s10SkipBridge13SwiftClosure2C7closure13forJavaObject7optionsq0_x_q_tYbcSgSvSg_0C3JNI19JConvertibleOptionsVtr1_lFZq0_x_q_tYbcfU0_+160) (BuildId: 2f2b07b8366f2ad68054dbdd05c0bf1bc104fcd8)
18:56:02.972  A        #05 pc 0000000000b27154  /data/app/~~BdRXBaMTPAUBPvI2a0GerQ==/com.foobar.android.debug-Rr3-jrjRXm9QmzCEtT3Ohw==/base.apk (offset 0x13528000) ($s20FoundationEssentials3URLVSDyS2SG10AppClients12WSConnection_pIeghnnr_AcdeF_pIeghggr_TRTATm+36) (BuildId: ec9f5f582d0ff4bb58d629b0d6789e69bf8eb5fe)
18:56:02.972  A        #06 pc 0000000000b23aec  /data/app/~~BdRXBaMTPAUBPvI2a0GerQ==/com.foobar.android.debug-Rr3-jrjRXm9QmzCEtT3Ohw==/base.apk (offset 0x13528000) ($s10AppClients19WSConnectionFactoryV15createWebSocketAcA0C0_p20FoundationEssentials3URLV_SDyS2SGtc_tcfcAaE_p0H10Networking10URLRequestVcfU_+96) (BuildId: ec9f5f582d0ff4bb58d629b0d6789e69bf8eb5fe)
18:56:02.972  A        #07 pc 00000000011076bc  /data/app/~~BdRXBaMTPAUBPvI2a0GerQ==/com.foobar.android.debug-Rr3-jrjRXm9QmzCEtT3Ohw==/base.apk (offset 0x13528000) ($s19LiveClientWebSocketAAC16createConnection33_F3B18F77F7BA9FD67E7D4203B0FE3294LL10AppClients12WSConnection_p11sessionTask_ScTyyts5NeverOG06listenU0AA13WSPingHandlerCSg04pingY0tyYaKFTY0_+388) (BuildId: ec9f5f582d0ff4bb58d629b0d6789e69bf8eb5fe)
18:56:02.972  A        #08 pc 00000000000957e0  /data/app/~~BdRXBaMTPAUBPvI2a0GerQ==/com.foobar.android.debug-Rr3-jrjRXm9QmzCEtT3Ohw==/base.apk!libswift_Concurrency.so (offset 0x10c0000) (swift::runJobInEstablishedExecutorContext(swift::Job*)+384) (BuildId: 2d101391dcbcc79589bd34cf02e0e8a5beee6542)
18:56:02.972  A        #09 pc 00000000000964ec  /data/app/~~BdRXBaMTPAUBPvI2a0GerQ==/com.foobar.android.debug-Rr3-jrjRXm9QmzCEtT3Ohw==/base.apk!libswift_Concurrency.so (offset 0x10c0000) (swift_job_run+160) (BuildId: 2d101391dcbcc79589bd34cf02e0e8a5beee6542)
18:56:02.972  A        #10 pc 0000000000036fa4  /data/app/~~BdRXBaMTPAUBPvI2a0GerQ==/com.foobar.android.debug-Rr3-jrjRXm9QmzCEtT3Ohw==/base.apk!libdispatch.so (offset 0x7d0000) (_dispatch_continuation_pop+224) (BuildId: 4d2f67b08e52299f862d8f694d06077377cc0d34)
18:56:02.972  A        #11 pc 0000000000036de8  /data/app/~~BdRXBaMTPAUBPvI2a0GerQ==/com.foobar.android.debug-Rr3-jrjRXm9QmzCEtT3Ohw==/base.apk!libdispatch.so (offset 0x7d0000) (_dispatch_async_redirect_invoke+172) (BuildId: 4d2f67b08e52299f862d8f694d06077377cc0d34)
18:56:02.972  A        #12 pc 0000000000041160  /data/app/~~BdRXBaMTPAUBPvI2a0GerQ==/com.foobar.android.debug-Rr3-jrjRXm9QmzCEtT3Ohw==/base.apk!libdispatch.so (offset 0x7d0000) (_dispatch_worker_thread+412) (BuildId: 4d2f67b08e52299f862d8f694d06077377cc0d34)

With the help of Codex I demangled it and found that the crash was here: SkipBridge.JavaBackedClosure.returnValue(for:) -> A where my Swift code looked like @escaping (URL, [String: String]) -> any WSConnection.

At that point I cloned the repo and asked it to figure out a solution.

Improve return value bridging logic in `JavaBackedClosure` class to
better support various Swift types. Add a method to retrieve a protocol
bridge implementation type and gracefully handle unbridgeable types with
a descriptive fatal error. This change ensures robust bridging of Java
closures to their Swift representation, enhancing reliability and
handling edge cases more effectively.
@cla-bot cla-bot bot added the cla-signed label Feb 17, 2026
@marcprux
Copy link
Member

Could you add a test case that demonstrates the protocol bridging?

Introduce `kotlinClosure0ProtocolVar` that returns a `KotlinProtocol` type.
The addition facilitates scenarios where closures return protocol types.
Implement associated test cases in `testSupport_kotlinClosure0ProtocolVar`
to ensure functionality correctness. This change enriches the flexibility
of closures and supports protocol handling in closure definitions.
@piercifani
Copy link
Contributor Author

@marcprux done!

@marcprux
Copy link
Member

Great, thank you!

@marcprux marcprux merged commit 9de70d5 into skiptools:main Feb 18, 2026
3 checks passed
@piercifani piercifani deleted the fix-protocol-crash branch February 18, 2026 12:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants