Skip to content

Commit f9bff50

Browse files
committed
[Remote Mirrors] Support Extended Existential Type Metadata
Teach Remote Mirrors to read extended existential type metadata.
1 parent c0f2f99 commit f9bff50

File tree

7 files changed

+185
-34
lines changed

7 files changed

+185
-34
lines changed

include/swift/ABI/GenericContext.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,27 @@ using GenericRequirementDescriptor =
191191
extern const GenericParamDescriptor
192192
ImplicitGenericParamDescriptors[MaxNumImplicitGenericParamDescriptors];
193193

194+
inline const GenericParamDescriptor *
195+
externalTargetImplicitGenericParamDescriptors() {
196+
static const GenericParamDescriptor
197+
buffer[MaxNumImplicitGenericParamDescriptors] = {
198+
#define D GenericParamDescriptor::implicit()
199+
D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D,
200+
D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D,
201+
D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D
202+
#undef D
203+
};
204+
return buffer;
205+
}
206+
194207
template <class Runtime>
195-
const GenericParamDescriptor *targetImplicitGenericParamDescriptors();
208+
const GenericParamDescriptor *targetImplicitGenericParamDescriptors() {
209+
return externalTargetImplicitGenericParamDescriptors();
210+
}
211+
template <>
212+
inline const GenericParamDescriptor *targetImplicitGenericParamDescriptors<InProcess>() {
213+
return ImplicitGenericParamDescriptors;
214+
}
196215

197216
/// A runtime description of a generic signature.
198217
template<typename Runtime>

