Skip to content

Commit 57c489b

Browse files
committed
Centralize the printing of long -> "self$" unsafe pointer in JNI
printing
1 parent 9c41054 commit 57c489b

File tree

5 files changed

+66
-45
lines changed

5 files changed

+66
-45
lines changed

Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,8 @@ extension JNISwift2JavaGenerator {
235235
let initArguments = translatedDecl.translatedFunctionSignature.parameters.map(\.name)
236236
printer.print(
237237
"""
238-
long selfPointer = \(type.qualifiedName).allocatingInit(\(initArguments.joined(separator: ", ")));
239-
return new \(type.qualifiedName)(selfPointer, swiftArena$);
238+
long self$ = \(type.qualifiedName).allocatingInit(\(initArguments.joined(separator: ", ")));
239+
return new \(type.qualifiedName)(self$, swiftArena$);
240240
"""
241241
)
242242
}

Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,9 @@ extension JNISwift2JavaGenerator {
138138
// TODO: Throwing initializers
139139
printer.print(
140140
"""
141-
let selfPointer = UnsafeMutablePointer<\(typeName)>.allocate(capacity: 1)
142-
selfPointer.initialize(to: \(typeName)(\(downcallArguments)))
143-
return Int64(Int(bitPattern: selfPointer)).getJNIValue(in: environment)
141+
let self$ = UnsafeMutablePointer<\(typeName)>.allocate(capacity: 1)
142+
self$.initialize(to: \(typeName)(\(downcallArguments)))
143+
return Int64(Int(bitPattern: self$)).getJNIValue(in: environment)
144144
"""
145145
)
146146
}
@@ -184,22 +184,20 @@ extension JNISwift2JavaGenerator {
184184
let translatedDecl = self.translatedDecl(for: decl)! // We will only call this method if can translate the decl.
185185
let swiftParentName = decl.parentType!.asNominalTypeDeclaration!.qualifiedName
186186

187+
let selfPointerParam = JavaParameter(name: "selfPointer", type: .long)
187188
printCDecl(
188189
&printer,
189190
javaMethodName: "$\(translatedDecl.name)",
190191
parentName: translatedDecl.parentName,
191192
parameters: translatedDecl.translatedFunctionSignature.parameters + [
192-
JavaParameter(name: "selfPointer", type: .long)
193+
selfPointerParam
193194
],
194195
isStatic: true,
195196
resultType: translatedDecl.translatedFunctionSignature.resultType
196197
) { printer in
197-
printer.print(
198-
"""
199-
let self$ = UnsafeMutablePointer<\(swiftParentName)>(bitPattern: Int(Int64(fromJNI: selfPointer, in: environment!)))!
200-
"""
201-
)
202-
self.printFunctionDowncall(&printer, decl, calleeName: "self$.pointee")
198+
let selfVar = self.printSelfJLongToUnsafeMutablePointer(&printer,
199+
swiftParentName: swiftParentName, selfPointerParam)
200+
self.printFunctionDowncall(&printer, decl, calleeName: "\(selfVar).pointee")
203201
}
204202
}
205203

