Skip to content

Commit 8402944

Browse files
committed
introduce tests for metadata size etc
Previously this was just in a hello world app.
1 parent 90977d6 commit 8402944

File tree

3 files changed

+97
-12
lines changed

3 files changed

+97
-12
lines changed

Samples/SwiftKitSampleApp/src/main/java/com/example/swift/HelloJava2Swift.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public static void main(String[] args) {
3434

3535
final var dylibNames = List.of(
3636
"swiftCore",
37-
"JavaKitExample"
37+
"ExampleSwiftLibrary"
3838
);
3939

4040

@@ -61,12 +61,5 @@ static void examples() {
6161

6262
obj.voidMethod();
6363
obj.takeIntMethod(42);
64-
65-
MemorySegment swiftType = SwiftKit.getTypeByMangledNameInEnvironment("SiSg");
66-
System.out.println("Memory layout for Swift.Int?:");
67-
System.out.println(" size = " + SwiftKit.sizeOfSwiftType(swiftType));
68-
System.out.println(" stride = " + SwiftKit.strideOfSwiftType(swiftType));
69-
System.out.println(" alignment = " + SwiftKit.alignmentOfSwiftType(swiftType));
70-
System.out.println(" Java layout = " + SwiftKit.layoutOfSwiftType(swiftType));
7164
}
7265
}

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

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ private static SymbolLookup getSymbolLookup() {
4848
.or(Linker.nativeLinker().defaultLookup());
4949
}
5050
}
51+
5152
public SwiftKit() {
5253
}
5354

