diff options
author | Alon Zakai <azakai@google.com> | 2021-05-10 20:06:53 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-10 20:06:53 -0700 |
commit | 09052c055c07ec5a1385cd5c142ff4d8534f1d1c (patch) | |
tree | 13302b7379e425d9babbf440c6eb3a31740fce14 /src | |
parent | 5670de328320a554d4b6fa20b2fde37b4f337ce3 (diff) | |
download | binaryen-09052c055c07ec5a1385cd5c142ff4d8534f1d1c.tar.gz binaryen-09052c055c07ec5a1385cd5c142ff4d8534f1d1c.tar.bz2 binaryen-09052c055c07ec5a1385cd5c142ff4d8534f1d1c.zip |
[Wasm GC] Fix StructSet::finalize on an unreachable value (#3874)
Also fix printing of unreachable StructSets, which must handle the case
of an unreachable reference, which means we do not know the RTT,
and so we must print a replacement for the StructSet somehow. Emit a
block with drops, fixing the old behavior which was missing the drops.
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/Print.cpp | 29 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 2 |
2 files changed, 29 insertions, 2 deletions
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 1392ccb6f..ef78bf582 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -1926,7 +1926,7 @@ struct PrintExpressionContents // where if the ref is unreachable, we don't know what heap type to print), // then print the children in a block, which is good enough as this // instruction is never reached anyhow. - printMedium(o, "block "); + printMedium(o, "block"); } void printFieldName(HeapType type, Index index) { processFieldName(wasm, type, index, [&](Name name) { @@ -2346,6 +2346,33 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> { o << " ;; end try"; } } + void printUnreachableReplacement(Expression* curr) { + // See the parallel function in PrintExpressionContents for background. + // + // Emit a block with drops of the children. + o << "(block"; + incIndent(); + for (auto* child : ChildIterator(curr)) { + Drop drop; + drop.value = child; + printFullLine(&drop); + } + decIndent(); + } + void visitStructSet(StructSet* curr) { + if (curr->ref->type == Type::unreachable) { + printUnreachableReplacement(curr); + return; + } + visitExpression(curr); + } + void visitStructGet(StructGet* curr) { + if (curr->ref->type == Type::unreachable) { + printUnreachableReplacement(curr); + return; + } + visitExpression(curr); + } // Module-level visitors void handleSignature(Signature curr, Name name = Name()) { o << "(func"; diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 410ba0573..69464e73f 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -977,7 +977,7 @@ void StructGet::finalize() { } void StructSet::finalize() { - if (ref->type == Type::unreachable) { + if (ref->type == Type::unreachable || value->type == Type::unreachable) { type = Type::unreachable; } else { type = Type::none; |