Skip to content

Commit b1e5c9a

Browse files
committed
Some fixes
1 parent f9032ae commit b1e5c9a

File tree

3 files changed

+25
-6
lines changed

3 files changed

+25
-6
lines changed

jnim/java/lang.nim

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,3 +181,6 @@ proc asJVM*(ex: JavaException): Throwable =
181181

182182
proc getCurrentJVMException*: Throwable =
183183
((ref JavaException)getCurrentException())[].asJVM
184+
185+
jclass java.lang.Runnable* of JVMObject:
186+
proc run*()

jnim/private/jni_api.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,10 @@ proc get*(o: JVMObject): jobject =
312312
assert(not o.obj.isNil)
313313
o.obj
314314

315-
proc getNoCreate*(o: JVMObject): jobject = o.obj
315+
proc getNoCreate*(o: JVMObject): jobject {.inline.} = o.obj
316316

317317
proc setObj*(o: JVMObject, obj: jobject) =
318-
assert(obj == nil or theEnv.GetObjectRefType(theEnv, obj) == JNILocalRefType)
318+
assert(obj == nil or theEnv.GetObjectRefType(theEnv, obj) in {JNILocalRefType, JNIWeakGlobalRefType})
319319
o.obj = obj
320320

321321
proc toJValue*(o: JVMObject): jvalue =

jnim/private/jni_export.nim

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -236,13 +236,24 @@ proc setNimObjectToJObject(e: JNIEnvPtr, j: jobject, o: JVMObject) =
236236
e.deleteLocalRef(clazz)
237237
GC_ref(o)
238238
e.SetLongField(e, j, fid, cast[jlong](o))
239-
o.setObj(j)
239+
let wr = e.NewWeakGlobalRef(e, j)
240+
o.setObj(wr)
240241

241242
proc finalizeJobject(e: JNIEnvPtr, j: jobject, p: jlong) =
242243
let p = cast[JVMObject](p)
243244
if not p.isNil:
244245
GC_unref(p)
246+
let j = p.getNoCreate()
245247
p.setObj(nil)
248+
if not j.isNil:
249+
e.DeleteWeakGlobalRef(e, j)
250+
251+
proc createJObjectAux(self: JVMObject, clazz: JVMClass) =
252+
GC_ref(self)
253+
let inst = clazz.newObjectRaw("(J)V", [toJValue(cast[jlong](self))])
254+
let wr = theEnv.NewWeakGlobalRef(theEnv, inst)
255+
theEnv.deleteLocalRef(inst)
256+
self.setObj(wr)
246257

247258
macro jexport*(a: varargs[untyped]): untyped =
248259
var (className, parentClass, interfaces, body, isPublic) = extractArguments(a)
@@ -368,6 +379,13 @@ macro jexport*(a: varargs[untyped]): untyped =
368379
echo "Unexpected AST: ", repr(m)
369380
assert(false)
370381

382+
block: # Finalizer thunk
383+
let thunkName = genSym(nskProc, JniExportedFunctionPrefix & className & "__0")
384+
result.add quote do:
385+
proc `thunkName`(jniEnv: JNIEnvPtr, this: jobject, p: jlong) {.exportc, cdecl.} =
386+
finalizeJobject(jniEnv, this, p)
387+
388+
371389
result.add newCall(bindSym"jexportAux", newLit(className), parentFq, inter, newLit(isPublic), methodDefs, staticSection, emitSection)
372390

373391
# Add finalizer impl
@@ -393,9 +411,7 @@ macro jexport*(a: varargs[untyped]): untyped =
393411
`clazzIdent` = JVMClass.getByFqcn(fq)
394412
`nativeMethodsRegistration`
395413

396-
GC_ref(self)
397-
let inst = `clazzIdent`.newObjectRaw("(J)V", [toJValue(cast[jlong](self))])
398-
self.setObj(inst)
414+
createJObjectAux(self, `clazzIdent`)
399415

400416
# Generate interface converters
401417
for interf in interfaces:

0 commit comments

Comments
 (0)