@@ -313,6 +314,9 @@ public static MemorySegment valueWitnessTable(MemorySegment typeMetadata) {
313314

314315
/**
315316
* Determine the size of a Swift type given its type metadata.
317+
*
318+
* @param typeMetadata the memory segment must point to a Swift metadata,
319+
* e.g. the result of a {@link SwiftKit.swift_getTypeByMangledNameInEnvironment} call
316320
*/
317321
public static long sizeOfSwiftType(MemorySegment typeMetadata) {
318322
return getSwiftInt(valueWitnessTable(typeMetadata), SwiftValueWitnessTable.$size$offset);
@@ -321,14 +325,22 @@ public static long sizeOfSwiftType(MemorySegment typeMetadata) {
321325
/**
322326
* Determine the stride of a Swift type given its type metadata, which is
323327
* how many bytes are between successive elements of this type within an
324-
* array. It is >= the size.
328+
* array.
329+
*
330+
* It is >= the size.
331+
*
332+
* @param typeMetadata the memory segment must point to a Swift metadata,
333+
* e.g. the result of a {@link SwiftKit.swift_getTypeByMangledNameInEnvironment} call
325334
*/
326335
public static long strideOfSwiftType(MemorySegment typeMetadata) {
327336
return getSwiftInt(valueWitnessTable(typeMetadata), SwiftValueWitnessTable.$stride$offset);
328337
}
329338

330339
/**
331340
* Determine the alignment of the given Swift type.
341+
*
342+
* @param typeMetadata the memory segment must point to a Swift metadata,
343+
* e.g. the result of a {@link SwiftKit.swift_getTypeByMangledNameInEnvironment} call
332344
*/
333345
public static long alignmentOfSwiftType(MemorySegment typeMetadata) {
334346
long flags = getSwiftInt(valueWitnessTable(typeMetadata), SwiftValueWitnessTable.$flags$offset);
@@ -365,6 +377,9 @@ private static class swift_getTypeName {
365377
* <p>
366378
* If 'qualified' is true, leave all the qualification in place to
367379
* disambiguate the type, producing a more complete (but longer) type name.
380+
*
381+
* @param typeMetadata the memory segment must point to a Swift metadata,
382+
* e.g. the result of a {@link SwiftKit.swift_getTypeByMangledNameInEnvironment} call
368383
*/
369384
public static String nameOfSwiftType(MemorySegment typeMetadata, boolean qualified) {
370385
try {
@@ -388,14 +403,29 @@ public static String nameOfSwiftType(MemorySegment typeMetadata, boolean qualifi
388403
* <p>
389404
* In the future, this layout could be extended to provide more detail,
390405
* such as the fields of a Swift struct.
406+
*
407+
* @param typeMetadata the memory segment must point to a Swift metadata,
408+
* e.g. the result of a {@link SwiftKit.swift_getTypeByMangledNameInEnvironment} call
391409
*/
392410
public static MemoryLayout layoutOfSwiftType(MemorySegment typeMetadata) {
393411
long size = sizeOfSwiftType(typeMetadata);
394412
long stride = strideOfSwiftType(typeMetadata);
413+
long padding = stride - size;
414+
415+
// constructing a zero-length paddingLayout is illegal, so we avoid doing so
416+
MemoryLayout[] layouts = padding == 0 ?
417+
new MemoryLayout[]{
418+
MemoryLayout.sequenceLayout(size, JAVA_BYTE)
419+
.withByteAlignment(alignmentOfSwiftType(typeMetadata))
420+
} :
421+
new MemoryLayout[]{
422+
MemoryLayout.sequenceLayout(size, JAVA_BYTE)
423+
.withByteAlignment(alignmentOfSwiftType(typeMetadata)),
424+
MemoryLayout.paddingLayout(stride - size)
425+
};
426+
395427
return MemoryLayout.structLayout(
396-
MemoryLayout.sequenceLayout(size, JAVA_BYTE)
397-
.withByteAlignment(alignmentOfSwiftType(typeMetadata)),
398-
MemoryLayout.paddingLayout(stride - size)
428+
layouts
399429
).withName(nameOfSwiftType(typeMetadata, true));
400430
}
401431
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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 org.junit.jupiter.api.Assertions;
18+
import org.junit.jupiter.api.Test;
19+
20+
import java.lang.foreign.MemorySegment;
21+
22+
public class SwiftRuntimeMetadataTest {
23+
24+
@Test
25+
public void integer_layout_metadata() {
26+
MemorySegment swiftType = SwiftKit.getTypeByMangledNameInEnvironment("Si");
27+
28+
if (SwiftValueLayout.addressByteSize() == 4) {
29+
// 32-bit platform
30+
Assertions.assertEquals(8, SwiftKit.sizeOfSwiftType(swiftType));
31+
Assertions.assertEquals(8, SwiftKit.strideOfSwiftType(swiftType));
32+
Assertions.assertEquals(8, SwiftKit.alignmentOfSwiftType(swiftType));
33+
Assertions.assertEquals("[8%[9:b1]x7](Swift.Int)", SwiftKit.layoutOfSwiftType(swiftType).toString());
34+
} else {
35+
// 64-bit platform
36+
Assertions.assertEquals(8, SwiftKit.sizeOfSwiftType(swiftType));
37+
Assertions.assertEquals(8, SwiftKit.strideOfSwiftType(swiftType));
38+
Assertions.assertEquals(8, SwiftKit.alignmentOfSwiftType(swiftType));
39+
Assertions.assertEquals("[8%[8:b1]](Swift.Int)", SwiftKit.layoutOfSwiftType(swiftType).toString());
40+
}
41+
}
42+
43+
@Test
44+
public void optional_integer_layout_metadata() {
45+
MemorySegment swiftType = SwiftKit.getTypeByMangledNameInEnvironment("SiSg");
46+
47+
if (SwiftValueLayout.addressByteSize() == 4) {
48+
// 64-bit platform
49+
Assertions.assertEquals(9, SwiftKit.sizeOfSwiftType(swiftType));
50+
Assertions.assertEquals(16, SwiftKit.strideOfSwiftType(swiftType));
51+
Assertions.assertEquals(8, SwiftKit.alignmentOfSwiftType(swiftType));
52+
Assertions.assertEquals("[8%[9:b1]x7](Swift.Optional<Swift.Int>)", SwiftKit.layoutOfSwiftType(swiftType).toString());
53+
} else {
54+
// 64-bit platform
55+
Assertions.assertEquals(9, SwiftKit.sizeOfSwiftType(swiftType));
56+
Assertions.assertEquals(16, SwiftKit.strideOfSwiftType(swiftType));
57+
Assertions.assertEquals(8, SwiftKit.alignmentOfSwiftType(swiftType));
58+
Assertions.assertEquals("[8%[9:b1]x7](Swift.Optional<Swift.Int>)", SwiftKit.layoutOfSwiftType(swiftType).toString());
59+
}
60+
}
61+
62+
}

0 commit comments

Comments
 (0)