Skip to content

Commit 4f6f7b5

Browse files
committed
Initial implementation of a new lowering from a Swift func to @_cdecl func
Start implementing a more complete and formal lowering from an arbitrary Swift function to a `@_cdecl`-compatible thunk that calls that function. This is set up in stages more akin to what you'd see in a compiler: 1. Resolve the syntax trees for the function into a more semantic representation, for example resolving type names to nominal type declarations. This includes a simplistic implementation of a symbol table so we can resolve arbitrary type names. 2. Lower the semantic representation of each function parameter (including self). How we do this varies based on type: * Value types (struct / enum) are passed indirectly via Unsafe(Mutable)RawPointer, using a mutable pointer when the corresponding parameter is inout. * Class / actor types are passed directly via UnsafeRawPointer. * Swift types that map to primitive types (like Swift.Int32) in passed directly, no translation required. * Tuple types are recursively "exploded" into multiple parameters. * Unsafe*BufferPointer types are "exploded" into a pointer and count. * Typed unsafe pointers types are passed via their raw versions. 3. Lower returns similarly to parameters, using indirect mutable parameters for the return when we can't return directly. 4. Render the lowered declaration into a FunctionDeclSyntax node, which can be modified by the client. At present, we aren't rendering the bodies of these thunks, which need to effectively undo the transformations described in (3) and (4). For example, reconstituting a tuple from disparate arguments, appropriately re-typing and loading from indirectly-passed value types, and so on. The description of the lowered signature is intended to provide sufficient information for doing so, but will likely require tweaking. At present, this new code is not integrated in the main code path for jextract-swift. Once it hits feature parity, we'll enable it.
1 parent 9c96f65 commit 4f6f7b5

17 files changed

+1641
-22
lines changed

Sources/JExtractSwift/JavaConstants/ForeignValueLayouts.swift

+21-1
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
import Foundation
16+
import JavaTypes
1617

1718
/// Represents a value of a `java.lang.foreign.Self` that we want to render in generated Java code.
1819
///
1920
/// This type may gain further methods for adjusting target layout, byte order, names etc.
20-
public struct ForeignValueLayout: CustomStringConvertible {
21+
public struct ForeignValueLayout: CustomStringConvertible, Equatable {
2122
var inlineComment: String?
2223
var value: String
2324

@@ -35,6 +36,20 @@ public struct ForeignValueLayout: CustomStringConvertible {
3536
self.needsMemoryLayoutCall = true
3637
}
3738

39+
public init?(javaType: JavaType) {
40+
switch javaType {
41+
case .boolean: self = .SwiftBool
42+
case .byte: self = .SwiftInt8
43+
case .char: self = .SwiftUInt16
44+
case .short: self = .SwiftInt16
45+
case .int: self = .SwiftInt32
46+
case .long: self = .SwiftInt64
47+
case .float: self = .SwiftFloat
48+
case .double: self = .SwiftDouble
49+
case .array, .class, .void: return nil
50+
}
51+
}
52+
3853
public var description: String {
3954
var result = ""
4055

@@ -68,4 +83,9 @@ extension ForeignValueLayout {
6883

6984
public static let SwiftFloat = Self(javaConstant: "SWIFT_FLOAT")
7085
public static let SwiftDouble = Self(javaConstant: "SWIFT_DOUBLE")
86+
87+
var isPrimitive: Bool {
88+
// FIXME: This is a hack, we need an enum to better describe this!
89+
value != "SWIFT_POINTER"
90+
}
7191
}

Sources/JExtractSwift/NominalTypeResolution.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ public class NominalTypeResolution {
2525

2626
/// Mapping from extension declarations to the type declaration that they
2727
/// extend.
28-
private var resolvedExtensions: [ExtensionDeclSyntax: NominalTypeDeclSyntaxNode] = [:]
28+
var resolvedExtensions: [ExtensionDeclSyntax: NominalTypeDeclSyntaxNode] = [:]
2929

3030
/// Extensions that have been encountered but not yet resolved to
3131
private var unresolvedExtensions: [ExtensionDeclSyntax] = []
3232

3333
/// Mapping from qualified nominal type names to their syntax nodes.
34-
private var topLevelNominalTypes: [String: NominalTypeDeclSyntaxNode] = [:]
34+
var topLevelNominalTypes: [String: NominalTypeDeclSyntaxNode] = [:]
3535

3636
@_spi(Testing) public init() { }
3737
}

0 commit comments

Comments
 (0)