@@ -1696,10 +1696,56 @@ tryCastUnwrappingExistentialSource(
16961696 return tryCast (destLocation, destType,
16971697 srcInnerValue, srcInnerType,
16981698 destFailureType, srcFailureType,
1699- takeOnSuccess & (srcInnerValue == srcValue),
1699+ takeOnSuccess && (srcInnerValue == srcValue),
17001700 mayDeferChecks);
17011701}
17021702
1703+ static DynamicCastResult tryCastUnwrappingExtendedExistentialSource (
1704+ OpaqueValue *destLocation, const Metadata *destType, OpaqueValue *srcValue,
1705+ const Metadata *srcType, const Metadata *&destFailureType,
1706+ const Metadata *&srcFailureType, bool takeOnSuccess, bool mayDeferChecks) {
1707+ assert (srcType != destType);
1708+ assert (srcType->getKind () == MetadataKind::ExtendedExistential);
1709+
1710+ auto srcExistentialType = cast<ExtendedExistentialTypeMetadata>(srcType);
1711+
1712+ // Unpack the existential content
1713+ const Metadata *srcInnerType = nullptr ;
1714+ OpaqueValue *srcInnerValue = nullptr ;
1715+ switch (srcExistentialType->Shape ->Flags .getSpecialKind ()) {
1716+ case ExtendedExistentialTypeShape::SpecialKind::None: {
1717+ auto opaqueContainer =
1718+ reinterpret_cast <OpaqueExistentialContainer *>(srcValue);
1719+ srcInnerType = opaqueContainer->Type ;
1720+ srcInnerValue = const_cast <OpaqueValue *>(opaqueContainer->projectValue ());
1721+ break ;
1722+ }
1723+ case ExtendedExistentialTypeShape::SpecialKind::Class: {
1724+ auto classContainer =
1725+ reinterpret_cast <ClassExistentialContainer *>(srcValue);
1726+ srcInnerType = swift_getObjectType ((HeapObject *)classContainer->Value );
1727+ srcInnerValue = reinterpret_cast <OpaqueValue *>(&classContainer->Value );
1728+ break ;
1729+ }
1730+ case ExtendedExistentialTypeShape::SpecialKind::Metatype: {
1731+ auto srcExistentialContainer =
1732+ reinterpret_cast <ExistentialMetatypeContainer *>(srcValue);
1733+ srcInnerType = swift_getMetatypeMetadata (srcExistentialContainer->Value );
1734+ srcInnerValue = reinterpret_cast <OpaqueValue *>(&srcExistentialContainer->Value );
1735+ break ;
1736+ }
1737+ case ExtendedExistentialTypeShape::SpecialKind::ExplicitLayout: {
1738+ swift_unreachable (" Explicit layout not yet implemented" );
1739+ break ;
1740+ }
1741+ }
1742+
1743+ srcFailureType = srcInnerType;
1744+ return tryCast (destLocation, destType, srcInnerValue, srcInnerType,
1745+ destFailureType, srcFailureType,
1746+ takeOnSuccess & (srcInnerValue == srcValue), mayDeferChecks);
1747+ }
1748+
17031749static DynamicCastResult
17041750tryCastUnwrappingExistentialMetatypeSource (
17051751 OpaqueValue *destLocation, const Metadata *destType,
@@ -1723,6 +1769,103 @@ tryCastUnwrappingExistentialMetatypeSource(
17231769 mayDeferChecks);
17241770}
17251771
1772+
1773+ static DynamicCastResult tryCastToExtendedExistential (
1774+ OpaqueValue *destLocation, const Metadata *destType, OpaqueValue *srcValue,
1775+ const Metadata *srcType, const Metadata *&destFailureType,
1776+ const Metadata *&srcFailureType, bool takeOnSuccess, bool mayDeferChecks) {
1777+ assert (srcType != destType);
1778+ assert (destType->getKind () == MetadataKind::ExtendedExistential);
1779+
1780+ auto destExistentialType = cast<ExtendedExistentialTypeMetadata>(destType);
1781+ auto *destExistentialShape = destExistentialType->Shape ;
1782+ const unsigned shapeArgumentCount =
1783+ destExistentialShape->getGenSigArgumentLayoutSizeInWords ();
1784+
1785+ llvm::SmallVector<const void *, 8 > allGenericArgsVec;
1786+ unsigned witnessesMark = 0 ;
1787+ {
1788+ // Line up the arguments to the requirement signature.
1789+ auto genArgs = destExistentialType->getGeneralizationArguments ();
1790+ allGenericArgsVec.append (genArgs, genArgs + shapeArgumentCount);
1791+ // Tack on the `Self` argument.
1792+ allGenericArgsVec.push_back ((const void *)srcType);
1793+ // Mark the point where the generic arguments end.
1794+ // _checkGenericRequirements is going to fill in a set of witness tables
1795+ // after that.
1796+ witnessesMark = allGenericArgsVec.size ();
1797+
1798+ SubstGenericParametersFromMetadata substitutions (destExistentialShape,
1799+ allGenericArgsVec.data ());
1800+ // Verify the requirements in the requirement signature against the
1801+ // arguments from the source value.
1802+ auto error = swift::_checkGenericRequirements (
1803+ destExistentialShape->getRequirementSignature ().getRequirements (),
1804+ allGenericArgsVec,
1805+ [&substitutions](unsigned depth, unsigned index) {
1806+ return substitutions.getMetadata (depth, index);
1807+ },
1808+ [](const Metadata *type, unsigned index) -> const WitnessTable * {
1809+ swift_unreachable (" Resolution of witness tables is not supported" );
1810+ });
1811+ if (error)
1812+ return DynamicCastResult::Failure;
1813+ }
1814+
1815+ OpaqueValue *destBox = nullptr ;
1816+ const WitnessTable **destWitnesses = nullptr ;
1817+ switch (destExistentialShape->Flags .getSpecialKind ()) {
1818+ case ExtendedExistentialTypeShape::SpecialKind::None: {
1819+ auto destExistential =
1820+ reinterpret_cast <OpaqueExistentialContainer *>(destLocation);
1821+
1822+ // Allocate a box and fill in the type information.
1823+ destExistential->Type = srcType;
1824+ destBox = srcType->allocateBoxForExistentialIn (&destExistential->Buffer );
1825+ destWitnesses = destExistential->getWitnessTables ();
1826+ break ;
1827+ }
1828+ case ExtendedExistentialTypeShape::SpecialKind::Class: {
1829+ auto destExistential =
1830+ reinterpret_cast <ClassExistentialContainer *>(destLocation);
1831+ destBox = reinterpret_cast <OpaqueValue *>(&destExistential->Value );
1832+ destWitnesses = destExistential->getWitnessTables ();
1833+ break ;
1834+ }
1835+ case ExtendedExistentialTypeShape::SpecialKind::Metatype: {
1836+ auto destExistential =
1837+ reinterpret_cast <ExistentialMetatypeContainer *>(destLocation);
1838+ destBox = reinterpret_cast <OpaqueValue *>(&destExistential->Value );
1839+ destWitnesses = destExistential->getWitnessTables ();
1840+ break ;
1841+ }
1842+ case ExtendedExistentialTypeShape::SpecialKind::ExplicitLayout:
1843+ swift_unreachable (" Witnesses for explicit layout not yet implemented" );
1844+ }
1845+
1846+ // Fill in the trailing set of witness tables.
1847+ const unsigned numWitnessTables = allGenericArgsVec.size () - witnessesMark;
1848+ assert (numWitnessTables ==
1849+ llvm::count_if (destExistentialShape->getRequirementSignature ().getRequirements (),
1850+ [](const auto &req) -> bool {
1851+ return req.getKind () ==
1852+ GenericRequirementKind::Protocol;
1853+ }));
1854+ for (unsigned i = 0 ; i < numWitnessTables; ++i) {
1855+ const auto witness = i + witnessesMark;
1856+ destWitnesses[i] =
1857+ reinterpret_cast <const WitnessTable *>(allGenericArgsVec[witness]);
1858+ }
1859+
1860+ if (takeOnSuccess) {
1861+ srcType->vw_initializeWithTake (destBox, srcValue);
1862+ return DynamicCastResult::SuccessViaTake;
1863+ } else {
1864+ srcType->vw_initializeWithCopy (destBox, srcValue);
1865+ return DynamicCastResult::SuccessViaCopy;
1866+ }
1867+ }
1868+
17261869/* *****************************************************************************/
17271870/* *************************** Opaque Destination ******************************/
17281871/* *****************************************************************************/
@@ -2007,12 +2150,14 @@ static tryCastFunctionType *selectCasterForDest(const Metadata *destType) {
20072150 swift_unreachable (
20082151 " Unknown existential type representation in dynamic cast dispatch" );
20092152 }
2153+ case MetadataKind::ExtendedExistential:
2154+ return tryCastToExtendedExistential;
20102155 case MetadataKind::Metatype:
2011- return tryCastToMetatype;
2012- case MetadataKind::ObjCClassWrapper:
2156+ return tryCastToMetatype;
2157+ case MetadataKind::ObjCClassWrapper:
20132158 return tryCastToObjectiveCClass;
20142159 case MetadataKind::ExistentialMetatype:
2015- return tryCastToExistentialMetatype;
2160+ return tryCastToExistentialMetatype;
20162161 case MetadataKind::HeapLocalVariable:
20172162 case MetadataKind::HeapGenericLocalVariable:
20182163 case MetadataKind::ErrorObject:
@@ -2170,6 +2315,15 @@ tryCast(
21702315 break ;
21712316 }
21722317
2318+ case MetadataKind::ExtendedExistential: {
2319+ auto subcastResult = tryCastUnwrappingExtendedExistentialSource (
2320+ destLocation, destType, srcValue, srcType, destFailureType,
2321+ srcFailureType, takeOnSuccess, mayDeferChecks);
2322+ if (isSuccess (subcastResult)) {
2323+ return subcastResult;
2324+ }
2325+ break ;
2326+ }
21732327 default :
21742328 break ;
21752329 }
0 commit comments