Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 23fac72

Browse files
authored
Merge pull request #88933 from mikeash/remote-mirror-inline-array
[Reflection] Support inspection of InlineArray.
2 parents 1e1fa73 + 2bcfe0b commit 23fac72

7 files changed

Lines changed: 185 additions & 7 deletions

File tree

include/swift/Remote/MetadataReader.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,23 @@ class MetadataReader {
12431243
TypeCache[TypeCacheKey] = BuiltForeign;
12441244
return BuiltForeign;
12451245
}
1246+
case MetadataKind::FixedArray: {
1247+
auto fixedArray = cast<TargetFixedArrayTypeMetadata<Runtime>>(Meta);
1248+
auto elementAddress = RemoteAddress(
1249+
fixedArray->Element, MetadataAddress.getAddressSpace());
1250+
auto Element =
1251+
readTypeFromMetadata(elementAddress, false, recursion_limit);
1252+
if (!Element) return BuiltType();
1253+
1254+
auto count = static_cast<intptr_t>(fixedArray->Count);
1255+
BuiltType Size = (count < 0) ? Builder.createNegativeIntegerType(count)
1256+
: Builder.createIntegerType(count);
1257+
if (!Size) return BuiltType();
1258+
1259+
auto BuiltFixedArray = Builder.createBuiltinFixedArrayType(Size, Element);
1260+
TypeCache[TypeCacheKey] = BuiltFixedArray;
1261+
return BuiltFixedArray;
1262+
}
12461263
case MetadataKind::HeapLocalVariable:
12471264
case MetadataKind::HeapGenericLocalVariable:
12481265
case MetadataKind::ErrorObject:

