1616
1717import java .lang .foreign .*;
1818import java .lang .invoke .MethodHandle ;
19- import org .swift .swiftkit .util .StringUtils ;
2019
20+ import static java .lang .foreign .ValueLayout .ADDRESS ;
2121import static java .lang .foreign .ValueLayout .JAVA_BYTE ;
2222import static org .swift .swiftkit .SwiftKit .getSwiftInt ;
23+ import static org .swift .swiftkit .util .StringUtils .hexString ;
2324
2425public abstract class SwiftValueWitnessTable {
2526
@@ -162,7 +163,7 @@ public static MemoryLayout layoutOfSwiftType(MemorySegment typeMetadata) {
162163 $LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("flags" ));
163164
164165 /**
165- * {@snippet lang=C :
166+ * {@snippet lang = C :
166167 * ///void(*destroy)(T *object, witness_t *self);
167168 * ///
168169 * /// Given a valid object of this type, destroy it, leaving it as an
@@ -173,23 +174,24 @@ public static MemoryLayout layoutOfSwiftType(MemorySegment typeMetadata) {
173174 * Destroy,
174175 * VOID_TYPE,
175176 * (MUTABLE_VALUE_TYPE, TYPE_TYPE))
176- * }
177+ *}
177178 */
178179 private static class destroy {
179180
180181 static final long $offset =
181182 $LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("destroy" ));
182183
183184 static final FunctionDescriptor DESC = FunctionDescriptor .ofVoid (
184- SwiftValueLayout .SWIFT_POINTER
185+ ValueLayout .ADDRESS
186+ // SwiftValueLayout.SWIFT_POINTER // should be a "pointer to the self pointer"
185187// , // the object
186188// SwiftValueLayout.SWIFT_POINTER // the type
187189 );
188190
189191 /**
190192 * Function pointer for the destroy operation
191193 */
192- static MemorySegment addr (SwiftAnyType ty , MemorySegment memory ) {
194+ static MemorySegment addr (SwiftAnyType ty ) {
193195 // Get the value witness table of the type
194196 final var vwt = SwiftValueWitnessTable .valueWitnessTable (ty .$memorySegment ());
195197
@@ -198,8 +200,8 @@ static MemorySegment addr(SwiftAnyType ty, MemorySegment memory) {
198200 return MemorySegment .ofAddress (funcAddress );
199201 }
200202
201- static MethodHandle handle (SwiftAnyType ty , MemorySegment memory ) {
202- return Linker .nativeLinker ().downcallHandle (addr (ty , memory ), DESC );
203+ static MethodHandle handle (SwiftAnyType ty ) {
204+ return Linker .nativeLinker ().downcallHandle (addr (ty ), DESC );
203205 }
204206 }
205207
@@ -213,14 +215,32 @@ public static void destroy(SwiftAnyType type, MemorySegment object) {
213215 System .out .println ("Destroy object: " + object );
214216 System .out .println ("Destroy object type: " + type );
215217
216- var handle = destroy .handle (type , object );
218+ var handle = destroy .handle (type );
217219 System .out .println ("Destroy object handle: " + handle );
218220
219- try {
220- handle .invokeExact (object );
221- // handle.invokeExact(object, type.$memorySegment());
221+ try (var arena = Arena .ofConfined ()) {
222+ // we need to make a pointer to the self pointer when calling witness table functions:
223+ MemorySegment indirect = arena .allocate (SwiftValueLayout .SWIFT_POINTER );
224+
225+ // Write the address of as the value of the newly created pointer.
226+ // We need to type-safely set the pointer value which may be 64 or 32-bit.
227+ if (SwiftValueLayout .SWIFT_INT == ValueLayout .JAVA_LONG ) {
228+ indirect .set (ValueLayout .JAVA_LONG , /*offset=*/ 0 , object .address ());
229+ } else {
230+ indirect .set (ValueLayout .JAVA_INT , /*offset=*/ 0 , (int ) object .address ());
231+ }
232+
233+ System .out .println ("indirect = " + indirect );
234+ if (SwiftValueLayout .SWIFT_INT == ValueLayout .JAVA_LONG ) {
235+ System .out .println ("indirect.get(ValueLayout.JAVA_LONG, 0) = " + hexString (indirect .get (ValueLayout .JAVA_LONG , 0 )));
236+ } else {
237+ System .out .println ("indirect.get(ValueLayout.JAVA_INT, 0) = " + hexString (indirect .get (ValueLayout .JAVA_INT , 0 )));
238+ }
239+
240+ // handle.invokeExact(object); // NOTE: This does "nothing"
241+ handle .invokeExact (indirect );
222242 } catch (Throwable th ) {
223- throw new AssertionError ("Failed to destroy '" + type + "' at " + object , th );
243+ throw new AssertionError ("Failed to destroy '" + type + "' at " + object , th );
224244 }
225245 }
226246
0 commit comments