@@ -153,15 +153,16 @@ extension AnyJavaObject {
153153 method: jmethodID ,
154154 args: repeat each Param
155155 ) throws -> Result {
156- // Retrieve the method that performs this call, then package the values and
157- // call it .
156+ // Wrap arg creation, the call, and result conversion in a local frame so
157+ // that jstring/jarray local refs created by getJValues are freed on exit .
158158 let jniMethod = Result . jniMethodCall ( in: environment)
159- let jniArgs = getJValues ( repeat each args, in: environment)
160- let jniResult = try environment. translatingJNIExceptions {
161- jniMethod ( environment, this, method, jniArgs)
159+ return try environment. withLocalFrame ( capacity: countArgs ( repeat each args) + 1 ) {
160+ let jniArgs = getJValues ( repeat each args, in: environment)
161+ let jniResult = try environment. translatingJNIExceptions {
162+ jniMethod ( environment, this, method, jniArgs)
163+ }
164+ return Result ( fromJNI: jniResult, in: environment)
162165 }
163-
164- return Result ( fromJNI: jniResult, in: environment)
165166 }
166167
167168 /// Call a Java method with the given name and arguments, which must be of the correct
@@ -219,12 +220,14 @@ extension AnyJavaObject {
219220 method: jmethodID ,
220221 args: repeat each Param
221222 ) throws {
222- // Retrieve the method that performs this call, then package the arguments
223- // and call it .
223+ // Wrap arg creation and the call in a local frame so that jstring/jarray
224+ // local refs created by getJValues are freed on exit .
224225 let jniMethod = environment. interface. CallVoidMethodA!
225- let jniArgs = getJValues ( repeat each args, in: environment)
226- try environment. translatingJNIExceptions {
227- jniMethod ( environment, this, method, jniArgs)
226+ try environment. withLocalFrame ( capacity: countArgs ( repeat each args) + 1 ) {
227+ let jniArgs = getJValues ( repeat each args, in: environment)
228+ try environment. translatingJNIExceptions {
229+ jniMethod ( environment, this, method, jniArgs)
230+ }
228231 }
229232 }
230233
@@ -271,9 +274,16 @@ extension AnyJavaObject {
271274 in: environment
272275 )
273276
274- let jniArgs = getJValues ( repeat each arguments, in: environment)
275- return try environment. translatingJNIExceptions {
276- environment. interface. NewObjectA!( environment, thisClass, methodID, jniArgs)
277+ // Wrap arg creation and the constructor call in a local frame, promoting
278+ // the new object's local ref to the outer frame so the caller can wrap
279+ // it in a JavaObjectHolder (which will then delete that promoted ref).
280+ return try environment. withLocalFramePromotingResult (
281+ capacity: countArgs ( repeat each arguments) + 1
282+ ) {
283+ let jniArgs = getJValues ( repeat each arguments, in: environment)
284+ return try environment. translatingJNIExceptions {
285+ environment. interface. NewObjectA!( environment, thisClass, methodID, jniArgs)
286+ } !
277287 } !
278288 }
279289 }
@@ -308,7 +318,9 @@ extension AnyJavaObject {
308318
309319 let fieldID = getJNIFieldID ( fieldName, fieldType: fieldType) !
310320 let jniMethod = FieldType . jniFieldSet ( in: environment)
311- jniMethod ( environment, javaThis, fieldID, newValue. getJNIValue ( in: environment) )
321+ try ! environment. withLocalFrame ( capacity: 1 ) {
322+ jniMethod ( environment, javaThis, fieldID, newValue. getJNIValue ( in: environment) )
323+ }
312324 }
313325 }
314326}
@@ -340,12 +352,13 @@ extension JavaClass {
340352 } !
341353
342354 let jniMethod = Result . jniStaticMethodCall ( in: environment)
343- let jniArgs = getJValues ( repeat each arguments, in: environment)
344- let jniResult = try environment. translatingJNIExceptions {
345- jniMethod ( environment, thisClass, methodID, jniArgs)
355+ return try environment. withLocalFrame ( capacity: countArgs ( repeat each arguments) + 1 ) {
356+ let jniArgs = getJValues ( repeat each arguments, in: environment)
357+ let jniResult = try environment. translatingJNIExceptions {
358+ jniMethod ( environment, thisClass, methodID, jniArgs)
359+ }
360+ return Result ( fromJNI: jniResult, in: environment)
346361 }
347-
348- return Result ( fromJNI: jniResult, in: environment)
349362 }
350363
351364 /// Call a Java static method with the given name and arguments, which must be
@@ -373,9 +386,11 @@ extension JavaClass {
373386 } !
374387
375388 let jniMethod = environment. interface. CallStaticVoidMethodA
376- let jniArgs = getJValues ( repeat each arguments, in: environment)
377- try environment. translatingJNIExceptions {
378- jniMethod!( environment, thisClass, methodID, jniArgs)
389+ try environment. withLocalFrame ( capacity: countArgs ( repeat each arguments) + 1 ) {
390+ let jniArgs = getJValues ( repeat each arguments, in: environment)
391+ try environment. translatingJNIExceptions {
392+ jniMethod!( environment, thisClass, methodID, jniArgs)
393+ }
379394 }
380395 }
381396
@@ -403,7 +418,9 @@ extension JavaClass {
403418
404419 let fieldID = getJNIStaticFieldID ( fieldName, fieldType: fieldType) !
405420 let jniMethod = FieldType . jniStaticFieldSet ( in: environment)
406- jniMethod ( environment, javaThis, fieldID, newValue. getJNIValue ( in: environment) )
421+ try ! environment. withLocalFrame ( capacity: 1 ) {
422+ jniMethod ( environment, javaThis, fieldID, newValue. getJNIValue ( in: environment) )
423+ }
407424 }
408425 }
409426}
0 commit comments