File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -171,6 +171,19 @@ extension JNISwift2JavaGenerator {
171171 }
172172
173173 printer. printBraceBlock ( function. swiftDecl. signatureString) { printer in
174+ // Push a local JNI frame so refs created during this upcall are freed on exit.
175+ // When called from a Swift async context (e.g. cooperative thread pool) there is
176+ // no enclosing JNI frame, so refs would otherwise accumulate indefinitely. When
177+ // called from a Java-initiated native call there is already a frame, but pushing
178+ // a sub-frame still frees refs earlier and prevents overflow within a single call.
179+ let paramCount = function. originalFunctionSignature. parameters. count
180+ printer. print (
181+ """
182+ let environment$ = try! JavaVirtualMachine.shared().environment()
183+ environment$.interface.PushLocalFrame(environment$, \( paramCount * 2 + 4 ) )
184+ defer { environment$.interface.PopLocalFrame(environment$, nil) }
185+ """
186+ )
174187 var upcallArguments = zip (
175188 function. originalFunctionSignature. parameters,
176189 function. parameterConversions
Original file line number Diff line number Diff line change @@ -315,9 +315,15 @@ struct JNIProtocolTests {
315315 """
316316 extension SwiftJavaSomeProtocolWrapper {
317317 public func method() {
318+ let environment$ = try! JavaVirtualMachine.shared().environment()
319+ environment$.interface.PushLocalFrame(environment$, 4)
320+ defer { environment$.interface.PopLocalFrame(environment$, nil) }
318321 _javaSomeProtocolInterface.method()
319322 }
320323 public func withObject(c: SomeClass) -> SomeClass {
324+ let environment$ = try! JavaVirtualMachine.shared().environment()
325+ environment$.interface.PushLocalFrame(environment$, 6)
326+ defer { environment$.interface.PopLocalFrame(environment$, nil) }
321327 let cClass = try! JavaClass<JavaSomeClass>(environment: JavaVirtualMachine.shared().environment())
322328 let cPointer = UnsafeMutablePointer<SomeClass>.allocate(capacity: 1)
323329 cPointer.initialize(to: c)
You can’t perform that action at this time.
0 commit comments