Skip to content

Commit f66e908

Browse files
committed
WIP
1 parent 962e2e9 commit f66e908

File tree

4 files changed

+46
-55
lines changed

4 files changed

+46
-55
lines changed

Sources/JExtractSwift/ImportedDecls.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public final class ImportedFunc: ImportedDecl, CustomStringConvertible {
4242
public var module: String
4343

4444
/// The function name.
45-
/// e.g., "init" for an initializer or "f" for "f(a:b:)".
45+
/// e.g., "init" for an initializer or "foo" for "foo(a:b:)".
4646
public var name: String
4747

4848
public var swiftDecl: any DeclSyntaxProtocol
@@ -61,6 +61,11 @@ public final class ImportedFunc: ImportedDecl, CustomStringConvertible {
6161
loweredSignature.original
6262
}
6363

64+
package func cFunctionDecl(cName: String) -> CFunction {
65+
// 'try!' because we know 'loweredSignature' can be described with C.
66+
try! loweredSignature.cFunctionDecl(cName: cName)
67+
}
68+
6469
package var kind: SwiftAPIKind {
6570
loweredSignature.apiKind
6671
}

Sources/JExtractSwift/Swift2JavaTranslator+JavaBindingsPrinting.swift

Lines changed: 33 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -310,12 +310,7 @@ extension Swift2JavaTranslator {
310310
) {
311311
printer.printSeparator(decl.displayName)
312312

313-
let descClassIdentifier = thunkNameRegistry.functionThunkName(decl: decl)
314-
printer.printBraceBlock("private static class \(descClassIdentifier)") { printer in
315-
printFunctionDescriptorValue(&printer, decl)
316-
printFunctionAddrValue(&printer, decl)
317-
printFunctionHandleValue(&printer)
318-
}
313+
printJavaBindingDescriptorClass(&printer, decl)
319314

320315
// Render the "make the downcall" functions.
321316
printInitializerDowncallConstructor(&printer, decl)
@@ -327,71 +322,59 @@ extension Swift2JavaTranslator {
327322
) {
328323
printer.printSeparator(decl.displayName)
329324

330-
let descClassIdentifier = thunkNameRegistry.functionThunkName(decl: decl)
331-
printer.printBraceBlock("private static class \(descClassIdentifier)") { printer in
332-
printFunctionDescriptorValue(&printer, decl)
333-
printFunctionAddrValue(&printer, decl)
334-
printFunctionHandleValue(&printer)
335-
}
325+
printJavaBindingDescriptorClass(&printer, decl)
336326

337327
// Render the "make the downcall" functions.
338328
printFuncDowncallMethod(&printer, decl)
339329
}
340330

341-
/// Print the 'FunctionDescriptor' of the Swift API.
342-
public func printFunctionDescriptorValue(
331+
/// Printer FFM Java binding descriptors for the imported Swift API.
332+
func printJavaBindingDescriptorClass(
343333
_ printer: inout CodePrinter,
344334
_ decl: ImportedFunc
335+
) {
336+
let thunkName = thunkNameRegistry.functionThunkName(decl: decl)
337+
let cFunc = decl.cFunctionDecl(cName: thunkName)
338+
339+
printer.printBraceBlock("private static class \(cFunc.name)") { printer in
340+
printFunctionDescriptorValue(&printer, cFunc)
341+
printer.print(
342+
"""
343+
public static final MemorySegment ADDR =
344+
\(self.swiftModuleName).findOrThrow("\(cFunc.name)");
345+
public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC);
346+
"""
347+
)
348+
}
349+
}
350+
351+
/// Print the 'FunctionDescriptor' of the lowered cdecl thunk.
352+
public func printFunctionDescriptorValue(
353+
_ printer: inout CodePrinter,
354+
_ cFunc: CFunction
345355
) {
346356
printer.start("public static final FunctionDescriptor DESC = ")
347357

348-
let loweredSignature = decl.loweredSignature
349-
let loweredParams = loweredSignature.allLoweredParameters
350-
let resultType = try! CType(cdeclType: loweredSignature.result.cdeclResultType)
351-
let isEmptyParam = loweredParams.isEmpty
352-
if resultType.isVoid {
358+
let isEmptyParam = cFunc.parameters.isEmpty
359+
if cFunc.resultType.isVoid {
353360
printer.print("FunctionDescriptor.ofVoid(", isEmptyParam ? .continue : .newLine)
354361
printer.indent()
355362
} else {
356363
printer.print("FunctionDescriptor.of(")
357364
printer.indent()
358365
printer.print("/* -> */", .continue)
359-
printer.print(resultType.foreignValueLayout, .parameterNewlineSeparator(isEmptyParam))
366+
printer.print(cFunc.resultType.foreignValueLayout, .parameterNewlineSeparator(isEmptyParam))
360367
}
361368

362-
for (param, isLast) in loweredParams.withIsLast {
363-
let paramType = try! CType(cdeclType: param.type)
364-
printer.print("/* \(param.parameterName ?? "_"): */", .continue)
365-
printer.print(paramType.foreignValueLayout, .parameterNewlineSeparator(isLast))
369+
for (param, isLast) in cFunc.parameters.withIsLast {
370+
printer.print("/* \(param.name ?? "_"): */", .continue)
371+
printer.print(param.type.foreignValueLayout, .parameterNewlineSeparator(isLast))
366372
}
367373

368374
printer.outdent()
369375
printer.print(");")
370376
}
371377

372-
func printFunctionAddrValue(
373-
_ printer: inout CodePrinter,
374-
_ decl: ImportedFunc
375-
) {
376-
let thunkName = thunkNameRegistry.functionThunkName(decl: decl)
377-
printer.print(
378-
"""
379-
public static final MemorySegment ADDR =
380-
\(self.swiftModuleName).findOrThrow("\(thunkName)");
381-
"""
382-
)
383-
}
384-
385-
func printFunctionHandleValue(
386-
_ printer: inout CodePrinter
387-
) {
388-
printer.print(
389-
"""
390-
public static final MethodHandle HANDLE = Linker.nativeLinker().downcallHandle(ADDR, DESC);
391-
"""
392-
)
393-
}
394-
395378
public func printInitializerDowncallConstructor(
396379
_ printer: inout CodePrinter,
397380
_ decl: ImportedFunc
@@ -562,10 +545,10 @@ extension Swift2JavaTranslator {
562545
} else if decl.translatedSignature.result.javaResultType == .void {
563546
printer.print("\(downCall);")
564547
} else {
565-
let placeholder = if !decl.translatedSignature.result.outParameters.isEmpty {
566-
"_result"
567-
} else {
548+
let placeholder = if decl.translatedSignature.result.outParameters.isEmpty {
568549
downCall
550+
} else {
551+
"_result"
569552
}
570553
let result = decl.translatedSignature.result.conversion.render(&printer, placeholder)
571554

Sources/JExtractSwift/Swift2JavaTranslator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public final class Swift2JavaTranslator {
5454

5555
package let symbolTable: SwiftSymbolTable
5656

57-
var thunkNameRegistry: ThunkNameRegistry = ThunkNameRegistry()
57+
package var thunkNameRegistry: ThunkNameRegistry = ThunkNameRegistry()
5858

5959
/// The name of the Swift module being translated.
6060
var swiftModuleName: String {

Tests/JExtractSwiftTests/FunctionDescriptorImportTests.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,10 @@ extension FunctionDescriptorTests {
145145
$0.name == methodIdentifier
146146
}!
147147

148+
let thunkName = st.thunkNameRegistry.functionThunkName(decl: funcDecl)
149+
let cFunc = funcDecl.cFunctionDecl(cName: thunkName)
148150
let output = CodePrinter.toString { printer in
149-
st.printFunctionDescriptorValue(&printer, funcDecl)
151+
st.printFunctionDescriptorValue(&printer, cFunc)
150152
}
151153

152154
try body(output)
@@ -178,9 +180,10 @@ extension FunctionDescriptorTests {
178180
fatalError("Cannot find descriptor of: \(identifier)")
179181
}
180182

183+
let thunkName = st.thunkNameRegistry.functionThunkName(decl: accessorDecl)
184+
let cFunc = accessorDecl.cFunctionDecl(cName: thunkName)
181185
let getOutput = CodePrinter.toString { printer in
182-
st.printFunctionDescriptorValue(
183-
&printer, accessorDecl)
186+
st.printFunctionDescriptorValue(&printer, cFunc)
184187
}
185188

186189
try body(getOutput)

0 commit comments

Comments
 (0)