Skip to content

Commit 9c96f65

Browse files
authored
Revert "Prefer VarHandle to raw offset APIs" (#208)
This reverts commit 6c4f77a.
1 parent 6c4f77a commit 9c96f65

File tree

1 file changed

+42
-31
lines changed

1 file changed

+42
-31
lines changed

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

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

1717
import java.lang.foreign.*;
1818
import java.lang.invoke.MethodHandle;
19-
import java.lang.invoke.VarHandle;
2019

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

Comments
 (0)