Skip to content

Commit 3a396e2

Browse files
committed
Some steps towards importing structs as SwiftValue
This was a pre-holidays WIP and it's gotten far enough to be useful as a small step
1 parent a2e8551 commit 3a396e2

File tree

13 files changed

+277
-69
lines changed

13 files changed

+277
-69
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
public class MySwiftClass {
16+
17+
public var len: Int
18+
public var cap: Int
19+
20+
public init(len: Int, cap: Int) {
21+
self.len = len
22+
self.cap = cap
23+
24+
p("\(MySwiftClass.self).len = \(self.len)")
25+
p("\(MySwiftClass.self).cap = \(self.cap)")
26+
let addr = unsafeBitCast(self, to: UInt64.self)
27+
p("initializer done, self = 0x\(String(addr, radix: 16, uppercase: true))")
28+
}
29+
30+
deinit {
31+
let addr = unsafeBitCast(self, to: UInt64.self)
32+
p("Deinit, self = 0x\(String(addr, radix: 16, uppercase: true))")
33+
}
34+
35+
public var counter: Int32 = 0
36+
37+
public func voidMethod() {
38+
p("")
39+
}
40+
41+
public func takeIntMethod(i: Int) {
42+
p("i:\(i)")
43+
}
44+
45+
public func echoIntMethod(i: Int) -> Int {
46+
p("i:\(i)")
47+
return i
48+
}
49+
50+
public func makeIntMethod() -> Int {
51+
p("make int -> 12")
52+
return 12
53+
}
54+
55+
public func makeRandomIntMethod() -> Int {
56+
return Int.random(in: 1..<256)
57+
}
58+
}

Samples/SwiftKitSampleApp/Sources/MySwiftLibrary/MySwiftLibrary.swift

Lines changed: 1 addition & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -39,63 +39,9 @@ public func globalCallMeRunnable(run: () -> ()) {
3939
run()
4040
}
4141

42-
public class MySwiftClass {
43-
44-
public var len: Int
45-
public var cap: Int
46-
47-
public init(len: Int, cap: Int) {
48-
self.len = len
49-
self.cap = cap
50-
51-
p("\(MySwiftClass.self).len = \(self.len)")
52-
p("\(MySwiftClass.self).cap = \(self.cap)")
53-
let addr = unsafeBitCast(self, to: UInt64.self)
54-
p("initializer done, self = 0x\(String(addr, radix: 16, uppercase: true))")
55-
}
56-
57-
deinit {
58-
let addr = unsafeBitCast(self, to: UInt64.self)
59-
p("Deinit, self = 0x\(String(addr, radix: 16, uppercase: true))")
60-
}
61-
62-
public var counter: Int32 = 0
63-
64-
public func voidMethod() {
65-
p("")
66-
}
67-
68-
public func takeIntMethod(i: Int) {
69-
p("i:\(i)")
70-
}
71-
72-
public func echoIntMethod(i: Int) -> Int {
73-
p("i:\(i)")
74-
return i
75-
}
76-
77-
public func makeIntMethod() -> Int {
78-
p("make int -> 12")
79-
return 12
80-
}
81-
82-
public func makeRandomIntMethod() -> Int {
83-
return Int.random(in: 1..<256)
84-
}
85-
}
86-
8742
// ==== Internal helpers
8843