include/swift/Remote/MetadataReader.h

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,85 @@ class MetadataReader {
929929
TypeCache[MetadataAddress] = BuiltExist;
930930
return BuiltExist;
931931
}
932+
case MetadataKind::ExtendedExistential: {
933+
auto Exist = cast<TargetExtendedExistentialTypeMetadata<Runtime>>(Meta);
934+
935+
// Read the shape for this existential.
936+
StoredPointer shapeAddress = stripSignedPointer(Exist->Shape);
937+
ShapeRef Shape = readShape(shapeAddress);
938+
if (!Shape)
939+
return BuiltType();
940+
941+
const unsigned shapeArgumentCount
942+
= Shape->getGenSigArgumentLayoutSizeInWords();
943+
// Pull out the arguments to the generalization signature.
944+
assert(Shape->hasGeneralizationSignature());
945+
std::vector<BuiltType> builtArgs;
946+
for (unsigned i = 0; i < shapeArgumentCount; ++i) {
947+
auto remoteArg = Exist->getGeneralizationArguments()[i];
948+
auto builtArg = readTypeFromMetadata(remoteArg);
949+
if (!builtArg)
950+
return BuiltType();
951+
builtArgs.push_back(builtArg);
952+
}
953+
954+
// Pull out the existential type from the mangled type name.
955+
Demangler dem;
956+
auto mangledExistentialAddr =
957+
resolveRelativeField(Shape, Shape->ExistentialType);
958+
auto node = readMangledName(RemoteAddress(mangledExistentialAddr),
959+
MangledNameKind::Type, dem);
960+
if (!node)
961+
return BuiltType();
962+
963+
BuiltType builtProto = decodeMangledType(node).getType();
964+
if (!builtProto)
965+
return BuiltType();
966+
967+
// Build up a substitution map for the generalized signature.
968+
BuiltGenericSignature sig =
969+
decodeRuntimeGenericSignature(Shape,
970+
Shape->getGeneralizationSignature())
971+
.getType();
972+
if (!sig)
973+
return BuiltType();
974+
975+
BuiltSubstitutionMap subst =
976+
Builder.createSubstitutionMap(sig, builtArgs);
977+
if (subst.empty())
978+
return BuiltType();
979+
980+
builtProto = Builder.subst(builtProto, subst);
981+
if (!builtProto)
982+
return BuiltType();
983+
984+
// Read the type expression to build up any remaining layers of
985+
// existential metatype.
986+
if (Shape->Flags.hasTypeExpression()) {
987+
Demangler dem;
988+
989+
// Read the mangled name.
990+
auto mangledContextName = Shape->getTypeExpression();
991+
auto mangledNameAddress =
992+
resolveRelativeField(Shape, mangledContextName->name);
993+
auto node = readMangledName(RemoteAddress(mangledNameAddress),
994+
MangledNameKind::Type, dem);
995+
if (!node)
996+
return BuiltType();
997+
998+
while (node->getKind() == Demangle::Node::Kind::Type &&
999+
node->getNumChildren() &&
1000+
node->getChild(0)->getKind() == Demangle::Node::Kind::Metatype &&
1001+
node->getChild(0)->getNumChildren()) {
1002+
builtProto = Builder.createExistentialMetatypeType(builtProto);
1003+
node = node->getChild(0)->getChild(0);
1004+
}
1005+
}
1006+
1007+
TypeCache[MetadataAddress] = builtProto;
1008+
return builtProto;
1009+
}
1010+
9321011
case MetadataKind::Metatype: {
9331012
auto Metatype = cast<TargetMetatypeMetadata<Runtime>>(Meta);
9341013
auto Instance = readTypeFromMetadata(Metatype->InstanceType);
@@ -1044,7 +1123,7 @@ class MetadataReader {
10441123
break;
10451124
}
10461125
case GenericRequirementKind::Protocol: {
1047-
/// Resolver to turn a protocol reference into a protocol declaration.
1126+
/// Resolver to turn a protocol reference into an existential type.
10481127
struct ProtocolReferenceResolver {
10491128
using Result = BuiltType;
10501129

@@ -1895,6 +1974,8 @@ class MetadataReader {
18951974
}
18961975
case MetadataKind::ExistentialMetatype:
18971976
return _readMetadata<TargetExistentialMetatypeMetadata>(address);
1977+
case MetadataKind::ExtendedExistential:
1978+
return _readMetadata<TargetExtendedExistentialTypeMetadata>(address);
18981979
case MetadataKind::ForeignClass:
18991980
return _readMetadata<TargetForeignClassMetadata>(address);
19001981
case MetadataKind::Function: {

lib/RemoteAST/RemoteAST.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,6 @@ using namespace swift::remoteAST;
5151
using irgen::Alignment;
5252
using irgen::Size;
5353

54-
template <class Runtime>
55-
const GenericParamDescriptor *swift::targetImplicitGenericParamDescriptors() {
56-
static const GenericParamDescriptor
57-
buffer[MaxNumImplicitGenericParamDescriptors] = {
58-
#define D GenericParamDescriptor::implicit()
59-
D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D,
60-
D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D,
61-
D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D
62-
#undef D
63-
};
64-
return buffer;
65-
}
66-
6754
static inline RemoteAddress operator+(RemoteAddress address, Size offset) {
6855
return RemoteAddress(address.getAddressData() + offset.getValue());
6956
}

stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,6 @@ using Runtime = External<NoObjCInterop<RuntimeTarget<sizeof(uintptr_t)>>>;
4343
#endif
4444
using NativeReflectionContext = swift::reflection::ReflectionContext<Runtime>;
4545

46-
template <class Runtime>
47-
const GenericParamDescriptor *swift::targetImplicitGenericParamDescriptors() {
48-
static const GenericParamDescriptor
49-
buffer[MaxNumImplicitGenericParamDescriptors] = {
50-
#define D GenericParamDescriptor::implicit()
51-
D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D,
52-
D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D,
53-
D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D
54-
#undef D
55-
};
56-
return buffer;
57-
}
58-
5946
struct SwiftReflectionContext {
6047
NativeReflectionContext *nativeContext;
6148
std::vector<std::function<void()>> freeFuncs;

stdlib/public/runtime/Metadata.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,6 @@ swift::ImplicitGenericParamDescriptors[MaxNumImplicitGenericParamDescriptors] =
8686
};
8787
static_assert(MaxNumImplicitGenericParamDescriptors == 64, "length mismatch");
8888

89-
template <>
90-
const GenericParamDescriptor *
91-
swift::targetImplicitGenericParamDescriptors<InProcess>() {
92-
return ImplicitGenericParamDescriptors;
93-
}
94-
9589
static ClassMetadata *
9690
_swift_relocateClassMetadata(const ClassDescriptor *description,
9791
const ResilientClassMetadataPattern *pattern);

stdlib/public/runtime/ReflectionMirror.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,8 @@ const char *swift_OpaqueSummary(const Metadata *T) {
10761076
return "(Heap Generic Local Variable)";
10771077
case MetadataKind::ErrorObject:
10781078
return "(ErrorType Object)";
1079+
case MetadataKind::ExtendedExistential:
1080+
return "(Extended Existential)";
10791081
default:
10801082
return "(Unknown)";
10811083
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// RUN: %target-swift-remoteast-test -enable-parameterized-existential-types %s | %FileCheck %s
2+
3+
// REQUIRES: swift-remoteast-test
4+
5+
@_silgen_name("printDynamicTypeAndAddressForExistential")
6+
func printDynamicTypeAndAddressForExistential<T>(_: T)
7+
8+
@_silgen_name("stopRemoteAST")
9+
func stopRemoteAST()
10+
11+
protocol Paddock<Animal> {
12+
associatedtype Animal
13+
}
14+
15+
struct Chicken {}
16+
struct Coop: Paddock {
17+
typealias Animal = Chicken
18+
}
19+
20+
struct Pig {}
21+
struct Pen: Paddock {
22+
typealias Animal = Pig
23+
}
24+
25+
struct Field<Animal>: Paddock {}
26+
27+
protocol SharedYard<Animal1, Animal2, Animal3, Animal4> {
28+
associatedtype Animal1
29+
associatedtype Animal2
30+
associatedtype Animal3
31+
associatedtype Animal4
32+
}
33+
34+
class Lea: SharedYard {
35+
typealias Animal1 = Chicken
36+
typealias Animal2 = Pig
37+
typealias Animal3 = Chicken
38+
typealias Animal4 = Pig
39+
40+
init() {}
41+
}
42+
43+
let coop = Coop()
44+
// CHECK: Coop
45+
printDynamicTypeAndAddressForExistential(coop as any Paddock)
46+
47+
// CHECK-NEXT: Coop
48+
printDynamicTypeAndAddressForExistential(coop as any Paddock<Chicken>)
49+
50+
// CHECK-NEXT: Coop.Type
51+
printDynamicTypeAndAddressForExistential(Coop.self as (any Paddock<Chicken>.Type))
52+
53+
// CHECK-NEXT: Coop.Type.Type.Type.Type
54+
printDynamicTypeAndAddressForExistential(Coop.Type.Type.Type.self as (any Paddock<Chicken>.Type.Type.Type.Type))
55+
56+
let pen = Pen()
57+
// CHECK-NEXT: Pen
58+
printDynamicTypeAndAddressForExistential(pen as any Paddock)
59+
60+
// CHECK-NEXT: Pen
61+
printDynamicTypeAndAddressForExistential(pen as any Paddock<Pig>)
62+
63+
let lea = Lea()
64+
// CHECK-NEXT: Lea
65+
printDynamicTypeAndAddressForExistential(lea as any SharedYard)
66+
67+
// CHECK-NEXT: Lea
68+
printDynamicTypeAndAddressForExistential(lea as any SharedYard<Chicken, Pig, Chicken, Pig>)
69+
70+
71+
func freeRange<Animal>(_ x: Animal.Type) {
72+
printDynamicTypeAndAddressForExistential(Field<Animal>() as any Paddock<Animal>)
73+
}
74+
75+
// CHECK-NEXT: Field<Chicken>
76+
freeRange(Chicken.self)
77+
// CHECK-NEXT: Field<Pig>
78+
freeRange(Pig.self)
79+
80+
81+
stopRemoteAST()

0 commit comments

Comments
 (0)