Skip to content

[SwiftKit] Move 'selfPointer' to 'JNISwiftInstance' & downcall trace logs #322

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

Merged
merged 13 commits into from
Jul 17, 2025

Conversation

ktoso
Copy link
Collaborator

@ktoso ktoso commented Jul 16, 2025

Seems I could not push "to" the PR here #321

Minor refactor, we can easily keep the pointer in the base type

@ktoso ktoso requested a review from rintaro July 16, 2025 00:33
@ktoso ktoso changed the title Swiftkit selfpointer [SwiftKit] Move 'selfPointer' to 'JNISwiftInstance' Jul 16, 2025
@ktoso ktoso changed the title [SwiftKit] Move 'selfPointer' to 'JNISwiftInstance' [SwiftKit] Move 'selfPointer' to 'JNISwiftInstance' & downcall trace logs Jul 16, 2025
@ktoso ktoso marked this pull request as draft July 16, 2025 09:37
@ktoso ktoso force-pushed the swiftkit-selfpointer branch from 7c96b3b to e7612f0 Compare July 16, 2025 11:03
@ktoso ktoso force-pushed the swiftkit-selfpointer branch from 2d2318a to 49e95c6 Compare July 16, 2025 12:00

let returnKeyword = translatedDecl.translatedFunctionSignature.resultType.isVoid ? "" : "return "

printer.print(
"""
long selfPointer = this.pointer();
long \(selfVarName) = this.$memoryAddress();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are basically unsafe, so I figured we shoudl hide them using our $ pattern.

@@ -206,13 +206,15 @@ extension JNISwift2JavaGenerator {
printDeclDocumentation(&printer, decl)
printer.printBraceBlock("public \(renderFunctionSignature(decl))") { printer in
var arguments = translatedDecl.translatedFunctionSignature.parameters.map(\.name)
arguments.append("selfPointer")

let selfVarName = "self$"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason we're doing $ in names in bodies is so they don't clash with any parameter name that someone can come up with, so I moved to self$ here -- FYI @madsodgaard

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea!

CallTraces.traceDowncall("\(type.swiftNominal.name).\(funcName)",
"this", this,
"self", self$);
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a bit of downtracing helped diagnose issues

fatalError("Missing self pointer in call to \\(#function)!")
}
"""
)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code was repeated 2 times, so now it's in 1 place.

The reason to split it up into more lines and not just the single line with multiple ! is so we have better messages when things fail; It took me a while to diagnose an issue without this so I'd suggest to keep this in.


// TODO: make this a flagset integer and/or use a field updater
/** Used to track additional state of the underlying object, e.g. if it was explicitly destroyed. */
private final AtomicBoolean $state$destroyed = new AtomicBoolean(false);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fields should be before methods; we should install a formatting tool tbh

@@ -42,7 +55,7 @@ protected JNISwiftInstance(long pointer, SwiftArena arena) {
protected abstract Runnable $createDestroyFunction();

@Override
public SwiftInstanceCleanup createCleanupAction() {
public SwiftInstanceCleanup $createCleanup() {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also not a method end users should be invoking explicitly, so changed it while at it.

@@ -17,49 +17,38 @@
import java.util.concurrent.atomic.AtomicBoolean;

public abstract class SwiftInstance {
/// Pointer to the "self".
private final long selfPointer;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"The change" the SwiftInstance does not need storage, we can just have FFM or JNI one implement the abstract method instead

*/
protected SwiftInstance(long pointer, SwiftArena arena) {
this.selfPointer = pointer;
arena.register(this);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Necessary to remove this since otherwise we'd race the register with a non-initialized memory address value in the class calling super()

/**
* Utility functions, similar to @{link java.util.Objects}
*/
public class SwiftObjects {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following java.util.Objects but with more helpers for us ;)

@Override
public long $memoryAddress() {
return $memorySegment().address();
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:-)

Copy link
Contributor

@madsodgaard madsodgaard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice 👍

let selfBits$ = Int(Int64(fromJNI: \(selfPointerParam.name), in: env$))
assert(selfBits$ != 0, "$self memory address was null: \(selfPointerParam.name) = \\(\(selfPointerParam.name))" )
guard let \(newSelfParamName) = UnsafeMutablePointer<\(swiftParentName)>(bitPattern: selfBits$) else {
fatalError("Missing self pointer in call to \\(#function)!")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can move the above assert message to this fatalError instead. The UnsafeMutablePointer initializer will fail if the bitPattern is zero.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, done

@ktoso ktoso marked this pull request as ready for review July 17, 2025 03:30
@ktoso
Copy link
Collaborator Author

ktoso commented Jul 17, 2025

Continued spm instability on linux :(

#314

@ktoso ktoso merged commit c0f166d into swiftlang:main Jul 17, 2025
108 of 112 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants