Skip to content

[WIP][JExtract] Import Foundation.Data if used #301

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Plugins/JExtractSwiftPlugin/JExtractSwiftPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ struct JExtractSwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
outputSwiftDirectory.appending(path: "\(sourceModule.name)Module+SwiftJava.swift")
]

// If the module uses 'Data' type, the thunk file is emitted as if 'Data' is declared
// in that module. Declare the thunk file as the output.
// FIXME: Make this conditional.
outputSwiftFiles += [
outputSwiftDirectory.appending(path: "Data+SwiftJava.swift")
]

return [
.buildCommand(
displayName: "Generate Java wrappers for Swift types",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import Glibc
import Darwin.C
#endif

import Foundation

public func helloWorld() {
p("\(#function)")
}
Expand Down Expand Up @@ -53,6 +55,10 @@ public func globalReceiveRawBuffer(buf: UnsafeRawBufferPointer) -> Int {

public var globalBuffer: UnsafeRawBufferPointer = UnsafeRawBufferPointer(UnsafeMutableRawBufferPointer.allocate(byteCount: 124, alignment: 1))

public func globalReceiveReturnData(data: Data) -> Data {
return Data(data)
}

public func withBuffer(body: (UnsafeRawBufferPointer) -> Void) {
body(globalBuffer)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
import org.swift.swiftkit.SwiftArena;
import org.swift.swiftkit.SwiftKit;

import java.lang.foreign.MemoryLayout;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;

public class HelloJava2Swift {

public static void main(String[] args) {
Expand Down Expand Up @@ -77,6 +81,22 @@ static void examples() {
});
}

// Example of using 'Data'.
try (var arena = SwiftArena.ofConfined()) {
var origBytes = arena.allocateFrom("foobar");
var origDat = Data.init(origBytes, origBytes.byteSize(), arena);

// var origBytes = arena.allocate(ValueLayout.JAVA_INT, arry.length);
// origBytes.copyFrom(MemorySegment.ofArray(arry));
// var dat = MySwiftLibrary.globalReceiveReturnData(origDat, arena);
// dat.withUnsafeBytes((retBytes) -> {
// SwiftKit.trace("retBytes=" + retBytes.toArray(ValueLayout.JAVA_INT)[1]);
// SwiftKit.trace("foobar");
// });
//SwiftKit.trace(origDat);
}


System.out.println("DONE.");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ enum CDeclToCLoweringError: Error {
case invalidFunctionConvention(SwiftFunctionType)
}

extension SwiftStandardLibraryTypeKind {
extension SwiftKnownTypeDeclKind {
/// Determine the primitive C type that corresponds to this C standard
/// library type, if there is one.
var primitiveCType: CType? {
Expand All @@ -125,7 +125,7 @@ extension SwiftStandardLibraryTypeKind {
.qualified(const: true, volatile: false, type: .void)
)
case .void: .void
case .unsafePointer, .unsafeMutablePointer, .unsafeRawBufferPointer, .unsafeMutableRawBufferPointer, .unsafeBufferPointer, .unsafeMutableBufferPointer, .string:
case .unsafePointer, .unsafeMutablePointer, .unsafeRawBufferPointer, .unsafeMutableRawBufferPointer, .unsafeBufferPointer, .unsafeMutableBufferPointer, .string, .data:
nil
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ extension FFMSwift2JavaGenerator {
enclosingType: try enclosingType.map { try SwiftType($0, symbolTable: symbolTable) },
symbolTable: symbolTable
)
return try CdeclLowering(swiftStdlibTypes: swiftStdlibTypes).lowerFunctionSignature(signature)
return try CdeclLowering(symbolTable: symbolTable).lowerFunctionSignature(signature)
}

/// Lower the given initializer to a C-compatible entrypoint,
Expand All @@ -46,7 +46,7 @@ extension FFMSwift2JavaGenerator {
symbolTable: symbolTable
)

return try CdeclLowering(swiftStdlibTypes: swiftStdlibTypes).lowerFunctionSignature(signature)
return try CdeclLowering(symbolTable: symbolTable).lowerFunctionSignature(signature)
}

/// Lower the given variable decl to a C-compatible entrypoint,
Expand All @@ -69,16 +69,16 @@ extension FFMSwift2JavaGenerator {
enclosingType: try enclosingType.map { try SwiftType($0, symbolTable: symbolTable) },
symbolTable: symbolTable
)
return try CdeclLowering(swiftStdlibTypes: swiftStdlibTypes).lowerFunctionSignature(signature)
return try CdeclLowering(symbolTable: symbolTable).lowerFunctionSignature(signature)
}
}

/// Responsible for lowering Swift API to C API.
struct CdeclLowering {
var knownTypes: SwiftKnownTypes

init(swiftStdlibTypes: SwiftStandardLibraryTypeDecls) {
self.knownTypes = SwiftKnownTypes(decls: swiftStdlibTypes)
init(symbolTable: SwiftSymbolTable) {
self.knownTypes = SwiftKnownTypes(symbolTable: symbolTable)
}

/// Lower the given Swift function signature to a Swift @_cdecl function signature,
Expand Down Expand Up @@ -266,6 +266,9 @@ struct CdeclLowering {
)
}

case .data:
break

default:
// Unreachable? Should be handled by `CType(cdeclType:)` lowering above.
throw LoweringError.unhandledType(type)
Expand Down Expand Up @@ -407,6 +410,9 @@ struct CdeclLowering {
])
)

case .data:
break

default:
throw LoweringError.unhandledType(type)
}
Expand Down Expand Up @@ -509,6 +515,9 @@ struct CdeclLowering {
// Returning string is not supported at this point.
throw LoweringError.unhandledType(type)

case .data:
break

default:
// Unreachable? Should be handled by `CType(cdeclType:)` lowering above.
throw LoweringError.unhandledType(type)
Expand Down Expand Up @@ -663,8 +672,7 @@ extension LoweredFunctionSignature {
package func cdeclThunk(
cName: String,
swiftAPIName: String,
as apiKind: SwiftAPIKind,
stdlibTypes: SwiftStandardLibraryTypeDecls
as apiKind: SwiftAPIKind
) -> FunctionDeclSyntax {

let cdeclParams = allLoweredParameters.map(\.description).joined(separator: ", ")
Expand Down Expand Up @@ -765,7 +773,7 @@ extension LoweredFunctionSignature {
}

enum LoweringError: Error {
case inoutNotSupported(SwiftType)
case unhandledType(SwiftType)
case effectNotSupported(SwiftEffectSpecifier)
case inoutNotSupported(SwiftType, file: String = #file, line: Int = #line)
case unhandledType(SwiftType, file: String = #file, line: Int = #line)
case effectNotSupported(SwiftEffectSpecifier, file: String = #file, line: Int = #line)
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ extension FFMSwift2JavaGenerator {

let translated: TranslatedFunctionDecl?
do {
let translation = JavaTranslation(swiftStdlibTypes: self.swiftStdlibTypes)
let translation = JavaTranslation(symbolTable: self.symbolTable)
translated = try translation.translate(decl)
} catch {
self.log.info("Failed to translate: '\(decl.swiftDecl.qualifiedNameForDebug)'; \(error)")
Expand Down Expand Up @@ -113,12 +113,12 @@ extension FFMSwift2JavaGenerator {
}

struct JavaTranslation {
var swiftStdlibTypes: SwiftStandardLibraryTypeDecls
var symbolTable: SwiftSymbolTable

func translate(
_ decl: ImportedFunc
) throws -> TranslatedFunctionDecl {
let lowering = CdeclLowering(swiftStdlibTypes: self.swiftStdlibTypes)
let lowering = CdeclLowering(symbolTable: symbolTable)
let loweredSignature = try lowering.lowerFunctionSignature(decl.functionSignature)

// Name.
Expand Down Expand Up @@ -353,6 +353,9 @@ extension FFMSwift2JavaGenerator {
conversion: .call(.placeholder, function: "SwiftKit.toCString", withArena: true)
)

case .data:
break

default:
throw JavaTranslationError.unhandledType(swiftType)
}
Expand Down Expand Up @@ -438,6 +441,9 @@ extension FFMSwift2JavaGenerator {
)
)

case .data:
break

case .unsafePointer, .unsafeMutablePointer:
// FIXME: Implement
throw JavaTranslationError.unhandledType(swiftType)
Expand Down Expand Up @@ -629,6 +635,6 @@ extension CType {
}

enum JavaTranslationError: Error {
case inoutNotSupported(SwiftType)
case inoutNotSupported(SwiftType, file: String = #file, line: Int = #line)
case unhandledType(SwiftType, file: String = #file, line: Int = #line)
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ extension FFMSwift2JavaGenerator {

""")

printSwiftThunkImports(&printer)

for thunk in stt.renderGlobalThunks() {
printer.print(thunk)
printer.println()
Expand Down Expand Up @@ -114,11 +116,22 @@ extension FFMSwift2JavaGenerator {
"""
)

printSwiftThunkImports(&printer)

for thunk in stt.renderThunks(forType: ty) {
printer.print("\(thunk)")
printer.print("")
}
}

func printSwiftThunkImports(_ printer: inout CodePrinter) {
for module in self.symbolTable.importedModules.keys.sorted() {
guard module != "Swift" else {
continue
}
printer.print("import \(module)")
}
}
}

struct SwiftThunkTranslator {
Expand Down Expand Up @@ -196,8 +209,7 @@ struct SwiftThunkTranslator {
let thunkFunc = translated.loweredSignature.cdeclThunk(
cName: thunkName,
swiftAPIName: decl.name,
as: decl.apiKind,
stdlibTypes: st.swiftStdlibTypes
as: decl.apiKind
)
return [DeclSyntax(thunkFunc)]
}
Expand Down
2 changes: 0 additions & 2 deletions Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ package class FFMSwift2JavaGenerator: Swift2JavaGenerator {
let javaPackage: String
let swiftOutputDirectory: String
let javaOutputDirectory: String
let swiftStdlibTypes: SwiftStandardLibraryTypeDecls
let symbolTable: SwiftSymbolTable

var javaPackagePath: String {
Expand Down Expand Up @@ -53,7 +52,6 @@ package class FFMSwift2JavaGenerator: Swift2JavaGenerator {
self.swiftOutputDirectory = swiftOutputDirectory
self.javaOutputDirectory = javaOutputDirectory
self.symbolTable = translator.symbolTable
self.swiftStdlibTypes = translator.swiftStdlibTypeDecls

// If we are forced to write empty files, construct the expected outputs
if translator.config.writeEmptyFiles ?? false {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ extension JNISwift2JavaGenerator {
switch swiftType {
case .nominal(let nominalType):
if let knownType = nominalType.nominalTypeDecl.knownStandardLibraryType {
guard let javaType = translate(standardLibraryType: knownType) else {
guard let javaType = translate(knownType: knownType) else {
fatalError("unsupported known type: \(knownType)")
}
return javaType
Expand All @@ -83,8 +83,8 @@ extension JNISwift2JavaGenerator {
}
}

func translate(standardLibraryType: SwiftStandardLibraryTypeKind) -> JavaType? {
switch standardLibraryType {
func translate(knownType: SwiftKnownTypeDeclKind) -> JavaType? {
switch knownType {
case .bool: .boolean
case .int8: .byte
case .uint16: .char
Expand All @@ -101,6 +101,8 @@ extension JNISwift2JavaGenerator {
.unsafeRawBufferPointer, .unsafeMutableRawBufferPointer,
.unsafeBufferPointer, .unsafeMutableBufferPointer:
nil
case .data:
fatalError("unimplemented")
}
}
}
Expand Down
Loading
Loading