Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -383,8 +383,6 @@ extension JNISwift2JavaGenerator {
"""
)
printer.println()

printDestroyFunction(&printer, decl)
}
}

Expand Down Expand Up @@ -876,58 +874,6 @@ extension JNISwift2JavaGenerator {
}
}

/// Prints the destroy function for a `JNISwiftInstance`
private func printDestroyFunction(_ printer: inout CodePrinter, _ type: ImportedNominalType) {
let funcName = "$createDestroyFunction"
let isEffectivelyGeneric = type.swiftNominal.isGeneric && !type.isSpecialization
let typeName = type.effectiveJavaSimpleName
printer.print("@Override")
printer.printBraceBlock("public Runnable \(funcName)()") { printer in
printer.print("long self$ = this.$memoryAddress();")
printer.print("long selfType$ = this.$typeMetadataAddress();")
if isEffectivelyGeneric {
printer.print(
"""
if (CallTraces.TRACE_DOWNCALLS) {
CallTraces.traceDowncall("\(typeName).\(funcName)",
"this", this,
"self", self$,
"selfType", selfType$);
}
return new Runnable() {
@Override
public void run() {
if (CallTraces.TRACE_DOWNCALLS) {
CallTraces.traceDowncall("\(typeName).$destroy", "self", self$, "selfType", selfType$);
}
SwiftObjects.destroy(self$, selfType$);
}
};
"""
)
} else {
printer.print(
"""
if (CallTraces.TRACE_DOWNCALLS) {
CallTraces.traceDowncall("\(typeName).\(funcName)",
"this", this,
"self", self$);
}
return new Runnable() {
@Override
public void run() {
if (CallTraces.TRACE_DOWNCALLS) {
CallTraces.traceDowncall("\(typeName).$destroy", "self", self$);
}
SwiftObjects.destroy(self$, selfType$);
}
};
"""
)
}
}
}

private func printFoundationDateHelpers(_ printer: inout CodePrinter, _ decl: ImportedNominalType) {
printer.print(
"""
Expand Down
9 changes: 9 additions & 0 deletions Sources/SwiftJava/SwiftObjects.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,13 @@ extension SwiftObjects {
}
return perform(as: typeMetadata)
}

