Skip to content
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

[Dynamic Casting] Overhauled Runtime #33561

Merged
merged 15 commits into from
Aug 27, 2020
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
9 changes: 8 additions & 1 deletion stdlib/public/core/DebuggerSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,14 @@ public enum _DebuggerSupport {
// yes, a type can lie and say it's a class when it's not since we only
// check the displayStyle - but then the type would have a custom Mirror
// anyway, so there's that...
let willExpand = mirror.displayStyle != .`class` || value is CustomReflectable?
let isNonClass = mirror.displayStyle != .`class`
let isCustomReflectable: Bool
if let value = value {
isCustomReflectable = value is CustomReflectable
} else {
isCustomReflectable = true
}
let willExpand = isNonClass || isCustomReflectable

let count = mirror._children.count
let bullet = isRoot && (count == 0 || !willExpand) ? ""
Expand Down
1 change: 1 addition & 0 deletions stdlib/public/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ set(swift_runtime_sources
CompatibilityOverride.cpp
CygwinPort.cpp
Demangle.cpp
DynamicCast.cpp
Enum.cpp
EnvironmentVariables.cpp
ErrorObjectCommon.cpp
Expand Down
58 changes: 56 additions & 2 deletions stdlib/public/runtime/Casting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,15 @@ _dynamicCastClassMetatype(const ClassMetadata *sourceType,
return nullptr;
}

#if !SWIFT_OBJC_INTEROP // __SwiftValue is a native class
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
bool swift_unboxFromSwiftValueWithType(OpaqueValue *source,
OpaqueValue *result,
const Metadata *destinationType);
/// Nominal type descriptor for Swift.__SwiftValue
extern "C" const ClassDescriptor NOMINAL_TYPE_DESCR_SYM(s12__SwiftValueC);
#endif

/// Dynamically cast a class instance to a Swift class type.
static const void *swift_dynamicCastClassImpl(const void *object,
const ClassMetadata *targetType) {
Expand All @@ -351,10 +360,28 @@ static const void *swift_dynamicCastClassImpl(const void *object,
}
#endif

auto isa = _swift_getClassOfAllocated(object);
auto srcType = _swift_getClassOfAllocated(object);

if (_dynamicCastClassMetatype(isa, targetType))
if (_dynamicCastClassMetatype(srcType, targetType))
return object;

#if !SWIFT_OBJC_INTEROP // __SwiftValue is a native class on Linux
if (srcType->getKind() == MetadataKind::Class
&& targetType->getKind() == MetadataKind::Class) {
auto srcClassType = cast<ClassMetadata>(srcType);
auto srcDescr = srcClassType->getDescription();
if (srcDescr == &NOMINAL_TYPE_DESCR_SYM(s12__SwiftValueC)) {
auto srcValue = reinterpret_cast<OpaqueValue *>(&object);
void *result;
auto destLocation = reinterpret_cast<OpaqueValue *>(&result);
if (swift_unboxFromSwiftValueWithType(srcValue, destLocation, targetType)) {
swift_unknownObjectRelease(const_cast<void *>(object));
return result;
}
}
}
#endif

return nullptr;
}

Expand Down Expand Up @@ -3262,3 +3289,30 @@ HeapObject *_swift_bridgeToObjectiveCUsingProtocolIfPossible(
#define OVERRIDE_CASTING COMPATIBILITY_OVERRIDE
#include "CompatibilityOverride.def"

// XXX TODO XXX REMOVE XXX TRANSITION SHIM XXX
// XXX TODO XXX REMOVE XXX TRANSITION SHIM XXX
// XXX TODO XXX REMOVE XXX TRANSITION SHIM XXX

// A way for the new implementation to call the old one, so we
// can support switching between the two until the new one is
// fully settled.

// XXX TODO XXX Once the new implementation is stable, remove the following,
// swift_dynamicCastImpl above, and all the other code above that only exists to
// support that. (Don't forget _dynamicCastToExistential!!) This file should
// be only ~1400 lines when you're done.

extern "C" {
bool swift_dynamicCast_OLD(OpaqueValue *destLocation,
OpaqueValue *srcValue,
const Metadata *srcType,
const Metadata *destType,
DynamicCastFlags flags)
{
return swift_dynamicCastImpl(destLocation, srcValue, srcType, destType, flags);
}
}

// XXX TODO XXX REMOVE XXX TRANSITION SHIM XXX
// XXX TODO XXX REMOVE XXX TRANSITION SHIM XXX
// XXX TODO XXX REMOVE XXX TRANSITION SHIM XXX
17 changes: 11 additions & 6 deletions stdlib/public/runtime/CompatibilityOverride.def
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#ifdef OVERRIDE
# define OVERRIDE_METADATALOOKUP OVERRIDE
# define OVERRIDE_CASTING OVERRIDE
# define OVERRIDE_DYNAMICCASTING OVERRIDE
# define OVERRIDE_OBJC OVERRIDE
# define OVERRIDE_FOREIGN OVERRIDE
# define OVERRIDE_PROTOCOLCONFORMANCE OVERRIDE
Expand All @@ -52,6 +53,9 @@
# ifndef OVERRIDE_CASTING
# define OVERRIDE_CASTING(...)
# endif
# ifndef OVERRIDE_DYNAMICCASTING
# define OVERRIDE_DYNAMICCASTING(...)
# endif
# ifndef OVERRIDE_OBJC
# define OVERRIDE_OBJC(...)
# endif
Expand All @@ -69,12 +73,12 @@
# endif
#endif

OVERRIDE_CASTING(dynamicCast, bool, , , swift::,
(OpaqueValue *dest, OpaqueValue *src,
const Metadata *srcType,
const Metadata *targetType,
DynamicCastFlags flags),
(dest, src, srcType, targetType, flags))
OVERRIDE_DYNAMICCASTING(dynamicCast, bool, , , swift::,
(OpaqueValue *dest, OpaqueValue *src,
const Metadata *srcType,
const Metadata *targetType,
DynamicCastFlags flags),
(dest, src, srcType, targetType, flags))


OVERRIDE_CASTING(dynamicCastClass, const void *, , , swift::,
Expand Down Expand Up @@ -219,6 +223,7 @@ OVERRIDE_FOREIGN(dynamicCastForeignClassUnconditional, const void *, , , swift::
#undef OVERRIDE
#undef OVERRIDE_METADATALOOKUP
#undef OVERRIDE_CASTING
#undef OVERRIDE_DYNAMICCASTING
#undef OVERRIDE_OBJC
#undef OVERRIDE_FOREIGN
#undef OVERRIDE_PROTOCOLCONFORMANCE
Expand Down
Loading