1616
1717import java .lang .foreign .*;
1818import java .lang .invoke .MethodHandle ;
19- import java .lang .invoke .VarHandle ;
2019
2120import static java .lang .foreign .ValueLayout .JAVA_BYTE ;
2221import static org .swift .swiftkit .SwiftKit .getSwiftInt ;
@@ -71,7 +70,8 @@ public static MemorySegment fullTypeMetadata(MemorySegment typeMetadata) {
7170 */
7271 public static MemorySegment valueWitnessTable (MemorySegment typeMetadata ) {
7372 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);
7575 }
7676
7777
@@ -81,33 +81,22 @@ 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-
9084 /**
9185 * Determine the size of a Swift type given its type metadata.
9286 *
9387 * @param typeMetadata the memory segment must point to a Swift metadata
9488 */
9589 public static long sizeOfSwiftType (MemorySegment typeMetadata ) {
96- return getSwiftInt (valueWitnessTable (typeMetadata ), $size$mh );
90+ return getSwiftInt (valueWitnessTable (typeMetadata ), SwiftValueWitnessTable . $size$offset );
9791 }
9892
93+
9994 /**
10095 * Offset for the "stride" field within the value witness table.
10196 */
10297 static final long $stride$offset =
10398 $LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("stride" ));
10499
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-
111100 /**
112101 * Determine the stride of a Swift type given its type metadata, which is
113102 * how many bytes are between successive elements of this type within an
@@ -118,7 +107,7 @@ public static long sizeOfSwiftType(MemorySegment typeMetadata) {
118107 * @param typeMetadata the memory segment must point to a Swift metadata
119108 */
120109 public static long strideOfSwiftType (MemorySegment typeMetadata ) {
121- return getSwiftInt (valueWitnessTable (typeMetadata ), $stride$mh );
110+ return getSwiftInt (valueWitnessTable (typeMetadata ), SwiftValueWitnessTable . $stride$offset );
122111 }
123112
124113
@@ -128,7 +117,7 @@ public static long strideOfSwiftType(MemorySegment typeMetadata) {
128117 * @param typeMetadata the memory segment must point to a Swift metadata
129118 */
130119 public static long alignmentOfSwiftType (MemorySegment typeMetadata ) {
131- long flags = getSwiftInt (valueWitnessTable (typeMetadata ), $flags$offset );
120+ long flags = getSwiftInt (valueWitnessTable (typeMetadata ), SwiftValueWitnessTable . $flags$offset );
132121 return (flags & 0xFF ) + 1 ;
133122 }
134123
@@ -172,12 +161,9 @@ public static MemoryLayout layoutOfSwiftType(MemorySegment typeMetadata) {
172161 static final long $flags$offset =
173162 $LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("flags" ));
174163
175- // ==== ------------------------------------------------------------------------------------------------------------
176- // destroy
177-
178164 /**
179165 * {@snippet lang = C:
180- * /// void(*destroy)(T *object, witness_t *self);
166+ * ///void(*destroy)(T *object, witness_t *self);
181167 * ///
182168 * /// Given a valid object of this type, destroy it, leaving it as an
183169 * /// invalid object. This is useful when generically destroying
@@ -216,6 +202,7 @@ static MethodHandle handle(SwiftAnyType ty) {
216202 }
217203 }
218204
205+
219206 /**
220207 * Destroy the value/object.
221208 * <p>
@@ -238,9 +225,6 @@ public static void destroy(SwiftAnyType type, MemorySegment object) {
238225 }
239226 }
240227
241- // ==== ------------------------------------------------------------------------------------------------------------
242- // initializeWithCopy
243-
244228 /**
245229 * {@snippet lang = C:
246230 * /// T *(*initializeWithCopy)(T *dest, T *src, M *self);
@@ -254,23 +238,26 @@ public static void destroy(SwiftAnyType type, MemorySegment object) {
254238 *}
255239 */
256240 private static class initializeWithCopy {
241+
257242 static final long $offset =
258- $LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("destroy " ));
243+ $LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("initializeWithCopy " ));
259244
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
262249 ValueLayout .ADDRESS // pointer to the witness table
263250 );
264251
265252 /**
266- * Function pointer for the destroy operation
253+ * Function pointer for the initializeWithCopy operation
267254 */
268255 static MemorySegment addr (SwiftAnyType ty ) {
269256 // Get the value witness table of the type
270257 final var vwt = SwiftValueWitnessTable .valueWitnessTable (ty .$memorySegment ());
271258
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 );
274261 return MemorySegment .ofAddress (funcAddress );
275262 }
276263
@@ -279,7 +266,31 @@ static MethodHandle handle(SwiftAnyType ty) {
279266 }
280267 }
281268
282- public static void initializeWithCopy (SwiftAnyType type , MemorySegment from , MemorySegment target ) {
283269
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+ }
284294 }
295+
285296}
0 commit comments