|
20 | 20 | #include "swift/Subsystems.h"
|
21 | 21 | #include "swift/AST/ASTContext.h"
|
22 | 22 | #include "swift/AST/Decl.h"
|
| 23 | +#include "swift/AST/ExistentialLayout.h" |
23 | 24 | #include "swift/AST/GenericSignature.h"
|
24 | 25 | #include "swift/AST/Module.h"
|
25 | 26 | #include "swift/AST/NameLookup.h"
|
@@ -810,6 +811,9 @@ class RemoteASTContextImpl {
|
810 | 811 | getDeclForRemoteNominalTypeDescriptor(RemoteAddress descriptor) = 0;
|
811 | 812 | virtual Result<RemoteAddress>
|
812 | 813 | getHeapMetadataForObject(RemoteAddress object) = 0;
|
| 814 | + virtual Result<std::pair<Type, RemoteAddress>> |
| 815 | + getDynamicTypeAndAddressForExistential(RemoteAddress object, |
| 816 | + Type staticType) = 0; |
813 | 817 |
|
814 | 818 | Result<uint64_t>
|
815 | 819 | getOffsetOfMember(Type type, RemoteAddress optMetadata, StringRef memberName){
|
@@ -1162,6 +1166,85 @@ class RemoteASTContextConcreteImpl final : public RemoteASTContextImpl {
|
1162 | 1166 | if (result) return RemoteAddress(*result);
|
1163 | 1167 | return getFailure<RemoteAddress>();
|
1164 | 1168 | }
|
| 1169 | + |
| 1170 | + Result<std::pair<Type, RemoteAddress>> |
| 1171 | + getDynamicTypeAndAddressClassExistential(RemoteAddress object) { |
| 1172 | + auto pointed = Reader.readPointedValue(object.getAddressData()); |
| 1173 | + if (!pointed) |
| 1174 | + return getFailure<std::pair<Type, RemoteAddress>>(); |
| 1175 | + auto result = Reader.readMetadataFromInstance(*pointed); |
| 1176 | + if (!result) |
| 1177 | + return getFailure<std::pair<Type, RemoteAddress>>(); |
| 1178 | + auto typeResult = Reader.readTypeFromMetadata(result.getValue()); |
| 1179 | + if (!typeResult) |
| 1180 | + return getFailure<std::pair<Type, RemoteAddress>>(); |
| 1181 | + return std::make_pair<Type, RemoteAddress>(std::move(typeResult), |
| 1182 | + std::move(object)); |
| 1183 | + } |
| 1184 | + |
| 1185 | + Result<std::pair<Type, RemoteAddress>> |
| 1186 | + getDynamicTypeAndAddressErrorExistential(RemoteAddress object) { |
| 1187 | + auto pointed = Reader.readPointedValue(object.getAddressData()); |
| 1188 | + if (!pointed) |
| 1189 | + return getFailure<std::pair<Type, RemoteAddress>>(); |
| 1190 | + auto result = |
| 1191 | + Reader.readMetadataAndValueErrorExistential(RemoteAddress(*pointed)); |
| 1192 | + if (!result) |
| 1193 | + return getFailure<std::pair<Type, RemoteAddress>>(); |
| 1194 | + RemoteAddress metadataAddress = result->first; |
| 1195 | + RemoteAddress valueAddress = result->second; |
| 1196 | + |
| 1197 | + auto typeResult = |
| 1198 | + Reader.readTypeFromMetadata(metadataAddress.getAddressData()); |
| 1199 | + if (!typeResult) |
| 1200 | + return getFailure<std::pair<Type, RemoteAddress>>(); |
| 1201 | + return std::make_pair<Type, RemoteAddress>(std::move(typeResult), |
| 1202 | + std::move(valueAddress)); |
| 1203 | + } |
| 1204 | + |
| 1205 | + Result<std::pair<Type, RemoteAddress>> |
| 1206 | + getDynamicTypeAndAddressOpaqueExistential(RemoteAddress object) { |
| 1207 | + auto result = Reader.readMetadataAndValueOpaqueExistential(object); |
| 1208 | + if (!result) |
| 1209 | + return getFailure<std::pair<Type, RemoteAddress>>(); |
| 1210 | + RemoteAddress metadataAddress = result->first; |
| 1211 | + RemoteAddress valueAddress = result->second; |
| 1212 | + |
| 1213 | + auto typeResult = |
| 1214 | + Reader.readTypeFromMetadata(metadataAddress.getAddressData()); |
| 1215 | + if (!typeResult) |
| 1216 | + return getFailure<std::pair<Type, RemoteAddress>>(); |
| 1217 | + return std::make_pair<Type, RemoteAddress>(std::move(typeResult), |
| 1218 | + std::move(valueAddress)); |
| 1219 | + } |
| 1220 | + |
| 1221 | + /// Resolve the dynamic type and the value address of an existential, |
| 1222 | + /// given its address and its static type. For class and error existentials, |
| 1223 | + /// this API takes a pointer to the instance reference rather than the |
| 1224 | + /// instance reference itself. |
| 1225 | + Result<std::pair<Type, RemoteAddress>> |
| 1226 | + getDynamicTypeAndAddressForExistential(RemoteAddress object, |
| 1227 | + Type staticType) override { |
| 1228 | + // If this is not an existential, give up. |
| 1229 | + if (!staticType->isAnyExistentialType()) |
| 1230 | + return getFailure<std::pair<Type, RemoteAddress>>(); |
| 1231 | + |
| 1232 | + // TODO: implement support for ExistentialMetaTypes. |
| 1233 | + if (!staticType->isExistentialType()) |
| 1234 | + return getFailure<std::pair<Type, RemoteAddress>>(); |
| 1235 | + |
| 1236 | + // This should be an existential type at this point. |
| 1237 | + auto layout = staticType->getExistentialLayout(); |
| 1238 | + switch (layout.getKind()) { |
| 1239 | + case ExistentialLayout::Kind::Class: |
| 1240 | + return getDynamicTypeAndAddressClassExistential(object); |
| 1241 | + case ExistentialLayout::Kind::Error: |
| 1242 | + return getDynamicTypeAndAddressErrorExistential(object); |
| 1243 | + case ExistentialLayout::Kind::Opaque: |
| 1244 | + return getDynamicTypeAndAddressOpaqueExistential(object); |
| 1245 | + } |
| 1246 | + llvm_unreachable("invalid type kind"); |
| 1247 | + } |
1165 | 1248 | };
|
1166 | 1249 |
|
1167 | 1250 | } // end anonymous namespace
|
@@ -1219,3 +1302,10 @@ Result<remote::RemoteAddress>
|
1219 | 1302 | RemoteASTContext::getHeapMetadataForObject(remote::RemoteAddress address) {
|
1220 | 1303 | return asImpl(Impl)->getHeapMetadataForObject(address);
|
1221 | 1304 | }
|
| 1305 | + |
| 1306 | +Result<std::pair<Type, remote::RemoteAddress>> |
| 1307 | +RemoteASTContext::getDynamicTypeAndAddressForExistential( |
| 1308 | + remote::RemoteAddress address, Type staticType) { |
| 1309 | + return asImpl(Impl)->getDynamicTypeAndAddressForExistential(address, |
| 1310 | + staticType); |
| 1311 | +} |
0 commit comments