/* * Copyright (c) 2021, Ali Mohammad Pur * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include #include #include #include namespace Wasm { #define TRAP_IF_NOT(x) \ do { \ if (trap_if_not(x)) { \ dbgln_if(WASM_TRACE_DEBUG, "Trapped because {} failed, at line {}", #x, __LINE__); \ return; \ } \ } while (false) #define TRAP_IF_NOT_NORETURN(x) \ do { \ if (trap_if_not(x)) { \ dbgln_if(WASM_TRACE_DEBUG, "Trapped because {} failed, at line {}", #x, __LINE__); \ } \ } while (false) void BytecodeInterpreter::interpret(Configuration& configuration) { m_do_trap = false; auto& instructions = configuration.frame().expression().instructions(); auto max_ip_value = InstructionPointer { instructions.size() }; auto& current_ip_value = configuration.ip(); while (current_ip_value < max_ip_value) { auto& instruction = instructions[current_ip_value.value()]; auto old_ip = current_ip_value; interpret(configuration, current_ip_value, instruction); if (m_do_trap) return; if (current_ip_value == old_ip) // If no jump occurred ++current_ip_value; } } void BytecodeInterpreter::branch_to_label(Configuration& configuration, LabelIndex index) { dbgln_if(WASM_TRACE_DEBUG, "Branch to label with index {}...", index.value()); auto label = configuration.nth_label(index.value()); TRAP_IF_NOT(label.has_value()); dbgln_if(WASM_TRACE_DEBUG, "...which is actually IP {}, and has {} result(s)", label->continuation().value(), label->arity()); auto results = pop_values(configuration, label->arity()); size_t drop_count = index.value() + 1; for (; !configuration.stack().is_empty();) { auto& entry = configuration.stack().peek(); if (entry.has