Skip to content

Commit 476087b

Browse files
authored
Merge pull request #240 from rintaro/jextract-value-or-reference
[JExtract] Unify mechanisms between value types and reference types
2 parents 592fca1 + 68f8049 commit 476087b

File tree

28 files changed

+274
-450
lines changed

28 files changed

+274
-450
lines changed

Samples/SwiftAndJavaJarSampleLib/src/jmh/java/org/swift/swiftkit/JavaToSwiftBenchmark.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public class JavaToSwiftBenchmark {
3333

3434
@State(Scope.Benchmark)
3535
public static class BenchmarkState {
36+
ClosableSwiftArena arena;
3637
MySwiftClass obj;
3738

3839
@Setup(Level.Trial)
@@ -43,7 +44,13 @@ public void beforeALl() {
4344
// Tune down debug statements so they don't fill up stdout
4445
System.setProperty("jextract.trace.downcalls", "false");
4546

46-
obj = new MySwiftClass(1, 2);
47+
arena = SwiftArena.ofConfined();
48+
obj = new MySwiftClass(1, 2, arena);
49+
}
50+
51+
@TearDown(Level.Trial)
52+
public void afterAll() {
53+
arena.close();
4754
}
4855
}
4956

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ static void examples() {
4444

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

4949
// just checking retains/releases work
50-
SwiftKit.retain(obj.$memorySegment());
51-
SwiftKit.release(obj.$memorySegment());
50+
SwiftKit.retain(obj);
51+
SwiftKit.release(obj);
5252

5353
obj.voidMethod();
5454
obj.takeIntMethod(42);

Samples/SwiftAndJavaJarSampleLib/src/test/java/com/example/swift/MySwiftClassTest.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import org.junit.jupiter.api.Disabled;
1818
import org.junit.jupiter.api.Test;
19+
import org.swift.swiftkit.SwiftArena;
1920
import org.swift.swiftkit.SwiftKit;
2021

2122
import java.io.File;
@@ -41,8 +42,8 @@ void checkPaths(Throwable throwable) {
4142

4243
@Test
4344
void test_MySwiftClass_voidMethod() {
44-
try {
45-
MySwiftClass o = new MySwiftClass(12, 42);
45+
try(var arena = SwiftArena.ofConfined()) {
46+
MySwiftClass o = new MySwiftClass(12, 42, arena);
4647
o.voidMethod();
4748
} catch (Throwable throwable) {
4849
checkPaths(throwable);
@@ -51,17 +52,21 @@ void test_MySwiftClass_voidMethod() {
5152

5253
@Test
5354
void test_MySwiftClass_makeIntMethod() {
54-
MySwiftClass o = new MySwiftClass(12, 42);
55-
var got = o.makeIntMethod();
56-
assertEquals(12, got);
55+
try(var arena = SwiftArena.ofConfined()) {
56+
MySwiftClass o = new MySwiftClass(12, 42, arena);
57+
var got = o.makeIntMethod();
58+
assertEquals(12, got);
59+
}
5760
}
5861

5962
@Test
6063
@Disabled // TODO: Need var mangled names in interfaces
6164
void test_MySwiftClass_property_len() {
62-
MySwiftClass o = new MySwiftClass(12, 42);
63-
var got = o.getLen();
64-
assertEquals(12, got);
65+
try(var arena = SwiftArena.ofConfined()) {
66+
MySwiftClass o = new MySwiftClass(12, 42, arena);
67+
var got = o.getLen();
68+
assertEquals(12, got);
69+
}
6570
}
6671

6772
}

Samples/SwiftAndJavaJarSampleLib/src/test/java/org/swift/swiftkit/MySwiftClassTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ public class MySwiftClassTest {
2525
@Test
2626
void call_retain_retainCount_release() {
2727
var arena = SwiftArena.ofConfined();
28-
var obj = new MySwiftClass(arena, 1, 2);
28+
var obj = new MySwiftClass(1, 2, arena);
2929

30-
assertEquals(1, SwiftKit.retainCount(obj.$memorySegment()));
30+
assertEquals(1, SwiftKit.retainCount(obj));
3131
// TODO: test directly on SwiftHeapObject inheriting obj
3232

33-
SwiftKit.retain(obj.$memorySegment());
34-
assertEquals(2, SwiftKit.retainCount(obj.$memorySegment()));
33+
SwiftKit.retain(obj);
34+
assertEquals(2, SwiftKit.retainCount(obj));
3535

36-
SwiftKit.release(obj.$memorySegment());
37-
assertEquals(1, SwiftKit.retainCount(obj.$memorySegment()));
36+
SwiftKit.release(obj);
37+
assertEquals(1, SwiftKit.retainCount(obj));
3838
}
3939
}

Samples/SwiftAndJavaJarSampleLib/src/test/java/org/swift/swiftkit/SwiftArenaTest.java

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -39,37 +39,15 @@ static boolean isAmd64() {
3939
@DisabledIf("isAmd64")
4040
public void arena_releaseClassOnClose_class_ok() {
4141
try (var arena = SwiftArena.ofConfined()) {
42-
var obj = new MySwiftClass(arena,1, 2);
42+
var obj = new MySwiftClass(1, 2, arena);
4343

44-
retain(obj.$memorySegment());
45-
assertEquals(2, retainCount(obj.$memorySegment()));
44+
retain(obj);
45+
assertEquals(2, retainCount(obj));
4646

47-
release(obj.$memorySegment());
48-
assertEquals(1, retainCount(obj.$memorySegment()));
47+
release(obj);
48+
assertEquals(1, retainCount(obj));
4949
}
5050

5151
// TODO: should we zero out the $memorySegment perhaps?
5252
}
53-
54-
@Test
55-
public void arena_releaseClassOnClose_class_leaked() {
56-
String memorySegmentDescription = "<none>";
57-
58-
try {
59-
try (var arena = SwiftArena.ofConfined()) {
60-
var obj = new MySwiftClass(arena,1, 2);
61-
memorySegmentDescription = obj.$memorySegment().toString();
62-
63-
// Pretend that we "leaked" the class, something still holds a reference to it while we try to destroy it
64-
retain(obj.$memorySegment());
65-
assertEquals(2, retainCount(obj.$memorySegment()));
66-
}
67-
68-
fail("Expected exception to be thrown while the arena is closed!");
69-
} catch (Exception ex) {
70-
// The message should point out which objects "leaked":
71-
assertTrue(ex.getMessage().contains(memorySegmentDescription));
72-
}
73-
74-
}
7553
}

Samples/SwiftKitSampleApp/src/jmh/java/org/swift/swiftkit/JavaToSwiftBenchmark.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public static class BenchmarkState {
3737
@Setup(Level.Trial)
3838
public void beforeAll() {
3939
arena = SwiftArena.ofConfined();
40-
obj = new MySwiftClass(arena, 1, 2);
40+
obj = new MySwiftClass(1, 2, arena);
4141
}
4242

4343
@TearDown(Level.Trial)

Samples/SwiftKitSampleApp/src/jmh/java/org/swift/swiftkit/StringPassingBenchmark.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public class StringPassingBenchmark {
4646
@Setup(Level.Trial)
4747
public void beforeAll() {
4848
arena = SwiftArena.ofConfined();
49-
obj = new MySwiftClass(arena, 1, 2);
49+
obj = new MySwiftClass(1, 2, arena);
5050
string = makeString(stringLen);
5151
}
5252

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,19 @@ static void examples() {
4242

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

4747
// just checking retains/releases work
48-
SwiftKit.retain(obj.$memorySegment());
49-
SwiftKit.release(obj.$memorySegment());
48+
SwiftKit.trace("retainCount = " + SwiftKit.retainCount(obj));
49+
SwiftKit.retain(obj);
50+
SwiftKit.trace("retainCount = " + SwiftKit.retainCount(obj));
51+
SwiftKit.release(obj);
52+
SwiftKit.trace("retainCount = " + SwiftKit.retainCount(obj));
5053

5154
obj.voidMethod();
5255
obj.takeIntMethod(42);
5356

54-
MySwiftStruct swiftValue = new MySwiftStruct(arena, 2222, 1111);
57+
MySwiftStruct swiftValue = new MySwiftStruct(2222, 1111, arena);
5558
}
5659

5760
System.out.println("DONE.");

Samples/SwiftKitSampleApp/src/test/java/com/example/swift/MySwiftClassTest.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import org.junit.jupiter.api.Disabled;
1818
import org.junit.jupiter.api.Test;
19+
import org.swift.swiftkit.SwiftArena;
1920
import org.swift.swiftkit.SwiftKit;
2021

2122
import java.io.File;
@@ -40,8 +41,8 @@ void checkPaths(Throwable throwable) {
4041

4142
@Test
4243
void test_MySwiftClass_voidMethod() {
43-
try {
44-
MySwiftClass o = new MySwiftClass(12, 42);
44+
try(var arena = SwiftArena.ofConfined()) {
45+
MySwiftClass o = new MySwiftClass(12, 42, arena);
4546
o.voidMethod();
4647
} catch (Throwable throwable) {
4748
checkPaths(throwable);
@@ -50,17 +51,21 @@ void test_MySwiftClass_voidMethod() {
5051

5152
@Test
5253
void test_MySwiftClass_makeIntMethod() {
53-
MySwiftClass o = new MySwiftClass(12, 42);
54-
var got = o.makeIntMethod();
55-
assertEquals(12, got);
54+
try(var arena = SwiftArena.ofConfined()) {
55+
MySwiftClass o = new MySwiftClass(12, 42, arena);
56+
var got = o.makeIntMethod();
57+
assertEquals(12, got);
58+
}
5659
}
5760

5861
@Test
5962
@Disabled // TODO: Need var mangled names in interfaces
6063
void test_MySwiftClass_property_len() {
61-
MySwiftClass o = new MySwiftClass(12, 42);
62-
var got = o.getLen();
63-
assertEquals(12, got);
64+
try(var arena = SwiftArena.ofConfined()) {
65+
MySwiftClass o = new MySwiftClass(12, 42, arena);
66+
var got = o.getLen();
67+
assertEquals(12, got);
68+
}
6469
}
6570

6671
}

Samples/SwiftKitSampleApp/src/test/java/org/swift/swiftkit/MySwiftClassTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ public class MySwiftClassTest {
2525
@Test
2626
void call_retain_retainCount_release() {
2727
var arena = SwiftArena.ofConfined();
28-
var obj = new MySwiftClass(arena, 1, 2);
28+
var obj = new MySwiftClass(1, 2, arena);
2929

30-
assertEquals(1, SwiftKit.retainCount(obj.$memorySegment()));
30+
assertEquals(1, SwiftKit.retainCount(obj));
3131
// TODO: test directly on SwiftHeapObject inheriting obj
3232

33-
SwiftKit.retain(obj.$memorySegment());
34-
assertEquals(2, SwiftKit.retainCount(obj.$memorySegment()));
33+
SwiftKit.retain(obj);
34+
assertEquals(2, SwiftKit.retainCount(obj));
3535

36-
SwiftKit.release(obj.$memorySegment());
37-
assertEquals(1, SwiftKit.retainCount(obj.$memorySegment()));
36+
SwiftKit.release(obj);
37+
assertEquals(1, SwiftKit.retainCount(obj));
3838
}
3939
}

Samples/SwiftKitSampleApp/src/test/java/org/swift/swiftkit/MySwiftStructTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ void create_struct() {
2626
try (var arena = SwiftArena.ofConfined()) {
2727
long cap = 12;
2828
long len = 34;
29-
var struct = new MySwiftStruct(arena, cap, len);
29+
var struct = new MySwiftStruct(cap, len, arena);
3030

3131
assertEquals(cap, struct.getCapacity());
3232
assertEquals(len, struct.getLength());

Samples/SwiftKitSampleApp/src/test/java/org/swift/swiftkit/SwiftArenaTest.java

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ static boolean isAmd64() {
4040
@DisabledIf("isAmd64")
4141
public void arena_releaseClassOnClose_class_ok() {
4242
try (var arena = SwiftArena.ofConfined()) {
43-
var obj = new MySwiftClass(arena,1, 2);
43+
var obj = new MySwiftClass(1, 2, arena);
4444

45-
retain(obj.$memorySegment());
46-
assertEquals(2, retainCount(obj.$memorySegment()));
45+
retain(obj);
46+
assertEquals(2, retainCount(obj));
4747

48-
release(obj.$memorySegment());
49-
assertEquals(1, retainCount(obj.$memorySegment()));
48+
release(obj);
49+
assertEquals(1, retainCount(obj));
5050
}
5151
}
5252

@@ -57,7 +57,7 @@ public void arena_markAsDestroyed_preventUseAfterFree_class() {
5757
MySwiftClass unsafelyEscapedOutsideArenaScope = null;
5858

5959
try (var arena = SwiftArena.ofConfined()) {
60-
var obj = new MySwiftClass(arena,1, 2);
60+
var obj = new MySwiftClass(1, 2, arena);
6161
unsafelyEscapedOutsideArenaScope = obj;
6262
}
6363

@@ -76,7 +76,7 @@ public void arena_markAsDestroyed_preventUseAfterFree_struct() {
7676
MySwiftStruct unsafelyEscapedOutsideArenaScope = null;
7777

7878
try (var arena = SwiftArena.ofConfined()) {
79-
var s = new MySwiftStruct(arena,1, 2);
79+
var s = new MySwiftStruct(1, 2, arena);
8080
unsafelyEscapedOutsideArenaScope = s;
8181
}
8282

@@ -88,27 +88,6 @@ public void arena_markAsDestroyed_preventUseAfterFree_struct() {
8888
}
8989
}
9090

91-
@Test
92-
public void arena_releaseClassOnClose_class_leaked() {
93-
String memorySegmentDescription = "<none>";
94-
95-
try {
96-
try (var arena = SwiftArena.ofConfined()) {
97-
var obj = new MySwiftClass(arena,1, 2);
98-
memorySegmentDescription = obj.$memorySegment().toString();
99-
100-
// Pretend that we "leaked" the class, something still holds a reference to it while we try to destroy it
101-
retain(obj.$memorySegment());
102-
assertEquals(2, retainCount(obj.$memorySegment()));
103-
}
104-
105-
fail("Expected exception to be thrown while the arena is closed!");
106-
} catch (Exception ex) {
107-
// The message should point out which objects "leaked":
108-
assertTrue(ex.getMessage().contains(memorySegmentDescription));
109-
}
110-
}
111-
11291
@Test
11392
public void arena_initializeWithCopy_struct() {
11493

Sources/JExtractSwift/ImportedDecls.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,12 @@ public struct ImportedFunc: ImportedDecl, CustomStringConvertible {
267267
public var isInit: Bool = false
268268

269269
public var isIndirectReturn: Bool {
270-
returnType.isValueType ||
271-
(isInit && (parent?.isValueType ?? false))
270+
switch returnType.originalSwiftTypeKind {
271+
case .actor, .class, .struct, .enum:
272+
return true
273+
default:
274+
return false
275+
}
272276
}
273277

274278
public init(

0 commit comments

Comments
 (0)