summaryrefslogtreecommitdiff
path: root/src/passes/Print.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/Print.cpp')
-rw-r--r--src/passes/Print.cpp120
1 files changed, 93 insertions, 27 deletions
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 812a69692..0bf61e784 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -1162,6 +1162,23 @@ struct PrintExpressionContents
break;
}
}
+ void visitTry(Try* curr) {
+ printMedium(o, "try");
+ if (isConcreteType(curr->type)) {
+ o << " (result " << printType(curr->type) << ')';
+ }
+ }
+ void visitThrow(Throw* curr) {
+ printMedium(o, "throw ");
+ printName(curr->event, o);
+ }
+ void visitRethrow(Rethrow* curr) { printMedium(o, "rethrow"); }
+ void visitBrOnExn(BrOnExn* curr) {
+ printMedium(o, "br_on_exn ");
+ printName(curr->name, o);
+ o << " ";
+ printName(curr->event, o);
+ }
void visitNop(Nop* curr) { printMinor(o, "nop"); }
void visitUnreachable(Unreachable* curr) { printMinor(o, "unreachable"); }
void visitPush(Push* curr) { prepareColor(o) << "push"; }
@@ -1260,6 +1277,20 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> {
o << maybeNewLine;
}
+ // loop, if, and try can contain implicit blocks. But they are not needed to
+ // be printed in some cases.
+ void maybePrintImplicitBlock(Expression* curr, bool allowMultipleInsts) {
+ auto block = curr->dynCast<Block>();
+ if (!full && block && block->name.isNull() &&
+ (allowMultipleInsts || block->list.size() == 1)) {
+ for (auto expression : block->list) {
+ printFullLine(expression);
+ }
+ } else {
+ printFullLine(curr);
+ }
+ }
+
void visitBlock(Block* curr) {
// special-case Block, because Block nesting (in their first element) can be
// incredibly deep
@@ -1319,22 +1350,9 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> {
PrintExpressionContents(currFunction, o).visit(curr);
incIndent();
printFullLine(curr->condition);
- // ifTrue and False have implict blocks, avoid printing them if possible
- if (!full && curr->ifTrue->is<Block>() &&
- curr->ifTrue->dynCast<Block>()->name.isNull() &&
- curr->ifTrue->dynCast<Block>()->list.size() == 1) {
- printFullLine(curr->ifTrue->dynCast<Block>()->list.back());
- } else {
- printFullLine(curr->ifTrue);
- }
+ maybePrintImplicitBlock(curr->ifTrue, false);
if (curr->ifFalse) {
- if (!full && curr->ifFalse->is<Block>() &&
- curr->ifFalse->dynCast<Block>()->name.isNull() &&
- curr->ifFalse->dynCast<Block>()->list.size() == 1) {
- printFullLine(curr->ifFalse->dynCast<Block>()->list.back());
- } else {
- printFullLine(curr->ifFalse);
- }
+ maybePrintImplicitBlock(curr->ifFalse, false);
}
decIndent();
if (full) {
@@ -1345,16 +1363,7 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> {
o << '(';
PrintExpressionContents(currFunction, o).visit(curr);
incIndent();
- auto block = curr->body->dynCast<Block>();
- if (!full && block && block->name.isNull()) {
- // wasm spec has loops containing children directly, while our ast
- // has a single child for simplicity. print out the optimal form.
- for (auto expression : block->list) {
- printFullLine(expression);
- }
- } else {
- printFullLine(curr->body);
- }
+ maybePrintImplicitBlock(curr->body, true);
decIndent();
if (full) {
o << " ;; end loop";
@@ -1631,6 +1640,54 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> {
}
}
}
+ // try-catch-end is written in the folded wast format as
+ // (try
+ // ...
+ // (catch
+ // ...
+ // )
+ // )
+ // The parenthesis wrapping 'catch' is just a syntax and does not affect
+ // nested depths of instructions within.
+ void visitTry(Try* curr) {
+ o << '(';
+ PrintExpressionContents(currFunction, o).visit(curr);
+ incIndent();
+ maybePrintImplicitBlock(curr->body, true);
+ doIndent(o, indent);
+ o << "(catch";
+ incIndent();
+ maybePrintImplicitBlock(curr->catchBody, true);
+ decIndent();
+ o << "\n";
+ decIndent();
+ if (full) {
+ o << " ;; end try";
+ }
+ }
+ void visitThrow(Throw* curr) {
+ o << '(';
+ PrintExpressionContents(currFunction, o).visit(curr);
+ incIndent();
+ for (auto operand : curr->operands) {
+ printFullLine(operand);
+ }
+ decIndent();
+ }
+ void visitRethrow(Rethrow* curr) {
+ o << '(';
+ PrintExpressionContents(currFunction, o).visit(curr);
+ incIndent();
+ printFullLine(curr->exnref);
+ decIndent();
+ }
+ void visitBrOnExn(BrOnExn* curr) {
+ o << '(';
+ PrintExpressionContents(currFunction, o).visit(curr);
+ incIndent();
+ printFullLine(curr->exnref);
+ decIndent();
+ }
void visitNop(Nop* curr) {
o << '(';
PrintExpressionContents(currFunction, o).visit(curr);
@@ -2198,7 +2255,8 @@ WasmPrinter::printStackIR(StackIR* ir, std::ostream& o, Function* func) {
}
case StackInst::BlockBegin:
case StackInst::IfBegin:
- case StackInst::LoopBegin: {
+ case StackInst::LoopBegin:
+ case StackInst::TryBegin: {
doIndent();
PrintExpressionContents(func, o).visit(inst->origin);
indent++;
@@ -2206,7 +2264,8 @@ WasmPrinter::printStackIR(StackIR* ir, std::ostream& o, Function* func) {
}
case StackInst::BlockEnd:
case StackInst::IfEnd:
- case StackInst::LoopEnd: {
+ case StackInst::LoopEnd:
+ case StackInst::TryEnd: {
indent--;
doIndent();
o << "end";
@@ -2219,6 +2278,13 @@ WasmPrinter::printStackIR(StackIR* ir, std::ostream& o, Function* func) {
indent++;
break;
}
+ case StackInst::Catch: {
+ indent--;
+ doIndent();
+ o << "catch";
+ indent++;
+ break;
+ }
default:
WASM_UNREACHABLE();
}