@@ -1464,6 +1464,20 @@ std::ostream& operator<<(std::ostream& os, TypeBuilder::ErrorReason reason) {
1464
1464
return os << " Continuation has invalid function type" ;
1465
1465
case TypeBuilder::ErrorReason::InvalidUnsharedField:
1466
1466
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" ;
1467
1481
}
1468
1482
WASM_UNREACHABLE (" Unexpected error reason" );
1469
1483
}
@@ -2370,6 +2384,25 @@ bool isValidSupertype(const HeapTypeInfo& sub, const HeapTypeInfo& super) {
2370
2384
if (sub.kind != super.kind ) {
2371
2385
return false ;
2372
2386
}
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
+ }
2373
2406
SubTyper typer;
2374
2407
switch (sub.kind ) {
2375
2408
case HeapTypeKind::Func:
@@ -2399,12 +2432,38 @@ validateType(HeapTypeInfo& info, std::unordered_set<HeapType>& seenTypes) {
2399
2432
return TypeBuilder::ErrorReason::InvalidSupertype;
2400
2433
}
2401
2434
}
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
+ }
2402
2455
if (info.isContinuation ()) {
2403
2456
if (!info.continuation .type .isSignature ()) {
2404
2457
return TypeBuilder::ErrorReason::InvalidFuncType;
2405
2458
}
2406
2459
}
2407
2460
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
+ }
2408
2467
switch (info.kind ) {
2409
2468
case HeapTypeKind::Func:
2410
2469
// TODO: Figure out and enforce shared function rules.
0 commit comments