Skip to content

Commit 11d320b

Browse files
satoshiotomakanvcoolish10gic
authored
[Dev/UnderAudit]: Dev<->Master (#4046)
* Kotlin multiplatform leaking memory (#4037) * Add deinit for KMP iOS and JVM targets * Add deinit for JS target * Add deinit for JS target * Fix JVM native name * Reuse one thread on JVM --------- Co-authored-by: satoshiotomakan <[email protected]> * [KMP] Fix issue: memory leak found in Base58.decode in iOS (#4031) * Fix kmp issue: memory leak found in Base58.decode in iOS * Remove unused functions * Fix failed test cases * Revert "Fix failed test cases" This reverts commit 57eee39. * Revert val -> value argument name refactoring * Output better indentation * Revert changes in TWEthereumAbiFunction.h * Fix inconsistent naming --------- Co-authored-by: satoshiotomakan <[email protected]> * [TON]: Add support for TON 24-words mnemonic (#3998) * feat(ton): Add support for TON 24-words mnemonic in Rust * feat(ton): Add tw_ton_wallet FFIs * feat(ton): Add TWTONWallet FFI in C++ * feat(ton): Add tonMnemonic StoredKey type * feat(ton): Add StoredKey TON tests * feat(ton): Add TWStoredKey TON tests * feat(ton): Add TONWallet support in Swift * TODO add iOS tests * feat(ton): Add `KeyStore` iOS tests * feat(ton): Add TONWallet support in JavaScript * Add `KeyStore` TypeScript tests * feat(ton): Remove `TonMnemonic` structure, replace with a `validate_mnemonic_words` function * [CI] Trigger CI * feat(ton): Fix rustfmt * feat(ton): Fix C++ build * feat(ton): Fix C++ build * feat(ton): Fix C++ build * feat(ton): Fix C++ address analyzer * feat(ton): Fix C++ tests * feat(ton): Add Android tests * feat(ton): Bump `actions/upload-artifact` to v4 * Bump `dawidd6/action-download-artifact` to v6 * feat(eth): Fix PR comments * Fix Java JVM leak (#4092) * [Chore]: Fix Android bindings (#4095) * [Chore]: Add GenericPhantomReference.java * [Chore]: Fix unnecessary null assertion in WalletCoreLibLoader.kt * Fix memory lead found in public key in kmp binding (#4097) * Update Callisto explorer (#4131) * Revert "[TON]: Add support for TON 24-words mnemonic (#3998)" (#4148) This reverts commit 0b16771. --------- Co-authored-by: Viacheslav Kulish <[email protected]> Co-authored-by: 10gic <[email protected]>
1 parent 7b1bee5 commit 11d320b

File tree

21 files changed

+310
-82
lines changed

21 files changed

+310
-82
lines changed

codegen/lib/kotlin_helper.rb

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,13 @@ def self.js_parameters(params)
3131
def self.calling_parameters_ios(params)
3232
names = params.map do |param|
3333
name = fix_name(param.name)
34+
if param.type.name == :data
35+
"#{name}Data#{convert_calling_type_ios(param.type)}"
36+
elsif param.type.name == :string
37+
"#{name}String#{convert_calling_type_ios(param.type)}"
38+
else
3439
"#{name}#{convert_calling_type_ios(param.type)}"
40+
end
3541
end
3642
names.join(', ')
3743
end
@@ -56,7 +62,7 @@ def self.fix_name(name)
5662
when ''
5763
"value"
5864
when 'val'
59-
"value"
65+
"value"
6066
when 'return'
6167
'`return`'
6268
else
@@ -65,19 +71,12 @@ def self.fix_name(name)
6571
end
6672

6773
def self.convert_calling_type_ios(t)
68-
case t.name
69-
when :data
70-
"#{if t.is_nullable then '?' else '' end}.toTwData()"
71-
when :string
72-
"#{if t.is_nullable then '?' else '' end}.toTwString()"
74+
if t.is_enum
75+
"#{if t.is_nullable then '?' else '' end}.nativeValue"
76+
elsif t.is_class
77+
"#{if t.is_nullable then '?' else '' end}.pointer"
7378
else
74-
if t.is_enum
75-
"#{if t.is_nullable then '?' else '' end}.nativeValue"
76-
elsif t.is_class
77-
"#{if t.is_nullable then '?' else '' end}.pointer"
78-
else
79-
''
80-
end
79+
''
8180
end
8281
end
8382

codegen/lib/templates/java/class.erb

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import java.security.InvalidParameterException;
2-
import java.util.HashSet;
2+
import wallet.core.java.GenericPhantomReference;
33

44
<% less = entity.static_methods.detect{ |i| i.name == 'Less' } -%>
55
<% equal = entity.static_methods.detect{ |i| i.name == 'Equal' } -%>
@@ -21,7 +21,7 @@ public final class <%= entity.name %> {
2121
<%= entity.name %> instance = new <%= entity.name %>();
2222
instance.nativeHandle = nativeHandle;
2323
<% unless entity.methods.select{ |x| x.name == "Delete" }.empty? -%>
24-
<%= entity.name %>PhantomReference.register(instance, nativeHandle);
24+
GenericPhantomReference.register(instance, nativeHandle, <%= entity.name %>::nativeDelete);
2525
<% end -%>
2626
return instance;
2727
}
@@ -96,32 +96,8 @@ public final class <%= entity.name %> {
9696
throw new InvalidParameterException();
9797
}
9898

99-
<%= entity.name %>PhantomReference.register(this, nativeHandle);
99+
GenericPhantomReference.register(this, nativeHandle, <%= entity.name %>::nativeDelete);
100100
}
101101

102102
<%- end -%>
103103
}
104-
<% unless entity.methods.select{ |x| x.name == "Delete" }.empty? -%>
105-
class <%= entity.name %>PhantomReference extends java.lang.ref.PhantomReference<<%= entity.name %>> {
106-
private static java.util.Set<<%= entity.name %>PhantomReference> references = new HashSet<<%= entity.name %>PhantomReference>();
107-
private static java.lang.ref.ReferenceQueue<<%= entity.name %>> queue = new java.lang.ref.ReferenceQueue<<%= entity.name %>>();
108-
private long nativeHandle;
109-
110-
private <%= entity.name %>PhantomReference(<%= entity.name %> referent, long nativeHandle) {
111-
super(referent, queue);
112-
this.nativeHandle = nativeHandle;
113-
}
114-
115-
static void register(<%= entity.name %> referent, long nativeHandle) {
116-
references.add(new <%= entity.name %>PhantomReference(referent, nativeHandle));
117-
}
118-
119-
public static void doDeletes() {
120-
<%= entity.name %>PhantomReference ref = (<%= entity.name %>PhantomReference) queue.poll();
121-
for (; ref != null; ref = (<%= entity.name %>PhantomReference) queue.poll()) {
122-
<%= entity.name %>.nativeDelete(ref.nativeHandle);
123-
references.remove(ref);
124-
}
125-
}
126-
}
127-
<% end -%>

