mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #17571 from dcci/existentialremoteast
[RemoteAST] Initial support for projecting the type out of an existen…
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include "swift/Subsystems.h"
|
||||
#include "swift/AST/ASTContext.h"
|
||||
#include "swift/AST/Decl.h"
|
||||
#include "swift/AST/ExistentialLayout.h"
|
||||
#include "swift/AST/GenericSignature.h"
|
||||
#include "swift/AST/Module.h"
|
||||
#include "swift/AST/NameLookup.h"
|
||||
@@ -808,6 +809,9 @@ public:
|
||||
getDeclForRemoteNominalTypeDescriptor(RemoteAddress descriptor) = 0;
|
||||
virtual Result<RemoteAddress>
|
||||
getHeapMetadataForObject(RemoteAddress object) = 0;
|
||||
virtual Result<std::pair<Type, RemoteAddress>>
|
||||
getDynamicTypeAndAddressForExistential(RemoteAddress object,
|
||||
Type staticType) = 0;
|
||||
|
||||
Result<uint64_t>
|
||||
getOffsetOfMember(Type type, RemoteAddress optMetadata, StringRef memberName){
|
||||
@@ -1160,6 +1164,85 @@ public:
|
||||
if (result) return RemoteAddress(*result);
|
||||
return getFailure<RemoteAddress>();
|
||||
}
|
||||
|
||||
Result<std::pair<Type, RemoteAddress>>
|
||||
getDynamicTypeAndAddressClassExistential(RemoteAddress object) {
|
||||
auto pointed = Reader.readPointedValue(object.getAddressData());
|
||||
if (!pointed)
|
||||
return getFailure<std::pair<Type, RemoteAddress>>();
|
||||
auto result = Reader.readMetadataFromInstance(*pointed);
|
||||
if (!result)
|
||||
return getFailure<std::pair<Type, RemoteAddress>>();
|
||||
auto typeResult = Reader.readTypeFromMetadata(result.getValue());
|
||||
if (!typeResult)
|
||||
return getFailure<std::pair<Type, RemoteAddress>>();
|
||||
return std::make_pair<Type, RemoteAddress>(std::move(typeResult),
|
||||
std::move(object));
|
||||
}
|
||||
|
||||
Result<std::pair<Type, RemoteAddress>>
|
||||
getDynamicTypeAndAddressErrorExistential(RemoteAddress object) {
|
||||
auto pointed = Reader.readPointedValue(object.getAddressData());
|
||||
if (!pointed)
|
||||
return getFailure<std::pair<Type, RemoteAddress>>();
|
||||
auto result =
|
||||
Reader.readMetadataAndValueErrorExistential(RemoteAddress(*pointed));
|
||||
if (!result)
|
||||
return getFailure<std::pair<Type, RemoteAddress>>();
|
||||
RemoteAddress metadataAddress = result->first;
|
||||
RemoteAddress valueAddress = result->second;
|
||||
|
||||
auto typeResult =
|
||||
Reader.readTypeFromMetadata(metadataAddress.getAddressData());
|
||||
if (!typeResult)
|
||||
return getFailure<std::pair<Type, RemoteAddress>>();
|
||||
return std::make_pair<Type, RemoteAddress>(std::move(typeResult),
|
||||
std::move(valueAddress));
|
||||
}
|
||||
|
||||
Result<std::pair<Type, RemoteAddress>>
|
||||
getDynamicTypeAndAddressOpaqueExistential(RemoteAddress object) {
|
||||
auto result = Reader.readMetadataAndValueOpaqueExistential(object);
|
||||
if (!result)
|
||||
return getFailure<std::pair<Type, RemoteAddress>>();
|
||||
RemoteAddress metadataAddress = result->first;
|
||||
RemoteAddress valueAddress = result->second;
|
||||
|
||||
auto typeResult =
|
||||
Reader.readTypeFromMetadata(metadataAddress.getAddressData());
|
||||
if (!typeResult)
|
||||
return getFailure<std::pair<Type, RemoteAddress>>();
|
||||
return std::make_pair<Type, RemoteAddress>(std::move(typeResult),
|
||||
std::move(valueAddress));
|
||||
}
|
||||
|
||||
/// Resolve the dynamic type and the value address of an existential,
|
||||
/// given its address and its static type. For class and error existentials,
|
||||
/// this API takes a pointer to the instance reference rather than the
|
||||
/// instance reference itself.
|
||||
Result<std::pair<Type, RemoteAddress>>
|
||||
getDynamicTypeAndAddressForExistential(RemoteAddress object,
|
||||
Type staticType) override {
|
||||
// If this is not an existential, give up.
|
||||
if (!staticType->isAnyExistentialType())
|
||||
return getFailure<std::pair<Type, RemoteAddress>>();
|
||||
|
||||
// TODO: implement support for ExistentialMetaTypes.
|
||||
if (!staticType->isExistentialType())
|
||||
return getFailure<std::pair<Type, RemoteAddress>>();
|
||||
|
||||
// This should be an existential type at this point.
|
||||
auto layout = staticType->getExistentialLayout();
|
||||
switch (layout.getKind()) {
|
||||
case ExistentialLayout::Kind::Class:
|
||||
return getDynamicTypeAndAddressClassExistential(object);
|
||||
case ExistentialLayout::Kind::Error:
|
||||
return getDynamicTypeAndAddressErrorExistential(object);
|
||||
case ExistentialLayout::Kind::Opaque:
|
||||
return getDynamicTypeAndAddressOpaqueExistential(object);
|
||||
}
|
||||
llvm_unreachable("invalid type kind");
|
||||
}
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
@@ -1217,3 +1300,10 @@ Result<remote::RemoteAddress>
|
||||
RemoteASTContext::getHeapMetadataForObject(remote::RemoteAddress address) {
|
||||
return asImpl(Impl)->getHeapMetadataForObject(address);
|
||||
}
|
||||
|
||||
Result<std::pair<Type, remote::RemoteAddress>>
|
||||
RemoteASTContext::getDynamicTypeAndAddressForExistential(
|
||||
remote::RemoteAddress address, Type staticType) {
|
||||
return asImpl(Impl)->getDynamicTypeAndAddressForExistential(address,
|
||||
staticType);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user