Skip to content

Commit 50750e0

Browse files
committed
Properly avoid Any in thunks we're emitting
Correct reference counting in init thunk lots of fixing around how we deal with config and library loading move trace functions into SwiftKit; avoid regenerating adjust swift source gen tests
1 parent 7f9a986 commit 50750e0

File tree

12 files changed

+108
-104
lines changed

12 files changed

+108
-104
lines changed

.github/scripts/validate_samples.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ for samplePackage in ${SAMPLE_PACKAGES} ; do
2222
./${CI_VALIDATE_SCRIPT} || exit
2323
elif [[ $(find . -name 'build.gradle*' -maxdepth 1) ]]; then
2424
echo -e "${BOLD}Gradle${RESET} build..."
25-
./gradlew build --info || exit
25+
./gradlew build || ./gradlew build --info # re-run to get better failure output
2626
else
2727
echo -e "${BOLD}SwiftPM${RESET} build..."
2828
swift build || exit

Plugins/JExtractSwiftCommandPlugin/JExtractSwiftCommandPlugin.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
6060
print("[swift-java-command] error: Failed to extract from target '\(target.name)': \(error)")
6161
}
6262

63+
print("[swift-java-command] Done.")
6364
}
6465
print("[swift-java-command] Generating sources: " + "done".green + ".")
6566
}

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

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,33 +24,35 @@
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 = " +SwiftKit.getJavaLibraryPath());
3736

3837
examples();
39-
4038
}
4139

4240
static void examples() {
4341
MySwiftLibrary.helloWorld();
4442

4543
MySwiftLibrary.globalTakeInt(1337);
4644

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

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

52-
obj.voidMethod();
53-
obj.takeIntMethod(42);
53+
obj.voidMethod();
54+
obj.takeIntMethod(42);
55+
}
5456

5557
System.out.println("DONE.");
5658
}

Sources/JExtractSwift/Swift2JavaTranslator+Printing.swift

