Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions codegen/lib/templates/kotlin/android_class.erb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ actual class <%= entity.name %> private constructor(

init {
if (nativeHandle == 0L) throw IllegalArgumentException()
<% unless entity.methods.select{ |x| x.name == "Delete" }.empty? -%>
GenericPhantomReference.register(this, nativeHandle, ::delete)
<% end -%>
}
<%# Constructors -%>
<%- constructors.each do |constructor| -%>
Expand Down Expand Up @@ -52,6 +55,12 @@ actual class <%= entity.name %> private constructor(
@JvmStatic
@JvmName("createFromNative")
private fun createFromNative(nativeHandle: Long) = <%= entity.name %>(nativeHandle)

<% unless entity.methods.select{ |x| x.name == "Delete" }.empty? -%>
@JvmStatic
@JvmName("delete")
private external fun delete(handle: Long)
<%- end -%>
<%- constructors.each do |constructor| -%>

@JvmStatic
Expand Down
6 changes: 6 additions & 0 deletions codegen/lib/templates/kotlin/ios_class.erb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ import kotlinx.cinterop.CPointer
actual class <%= entity.name %> constructor(
val pointer: CPointer<TW<%= entity.name %>>,
) {
<% unless entity.methods.select{ |x| x.name == "Delete" }.empty? -%>
@OptIn(ExperimentalStdlibApi::class)
private val cleaner = kotlin.native.internal.createCleaner(pointer) { ptr ->
TW<%= entity.name %>Delete(ptr)
}
<% end -%>
<%# Constructors -%>
<%- constructors.each do |constructor| -%>

Expand Down
3 changes: 3 additions & 0 deletions codegen/lib/templates/kotlin/js_accessors_class.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ external interface Js<%= entity.name %> {
<%- entity.properties.each do |property| -%>
fun <%= KotlinHelper.fix_name(WasmCppHelper.format_name(property.name)) %>()<%= KotlinHelper.js_return_type(property.return_type) %>
<%- end -%>
<% unless entity.methods.select{ |x| x.name == "Delete" }.empty? -%>
fun delete()
<% end -%>
<% entity.methods.each do |method| -%>
<% next if method.name == "Delete" -%>
fun <%= KotlinHelper.fix_name(WasmCppHelper.format_name(method.name)) %>(<%= KotlinHelper.js_parameters(method.parameters.drop(1)) %>)<%= KotlinHelper.js_return_type(method.return_type) %>
Expand Down
15 changes: 15 additions & 0 deletions codegen/lib/templates/kotlin/js_class.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@
actual class <%= entity.name %> constructor(
val jsValue: Js<%= entity.name %>,
) {
<% unless entity.methods.select{ |x| x.name == "Delete" }.empty? -%>
private val finalizationRegistry =
js(
"""
new FinalizationRegistry(function(heldValue) {
heldValue.delete();
})
"""
)

init {
finalizationRegistry.register(this, jsValue)
}
<% end -%>

<%# Constructors -%>
<%- constructors.each do |constructor| -%>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.trustwallet.core

import java.lang.ref.PhantomReference
import java.lang.ref.ReferenceQueue

internal class GenericPhantomReference private constructor(
referent: Any,
private val handle: Long,
private val onDelete: (Long) -> Unit,
) : PhantomReference<Any>(referent, queue) {

companion object {
private val references: MutableSet<GenericPhantomReference> = HashSet()
private val queue: ReferenceQueue<Any> = ReferenceQueue()

init {
Thread {
try {
doDeletes()
} catch (e: InterruptedException) {
Thread.currentThread().interrupt()
}
}.apply {
name = "WCFinalizingDaemon"
isDaemon = true
priority = Thread.NORM_PRIORITY
start()
}
}

fun register(
referent: Any,
handle: Long,
onDelete: (Long) -> Unit,
) {
references.add(GenericPhantomReference(referent, handle, onDelete))
}

private fun doDeletes() {
while (true) {
val ref = queue.remove() as GenericPhantomReference
ref.onDelete(ref.handle)
references.remove(ref)
}
}
}
}
Loading