89-
private func p(_ msg: String, file: String = #fileID, line: UInt = #line, function: String = #function) {
44+
func p(_ msg: String, file: String = #fileID, line: UInt = #line, function: String = #function) {
9045
print("[swift][\(file):\(line)](\(function)) \(msg)")
9146
fflush(stdout)
9247
}
93-
94-
#if os(Linux)
95-
// FIXME: why do we need this workaround?
96-
@_silgen_name("_objc_autoreleaseReturnValue")
97-
public func _objc_autoreleaseReturnValue(a: Any) {}
98-
99-
@_silgen_name("objc_autoreleaseReturnValue")
100-
public func objc_autoreleaseReturnValue(a: Any) {}
101-
#endif
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
public struct MySwiftStruct {
16+
17+
public var number: Int
18+
19+
public init(number: Int) {
20+
self.number = number
21+
}
22+
23+
public func voidMethod() {
24+
p("")
25+
}
26+
27+
public func takeIntMethod(i: Int) {
28+
p("i:\(i)")
29+
}
30+
31+
public func echoIntMethod(i: Int) -> Int {
32+
p("i:\(i)")
33+
return i
34+
}
35+
36+
public func makeIntMethod() -> Int {
37+
p("make int -> 12")
38+
return 12
39+
}
40+
41+
public func makeRandomIntMethod() -> Int {
42+
return Int.random(in: 1..<256)
43+
}
44+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#if os(Linux)
16+
// FIXME: why do we need this workaround?
17+
@_silgen_name("_objc_autoreleaseReturnValue")
18+
public func _objc_autoreleaseReturnValue(a: Any) {}
19+
20+
@_silgen_name("objc_autoreleaseReturnValue")
21+
public func objc_autoreleaseReturnValue(a: Any) {}
22+
#endif

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ static void examples() {
5252

5353
obj.voidMethod();
5454
obj.takeIntMethod(42);
55+
56+
MySwiftStruct swiftValue = new MySwiftStruct(12);
57+
5558
}
5659

5760
System.out.println("DONE.");
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
package com.example.swift;
16+
17+
import org.junit.jupiter.api.Disabled;
18+
import org.junit.jupiter.api.Test;
19+
import org.swift.swiftkit.SwiftArena;
20+
import org.swift.swiftkit.SwiftKit;
21+
22+
import java.io.File;
23+
import java.util.stream.Stream;
24+
25+
import static org.junit.jupiter.api.Assertions.assertEquals;
26+
27+
public class MySwiftStructTest {
28+
29+
@Test
30+
void test_MySwiftClass_voidMethod() {
31+
try (var arena = SwiftArena.ofConfined()) {
32+
MySwiftStruct o = new MySwiftStruct(12);
33+
// o.voidMethod();
34+
}
35+
}
36+
37+
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ public void arena_releaseClassOnClose_class_leaked() {
7070
// The message should point out which objects "leaked":
7171
assertTrue(ex.getMessage().contains(memorySegmentDescription));
7272
}
73+
}
74+
75+
@Test
76+
public void arena_initializeWithCopy_struct() {
7377

7478
}
7579
}

Sources/ExampleSwiftLibrary/MySwiftLibrary.swift

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,7 @@ public func _getTypeByMangledNameInEnvironment(
9797

9898
// ==== Internal helpers
9999

100-
private func p(_ msg: String, file: String = #fileID, line: UInt = #line, function: String = #function) {
100+
func p(_ msg: String, file: String = #fileID, line: UInt = #line, function: String = #function) {
101101
print("[swift][\(file):\(line)](\(function)) \(msg)")
102102
fflush(stdout)
103103
}
104-
105-
#if os(Linux)
106-
// FIXME: why do we need this workaround?
107-
@_silgen_name("_objc_autoreleaseReturnValue")
108-
public func _objc_autoreleaseReturnValue(a: Any) {}
109-
110-
@_silgen_name("objc_autoreleaseReturnValue")
111-
public func objc_autoreleaseReturnValue(a: Any) {}
112-
#endif

Sources/JExtractSwift/ImportedDecls.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ public struct ImportedNominalType: ImportedDecl {
4949
javaType: javaType
5050
)
5151
}
52+
53+
public var isReferenceType: Bool {
54+
switch self.kind {
55+
case .class, .actor:
56+
return true
57+
case .enum, .struct:
58+
return false
59+
}
60+
}
5261

5362
/// The Java class name without the package.
5463
public var javaClassName: String {

Sources/JExtractSwift/Swift2JavaTranslator+Printing.swift

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ extension Swift2JavaTranslator {
173173
printPackage(&printer)
174174
printImports(&printer)
175175

176-
printClass(&printer, decl) { printer in
176+
printNominal(&printer, decl) { printer in
177177
// Prepare type metadata, we're going to need these when invoking e.g. initializers so cache them in a static.
178178
// We call into source swift-java source generated accessors which give us the type of the Swift object:
179179
// TODO: seems we no longer need the mangled name per se, so avoiding such constant and downcall
@@ -257,10 +257,17 @@ extension Swift2JavaTranslator {
257257
printer.print("")
258258
}
259259

260-
public func printClass(
260+
public func printNominal(
261261
_ printer: inout CodePrinter, _ decl: ImportedNominalType, body: (inout CodePrinter) -> Void
262262
) {
263-
printer.printTypeDecl("public final class \(decl.javaClassName) implements SwiftHeapObject") {
263+
let parentProtocol: String
264+
if decl.isReferenceType {
265+
parentProtocol = "SwiftHeapObject"
266+
} else {
267+
parentProtocol = "SwiftValue"
268+
}
269+
270+
printer.printTypeDecl("public final class \(decl.javaClassName) implements \(parentProtocol)") {
264271
printer in
265272
// ==== Storage of the class
266273
printClassSelfProperty(&printer, decl)

0 commit comments

Comments
 (0)