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