diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2022-08-04 17:05:54 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-05 00:05:54 +0000 |
commit | 6759371b5239efa3daa9d988455abdd14a8b18ca (patch) | |
tree | 0c3a3e371ed742bdbd790f7344ec86e8536bc167 /src/wasm/wasm-validator.cpp | |
parent | 9534e6927c41f4a6a5d06d58d00c271c9f066e9a (diff) | |
download | binaryen-6759371b5239efa3daa9d988455abdd14a8b18ca.tar.gz binaryen-6759371b5239efa3daa9d988455abdd14a8b18ca.tar.bz2 binaryen-6759371b5239efa3daa9d988455abdd14a8b18ca.zip |
Remove RTTs (#4848)
RTTs were removed from the GC spec and if they are added back in in the future,
they will be heap types rather than value types as in our implementation.
Updating our implementation to have RTTs be heap types would have been more work
than deleting them for questionable benefit since we don't know how long it will
be before they are specced again.
Diffstat (limited to 'src/wasm/wasm-validator.cpp')
-rw-r--r-- | src/wasm/wasm-validator.cpp | 143 |
1 files changed, 17 insertions, 126 deletions
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 65a910747..bc51d8b63 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -383,8 +383,6 @@ public: void visitRefTest(RefTest* curr); void visitRefCast(RefCast* curr); void visitBrOn(BrOn* curr); - void visitRttCanon(RttCanon* curr); - void visitRttSub(RttSub* curr); void visitStructNew(StructNew* curr); void visitStructGet(StructGet* curr); void visitStructSet(StructSet* curr); @@ -2338,23 +2336,12 @@ void FunctionValidator::visitRefTest(RefTest* curr) { shouldBeTrue( curr->ref->type.isRef(), curr, "ref.test ref must have ref type"); } - if (curr->rtt) { - if (curr->rtt->type != Type::unreachable) { - shouldBeTrue( - curr->rtt->type.isRtt(), curr, "ref.test rtt must have rtt type"); - } - shouldBeEqual(curr->intendedType, + shouldBeUnequal(curr->intendedType, HeapType(), curr, - "dynamic ref.test must not use intendedType field"); - } else { - shouldBeUnequal(curr->intendedType, - HeapType(), - curr, - "static ref.test must set intendedType field"); - shouldBeTrue( - !curr->intendedType.isBasic(), curr, "ref.test must test a non-basic"); - } + "static ref.test must set intendedType field"); + shouldBeTrue( + !curr->intendedType.isBasic(), curr, "ref.test must test a non-basic"); } void FunctionValidator::visitRefCast(RefCast* curr) { @@ -2364,23 +2351,12 @@ void FunctionValidator::visitRefCast(RefCast* curr) { shouldBeTrue( curr->ref->type.isRef(), curr, "ref.cast ref must have ref type"); } - if (curr->rtt) { - if (curr->rtt->type != Type::unreachable) { - shouldBeTrue( - curr->rtt->type.isRtt(), curr, "ref.cast rtt must have rtt type"); - } - shouldBeEqual(curr->intendedType, + shouldBeUnequal(curr->intendedType, HeapType(), curr, - "dynamic ref.cast must not use intendedType field"); - } else { - shouldBeUnequal(curr->intendedType, - HeapType(), - curr, - "static ref.cast must set intendedType field"); - shouldBeTrue( - !curr->intendedType.isBasic(), curr, "ref.cast must cast to a non-basic"); - } + "static ref.cast must set intendedType field"); + shouldBeTrue( + !curr->intendedType.isBasic(), curr, "ref.cast must cast to a non-basic"); } void FunctionValidator::visitBrOn(BrOn* curr) { @@ -2392,28 +2368,14 @@ void FunctionValidator::visitBrOn(BrOn* curr) { curr->ref->type.isRef(), curr, "br_on_cast ref must have ref type"); } if (curr->op == BrOnCast || curr->op == BrOnCastFail) { - if (curr->rtt) { - // Note that an unreachable rtt is not supported: the text and binary - // formats do not provide the type, so if it's unreachable we should not - // even create a br_on_cast in such a case, as we'd have no idea what it - // casts to. - shouldBeTrue( - curr->rtt->type.isRtt(), curr, "br_on_cast rtt must have rtt type"); - shouldBeEqual(curr->intendedType, + shouldBeUnequal(curr->intendedType, HeapType(), curr, - "dynamic br_on_cast* must not use intendedType field"); - } else { - shouldBeUnequal(curr->intendedType, - HeapType(), - curr, - "static br_on_cast* must set intendedType field"); - shouldBeTrue(!curr->intendedType.isBasic(), - curr, - "br_on_cast* must cast to a non-basic"); - } + "static br_on_cast* must set intendedType field"); + shouldBeTrue(!curr->intendedType.isBasic(), + curr, + "br_on_cast* must cast to a non-basic"); } else { - shouldBeTrue(curr->rtt == nullptr, curr, "non-cast BrOn must not have rtt"); shouldBeEqual(curr->intendedType, HeapType(), curr, @@ -2422,38 +2384,6 @@ void FunctionValidator::visitBrOn(BrOn* curr) { noteBreak(curr->name, curr->getSentType(), curr); } -void FunctionValidator::visitRttCanon(RttCanon* curr) { - shouldBeTrue( - getModule()->features.hasGC(), curr, "rtt.canon requires gc to be enabled"); - shouldBeTrue(curr->type.isRtt(), curr, "rtt.canon must have RTT type"); - auto rtt = curr->type.getRtt(); - shouldBeEqual(rtt.depth, - Index(curr->type.getHeapType().getDepth()), - curr, - "rtt.canon must have the depth of its heap type"); -} - -void FunctionValidator::visitRttSub(RttSub* curr) { - shouldBeTrue( - getModule()->features.hasGC(), curr, "rtt.sub requires gc to be enabled"); - shouldBeTrue(curr->type.isRtt(), curr, "rtt.sub must have RTT type"); - if (curr->parent->type != Type::unreachable) { - shouldBeTrue( - curr->parent->type.isRtt(), curr, "rtt.sub parent must have RTT type"); - auto parentRtt = curr->parent->type.getRtt(); - auto rtt = curr->type.getRtt(); - if (rtt.hasDepth() && parentRtt.hasDepth()) { - shouldBeEqual(rtt.depth, - parentRtt.depth + 1, - curr, - "rtt.canon has a depth of 1 over the parent"); - } - shouldBeTrue(HeapType::isSubType(rtt.heapType, parentRtt.heapType), - curr, - "rtt.sub parent must be a supertype"); - } -} - void FunctionValidator::visitStructNew(StructNew* curr) { shouldBeTrue(getModule()->features.hasGC(), curr, @@ -2461,19 +2391,7 @@ void FunctionValidator::visitStructNew(StructNew* curr) { if (curr->type == Type::unreachable) { return; } - if (curr->rtt) { - if (!shouldBeTrue( - curr->rtt->type.isRtt(), curr, "struct.new rtt must be rtt")) { - return; - } - } auto heapType = curr->type.getHeapType(); - if (curr->rtt) { - shouldBeEqual(curr->rtt->type.getHeapType(), - heapType, - curr, - "struct.new heap type must match rtt"); - } if (!shouldBeTrue( heapType.isStruct(), curr, "struct.new heap type must be struct")) { return; @@ -2565,19 +2483,7 @@ void FunctionValidator::visitArrayNew(ArrayNew* curr) { if (curr->type == Type::unreachable) { return; } - if (curr->rtt) { - if (!shouldBeTrue( - curr->rtt->type.isRtt(), curr, "array.new rtt must be rtt")) { - return; - } - } auto heapType = curr->type.getHeapType(); - if (curr->rtt) { - shouldBeEqual(curr->rtt->type.getHeapType(), - heapType, - curr, - "array.new heap type must match rtt"); - } if (!shouldBeTrue( heapType.isArray(), curr, "array.new heap type must be array")) { return; @@ -2607,19 +2513,7 @@ void FunctionValidator::visitArrayInit(ArrayInit* curr) { if (curr->type == Type::unreachable) { return; } - if (curr->rtt) { - if (!shouldBeTrue( - curr->rtt->type.isRtt(), curr, "array.init rtt must be rtt")) { - return; - } - } auto heapType = curr->type.getHeapType(); - if (curr->rtt) { - shouldBeEqual(curr->rtt->type.getHeapType(), - heapType, - curr, - "array.init heap type must match rtt"); - } if (!shouldBeTrue( heapType.isArray(), curr, "array.init heap type must be array")) { return; @@ -2716,9 +2610,7 @@ void FunctionValidator::visitFunction(Function* curr) { } for (const auto& var : curr->vars) { features |= var.getFeatures(); - bool valid = getModule()->features.hasGCNNLocals() - ? var.isDefaultableOrNonNullable() - : var.isDefaultable(); + bool valid = getModule()->features.hasGCNNLocals() || var.isDefaultable(); shouldBeTrue(valid, var, "vars must be defaultable"); } shouldBeTrue(features <= getModule()->features, @@ -3167,10 +3059,9 @@ static void validateTables(Module& module, ValidationInfo& info) { for (auto& segment : module.elementSegments) { // Since element segment items need to be constant expressions, that leaves - // us with ref.null, ref.func and global.get. The GC proposal adds rtt.canon - // and rtt.sub to the list, but Binaryen doesn't consider RTTs as reference- - // types yet. As a result, the only possible type for element segments will - // be function references. + // us with ref.null, ref.func and global.get. As a result, the only possible + // type for element segments will be function references. + // TODO: This is not true! Allow GC data here (#4846). info.shouldBeTrue(segment->type.isFunction(), "elem", "element segment type must be of function type."); |