diff options
author | Alon Zakai <azakai@google.com> | 2021-01-28 22:09:31 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-28 14:09:31 -0800 |
commit | 6299471584ce74d365526e33ed0a662bd2ee3490 (patch) | |
tree | d3aa2132d0897ea84bacab31c4e424780009efad /src/wasm/wasm-validator.cpp | |
parent | 53c471a445ef26eac7befc3f3a5e0a53870df8cb (diff) | |
download | binaryen-6299471584ce74d365526e33ed0a662bd2ee3490.tar.gz binaryen-6299471584ce74d365526e33ed0a662bd2ee3490.tar.bz2 binaryen-6299471584ce74d365526e33ed0a662bd2ee3490.zip |
[GC] Add br_on_func/data/i31 (#3525)
This expands the existing BrOnCast into BrOn that can also handle the
func/data/i31 variants. This is not as elegant as RefIs / RefAs in that BrOnCast
has an extra rtt field, but I think it is still the best option. We already have optional
fields on Break (the value and condition), so making rtt optional is not odd. And
it allows us to share all the behavior of br_on_* which aside from the cast or the
check itself, is identical - returning the value if the branch is not taken, etc.
Diffstat (limited to 'src/wasm/wasm-validator.cpp')
-rw-r--r-- | src/wasm/wasm-validator.cpp | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index c6d0d9fe7..6a1b72476 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -344,7 +344,7 @@ public: void visitI31Get(I31Get* curr); void visitRefTest(RefTest* curr); void visitRefCast(RefCast* curr); - void visitBrOnCast(BrOnCast* curr); + void visitBrOn(BrOn* curr); void visitRttCanon(RttCanon* curr); void visitRttSub(RttSub* curr); void visitStructNew(StructNew* curr); @@ -2207,7 +2207,7 @@ void FunctionValidator::visitRefCast(RefCast* curr) { } } -void FunctionValidator::visitBrOnCast(BrOnCast* curr) { +void FunctionValidator::visitBrOn(BrOn* curr) { shouldBeTrue(getModule()->features.hasGC(), curr, "br_on_cast requires gc to be enabled"); @@ -2215,12 +2215,17 @@ void FunctionValidator::visitBrOnCast(BrOnCast* curr) { shouldBeTrue( curr->ref->type.isRef(), curr, "br_on_cast ref must have ref type"); } - // 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"); - noteBreak(curr->name, curr->getCastType(), curr); + if (curr->op == BrOnCast) { + // 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"); + noteBreak(curr->name, curr->getCastType(), curr); + } else { + shouldBeTrue(curr->rtt == nullptr, curr, "non-cast BrOn must not have rtt"); + } } void FunctionValidator::visitRttCanon(RttCanon* curr) { |