@@ -52,6 +52,10 @@ struct HeapTypeInfo {
52
52
Shareability share = Unshared;
53
53
// The supertype of this HeapType, if it exists.
54
54
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 ;
55
59
// The recursion group of this type or null if the recursion group is trivial
56
60
// (i.e. contains only this type).
57
61
RecGroupInfo* recGroup = nullptr ;
@@ -976,6 +980,26 @@ std::optional<HeapType> HeapType::getSuperType() const {
976
980
WASM_UNREACHABLE (" unexpected kind" );
977
981
}
978
982
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
+
979
1003
size_t HeapType::getDepth () const {
980
1004
size_t depth = 0 ;
981
1005
std::optional<HeapType> super;
@@ -1149,6 +1173,12 @@ std::vector<HeapType> HeapType::getReferencedHeapTypes() const {
1149
1173
if (auto super = getDeclaredSuperType ()) {
1150
1174
types.push_back (*super);
1151
1175
}
1176
+ if (auto desc = getDescriptorType ()) {
1177
+ types.push_back (*desc);
1178
+ }
1179
+ if (auto desc = getDescribedType ()) {
1180
+ types.push_back (*desc);
1181
+ }
1152
1182
return types;
1153
1183
}
1154
1184
@@ -1280,6 +1310,10 @@ FeatureSet HeapType::getFeatures() const {
1280
1310
feats |= FeatureSet::ReferenceTypes | FeatureSet::GC;
1281
1311
}
1282
1312
1313
+ if (heapType.getDescriptorType () || heapType.getDescribedType ()) {
1314
+ feats |= FeatureSet::CustomDescriptors;
1315
+ }
1316
+
1283
1317
if (heapType.isStruct () || heapType.isArray ()) {
1284
1318
feats |= FeatureSet::ReferenceTypes | FeatureSet::GC;
1285
1319
} else if (heapType.isSignature ()) {
@@ -1765,6 +1799,16 @@ std::ostream& TypePrinter::print(HeapType type) {
1765
1799
if (type.isShared ()) {
1766
1800
os << " (shared " ;
1767
1801
}
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
+ }
1768
1812
switch (type.getKind ()) {
1769
1813
case HeapTypeKind::Func:
1770
1814
print (type.getSignature ());
@@ -1781,6 +1825,12 @@ std::ostream& TypePrinter::print(HeapType type) {
1781
1825
case HeapTypeKind::Basic:
1782
1826
WASM_UNREACHABLE (" unexpected kind" );
1783
1827
}
1828
+ if (type.getDescriptorType ()) {
1829
+ os << ' )' ;
1830
+ }
1831
+ if (type.getDescribedType ()) {
1832
+ os << ' )' ;
1833
+ }
1784
1834
if (type.isShared ()) {
1785
1835
os << ' )' ;
1786
1836
}
@@ -1927,9 +1977,18 @@ size_t RecGroupHasher::hash(HeapType type) const {
1927
1977
1928
1978
size_t RecGroupHasher::hash (const HeapTypeInfo& info) const {
1929
1979
size_t digest = wasm::hash (bool (info.supertype ));
1980
+ wasm::rehash (digest, !!info.supertype );
1930
1981
if (info.supertype ) {
1931
1982
hash_combine (digest, hash (HeapType (uintptr_t (info.supertype ))));
1932
1983
}
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
+ }
1933
1992
wasm::rehash (digest, info.isOpen );
1934
1993
wasm::rehash (digest, info.share );
1935
1994
wasm::rehash (digest, info.kind );
@@ -2051,7 +2110,7 @@ bool RecGroupEquator::eq(HeapType a, HeapType b) const {
2051
2110
}
2052
2111
2053
2112
bool RecGroupEquator::eq (const HeapTypeInfo& a, const HeapTypeInfo& b) const {
2054
- if (bool ( a.supertype ) != bool ( b.supertype ) ) {
2113
+ if (!! a.supertype != !! b.supertype ) {
2055
2114
return false ;
2056
2115
}
2057
2116
if (a.supertype ) {
@@ -2061,6 +2120,26 @@ bool RecGroupEquator::eq(const HeapTypeInfo& a, const HeapTypeInfo& b) const {
2061
2120
return false ;
2062
2121
}
2063
2122
}
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
+ }
2064
2143
if (a.isOpen != b.isOpen ) {
2065
2144
return false ;
2066
2145
}
@@ -2227,6 +2306,16 @@ void TypeBuilder::setSubType(size_t i, std::optional<HeapType> super) {
2227
2306
HeapTypeInfo* sub = impl->entries [i].info .get ();
2228
2307
sub->supertype = super ? getHeapTypeInfo (*super) : nullptr ;
2229
2308
}
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
+ }
2230
2319
2231
2320
void TypeBuilder::createRecGroup (size_t index, size_t length) {
2232
2321
assert (index <= size () && index + length <= size () && " group out of bounds" );
@@ -2382,6 +2471,20 @@ void updateReferencedHeapTypes(
2382
2471
info->supertype = getHeapTypeInfo (it->second );
2383
2472
}
2384
2473
}
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
+ }
2385
2488
}
2386
2489
2387
2490
TypeBuilder::BuildResult
0 commit comments