Runtime: Add support for resilient superclasses

If the nominal type descriptor's resilient superclass flag
is set, the generic parameter offset, vtable start offset
and field offset start offset are all relative to the
start of the class's immedaite members, and not the start
of the class metadata.

Support this by loading the size of the superclass and
adding it to these offsets if the flag is set.
This commit is contained in:
Slava Pestov
2018-01-02 21:33:15 -08:00
parent 22f08f7f47
commit fea92a0214
4 changed files with 139 additions and 30 deletions

View File

@@ -992,6 +992,35 @@ public:
swift_runtime_unreachable("Unhandled IsaEncodingKind in switch.");
}
/// Read the offset of the generic parameters of a class from the nominal
/// type descriptor. If the class has a resilient superclass, we also
/// have to read the superclass size and add that to the offset.
///
/// The offset is in units of words, from the start of the class's
/// metadata.
std::pair<bool, uint32_t>
readGenericArgsOffset(MetadataRef metadata,
NominalTypeDescriptorRef descriptor) {
if (metadata->getKind() == MetadataKind::Class) {
auto *classMetadata = cast<TargetClassMetadata<Runtime>>(metadata);
if (classMetadata->SuperClass) {
auto superMetadata = readMetadata(classMetadata->SuperClass);
if (!superMetadata)
return std::make_pair(false, 0);
auto result =
descriptor->GenericParams.getOffset(
classMetadata,
cast<TargetClassMetadata<Runtime>>(superMetadata));
return std::make_pair(true, result);
}
}
auto result = descriptor->GenericParams.getOffset();
return std::make_pair(true, result);
}
/// Read a single generic type argument from a bound generic type
/// metadata.
std::pair<bool, StoredPointer>
@@ -1010,11 +1039,14 @@ public:
return std::make_pair(false, 0);
auto numGenericParams = descriptor->GenericParams.NumPrimaryParams;
auto offsetToGenericArgs =
sizeof(StoredPointer) * (descriptor->GenericParams.Offset);
auto offsetToGenericArgs = readGenericArgsOffset(Meta, descriptor);
if (!offsetToGenericArgs.first)
return std::make_pair(false, 0);
auto addressOfGenericArgAddress =
Meta.getAddress() + offsetToGenericArgs +
index * sizeof(StoredPointer);
(Meta.getAddress() +
offsetToGenericArgs.second * sizeof(StoredPointer) +
index * sizeof(StoredPointer));
if (index >= numGenericParams)
return std::make_pair(false, 0);
@@ -1357,10 +1389,13 @@ private:
std::vector<BuiltType> substitutions;
auto numGenericParams = descriptor->GenericParams.NumPrimaryParams;
auto offsetToGenericArgs =
sizeof(StoredPointer) * (descriptor->GenericParams.Offset);
auto offsetToGenericArgs = readGenericArgsOffset(metadata, descriptor);
if (!offsetToGenericArgs.first)
return {};
auto addressOfGenericArgAddress =
metadata.getAddress() + offsetToGenericArgs;
(metadata.getAddress() + sizeof(StoredPointer) *
offsetToGenericArgs.second);
using ArgIndex = decltype(descriptor->GenericParams.NumPrimaryParams);
for (ArgIndex i = 0; i < numGenericParams;