jni: Unify common methods using generic implementations#582
jni: Unify common methods using generic implementations#582sidepelican wants to merge 9 commits intoswiftlang:mainfrom
Conversation
# Conflicts: # Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift # Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift # Sources/JExtractSwiftLib/Swift2JavaVisitor.swift # Tests/JExtractSwiftTests/JNI/JNIClassTests.swift # Tests/JExtractSwiftTests/JNI/JNIEnumTests.swift # Tests/JExtractSwiftTests/JNI/JNIGenericTypeTests.swift # Tests/JExtractSwiftTests/JNI/JNIStructTests.swift
Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift
Show resolved
Hide resolved
| thisClass: jclass, | ||
| selfPointer: jlong, | ||
| selfTypePointer: jlong | ||
| ) -> jint { |
There was a problem hiding this comment.
We should be able to get away with implementing them as
@JavaImplementation("org.swift.swiftkit.core.JavaObjects")
struct SwiftObjects {
@JavaStaticMethod
func getRawDiscriminator(selfPointer: Long, selfTypePointer: Long) -> Int { ... }
}since SwiftJava depends on the SwiftJavaMacros... I'd like to avoid not-using our own tools in this project, this way it's a good feedback mechanism if something is off or missing, and we avoid the typical mistakes with the cdecls etc.
I forget the exact syntax so sorry if the snippet isn't exactly right above here :)
There was a problem hiding this comment.
I didn't realize that we can use SwiftJavaMacros here! This would be better.
| exclude: ["swift-java.config"], | ||
| swiftSettings: [ | ||
| .swiftLanguageMode(.v5), | ||
| .enableUpcomingFeature("ImplicitOpenExistentials"), |
| ... | ||
| return String(reflecting: selfPointer$.pointee).getJNIValue(in: environment) | ||
| public String toDebugString() { | ||
| return SwiftObjects.toDebugString(this.$memoryAddress(), this.$typeMetadataAddress()); |
There was a problem hiding this comment.
Overall I really like this shape, it's true as you say we take some performance hit here for the opening but perhaps it is worth it anyway.
Would you be able to do a quick benchmark before/after? We have benchmarks set up in the repo, should be quick to add and try.
Overall though I'm supportive of this change, it's a nice pattern we'll likely follow in many more places!
Motivation
As mentioned in the 'Others' section of PR #572, we currently have branching logic in the generator for common functions like
destroy, depending on whether the target type is generic or not.This branching is undesirable as it increases maintenance costs.
While PR #567 partially addressed this by introducing
.synthesizedFunction, I have found a better approach, I propose it and solve the problem.Solution
Instead of generating type-specific code, providing a single generic implementation within the
SwiftJavapackage for functions liketoStringanddestroy.Since
JNISwiftInstancealways including type metadata, I realized that we can utilize the technique proposed in this comment to call a generic implementation.Pros:
Cons:
open_existential_metatype).Regarding the downsides, I believe the overhead is negligible compared to the inherent cost of JNI calls.
Changes
Following this new direction, I have replaced the generated code for the following functions with generic implementations:
toStringtoDebugStringdestroygetDiscriminatorAdditionally, I have removed
.synthesizedFunctionas it is no longer needed.