include/swift/RemoteInspection/TypeLowering.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,17 +383,22 @@ class ReferenceTypeInfo : public TypeInfo {
383383

384384
/// Array based layouts like Builtin.FixedArray<N, T>
385385
class ArrayTypeInfo : public TypeInfo {
386+
const TypeRef *ElementTR;
386387
const TypeInfo *ElementTI;
388+
intptr_t ElementCount;
387389

388390
public:
389-
explicit ArrayTypeInfo(intptr_t size, const TypeInfo *elementTI);
391+
explicit ArrayTypeInfo(intptr_t size, const TypeRef *elementTR,
392+
const TypeInfo *elementTI);
390393

391394
bool readExtraInhabitantIndex(remote::MemoryReader &reader,
392395
remote::RemoteAddress address,
393396
int *extraInhabitantIndex) const override;
394397

395398
BitMask getSpareBits(TypeConverter &TC, bool &hasAddrOnly) const override;
399+
const TypeRef *getElementTypeRef() const { return ElementTR; }
396400
const TypeInfo *getElementTypeInfo() const { return ElementTI; }
401+
intptr_t getElementCount() const { return ElementCount; }
397402
static bool classof(const TypeInfo *TI) {
398403
return TI->getKind() == TypeInfoKind::Array;
399404
}

include/swift/SwiftRemoteMirror/SwiftRemoteMirrorTypes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ typedef enum swift_layout_kind {
145145
SWIFT_CLOSURE_CONTEXT,
146146

147147
// A contiguous list of N Ts, typically for Builtin.FixedArray<N, T>.
148+
// NumFields will report the array count. All children are the same type, so
149+
// users can make a single call to swift_reflection_childOfTypeRef regardless
150+
// of the count.
148151
SWIFT_ARRAY,
149152
} swift_layout_kind_t;
150153

stdlib/public/RemoteInspection/TypeLowering.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,9 @@ class PrintTypeInfo {
222222
case TypeInfoKind::Array: {
223223
printHeader("array");
224224
printBasic(TI);
225+
auto &ArrayTI = cast<ArrayTypeInfo>(TI);
226+
printField("count", std::to_string(ArrayTI.getElementCount()));
227+
printRec(*ArrayTI.getElementTypeInfo());
225228
stream << ")";
226229
return;
227230
}
@@ -493,15 +496,16 @@ BitMask RecordTypeInfo::getSpareBits(TypeConverter &TC, bool &hasAddrOnly) const
493496
return mask;
494497
}
495498

496-
ArrayTypeInfo::ArrayTypeInfo(intptr_t size, const TypeInfo *elementTI)
499+
ArrayTypeInfo::ArrayTypeInfo(intptr_t size, const TypeRef *elementTR,
500+
const TypeInfo *elementTI)
497501
: TypeInfo(TypeInfoKind::Array,
498502
/* size */ elementTI->getStride() * size,
499503
/* alignment */ elementTI->getAlignment(),
500504
/* stride */ elementTI->getStride() * size,
501505
/* numExtraInhabitants */ elementTI->getNumExtraInhabitants(),
502506
/* borrowability */ elementTI->getBorrowability(),
503507
/* FixedArray is always afd */ true),
504-
ElementTI(elementTI) {}
508+
ElementTR(elementTR), ElementTI(elementTI), ElementCount(size) {}
505509

506510
bool ArrayTypeInfo::readExtraInhabitantIndex(
507511
remote::MemoryReader &reader, remote::RemoteAddress address,
@@ -2771,7 +2775,8 @@ class LowerType
27712775
return nullptr;
27722776
}
27732777

2774-
return TC.makeTypeInfo<ArrayTypeInfo>(sizeInt->getValue(), elementTI);
2778+
return TC.makeTypeInfo<ArrayTypeInfo>(sizeInt->getValue(),
2779+
BA->getElementType(), elementTI);
27752780
}
27762781

27772782
const TypeInfo *visitBuiltinBorrowTypeRef(const BuiltinBorrowTypeRef *BA) {

stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,8 @@ static swift_typeinfo_t convertTypeInfo(const TypeInfo *TI) {
586586
NumFields = RecordTI->getNumCases();
587587
} else if (auto *RecordTI = dyn_cast<RecordTypeInfo>(TI)) {
588588
NumFields = RecordTI->getNumFields();
589+
} else if (auto *ArrayTI = dyn_cast<ArrayTypeInfo>(TI)) {
590+
NumFields = ArrayTI->getElementCount();
589591
}
590592

591593
return {
@@ -601,13 +603,23 @@ static swift_childinfo_t convertChild(const TypeInfo *TI, unsigned Index) {
601603
if (!TI)
602604
return {};
603605

606+
if (auto *ArrayTI = dyn_cast<ArrayTypeInfo>(TI)) {
607+
auto *ElementTI = ArrayTI->getElementTypeInfo();
608+
return {
609+
"element",
610+
Index * ElementTI->getStride(),
611+
getTypeInfoKind(*ElementTI),
612+
reinterpret_cast<swift_typeref_t>(ArrayTI->getElementTypeRef()),
613+
};
614+
}
615+
604616
const FieldInfo *FieldInfo = nullptr;
605617
if (auto *EnumTI = dyn_cast<EnumTypeInfo>(TI)) {
606618
FieldInfo = &(EnumTI->getCases()[Index]);
607619
} else if (auto *RecordTI = dyn_cast<RecordTypeInfo>(TI)) {
608620
FieldInfo = &(RecordTI->getFields()[Index]);
609621
} else {
610-
assert(false && "convertChild(TI): TI must be record or enum typeinfo");
622+
assert(false && "convertChild(TI): TI must be record, enum, or array typeinfo");
611623
return {
612624
"unknown TypeInfo kind",
613625
0,

test/Reflection/typeref_lowering.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,12 +1277,18 @@ $1_SiBV
12771277
// CHECK-64: (builtin_fixed_array
12781278
// CHECK-64-NEXT: (integer value=2)
12791279
// CHECK-64-NEXT: (struct Swift.Int))
1280-
// CHECK-64-NEXT: (array size=16 alignment=8 stride=16 num_extra_inhabitants=0 bitwise_takable=1)
1280+
// CHECK-64-NEXT: (array size=16 alignment=8 stride=16 num_extra_inhabitants=0 bitwise_takable=1 count=2
1281+
// CHECK-64-NEXT: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
1282+
// CHECK-64-NEXT: (field name=_value offset=0
1283+
// CHECK-64-NEXT: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
12811284

12821285
// CHECK-32: (builtin_fixed_array
12831286
// CHECK-32-NEXT: (integer value=2)
12841287
// CHECK-32-NEXT: (struct Swift.Int))
1285-
// CHECK-32-NEXT: (array size=8 alignment=4 stride=8 num_extra_inhabitants=0 bitwise_takable=1)
1288+
// CHECK-32-NEXT: (array size=8 alignment=4 stride=8 num_extra_inhabitants=0 bitwise_takable=1 count=2
1289+
// CHECK-32-NEXT: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
1290+
// CHECK-32-NEXT: (field name=_value offset=0
1291+
// CHECK-32-NEXT: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
12861292

12871293
SiBW
12881294
// CHECK-64: (builtin_borrow
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift -lswiftSwiftReflectionTest %s -o %t/reflect_InlineArray -Xfrontend -disable-availability-checking
3+
// RUN: %target-codesign %t/reflect_InlineArray
4+
5+
// RUN: %target-run %target-swift-reflection-test %t/reflect_InlineArray | %FileCheck %s --check-prefix=CHECK-%target-ptrsize
6+
7+
// REQUIRES: reflection_test_support
8+
// REQUIRES: executable_test
9+
// UNSUPPORTED: use_os_stdlib
10+
// UNSUPPORTED: back_deployment_runtime
11+
// UNSUPPORTED: asan
12+
13+
import SwiftReflectionTest
14+
15+
class TestClass {
16+
var t: InlineArray<42, Int>
17+
var u: InlineArray<42, Int>
18+
var v: InlineArray<42, Int>
19+
var bytes: InlineArray<7, UInt8>
20+
var nested: InlineArray<3, InlineArray<5, Int16>>
21+
init(t: InlineArray<42, Int>) {
22+
self.t = t
23+
self.u = t
24+
self.v = t
25+
self.bytes = .init(repeating: 0)
26+
self.nested = .init(repeating: .init(repeating: 0))
27+
}
28+
}
29+
30+
var obj = TestClass(t: .init(repeating: 42))
31+
32+
reflect(object: obj)
33+
34+
// CHECK-64: Reflecting an object.
35+
// CHECK-64: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
36+
// CHECK-64: Type reference:
37+
// CHECK-64: (class reflect_InlineArray.TestClass)
38+
39+
// CHECK-64: Type info:
40+
// CHECK-64: (class_instance size={{[0-9]+}} alignment=8 stride={{[0-9]+}} num_extra_inhabitants=0 bitwise_takable=1
41+
// CHECK-64: (field name=t offset={{[0-9]+}}
42+
// CHECK-64: (struct size=336 alignment=8 stride=336 num_extra_inhabitants=0 bitwise_takable=1
43+
// CHECK-64: (field name=_storage offset=0
44+
// CHECK-64: (array size=336 alignment=8 stride=336 num_extra_inhabitants=0 bitwise_takable=1 count=42
45+
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
46+
// CHECK-64: (field name=_value offset=0
47+
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))))
48+
// CHECK-64: (field name=u offset={{[0-9]+}}
49+
// CHECK-64: (struct size=336 alignment=8 stride=336 num_extra_inhabitants=0 bitwise_takable=1
50+
// CHECK-64: (field name=_storage offset=0
51+
// CHECK-64: (array size=336 alignment=8 stride=336 num_extra_inhabitants=0 bitwise_takable=1 count=42
52+
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
53+
// CHECK-64: (field name=_value offset=0
54+
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))))
55+
// CHECK-64: (field name=v offset={{[0-9]+}}
56+
// CHECK-64: (struct size=336 alignment=8 stride=336 num_extra_inhabitants=0 bitwise_takable=1
57+
// CHECK-64: (field name=_storage offset=0
58+
// CHECK-64: (array size=336 alignment=8 stride=336 num_extra_inhabitants=0 bitwise_takable=1 count=42
59+
// CHECK-64: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
60+
// CHECK-64: (field name=_value offset=0
61+
// CHECK-64: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))))
62+
// CHECK-64: (field name=bytes offset={{[0-9]+}}
63+
// CHECK-64: (struct size=7 alignment=1 stride=7 num_extra_inhabitants=0 bitwise_takable=1
64+
// CHECK-64: (field name=_storage offset=0
65+
// CHECK-64: (array size=7 alignment=1 stride=7 num_extra_inhabitants=0 bitwise_takable=1 count=7
66+
// CHECK-64: (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
67+
// CHECK-64: (field name=_value offset=0
68+
// CHECK-64: (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1)))))))
69+
// CHECK-64: (field name=nested offset={{[0-9]+}}
70+
// CHECK-64: (struct size=30 alignment=2 stride=30 num_extra_inhabitants=0 bitwise_takable=1
71+
// CHECK-64: (field name=_storage offset=0
72+
// CHECK-64: (array size=30 alignment=2 stride=30 num_extra_inhabitants=0 bitwise_takable=1 count=3
73+
// CHECK-64: (struct size=10 alignment=2 stride=10 num_extra_inhabitants=0 bitwise_takable=1
74+
// CHECK-64: (field name=_storage offset=0
75+
// CHECK-64: (array size=10 alignment=2 stride=10 num_extra_inhabitants=0 bitwise_takable=1 count=5
76+
// CHECK-64: (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
77+
// CHECK-64: (field name=_value offset=0
78+
// CHECK-64: (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1)))))))))))
79+
80+
// CHECK-32: Reflecting an object.
81+
// CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
82+
// CHECK-32: Type reference:
83+
// CHECK-32: (class reflect_InlineArray.TestClass)
84+
85+
// CHECK-32: Type info:
86+
// CHECK-32: (class_instance size={{[0-9]+}} alignment={{[0-9]+}} stride={{[0-9]+}} num_extra_inhabitants={{[0-9]+}} bitwise_takable=1
87+
// CHECK-32: (field name=t offset={{[0-9]+}}
88+
// CHECK-32: (struct size=168 alignment=4 stride=168 num_extra_inhabitants=0 bitwise_takable=1
89+
// CHECK-32: (field name=_storage offset=0
90+
// CHECK-32: (array size=168 alignment=4 stride=168 num_extra_inhabitants=0 bitwise_takable=1 count=42
91+
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
92+
// CHECK-32: (field name=_value offset=0
93+
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))))
94+
// CHECK-32: (field name=u offset={{[0-9]+}}
95+
// CHECK-32: (struct size=168 alignment=4 stride=168 num_extra_inhabitants=0 bitwise_takable=1
96+
// CHECK-32: (field name=_storage offset=0
97+
// CHECK-32: (array size=168 alignment=4 stride=168 num_extra_inhabitants=0 bitwise_takable=1 count=42
98+
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
99+
// CHECK-32: (field name=_value offset=0
100+
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))))
101+
// CHECK-32: (field name=v offset={{[0-9]+}}
102+
// CHECK-32: (struct size=168 alignment=4 stride=168 num_extra_inhabitants=0 bitwise_takable=1
103+
// CHECK-32: (field name=_storage offset=0
104+
// CHECK-32: (array size=168 alignment=4 stride=168 num_extra_inhabitants=0 bitwise_takable=1 count=42
105+
// CHECK-32: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
106+
// CHECK-32: (field name=_value offset=0
107+
// CHECK-32: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))))
108+
// CHECK-32: (field name=bytes offset={{[0-9]+}}
109+
// CHECK-32: (struct size=7 alignment=1 stride=7 num_extra_inhabitants=0 bitwise_takable=1
110+
// CHECK-32: (field name=_storage offset=0
111+
// CHECK-32: (array size=7 alignment=1 stride=7 num_extra_inhabitants=0 bitwise_takable=1 count=7
112+
// CHECK-32: (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
113+
// CHECK-32: (field name=_value offset=0
114+
// CHECK-32: (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1)))))))
115+
// CHECK-32: (field name=nested offset={{[0-9]+}}
116+
// CHECK-32: (struct size=30 alignment=2 stride=30 num_extra_inhabitants=0 bitwise_takable=1
117+
// CHECK-32: (field name=_storage offset=0
118+
// CHECK-32: (array size=30 alignment=2 stride=30 num_extra_inhabitants=0 bitwise_takable=1 count=3
119+
// CHECK-32: (struct size=10 alignment=2 stride=10 num_extra_inhabitants=0 bitwise_takable=1
120+
// CHECK-32: (field name=_storage offset=0
121+
// CHECK-32: (array size=10 alignment=2 stride=10 num_extra_inhabitants=0 bitwise_takable=1 count=5
122+
// CHECK-32: (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
123+
// CHECK-32: (field name=_value offset=0
124+
// CHECK-32: (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1)))))))))))
125+
126+
doneReflecting()
127+
128+
// CHECK-64: Done.
129+
130+
// CHECK-32: Done.

0 commit comments

Comments
 (0)