Skip to content

[Runtime] Add entry point to compare type context descriptors. #32476

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions include/swift/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,10 @@ class ASTContext final {
/// metadata.
AvailabilityContext getPrespecializedGenericMetadataAvailability();

/// Get the runtime availability of the swift_compareTypeContextDescriptors
/// for the target platform.
AvailabilityContext getCompareTypeContextDescriptorsAvailability();

/// Get the runtime availability of features introduced in the Swift 5.2
/// compiler for the target platform.
AvailabilityContext getSwift52Availability();
Expand Down
14 changes: 14 additions & 0 deletions include/swift/Runtime/Metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,20 @@ const
/// the same context.
bool equalContexts(const ContextDescriptor *a, const ContextDescriptor *b);

/// Determines whether two type context descriptors describe the same type
/// context.
///
/// Runtime availability: Swift 5.4.
///
/// \param lhs The first type context descriptor to compare.
/// \param rhs The second type context descriptor to compare.
///
/// \returns true if both describe the same type context, false otherwise.
SWIFT_RUNTIME_EXPORT
SWIFT_CC(swift)
bool swift_compareTypeContextDescriptors(const TypeContextDescriptor *lhs,
const TypeContextDescriptor *rhs);

/// Compute the bounds of class metadata with a resilient superclass.
ClassMetadataBounds getResilientMetadataBounds(
const ClassDescriptor *descriptor);
Expand Down
12 changes: 12 additions & 0 deletions include/swift/Runtime/RuntimeFunctions.def
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,18 @@ FUNCTION(GetForeignTypeMetadata, swift_getForeignTypeMetadata,
ARGS(SizeTy, TypeMetadataPtrTy),
ATTRS(NoUnwind, ReadNone)) // only writes to runtime-private fields

// SWIFT_RUNTIME_EXPORT
// SWIFT_CC(swift)
// bool swift_compareTypeContextDescriptors(const TypeContextDescriptor *lhs,
// const TypeContextDescriptor *rhs);
FUNCTION(CompareTypeContextDescriptors,
swift_compareTypeContextDescriptors, SwiftCC,
CompareTypeContextDescriptorsAvailability,
RETURNS(Int1Ty),
ARGS(TypeContextDescriptorPtrTy,
TypeContextDescriptorPtrTy),
ATTRS(NoUnwind, ReadNone))

// MetadataResponse swift_getSingletonMetadata(MetadataRequest request,
// TypeContextDescriptor *type);
FUNCTION(GetSingletonMetadata, swift_getSingletonMetadata,
Expand Down
4 changes: 4 additions & 0 deletions lib/AST/Availability.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,10 @@ AvailabilityContext ASTContext::getPrespecializedGenericMetadataAvailability() {
return getSwift53Availability();
}

AvailabilityContext ASTContext::getCompareTypeContextDescriptorsAvailability() {
return getSwiftFutureAvailability();
}

AvailabilityContext ASTContext::getSwift52Availability() {
auto target = LangOpts.Target;

Expand Down
10 changes: 10 additions & 0 deletions lib/IRGen/IRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,16 @@ namespace RuntimeConstants {
}
return RuntimeAvailability::AlwaysAvailable;
}

RuntimeAvailability
CompareTypeContextDescriptorsAvailability(ASTContext &Context) {
auto featureAvailability =
Context.getCompareTypeContextDescriptorsAvailability();
if (!isDeploymentAvailabilityContainedIn(Context, featureAvailability)) {
return RuntimeAvailability::ConditionallyAvailable;
}
return RuntimeAvailability::AlwaysAvailable;
}
} // namespace RuntimeConstants

// We don't use enough attributes to justify generalizing the
Expand Down
27 changes: 27 additions & 0 deletions stdlib/public/runtime/Metadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1918,6 +1918,33 @@ bool swift::equalContexts(const ContextDescriptor *a,
}
}

SWIFT_CC(swift)
bool swift::swift_compareTypeContextDescriptors(
const TypeContextDescriptor *a, const TypeContextDescriptor *b) {
// The implementation is the same as the implementation of
// swift::equalContexts except that the handling of non-type
// context descriptors and casts to TypeContextDescriptor are removed.

// Fast path: pointer equality.
if (a == b) return true;

// If either context is null, we're done.
if (a == nullptr || b == nullptr)
return false;

// If either descriptor is known to be unique, we're done.
if (a->isUnique() || b->isUnique()) return false;

// Do the kinds match?
if (a->getKind() != b->getKind()) return false;

// Do the parents match?
if (!equalContexts(a->Parent.get(), b->Parent.get()))
return false;

return TypeContextIdentity(a) == TypeContextIdentity(b);
}

/***************************************************************************/
/*** Common value witnesses ************************************************/
/***************************************************************************/
Expand Down