codegen/lib/templates/kotlin/android_class.erb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ actual class <%= entity.name %> private constructor(
99

1010
init {
1111
if (nativeHandle == 0L) throw IllegalArgumentException()
12+
<% unless entity.methods.select{ |x| x.name == "Delete" }.empty? -%>
13+
GenericPhantomReference.register(this, nativeHandle, ::delete)
14+
<% end -%>
1215
}
1316
<%# Constructors -%>
1417
<%- constructors.each do |constructor| -%>
@@ -52,6 +55,12 @@ actual class <%= entity.name %> private constructor(
5255
@JvmStatic
5356
@JvmName("createFromNative")
5457
private fun createFromNative(nativeHandle: Long) = <%= entity.name %>(nativeHandle)
58+
59+
<% unless entity.methods.select{ |x| x.name == "Delete" }.empty? -%>
60+
@JvmStatic
61+
@JvmName("delete")
62+
private external fun delete(handle: Long)
63+
<%- end -%>
5564
<%- constructors.each do |constructor| -%>
5665

5766
@JvmStatic

codegen/lib/templates/kotlin/ios_class.erb

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,28 @@
22

33
import cnames.structs.TW<%= entity.name %>
44
import kotlinx.cinterop.CPointer
5+
import kotlinx.cinterop.toCValues
56

67
<% constructors = entity.static_methods.select { |method| method.name.start_with?('Create') } -%>
78
<% methods = entity.methods.select { |method| not method.name.start_with?('Delete') } -%>
89
<% static_methods = entity.static_methods.select { |method| not method.name.start_with?('Create') } -%>
910
actual class <%= entity.name %> constructor(
1011
val pointer: CPointer<TW<%= entity.name %>>,
1112
) {
13+
<% unless entity.methods.select{ |x| x.name == "Delete" }.empty? -%>
14+
@OptIn(ExperimentalStdlibApi::class)
15+
private val cleaner = kotlin.native.internal.createCleaner(pointer) { ptr ->
16+
TW<%= entity.name %>Delete(ptr)
17+
}
18+
<% end -%>
1219
<%# Constructors -%>
1320
<%- constructors.each do |constructor| -%>
1421

1522
<% if constructor.return_type.is_nullable -%>
1623
@Throws(IllegalArgumentException::class)
17-
actual constructor(<%= KotlinHelper.parameters(constructor.parameters) %>) : this(
18-
TW<%= entity.name %><%= constructor.name %>(<%= KotlinHelper.calling_parameters_ios(constructor.parameters) %>) ?: throw IllegalArgumentException()
19-
<% else -%>
20-
actual constructor(<%= KotlinHelper.parameters(constructor.parameters) %>) : this(
21-
TW<%= entity.name %><%= constructor.name %>(<%= KotlinHelper.calling_parameters_ios(constructor.parameters) %>)!!
2224
<% end -%>
25+
actual constructor(<%= KotlinHelper.parameters(constructor.parameters) %>) : this(
26+
wrapperTW<%= entity.name %><%= constructor.name %>(<%= KotlinHelper.arguments(constructor.parameters) %>)
2327
)
2428
<% end -%>
2529
<%# Property declarations -%>
@@ -31,12 +35,38 @@ actual class <%= entity.name %> constructor(
3135
<%# Method declarations -%>
3236
<% methods.each do |method| -%>
3337

34-
actual fun <%= KotlinHelper.format_name(method.name) %>(<%= KotlinHelper.parameters(method.parameters.drop(1)) %>)<%= KotlinHelper.return_type(method.return_type) %> =
35-
<%= KotlinHelper.convert_calling_return_type_ios(method.return_type, "TW#{entity.name}#{method.name}(pointer#{', ' if not method.parameters.one?}#{KotlinHelper.calling_parameters_ios(method.parameters.drop(1))})") %>
38+
actual fun <%= KotlinHelper.format_name(method.name) %>(<%= KotlinHelper.parameters(method.parameters.drop(1)) %>)<%= KotlinHelper.return_type(method.return_type) %> {
39+
<%= render('kotlin/ios_parameter_access.erb', { method: method }) -%>
40+
val result = <%= KotlinHelper.convert_calling_return_type_ios(method.return_type, "TW#{entity.name}#{method.name}(pointer#{', ' if not method.parameters.one?}#{KotlinHelper.calling_parameters_ios(method.parameters.drop(1))})") %>
41+
<%= render('kotlin/ios_parameter_release.erb', { method: method }) -%>
42+
return result
43+
}
3644
<% end -%>
37-
<% if entity.static_properties.any? || static_methods.any? -%>
45+
<% if entity.static_properties.any? || static_methods.any? || constructors.any? -%>
46+
47+
<%= if entity.static_properties.any? || static_methods.any? then "actual" else "private" end %> companion object {
48+
<%# Constructor wrappers -%>
49+
<% if constructors.any? -%>
50+
<% constructors.each do |constructor| -%>
3851

39-
actual companion object {
52+
<% if constructor.return_type.is_nullable -%>
53+
@Throws(IllegalArgumentException::class)
54+
<% end -%>
55+
private fun wrapperTW<%= entity.name %><%= constructor.name %>(<%= KotlinHelper.parameters(constructor.parameters) %>): CPointer<TW<%= entity.name %>> {
56+
<%= render('kotlin/ios_parameter_access.erb', { method: constructor, more_index: 4 }) -%>
57+
val result = TW<%= entity.name %><%= constructor.name %>(<%= KotlinHelper.calling_parameters_ios(constructor.parameters) %>)
58+
<%= render('kotlin/ios_parameter_release.erb', { method: constructor, more_index: 4 }) -%>
59+
<% if constructor.return_type.is_nullable -%>
60+
if (result == null) {
61+
throw IllegalArgumentException()
62+
}
63+
return result
64+
<% else -%>
65+
return result!!
66+
<% end -%>
67+
}
68+
<% end -%>
69+
<% end -%>
4070
<%# Static property declarations -%>
4171
<% entity.static_properties.each do |property| -%>
4272

@@ -46,8 +76,12 @@ actual class <%= entity.name %> constructor(
4676
<%# Static method declarations -%>
4777
<% static_methods.each do |method| -%>
4878

49-
actual fun <%= KotlinHelper.format_name(method.name) %>(<%= KotlinHelper.parameters(method.parameters) %>)<%= KotlinHelper.return_type(method.return_type) %> =
50-
<%= KotlinHelper.convert_calling_return_type_ios(method.return_type, "TW#{entity.name}#{method.name}(#{KotlinHelper.calling_parameters_ios(method.parameters)})") %>
79+
actual fun <%= KotlinHelper.format_name(method.name) %>(<%= KotlinHelper.parameters(method.parameters) %>)<%= KotlinHelper.return_type(method.return_type) %> {
80+
<%= render('kotlin/ios_parameter_access.erb', { method: method, more_index: 4 }) -%>
81+
val result = <%= KotlinHelper.convert_calling_return_type_ios(method.return_type, "TW#{entity.name}#{method.name}(#{KotlinHelper.calling_parameters_ios(method.parameters)})") %>
82+
<%= render('kotlin/ios_parameter_release.erb', { method: method, more_index: 4 }) -%>
83+
return result
84+
}
5185
<% end -%>
5286
}
5387
<% end -%>

codegen/lib/templates/kotlin/ios_enum.erb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,12 @@ actual enum class <%= entity.name %>(
4141
<%- entity.methods.each do |method| -%>
4242
<%- next if method.name.start_with?('Delete') -%>
4343

44-
actual fun <%= KotlinHelper.format_name(method.name) %>(<%= KotlinHelper.parameters(method.parameters.drop(1)) %>)<%= KotlinHelper.return_type(method.return_type) %> =
45-
TW<%= entity.name %><%= method.name %>(value<%= ', ' if not method.parameters.one? %><%= KotlinHelper.calling_parameters_ios(method.parameters.drop(1)) %>)<%= KotlinHelper.convert_calling_return_type_ios(method.return_type) %>
44+
actual fun <%= KotlinHelper.format_name(method.name) %>(<%= KotlinHelper.parameters(method.parameters.drop(1)) %>)<%= KotlinHelper.return_type(method.return_type) %> {
45+
<%= render('kotlin/ios_parameter_access.erb', { method: method }) -%>
46+
val result = TW<%= entity.name %><%= method.name %>(value<%= ', ' if not method.parameters.one? %><%= KotlinHelper.calling_parameters_ios(method.parameters.drop(1)) %>)<%= KotlinHelper.convert_calling_return_type_ios(method.return_type) %>
47+
<%= render('kotlin/ios_parameter_release.erb', { method: method }) -%>
48+
return result
49+
}
4650
<%- end -%>
4751
<%# Value -%>
4852
<% if entity.cases.any? { |e| !e.value.nil? } -%>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<%
2+
method = locals[:method]
3+
more_index = locals[:more_index] || 0
4+
5+
method.parameters.each do |param| -%>
6+
<% if param.type.name == :data -%>
7+
<% if param.type.is_nullable -%>
8+
<%= ' ' * more_index %> val <%= KotlinHelper.fix_name(param.name) %>Data = if (<%= KotlinHelper.fix_name(param.name) %> == null) {
9+
<%= ' ' * more_index %> null
10+
<%= ' ' * more_index %> } else {
11+
<%= ' ' * more_index %> TWDataCreateWithBytes(<%= KotlinHelper.fix_name(param.name) %>.toUByteArray().toCValues(), <%= KotlinHelper.fix_name(param.name) %>.size.toULong())
12+
<%= ' ' * more_index %> }
13+
<% else -%>
14+
<%= ' ' * more_index %> val <%= KotlinHelper.fix_name(param.name) %>Data = TWDataCreateWithBytes(<%= KotlinHelper.fix_name(param.name) %>.toUByteArray().toCValues(), <%= KotlinHelper.fix_name(param.name) %>.size.toULong())
15+
<% end -%>
16+
<% elsif param.type.name == :string -%>
17+
<% if param.type.is_nullable -%>
18+
<%= ' ' * more_index %> val <%= KotlinHelper.fix_name(param.name) %>String = if (<%= KotlinHelper.fix_name(param.name) %> == null) {
19+
<%= ' ' * more_index %> null
20+
<%= ' ' * more_index %> } else {
21+
<%= ' ' * more_index %> TWStringCreateWithUTF8Bytes(<%= KotlinHelper.fix_name(param.name) %>)
22+
<%= ' ' * more_index %> }
23+
<% else -%>
24+
<%= ' ' * more_index %> val <%= KotlinHelper.fix_name(param.name) %>String = TWStringCreateWithUTF8Bytes(<%= KotlinHelper.fix_name(param.name) %>)
25+
<% end -%>
26+
<% end -%>
27+
<% end -%>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<%
2+
method = locals[:method]
3+
more_index = locals[:more_index] || 0
4+
5+
method.parameters.each do |param| -%>
6+
<% if param.type.name == :data -%>
7+
<% if param.type.is_nullable -%>
8+
<%= ' ' * more_index %> if (<%= KotlinHelper.fix_name(param.name) %>Data != null) {
9+
<%= ' ' * more_index %> TWDataDelete(<%= KotlinHelper.fix_name(param.name) %>Data)
10+
<%= ' ' * more_index %> }
11+
<% else -%>
12+
<%= ' ' * more_index %> TWDataDelete(<%= KotlinHelper.fix_name(param.name) %>Data)
13+
<% end -%>
14+
<% elsif param.type.name == :string -%>
15+
<% if param.type.is_nullable -%>
16+
<%= ' ' * more_index %> if (<%= KotlinHelper.fix_name(param.name) %>String != null) {
17+
<%= ' ' * more_index %> TWStringDelete(<%= KotlinHelper.fix_name(param.name) %>String)
18+
<%= ' ' * more_index %> }
19+
<% else -%>
20+
<%= ' ' * more_index %> TWStringDelete(<%= KotlinHelper.fix_name(param.name) %>String)
21+
<% end -%>
22+
<% end -%>
23+
<% end -%>

codegen/lib/templates/kotlin/ios_struct.erb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<%= render('kotlin/package.erb') %>
22

3+
import kotlinx.cinterop.toCValues
4+
35
actual object <%= entity.name %> {
46
<%# Static property declarations -%>
57
<% entity.static_properties.each do |property| -%>
@@ -10,7 +12,11 @@ actual object <%= entity.name %> {
1012
<% entity.static_methods.each do |method| -%>
1113
<% next if method.name.start_with?('Create') -%>
1214

13-
actual fun <%= KotlinHelper.format_name(method.name) %>(<%= KotlinHelper.parameters(method.parameters) %>)<%= KotlinHelper.return_type(method.return_type) %> =
14-
<%= KotlinHelper.convert_calling_return_type_ios(method.return_type, "TW#{entity.name}#{method.name}(#{KotlinHelper.calling_parameters_ios(method.parameters)})") %>
15+
actual fun <%= KotlinHelper.format_name(method.name) %>(<%= KotlinHelper.parameters(method.parameters) %>)<%= KotlinHelper.return_type(method.return_type) %> {
16+
<%= render('kotlin/ios_parameter_access.erb', { method: method }) -%>
17+
val result = <%= KotlinHelper.convert_calling_return_type_ios(method.return_type, "TW#{entity.name}#{method.name}(#{KotlinHelper.calling_parameters_ios(method.parameters)})") %>
18+
<%= render('kotlin/ios_parameter_release.erb', { method: method }) -%>
19+
return result
20+
}
1521
<% end -%>
1622
}

codegen/lib/templates/kotlin/js_accessors_class.erb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ external interface Js<%= entity.name %> {
88
<%- entity.properties.each do |property| -%>
99
fun <%= KotlinHelper.fix_name(WasmCppHelper.format_name(property.name)) %>()<%= KotlinHelper.js_return_type(property.return_type) %>
1010
<%- end -%>
11+
<% unless entity.methods.select{ |x| x.name == "Delete" }.empty? -%>
12+
fun delete()
13+
<% end -%>
1114
<% entity.methods.each do |method| -%>
1215
<% next if method.name == "Delete" -%>
1316
fun <%= KotlinHelper.fix_name(WasmCppHelper.format_name(method.name)) %>(<%= KotlinHelper.js_parameters(method.parameters.drop(1)) %>)<%= KotlinHelper.js_return_type(method.return_type) %>

codegen/lib/templates/kotlin/js_class.erb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,21 @@
66
actual class <%= entity.name %> constructor(
77
val jsValue: Js<%= entity.name %>,
88
) {
9+
<% unless entity.methods.select{ |x| x.name == "Delete" }.empty? -%>
10+
private val finalizationRegistry =
11+
js(
12+
"""
13+
new FinalizationRegistry(function(heldValue) {
14+
heldValue.delete();
15+
})
16+
"""
17+
)
18+
19+
init {
20+
finalizationRegistry.register(this, jsValue)
21+
}
22+
<% end -%>
23+
924
<%# Constructors -%>
1025
<%- constructors.each do |constructor| -%>
1126

0 commit comments

Comments
 (0)