Allow weak references to permanent objects. (#3781)
This commit is contained in:
@@ -10,7 +10,7 @@ import kotlin.native.ref.*
|
|||||||
|
|
||||||
class Node(var next: Node?)
|
class Node(var next: Node?)
|
||||||
|
|
||||||
@Test fun runTest() {
|
@Test fun runTest1() {
|
||||||
val node1 = Node(null)
|
val node1 = Node(null)
|
||||||
val node2 = Node(node1)
|
val node2 = Node(node1)
|
||||||
node1.next = node2
|
node1.next = node2
|
||||||
@@ -18,3 +18,15 @@ class Node(var next: Node?)
|
|||||||
kotlin.native.ref.WeakReference(node1)
|
kotlin.native.ref.WeakReference(node1)
|
||||||
println("OK")
|
println("OK")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test fun runTest2() {
|
||||||
|
val string = "Hello"
|
||||||
|
val refString = WeakReference(string)
|
||||||
|
assertEquals(string, refString.value)
|
||||||
|
val zero = 0
|
||||||
|
val refZero = WeakReference(zero)
|
||||||
|
assertEquals(0, refZero.value)
|
||||||
|
val long = Long.MAX_VALUE
|
||||||
|
val refLong = WeakReference(long)
|
||||||
|
assertEquals(Long.MAX_VALUE, refLong.value)
|
||||||
|
}
|
||||||
|
|||||||
@@ -49,10 +49,15 @@ extern "C" {
|
|||||||
|
|
||||||
OBJ_GETTER(makeWeakReferenceCounter, void*);
|
OBJ_GETTER(makeWeakReferenceCounter, void*);
|
||||||
OBJ_GETTER(makeObjCWeakReferenceImpl, void*);
|
OBJ_GETTER(makeObjCWeakReferenceImpl, void*);
|
||||||
|
OBJ_GETTER(makePermanentWeakReferenceImpl, ObjHeader*);
|
||||||
|
|
||||||
// See Weak.kt for implementation details.
|
// See Weak.kt for implementation details.
|
||||||
// Retrieve link on the counter object.
|
// Retrieve link on the counter object.
|
||||||
OBJ_GETTER(Konan_getWeakReferenceImpl, ObjHeader* referred) {
|
OBJ_GETTER(Konan_getWeakReferenceImpl, ObjHeader* referred) {
|
||||||
|
if (referred->container() == nullptr) {
|
||||||
|
RETURN_RESULT_OF(makePermanentWeakReferenceImpl, referred);
|
||||||
|
}
|
||||||
|
|
||||||
MetaObjHeader* meta = referred->meta_object();
|
MetaObjHeader* meta = referred->meta_object();
|
||||||
|
|
||||||
#if KONAN_OBJC_INTEROP
|
#if KONAN_OBJC_INTEROP
|
||||||
|
|||||||
@@ -37,5 +37,11 @@ public class WeakReference<T : Any> {
|
|||||||
*/
|
*/
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
public fun get(): T? = pointer?.get() as T?
|
public fun get(): T? = pointer?.get() as T?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns either reference to an object or null, if it was collected.
|
||||||
|
*/
|
||||||
|
public val value: T?
|
||||||
|
get() = this.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,3 +56,10 @@ external internal fun getWeakReferenceImpl(referent: Any): WeakReferenceImpl
|
|||||||
@ExportForCppRuntime
|
@ExportForCppRuntime
|
||||||
internal fun makeWeakReferenceCounter(referred: COpaquePointer) = WeakReferenceCounter(referred)
|
internal fun makeWeakReferenceCounter(referred: COpaquePointer) = WeakReferenceCounter(referred)
|
||||||
|
|
||||||
|
internal class PermanentWeakReferenceImpl(val referred: Any): kotlin.native.ref.WeakReferenceImpl() {
|
||||||
|
override fun get(): Any? = referred
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a reference to the permanent object.
|
||||||
|
@ExportForCppRuntime
|
||||||
|
internal fun makePermanentWeakReferenceImpl(referred: Any) = PermanentWeakReferenceImpl(referred)
|
||||||
|
|||||||
Reference in New Issue
Block a user