Lines changed: 15 additions & 46 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("")
@@ -258,9 +267,6 @@ extension Swift2JavaTranslator {
258267
// Layout of the class
259268
printClassMemoryLayout(&printer, decl)
260269

261-
// Render the 'trace' functions etc
262-
printTraceFunctionDecls(&printer)
263-
264270
body(&printer)
265271
}
266272
}
@@ -273,9 +279,6 @@ extension Swift2JavaTranslator {
273279
printClassConstants(printer: &printer)
274280
printTypeMappingDecls(&printer)
275281

276-
// Render the 'trace' functions etc
277-
printTraceFunctionDecls(&printer)
278-
279282
printer.print(
280283
"""
281284
static MemorySegment findOrThrow(String symbol) {
@@ -434,40 +437,6 @@ extension Swift2JavaTranslator {
434437
)
435438
}
436439

437-
public func printTraceFunctionDecls(_ printer: inout CodePrinter) {
438-
printer.print(
439-
"""
440-
static final boolean TRACE_DOWNCALLS = Boolean.getBoolean("jextract.trace.downcalls");
441-
442-
static void traceDowncall(Object... args) {
443-
var ex = new RuntimeException();
444-
445-
String traceArgs = Arrays.stream(args)
446-
.map(Object::toString)
447-
.collect(Collectors.joining(", "));
448-
System.out.printf("[java][%s:%d] Downcall: %s(%s)\\n",
449-
ex.getStackTrace()[2].getFileName(),
450-
ex.getStackTrace()[2].getLineNumber(),
451-
ex.getStackTrace()[2].getMethodName(),
452-
traceArgs);
453-
}
454-
455-
static void trace(Object... args) {
456-
var ex = new RuntimeException();
457-
458-
String traceArgs = Arrays.stream(args)
459-
.map(Object::toString)
460-
.collect(Collectors.joining(", "));
461-
System.out.printf("[java][%s:%d] %s: %s\\n",
462-
ex.getStackTrace()[2].getFileName(),
463-
ex.getStackTrace()[2].getLineNumber(),
464-
ex.getStackTrace()[2].getMethodName(),
465-
traceArgs);
466-
}
467-
"""
468-
)
469-
}
470-
471440
public func printClassConstructors(_ printer: inout CodePrinter, _ decl: ImportedFunc) {
472441
guard let parentName = decl.parent else {
473442
fatalError("init must be inside a parent type! Was: \(decl)")
@@ -515,8 +484,8 @@ extension Swift2JavaTranslator {
515484
public \(parentName.unqualifiedJavaTypeName)(SwiftArena arena, \(renderJavaParamDecls(decl, paramPassingStyle: .wrapper))) {
516485
var mh$ = \(descClassIdentifier).HANDLE;
517486
try {
518-
if (TRACE_DOWNCALLS) {
519-
traceDowncall(\(renderForwardJavaParams(decl, paramPassingStyle: nil)));
487+
if (SwiftKit.TRACE_DOWNCALLS) {
488+
SwiftKit.traceDowncall(\(renderForwardJavaParams(decl, paramPassingStyle: nil)));
520489
}
521490
522491
this.selfMemorySegment = (MemorySegment) mh$.invokeExact(\(renderForwardJavaParams(decl, paramPassingStyle: nil)), TYPE_METADATA.$memorySegment());
@@ -747,8 +716,8 @@ extension Swift2JavaTranslator {
747716
\(renderUpcallHandles(decl))
748717
""",
749718
"""
750-
if (TRACE_DOWNCALLS) {
751-
traceDowncall(\(renderForwardJavaParams(decl, paramPassingStyle: .memorySegment)));
719+
if (SwiftKit.TRACE_DOWNCALLS) {
720+
SwiftKit.traceDowncall(\(renderForwardJavaParams(decl, paramPassingStyle: .memorySegment)));
752721
}
753722
\(maybeReturnCast) mh$.invokeExact(\(renderForwardJavaParams(decl, paramPassingStyle: paramPassingStyle)));
754723
} catch (Throwable ex$) {
@@ -800,8 +769,8 @@ extension Swift2JavaTranslator {
800769
public static \(returnTy) \(decl.baseIdentifier)(\(renderJavaParamDecls(decl, paramPassingStyle: paramPassingStyle))) {
801770
var mh$ = \(decl.baseIdentifier).HANDLE;
802771
try {
803-
if (TRACE_DOWNCALLS) {
804-
traceDowncall(\(renderForwardJavaParams(decl, paramPassingStyle: .memorySegment)));
772+
if (SwiftKit.TRACE_DOWNCALLS) {
773+
SwiftKit.traceDowncall(\(renderForwardJavaParams(decl, paramPassingStyle: .memorySegment)));
805774
}
806775
\(maybeReturnCast) mh$.invokeExact(\(renderForwardJavaParams(decl, paramPassingStyle: paramPassingStyle)));
807776
} catch (Throwable ex$) {

Sources/JExtractSwift/SwiftThunkTranslator.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ struct SwiftThunkTranslator {
7171
return
7272
"""
7373
@_cdecl("\(raw: funcName)")
74-
public func \(raw: funcName)() -> Any /* Any.Type */ {
75-
return \(raw: nominal.swiftTypeName).self
74+
public func \(raw: funcName)() -> UnsafeMutableRawPointer /* Any.Type */ {
75+
return unsafeBitCast(\(raw: nominal.swiftTypeName).self, to: UnsafeMutableRawPointer.self)
7676
}
7777
"""
7878
}
@@ -89,9 +89,10 @@ struct SwiftThunkTranslator {
8989
[
9090
"""
9191
@_cdecl("\(raw: thunkName)")
92-
public func \(raw: thunkName)(\(raw: st.renderSwiftParamDecls(function, paramPassingStyle: nil))) -> Any /* \(raw: parent.swiftTypeName) */ {
93-
print("[swift] init class \(raw: parent.swiftTypeName)")
94-
return \(raw: parent.swiftTypeName)(\(raw: st.renderForwardSwiftParams(function, paramPassingStyle: nil)))
92+
public func \(raw: thunkName)(\(raw: st.renderSwiftParamDecls(function, paramPassingStyle: nil))) -> UnsafeMutableRawPointer /* \(raw: parent.swiftTypeName) */ {
93+
let _self = \(raw: parent.swiftTypeName)(\(raw: st.renderForwardSwiftParams(function, paramPassingStyle: nil)))
94+
let self$ = unsafeBitCast(_self, to: UnsafeMutableRawPointer.self)
95+
return _swiftjava_swift_retain(object: self$)
9596
}
9697
"""
9798
]
@@ -127,7 +128,7 @@ struct SwiftThunkTranslator {
127128
"""
128129
@_cdecl("\(raw: thunkName)")
129130
public func \(raw: thunkName)(\(raw: st.renderSwiftParamDecls(decl, paramPassingStyle: paramPassingStyle))) \(raw: returnArrowTy) {
130-
\(raw: callBaseDot)\(raw: decl.baseIdentifier)(\(raw: st.renderForwardSwiftParams(decl, paramPassingStyle: paramPassingStyle)))
131+
return \(raw: callBaseDot)\(raw: decl.baseIdentifier)(\(raw: st.renderForwardSwiftParams(decl, paramPassingStyle: paramPassingStyle)))
131132
}
132133
"""
133134
]

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+
}

SwiftKit/src/main/java/org/swift/swiftkit/SwiftKit.java

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ public class SwiftKit {
2929

3030
public static final String STDLIB_DYLIB_NAME = "swiftCore";
3131
public static final String SWIFTKITSWIFT_DYLIB_NAME = "SwiftKitSwift";
32+
public static final boolean TRACE_DOWNCALLS = Boolean.getBoolean("jextract.trace.downcalls");
33+
3234
private static final String STDLIB_MACOS_DYLIB_PATH = "/usr/lib/swift/libswiftCore.dylib";
3335

3436
private static final Arena LIBRARY_ARENA = Arena.ofAuto();
35-
static final boolean TRACE_DOWNCALLS = Boolean.getBoolean("jextract.trace.downcalls");
3637

3738
@SuppressWarnings("unused")
3839
private static final boolean INITIALIZED_LIBS = loadLibraries(false);
@@ -62,12 +63,31 @@ private static SymbolLookup getSymbolLookup() {
6263
public SwiftKit() {
6364
}
6465

65-
static void traceDowncall(String name, Object... args) {
66-
String traceArgs = Arrays.stream(args)
67-
.map(Object::toString)
68-
.collect(Collectors.joining(", "));
69-
System.out.printf("[java] Downcall: %s(%s)\n", name, traceArgs);
70-
}
66+
public static void traceDowncall(Object... args) {
67+
var ex = new RuntimeException();
68+
69+
String traceArgs = Arrays.stream(args)
70+
.map(Object::toString)
71+
.collect(Collectors.joining(", "));
72+
System.out.printf("[java][%s:%d] Downcall: %s(%s)\n",
73+
ex.getStackTrace()[1].getFileName(),
74+
ex.getStackTrace()[1].getLineNumber(),
75+
ex.getStackTrace()[1].getMethodName(),
76+
traceArgs);
77+
}
78+
79+
public static void trace(Object... args) {
80+
var ex = new RuntimeException();
81+
82+
String traceArgs = Arrays.stream(args)
83+
.map(Object::toString)
84+
.collect(Collectors.joining(", "));
85+
System.out.printf("[java][%s:%d] %s: %s\n",
86+
ex.getStackTrace()[1].getFileName(),
87+
ex.getStackTrace()[1].getLineNumber(),
88+
ex.getStackTrace()[1].getMethodName(),
89+
traceArgs);
90+
}
7191

7292
static MemorySegment findOrThrow(String symbol) {
7393
return SYMBOL_LOOKUP.find(symbol)

Tests/JExtractSwiftTests/FuncCallbackImportTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ final class FuncCallbackImportTests {
6969
callMe_callback_handle$ = callMe_callback_handle$.bindTo(callback);
7070
Linker linker = Linker.nativeLinker();
7171
MemorySegment callback$ = linker.upcallStub(callMe_callback_handle$, callMe_callback_desc$, arena);
72-
if (TRACE_DOWNCALLS) {
73-
traceDowncall(callback$);
72+
if (SwiftKit.TRACE_DOWNCALLS) {
73+
SwiftKit.traceDowncall(callback$);
7474
}
7575
mh$.invokeExact(callback$);
7676
} catch (Throwable ex$) {

Tests/JExtractSwiftTests/MethodImportTests.swift

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ final class MethodImportTests {
9191
public static void helloWorld() {
9292
var mh$ = helloWorld.HANDLE;
9393
try {
94-
if (TRACE_DOWNCALLS) {
95-
traceDowncall();
94+
if (SwiftKit.TRACE_DOWNCALLS) {
95+
SwiftKit.traceDowncall();
9696
}
9797
mh$.invokeExact();
9898
} catch (Throwable ex$) {
@@ -134,8 +134,8 @@ final class MethodImportTests {
134134
public static void globalTakeInt(long i) {
135135
var mh$ = globalTakeInt.HANDLE;
136136
try {
137-
if (TRACE_DOWNCALLS) {
138-
traceDowncall(i);
137+
if (SwiftKit.TRACE_DOWNCALLS) {
138+
SwiftKit.traceDowncall(i);
139139
}
140140
mh$.invokeExact(i);
141141
} catch (Throwable ex$) {
@@ -177,8 +177,8 @@ final class MethodImportTests {
177177
public static void globalTakeIntLongString(int i32, long l, com.example.swift.String s) {
178178
var mh$ = globalTakeIntLongString.HANDLE;
179179
try {
180-
if (TRACE_DOWNCALLS) {
181-
traceDowncall(i32, l, s.$memorySegment());
180+
if (SwiftKit.TRACE_DOWNCALLS) {
181+
SwiftKit.traceDowncall(i32, l, s.$memorySegment());
182182
}
183183
mh$.invokeExact(i32, l, s.$memorySegment());
184184
} catch (Throwable ex$) {
@@ -220,8 +220,8 @@ final class MethodImportTests {
220220
public static void helloMemberFunction(java.lang.foreign.MemorySegment self$) {
221221
var mh$ = helloMemberFunction.HANDLE;
222222
try {
223-
if (TRACE_DOWNCALLS) {
224-
traceDowncall(self$);
223+
if (SwiftKit.TRACE_DOWNCALLS) {
224+
SwiftKit.traceDowncall(self$);
225225
}
226226
mh$.invokeExact(self$);
227227
} catch (Throwable ex$) {
@@ -263,8 +263,8 @@ final class MethodImportTests {
263263
public static void helloMemberInExtension(java.lang.foreign.MemorySegment self$) {
264264
var mh$ = helloMemberInExtension.HANDLE;
265265
try {
266-
if (TRACE_DOWNCALLS) {
267-
traceDowncall(self$);
266+
if (SwiftKit.TRACE_DOWNCALLS) {
267+
SwiftKit.traceDowncall(self$);
268268
}
269269
mh$.invokeExact(self$);
270270
} catch (Throwable ex$) {
@@ -306,8 +306,8 @@ final class MethodImportTests {
306306
public static void helloMemberFunction(java.lang.foreign.MemorySegment self$) {
307307
var mh$ = helloMemberFunction.HANDLE;
308308
try {
309-
if (TRACE_DOWNCALLS) {
310-
traceDowncall(self$);
309+
if (SwiftKit.TRACE_DOWNCALLS) {
310+
SwiftKit.traceDowncall(self$);
311311
}
312312
mh$.invokeExact(self$);
313313
} catch (Throwable ex$) {
@@ -431,8 +431,8 @@ final class MethodImportTests {
431431
public MySwiftClass(SwiftArena arena, long len, long cap) {
432432
var mh$ = init_len_cap.HANDLE;
433433
try {
434-
if (TRACE_DOWNCALLS) {
435-
traceDowncall(len, cap);
434+
if (SwiftKit.TRACE_DOWNCALLS) {
435+
SwiftKit.traceDowncall(len, cap);
436436
}
437437
this.selfMemorySegment = (MemorySegment) mh$.invokeExact(len, cap, TYPE_METADATA.$memorySegment());
438438
if (arena != null) {

0 commit comments

Comments
 (0)