@@ -320,28 +318,54 @@ extension JNISwift2JavaGenerator {
320318

321319
/// Prints the implementation of the destroy function.
322320
private func printDestroyFunctionThunk(_ printer: inout CodePrinter, _ type: ImportedNominalType) {
321+
let selfPointerParam = JavaParameter(name: "selfPointer", type: .long)
323322
printCDecl(
324323
&printer,
325324
javaMethodName: "$destroy",
326325
parentName: type.swiftNominal.name,
327326
parameters: [
328-
JavaParameter(name: "selfPointer", type: .long)
327+
selfPointerParam
329328
],
330329
isStatic: true,
331330
resultType: .void
332331
) { printer in
332+
let parentName = type.qualifiedName
333+
let selfVar = self.printSelfJLongToUnsafeMutablePointer(&printer, swiftParentName: parentName, selfPointerParam)
333334
// Deinitialize the pointer allocated (which will call the VWT destroy method)
334335
// then deallocate the memory.
335336
printer.print(
336337
"""
337-
let pointer = UnsafeMutablePointer<\(type.qualifiedName)>(bitPattern: Int(Int64(fromJNI: selfPointer, in: environment!)))!
338-
pointer.deinitialize(count: 1)
339-
pointer.deallocate()
338+
\(selfVar).deinitialize(count: 1)
339+
\(selfVar).deallocate()
340340
"""
341341
)
342342
}
343343
}
344344

345+
/// Print the necessary conversion logic to go from a `jlong` to a `UnsafeMutablePointer<Type>`
346+
///
347+
/// - Returns: name of the created "self" variable
348+
private func printSelfJLongToUnsafeMutablePointer(
349+
_ printer: inout CodePrinter,
350+
swiftParentName: String, _ selfPointerParam: JavaParameter) -> String {
351+
let newSelfParamName = "self$"
352+
printer.print(
353+
"""
354+
guard let env$ = environment else {
355+
fatalError("Missing JNIEnv in downcall to \\(#function)")
356+
}
357+
assert(\(selfPointerParam.name) != 0, "\(selfPointerParam.name) memory address was null")
358+
let selfBits$ = Int(Int64(fromJNI: \(selfPointerParam.name), in: env$))
359+
assert(selfBits$ != 0, "$self memory address was null: \(selfPointerParam.name) = \\(\(selfPointerParam.name))" )
360+
guard let \(newSelfParamName) = UnsafeMutablePointer<\(swiftParentName)>(bitPattern: selfBits$) else {
361+
fatalError("Missing self pointer in call to \\(#function)!")
362+
}
363+
"""
364+
)
365+
return newSelfParamName
366+
}
367+
368+
345369
/// Renders the arguments for making a downcall
346370
private func renderDowncallArguments(
347371
swiftFunctionSignature: SwiftFunctionSignature,

SwiftKitCore/src/main/java/org/swift/swiftkit/core/JNISwiftInstance.java

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,30 @@
1414

1515
package org.swift.swiftkit.core;
1616

17+
import java.util.Objects;
1718
import java.util.concurrent.atomic.AtomicBoolean;
1819

1920
public abstract class JNISwiftInstance extends SwiftInstance {
20-
/// Pointer to the "self".
21-
private final long selfPointer;
22-
23-
/**
24-
* The pointer to the instance in memory. I.e. the {@code self} of the Swift object or value.
25-
*/
26-
public final long pointer() {
27-
return this.selfPointer;
28-
}
21+
// Pointer to the "self".
22+
protected final long selfPointer;
2923

3024
/**
3125
* The designated constructor of any imported Swift types.
3226
*
33-
* @param pointer a pointer to the memory containing the value
27+
* @param selfPointer a pointer to the memory containing the value
3428
* @param arena the arena this object belongs to. When the arena goes out of scope, this value is destroyed.
3529
*/
36-
protected JNISwiftInstance(long pointer, SwiftArena arena) {
37-
super(arena);
38-
this.selfPointer = pointer;
30+
protected JNISwiftInstance(long selfPointer, SwiftArena arena) {
31+
SwiftObjects.requireNonZero(selfPointer, "selfPointer");
32+
this.selfPointer = selfPointer;
33+
34+
// Only register once we have fully initialized the object since this will need the object pointer.
35+
arena.register(this);
3936
}
4037

4138
@Override
4239
public long $memoryAddress() {
43-
return selfPointer;
40+
return this.selfPointer;
4441
}
4542

4643
/**
@@ -58,7 +55,7 @@ protected JNISwiftInstance(long pointer, SwiftArena arena) {
5855
protected abstract Runnable $createDestroyFunction();
5956

6057
@Override
61-
public SwiftInstanceCleanup createCleanupAction() {
58+
public SwiftInstanceCleanup $createCleanup() {
6259
final AtomicBoolean statusDestroyedFlag = $statusDestroyedFlag();
6360
Runnable markAsDestroyed = new Runnable() {
6461
@Override

SwiftKitFFM/src/main/java/org/swift/swiftkit/ffm/FFMSwiftInstanceCleanup.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public void run() {
3636
// Allow null pointers just for AutoArena tests.
3737
if (selfType != null && selfPointer != null) {
3838
System.out.println("[debug] Destroy swift value [" + selfType.getSwiftName() + "]: " + selfPointer);
39-
SwiftValueWitnessTable.destroy(selfType, selfPointer);
39+
SwiftValueWitnessTable.destroy(selfType, self$);
4040
}
4141
}
4242
}

Tests/JExtractSwiftTests/JNI/JNIClassTests.swift

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ struct JNIClassTests {
135135
* }
136136
*/
137137
public static MyClass init(long x, long y, SwiftArena swiftArena$) {
138-
long selfPointer = MyClass.allocatingInit(x, y);
139-
return new MyClass(selfPointer, swiftArena$);
138+
long self$ = MyClass.allocatingInit(x, y);
139+
return new MyClass(self$, swiftArena$);
140140
}
141141
""",
142142
"""
@@ -147,8 +147,8 @@ struct JNIClassTests {
147147
* }
148148
*/
149149
public static MyClass init(SwiftArena swiftArena$) {
150-
long selfPointer = MyClass.allocatingInit();
151-
return new MyClass(selfPointer, swiftArena$);
150+
long self$ = MyClass.allocatingInit();
151+
return new MyClass(self$, swiftArena$);
152152
}
153153
""",
154154
"""
@@ -172,17 +172,17 @@ struct JNIClassTests {
172172
"""
173173
@_cdecl("Java_com_example_swift_MyClass_allocatingInit__")
174174
func Java_com_example_swift_MyClass_allocatingInit__(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass) -> jlong {
175-
let selfPointer = UnsafeMutablePointer<MyClass>.allocate(capacity: 1)
176-
selfPointer.initialize(to: MyClass())
177-
return Int64(Int(bitPattern: selfPointer)).getJNIValue(in: environment)
175+
let self$ = UnsafeMutablePointer<MyClass>.allocate(capacity: 1)
176+
self$.initialize(to: MyClass())
177+
return Int64(Int(bitPattern: self$)).getJNIValue(in: environment)
178178
}
179179
""",
180180
"""
181181
@_cdecl("Java_com_example_swift_MyClass_allocatingInit__JJ")
182182
func Java_com_example_swift_MyClass_allocatingInit__JJ(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass, x: jlong, y: jlong) -> jlong {
183-
let selfPointer = UnsafeMutablePointer<MyClass>.allocate(capacity: 1)
184-
selfPointer.initialize(to: MyClass(x: Int64(fromJNI: x, in: environment!), y: Int64(fromJNI: y, in: environment!)))
185-
return Int64(Int(bitPattern: selfPointer)).getJNIValue(in: environment)
183+
let self$ = UnsafeMutablePointer<MyClass>.allocate(capacity: 1)
184+
self$.initialize(to: MyClass(x: Int64(fromJNI: x, in: environment!), y: Int64(fromJNI: y, in: environment!)))
185+
return Int64(Int(bitPattern: self$)).getJNIValue(in: environment)
186186
}
187187
"""
188188
]
@@ -200,9 +200,9 @@ struct JNIClassTests {
200200
"""
201201
@_cdecl("Java_com_example_swift_MyClass__00024destroy__J")
202202
func Java_com_example_swift_MyClass__00024destroy__J(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass, selfPointer: jlong) {
203-
let pointer = UnsafeMutablePointer<MyClass>(bitPattern: Int(Int64(fromJNI: selfPointer, in: environment!)))!
204-
pointer.deinitialize(count: 1)
205-
pointer.deallocate()
203+
let self$ = UnsafeMutablePointer<MyClass>(bitPattern: Int(Int64(fromJNI: selfPointer, in: environment!)))!
204+
self$.deinitialize(count: 1)
205+
self$.deallocate()
206206
}
207207
"""
208208
]

0 commit comments

Comments
 (0)