1616
1717import java .lang .foreign .*;
1818import java .lang .invoke .MethodHandle ;
19+ import java .lang .invoke .VarHandle ;
1920
2021import static java .lang .foreign .ValueLayout .JAVA_BYTE ;
2122import static org .swift .swiftkit .SwiftKit .getSwiftInt ;
@@ -70,8 +71,7 @@ public static MemorySegment fullTypeMetadata(MemorySegment typeMetadata) {
7071 */
7172 public static MemorySegment valueWitnessTable (MemorySegment typeMetadata ) {
7273 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 );
7575 }
7676
7777
@@ -81,22 +81,33 @@ public static MemorySegment valueWitnessTable(MemorySegment typeMetadata) {
8181 static final long $size$offset =
8282 $LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("size" ));
8383
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+
8490 /**
8591 * Determine the size of a Swift type given its type metadata.
8692 *
8793 * @param typeMetadata the memory segment must point to a Swift metadata
8894 */
8995 public static long sizeOfSwiftType (MemorySegment typeMetadata ) {
90- return getSwiftInt (valueWitnessTable (typeMetadata ), SwiftValueWitnessTable . $size$offset );
96+ return getSwiftInt (valueWitnessTable (typeMetadata ), $size$mh );
9197 }
9298
93-
9499 /**
95100 * Offset for the "stride" field within the value witness table.
96101 */
97102 static final long $stride$offset =
98103 $LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("stride" ));
99104
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+
100111 /**
101112 * Determine the stride of a Swift type given its type metadata, which is
102113 * how many bytes are between successive elements of this type within an
@@ -107,7 +118,7 @@ public static long sizeOfSwiftType(MemorySegment typeMetadata) {
107118 * @param typeMetadata the memory segment must point to a Swift metadata
108119 */
109120 public static long strideOfSwiftType (MemorySegment typeMetadata ) {
110- return getSwiftInt (valueWitnessTable (typeMetadata ), SwiftValueWitnessTable . $stride$offset );
121+ return getSwiftInt (valueWitnessTable (typeMetadata ), $stride$mh );
111122 }
112123
113124
@@ -117,7 +128,7 @@ public static long strideOfSwiftType(MemorySegment typeMetadata) {
117128 * @param typeMetadata the memory segment must point to a Swift metadata
118129 */
119130 public static long alignmentOfSwiftType (MemorySegment typeMetadata ) {
120- long flags = getSwiftInt (valueWitnessTable (typeMetadata ), SwiftValueWitnessTable . $flags$offset );
131+ long flags = getSwiftInt (valueWitnessTable (typeMetadata ), $flags$offset );
121132 return (flags & 0xFF ) + 1 ;
122133 }
123134
@@ -161,9 +172,12 @@ public static MemoryLayout layoutOfSwiftType(MemorySegment typeMetadata) {
161172 static final long $flags$offset =
162173 $LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("flags" ));
163174
175+ // ==== ------------------------------------------------------------------------------------------------------------
176+ // destroy
177+
164178 /**
165179 * {@snippet lang = C:
166- * ///void(*destroy)(T *object, witness_t *self);
180+ * /// void(*destroy)(T *object, witness_t *self);
167181 * ///
168182 * /// Given a valid object of this type, destroy it, leaving it as an
169183 * /// invalid object. This is useful when generically destroying
@@ -202,7 +216,6 @@ static MethodHandle handle(SwiftAnyType ty) {
202216 }
203217 }
204218
205-
206219 /**
207220 * Destroy the value/object.
208221 * <p>
@@ -225,6 +238,9 @@ public static void destroy(SwiftAnyType type, MemorySegment object) {
225238 }
226239 }
227240
241+ // ==== ------------------------------------------------------------------------------------------------------------
242+ // initializeWithCopy
243+
228244 /**
229245 * {@snippet lang = C:
230246 * /// T *(*initializeWithCopy)(T *dest, T *src, M *self);
@@ -238,26 +254,23 @@ public static void destroy(SwiftAnyType type, MemorySegment object) {
238254 *}
239255 */
240256 private static class initializeWithCopy {
241-
242257 static final long $offset =
243- $LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("initializeWithCopy " ));
258+ $LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("destroy " ));
244259
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
249262 ValueLayout .ADDRESS // pointer to the witness table
250263 );
251264
252265 /**
253- * Function pointer for the initializeWithCopy operation
266+ * Function pointer for the destroy operation
254267 */
255268 static MemorySegment addr (SwiftAnyType ty ) {
256269 // Get the value witness table of the type
257270 final var vwt = SwiftValueWitnessTable .valueWitnessTable (ty .$memorySegment ());
258271
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 );
261274 return MemorySegment .ofAddress (funcAddress );
262275 }
263276
@@ -266,31 +279,7 @@ static MethodHandle handle(SwiftAnyType ty) {
266279 }
267280 }
268281
282+ public static void initializeWithCopy (SwiftAnyType type , MemorySegment from , MemorySegment target ) {
269283
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- }
294284 }
295-
296285}
0 commit comments