Skip to content

Commit 6c4f77a

Browse files
authored
Prefer VarHandle to raw offset APIs
A bit more idiomatic to use var handles rather than raw offsets.
1 parent b5c4a18 commit 6c4f77a

File tree

1 file changed

+31
-42
lines changed

1 file changed

+31
-42
lines changed

SwiftKit/src/main/java/org/swift/swiftkit/SwiftValueWitnessTable.java

+31-42
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import java.lang.foreign.*;
1818
import java.lang.invoke.MethodHandle;
19+
import java.lang.invoke.VarHandle;
1920

2021
import static java.lang.foreign.ValueLayout.JAVA_BYTE;
2122
import 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

Comments
 (0)