@@ -1464,6 +1464,20 @@ std::ostream& operator<<(std::ostream& os, TypeBuilder::ErrorReason reason) {
14641464 return os << " Continuation has invalid function type" ;
14651465 case TypeBuilder::ErrorReason::InvalidUnsharedField:
14661466 return os << " Heap type has an invalid unshared field" ;
1467+ case TypeBuilder::ErrorReason::NonStructDescribes:
1468+ return os << " Describes clause on a non-struct type" ;
1469+ case TypeBuilder::ErrorReason::ForwardDescribesReference:
1470+ return os << " Describes clause is a forward reference" ;
1471+ case TypeBuilder::ErrorReason::MismatchedDescribes:
1472+ return os << " Described type is not a matching descriptor" ;
1473+ case TypeBuilder::ErrorReason::NonStructDescriptor:
1474+ return os << " Descriptor clause on a non-struct type" ;
1475+ case TypeBuilder::ErrorReason::MismatchedDescriptor:
1476+ return os << " Descriptor type does not describe heap type" ;
1477+ case TypeBuilder::ErrorReason::InvalidUnsharedDescriptor:
1478+ return os << " Heap type has an invalid unshared descriptor" ;
1479+ case TypeBuilder::ErrorReason::InvalidUnsharedDescribes:
1480+ return os << " Heap type describes an invalid unshared type" ;
14671481 }
14681482 WASM_UNREACHABLE (" Unexpected error reason" );
14691483}
@@ -2370,6 +2384,25 @@ bool isValidSupertype(const HeapTypeInfo& sub, const HeapTypeInfo& super) {
23702384 if (sub.kind != super.kind ) {
23712385 return false ;
23722386 }
2387+ if (sub.descriptor ) {
2388+ // A supertype of a type with a (descriptor $x) must either not have a
2389+ // descriptor or have a (descriptor $y) where $y is the declared supertype
2390+ // of $x.
2391+ if (super.descriptor && sub.descriptor ->supertype != super.descriptor ) {
2392+ return false ;
2393+ }
2394+ } else {
2395+ // A supertype of a type without a descriptor must also not have a
2396+ // descriptor.
2397+ if (super.descriptor ) {
2398+ return false ;
2399+ }
2400+ }
2401+ // A supertype of a type must have a describes clause iff the type has a
2402+ // describes clause.
2403+ if (bool (sub.described ) != bool (super.described )) {
2404+ return false ;
2405+ }
23732406 SubTyper typer;
23742407 switch (sub.kind ) {
23752408 case HeapTypeKind::Func:
@@ -2399,12 +2432,38 @@ validateType(HeapTypeInfo& info, std::unordered_set<HeapType>& seenTypes) {
23992432 return TypeBuilder::ErrorReason::InvalidSupertype;
24002433 }
24012434 }
2435+ if (auto * desc = info.described ) {
2436+ if (info.kind != HeapTypeKind::Struct) {
2437+ return TypeBuilder::ErrorReason::NonStructDescribes;
2438+ }
2439+ assert (desc->isTemp && " unexpected canonical described type" );
2440+ if (!seenTypes.count (HeapType (uintptr_t (desc)))) {
2441+ return TypeBuilder::ErrorReason::ForwardDescribesReference;
2442+ }
2443+ if (desc->descriptor != &info) {
2444+ return TypeBuilder::ErrorReason::MismatchedDescribes;
2445+ }
2446+ }
2447+ if (auto * desc = info.descriptor ) {
2448+ if (info.kind != HeapTypeKind::Struct) {
2449+ return TypeBuilder::ErrorReason::NonStructDescriptor;
2450+ }
2451+ if (desc->described != &info) {
2452+ return TypeBuilder::ErrorReason::MismatchedDescriptor;
2453+ }
2454+ }
24022455 if (info.isContinuation ()) {
24032456 if (!info.continuation .type .isSignature ()) {
24042457 return TypeBuilder::ErrorReason::InvalidFuncType;
24052458 }
24062459 }
24072460 if (info.share == Shared) {
2461+ if (info.described && info.described ->share != Shared) {
2462+ return TypeBuilder::ErrorReason::InvalidUnsharedDescribes;
2463+ }
2464+ if (info.descriptor && info.descriptor ->share != Shared) {
2465+ return TypeBuilder::ErrorReason::InvalidUnsharedDescriptor;
2466+ }
24082467 switch (info.kind ) {
24092468 case HeapTypeKind::Func:
24102469 // TODO: Figure out and enforce shared function rules.
0 commit comments