Skip to content

Commit 69e487b

Browse files
authored
jextract: hide memory location wrapping constructor, give it proper name (#360)
1 parent 5dd3f36 commit 69e487b

12 files changed

+84
-26
lines changed

Sources/JExtractSwiftLib/FFM/ConversionStep.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ enum ConversionStep: Equatable {
123123
// of splatting out text.
124124
let renderedArgumentList = renderedArguments.joined(separator: ", ")
125125
return "\(raw: type.description)(\(raw: renderedArgumentList))"
126-
126+
127127
case .tuplify(let elements):
128128
let renderedElements: [String] = elements.enumerated().map { (index, element) in
129129
element.asExprSyntax(placeholder: "\(placeholder)_\(index)", bodyItems: &bodyItems)!.description

Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator+JavaBindingsPrinting.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ extension FFMSwift2JavaGenerator {
407407
"arena$"
408408
}
409409

410+
// FIXME: use trailing$ convention
410411
let varName = outParameter.name.isEmpty ? "_result" : "_result_" + outParameter.name
411412

412413
printer.print(
@@ -463,7 +464,7 @@ extension FFMSwift2JavaGenerator.JavaConversionStep {
463464
switch self {
464465
case .placeholder, .explodedName, .constant, .readMemorySegment:
465466
return false
466-
case .constructSwiftValue:
467+
case .constructSwiftValue, .wrapMemoryAddressUnsafe:
467468
return true
468469

469470
case .call(let inner, _, _), .cast(let inner, _), .construct(let inner, _),
@@ -482,7 +483,11 @@ extension FFMSwift2JavaGenerator.JavaConversionStep {
482483
return false
483484
case .readMemorySegment:
484485
return true
485-
case .cast(let inner, _), .construct(let inner, _), .constructSwiftValue(let inner, _), .swiftValueSelfSegment(let inner):
486+
case .cast(let inner, _),
487+
.construct(let inner, _),
488+
.constructSwiftValue(let inner, _),
489+
.swiftValueSelfSegment(let inner),
490+
.wrapMemoryAddressUnsafe(let inner, _):
486491
return inner.requiresSwiftArena
487492
case .call(let inner, _, let withArena):
488493
return withArena || inner.requiresTemporaryArena
@@ -522,6 +527,10 @@ extension FFMSwift2JavaGenerator.JavaConversionStep {
522527
let inner = inner.render(&printer, placeholder)
523528
return "new \(javaType.className!)(\(inner), swiftArena$)"
524529

530+
case .wrapMemoryAddressUnsafe(let inner, let javaType):
531+
let inner = inner.render(&printer, placeholder)
532+
return "\(javaType.className!).wrapMemoryAddressUnsafe(\(inner), swiftArena$)"
533+
525534
case .construct(let inner, let javaType):
526535
let inner = inner.render(&printer, placeholder)
527536
return "new \(javaType)(\(inner))"

Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator+JavaTranslation.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ extension FFMSwift2JavaGenerator {
684684
outParameters: [
685685
JavaParameter(name: "", type: javaType)
686686
],
687-
conversion: .constructSwiftValue(.placeholder, javaType)
687+
conversion: .wrapMemoryAddressUnsafe(.placeholder, javaType)
688688
)
689689

690690
case .tuple:
@@ -732,6 +732,9 @@ extension FFMSwift2JavaGenerator {
732732
// Call 'new \(Type)(\(placeholder), swiftArena$)'.
733733
indirect case constructSwiftValue(JavaConversionStep, JavaType)
734734

735+
/// Call the `MyType.wrapMemoryAddressUnsafe` in order to wrap a memory address using the Java binding type
736+
indirect case wrapMemoryAddressUnsafe(JavaConversionStep, JavaType)
737+
735738
// Construct the type using the placeholder as arguments.
736739
indirect case construct(JavaConversionStep, JavaType)
737740

Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,22 @@ extension FFMSwift2JavaGenerator {
216216

217217
printer.print(
218218
"""
219-
public \(decl.swiftNominal.name)(MemorySegment segment, AllocatingSwiftArena arena) {
219+
private \(decl.swiftNominal.name)(MemorySegment segment, AllocatingSwiftArena arena) {
220220
super(segment, arena);
221221
}
222+
223+
/**
224+
* Assume that the passed {@code MemorySegment} represents a memory address of a {@link \(decl.swiftNominal.name)}.
225+
* <p/>
226+
* Warnings:
227+
* <ul>
228+
* <li>No checks are performed about the compatibility of the pointed at memory and the actual \(decl.swiftNominal.name) types.</li>
229+
* <li>This operation does not copy, or retain, the pointed at pointer, so its lifetime must be ensured manually to be valid when wrapping.</li>
230+
* </ul>
231+
*/
232+
public static \(decl.swiftNominal.name) wrapMemoryAddressUnsafe(MemorySegment selfPointer, AllocatingSwiftArena swiftArena) {
233+
return new \(decl.swiftNominal.name)(selfPointer, swiftArena);
234+
}
222235
"""
223236
)
224237

Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,22 @@ extension JNISwift2JavaGenerator {
117117

118118
printer.print(
119119
"""
120-
public \(decl.swiftNominal.name)(long selfPointer, SwiftArena swiftArena) {
120+
private \(decl.swiftNominal.name)(long selfPointer, SwiftArena swiftArena) {
121121
super(selfPointer, swiftArena);
122122
}
123+
124+
/**
125+
* Assume that the passed {@code long} represents a memory address of a {@link \(decl.swiftNominal.name)}.
126+
* <p/>
127+
* Warnings:
128+
* <ul>
129+
* <li>No checks are performed about the compatibility of the pointed at memory and the actual \(decl.swiftNominal.name) types.</li>
130+
* <li>This operation does not copy, or retain, the pointed at pointer, so its lifetime must be ensured manually to be valid when wrapping.</li>
131+
* </ul>
132+
*/
133+
public static \(decl.swiftNominal.name) wrapMemoryAddressUnsafe(long selfPointer, SwiftArena swiftArena) {
134+
return new \(decl.swiftNominal.name)(selfPointer, swiftArena);
135+
}
123136
"""
124137
)
125138

Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ extension JNISwift2JavaGenerator {
383383
javaType: javaType,
384384
annotations: resultAnnotations,
385385
outParameters: [],
386-
conversion: .constructSwiftValue(.placeholder, javaType)
386+
conversion: .wrapMemoryAddressUnsafe(.placeholder, javaType)
387387
)
388388

389389
case .tuple([]):
@@ -465,7 +465,7 @@ extension JNISwift2JavaGenerator {
465465
discriminatorName: "result_discriminator$",
466466
optionalClass: "Optional",
467467
javaType: .long,
468-
toValue: .constructSwiftValue(.placeholder, .class(package: nil, name: nominalTypeName))
468+
toValue: .wrapMemoryAddressUnsafe(.placeholder, .class(package: nil, name: nominalTypeName))
469469
)
470470
)
471471

@@ -582,6 +582,9 @@ extension JNISwift2JavaGenerator {
582582
/// Call `new \(Type)(\(placeholder), swiftArena$)`
583583
indirect case constructSwiftValue(JavaNativeConversionStep, JavaType)
584584

585+
/// Call the `MyType.wrapMemoryAddressUnsafe` in order to wrap a memory address using the Java binding type
586+
indirect case wrapMemoryAddressUnsafe(JavaNativeConversionStep, JavaType)
587+
585588
indirect case call(JavaNativeConversionStep, function: String)
586589

587590
indirect case method(JavaNativeConversionStep, function: String, arguments: [JavaNativeConversionStep] = [])
@@ -641,6 +644,10 @@ extension JNISwift2JavaGenerator {
641644
case .constructSwiftValue(let inner, let javaType):
642645
let inner = inner.render(&printer, placeholder)
643646
return "new \(javaType.className!)(\(inner), swiftArena$)"
647+
648+
case .wrapMemoryAddressUnsafe(let inner, let javaType):
649+
let inner = inner.render(&printer, placeholder)
650+
return "\(javaType.className!).wrapMemoryAddressUnsafe(\(inner), swiftArena$)"
644651

645652
case .call(let inner, let function):
646653
let inner = inner.render(&printer, placeholder)
@@ -705,7 +712,7 @@ extension JNISwift2JavaGenerator {
705712
case .placeholder, .constant, .isOptionalPresent:
706713
return false
707714

708-
case .constructSwiftValue:
715+
case .constructSwiftValue, .wrapMemoryAddressUnsafe:
709716
return true
710717

711718
case .valueMemoryAddress(let inner):

Tests/JExtractSwiftTests/DataImportTests.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ final class DataImportTests {
8686
]
8787
)
8888
}
89-
89+
9090
@Test("Import Data: JavaBindings")
9191
func data_javaBindings() throws {
9292

@@ -167,7 +167,7 @@ final class DataImportTests {
167167
public static Data returnData(AllocatingSwiftArena swiftArena$) {
168168
MemorySegment _result = swiftArena$.allocate(Data.$LAYOUT);
169169
swiftjava_SwiftModule_returnData.call(_result);
170-
return new Data(_result, swiftArena$);
170+
return Data.wrapMemoryAddressUnsafe(_result, swiftArena$);
171171
}
172172
""",
173173

@@ -210,7 +210,7 @@ final class DataImportTests {
210210
public static Data init(java.lang.foreign.MemorySegment bytes, long count, AllocatingSwiftArena swiftArena$) {
211211
MemorySegment _result = swiftArena$.allocate(Data.$LAYOUT);
212212
swiftjava_SwiftModule_Data_init_bytes_count.call(bytes, count, _result);
213-
return new Data(_result, swiftArena$);
213+
return Data.wrapMemoryAddressUnsafe(_result, swiftArena$);
214214
}
215215
""",
216216

@@ -408,4 +408,5 @@ final class DataImportTests {
408408
]
409409
)
410410
}
411+
411412
}

Tests/JExtractSwiftTests/JNI/JNIClassTests.swift

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,17 @@ struct JNIClassTests {
6666
System.loadLibrary(LIB_NAME);
6767
return true;
6868
}
69-
70-
public MyClass(long selfPointer, SwiftArena swiftArena) {
69+
""",
70+
"""
71+
private MyClass(long selfPointer, SwiftArena swiftArena) {
7172
super(selfPointer, swiftArena);
7273
}
7374
""",
75+
"""
76+
public static MyClass wrapMemoryAddressUnsafe(long selfPointer, SwiftArena swiftArena) {
77+
return new MyClass(selfPointer, swiftArena);
78+
}
79+
"""
7480
])
7581
try assertOutput(
7682
input: source,
@@ -164,7 +170,7 @@ struct JNIClassTests {
164170
* }
165171
*/
166172
public static MyClass init(long x, long y, SwiftArena swiftArena$) {
167-
return new MyClass(MyClass.$init(x, y), swiftArena$);
173+
return MyClass.wrapMemoryAddressUnsafe(MyClass.$init(x, y), swiftArena$);
168174
}
169175
""",
170176
"""
@@ -175,7 +181,7 @@ struct JNIClassTests {
175181
* }
176182
*/
177183
public static MyClass init(SwiftArena swiftArena$) {
178-
return new MyClass(MyClass.$init(), swiftArena$);
184+
return MyClass.wrapMemoryAddressUnsafe(MyClass.$init(), swiftArena$);
179185
}
180186
""",
181187
"""
@@ -309,7 +315,7 @@ struct JNIClassTests {
309315
* }
310316
*/
311317
public MyClass copy(SwiftArena swiftArena$) {
312-
return new MyClass(MyClass.$copy(this.$memoryAddress()), swiftArena$);
318+
return MyClass.wrapMemoryAddressUnsafe(MyClass.$copy(this.$memoryAddress()), swiftArena$);
313319
}
314320
""",
315321
"""

Tests/JExtractSwiftTests/JNI/JNIOptionalTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ struct JNIOptionalTests {
158158
public static Optional<MyClass> optionalClass(Optional<MyClass> arg, SwiftArena swiftArena$) {
159159
byte[] result_discriminator$ = new byte[1];
160160
long result$ = SwiftModule.$optionalClass(arg.map(MyClass::$memoryAddress).orElse(0L), result_discriminator$);
161-
return (result_discriminator$[0] == 1) ? Optional.of(new MyClass(result$, swiftArena$)) : Optional.empty();
161+
return (result_discriminator$[0] == 1) ? Optional.of(MyClass.wrapMemoryAddressUnsafe(result$, swiftArena$)) : Optional.empty();
162162
}
163163
""",
164164
"""

Tests/JExtractSwiftTests/JNI/JNIStructTests.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,16 @@ struct JNIStructTests {
5656
System.loadLibrary(LIB_NAME);
5757
return true;
5858
}
59-
60-
public MyStruct(long selfPointer, SwiftArena swiftArena) {
59+
""",
60+
"""
61+
private MyStruct(long selfPointer, SwiftArena swiftArena) {
6162
super(selfPointer, swiftArena);
6263
}
64+
""",
65+
"""
66+
public static MyStruct wrapMemoryAddressUnsafe(long selfPointer, SwiftArena swiftArena) {
67+
return new MyStruct(selfPointer, swiftArena);
68+
}
6369
"""
6470
])
6571
try assertOutput(
@@ -110,7 +116,7 @@ struct JNIStructTests {
110116
* }
111117
*/
112118
public static MyStruct init(long x, long y, SwiftArena swiftArena$) {
113-
return new MyStruct(MyStruct.$init(x, y), swiftArena$);
119+
return MyStruct.wrapMemoryAddressUnsafe(MyStruct.$init(x, y), swiftArena$);
114120
}
115121
""",
116122
"""

0 commit comments

Comments
 (0)