@@ -1695,10 +1695,56 @@ tryCastUnwrappingExistentialSource(
1695
1695
return tryCast (destLocation, destType,
1696
1696
srcInnerValue, srcInnerType,
1697
1697
destFailureType, srcFailureType,
1698
- takeOnSuccess & (srcInnerValue == srcValue),
1698
+ takeOnSuccess && (srcInnerValue == srcValue),
1699
1699
mayDeferChecks);
1700
1700
}
1701
1701
1702
+ static DynamicCastResult tryCastUnwrappingExtendedExistentialSource (
1703
+ OpaqueValue *destLocation, const Metadata *destType, OpaqueValue *srcValue,
1704
+ const Metadata *srcType, const Metadata *&destFailureType,
1705
+ const Metadata *&srcFailureType, bool takeOnSuccess, bool mayDeferChecks) {
1706
+ assert (srcType != destType);
1707
+ assert (srcType->getKind () == MetadataKind::ExtendedExistential);
1708
+
1709
+ auto srcExistentialType = cast<ExtendedExistentialTypeMetadata>(srcType);
1710
+
1711
+ // Unpack the existential content
1712
+ const Metadata *srcInnerType = nullptr ;
1713
+ OpaqueValue *srcInnerValue = nullptr ;
1714
+ switch (srcExistentialType->Shape ->Flags .getSpecialKind ()) {
1715
+ case ExtendedExistentialTypeShape::SpecialKind::None: {
1716
+ auto opaqueContainer =
1717
+ reinterpret_cast <OpaqueExistentialContainer *>(srcValue);
1718
+ srcInnerType = opaqueContainer->Type ;
1719
+ srcInnerValue = const_cast <OpaqueValue *>(opaqueContainer->projectValue ());
1720
+ break ;
1721
+ }
1722
+ case ExtendedExistentialTypeShape::SpecialKind::Class: {
1723
+ auto classContainer =
1724
+ reinterpret_cast <ClassExistentialContainer *>(srcValue);
1725
+ srcInnerType = swift_getObjectType ((HeapObject *)classContainer->Value );
1726
+ srcInnerValue = reinterpret_cast <OpaqueValue *>(&classContainer->Value );
1727
+ break ;
1728
+ }
1729
+ case ExtendedExistentialTypeShape::SpecialKind::Metatype: {
1730
+ auto srcExistentialContainer =
1731
+ reinterpret_cast <ExistentialMetatypeContainer *>(srcValue);
1732
+ srcInnerType = swift_getMetatypeMetadata (srcExistentialContainer->Value );
1733
+ srcInnerValue = reinterpret_cast <OpaqueValue *>(&srcExistentialContainer->Value );
1734
+ break ;
1735
+ }
1736
+ case ExtendedExistentialTypeShape::SpecialKind::ExplicitLayout: {
1737
+ swift_unreachable (" Explicit layout not yet implemented" );
1738
+ break ;
1739
+ }
1740
+ }
1741
+
1742
+ srcFailureType = srcInnerType;
1743
+ return tryCast (destLocation, destType, srcInnerValue, srcInnerType,
1744
+ destFailureType, srcFailureType,
1745
+ takeOnSuccess & (srcInnerValue == srcValue), mayDeferChecks);
1746
+ }
1747
+
1702
1748
static DynamicCastResult
1703
1749
tryCastUnwrappingExistentialMetatypeSource (
1704
1750
OpaqueValue *destLocation, const Metadata *destType,
@@ -1722,6 +1768,134 @@ tryCastUnwrappingExistentialMetatypeSource(
1722
1768
mayDeferChecks);
1723
1769
}
1724
1770
1771
+
1772
+ static DynamicCastResult tryCastToExtendedExistential (
1773
+ OpaqueValue *destLocation, const Metadata *destType, OpaqueValue *srcValue,
1774
+ const Metadata *srcType, const Metadata *&destFailureType,
1775
+ const Metadata *&srcFailureType, bool takeOnSuccess, bool mayDeferChecks) {
1776
+ assert (srcType != destType);
1777
+ assert (destType->getKind () == MetadataKind::ExtendedExistential);
1778
+
1779
+ auto destExistentialType = cast<ExtendedExistentialTypeMetadata>(destType);
1780
+ auto *destExistentialShape = destExistentialType->Shape ;
1781
+ const unsigned shapeArgumentCount =
1782
+ destExistentialShape->getGenSigArgumentLayoutSizeInWords ();
1783
+ const Metadata *selfType = srcType;
1784
+
1785
+ // If we have a type expression to look into, unwrap as much metatype
1786
+ // structure as possible so we can reach the type metadata for the 'Self'
1787
+ // parameter.
1788
+ if (destExistentialShape->Flags .hasTypeExpression ()) {
1789
+ Demangler dem;
1790
+ auto *node = dem.demangleType (destExistentialShape->getTypeExpression ()->name .get ());
1791
+ if (!node)
1792
+ return DynamicCastResult::Failure;
1793
+
1794
+ while (node->getKind () == Demangle::Node::Kind::Type &&
1795
+ node->getNumChildren () &&
1796
+ node->getChild (0 )->getKind () == Demangle::Node::Kind::Metatype &&
1797
+ node->getChild (0 )->getNumChildren ()) {
1798
+ auto *metatypeMetadata = dyn_cast<MetatypeMetadata>(selfType);
1799
+ if (!metatypeMetadata)
1800
+ return DynamicCastResult::Failure;
1801
+
1802
+ selfType = metatypeMetadata->InstanceType ;
1803
+ node = node->getChild (0 )->getChild (0 );
1804
+ }
1805
+
1806
+ // Make sure the thing we've pulled out at the end is a dependent
1807
+ // generic parameter.
1808
+ if (!(node->getKind () == Demangle::Node::Kind::Type &&
1809
+ node->getNumChildren () &&
1810
+ node->getChild (0 )->getKind () ==
1811
+ Demangle::Node::Kind::DependentGenericParamType))
1812
+ return DynamicCastResult::Failure;
1813
+ }
1814
+
1815
+ llvm::SmallVector<const void *, 8 > allGenericArgsVec;
1816
+ unsigned witnessesMark = 0 ;
1817
+ {
1818
+ // Line up the arguments to the requirement signature.
1819
+ auto genArgs = destExistentialType->getGeneralizationArguments ();
1820
+ allGenericArgsVec.append (genArgs, genArgs + shapeArgumentCount);
1821
+ // Tack on the `Self` argument.
1822
+ allGenericArgsVec.push_back ((const void *)selfType);
1823
+ // Mark the point where the generic arguments end.
1824
+ // _checkGenericRequirements is going to fill in a set of witness tables
1825
+ // after that.
1826
+ witnessesMark = allGenericArgsVec.size ();
1827
+
1828
+ SubstGenericParametersFromMetadata substitutions (destExistentialShape,
1829
+ allGenericArgsVec.data ());
1830
+ // Verify the requirements in the requirement signature against the
1831
+ // arguments from the source value.
1832
+ auto error = swift::_checkGenericRequirements (
1833
+ destExistentialShape->getRequirementSignature ().getRequirements (),
1834
+ allGenericArgsVec,
1835
+ [&substitutions](unsigned depth, unsigned index) {
1836
+ return substitutions.getMetadata (depth, index);
1837
+ },
1838
+ [](const Metadata *type, unsigned index) -> const WitnessTable * {
1839
+ swift_unreachable (" Resolution of witness tables is not supported" );
1840
+ });
1841
+ if (error)
1842
+ return DynamicCastResult::Failure;
1843
+ }
1844
+
1845
+ OpaqueValue *destBox = nullptr ;
1846
+ const WitnessTable **destWitnesses = nullptr ;
1847
+ switch (destExistentialShape->Flags .getSpecialKind ()) {
1848
+ case ExtendedExistentialTypeShape::SpecialKind::None: {
1849
+ auto destExistential =
1850
+ reinterpret_cast <OpaqueExistentialContainer *>(destLocation);
1851
+
1852
+ // Allocate a box and fill in the type information.
1853
+ destExistential->Type = srcType;
1854
+ destBox = srcType->allocateBoxForExistentialIn (&destExistential->Buffer );
1855
+ destWitnesses = destExistential->getWitnessTables ();
1856
+ break ;
1857
+ }
1858
+ case ExtendedExistentialTypeShape::SpecialKind::Class: {
1859
+ auto destExistential =
1860
+ reinterpret_cast <ClassExistentialContainer *>(destLocation);
1861
+ destBox = reinterpret_cast <OpaqueValue *>(&destExistential->Value );
1862
+ destWitnesses = destExistential->getWitnessTables ();
1863
+ break ;
1864
+ }
1865
+ case ExtendedExistentialTypeShape::SpecialKind::Metatype: {
1866
+ auto destExistential =
1867
+ reinterpret_cast <ExistentialMetatypeContainer *>(destLocation);
1868
+ destBox = reinterpret_cast <OpaqueValue *>(&destExistential->Value );
1869
+ destWitnesses = destExistential->getWitnessTables ();
1870
+ break ;
1871
+ }
1872
+ case ExtendedExistentialTypeShape::SpecialKind::ExplicitLayout:
1873
+ swift_unreachable (" Witnesses for explicit layout not yet implemented" );
1874
+ }
1875
+
1876
+ // Fill in the trailing set of witness tables.
1877
+ const unsigned numWitnessTables = allGenericArgsVec.size () - witnessesMark;
1878
+ assert (numWitnessTables ==
1879
+ llvm::count_if (destExistentialShape->getRequirementSignature ().getRequirements (),
1880
+ [](const auto &req) -> bool {
1881
+ return req.getKind () ==
1882
+ GenericRequirementKind::Protocol;
1883
+ }));
1884
+ for (unsigned i = 0 ; i < numWitnessTables; ++i) {
1885
+ const auto witness = i + witnessesMark;
1886
+ destWitnesses[i] =
1887
+ reinterpret_cast <const WitnessTable *>(allGenericArgsVec[witness]);
1888
+ }
1889
+
1890
+ if (takeOnSuccess) {
1891
+ srcType->vw_initializeWithTake (destBox, srcValue);
1892
+ return DynamicCastResult::SuccessViaTake;
1893
+ } else {
1894
+ srcType->vw_initializeWithCopy (destBox, srcValue);
1895
+ return DynamicCastResult::SuccessViaCopy;
1896
+ }
1897
+ }
1898
+
1725
1899
/* *****************************************************************************/
1726
1900
/* *************************** Opaque Destination ******************************/
1727
1901
/* *****************************************************************************/
@@ -2006,12 +2180,14 @@ static tryCastFunctionType *selectCasterForDest(const Metadata *destType) {
2006
2180
swift_unreachable (
2007
2181
" Unknown existential type representation in dynamic cast dispatch" );
2008
2182
}
2183
+ case MetadataKind::ExtendedExistential:
2184
+ return tryCastToExtendedExistential;
2009
2185
case MetadataKind::Metatype:
2010
- return tryCastToMetatype;
2011
- case MetadataKind::ObjCClassWrapper:
2186
+ return tryCastToMetatype;
2187
+ case MetadataKind::ObjCClassWrapper:
2012
2188
return tryCastToObjectiveCClass;
2013
2189
case MetadataKind::ExistentialMetatype:
2014
- return tryCastToExistentialMetatype;
2190
+ return tryCastToExistentialMetatype;
2015
2191
case MetadataKind::HeapLocalVariable:
2016
2192
case MetadataKind::HeapGenericLocalVariable:
2017
2193
case MetadataKind::ErrorObject:
@@ -2169,6 +2345,15 @@ tryCast(
2169
2345
break ;
2170
2346
}
2171
2347
2348
+ case MetadataKind::ExtendedExistential: {
2349
+ auto subcastResult = tryCastUnwrappingExtendedExistentialSource (
2350
+ destLocation, destType, srcValue, srcType, destFailureType,
2351
+ srcFailureType, takeOnSuccess, mayDeferChecks);
2352
+ if (isSuccess (subcastResult)) {
2353
+ return subcastResult;
2354
+ }
2355
+ break ;
2356
+ }
2172
2357
default :
2173
2358
break ;
2174
2359
}
0 commit comments