16
16
17
17
import java .lang .foreign .*;
18
18
import java .lang .invoke .MethodHandle ;
19
- import org .swift .swiftkit .util .StringUtils ;
20
19
20
+ import static java .lang .foreign .ValueLayout .ADDRESS ;
21
21
import static java .lang .foreign .ValueLayout .JAVA_BYTE ;
22
22
import static org .swift .swiftkit .SwiftKit .getSwiftInt ;
23
+ import static org .swift .swiftkit .util .StringUtils .hexString ;
23
24
24
25
public abstract class SwiftValueWitnessTable {
25
26
@@ -162,7 +163,7 @@ public static MemoryLayout layoutOfSwiftType(MemorySegment typeMetadata) {
162
163
$LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("flags" ));
163
164
164
165
/**
165
- * {@snippet lang=C :
166
+ * {@snippet lang = C :
166
167
* ///void(*destroy)(T *object, witness_t *self);
167
168
* ///
168
169
* /// Given a valid object of this type, destroy it, leaving it as an
@@ -173,23 +174,24 @@ public static MemoryLayout layoutOfSwiftType(MemorySegment typeMetadata) {
173
174
* Destroy,
174
175
* VOID_TYPE,
175
176
* (MUTABLE_VALUE_TYPE, TYPE_TYPE))
176
- * }
177
+ *}
177
178
*/
178
179
private static class destroy {
179
180
180
181
static final long $offset =
181
182
$LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("destroy" ));
182
183
183
184
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"
185
187
// , // the object
186
188
// SwiftValueLayout.SWIFT_POINTER // the type
187
189
);
188
190
189
191
/**
190
192
* Function pointer for the destroy operation
191
193
*/
192
- static MemorySegment addr (SwiftAnyType ty , MemorySegment memory ) {
194
+ static MemorySegment addr (SwiftAnyType ty ) {
193
195
// Get the value witness table of the type
194
196
final var vwt = SwiftValueWitnessTable .valueWitnessTable (ty .$memorySegment ());
195
197
@@ -198,8 +200,8 @@ static MemorySegment addr(SwiftAnyType ty, MemorySegment memory) {
198
200
return MemorySegment .ofAddress (funcAddress );
199
201
}
200
202
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 );
203
205
}
204
206
}
205
207
@@ -213,14 +215,32 @@ public static void destroy(SwiftAnyType type, MemorySegment object) {
213
215
System .out .println ("Destroy object: " + object );
214
216
System .out .println ("Destroy object type: " + type );
215
217
216
- var handle = destroy .handle (type , object );
218
+ var handle = destroy .handle (type );
217
219
System .out .println ("Destroy object handle: " + handle );
218
220
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 );
222
242
} 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 );
224
244
}
225
245
}
226
246
0 commit comments