Skip to content

Commit 90977d6

Browse files
committed
wip
1 parent d1268d6 commit 90977d6

File tree

3 files changed

+136
-76
lines changed

3 files changed

+136
-76
lines changed

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

Lines changed: 12 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
package org.swift.swiftkit;
1616

1717
import java.lang.foreign.*;
18-
import java.lang.foreign.MemoryLayout.PathElement;
1918
import java.lang.invoke.MethodHandle;
2019
import java.util.Arrays;
2120
import java.util.stream.Collectors;
2221

2322
import static java.lang.foreign.ValueLayout.JAVA_BYTE;
23+
import static org.swift.swiftkit.SwiftValueWitnessTable.fullTypeMetadataLayout;
2424

2525
public class SwiftKit {
2626

@@ -34,9 +34,6 @@ public class SwiftKit {
3434
System.loadLibrary(STDLIB_DYLIB_NAME);
3535
}
3636

37-
public static final AddressLayout SWIFT_POINTER = ValueLayout.ADDRESS
38-
.withTargetLayout(MemoryLayout.sequenceLayout(java.lang.Long.MAX_VALUE, JAVA_BYTE));
39-
4037
static final SymbolLookup SYMBOL_LOOKUP = getSymbolLookup();
4138

4239
private static SymbolLookup getSymbolLookup() {
@@ -251,7 +248,7 @@ public static MemorySegment getTypeByName(String string) {
251248
*/
252249
private static class swift_getTypeByMangledNameInEnvironment {
253250
public static final FunctionDescriptor DESC = FunctionDescriptor.of(
254-
/*returns=*/SWIFT_POINTER,
251+
/*returns=*/SwiftValueLayout.SWIFT_POINTER,
255252
ValueLayout.ADDRESS,
256253
ValueLayout.JAVA_INT,
257254
ValueLayout.ADDRESS,
@@ -282,88 +279,26 @@ public static MemorySegment getTypeByMangledNameInEnvironment(String string) {
282279
}
283280
}
284281

285-
/**
286-
* The value layout for Swift's Int type, which is a signed type that follows
287-
* the size of a pointer (aka C's ptrdiff_t).
288-
*/
289-
public static ValueLayout SWIFT_INT = (ValueLayout.ADDRESS.byteSize() == 4) ?
290-
ValueLayout.JAVA_INT : ValueLayout.JAVA_LONG;
291-
292-
/**
293-
* The value layout for Swift's UInt type, which is an unsigned type that follows
294-
* the size of a pointer (aka C's size_t). Java does not have unsigned integer
295-
* types in general, so we use the layout for Swift's Int.
296-
*/
297-
public static ValueLayout SWIFT_UINT = SWIFT_INT;
298-
299282
/**
300283
* Read a Swift.Int value from memory at the given offset and translate it into a Java long.
301284
* <p>
302285
* This function copes with the fact that a Swift.Int might be 32 or 64 bits.
303286
*/
304287
public static final long getSwiftInt(MemorySegment memorySegment, long offset) {
305-
if (SWIFT_INT == ValueLayout.JAVA_LONG) {
288+
if (SwiftValueLayout.SWIFT_INT == ValueLayout.JAVA_LONG) {
306289
return memorySegment.get(ValueLayout.JAVA_LONG, offset);
307290
} else {
308291
return memorySegment.get(ValueLayout.JAVA_INT, offset);
309292
}
310293
}
311294

312-
/**
313-
* Value witness table layout.
314-
*/
315-
public static final MemoryLayout valueWitnessTableLayout = MemoryLayout.structLayout(
316-
ValueLayout.ADDRESS.withName("initializeBufferWithCopyOfBuffer"),
317-
ValueLayout.ADDRESS.withName("destroy"),
318-
ValueLayout.ADDRESS.withName("initializeWithCopy"),
319-
ValueLayout.ADDRESS.withName("assignWithCopy"),
320-
ValueLayout.ADDRESS.withName("initializeWithTake"),
321-
ValueLayout.ADDRESS.withName("assignWithTake"),
322-
ValueLayout.ADDRESS.withName("getEnumTagSinglePayload"),
323-
ValueLayout.ADDRESS.withName("storeEnumTagSinglePayload"),
324-
SwiftKit.SWIFT_INT.withName("size"),
325-
SwiftKit.SWIFT_INT.withName("stride"),
326-
SwiftKit.SWIFT_UINT.withName("flags"),
327-
SwiftKit.SWIFT_UINT.withName("extraInhabitantCount")
328-
).withName("SwiftValueWitnessTable");
329-
330-
/**
331-
* Offset for the "size" field within the value witness table.
332-
*/
333-
static final long valueWitnessTable$size$offset =
334-
valueWitnessTableLayout.byteOffset(PathElement.groupElement("size"));
335-
336-
/**
337-
* Offset for the "stride" field within the value witness table.
338-
*/
339-
static final long valueWitnessTable$stride$offset =
340-
valueWitnessTableLayout.byteOffset(PathElement.groupElement("stride"));
341-
342-
/**
343-
* Offset for the "flags" field within the value witness table.
344-
*/
345-
static final long valueWitnessTable$flags$offset =
346-
valueWitnessTableLayout.byteOffset(PathElement.groupElement("flags"));
347-
348-
/**
349-
* Type metadata pointer.
350-
*/
351-
public static final StructLayout fullTypeMetadataLayout = MemoryLayout.structLayout(
352-
SWIFT_POINTER.withName("vwt")
353-
).withName("SwiftFullTypeMetadata");
354-
355-
/**
356-
* Offset for the "vwt" field within the full type metadata.
357-
*/
358-
static final long fullTypeMetadata$vwt$offset =
359-
fullTypeMetadataLayout.byteOffset(PathElement.groupElement("vwt"));
360295

361296
/**
362297
* Given the address of Swift type metadata for a type, return the addres
363298
* of the "full" type metadata that can be accessed via fullTypeMetadataLayout.
364299
*/
365300
public static MemorySegment fullTypeMetadata(MemorySegment typeMetadata) {
366-
return MemorySegment.ofAddress(typeMetadata.address() - SWIFT_POINTER.byteSize())
301+
return MemorySegment.ofAddress(typeMetadata.address() - SwiftValueLayout.SWIFT_POINTER.byteSize())
367302
.reinterpret(fullTypeMetadataLayout.byteSize());
368303
}
369304

@@ -372,14 +307,15 @@ public static MemorySegment fullTypeMetadata(MemorySegment typeMetadata) {
372307
* references the value witness table for the type.
373308
*/
374309
public static MemorySegment valueWitnessTable(MemorySegment typeMetadata) {
375-
return fullTypeMetadata(typeMetadata).get(SWIFT_POINTER, fullTypeMetadata$vwt$offset);
310+
return fullTypeMetadata(typeMetadata)
311+
.get(SwiftValueLayout.SWIFT_POINTER, SwiftValueWitnessTable.fullTypeMetadata$vwt$offset);
376312
}
377313

378314
/**
379315
* Determine the size of a Swift type given its type metadata.
380316
*/
381317
public static long sizeOfSwiftType(MemorySegment typeMetadata) {
382-
return getSwiftInt(valueWitnessTable(typeMetadata), valueWitnessTable$size$offset);
318+
return getSwiftInt(valueWitnessTable(typeMetadata), SwiftValueWitnessTable.$size$offset);
383319
}
384320

385321
/**
@@ -388,14 +324,14 @@ public static long sizeOfSwiftType(MemorySegment typeMetadata) {
388324
* array. It is >= the size.
389325
*/
390326
public static long strideOfSwiftType(MemorySegment typeMetadata) {
391-
return getSwiftInt(valueWitnessTable(typeMetadata), valueWitnessTable$stride$offset);
327+
return getSwiftInt(valueWitnessTable(typeMetadata), SwiftValueWitnessTable.$stride$offset);
392328
}
393329

394330
/**
395331
* Determine the alignment of the given Swift type.
396332
*/
397333
public static long alignmentOfSwiftType(MemorySegment typeMetadata) {
398-
long flags = getSwiftInt(valueWitnessTable(typeMetadata), valueWitnessTable$flags$offset);
334+
long flags = getSwiftInt(valueWitnessTable(typeMetadata), SwiftValueWitnessTable.$flags$offset);
399335
return (flags & 0xFF) + 1;
400336
}
401337

@@ -406,8 +342,8 @@ private static class swift_getTypeName {
406342
*/
407343
public static final FunctionDescriptor DESC = FunctionDescriptor.of(
408344
/*returns=*/MemoryLayout.structLayout(
409-
SWIFT_POINTER.withName("utf8Chars"),
410-
SWIFT_INT.withName("length")
345+
SwiftValueLayout.SWIFT_POINTER.withName("utf8Chars"),
346+
SwiftValueLayout.SWIFT_INT.withName("length")
411347
),
412348
ValueLayout.ADDRESS,
413349
ValueLayout.JAVA_BOOLEAN
@@ -434,7 +370,7 @@ public static String nameOfSwiftType(MemorySegment typeMetadata, boolean qualifi
434370
try {
435371
try (Arena arena = Arena.ofConfined()) {
436372
MemorySegment charsAndLength = (MemorySegment) swift_getTypeName.HANDLE.invokeExact((SegmentAllocator) arena, typeMetadata, qualified);
437-
MemorySegment utf8Chars = charsAndLength.get(SWIFT_POINTER, 0);
373+
MemorySegment utf8Chars = charsAndLength.get(SwiftValueLayout.SWIFT_POINTER, 0);
438374
String typeName = utf8Chars.getString(0);
439375
cFree(utf8Chars);
440376
return typeName;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
package org.swift.swiftkit;
16+
17+
import java.lang.foreign.AddressLayout;
18+
import java.lang.foreign.MemoryLayout;
19+
import java.lang.foreign.StructLayout;
20+
import java.lang.foreign.ValueLayout;
21+
22+
import static java.lang.foreign.ValueLayout.JAVA_BYTE;
23+
24+
/**
25+
* Similar to {@link java.lang.foreign.ValueLayout} however with some Swift specifics.
26+
*/
27+
public class SwiftValueLayout {
28+
public static final AddressLayout SWIFT_POINTER = ValueLayout.ADDRESS
29+
.withTargetLayout(MemoryLayout.sequenceLayout(Long.MAX_VALUE, JAVA_BYTE));
30+
/**
31+
* The value layout for Swift's {@code Int} type, which is a signed type that follows
32+
* the size of a pointer (aka C's {@code ptrdiff_t}).
33+
*/
34+
public static ValueLayout SWIFT_INT = (ValueLayout.ADDRESS.byteSize() == 4) ?
35+
ValueLayout.JAVA_INT : ValueLayout.JAVA_LONG;
36+
37+
/**
38+
* The value layout for Swift's {@code UInt} type, which is an unsigned type that follows
39+
* the size of a pointer (aka C's {@code size_t}).
40+
* <p/>
41+
* Java does not have unsigned integer types, so we use the layout for Swift's {@code Int}.
42+
*/
43+
public static ValueLayout SWIFT_UINT = SWIFT_INT;
44+
45+
46+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
package org.swift.swiftkit;
16+
17+
import java.lang.foreign.MemoryLayout;
18+
import java.lang.foreign.MemorySegment;
19+
import java.lang.foreign.StructLayout;
20+
import java.lang.foreign.ValueLayout;
21+
22+
public abstract class SwiftValueWitnessTable {
23+
/**
24+
* Value witness table layout.
25+
*/
26+
public static final MemoryLayout $LAYOUT = MemoryLayout.structLayout(
27+
ValueLayout.ADDRESS.withName("initializeBufferWithCopyOfBuffer"),
28+
ValueLayout.ADDRESS.withName("destroy"),
29+
ValueLayout.ADDRESS.withName("initializeWithCopy"),
30+
ValueLayout.ADDRESS.withName("assignWithCopy"),
31+
ValueLayout.ADDRESS.withName("initializeWithTake"),
32+
ValueLayout.ADDRESS.withName("assignWithTake"),
33+
ValueLayout.ADDRESS.withName("getEnumTagSinglePayload"),
34+
ValueLayout.ADDRESS.withName("storeEnumTagSinglePayload"),
35+
SwiftValueLayout.SWIFT_INT.withName("size"),
36+
SwiftValueLayout.SWIFT_INT.withName("stride"),
37+
SwiftValueLayout.SWIFT_UINT.withName("flags"),
38+
SwiftValueLayout.SWIFT_UINT.withName("extraInhabitantCount")
39+
).withName("SwiftValueWitnessTable");
40+
41+
42+
/**
43+
* Offset for the "size" field within the value witness table.
44+
*/
45+
static final long $size$offset =
46+
$LAYOUT.byteOffset(MemoryLayout.PathElement.groupElement("size"));
47+
48+
/**
49+
* Offset for the "stride" field within the value witness table.
50+
*/
51+
static final long $stride$offset =
52+
$LAYOUT.byteOffset(MemoryLayout.PathElement.groupElement("stride"));
53+
54+
/**
55+
* Offset for the "flags" field within the value witness table.
56+
*/
57+
static final long $flags$offset =
58+
$LAYOUT.byteOffset(MemoryLayout.PathElement.groupElement("flags"));
59+
60+
/**
61+
* Type metadata pointer.
62+
*/
63+
static final StructLayout fullTypeMetadataLayout = MemoryLayout.structLayout(
64+
SwiftValueLayout.SWIFT_POINTER.withName("vwt")
65+
).withName("SwiftFullTypeMetadata");
66+
67+
/**
68+
* Offset for the "vwt" field within the full type metadata.
69+
*/
70+
static final long fullTypeMetadata$vwt$offset =
71+
fullTypeMetadataLayout.byteOffset(MemoryLayout.PathElement.groupElement("vwt"));
72+
73+
private static class destroy {
74+
static final long $offset =
75+
$LAYOUT.byteOffset(MemoryLayout.PathElement.groupElement("destroy"));
76+
}
77+
78+
}

0 commit comments

Comments
 (0)