@@ -52,6 +52,10 @@ struct HeapTypeInfo {
5252 Shareability share = Unshared;
5353 // The supertype of this HeapType, if it exists.
5454 HeapTypeInfo* supertype = nullptr ;
55+ // The descriptor of this HeapType, if it exists.
56+ HeapTypeInfo* descriptor = nullptr ;
57+ // The HeapType described by this one, if it exists.
58+ HeapTypeInfo* described = nullptr ;
5559 // The recursion group of this type or null if the recursion group is trivial
5660 // (i.e. contains only this type).
5761 RecGroupInfo* recGroup = nullptr ;
@@ -976,6 +980,26 @@ std::optional<HeapType> HeapType::getSuperType() const {
976980 WASM_UNREACHABLE (" unexpected kind" );
977981}
978982
983+ std::optional<HeapType> HeapType::getDescriptorType () const {
984+ if (isBasic ()) {
985+ return std::nullopt ;
986+ }
987+ if (auto * desc = getHeapTypeInfo (*this )->descriptor ) {
988+ return HeapType (uintptr_t (desc));
989+ }
990+ return std::nullopt ;
991+ }
992+
993+ std::optional<HeapType> HeapType::getDescribedType () const {
994+ if (isBasic ()) {
995+ return std::nullopt ;
996+ }
997+ if (auto * desc = getHeapTypeInfo (*this )->described ) {
998+ return HeapType (uintptr_t (desc));
999+ }
1000+ return std::nullopt ;
1001+ }
1002+
9791003size_t HeapType::getDepth () const {
9801004 size_t depth = 0 ;
9811005 std::optional<HeapType> super;
@@ -1149,6 +1173,12 @@ std::vector<HeapType> HeapType::getReferencedHeapTypes() const {
11491173 if (auto super = getDeclaredSuperType ()) {
11501174 types.push_back (*super);
11511175 }
1176+ if (auto desc = getDescriptorType ()) {
1177+ types.push_back (*desc);
1178+ }
1179+ if (auto desc = getDescribedType ()) {
1180+ types.push_back (*desc);
1181+ }
11521182 return types;
11531183}
11541184
@@ -1280,6 +1310,10 @@ FeatureSet HeapType::getFeatures() const {
12801310 feats |= FeatureSet::ReferenceTypes | FeatureSet::GC;
12811311 }
12821312
1313+ if (heapType.getDescriptorType () || heapType.getDescribedType ()) {
1314+ feats |= FeatureSet::CustomDescriptors;
1315+ }
1316+
12831317 if (heapType.isStruct () || heapType.isArray ()) {
12841318 feats |= FeatureSet::ReferenceTypes | FeatureSet::GC;
12851319 } else if (heapType.isSignature ()) {
@@ -1765,6 +1799,16 @@ std::ostream& TypePrinter::print(HeapType type) {
17651799 if (type.isShared ()) {
17661800 os << " (shared " ;
17671801 }
1802+ if (auto desc = type.getDescribedType ()) {
1803+ os << " (describes " ;
1804+ printHeapTypeName (*desc);
1805+ os << ' ' ;
1806+ }
1807+ if (auto desc = type.getDescriptorType ()) {
1808+ os << " (descriptor " ;
1809+ printHeapTypeName (*desc);
1810+ os << ' ' ;
1811+ }
17681812 switch (type.getKind ()) {
17691813 case HeapTypeKind::Func:
17701814 print (type.getSignature ());
@@ -1781,6 +1825,12 @@ std::ostream& TypePrinter::print(HeapType type) {
17811825 case HeapTypeKind::Basic:
17821826 WASM_UNREACHABLE (" unexpected kind" );
17831827 }
1828+ if (type.getDescriptorType ()) {
1829+ os << ' )' ;
1830+ }
1831+ if (type.getDescribedType ()) {
1832+ os << ' )' ;
1833+ }
17841834 if (type.isShared ()) {
17851835 os << ' )' ;
17861836 }
@@ -1927,9 +1977,18 @@ size_t RecGroupHasher::hash(HeapType type) const {
19271977
19281978size_t RecGroupHasher::hash (const HeapTypeInfo& info) const {
19291979 size_t digest = wasm::hash (bool (info.supertype ));
1980+ wasm::rehash (digest, !!info.supertype );
19301981 if (info.supertype ) {
19311982 hash_combine (digest, hash (HeapType (uintptr_t (info.supertype ))));
19321983 }
1984+ wasm::rehash (digest, !!info.descriptor );
1985+ if (info.descriptor ) {
1986+ hash_combine (digest, hash (HeapType (uintptr_t (info.descriptor ))));
1987+ }
1988+ wasm::rehash (digest, !!info.described );
1989+ if (info.described ) {
1990+ hash_combine (digest, hash (HeapType (uintptr_t (info.described ))));
1991+ }
19331992 wasm::rehash (digest, info.isOpen );
19341993 wasm::rehash (digest, info.share );
19351994 wasm::rehash (digest, info.kind );
@@ -2051,7 +2110,7 @@ bool RecGroupEquator::eq(HeapType a, HeapType b) const {
20512110}
20522111
20532112bool RecGroupEquator::eq (const HeapTypeInfo& a, const HeapTypeInfo& b) const {
2054- if (bool ( a.supertype ) != bool ( b.supertype ) ) {
2113+ if (!! a.supertype != !! b.supertype ) {
20552114 return false ;
20562115 }
20572116 if (a.supertype ) {
@@ -2061,6 +2120,26 @@ bool RecGroupEquator::eq(const HeapTypeInfo& a, const HeapTypeInfo& b) const {
20612120 return false ;
20622121 }
20632122 }
2123+ if (!!a.descriptor != !!b.descriptor ) {
2124+ return false ;
2125+ }
2126+ if (a.descriptor ) {
2127+ HeapType descA (uintptr_t (a.descriptor ));
2128+ HeapType descB (uintptr_t (b.descriptor ));
2129+ if (!eq (descA, descB)) {
2130+ return false ;
2131+ }
2132+ }
2133+ if (!!a.described != !!b.described ) {
2134+ return false ;
2135+ }
2136+ if (a.described ) {
2137+ HeapType descA (uintptr_t (a.described ));
2138+ HeapType descB (uintptr_t (b.described ));
2139+ if (!eq (descA, descB)) {
2140+ return false ;
2141+ }
2142+ }
20642143 if (a.isOpen != b.isOpen ) {
20652144 return false ;
20662145 }
@@ -2227,6 +2306,16 @@ void TypeBuilder::setSubType(size_t i, std::optional<HeapType> super) {
22272306 HeapTypeInfo* sub = impl->entries [i].info .get ();
22282307 sub->supertype = super ? getHeapTypeInfo (*super) : nullptr ;
22292308}
2309+ void TypeBuilder::setDescriptor (size_t i, std::optional<HeapType> desc) {
2310+ assert (i < size () && " index out of bounds" );
2311+ HeapTypeInfo* info = impl->entries [i].info .get ();
2312+ info->descriptor = desc ? getHeapTypeInfo (*desc) : nullptr ;
2313+ }
2314+ void TypeBuilder::setDescribed (size_t i, std::optional<HeapType> desc) {
2315+ assert (i < size () && " index out of bounds" );
2316+ HeapTypeInfo* info = impl->entries [i].info .get ();
2317+ info->described = desc ? getHeapTypeInfo (*desc) : nullptr ;
2318+ }
22302319
22312320void TypeBuilder::createRecGroup (size_t index, size_t length) {
22322321 assert (index <= size () && index + length <= size () && " group out of bounds" );
@@ -2382,6 +2471,20 @@ void updateReferencedHeapTypes(
23822471 info->supertype = getHeapTypeInfo (it->second );
23832472 }
23842473 }
2474+
2475+ // Update the descriptor and described types.
2476+ if (info->descriptor ) {
2477+ HeapType desc (uintptr_t (info->descriptor ));
2478+ if (auto it = canonicalized.find (desc); it != canonicalized.end ()) {
2479+ info->descriptor = getHeapTypeInfo (it->second );
2480+ }
2481+ }
2482+ if (info->described ) {
2483+ HeapType desc (uintptr_t (info->described ));
2484+ if (auto it = canonicalized.find (desc); it != canonicalized.end ()) {
2485+ info->described = getHeapTypeInfo (it->second );
2486+ }
2487+ }
23852488}
23862489
23872490TypeBuilder::BuildResult
0 commit comments