Skip to content

Commit 2afc1d9

Browse files
committed
correct how we get the unsafe self pointer of a struct
1 parent c0dac2c commit 2afc1d9

File tree

4 files changed

+88
-26
lines changed

4 files changed

+88
-26
lines changed

Samples/SwiftKitSampleApp/Sources/MySwiftLibrary/MySwiftLibrary.swift

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,6 @@ public class MySwiftClass {
134134
}
135135
}
136136

137-
public struct MySwiftStruct {
138-
public var number: Int
139-
140-
public init(number: Int) {
141-
self.number = number
142-
}
143-
144-
public func getTheNumber() -> Int {
145-
number
146-
}
147-
}
148-
149137
// ==== Internal helpers
150138

151139
package func p(_ msg: String, file: String = #fileID, line: UInt = #line, function: String = #function) {
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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+
import Glibc
17+
#else
18+
import Darwin.C
19+
#endif
20+
21+
public struct MySwiftStruct {
22+
private var numberA: Int
23+
private var numberB: Int
24+
private var numberC: Int
25+
private var numberD: Int
26+
27+
public init(number: Int) {
28+
self.numberA = number
29+
self.numberB = number
30+
self.numberC = number
31+
self.numberD = number
32+
}
33+
34+
public func getTheNumber() -> Int {
35+
numberA
36+
}
37+
}
38+
39+
public struct MyHugeSwiftStruct {
40+
private var numberA: Int
41+
private var numberB: Int
42+
private var numberC: Int
43+
private var numberD: Int
44+
45+
private var numberA2: Int = 0
46+
private var numberB2: Int = 0
47+
private var numberC2: Int = 0
48+
private var numberD2: Int = 0
49+
50+
public init(number: Int) {
51+
self.numberA = number
52+
self.numberB = number
53+
self.numberC = number
54+
self.numberD = number
55+
}
56+
57+
public func getTheNumber() -> Int {
58+
numberA
59+
}
60+
}

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ static void examples() {
5757
// public func getArrayMySwiftClass() -> [MySwiftClass]
5858
SwiftArrayRef<MySwiftClass> arr = ManualImportedMethods.getArrayMySwiftClass();
5959

60-
precondition(3, arr.count());
60+
// precondition(3, arr.count());
6161

6262
MySwiftClass first = arr.get(0);
6363
System.out.println("[java] first = " + first);
@@ -78,10 +78,17 @@ static void examples() {
7878
precondition(22, second.getterForCap());
7979

8080
try (var arena = SwiftArena.ofConfined()) {
81-
MySwiftStruct struct = new MySwiftStruct(arena, 44);
82-
System.out.println("struct.getTheNumber() = " + struct.getTheNumber());
83-
long theNumber = struct.getTheNumber();
84-
precondition(44, theNumber);
81+
var struct = new MySwiftStruct(arena, 44);
82+
// System.out.println("struct.getTheNumber() = " + struct.getTheNumber());
83+
// long theNumber = struct.getTheNumber();
84+
// precondition(44, theNumber);
85+
86+
System.out.println("struct.$layout() = " + struct.$layout());
87+
System.out.println("struct.$layout() = " + struct.$layout().byteSize());
88+
89+
var huge = new MyHugeSwiftStruct(arena, 44);
90+
System.out.println("huge.$layout() = " + huge.$layout());
91+
System.out.println("huge.$layout() = " + huge.$layout().byteSize());
8592
}
8693

8794

Sources/JExtractSwift/SwiftThunkTranslator.swift

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,21 +86,27 @@ struct SwiftThunkTranslator {
8686
let thunkName = self.st.thunkNameRegistry.functionThunkName(
8787
module: st.swiftModuleName, decl: function)
8888

89-
let maybeRetainedSelf: String =
90-
if parent.isReferenceType {
91-
"_swiftjava_swift_retain(object: self$)"
92-
} else {
93-
"self$"
94-
}
89+
let returnSelf: String =
90+
if parent.isReferenceType {
91+
"""
92+
let self$ = unsafeBitCast(_self, to: UnsafeMutableRawPointer.self)
93+
_swiftjava_swift_retain(object: self$)
94+
"""
95+
} else {
96+
"""
97+
// FIXME: Reconsider how else we want to deal with value types being returned to JVM
98+
let self$ = withUnsafePointer(to: &_self) { $0 }
99+
return UnsafeMutableRawPointer(mutating: self$)
100+
"""
101+
}
95102

96103
return
97104
[
98105
"""
99106
@_cdecl("\(raw: thunkName)")
100107
public func \(raw: thunkName)(\(raw: st.renderSwiftParamDecls(function, paramPassingStyle: nil))) -> UnsafeMutableRawPointer /* \(raw: parent.swiftTypeName) */ {
101-
let _self = \(raw: parent.swiftTypeName)(\(raw: st.renderForwardSwiftParams(function, paramPassingStyle: nil)))
102-
let self$ = unsafeBitCast(_self, to: UnsafeMutableRawPointer.self)
103-
return \(raw: maybeRetainedSelf)
108+
var _self = \(raw: parent.swiftTypeName)(\(raw: st.renderForwardSwiftParams(function, paramPassingStyle: nil)))
109+
\(raw: returnSelf)
104110
}
105111
"""
106112
]
@@ -123,6 +129,7 @@ struct SwiftThunkTranslator {
123129
let callBaseDot: String
124130
if let parent = decl.parent {
125131
paramPassingStyle = .swiftThunkSelf
132+
// FIXME: for structs
126133
callBase = "let self$ = unsafeBitCast(_self, to: \(parent.originalSwiftType).self)"
127134
callBaseDot = "self$."
128135
} else {

0 commit comments

Comments
 (0)