diff options
Diffstat (limited to 'src/wasm-stack.h')
-rw-r--r-- | src/wasm-stack.h | 54 |
1 files changed, 52 insertions, 2 deletions
diff --git a/src/wasm-stack.h b/src/wasm-stack.h index 64718b7b2..562a00684 100644 --- a/src/wasm-stack.h +++ b/src/wasm-stack.h @@ -67,6 +67,9 @@ public: IfEnd, // the ending of a if LoopBegin, // the beginning of a loop LoopEnd, // the ending of a loop + TryBegin, // the beginning of a try + Catch, // the catch within a try + TryEnd // the ending of a try } op; Expression* origin; // the expression this originates from @@ -115,6 +118,10 @@ public: void visitSelect(Select* curr); void visitReturn(Return* curr); void visitHost(Host* curr); + void visitTry(Try* curr); + void visitThrow(Throw* curr); + void visitRethrow(Rethrow* curr); + void visitBrOnExn(BrOnExn* curr); void visitNop(Nop* curr); void visitUnreachable(Unreachable* curr); void visitDrop(Drop* curr); @@ -122,7 +129,8 @@ public: void visitPop(Pop* curr); void emitIfElse(); - void emitScopeEnd(); // emit an end at the end of a block/loop/if + void emitCatch(); + void emitScopeEnd(); // emit an end at the end of a block/loop/if/try void emitFunctionEnd(); // emit an end at the end of a function void emitUnreachable(); void mapLocalsAndEmitHeader(); @@ -185,6 +193,10 @@ public: void visitSelect(Select* curr); void visitReturn(Return* curr); void visitHost(Host* curr); + void visitTry(Try* curr); + void visitThrow(Throw* curr); + void visitRethrow(Rethrow* curr); + void visitBrOnExn(BrOnExn* curr); void visitNop(Nop* curr); void visitUnreachable(Unreachable* curr); void visitDrop(Drop* curr); @@ -198,6 +210,7 @@ private: void emit(Expression* curr) { static_cast<SubType*>(this)->emit(curr); } void emitHeader() { static_cast<SubType*>(this)->emitHeader(); } void emitIfElse(If* curr) { static_cast<SubType*>(this)->emitIfElse(curr); } + void emitCatch(Try* curr) { static_cast<SubType*>(this)->emitCatch(curr); } void emitScopeEnd(Expression* curr) { static_cast<SubType*>(this)->emitScopeEnd(curr); } @@ -305,7 +318,6 @@ template<typename SubType> void BinaryenIRWriter<SubType>::visitIf(If* curr) { return; } emit(curr); - // TODO: emit block contents directly, if possible visitPossibleBlockContents(curr->ifTrue); if (curr->ifFalse) { @@ -657,6 +669,40 @@ void BinaryenIRWriter<SubType>::visitHost(Host* curr) { emit(curr); } +template<typename SubType> void BinaryenIRWriter<SubType>::visitTry(Try* curr) { + emit(curr); + visitPossibleBlockContents(curr->body); + emitCatch(curr); + visitPossibleBlockContents(curr->catchBody); + emitScopeEnd(curr); + if (curr->type == unreachable) { + emitUnreachable(); + } +} + +template<typename SubType> +void BinaryenIRWriter<SubType>::visitThrow(Throw* curr) { + for (auto* operand : curr->operands) { + visit(operand); + } + emit(curr); +} + +template<typename SubType> +void BinaryenIRWriter<SubType>::visitRethrow(Rethrow* curr) { + visit(curr->exnref); + emit(curr); +} + +template<typename SubType> +void BinaryenIRWriter<SubType>::visitBrOnExn(BrOnExn* curr) { + visit(curr->exnref); + emit(curr); + if (curr->type == unreachable) { + emitUnreachable(); + } +} + template<typename SubType> void BinaryenIRWriter<SubType>::visitNop(Nop* curr) { emit(curr); } @@ -707,6 +753,7 @@ public: writer.mapLocalsAndEmitHeader(); } void emitIfElse(If* curr) { writer.emitIfElse(); } + void emitCatch(Try* curr) { writer.emitCatch(); } void emitScopeEnd(Expression* curr) { writer.emitScopeEnd(); } void emitFunctionEnd() { if (func->epilogLocation.size()) { @@ -740,6 +787,9 @@ public: void emitIfElse(If* curr) { stackIR.push_back(makeStackInst(StackInst::IfElse, curr)); } + void emitCatch(Try* curr) { + stackIR.push_back(makeStackInst(StackInst::Catch, curr)); + } void emitFunctionEnd() {} void emitUnreachable() { stackIR.push_back(makeStackInst(Builder(allocator).makeUnreachable())); |