@JavaMethod
public static func typeDescription(environment: UnsafeMutablePointer<JNIEnv?>!, selfTypePointer: Int64) -> String {
guard let selfType$ = UnsafeRawPointer(bitPattern: Int(selfTypePointer)) else {
fatalError("selfType metadata address was null")
}
let typeMetadata = unsafeBitCast(selfType$, to: Any.Type.self)
return String(describing: typeMetadata)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,38 @@ public interface JNISwiftInstance extends SwiftInstance {
*
* @return a function that is called when the value should be destroyed.
*/
Runnable $createDestroyFunction();
default Runnable $createDestroyFunction() {
var memoryAddress = $memoryAddress();
var typeMetadataAddress = $typeMetadataAddress();
if (CallTraces.TRACE_DOWNCALLS) {
CallTraces.trace(
"this", this,
"self", memoryAddress,
"selfType", SwiftObjects.typeDescription(typeMetadataAddress)
);
}
return () -> {
if (CallTraces.TRACE_DOWNCALLS) {
CallTraces.traceDowncall(
"SwiftObjects.destroy",
"self", memoryAddress,
"selfType", SwiftObjects.typeDescription(typeMetadataAddress)
);
}
SwiftObjects.destroy(memoryAddress, typeMetadataAddress);
};
}

/**
* The Swift type metadata address of this type.
*/
long $typeMetadataAddress();

@Override
default SwiftInstanceCleanup $createCleanup() {
var statusDestroyedFlag = $statusDestroyedFlag();
Runnable markAsDestroyed = () -> statusDestroyedFlag.set(true);

return new JNISwiftInstanceCleanup(this.$createDestroyFunction(), markAsDestroyed);
return new JNISwiftInstanceCleanup(
$createDestroyFunction(),
$statusDestroyedFlag()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,23 @@

package org.swift.swiftkit.core;

import java.util.concurrent.atomic.AtomicBoolean;

class JNISwiftInstanceCleanup implements SwiftInstanceCleanup {
private final Runnable destroyFunction;
private final Runnable markAsDestroyed;
private final AtomicBoolean statusDestroyedFlag;

public JNISwiftInstanceCleanup(Runnable destroyFunction, Runnable markAsDestroyed) {
public JNISwiftInstanceCleanup(Runnable destroyFunction, AtomicBoolean statusDestroyedFlag) {
this.destroyFunction = destroyFunction;
this.markAsDestroyed = markAsDestroyed;
this.statusDestroyedFlag = statusDestroyedFlag;
}

@Override
public void run() {
markAsDestroyed.run();
destroyFunction.run();
if (statusDestroyedFlag.compareAndSet(false, true)) {
destroyFunction.run();
} else {
throw new IllegalStateException("Double destruction attempt detected!");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ public static void requireNonZero(long number, String name) {
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);
public static native String typeDescription(long selfTypePointer);
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,10 @@ protected FFMSwiftErrorInstance(MemorySegment segment, AllocatingSwiftArena aren

@Override
public SwiftInstanceCleanup $createCleanup() {
var statusDestroyedFlag = $statusDestroyedFlag();
Runnable markAsDestroyed = () -> statusDestroyedFlag.set(true);

return new FFMSwiftInstanceCleanup(
$memorySegment(),
$swiftType(),
markAsDestroyed
$statusDestroyedFlag()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,10 @@ protected FFMSwiftInstance(MemorySegment segment, AllocatingSwiftArena arena) {

@Override
public SwiftInstanceCleanup $createCleanup() {
var statusDestroyedFlag = $statusDestroyedFlag();
Runnable markAsDestroyed = () -> statusDestroyedFlag.set(true);

return new FFMSwiftInstanceCleanup(
$memorySegment(),
$swiftType(),
markAsDestroyed
$statusDestroyedFlag()
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,29 @@
import static org.swift.swiftkit.ffm.SwiftJavaLogGroup.LIFECYCLE;

import java.lang.foreign.MemorySegment;
import java.util.concurrent.atomic.AtomicBoolean;

public class FFMSwiftInstanceCleanup implements SwiftInstanceCleanup {
private final MemorySegment memoryAddress;
private final SwiftAnyType type;
private final Runnable markAsDestroyed;
private final AtomicBoolean statusDestroyedFlag;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We could move to atomic field updater here, but I'm happy to do this separately


public FFMSwiftInstanceCleanup(MemorySegment memoryAddress, SwiftAnyType type, Runnable markAsDestroyed) {
public FFMSwiftInstanceCleanup(MemorySegment memoryAddress, SwiftAnyType type, AtomicBoolean statusDestroyedFlag) {
this.memoryAddress = memoryAddress;
this.type = type;
this.markAsDestroyed = markAsDestroyed;
this.statusDestroyedFlag = statusDestroyedFlag;
}

@Override
public void run() {
markAsDestroyed.run();

// Allow null pointers just for AutoArena tests.
if (type != null && memoryAddress != null) {
SwiftRuntime.log(LIFECYCLE, "Destroy swift value [" + type.getSwiftName() + "]: " + memoryAddress);
SwiftValueWitnessTable.destroy(type, memoryAddress);
if (statusDestroyedFlag.compareAndSet(false, true)) {
// Allow null pointers just for AutoArena tests.
if (type != null && memoryAddress != null) {
SwiftRuntime.log(LIFECYCLE, "Destroy swift value [" + type.getSwiftName() + "]: " + memoryAddress);
SwiftValueWitnessTable.destroy(type, memoryAddress);
}
} else {
throw new IllegalStateException("Double destruction attempt detected!");
}
}
}
27 changes: 0 additions & 27 deletions Tests/JExtractSwiftTests/JNI/JNIClassTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -97,33 +97,6 @@ struct JNIClassTests {
""",
]
)
try assertOutput(
input: source,
.jni,
.java,
expectedChunks: [
"""
@Override
public Runnable $createDestroyFunction() {
long self$ = this.$memoryAddress();
long selfType$ = this.$typeMetadataAddress();
if (CallTraces.TRACE_DOWNCALLS) {
CallTraces.traceDowncall("MyClass.$createDestroyFunction",
"this", this,
"self", self$);
}
return new Runnable() {
@Override
public void run() {
if (CallTraces.TRACE_DOWNCALLS) {
CallTraces.traceDowncall("MyClass.$destroy", "self", self$);
}
SwiftObjects.destroy(self$, selfType$);
}
};
"""
]
)
}

@Test
Expand Down
21 changes: 0 additions & 21 deletions Tests/JExtractSwiftTests/JNI/JNIEnumTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,27 +83,6 @@ struct JNIEnumTests {
return new MyEnum(selfPointer, swiftArena);
}
""",
"""
@Override
public Runnable $createDestroyFunction() {
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$);
}
};
}
""",
]
)
}
Expand Down
22 changes: 0 additions & 22 deletions Tests/JExtractSwiftTests/JNI/JNIGenericTypeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,28 +76,6 @@ struct JNIGenericTypeTests {
return this.selfTypePointer;
}
""",
"""
@Override
public Runnable $createDestroyFunction() {
long self$ = this.$memoryAddress();
long selfType$ = this.$typeMetadataAddress();
if (CallTraces.TRACE_DOWNCALLS) {
CallTraces.traceDowncall("MyID.$createDestroyFunction",
"this", this,
"self", self$,
"selfType", selfType$);
}
return new Runnable() {
@Override
public void run() {
if (CallTraces.TRACE_DOWNCALLS) {
CallTraces.traceDowncall("MyID.$destroy", "self", self$, "selfType", selfType$);
}
SwiftObjects.destroy(self$, selfType$);
}
};
}
""",
]
)
}
Expand Down
28 changes: 0 additions & 28 deletions Tests/JExtractSwiftTests/JNI/JNIStructTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,34 +83,6 @@ struct JNIStructTests {
""",
]
)
try assertOutput(
input: source,
.jni,
.java,
expectedChunks: [
"""
@Override
public Runnable $createDestroyFunction() {
long self$ = this.$memoryAddress();
long selfType$ = this.$typeMetadataAddress();
if (CallTraces.TRACE_DOWNCALLS) {
CallTraces.traceDowncall("MyStruct.$createDestroyFunction",
"this", this,
"self", self$);
}
return new Runnable() {
@Override
public void run() {
if (CallTraces.TRACE_DOWNCALLS) {
CallTraces.traceDowncall("MyStruct.$destroy", "self", self$);
}
SwiftObjects.destroy(self$, selfType$);
}
};
}
"""
]
)
}

@Test
Expand Down
Loading