diff --git a/Tests/LibWasm/test-wasm.cpp b/Tests/LibWasm/test-wasm.cpp index 086203251b9..7b6f3c6aa5c 100644 --- a/Tests/LibWasm/test-wasm.cpp +++ b/Tests/LibWasm/test-wasm.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include TEST_ROOT("Userland/Libraries/LibWasm/Tests"); diff --git a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp index bb7315afd87..80ec5a619c2 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp +++ b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp @@ -4,9 +4,10 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include "Interpreter.h" #include +#include #include +#include #include namespace Wasm { diff --git a/Userland/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.cpp b/Userland/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.cpp new file mode 100644 index 00000000000..699aed649a3 --- /dev/null +++ b/Userland/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.cpp @@ -0,0 +1,999 @@ +/* + * 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