@@ -19,7 +19,7 @@ extension Swift2JavaTranslator {
19
19
_ printer: inout CodePrinter ,
20
20
_ decl: ImportedFunc
21
21
) {
22
- guard let _ = translatedSignature ( for: decl) else {
22
+ guard let _ = translatedDecl ( for: decl) else {
23
23
// Failed to translate. Skip.
24
24
return
25
25
}
@@ -28,6 +28,8 @@ extension Swift2JavaTranslator {
28
28
29
29
printJavaBindingDescriptorClass ( & printer, decl)
30
30
31
+ printJavaBindingWrapperHelperClass ( & printer, decl)
32
+
31
33
// Render the "make the downcall" functions.
32
34
printJavaBindingWrapperMethod ( & printer, decl)
33
35
}
@@ -38,9 +40,9 @@ extension Swift2JavaTranslator {
38
40
_ decl: ImportedFunc
39
41
) {
40
42
let thunkName = thunkNameRegistry. functionThunkName ( decl: decl)
41
- let translatedSignature = self . translatedSignature ( for: decl) !
43
+ let translated = self . translatedDecl ( for: decl) !
42
44
// 'try!' because we know 'loweredSignature' can be described with C.
43
- let cFunc = try ! translatedSignature . loweredSignature. cFunctionDecl ( cName: thunkName)
45
+ let cFunc = try ! translated . loweredSignature. cFunctionDecl ( cName: thunkName)
44
46
45
47
printer. printBraceBlock (
46
48
"""
@@ -52,37 +54,39 @@ extension Swift2JavaTranslator {
52
54
private static class \( cFunc. name)
53
55
"""
54
56
) { printer in
55
- printFunctionDescriptorValue ( & printer, cFunc)
57
+ printFunctionDescriptorDefinition ( & printer, cFunc. resultType , cFunc . parameters )
56
58
printer. print (
57
59
"""
58
- public static final MemorySegment ADDR =
60
+ private static final MemorySegment ADDR =
59
61
\( self . swiftModuleName) .findOrThrow( " \( cFunc. name) " );
60
- public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC);
62
+ private static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC);
61
63
"""
62
64
)
63
65
printJavaBindingDowncallMethod ( & printer, cFunc)
66
+ printParameterDescriptorClasses ( & printer, cFunc)
64
67
}
65
68
}
66
69
67
70
/// Print the 'FunctionDescriptor' of the lowered cdecl thunk.
68
- func printFunctionDescriptorValue (
71
+ func printFunctionDescriptorDefinition (
69
72
_ printer: inout CodePrinter ,
70
- _ cFunc: CFunction
73
+ _ resultType: CType ,
74
+ _ parameters: [ CParameter ]
71
75
) {
72
- printer. start ( " public static final FunctionDescriptor DESC = " )
76
+ printer. start ( " private static final FunctionDescriptor DESC = " )
73
77
74
- let isEmptyParam = cFunc . parameters. isEmpty
75
- if cFunc . resultType. isVoid {
78
+ let isEmptyParam = parameters. isEmpty
79
+ if resultType. isVoid {
76
80
printer. print ( " FunctionDescriptor.ofVoid( " , isEmptyParam ? . continue : . newLine)
77
81
printer. indent ( )
78
82
} else {
79
83
printer. print ( " FunctionDescriptor.of( " )
80
84
printer. indent ( )
81
85
printer. print ( " /* -> */" , . continue)
82
- printer. print ( cFunc . resultType. foreignValueLayout, . parameterNewlineSeparator( isEmptyParam) )
86
+ printer. print ( resultType. foreignValueLayout, . parameterNewlineSeparator( isEmptyParam) )
83
87
}
84
88
85
- for (param, isLast) in cFunc . parameters. withIsLast {
89
+ for (param, isLast) in parameters. withIsLast {
86
90
printer. print ( " /* \(param.name ?? "_"): */" , . continue)
87
91
printer. print ( param. type. foreignValueLayout, . parameterNewlineSeparator( isLast) )
88
92
}
@@ -124,16 +128,143 @@ extension Swift2JavaTranslator {
124
128
)
125
129
}
126
130
131
+ func printParameterDescriptorClasses(
132
+ _ printer: inout CodePrinter ,
133
+ _ cFunc: CFunction
134
+ ) {
135
+ for param in cFunc. parameters {
136
+ switch param. type {
137
+ case . pointer( . function) :
138
+ let name = " $ \( param. name!) "
139
+ printFunctionPointerParameterDescriptorClass ( & printer, name, param. type)
140
+ default :
141
+ continue
142
+ }
143
+ }
144
+ }
145
+
146
+ /// Print a class describing a closure parameter type.
147
+ /// ```
148
+ /// class <paramter-name> {
149
+ /// interface Function {
150
+ /// <return-type> apply(<parameters>);
151
+ /// }
152
+ /// static final MethodDescriptor DESC = FunctionDescriptor.of(...);s
153
+ /// static final MethodHandle HANDLE = SwiftKit.upcallHandle(Function.class, "apply", DESC);
154
+ /// static MemorySegment toUpcallStub(Function fi, Arena arena) {
155
+ /// return Linker.nativeLinker().upcallStub(HANDLE.bindTo(fi), DESC, arena);
156
+ /// }
157
+ /// }
158
+ /// ```
159
+ func printFunctionPointerParameterDescriptorClass(
160
+ _ printer: inout CodePrinter ,
161
+ _ name: String ,
162
+ _ cType: CType
163
+ ) {
164
+ guard case . pointer( . function( let cResultType, let cParameterTypes, variadic: false ) ) = cType else {
165
+ preconditionFailure ( " must be a C function pointer type " )
166
+ }
167
+
168
+ let cParams = cParameterTypes. enumerated ( ) . map { i, ty in
169
+ CParameter ( name: " _ \( i) " , type: ty)
170
+ }
171
+ let paramDecls = cParams. map ( { " \( $0. type. javaType) \( $0. name!) " } )
172
+
173
+ printer. printBraceBlock (
174
+ """
175
+ /**
176
+ * {snippet lang=c :
177
+ * \(cType)
178
+ * }
179
+ */
180
+ private static class \( name)
181
+ """
182
+ ) { printer in
183
+ printer. print (
184
+ """
185
+ public interface Function {
186
+ \( cResultType. javaType) apply( \( paramDecls. joined ( separator: " , " ) ) );
187
+ }
188
+ """
189
+ )
190
+ printFunctionDescriptorDefinition ( & printer, cResultType, cParams)
191
+ printer. print (
192
+ """
193
+ private static final MethodHandle HANDLE = SwiftKit.upcallHandle(Function.class, " apply " , DESC);
194
+ private static MemorySegment toUpcallStub(Function fi, Arena arena) {
195
+ return Linker.nativeLinker().upcallStub(HANDLE.bindTo(fi), DESC, arena);
196
+ }
197
+ """
198
+ )
199
+ }
200
+ }
201
+
202
+ func printJavaBindingWrapperHelperClass(
203
+ _ printer: inout CodePrinter ,
204
+ _ decl: ImportedFunc
205
+ ) {
206
+ let translated = self . translatedDecl ( for: decl) !
207
+ let bindingDescriptorName = self . thunkNameRegistry. functionThunkName ( decl: decl)
208
+ if translated. functionTypes. isEmpty {
209
+ return
210
+ }
211
+
212
+ printer. printBraceBlock (
213
+ """
214
+ private static class \( translated. name)
215
+ """
216
+ ) { printer in
217
+ for functionType in translated. functionTypes {
218
+ printJavaBindingWrapperFunctionTypeHelper ( & printer, functionType, bindingDescriptorName)
219
+ }
220
+ }
221
+ }
222
+
223
+ func printJavaBindingWrapperFunctionTypeHelper(
224
+ _ printer: inout CodePrinter ,
225
+ _ functionType: TranslatedFunctionType ,
226
+ _ bindingDescriptorName: String
227
+ ) {
228
+ let cdeclDescritor = " \( bindingDescriptorName) .$ \( functionType. name) "
229
+ if functionType. isTrivial {
230
+ printer. print (
231
+ """
232
+ public interface \( functionType. name) extends \( cdeclDescritor) .Function {
233
+ default MemorySegment toUpcallStub(Arena arena) {
234
+ return \( bindingDescriptorName) .$ \( functionType. name) .toUpcallStub(this, arena);
235
+ }
236
+ }
237
+ """
238
+ )
239
+ } else {
240
+ assertionFailure ( " should be unreachable at this point " )
241
+ let apiParams = functionType. parameters. flatMap {
242
+ $0. javaParameters. map { param in " \( param. type) \( param. name) " }
243
+ }
244
+
245
+ printer. print (
246
+ """
247
+ public interface \( functionType. name) {
248
+ \( functionType. result. javaResultType) apply( \( apiParams. joined ( separator: " , " ) ) );
249
+ private default MemorySegment toUpcallStub(Arena arena) {
250
+ return \( cdeclDescritor) .toUpcallStub((<cdecl-params>) -> {
251
+ <maybe-return> fi(<converted-args>)
252
+ }, arena);
253
+ }
254
+ }
255
+ """
256
+ )
257
+ }
258
+ }
259
+
127
260
/// Print the calling body that forwards all the parameters to the `methodName`,
128
261
/// with adding `SwiftArena.ofAuto()` at the end.
129
262
public func printJavaBindingWrapperMethod(
130
263
_ printer: inout CodePrinter ,
131
- _ decl: ImportedFunc ) {
132
- let methodName : String = switch decl. apiKind {
133
- case . getter: " get \( decl. name. toCamelCase) "
134
- case . setter: " set \( decl. name. toCamelCase) "
135
- case . function, . initializer: decl. name
136
- }
264
+ _ decl: ImportedFunc
265
+ ) {
266
+ let translated = self . translatedDecl ( for: decl) !
267
+ let methodName = translated. name
137
268
138
269
var modifiers = " public "
139
270
switch decl. functionSignature. selfParameter {
@@ -143,7 +274,7 @@ extension Swift2JavaTranslator {
143
274
break
144
275
}
145
276
146
- let translatedSignature = self . translatedSignature ( for : decl ) !
277
+ let translatedSignature = translated . translatedSignature
147
278
let returnTy = translatedSignature. result. javaResultType
148
279
149
280
var paramDecls = translatedSignature. parameters
@@ -182,7 +313,7 @@ extension Swift2JavaTranslator {
182
313
_ decl: ImportedFunc
183
314
) {
184
315
//=== Part 1: prepare temporary arena if needed.
185
- let translatedSignature = self . translatedSignature ( for: decl) !
316
+ let translatedSignature = self . translatedDecl ( for: decl) !. translatedSignature
186
317
187
318
if translatedSignature. requiresTemporaryArena {
188
319
printer. print ( " try(var arena$ = Arena.ofConfined()) { " )
@@ -273,7 +404,7 @@ extension JavaConversionStep {
273
404
/// Whether the conversion uses SwiftArena.
274
405
var requiresSwiftArena : Bool {
275
406
switch self {
276
- case . pass, . swiftValueSelfSegment, . construct, . cast, . call:
407
+ case . pass, . swiftValueSelfSegment, . construct, . cast, . call, . method :
277
408
return false
278
409
case . constructSwiftValue:
279
410
return true
@@ -285,7 +416,7 @@ extension JavaConversionStep {
285
416
switch self {
286
417
case . pass, . swiftValueSelfSegment, . construct, . constructSwiftValue, . cast:
287
418
return false
288
- case . call( _, let withArena) :
419
+ case . call( _, let withArena) , . method ( _ , _ , let withArena ) :
289
420
return withArena
290
421
}
291
422
}
@@ -297,7 +428,7 @@ extension JavaConversionStep {
297
428
switch self {
298
429
case . pass, . swiftValueSelfSegment:
299
430
return true
300
- case . cast, . construct, . constructSwiftValue, . call:
431
+ case . cast, . construct, . constructSwiftValue, . call, . method :
301
432
return false
302
433
}
303
434
}
@@ -317,6 +448,10 @@ extension JavaConversionStep {
317
448
let arenaArg = withArena ? " , arena$ " : " "
318
449
return " \( function) ( \( placeholder) \( arenaArg) ) "
319
450
451
+ case . method( let methodName, let arguments, let withArena) :
452
+ let argsStr = ( arguments + ( withArena ? [ " arena$ " ] : [ ] ) ) . joined ( separator: " , " )
453
+ return " \( placeholder) . \( methodName) ( \( argsStr) ) "
454
+
320
455
case . constructSwiftValue( let javaType) :
321
456
return " new \( javaType. className!) ( \( placeholder) , swiftArena$) "
322
457
0 commit comments