diff --git a/lib/fizzy/execute.cpp b/lib/fizzy/execute.cpp index c3a5e63af..12e01a89e 100644 --- a/lib/fizzy/execute.cpp +++ b/lib/fizzy/execute.cpp @@ -540,19 +540,18 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args, while (true) { - const auto instruction = *pc++; + const auto instruction = *pc; switch (instruction) { case Instr::unreachable: goto trap; - case Instr::nop: - case Instr::block: - case Instr::loop: - break; case Instr::if_: { if (stack.pop().as() != 0) + { immediates += 2 * sizeof(uint32_t); // Skip the immediates for else instruction. + break; + } else { const auto target_pc = read(immediates); @@ -560,8 +559,8 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args, pc = code.instructions.data() + target_pc; immediates = code.immediates.data() + target_imm; + continue; } - break; } case Instr::else_: { @@ -573,18 +572,16 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args, pc = code.instructions.data() + target_pc; immediates = code.immediates.data() + target_imm; - break; + continue; } case Instr::end: { - // End execution if it's a final end instruction. - if (pc == &code.instructions[code.instructions.size()]) - goto end; - break; + assert(pc == &code.instructions[code.instructions.size() - 1]); + goto end; } case Instr::br: case Instr::br_if: - case Instr::return_: + case Instr::return_: // TODO: Replace return with br { const auto arity = read(immediates); @@ -596,7 +593,7 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args, } branch(code, stack, pc, immediates, arity); - break; + continue; } case Instr::br_table: { @@ -611,7 +608,7 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args, immediates += label_idx_offset; branch(code, stack, pc, immediates, arity); - break; + continue; } case Instr::call: { @@ -1557,10 +1554,12 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args, default: FIZZY_UNREACHABLE(); } + + ++pc; } end: - assert(pc == &code.instructions[code.instructions.size()]); // End of code must be reached. + assert(pc == &code.instructions[code.instructions.size() - 1]); // End of code must be reached. assert(stack.size() == instance.module->get_function_type(func_idx).outputs.size()); return stack.size() != 0 ? ExecutionResult{stack.top()} : Void; diff --git a/lib/fizzy/parser_expr.cpp b/lib/fizzy/parser_expr.cpp index 28bc47a00..a658f1373 100644 --- a/lib/fizzy/parser_expr.cpp +++ b/lib/fizzy/parser_expr.cpp @@ -333,6 +333,8 @@ parser_result parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f } case Instr::nop: + continue; + case Instr::i32_eqz: case Instr::i32_eq: case Instr::i32_ne: @@ -466,7 +468,7 @@ parser_result parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f // Push label with immediates offset after arity. control_stack.emplace(Instr::block, block_type, static_cast(operand_stack.size()), code.instructions.size(), code.immediates.size()); - break; + continue; } case Instr::loop: @@ -476,7 +478,7 @@ parser_result parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f control_stack.emplace(Instr::loop, loop_type, static_cast(operand_stack.size()), code.instructions.size(), code.immediates.size()); - break; + continue; } case Instr::if_: @@ -538,9 +540,7 @@ parser_result parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f // In case it's an outermost implicit function block, // we want br to jump to the final end of the function. // Otherwise jump to the next instruction after block's end. - const auto target_pc = control_stack.size() == 1 ? - static_cast(code.instructions.size()) : - static_cast(code.instructions.size() + 1); + const auto target_pc = static_cast(code.instructions.size()); const auto target_imm = static_cast(code.immediates.size()); if (frame.instruction == Instr::if_ || frame.instruction == Instr::else_) @@ -569,10 +569,14 @@ parser_result parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f control_stack.pop(); // Pop the current frame. if (control_stack.empty()) + { continue_parsing = false; - else if (frame_type.has_value()) + break; + } + + if (frame_type.has_value()) push_operand(operand_stack, *frame_type); - break; + continue; } case Instr::br: