Skip to content

Commit 28e30c0

Browse files
committed
Correct reference counting in init thunk
1 parent ea47b16 commit 28e30c0

File tree

4 files changed

+48
-25
lines changed

4 files changed

+48
-25
lines changed

Samples/SwiftKitSampleApp/src/main/java/com/example/swift/HelloJava2Swift.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,16 @@
2424
import org.swift.swiftkit.SwiftKit;
2525
import org.swift.swiftkit.SwiftValueWitnessTable;
2626

27+
import java.util.Arrays;
28+
2729
public class HelloJava2Swift {
2830

2931
public static void main(String[] args) {
3032
boolean traceDowncalls = Boolean.getBoolean("jextract.trace.downcalls");
3133
System.out.println("Property: jextract.trace.downcalls = " + traceDowncalls);
3234

33-
System.out.print("java.library.path = \n");
34-
for (var path : SwiftKit.getJavaLibraryPath().split(":")) {
35-
System.out.println(" " + path);
36-
}
35+
System.out.print("Property: java.library.path = \n");
36+
System.out.println(SwiftKit.getJavaLibraryPath());
3737

3838
examples();
3939

@@ -44,13 +44,17 @@ static void examples() {
4444

4545
MySwiftLibrary.globalTakeInt(1337);
4646

47-
MySwiftClass obj = new MySwiftClass(2222, 7777);
47+
// Example of using an arena; MyClass.deinit is run at end of scope
48+
try (var arena = SwiftArena.ofConfined()) {
49+
MySwiftClass obj = new MySwiftClass(arena, 2222, 7777);
4850

49-
// SwiftKit.retain(obj.$memorySegment());
50-
// System.out.println("[java] obj ref count = " + SwiftKit.retainCount(obj.$memorySegment()));
51+
// just checking retains/releases work
52+
SwiftKit.retain(obj.$memorySegment());
53+
SwiftKit.release(obj.$memorySegment());
5154

52-
obj.voidMethod();
53-
// obj.takeIntMethod(42);
55+
obj.voidMethod();
56+
obj.takeIntMethod(42);
57+
}
5458

5559
System.out.println("DONE.");
5660
}

Sources/JExtractSwift/Swift2JavaTranslator+Printing.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,15 @@ extension Swift2JavaTranslator {
112112
public func printSwiftThunkSources(_ printer: inout CodePrinter, ty: ImportedNominalType) throws {
113113
let stt = SwiftThunkTranslator(self)
114114

115+
printer.print(
116+
"""
117+
// Generated by swift-java
118+
119+
import SwiftKitSwift
120+
121+
"""
122+
)
123+
115124
for thunk in stt.renderThunks(forType: ty) {
116125
printer.print("\(thunk)")
117126
printer.print("")

Sources/JExtractSwift/SwiftThunkTranslator.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ struct SwiftThunkTranslator {
7272
"""
7373
@_cdecl("\(raw: funcName)")
7474
public func \(raw: funcName)() -> UnsafeMutableRawPointer /* Any.Type */ {
75-
unsafeBitCast(\(raw: nominal.swiftTypeName).self, to: UnsafeMutableRawPointer.self)
75+
return unsafeBitCast(\(raw: nominal.swiftTypeName).self, to: UnsafeMutableRawPointer.self)
7676
}
7777
"""
7878
}
@@ -90,9 +90,9 @@ struct SwiftThunkTranslator {
9090
"""
9191
@_cdecl("\(raw: thunkName)")
9292
public func \(raw: thunkName)(\(raw: st.renderSwiftParamDecls(function, paramPassingStyle: nil))) -> UnsafeMutableRawPointer /* \(raw: parent.swiftTypeName) */ {
93-
print("[swift] init class \(raw: parent.swiftTypeName)")
9493
let _self = \(raw: parent.swiftTypeName)(\(raw: st.renderForwardSwiftParams(function, paramPassingStyle: nil)))
95-
return unsafeBitCast(_self, to: UnsafeMutableRawPointer.self)
94+
let self$ = unsafeBitCast(_self, to: UnsafeMutableRawPointer.self)
95+
return _swiftjava_swift_retain(object: self$)
9696
}
9797
"""
9898
]
@@ -128,7 +128,7 @@ struct SwiftThunkTranslator {
128128
"""
129129
@_cdecl("\(raw: thunkName)")
130130
public func \(raw: thunkName)(\(raw: st.renderSwiftParamDecls(decl, paramPassingStyle: paramPassingStyle))) \(raw: returnArrowTy) {
131-
\(raw: callBaseDot)\(raw: decl.baseIdentifier)(\(raw: st.renderForwardSwiftParams(decl, paramPassingStyle: paramPassingStyle)))
131+
return \(raw: callBaseDot)\(raw: decl.baseIdentifier)(\(raw: st.renderForwardSwiftParams(decl, paramPassingStyle: paramPassingStyle)))
132132
}
133133
"""
134134
]

Sources/SwiftKitSwift/SwiftKit.swift

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,6 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15-
// This is a "plain Swift" file containing various types of declarations,
16-
// that is exported to Java by using the `jextract-swift` tool.
17-
//
18-
// No annotations are necessary on the Swift side to perform the export.
19-
20-
// FIXME: this is a workaround until we can pass String to Swift directly
2115
@_silgen_name("getTypeByStringByteArray")
2216
public func getTypeByStringByteArray(_ name: UnsafePointer<UInt8>) -> Any.Type? {
2317
let string = String(cString: name)
@@ -26,9 +20,25 @@ public func getTypeByStringByteArray(_ name: UnsafePointer<UInt8>) -> Any.Type?
2620
return type
2721
}
2822

29-
//// FIXME: this is internal in stdlib, it would make things easier here
30-
//@_silgen_name("swift_stdlib_getTypeByMangledNameUntrusted")
31-
//public func _getTypeByMangledNameUntrusted(
32-
// _ name: UnsafePointer<UInt8>,
33-
// _ nameLength: UInt)
34-
// -> Any.Type?
23+
@_silgen_name("swift_retain")
24+
public func _swiftjava_swift_retain(object: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer
25+
26+
@_silgen_name("swift_release")
27+
public func _swiftjava_swift_release(object: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer
28+
29+
@_silgen_name("swift_retainCount")
30+
public func _swiftjava_swift_retainCount(object: UnsafeMutableRawPointer) -> Int
31+
32+
@_silgen_name("swift_isUniquelyReferenced")
33+
public func _swiftjava_swift_isUniquelyReferenced(object: UnsafeMutableRawPointer) -> Bool
34+
35+
36+
@_alwaysEmitIntoClient @_transparent
37+
internal func _swiftjava_withHeapObject<R>(
38+
of object: AnyObject,
39+
_ body: (UnsafeMutableRawPointer) -> R
40+
) -> R {
41+
defer { _fixLifetime(object) }
42+
let unmanaged = Unmanaged.passUnretained(object)
43+
return body(unmanaged.toOpaque())
44+
}

0 commit comments

Comments
 (0)