16
16
17
17
import java .lang .foreign .*;
18
18
import java .lang .invoke .MethodHandle ;
19
+ import java .lang .invoke .VarHandle ;
19
20
20
21
import static java .lang .foreign .ValueLayout .JAVA_BYTE ;
21
22
import static org .swift .swiftkit .SwiftKit .getSwiftInt ;
@@ -70,8 +71,7 @@ public static MemorySegment fullTypeMetadata(MemorySegment typeMetadata) {
70
71
*/
71
72
public static MemorySegment valueWitnessTable (MemorySegment typeMetadata ) {
72
73
return fullTypeMetadata (typeMetadata )
73
- .get (SwiftValueLayout .SWIFT_POINTER , SwiftValueWitnessTable .fullTypeMetadata$vwt$offset );
74
- // .get(ValueLayout.ADDRESS, SwiftValueWitnessTable.fullTypeMetadata$vwt$offset);
74
+ .get (SwiftValueLayout .SWIFT_POINTER , SwiftValueWitnessTable .fullTypeMetadata$vwt$offset );
75
75
}
76
76
77
77
@@ -81,22 +81,33 @@ public static MemorySegment valueWitnessTable(MemorySegment typeMetadata) {
81
81
static final long $size$offset =
82
82
$LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("size" ));
83
83
84
+ /**
85
+ * Variable handle for the "stride" field within the value witness table.
86
+ */
87
+ static final VarHandle $size$mh =
88
+ $LAYOUT .varHandle (MemoryLayout .PathElement .groupElement ("size" ));
89
+
84
90
/**
85
91
* Determine the size of a Swift type given its type metadata.
86
92
*
87
93
* @param typeMetadata the memory segment must point to a Swift metadata
88
94
*/
89
95
public static long sizeOfSwiftType (MemorySegment typeMetadata ) {
90
- return getSwiftInt (valueWitnessTable (typeMetadata ), SwiftValueWitnessTable . $size$offset );
96
+ return getSwiftInt (valueWitnessTable (typeMetadata ), $size$mh );
91
97
}
92
98
93
-
94
99
/**
95
100
* Offset for the "stride" field within the value witness table.
96
101
*/
97
102
static final long $stride$offset =
98
103
$LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("stride" ));
99
104
105
+ /**
106
+ * Variable handle for the "stride" field within the value witness table.
107
+ */
108
+ static final VarHandle $stride$mh =
109
+ $LAYOUT .varHandle (MemoryLayout .PathElement .groupElement ("size" ));
110
+
100
111
/**
101
112
* Determine the stride of a Swift type given its type metadata, which is
102
113
* how many bytes are between successive elements of this type within an
@@ -107,7 +118,7 @@ public static long sizeOfSwiftType(MemorySegment typeMetadata) {
107
118
* @param typeMetadata the memory segment must point to a Swift metadata
108
119
*/
109
120
public static long strideOfSwiftType (MemorySegment typeMetadata ) {
110
- return getSwiftInt (valueWitnessTable (typeMetadata ), SwiftValueWitnessTable . $stride$offset );
121
+ return getSwiftInt (valueWitnessTable (typeMetadata ), $stride$mh );
111
122
}
112
123
113
124
@@ -117,7 +128,7 @@ public static long strideOfSwiftType(MemorySegment typeMetadata) {
117
128
* @param typeMetadata the memory segment must point to a Swift metadata
118
129
*/
119
130
public static long alignmentOfSwiftType (MemorySegment typeMetadata ) {
120
- long flags = getSwiftInt (valueWitnessTable (typeMetadata ), SwiftValueWitnessTable . $flags$offset );
131
+ long flags = getSwiftInt (valueWitnessTable (typeMetadata ), $flags$offset );
121
132
return (flags & 0xFF ) + 1 ;
122
133
}
123
134
@@ -161,9 +172,12 @@ public static MemoryLayout layoutOfSwiftType(MemorySegment typeMetadata) {
161
172
static final long $flags$offset =
162
173
$LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("flags" ));
163
174
175
+ // ==== ------------------------------------------------------------------------------------------------------------
176
+ // destroy
177
+
164
178
/**
165
179
* {@snippet lang = C:
166
- * ///void(*destroy)(T *object, witness_t *self);
180
+ * /// void(*destroy)(T *object, witness_t *self);
167
181
* ///
168
182
* /// Given a valid object of this type, destroy it, leaving it as an
169
183
* /// invalid object. This is useful when generically destroying
@@ -202,7 +216,6 @@ static MethodHandle handle(SwiftAnyType ty) {
202
216
}
203
217
}
204
218
205
-
206
219
/**
207
220
* Destroy the value/object.
208
221
* <p>
@@ -225,6 +238,9 @@ public static void destroy(SwiftAnyType type, MemorySegment object) {
225
238
}
226
239
}
227
240
241
+ // ==== ------------------------------------------------------------------------------------------------------------
242
+ // initializeWithCopy
243
+
228
244
/**
229
245
* {@snippet lang = C:
230
246
* /// T *(*initializeWithCopy)(T *dest, T *src, M *self);
@@ -238,26 +254,23 @@ public static void destroy(SwiftAnyType type, MemorySegment object) {
238
254
*}
239
255
*/
240
256
private static class initializeWithCopy {
241
-
242
257
static final long $offset =
243
- $LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("initializeWithCopy " ));
258
+ $LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("destroy " ));
244
259
245
- static final FunctionDescriptor DESC = FunctionDescriptor .of (
246
- /* -> */ ValueLayout .ADDRESS , // returns the destination object
247
- ValueLayout .ADDRESS , // destination
248
- ValueLayout .ADDRESS , // source
260
+ static final FunctionDescriptor DESC = FunctionDescriptor .ofVoid (
261
+ ValueLayout .ADDRESS , // witness table functions expect a pointer to self pointer
249
262
ValueLayout .ADDRESS // pointer to the witness table
250
263
);
251
264
252
265
/**
253
- * Function pointer for the initializeWithCopy operation
266
+ * Function pointer for the destroy operation
254
267
*/
255
268
static MemorySegment addr (SwiftAnyType ty ) {
256
269
// Get the value witness table of the type
257
270
final var vwt = SwiftValueWitnessTable .valueWitnessTable (ty .$memorySegment ());
258
271
259
- // Get the address of the function stored at the offset of the witness table
260
- long funcAddress = getSwiftInt (vwt , initializeWithCopy .$offset );
272
+ // Get the address of the destroy function stored at the offset of the witness table
273
+ long funcAddress = getSwiftInt (vwt , destroy .$offset );
261
274
return MemorySegment .ofAddress (funcAddress );
262
275
}
263
276
@@ -266,31 +279,7 @@ static MethodHandle handle(SwiftAnyType ty) {
266
279
}
267
280
}
268
281
282
+ public static void initializeWithCopy (SwiftAnyType type , MemorySegment from , MemorySegment target ) {
269
283
270
- /**
271
- * Given an invalid object of this type, initialize it as a copy of
272
- * the source object.
273
- * <p/>
274
- * Returns the dest object.
275
- */
276
- public static MemorySegment initializeWithCopy (SwiftAnyType type , MemorySegment dest , MemorySegment src ) {
277
- var fullTypeMetadata = fullTypeMetadata (type .$memorySegment ());
278
- var wtable = valueWitnessTable (fullTypeMetadata );
279
-
280
- var mh = initializeWithCopy .handle (type );
281
-
282
- try (var arena = Arena .ofConfined ()) {
283
- // we need to make a pointer to the self pointer when calling witness table functions:
284
- MemorySegment indirectDest = arena .allocate (SwiftValueLayout .SWIFT_POINTER );
285
- MemorySegmentUtils .setSwiftPointerAddress (indirectDest , dest );
286
- MemorySegment indirectSrc = arena .allocate (SwiftValueLayout .SWIFT_POINTER );
287
- MemorySegmentUtils .setSwiftPointerAddress (indirectSrc , src );
288
-
289
- var returnedDest = (MemorySegment ) mh .invokeExact (indirectDest , indirectSrc , wtable );
290
- return returnedDest ;
291
- } catch (Throwable th ) {
292
- throw new AssertionError ("Failed to initializeWithCopy '" + type + "' (" + dest + ", " + src + ")" , th );
293
- }
294
284
}
295
-
296
285
}
0 commit comments