| 81 | } |
| 82 | |
| 83 | Expect<void> Executor::execute(Runtime::StackManager &StackMgr, |
| 84 | const AST::InstrView::iterator Start, |
| 85 | const AST::InstrView::iterator End) { |
| 86 | AST::InstrView::iterator PC = Start; |
| 87 | AST::InstrView::iterator PCEnd = End; |
| 88 | |
| 89 | auto Dispatch = [this, &PC, &StackMgr]() -> Expect<void> { |
| 90 | const AST::Instruction &Instr = *PC; |
| 91 | switch (Instr.getOpCode()) { |
| 92 | // Control instructions |
| 93 | case OpCode::Unreachable: |
| 94 | spdlog::error(ErrCode::Value::Unreachable); |
| 95 | spdlog::error( |
| 96 | ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset())); |
| 97 | return Unexpect(ErrCode::Value::Unreachable); |
| 98 | case OpCode::Nop: |
| 99 | return {}; |
| 100 | case OpCode::Block: |
| 101 | return {}; |
| 102 | case OpCode::Loop: |
| 103 | return {}; |
| 104 | case OpCode::If: |
| 105 | return runIfElseOp(StackMgr, Instr, PC); |
| 106 | case OpCode::Else: |
| 107 | if (Stat && Conf.getStatisticsConfigure().isCostMeasuring()) { |
| 108 | // Reach here means end of if-statement. |
| 109 | if (unlikely(!Stat->subInstrCost(Instr.getOpCode()))) { |
| 110 | spdlog::error(ErrCode::Value::CostLimitExceeded); |
| 111 | spdlog::error( |
| 112 | ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset())); |
| 113 | return Unexpect(ErrCode::Value::CostLimitExceeded); |
| 114 | } |
| 115 | if (unlikely(!Stat->addInstrCost(OpCode::End))) { |
| 116 | spdlog::error(ErrCode::Value::CostLimitExceeded); |
| 117 | spdlog::error( |
| 118 | ErrInfo::InfoInstruction(Instr.getOpCode(), Instr.getOffset())); |
| 119 | return Unexpect(ErrCode::Value::CostLimitExceeded); |
| 120 | } |
| 121 | } |
| 122 | PC += PC->getJumpEnd() - 1; |
| 123 | return {}; |
| 124 | case OpCode::End: |
| 125 | PC = StackMgr.maybePopFrameOrHandler(PC); |
| 126 | return {}; |
| 127 | case OpCode::Throw: |
| 128 | return runThrowOp(StackMgr, Instr, PC); |
| 129 | case OpCode::Throw_ref: |
| 130 | return runThrowRefOp(StackMgr, Instr, PC); |
| 131 | case OpCode::Br: |
| 132 | return runBrOp(StackMgr, Instr, PC); |
| 133 | case OpCode::Br_if: |
| 134 | return runBrIfOp(StackMgr, Instr, PC); |
| 135 | case OpCode::Br_table: |
| 136 | return runBrTableOp(StackMgr, Instr, PC); |
| 137 | case OpCode::Br_on_null: |
| 138 | return runBrOnNullOp(StackMgr, Instr, PC); |
| 139 | case OpCode::Br_on_non_null: |
| 140 | return runBrOnNonNullOp(StackMgr, Instr, PC); |
no test coverage detected