From 2bcdfef3635739768aeb07b58b4a0a8dcce48bd8 Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 4 Mar 2026 12:05:57 +0900 Subject: [PATCH 01/15] Using generic implementation to get enum discriminator --- ...t2JavaGenerator+JavaBindingsPrinting.swift | 14 +--- ...ift2JavaGenerator+SwiftThunkPrinting.swift | 66 ++----------------- Sources/SwiftJava/SynthesizedAPIs.swift | 36 ++++++++++ .../org/swift/swiftkit/core/SwiftObjects.java | 2 + 4 files changed, 46 insertions(+), 72 deletions(-) create mode 100644 Sources/SwiftJava/SynthesizedAPIs.swift diff --git a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift index 4a8b243b7..9a4f943d3 100644 --- a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift +++ b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift @@ -394,17 +394,9 @@ extension JNISwift2JavaGenerator { ) } - // TODO: Consider whether all of these "utility" functions can be printed using our existing printing logic. - if decl.swiftNominal.isGeneric { - printer.printBraceBlock("public Discriminator getDiscriminator()") { printer in - printer.print("return Discriminator.values()[$getDiscriminator(this.$memoryAddress(), this.$typeMetadataAddress())];") - } - printer.print("private static native int $getDiscriminator(long self, long selfType);") - } else { - printer.printBraceBlock("public Discriminator getDiscriminator()") { printer in - printer.print("return Discriminator.values()[$getDiscriminator(this.$memoryAddress())];") - } - printer.print("private static native int $getDiscriminator(long self);") + printer.printBraceBlock("public Discriminator getDiscriminator()") { printer in + printer.print("var raw = SwiftObjects.getRawDiscriminator(this.$memoryAddress(), this.$typeMetadataAddress());") + printer.print("return Discriminator.values()[raw];") } } diff --git a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift index 713c8141e..84d9203da 100644 --- a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift +++ b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift @@ -259,7 +259,7 @@ extension JNISwift2JavaGenerator { } if type.swiftNominal.kind == .enum { - printEnumDiscriminator(&printer, type) + printEnumRawDiscriminator(&printer, type) printer.println() if !type.swiftNominal.isGeneric { @@ -294,51 +294,14 @@ extension JNISwift2JavaGenerator { try printSwiftInterfaceWrapper(&printer, protocolWrapper) } - private func printEnumDiscriminator(_ printer: inout CodePrinter, _ type: ImportedNominalType) { + private func printEnumRawDiscriminator(_ printer: inout CodePrinter, _ type: ImportedNominalType) { if type.cases.isEmpty { return } - let selfPointerParam = JavaParameter(name: "selfPointer", type: .long) - var parameters = [selfPointerParam] - if type.swiftNominal.isGeneric { - parameters.append(JavaParameter(name: "selfType", type: .long)) - } - - printCDecl( - &printer, - javaMethodName: "$getDiscriminator", - parentName: type.swiftNominal.name, - parameters: parameters, - resultType: .int - ) { printer in - if type.swiftNominal.isGeneric { - let knownTypes = SwiftKnownTypes(symbolTable: lookupContext.symbolTable) - let discriminatorFunctionSignature = SwiftFunctionSignature( - selfParameter: .instance(SwiftParameter(convention: .byValue, parameterName: "selfPointer", type: type.swiftType)), - parameters: [], - result: .init(convention: .direct, type: knownTypes.int), - effectSpecifiers: [], - genericParameters: [], - genericRequirements: [] - ) - printFunctionOpenerCall( - &printer, - .init( - module: swiftModuleName, - swiftDecl: DeclSyntax("func getDiscriminator() -> Int"), - name: "getDiscriminator", - apiKind: .function, - functionSignature: discriminatorFunctionSignature - ) - ) - } else { - let selfPointer = self.printSelfJLongToUnsafeMutablePointer( - &printer, - swiftParentName: type.swiftNominal.name, - selfPointerParam - ) - printer.printBraceBlock("switch (\(selfPointer).pointee)") { printer in + printer.printBraceBlock("extension \(type.swiftNominal.qualifiedName): SwiftJava._RawDiscriminatorRepresentable") { printer in + printer.printBraceBlock("public var _rawDiscriminator: Int32") { printer in + printer.printBraceBlock("switch self") { printer in for (idx, enumCase) in type.cases.enumerated() { printer.print("case .\(enumCase.name): return \(idx)") } @@ -1009,10 +972,6 @@ extension JNISwift2JavaGenerator { printFunctionDecl(&printer, decl: method, skipMethodBody: true) } - if type.swiftNominal.kind == .enum { - printer.print("static func _getDiscriminator(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong) -> jint") - } - printer.print("static func _destroy(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong)") } printer.println() @@ -1027,21 +986,6 @@ extension JNISwift2JavaGenerator { printFunctionDecl(&printer, decl: method, skipMethodBody: false) } - if type.swiftNominal.kind == .enum { - printer.printBraceBlock("static func _getDiscriminator(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong) -> jint") { printer in - let selfPointer = self.printSelfJLongToUnsafeMutablePointer( - &printer, - swiftParentName: "Self", - JavaParameter(name: "selfPointer", type: .long) - ) - printer.printBraceBlock("switch (\(selfPointer).pointee)") { printer in - for (idx, enumCase) in type.cases.enumerated() { - printer.print("case .\(enumCase.name): return \(idx)") - } - } - } - } - printer.printBraceBlock("static func _destroy(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong)") { printer in printer.print(#"assert(selfPointer != 0, "self memory address was null")"#) printer.print("let selfBits$ = Int(Int64(fromJNI: selfPointer, in: environment))") diff --git a/Sources/SwiftJava/SynthesizedAPIs.swift b/Sources/SwiftJava/SynthesizedAPIs.swift new file mode 100644 index 000000000..afc7c2b9c --- /dev/null +++ b/Sources/SwiftJava/SynthesizedAPIs.swift @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2026 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +public protocol _RawDiscriminatorRepresentable { + var _rawDiscriminator: Int32 { get } +} + +@_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_getRawDiscriminator__JJ") +public func Java_org_swift_swiftkit_core_SwiftObjects_getRawDiscriminator__JJ(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) -> jint { + func perform(as type: T.Type) -> jint { + guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { + fatalError() + } + return self$.pointee._rawDiscriminator.getJNIValue(in: environment) + } + + let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) + guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { + fatalError("selfType metadata address was null") + } + guard let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) as? (any _RawDiscriminatorRepresentable.Type) else { + return 0 + } + return perform(as: typeMetadata) +} diff --git a/SwiftKitCore/src/main/java/org/swift/swiftkit/core/SwiftObjects.java b/SwiftKitCore/src/main/java/org/swift/swiftkit/core/SwiftObjects.java index c508e90e4..1d72c796c 100644 --- a/SwiftKitCore/src/main/java/org/swift/swiftkit/core/SwiftObjects.java +++ b/SwiftKitCore/src/main/java/org/swift/swiftkit/core/SwiftObjects.java @@ -23,4 +23,6 @@ public static void requireNonZero(long number, String name) { throw new IllegalArgumentException(String.format("'%s' must not be zero!", name)); } } + + public static native int getRawDiscriminator(long selfPointer, long selfTypePointer); } From 10778432314c822e85244c34601e51deee93a777 Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 4 Mar 2026 14:01:31 +0900 Subject: [PATCH 02/15] Using generic implementation for toString methods --- Package.swift | 1 + ...t2JavaGenerator+JavaBindingsPrinting.swift | 24 ++++++----- .../JExtractSwiftLib/Swift2JavaVisitor.swift | 2 - Sources/SwiftJava/SynthesizedAPIs.swift | 40 ++++++++++++++++++- .../org/swift/swiftkit/core/SwiftObjects.java | 2 + 5 files changed, 55 insertions(+), 14 deletions(-) diff --git a/Package.swift b/Package.swift index e3a5b37bd..33942566a 100644 --- a/Package.swift +++ b/Package.swift @@ -311,6 +311,7 @@ let package = Package( exclude: ["swift-java.config"], swiftSettings: [ .swiftLanguageMode(.v5), + .enableUpcomingFeature("ImplicitOpenExistentials"), .unsafeFlags( ["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"], .when(platforms: [.macOS, .linux, .windows]) diff --git a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift index 9a4f943d3..db8883e15 100644 --- a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift +++ b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift @@ -295,6 +295,20 @@ extension JNISwift2JavaGenerator { printTypeMetadataAddressFunction(&printer, decl) printer.println() + + printer.print( + """ + public String toString() { + return SwiftObjects.toString(this.$memoryAddress(), this.$typeMetadataAddress()); + } + + public String toDebugString() { + return SwiftObjects.toDebugString(this.$memoryAddress(), this.$typeMetadataAddress()); + } + """ + ) + printer.println() + printDestroyFunction(&printer, decl) } } @@ -713,16 +727,6 @@ extension JNISwift2JavaGenerator { let funcName = "$typeMetadataAddress" printer.print("@Override") printer.printBraceBlock("public long $typeMetadataAddress()") { printer in - printer.print( - """ - long self$ = this.$memoryAddress(); - if (CallTraces.TRACE_DOWNCALLS) { - CallTraces.traceDowncall("\(type.swiftNominal.name).\(funcName)", - "this", this, - "self", self$); - } - """ - ) printer.print("return \(type.swiftNominal.name).$typeMetadataAddressDowncall();") } } diff --git a/Sources/JExtractSwiftLib/Swift2JavaVisitor.swift b/Sources/JExtractSwiftLib/Swift2JavaVisitor.swift index ebfb25c61..fce70c54e 100644 --- a/Sources/JExtractSwiftLib/Swift2JavaVisitor.swift +++ b/Sources/JExtractSwiftLib/Swift2JavaVisitor.swift @@ -85,8 +85,6 @@ final class Swift2JavaVisitor { for memberItem in node.memberBlock.members { self.visit(decl: memberItem.decl, in: importedNominalType, sourceFilePath: sourceFilePath) } - - self.synthesizeToStringMethods(in: importedNominalType) } func visit( diff --git a/Sources/SwiftJava/SynthesizedAPIs.swift b/Sources/SwiftJava/SynthesizedAPIs.swift index afc7c2b9c..aa69f0703 100644 --- a/Sources/SwiftJava/SynthesizedAPIs.swift +++ b/Sources/SwiftJava/SynthesizedAPIs.swift @@ -29,8 +29,44 @@ public func Java_org_swift_swiftkit_core_SwiftObjects_getRawDiscriminator__JJ(en guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { fatalError("selfType metadata address was null") } - guard let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) as? (any _RawDiscriminatorRepresentable.Type) else { - return 0 + let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) + guard let typeMetadata = typeMetadata as? (any _RawDiscriminatorRepresentable.Type) else { + fatalError("_RawDiscriminatorRepresentable conformance did not found in \(typeMetadata)") } return perform(as: typeMetadata) } + +@_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_toString__JJ") +public func Java_org_swift_swiftkit_core_SwiftObjects_toString__JJ(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) -> jstring? { + func perform(as type: T.Type) -> jstring? { + guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { + fatalError() + } + return String(describing: self$.pointee).getJNIValue(in: environment) + } + + let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) + guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { + fatalError("selfType metadata address was null") + } + let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) + return perform(as: typeMetadata) +} + +@_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_toDebugString__JJ") +public func Java_org_swift_swiftkit_core_SwiftObjects_toDebugString__JJ(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) -> jstring? { + func perform(as type: T.Type) -> jstring? { + guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { + fatalError() + } + return String(reflecting: self$.pointee).getJNIValue(in: environment) + } + + let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) + guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { + fatalError("selfType metadata address was null") + } + let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) + return perform(as: typeMetadata) +} + diff --git a/SwiftKitCore/src/main/java/org/swift/swiftkit/core/SwiftObjects.java b/SwiftKitCore/src/main/java/org/swift/swiftkit/core/SwiftObjects.java index 1d72c796c..28e30bd65 100644 --- a/SwiftKitCore/src/main/java/org/swift/swiftkit/core/SwiftObjects.java +++ b/SwiftKitCore/src/main/java/org/swift/swiftkit/core/SwiftObjects.java @@ -25,4 +25,6 @@ public static void requireNonZero(long number, String name) { } public static native int getRawDiscriminator(long selfPointer, long selfTypePointer); + public static native String toString(long selfPointer, long selfTypePointer); + public static native String toDebugString(long selfPointer, long selfTypePointer); } From a7255380e855500ca19479c2a375f7fe4ef05121 Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 4 Mar 2026 14:11:52 +0900 Subject: [PATCH 03/15] Using generic implementation for destroy --- ...t2JavaGenerator+JavaBindingsPrinting.swift | 15 ++--- ...ift2JavaGenerator+SwiftThunkPrinting.swift | 63 ------------------- Sources/SwiftJava/SynthesizedAPIs.swift | 45 +++++++++---- .../org/swift/swiftkit/core/SwiftObjects.java | 1 + 4 files changed, 37 insertions(+), 87 deletions(-) diff --git a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift index db8883e15..2b119a409 100644 --- a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift +++ b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift @@ -734,21 +734,14 @@ extension JNISwift2JavaGenerator { /// Prints the destroy function for a `JNISwiftInstance` private func printDestroyFunction(_ printer: inout CodePrinter, _ type: ImportedNominalType) { - let isGeneric = type.swiftNominal.isGeneric - if isGeneric { - printer.print("private static native void $destroy(long selfPointer, long selfType);") - } else { - printer.print("private static native void $destroy(long selfPointer);") - } - let funcName = "$createDestroyFunction" printer.print("@Override") printer.printBraceBlock("public Runnable \(funcName)()") { printer in printer.print("long self$ = this.$memoryAddress();") - if isGeneric { + printer.print("long selfType$ = this.$typeMetadataAddress();") + if type.swiftNominal.isGeneric { printer.print( """ - long selfType$ = this.$typeMetadataAddress(); if (CallTraces.TRACE_DOWNCALLS) { CallTraces.traceDowncall("\(type.swiftNominal.name).\(funcName)", "this", this, @@ -761,7 +754,7 @@ extension JNISwift2JavaGenerator { if (CallTraces.TRACE_DOWNCALLS) { CallTraces.traceDowncall("\(type.swiftNominal.name).$destroy", "self", self$, "selfType", selfType$); } - \(type.swiftNominal.name).$destroy(self$, selfType$); + SwiftObjects.destroy(self$, selfType$); } }; """ @@ -780,7 +773,7 @@ extension JNISwift2JavaGenerator { if (CallTraces.TRACE_DOWNCALLS) { CallTraces.traceDowncall("\(type.swiftNominal.name).$destroy", "self", self$); } - \(type.swiftNominal.name).$destroy(self$); + SwiftObjects.destroy(self$, selfType$); } }; """ diff --git a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift index 84d9203da..29fc05b0b 100644 --- a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift +++ b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift @@ -283,7 +283,6 @@ extension JNISwift2JavaGenerator { printSpecificTypeThunks(&printer, type) printTypeMetadataAddressThunk(&printer, type) printer.println() - printDestroyFunctionThunk(&printer, type) } private func printProtocolThunks(_ printer: inout CodePrinter, _ type: ImportedNominalType) throws { @@ -777,55 +776,6 @@ extension JNISwift2JavaGenerator { } } - /// Prints the implementation of the destroy function. - private func printDestroyFunctionThunk(_ printer: inout CodePrinter, _ type: ImportedNominalType) { - let selfPointerParam = JavaParameter(name: "selfPointer", type: .long) - var parameters = [selfPointerParam] - if type.swiftNominal.isGeneric { - parameters.append(JavaParameter(name: "selfType", type: .long)) - } - - printCDecl( - &printer, - javaMethodName: "$destroy", - parentName: type.swiftNominal.qualifiedName, - parameters: parameters, - resultType: .void - ) { printer in - if type.swiftNominal.isGeneric { - let destroyFunctionSignature = SwiftFunctionSignature( - selfParameter: .instance(SwiftParameter(convention: .byValue, parameterName: "selfPointer", type: type.swiftType)), - parameters: [], - result: .void, - effectSpecifiers: [], - genericParameters: [], - genericRequirements: [] - ) - printFunctionOpenerCall( - &printer, - .init( - module: swiftModuleName, - swiftDecl: DeclSyntax("func destroy()"), - name: "destroy", - apiKind: .function, - functionSignature: destroyFunctionSignature - ) - ) - } else { - let parentName = type.qualifiedName - let selfVar = self.printSelfJLongToUnsafeMutablePointer(&printer, swiftParentName: parentName, selfPointerParam) - // Deinitialize the pointer allocated (which will call the VWT destroy method) - // then deallocate the memory. - printer.print( - """ - \(selfVar).deinitialize(count: 1) - \(selfVar).deallocate() - """ - ) - } - } - } - /// Prints thunks for specific known types like Foundation.Date, Foundation.Data private func printSpecificTypeThunks(_ printer: inout CodePrinter, _ type: ImportedNominalType) { guard let knownType = type.swiftNominal.knownTypeKind else { return } @@ -971,8 +921,6 @@ extension JNISwift2JavaGenerator { for method in type.methods { printFunctionDecl(&printer, decl: method, skipMethodBody: true) } - - printer.print("static func _destroy(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong)") } printer.println() printer.printBraceBlock("extension \(type.swiftNominal.name): \(protocolName)") { printer in @@ -985,17 +933,6 @@ extension JNISwift2JavaGenerator { if method.isStatic { continue } printFunctionDecl(&printer, decl: method, skipMethodBody: false) } - - printer.printBraceBlock("static func _destroy(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong)") { printer in - printer.print(#"assert(selfPointer != 0, "self memory address was null")"#) - printer.print("let selfBits$ = Int(Int64(fromJNI: selfPointer, in: environment))") - printer.print("let self$ = UnsafeMutablePointer(bitPattern: selfBits$)") - printer.printBraceBlock("guard let self$ else") { printer in - printer.print("fatalError(\"self memory address was null in call to \\(#function)!\")") - } - printer.print("self$.deinitialize(count: 1)") - printer.print("self$.deallocate()") - } } } diff --git a/Sources/SwiftJava/SynthesizedAPIs.swift b/Sources/SwiftJava/SynthesizedAPIs.swift index aa69f0703..45ca6af2b 100644 --- a/Sources/SwiftJava/SynthesizedAPIs.swift +++ b/Sources/SwiftJava/SynthesizedAPIs.swift @@ -18,13 +18,6 @@ public protocol _RawDiscriminatorRepresentable { @_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_getRawDiscriminator__JJ") public func Java_org_swift_swiftkit_core_SwiftObjects_getRawDiscriminator__JJ(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) -> jint { - func perform(as type: T.Type) -> jint { - guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { - fatalError() - } - return self$.pointee._rawDiscriminator.getJNIValue(in: environment) - } - let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { fatalError("selfType metadata address was null") @@ -33,40 +26,66 @@ public func Java_org_swift_swiftkit_core_SwiftObjects_getRawDiscriminator__JJ(en guard let typeMetadata = typeMetadata as? (any _RawDiscriminatorRepresentable.Type) else { fatalError("_RawDiscriminatorRepresentable conformance did not found in \(typeMetadata)") } + + func perform(as type: T.Type) -> jint { + guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { + fatalError("self memory address was null") + } + return self$.pointee._rawDiscriminator.getJNIValue(in: environment) + } return perform(as: typeMetadata) } @_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_toString__JJ") public func Java_org_swift_swiftkit_core_SwiftObjects_toString__JJ(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) -> jstring? { + let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) + guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { + fatalError("selfType metadata address was null") + } + let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) + func perform(as type: T.Type) -> jstring? { guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { - fatalError() + fatalError("self memory address was null") } return String(describing: self$.pointee).getJNIValue(in: environment) } + return perform(as: typeMetadata) +} +@_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_toDebugString__JJ") +public func Java_org_swift_swiftkit_core_SwiftObjects_toDebugString__JJ(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) -> jstring? { let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { fatalError("selfType metadata address was null") } let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) - return perform(as: typeMetadata) -} -@_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_toDebugString__JJ") -public func Java_org_swift_swiftkit_core_SwiftObjects_toDebugString__JJ(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) -> jstring? { func perform(as type: T.Type) -> jstring? { guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { - fatalError() + fatalError("self memory address was null") } return String(reflecting: self$.pointee).getJNIValue(in: environment) } + return perform(as: typeMetadata) +} + +@_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_destroy__JJ") +public func Java_org_swift_swiftkit_core_SwiftObjects_destroy__JJ(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) { let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { fatalError("selfType metadata address was null") } let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) + + func perform(as type: T.Type) { + guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { + fatalError("self memory address was null") + } + self$.deinitialize(count: 1) + self$.deallocate() + } return perform(as: typeMetadata) } diff --git a/SwiftKitCore/src/main/java/org/swift/swiftkit/core/SwiftObjects.java b/SwiftKitCore/src/main/java/org/swift/swiftkit/core/SwiftObjects.java index 28e30bd65..3674198eb 100644 --- a/SwiftKitCore/src/main/java/org/swift/swiftkit/core/SwiftObjects.java +++ b/SwiftKitCore/src/main/java/org/swift/swiftkit/core/SwiftObjects.java @@ -27,4 +27,5 @@ public static void requireNonZero(long number, String name) { public static native int getRawDiscriminator(long selfPointer, long selfTypePointer); public static native String toString(long selfPointer, long selfTypePointer); public static native String toDebugString(long selfPointer, long selfTypePointer); + public static native void destroy(long selfPointer, long selfTypePointer); } From 044f7e471b21b1655806c4929217e6ae4810e3c2 Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 4 Mar 2026 14:14:29 +0900 Subject: [PATCH 04/15] Remove unused synthesizedFunction logic --- ...Swift2JavaGenerator+FunctionLowering.swift | 8 ---- ...MSwift2JavaGenerator+JavaTranslation.swift | 2 +- Sources/JExtractSwiftLib/ImportedDecls.swift | 8 +--- ...ISwift2JavaGenerator+JavaTranslation.swift | 2 +- ...ift2JavaGenerator+SwiftThunkPrinting.swift | 9 ----- .../JExtractSwiftLib/Swift2JavaVisitor.swift | 40 ------------------- 6 files changed, 3 insertions(+), 66 deletions(-) diff --git a/Sources/JExtractSwiftLib/FFM/CDeclLowering/FFMSwift2JavaGenerator+FunctionLowering.swift b/Sources/JExtractSwiftLib/FFM/CDeclLowering/FFMSwift2JavaGenerator+FunctionLowering.swift index 9d53b8b54..32757a790 100644 --- a/Sources/JExtractSwiftLib/FFM/CDeclLowering/FFMSwift2JavaGenerator+FunctionLowering.swift +++ b/Sources/JExtractSwiftLib/FFM/CDeclLowering/FFMSwift2JavaGenerator+FunctionLowering.swift @@ -993,14 +993,6 @@ extension LoweredFunctionSignature { .joined(separator: ", ") resultExpr = "\(callee)(\(raw: arguments))" - case .synthesizedFunction(let function): - switch function { - case .toString: - resultExpr = "String(describing: \(callee))" - case .toDebugString: - resultExpr = "String(reflecting: \(callee))" - } - case .getter: assert(paramExprs.isEmpty) resultExpr = callee diff --git a/Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator+JavaTranslation.swift b/Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator+JavaTranslation.swift index 40d744473..a7050cf54 100644 --- a/Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator+JavaTranslation.swift +++ b/Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator+JavaTranslation.swift @@ -160,7 +160,7 @@ extension FFMSwift2JavaGenerator { switch decl.apiKind { case .getter, .subscriptGetter: decl.javaGetterName case .setter, .subscriptSetter: decl.javaSetterName - case .function, .synthesizedFunction, .initializer, .enumCase: decl.name + case .function, .initializer, .enumCase: decl.name } // Signature. diff --git a/Sources/JExtractSwiftLib/ImportedDecls.swift b/Sources/JExtractSwiftLib/ImportedDecls.swift index 1879bc767..21a36ef84 100644 --- a/Sources/JExtractSwiftLib/ImportedDecls.swift +++ b/Sources/JExtractSwiftLib/ImportedDecls.swift @@ -17,14 +17,8 @@ import SwiftSyntax /// Any imported (Swift) declaration protocol ImportedDecl: AnyObject {} -package enum SynthesizedAPI: Equatable { - case toString - case toDebugString -} - package enum SwiftAPIKind: Equatable { case function - case synthesizedFunction(SynthesizedAPI) case initializer case getter case setter @@ -188,7 +182,7 @@ public final class ImportedFunc: ImportedDecl, CustomStringConvertible { case .getter: "getter:" case .setter: "setter:" case .enumCase: "case:" - case .function, .synthesizedFunction, .initializer: "" + case .function, .initializer: "" case .subscriptGetter: "subscriptGetter:" case .subscriptSetter: "subscriptSetter:" } diff --git a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift index 3a4803add..8607ee16d 100644 --- a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift +++ b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift @@ -229,7 +229,7 @@ extension JNISwift2JavaGenerator { switch decl.apiKind { case .getter, .subscriptGetter: decl.javaGetterName case .setter, .subscriptSetter: decl.javaSetterName - case .function, .synthesizedFunction, .initializer, .enumCase: decl.name + case .function, .initializer, .enumCase: decl.name } // Swift -> Java diff --git a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift index 29fc05b0b..d5d91adfe 100644 --- a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift +++ b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift @@ -13,7 +13,6 @@ //===----------------------------------------------------------------------===// import JavaTypes -import SwiftSyntax #if canImport(FoundationEssentials) import FoundationEssentials @@ -585,14 +584,6 @@ extension JNISwift2JavaGenerator { .joined(separator: ", ") result = "\(tryClause)\(callee).\(decl.name)(\(downcallArguments))" - case .synthesizedFunction(let function): - switch function { - case .toString: - result = "String(describing: \(callee))" - case .toDebugString: - result = "String(reflecting: \(callee))" - } - case .enumCase: let downcallArguments = zip( decl.functionSignature.parameters, diff --git a/Sources/JExtractSwiftLib/Swift2JavaVisitor.swift b/Sources/JExtractSwiftLib/Swift2JavaVisitor.swift index fce70c54e..44e9c66f8 100644 --- a/Sources/JExtractSwiftLib/Swift2JavaVisitor.swift +++ b/Sources/JExtractSwiftLib/Swift2JavaVisitor.swift @@ -420,46 +420,6 @@ final class Swift2JavaVisitor { } } } - - private func synthesizeToStringMethods(in imported: ImportedNominalType) { - switch imported.swiftNominal.kind { - case .actor, .class, .enum, .struct: - break - case .protocol: - return - } - - let knownTypes = SwiftKnownTypes(symbolTable: translator.symbolTable) - let toStringFunctionSignature = SwiftFunctionSignature( - selfParameter: .instance(SwiftParameter(convention: .byValue, parameterName: "selfPointer", type: imported.swiftType)), - parameters: [], - result: SwiftResult(convention: .direct, type: knownTypes.string), - effectSpecifiers: [], - genericParameters: [], - genericRequirements: [] - ) - - func makeToStringFunc(name: String, kind: SwiftAPIKind) -> ImportedFunc { - ImportedFunc( - module: translator.swiftModuleName, - swiftDecl: DeclSyntax("func \(raw: name)() -> String"), - name: name, - apiKind: kind, - functionSignature: toStringFunctionSignature - ) - } - - if !imported.methods.contains(where: { - $0.name == "toString" && $0.functionSignature == toStringFunctionSignature - }) { - imported.methods.append(makeToStringFunc(name: "toString", kind: .synthesizedFunction(.toString))) - } - if !imported.methods.contains(where: { - $0.name == "toDebugString" && $0.functionSignature == toStringFunctionSignature - }) { - imported.methods.append(makeToStringFunc(name: "toDebugString", kind: .synthesizedFunction(.toDebugString))) - } - } } extension DeclSyntaxProtocol where Self: WithModifiersSyntax & WithAttributesSyntax { From 3f3f91b67488324845338b035525ca56be763586 Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 4 Mar 2026 14:32:18 +0900 Subject: [PATCH 05/15] Fix test fixtures --- ...ift2JavaGenerator+SwiftThunkPrinting.swift | 2 +- .../JNI/JNIClassTests.swift | 40 +------------ .../JExtractSwiftTests/JNI/JNIEnumTests.swift | 57 +++++++++---------- .../JNI/JNIGenericTypeTests.swift | 3 +- .../JNI/JNINestedTypesTests.swift | 12 ++-- .../JNI/JNIStructTests.swift | 39 +------------ .../JNI/JNISubscriptsTests.swift | 10 ---- .../JNI/JNIToStringTests.swift | 48 ++-------------- 8 files changed, 43 insertions(+), 168 deletions(-) diff --git a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift index d5d91adfe..d9cbca967 100644 --- a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift +++ b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift @@ -297,7 +297,7 @@ extension JNISwift2JavaGenerator { return } - printer.printBraceBlock("extension \(type.swiftNominal.qualifiedName): SwiftJava._RawDiscriminatorRepresentable") { printer in + printer.printBraceBlock("extension \(type.swiftNominal.qualifiedName): _RawDiscriminatorRepresentable") { printer in printer.printBraceBlock("public var _rawDiscriminator: Int32") { printer in printer.printBraceBlock("switch self") { printer in for (idx, enumCase) in type.cases.enumerated() { diff --git a/Tests/JExtractSwiftTests/JNI/JNIClassTests.swift b/Tests/JExtractSwiftTests/JNI/JNIClassTests.swift index 61afbf2b1..420cf1110 100644 --- a/Tests/JExtractSwiftTests/JNI/JNIClassTests.swift +++ b/Tests/JExtractSwiftTests/JNI/JNIClassTests.swift @@ -96,16 +96,6 @@ struct JNIClassTests { """, ] ) - try assertOutput( - input: source, - .jni, - .java, - expectedChunks: [ - """ - private static native void $destroy(long selfPointer); - """ - ] - ) try assertOutput( input: source, .jni, @@ -115,6 +105,7 @@ struct JNIClassTests { @Override public Runnable $createDestroyFunction() { long self$ = this.$memoryAddress(); + long selfType$ = this.$typeMetadataAddress(); if (CallTraces.TRACE_DOWNCALLS) { CallTraces.traceDowncall("MyClass.$createDestroyFunction", "this", this, @@ -126,7 +117,7 @@ struct JNIClassTests { if (CallTraces.TRACE_DOWNCALLS) { CallTraces.traceDowncall("MyClass.$destroy", "self", self$); } - MyClass.$destroy(self$); + SwiftObjects.destroy(self$, selfType$); } }; """ @@ -246,33 +237,6 @@ struct JNIClassTests { ) } - @Test - func destroyFunction_swiftThunks() throws { - try assertOutput( - input: source, - .jni, - .swift, - detectChunkByInitialLines: 1, - expectedChunks: [ - """ - @_cdecl("Java_com_example_swift_MyClass__00024destroy__J") - public func Java_com_example_swift_MyClass__00024destroy__J(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong) { - guard let env$ = environment else { - fatalError("Missing JNIEnv in downcall to \\(#function)") - } - assert(selfPointer != 0, "selfPointer memory address was null") - let selfBits$ = Int(Int64(fromJNI: selfPointer, in: env$)) - guard let self$ = UnsafeMutablePointer(bitPattern: selfBits$) else { - fatalError("self memory address was null in call to \\(#function)!") - } - self$.deinitialize(count: 1) - self$.deallocate() - } - """ - ] - ) - } - @Test func memberMethod_javaBindings() throws { try assertOutput( diff --git a/Tests/JExtractSwiftTests/JNI/JNIEnumTests.swift b/Tests/JExtractSwiftTests/JNI/JNIEnumTests.swift index 52d727ee8..94a893a5a 100644 --- a/Tests/JExtractSwiftTests/JNI/JNIEnumTests.swift +++ b/Tests/JExtractSwiftTests/JNI/JNIEnumTests.swift @@ -79,26 +79,25 @@ struct JNIEnumTests { } """, """ - private static native void $destroy(long selfPointer); - """, - """ @Override public Runnable $createDestroyFunction() { - long self$ = this.$memoryAddress(); - if (CallTraces.TRACE_DOWNCALLS) { - CallTraces.traceDowncall("MyEnum.$createDestroyFunction", - "this", this, - "self", self$); - } - return new Runnable() { - @Override - public void run() { - if (CallTraces.TRACE_DOWNCALLS) { - CallTraces.traceDowncall("MyEnum.$destroy", "self", self$); - } - MyEnum.$destroy(self$); + long self$ = this.$memoryAddress(); + long selfType$ = this.$typeMetadataAddress(); + if (CallTraces.TRACE_DOWNCALLS) { + CallTraces.traceDowncall("MyEnum.$createDestroyFunction", + "this", this, + "self", self$); } - }; + return new Runnable() { + @Override + public void run() { + if (CallTraces.TRACE_DOWNCALLS) { + CallTraces.traceDowncall("MyEnum.$destroy", "self", self$); + } + SwiftObjects.destroy(self$, selfType$); + } + }; + } """, ] ) @@ -110,7 +109,7 @@ struct JNIEnumTests { input: source, .jni, .java, - detectChunkByInitialLines: 1, + detectChunkByInitialLines: 2, expectedChunks: [ """ public enum Discriminator { @@ -121,12 +120,10 @@ struct JNIEnumTests { """, """ public Discriminator getDiscriminator() { - return Discriminator.values()[$getDiscriminator(this.$memoryAddress())]; + var raw = SwiftObjects.getRawDiscriminator(this.$memoryAddress(), this.$typeMetadataAddress()); + return Discriminator.values()[raw]; } - """, """ - private static native int $getDiscriminator(long self); - """, ] ) } @@ -140,14 +137,14 @@ struct JNIEnumTests { detectChunkByInitialLines: 1, expectedChunks: [ """ - @_cdecl("Java_com_example_swift_MyEnum__00024getDiscriminator__J") - public func Java_com_example_swift_MyEnum__00024getDiscriminator__J(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong) -> jint { - ... - switch (self$.pointee) { - case .first: return 0 - case .second: return 1 - case .third: return 2 - } + extension MyEnum: _RawDiscriminatorRepresentable { + public var _rawDiscriminator: Int32 { + switch self { + case .first: return 0 + case .second: return 1 + case .third: return 2 + } + } } """ ] diff --git a/Tests/JExtractSwiftTests/JNI/JNIGenericTypeTests.swift b/Tests/JExtractSwiftTests/JNI/JNIGenericTypeTests.swift index edcea576e..26461a0d5 100644 --- a/Tests/JExtractSwiftTests/JNI/JNIGenericTypeTests.swift +++ b/Tests/JExtractSwiftTests/JNI/JNIGenericTypeTests.swift @@ -73,7 +73,6 @@ struct JNIGenericTypeTests { } """, """ - private static native void $destroy(long selfPointer, long selfType); @Override public Runnable $createDestroyFunction() { long self$ = this.$memoryAddress(); @@ -90,7 +89,7 @@ struct JNIGenericTypeTests { if (CallTraces.TRACE_DOWNCALLS) { CallTraces.traceDowncall("MyID.$destroy", "self", self$, "selfType", selfType$); } - MyID.$destroy(self$, selfType$); + SwiftObjects.destroy(self$, selfType$); } }; } diff --git a/Tests/JExtractSwiftTests/JNI/JNINestedTypesTests.swift b/Tests/JExtractSwiftTests/JNI/JNINestedTypesTests.swift index bc36ac69c..d2d951e02 100644 --- a/Tests/JExtractSwiftTests/JNI/JNINestedTypesTests.swift +++ b/Tests/JExtractSwiftTests/JNI/JNINestedTypesTests.swift @@ -75,20 +75,20 @@ struct JNINestedTypesTests { detectChunkByInitialLines: 1, expectedChunks: [ """ - @_cdecl("Java_com_example_swift_A__00024destroy__J") - public func Java_com_example_swift_A__00024destroy__J(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong) { + @_cdecl("Java_com_example_swift_A__00024typeMetadataAddressDowncall__") + public func Java_com_example_swift_A__00024typeMetadataAddressDowncall__(environment: UnsafeMutablePointer!, thisClass: jclass) -> jlong { ... } """, """ - @_cdecl("Java_com_example_swift_A_00024B__00024destroy__J") - public func Java_com_example_swift_A_00024B__00024destroy__J(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong) { + @_cdecl("Java_com_example_swift_A_00024B__00024typeMetadataAddressDowncall__") + public func Java_com_example_swift_A_00024B__00024typeMetadataAddressDowncall__(environment: UnsafeMutablePointer!, thisClass: jclass) -> jlong { ... } """, """ - @_cdecl("Java_com_example_swift_A_00024B__00024destroy__J") - public func Java_com_example_swift_A_00024B__00024destroy__J(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong) { + @_cdecl("Java_com_example_swift_A_00024B_00024C__00024typeMetadataAddressDowncall__") + public func Java_com_example_swift_A_00024B_00024C__00024typeMetadataAddressDowncall__(environment: UnsafeMutablePointer!, thisClass: jclass) -> jlong { ... } """, diff --git a/Tests/JExtractSwiftTests/JNI/JNIStructTests.swift b/Tests/JExtractSwiftTests/JNI/JNIStructTests.swift index 023e72a33..1a13bf252 100644 --- a/Tests/JExtractSwiftTests/JNI/JNIStructTests.swift +++ b/Tests/JExtractSwiftTests/JNI/JNIStructTests.swift @@ -82,16 +82,6 @@ struct JNIStructTests { """, ] ) - try assertOutput( - input: source, - .jni, - .java, - expectedChunks: [ - """ - private static native void $destroy(long selfPointer); - """ - ] - ) try assertOutput( input: source, .jni, @@ -101,6 +91,7 @@ struct JNIStructTests { @Override public Runnable $createDestroyFunction() { long self$ = this.$memoryAddress(); + long selfType$ = this.$typeMetadataAddress(); if (CallTraces.TRACE_DOWNCALLS) { CallTraces.traceDowncall("MyStruct.$createDestroyFunction", "this", this, @@ -112,7 +103,7 @@ struct JNIStructTests { if (CallTraces.TRACE_DOWNCALLS) { CallTraces.traceDowncall("MyStruct.$destroy", "self", self$); } - MyStruct.$destroy(self$); + SwiftObjects.destroy(self$, selfType$); } }; } @@ -167,32 +158,6 @@ struct JNIStructTests { ) } - @Test - func destroyFunction_swiftThunks() throws { - try assertOutput( - input: source, - .jni, - .swift, - expectedChunks: [ - """ - @_cdecl("Java_com_example_swift_MyStruct__00024destroy__J") - public func Java_com_example_swift_MyStruct__00024destroy__J(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong) { - guard let env$ = environment else { - fatalError("Missing JNIEnv in downcall to \\(#function)") - } - assert(selfPointer != 0, "selfPointer memory address was null") - let selfBits$ = Int(Int64(fromJNI: selfPointer, in: env$)) - guard let self$ = UnsafeMutablePointer(bitPattern: selfBits$) else { - fatalError("self memory address was null in call to \\(#function)!") - } - self$.deinitialize(count: 1) - self$.deallocate() - } - """ - ] - ) - } - @Test func memberMethod_javaBindings() throws { try assertOutput( diff --git a/Tests/JExtractSwiftTests/JNI/JNISubscriptsTests.swift b/Tests/JExtractSwiftTests/JNI/JNISubscriptsTests.swift index 0d058bca4..2b3d11a77 100644 --- a/Tests/JExtractSwiftTests/JNI/JNISubscriptsTests.swift +++ b/Tests/JExtractSwiftTests/JNI/JNISubscriptsTests.swift @@ -62,16 +62,6 @@ struct JNISubscriptsTests { """, ] ) - try assertOutput( - input: noParamsSubscriptSource, - .jni, - .java, - expectedChunks: [ - """ - private static native void $destroy(long selfPointer); - """ - ] - ) } @Test("Test generation of JavaClass for subscript with parameters") diff --git a/Tests/JExtractSwiftTests/JNI/JNIToStringTests.swift b/Tests/JExtractSwiftTests/JNI/JNIToStringTests.swift index 45b67aca5..4b0437b96 100644 --- a/Tests/JExtractSwiftTests/JNI/JNIToStringTests.swift +++ b/Tests/JExtractSwiftTests/JNI/JNIToStringTests.swift @@ -32,28 +32,8 @@ struct JNIToStringTests { detectChunkByInitialLines: 1, expectedChunks: [ """ - public java.lang.String toString() { - return MyType.$toString(this.$memoryAddress()); - } - private static native java.lang.String $toString(long selfPointer); - """ - ] - ) - } - - @Test("JNI toString (Swift)") - func toString_swift() throws { - try assertOutput( - input: source, - .jni, - .swift, - detectChunkByInitialLines: 1, - expectedChunks: [ - """ - @_cdecl("Java_com_example_swift_MyType__00024toString__J") - public func Java_com_example_swift_MyType__00024toString__J(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong) -> jstring? { - ... - return String(describing: selfPointer$.pointee).getJNIValue(in: environment) + public String toString() { + return SwiftObjects.toString(this.$memoryAddress(), this.$typeMetadataAddress()); } """ ] @@ -69,28 +49,8 @@ struct JNIToStringTests { detectChunkByInitialLines: 1, expectedChunks: [ """ - public java.lang.String toDebugString() { - return MyType.$toDebugString(this.$memoryAddress()); - } - private static native java.lang.String $toDebugString(long selfPointer); - """ - ] - ) - } - - @Test("JNI toDebugString (Swift)") - func toDebugString_swift() throws { - try assertOutput( - input: source, - .jni, - .swift, - detectChunkByInitialLines: 1, - expectedChunks: [ - """ - @_cdecl("Java_com_example_swift_MyType__00024toDebugString__J") - public func Java_com_example_swift_MyType__00024toDebugString__J(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong) -> jstring? { - ... - return String(reflecting: selfPointer$.pointee).getJNIValue(in: environment) + public String toDebugString() { + return SwiftObjects.toDebugString(this.$memoryAddress(), this.$typeMetadataAddress()); } """ ] From 8879b1fc1973747457d6129578dd28652ce03274 Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 4 Mar 2026 14:45:49 +0900 Subject: [PATCH 06/15] Fix warning --- .../JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift index 2b119a409..e34ab64f0 100644 --- a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift +++ b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift @@ -723,8 +723,6 @@ extension JNISwift2JavaGenerator { } } else { printer.print("private static native long $typeMetadataAddressDowncall();") - - let funcName = "$typeMetadataAddress" printer.print("@Override") printer.printBraceBlock("public long $typeMetadataAddress()") { printer in printer.print("return \(type.swiftNominal.name).$typeMetadataAddressDowncall();") From bd8642043ee28ce3554548228da1b9ef1f6cc332 Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 4 Mar 2026 15:42:44 +0900 Subject: [PATCH 07/15] swift format --- ...t2JavaGenerator+JavaBindingsPrinting.swift | 2 +- Sources/SwiftJava/SynthesizedAPIs.swift | 22 +++++++++++++++---- .../JExtractSwiftTests/JNI/JNIEnumTests.swift | 2 +- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift index e34ab64f0..18d239356 100644 --- a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift +++ b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift @@ -301,7 +301,7 @@ extension JNISwift2JavaGenerator { public String toString() { return SwiftObjects.toString(this.$memoryAddress(), this.$typeMetadataAddress()); } - + public String toDebugString() { return SwiftObjects.toDebugString(this.$memoryAddress(), this.$typeMetadataAddress()); } diff --git a/Sources/SwiftJava/SynthesizedAPIs.swift b/Sources/SwiftJava/SynthesizedAPIs.swift index 45ca6af2b..21e6ff4c6 100644 --- a/Sources/SwiftJava/SynthesizedAPIs.swift +++ b/Sources/SwiftJava/SynthesizedAPIs.swift @@ -17,7 +17,12 @@ public protocol _RawDiscriminatorRepresentable { } @_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_getRawDiscriminator__JJ") -public func Java_org_swift_swiftkit_core_SwiftObjects_getRawDiscriminator__JJ(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) -> jint { +public func Java_org_swift_swiftkit_core_SwiftObjects_getRawDiscriminator__JJ( + environment: UnsafeMutablePointer!, + thisClass: jclass, + selfPointer: jlong, + selfTypePointer: jlong +) -> jint { let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { fatalError("selfType metadata address was null") @@ -37,7 +42,12 @@ public func Java_org_swift_swiftkit_core_SwiftObjects_getRawDiscriminator__JJ(en } @_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_toString__JJ") -public func Java_org_swift_swiftkit_core_SwiftObjects_toString__JJ(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) -> jstring? { +public func Java_org_swift_swiftkit_core_SwiftObjects_toString__JJ( + environment: UnsafeMutablePointer!, + thisClass: jclass, + selfPointer: jlong, + selfTypePointer: jlong +) -> jstring? { let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { fatalError("selfType metadata address was null") @@ -54,7 +64,12 @@ public func Java_org_swift_swiftkit_core_SwiftObjects_toString__JJ(environment: } @_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_toDebugString__JJ") -public func Java_org_swift_swiftkit_core_SwiftObjects_toDebugString__JJ(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) -> jstring? { +public func Java_org_swift_swiftkit_core_SwiftObjects_toDebugString__JJ( + environment: UnsafeMutablePointer!, + thisClass: jclass, + selfPointer: jlong, + selfTypePointer: jlong +) -> jstring? { let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { fatalError("selfType metadata address was null") @@ -88,4 +103,3 @@ public func Java_org_swift_swiftkit_core_SwiftObjects_destroy__JJ(environment: U } return perform(as: typeMetadata) } - diff --git a/Tests/JExtractSwiftTests/JNI/JNIEnumTests.swift b/Tests/JExtractSwiftTests/JNI/JNIEnumTests.swift index 1842017b7..65cacd90e 100644 --- a/Tests/JExtractSwiftTests/JNI/JNIEnumTests.swift +++ b/Tests/JExtractSwiftTests/JNI/JNIEnumTests.swift @@ -123,7 +123,7 @@ struct JNIEnumTests { var raw = SwiftObjects.getRawDiscriminator(this.$memoryAddress(), this.$typeMetadataAddress()); return Discriminator.values()[raw]; } - """ + """, ] ) } From 584523f5ed168c4473a4866c80bc19fed8b3d68b Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 4 Mar 2026 15:53:42 +0900 Subject: [PATCH 08/15] Add comment explaining why traceDowncall is omitted --- .../JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift | 2 ++ Sources/SwiftJava/SynthesizedAPIs.swift | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift index 18d239356..736e1ba3f 100644 --- a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift +++ b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift @@ -725,6 +725,8 @@ extension JNISwift2JavaGenerator { printer.print("private static native long $typeMetadataAddressDowncall();") printer.print("@Override") printer.printBraceBlock("public long $typeMetadataAddress()") { printer in + // INFO: We are omitting `CallTraces.traceDowncall` here. + // It internally calls `toString`, which in turn calls `$typeMetadataAddress`, creating an infinite loop. printer.print("return \(type.swiftNominal.name).$typeMetadataAddressDowncall();") } } diff --git a/Sources/SwiftJava/SynthesizedAPIs.swift b/Sources/SwiftJava/SynthesizedAPIs.swift index 21e6ff4c6..201bd2037 100644 --- a/Sources/SwiftJava/SynthesizedAPIs.swift +++ b/Sources/SwiftJava/SynthesizedAPIs.swift @@ -85,7 +85,6 @@ public func Java_org_swift_swiftkit_core_SwiftObjects_toDebugString__JJ( return perform(as: typeMetadata) } - @_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_destroy__JJ") public func Java_org_swift_swiftkit_core_SwiftObjects_destroy__JJ(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) { let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) From 1c2d7c351eb411e9628ec4c4a6fc88f9141fa9f1 Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 4 Mar 2026 16:24:13 +0900 Subject: [PATCH 09/15] Use SwiftJavaMacros and rename file --- Sources/SwiftJava/SwiftObjects.swift | 92 +++++++++++++++++++++ Sources/SwiftJava/SynthesizedAPIs.swift | 104 ------------------------ 2 files changed, 92 insertions(+), 104 deletions(-) create mode 100644 Sources/SwiftJava/SwiftObjects.swift delete mode 100644 Sources/SwiftJava/SynthesizedAPIs.swift diff --git a/Sources/SwiftJava/SwiftObjects.swift b/Sources/SwiftJava/SwiftObjects.swift new file mode 100644 index 000000000..c8c6a4e84 --- /dev/null +++ b/Sources/SwiftJava/SwiftObjects.swift @@ -0,0 +1,92 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2026 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +public protocol _RawDiscriminatorRepresentable { + var _rawDiscriminator: Int32 { get } +} + +@JavaClass("org.swift.swiftkit.core.SwiftObjects") +open class SwiftObjects: JavaObject { +} + +@JavaImplementation("org.swift.swiftkit.core.SwiftObjects") +extension SwiftObjects { + @JavaMethod + func getRawDiscriminator(selfPointer: Int, selfTypePointer: Int) -> Int32 { + guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypePointer) else { + fatalError("selfType metadata address was null") + } + let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) + guard let typeMetadata = typeMetadata as? (any _RawDiscriminatorRepresentable.Type) else { + fatalError("_RawDiscriminatorRepresentable conformance did not found in \(typeMetadata)") + } + + func perform(as type: T.Type) -> Int32 { + guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { + fatalError("self memory address was null") + } + return self$.pointee._rawDiscriminator + } + return perform(as: typeMetadata) + } + + @JavaMethod + public func toString(selfPointer: Int, selfTypePointer: Int) -> String { + guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypePointer) else { + fatalError("selfType metadata address was null") + } + let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) + + func perform(as type: T.Type) -> String { + guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { + fatalError("self memory address was null") + } + return String(describing: self$.pointee) + } + return perform(as: typeMetadata) + } + + @JavaMethod + public func toDebugString(selfPointer: Int, selfTypePointer: Int) -> String { + guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypePointer) else { + fatalError("selfType metadata address was null") + } + let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) + + func perform(as type: T.Type) -> String { + guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { + fatalError("self memory address was null") + } + return String(reflecting: self$.pointee) + } + return perform(as: typeMetadata) + } + + @JavaMethod + public func destroy(selfPointer: Int, selfTypePointer: Int) { + guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypePointer) else { + fatalError("selfType metadata address was null") + } + let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) + + func perform(as type: T.Type) { + guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { + fatalError("self memory address was null") + } + self$.deinitialize(count: 1) + self$.deallocate() + } + return perform(as: typeMetadata) + } +} diff --git a/Sources/SwiftJava/SynthesizedAPIs.swift b/Sources/SwiftJava/SynthesizedAPIs.swift deleted file mode 100644 index 201bd2037..000000000 --- a/Sources/SwiftJava/SynthesizedAPIs.swift +++ /dev/null @@ -1,104 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2026 Apple Inc. and the Swift.org project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift.org project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -public protocol _RawDiscriminatorRepresentable { - var _rawDiscriminator: Int32 { get } -} - -@_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_getRawDiscriminator__JJ") -public func Java_org_swift_swiftkit_core_SwiftObjects_getRawDiscriminator__JJ( - environment: UnsafeMutablePointer!, - thisClass: jclass, - selfPointer: jlong, - selfTypePointer: jlong -) -> jint { - let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) - guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { - fatalError("selfType metadata address was null") - } - let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) - guard let typeMetadata = typeMetadata as? (any _RawDiscriminatorRepresentable.Type) else { - fatalError("_RawDiscriminatorRepresentable conformance did not found in \(typeMetadata)") - } - - func perform(as type: T.Type) -> jint { - guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { - fatalError("self memory address was null") - } - return self$.pointee._rawDiscriminator.getJNIValue(in: environment) - } - return perform(as: typeMetadata) -} - -@_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_toString__JJ") -public func Java_org_swift_swiftkit_core_SwiftObjects_toString__JJ( - environment: UnsafeMutablePointer!, - thisClass: jclass, - selfPointer: jlong, - selfTypePointer: jlong -) -> jstring? { - let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) - guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { - fatalError("selfType metadata address was null") - } - let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) - - func perform(as type: T.Type) -> jstring? { - guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { - fatalError("self memory address was null") - } - return String(describing: self$.pointee).getJNIValue(in: environment) - } - return perform(as: typeMetadata) -} - -@_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_toDebugString__JJ") -public func Java_org_swift_swiftkit_core_SwiftObjects_toDebugString__JJ( - environment: UnsafeMutablePointer!, - thisClass: jclass, - selfPointer: jlong, - selfTypePointer: jlong -) -> jstring? { - let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) - guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { - fatalError("selfType metadata address was null") - } - let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) - - func perform(as type: T.Type) -> jstring? { - guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { - fatalError("self memory address was null") - } - return String(reflecting: self$.pointee).getJNIValue(in: environment) - } - return perform(as: typeMetadata) -} - -@_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_destroy__JJ") -public func Java_org_swift_swiftkit_core_SwiftObjects_destroy__JJ(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) { - let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) - guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { - fatalError("selfType metadata address was null") - } - let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) - - func perform(as type: T.Type) { - guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { - fatalError("self memory address was null") - } - self$.deinitialize(count: 1) - self$.deallocate() - } - return perform(as: typeMetadata) -} From be833a470928903f677ff14c70499b51421101dd Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 5 Mar 2026 11:00:47 +0900 Subject: [PATCH 10/15] Add generic benchmark --- .../Sources/MySwiftLibrary/Benchmark.swift | 31 ++++++++ .../com/example/swift/GenericBenchmark.java | 71 +++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 Samples/SwiftJavaExtractJNISampleApp/Sources/MySwiftLibrary/Benchmark.swift create mode 100644 Samples/SwiftJavaExtractJNISampleApp/src/jmh/java/com/example/swift/GenericBenchmark.java diff --git a/Samples/SwiftJavaExtractJNISampleApp/Sources/MySwiftLibrary/Benchmark.swift b/Samples/SwiftJavaExtractJNISampleApp/Sources/MySwiftLibrary/Benchmark.swift new file mode 100644 index 000000000..2ad57c925 --- /dev/null +++ b/Samples/SwiftJavaExtractJNISampleApp/Sources/MySwiftLibrary/Benchmark.swift @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2026 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +public struct BasicStruct { + public var value: Int + public init(value: Int) { + self.value = value + } +} + +public struct GenericStruct { + public var value: Int + public init(value: Int) { + self.value = value + } +} + +public func makeGenericStruct(value: Int) -> GenericStruct { + return GenericStruct(value: value) +} diff --git a/Samples/SwiftJavaExtractJNISampleApp/src/jmh/java/com/example/swift/GenericBenchmark.java b/Samples/SwiftJavaExtractJNISampleApp/src/jmh/java/com/example/swift/GenericBenchmark.java new file mode 100644 index 000000000..63a4aeb4a --- /dev/null +++ b/Samples/SwiftJavaExtractJNISampleApp/src/jmh/java/com/example/swift/GenericBenchmark.java @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2026 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +package com.example.swift; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; +import org.swift.swiftkit.core.ClosableSwiftArena; +import org.swift.swiftkit.core.ConfinedSwiftMemorySession; +import org.swift.swiftkit.core.SwiftArena; + +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@Warmup(iterations = 5, time = 200, timeUnit = TimeUnit.MILLISECONDS) +@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Fork(value = 3, jvmArgsAppend = { "--enable-native-access=ALL-UNNAMED" }) +public class GenericBenchmark { + @State(Scope.Benchmark) + public static class BenchmarkState { + ClosableSwiftArena arena; + BasicStruct basicStruct; + GenericStruct genericStruct; + + @Setup(Level.Trial) + public void beforeAll() { + arena = SwiftArena.ofConfined(); + basicStruct = BasicStruct.init(42, arena); + genericStruct = MySwiftLibrary.makeGenericStruct(42, arena); + } + + @TearDown(Level.Trial) + public void afterAll() { + arena.close(); + } + } + + @Benchmark + public long basicStruct_basicGetter(BenchmarkState state, Blackhole bh) { + return state.basicStruct.getValue(); + } + + @Benchmark + public long genericStruct_basicGetter(BenchmarkState state, Blackhole bh) { + return state.genericStruct.getValue(); + } + + @Benchmark + public String basicStruct_toString(BenchmarkState state, Blackhole bh) { + // toString is internally implemented as a generic method in Swift + return state.basicStruct.toString(); + } + + @Benchmark + public String genericStruct_toString(BenchmarkState state, Blackhole bh) { + // toString is internally implemented as a generic method in Swift + return state.genericStruct.toString(); + } +} From c87e3904513822ed1a59f440d780ee9cd44820a4 Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 5 Mar 2026 11:00:55 +0900 Subject: [PATCH 11/15] Revert "Use SwiftJavaMacros and rename file" This reverts commit 1c2d7c351eb411e9628ec4c4a6fc88f9141fa9f1. --- Sources/SwiftJava/SwiftObjects.swift | 92 --------------------- Sources/SwiftJava/SynthesizedAPIs.swift | 104 ++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 92 deletions(-) delete mode 100644 Sources/SwiftJava/SwiftObjects.swift create mode 100644 Sources/SwiftJava/SynthesizedAPIs.swift diff --git a/Sources/SwiftJava/SwiftObjects.swift b/Sources/SwiftJava/SwiftObjects.swift deleted file mode 100644 index c8c6a4e84..000000000 --- a/Sources/SwiftJava/SwiftObjects.swift +++ /dev/null @@ -1,92 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2026 Apple Inc. and the Swift.org project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift.org project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -public protocol _RawDiscriminatorRepresentable { - var _rawDiscriminator: Int32 { get } -} - -@JavaClass("org.swift.swiftkit.core.SwiftObjects") -open class SwiftObjects: JavaObject { -} - -@JavaImplementation("org.swift.swiftkit.core.SwiftObjects") -extension SwiftObjects { - @JavaMethod - func getRawDiscriminator(selfPointer: Int, selfTypePointer: Int) -> Int32 { - guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypePointer) else { - fatalError("selfType metadata address was null") - } - let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) - guard let typeMetadata = typeMetadata as? (any _RawDiscriminatorRepresentable.Type) else { - fatalError("_RawDiscriminatorRepresentable conformance did not found in \(typeMetadata)") - } - - func perform(as type: T.Type) -> Int32 { - guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { - fatalError("self memory address was null") - } - return self$.pointee._rawDiscriminator - } - return perform(as: typeMetadata) - } - - @JavaMethod - public func toString(selfPointer: Int, selfTypePointer: Int) -> String { - guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypePointer) else { - fatalError("selfType metadata address was null") - } - let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) - - func perform(as type: T.Type) -> String { - guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { - fatalError("self memory address was null") - } - return String(describing: self$.pointee) - } - return perform(as: typeMetadata) - } - - @JavaMethod - public func toDebugString(selfPointer: Int, selfTypePointer: Int) -> String { - guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypePointer) else { - fatalError("selfType metadata address was null") - } - let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) - - func perform(as type: T.Type) -> String { - guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { - fatalError("self memory address was null") - } - return String(reflecting: self$.pointee) - } - return perform(as: typeMetadata) - } - - @JavaMethod - public func destroy(selfPointer: Int, selfTypePointer: Int) { - guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypePointer) else { - fatalError("selfType metadata address was null") - } - let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) - - func perform(as type: T.Type) { - guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { - fatalError("self memory address was null") - } - self$.deinitialize(count: 1) - self$.deallocate() - } - return perform(as: typeMetadata) - } -} diff --git a/Sources/SwiftJava/SynthesizedAPIs.swift b/Sources/SwiftJava/SynthesizedAPIs.swift new file mode 100644 index 000000000..201bd2037 --- /dev/null +++ b/Sources/SwiftJava/SynthesizedAPIs.swift @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2026 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +public protocol _RawDiscriminatorRepresentable { + var _rawDiscriminator: Int32 { get } +} + +@_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_getRawDiscriminator__JJ") +public func Java_org_swift_swiftkit_core_SwiftObjects_getRawDiscriminator__JJ( + environment: UnsafeMutablePointer!, + thisClass: jclass, + selfPointer: jlong, + selfTypePointer: jlong +) -> jint { + let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) + guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { + fatalError("selfType metadata address was null") + } + let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) + guard let typeMetadata = typeMetadata as? (any _RawDiscriminatorRepresentable.Type) else { + fatalError("_RawDiscriminatorRepresentable conformance did not found in \(typeMetadata)") + } + + func perform(as type: T.Type) -> jint { + guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { + fatalError("self memory address was null") + } + return self$.pointee._rawDiscriminator.getJNIValue(in: environment) + } + return perform(as: typeMetadata) +} + +@_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_toString__JJ") +public func Java_org_swift_swiftkit_core_SwiftObjects_toString__JJ( + environment: UnsafeMutablePointer!, + thisClass: jclass, + selfPointer: jlong, + selfTypePointer: jlong +) -> jstring? { + let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) + guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { + fatalError("selfType metadata address was null") + } + let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) + + func perform(as type: T.Type) -> jstring? { + guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { + fatalError("self memory address was null") + } + return String(describing: self$.pointee).getJNIValue(in: environment) + } + return perform(as: typeMetadata) +} + +@_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_toDebugString__JJ") +public func Java_org_swift_swiftkit_core_SwiftObjects_toDebugString__JJ( + environment: UnsafeMutablePointer!, + thisClass: jclass, + selfPointer: jlong, + selfTypePointer: jlong +) -> jstring? { + let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) + guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { + fatalError("selfType metadata address was null") + } + let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) + + func perform(as type: T.Type) -> jstring? { + guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { + fatalError("self memory address was null") + } + return String(reflecting: self$.pointee).getJNIValue(in: environment) + } + return perform(as: typeMetadata) +} + +@_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_destroy__JJ") +public func Java_org_swift_swiftkit_core_SwiftObjects_destroy__JJ(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) { + let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) + guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { + fatalError("selfType metadata address was null") + } + let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) + + func perform(as type: T.Type) { + guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { + fatalError("self memory address was null") + } + self$.deinitialize(count: 1) + self$.deallocate() + } + return perform(as: typeMetadata) +} From 4a7e8dd4ad7f92e1630a1bf7d7a0da3285d98dd6 Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 5 Mar 2026 11:41:49 +0900 Subject: [PATCH 12/15] Reapply "Use SwiftJavaMacros and rename file" This reverts commit c87e3904513822ed1a59f440d780ee9cd44820a4. --- Sources/SwiftJava/SwiftObjects.swift | 92 +++++++++++++++++++++ Sources/SwiftJava/SynthesizedAPIs.swift | 104 ------------------------ 2 files changed, 92 insertions(+), 104 deletions(-) create mode 100644 Sources/SwiftJava/SwiftObjects.swift delete mode 100644 Sources/SwiftJava/SynthesizedAPIs.swift diff --git a/Sources/SwiftJava/SwiftObjects.swift b/Sources/SwiftJava/SwiftObjects.swift new file mode 100644 index 000000000..c8c6a4e84 --- /dev/null +++ b/Sources/SwiftJava/SwiftObjects.swift @@ -0,0 +1,92 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2026 Apple Inc. and the Swift.org project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift.org project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +public protocol _RawDiscriminatorRepresentable { + var _rawDiscriminator: Int32 { get } +} + +@JavaClass("org.swift.swiftkit.core.SwiftObjects") +open class SwiftObjects: JavaObject { +} + +@JavaImplementation("org.swift.swiftkit.core.SwiftObjects") +extension SwiftObjects { + @JavaMethod + func getRawDiscriminator(selfPointer: Int, selfTypePointer: Int) -> Int32 { + guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypePointer) else { + fatalError("selfType metadata address was null") + } + let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) + guard let typeMetadata = typeMetadata as? (any _RawDiscriminatorRepresentable.Type) else { + fatalError("_RawDiscriminatorRepresentable conformance did not found in \(typeMetadata)") + } + + func perform(as type: T.Type) -> Int32 { + guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { + fatalError("self memory address was null") + } + return self$.pointee._rawDiscriminator + } + return perform(as: typeMetadata) + } + + @JavaMethod + public func toString(selfPointer: Int, selfTypePointer: Int) -> String { + guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypePointer) else { + fatalError("selfType metadata address was null") + } + let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) + + func perform(as type: T.Type) -> String { + guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { + fatalError("self memory address was null") + } + return String(describing: self$.pointee) + } + return perform(as: typeMetadata) + } + + @JavaMethod + public func toDebugString(selfPointer: Int, selfTypePointer: Int) -> String { + guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypePointer) else { + fatalError("selfType metadata address was null") + } + let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) + + func perform(as type: T.Type) -> String { + guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { + fatalError("self memory address was null") + } + return String(reflecting: self$.pointee) + } + return perform(as: typeMetadata) + } + + @JavaMethod + public func destroy(selfPointer: Int, selfTypePointer: Int) { + guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypePointer) else { + fatalError("selfType metadata address was null") + } + let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) + + func perform(as type: T.Type) { + guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { + fatalError("self memory address was null") + } + self$.deinitialize(count: 1) + self$.deallocate() + } + return perform(as: typeMetadata) + } +} diff --git a/Sources/SwiftJava/SynthesizedAPIs.swift b/Sources/SwiftJava/SynthesizedAPIs.swift deleted file mode 100644 index 201bd2037..000000000 --- a/Sources/SwiftJava/SynthesizedAPIs.swift +++ /dev/null @@ -1,104 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2026 Apple Inc. and the Swift.org project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift.org project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -public protocol _RawDiscriminatorRepresentable { - var _rawDiscriminator: Int32 { get } -} - -@_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_getRawDiscriminator__JJ") -public func Java_org_swift_swiftkit_core_SwiftObjects_getRawDiscriminator__JJ( - environment: UnsafeMutablePointer!, - thisClass: jclass, - selfPointer: jlong, - selfTypePointer: jlong -) -> jint { - let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) - guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { - fatalError("selfType metadata address was null") - } - let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) - guard let typeMetadata = typeMetadata as? (any _RawDiscriminatorRepresentable.Type) else { - fatalError("_RawDiscriminatorRepresentable conformance did not found in \(typeMetadata)") - } - - func perform(as type: T.Type) -> jint { - guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { - fatalError("self memory address was null") - } - return self$.pointee._rawDiscriminator.getJNIValue(in: environment) - } - return perform(as: typeMetadata) -} - -@_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_toString__JJ") -public func Java_org_swift_swiftkit_core_SwiftObjects_toString__JJ( - environment: UnsafeMutablePointer!, - thisClass: jclass, - selfPointer: jlong, - selfTypePointer: jlong -) -> jstring? { - let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) - guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { - fatalError("selfType metadata address was null") - } - let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) - - func perform(as type: T.Type) -> jstring? { - guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { - fatalError("self memory address was null") - } - return String(describing: self$.pointee).getJNIValue(in: environment) - } - return perform(as: typeMetadata) -} - -@_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_toDebugString__JJ") -public func Java_org_swift_swiftkit_core_SwiftObjects_toDebugString__JJ( - environment: UnsafeMutablePointer!, - thisClass: jclass, - selfPointer: jlong, - selfTypePointer: jlong -) -> jstring? { - let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) - guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { - fatalError("selfType metadata address was null") - } - let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) - - func perform(as type: T.Type) -> jstring? { - guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { - fatalError("self memory address was null") - } - return String(reflecting: self$.pointee).getJNIValue(in: environment) - } - return perform(as: typeMetadata) -} - -@_cdecl("Java_org_swift_swiftkit_core_SwiftObjects_destroy__JJ") -public func Java_org_swift_swiftkit_core_SwiftObjects_destroy__JJ(environment: UnsafeMutablePointer!, thisClass: jclass, selfPointer: jlong, selfTypePointer: jlong) { - let selfTypeBits$ = Int(Int64(fromJNI: selfTypePointer, in: environment)) - guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypeBits$) else { - fatalError("selfType metadata address was null") - } - let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self) - - func perform(as type: T.Type) { - guard let self$ = UnsafeMutablePointer(bitPattern: selfPointer) else { - fatalError("self memory address was null") - } - self$.deinitialize(count: 1) - self$.deallocate() - } - return perform(as: typeMetadata) -} From ff4e8e766c144fd5d25df3b4f7945a5239e65d30 Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 5 Mar 2026 11:58:33 +0900 Subject: [PATCH 13/15] Fix usage of SwiftJavaMacros --- Sources/SwiftJava/SwiftObjects.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/SwiftJava/SwiftObjects.swift b/Sources/SwiftJava/SwiftObjects.swift index c8c6a4e84..14933a5b2 100644 --- a/Sources/SwiftJava/SwiftObjects.swift +++ b/Sources/SwiftJava/SwiftObjects.swift @@ -23,7 +23,7 @@ open class SwiftObjects: JavaObject { @JavaImplementation("org.swift.swiftkit.core.SwiftObjects") extension SwiftObjects { @JavaMethod - func getRawDiscriminator(selfPointer: Int, selfTypePointer: Int) -> Int32 { + public static func getRawDiscriminator(environment: UnsafeMutablePointer!, selfPointer: Int, selfTypePointer: Int) -> Int32 { guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypePointer) else { fatalError("selfType metadata address was null") } @@ -42,7 +42,7 @@ extension SwiftObjects { } @JavaMethod - public func toString(selfPointer: Int, selfTypePointer: Int) -> String { + public static func toString(environment: UnsafeMutablePointer!, selfPointer: Int, selfTypePointer: Int) -> String { guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypePointer) else { fatalError("selfType metadata address was null") } @@ -58,7 +58,7 @@ extension SwiftObjects { } @JavaMethod - public func toDebugString(selfPointer: Int, selfTypePointer: Int) -> String { + public static func toDebugString(environment: UnsafeMutablePointer!, selfPointer: Int, selfTypePointer: Int) -> String { guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypePointer) else { fatalError("selfType metadata address was null") } @@ -74,7 +74,7 @@ extension SwiftObjects { } @JavaMethod - public func destroy(selfPointer: Int, selfTypePointer: Int) { + public static func destroy(environment: UnsafeMutablePointer!, selfPointer: Int, selfTypePointer: Int) { guard let selfType$ = UnsafeRawPointer(bitPattern: selfTypePointer) else { fatalError("selfType metadata address was null") } From 4184025f4ec11d26ae3fe524bc7cbca65dc86d42 Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 5 Mar 2026 12:09:45 +0900 Subject: [PATCH 14/15] apply formatting --- .../Sources/MySwiftLibrary/Benchmark.swift | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Samples/SwiftJavaExtractJNISampleApp/Sources/MySwiftLibrary/Benchmark.swift b/Samples/SwiftJavaExtractJNISampleApp/Sources/MySwiftLibrary/Benchmark.swift index 2ad57c925..4f96b528f 100644 --- a/Samples/SwiftJavaExtractJNISampleApp/Sources/MySwiftLibrary/Benchmark.swift +++ b/Samples/SwiftJavaExtractJNISampleApp/Sources/MySwiftLibrary/Benchmark.swift @@ -13,19 +13,19 @@ //===----------------------------------------------------------------------===// public struct BasicStruct { - public var value: Int - public init(value: Int) { - self.value = value - } + public var value: Int + public init(value: Int) { + self.value = value + } } public struct GenericStruct { - public var value: Int - public init(value: Int) { - self.value = value - } + public var value: Int + public init(value: Int) { + self.value = value + } } public func makeGenericStruct(value: Int) -> GenericStruct { - return GenericStruct(value: value) + GenericStruct(value: value) } From b412bed37ff78c443317f2e0b3a82d437a8893e7 Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 5 Mar 2026 15:01:06 +0900 Subject: [PATCH 15/15] Embed SwiftJavaRuntimeSupport into SwiftJava dynamic library --- Package.swift | 8 +------- Samples/SwiftJavaExtractJNISampleApp/Package.swift | 1 - 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/Package.swift b/Package.swift index 33942566a..1702da7a0 100644 --- a/Package.swift +++ b/Package.swift @@ -152,7 +152,7 @@ let package = Package( .library( name: "SwiftJava", type: .dynamic, - targets: ["SwiftJava"] + targets: ["SwiftJava", "SwiftJavaRuntimeSupport"] ), .library( @@ -226,12 +226,6 @@ let package = Package( ] ), - // Support library written in Swift for SwiftKit "Java" - .library( - name: "SwiftJavaRuntimeSupport", - targets: ["SwiftJavaRuntimeSupport"] - ), - .library( name: "SwiftRuntimeFunctions", type: .dynamic, diff --git a/Samples/SwiftJavaExtractJNISampleApp/Package.swift b/Samples/SwiftJavaExtractJNISampleApp/Package.swift index 121ffad8b..c30326cd1 100644 --- a/Samples/SwiftJavaExtractJNISampleApp/Package.swift +++ b/Samples/SwiftJavaExtractJNISampleApp/Package.swift @@ -110,7 +110,6 @@ let package = Package( dependencies: [ .product(name: "SwiftJava", package: "swift-java"), .product(name: "CSwiftJavaJNI", package: "swift-java"), - .product(name: "SwiftJavaRuntimeSupport", package: "swift-java"), ], exclude: [ "swift-java.config"