/* * Copyright (c) 2021, Ali Mohammad Pur * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include namespace Wasm { struct Interpreter { virtual ~Interpreter() = default; virtual void interpret(Configuration&) = 0; virtual bool did_trap() const = 0; virtual void clear_trap() = 0; }; struct BytecodeInterpreter : public Interpreter { virtual void interpret(Configuration&) override; virtual ~BytecodeInterpreter() override = default; virtual bool did_trap() const override { return m_do_trap; } virtual void clear_trap() override { m_do_trap = false; } struct CallFrameHandle { explicit CallFrameHandle(BytecodeInterpreter& interpreter, Configuration& configuration) : m_configuration_handle(configuration) , m_interpreter(interpreter) { } ~CallFrameHandle() = default; Configuration::CallFrameHandle m_configuration_handle; BytecodeInterpreter& m_interpreter; }; protected: virtual void interpret(Configuration&, InstructionPointer&, const Instruction&); void branch_to_label(Configuration&, LabelIndex); template void load_and_push(Configuration&, const Instruction&); void store_to_memory(Configuration&, const Instruction&, ReadonlyBytes data); void call_address(Configuration&, FunctionAddress); template MakeUnsigned checked_unsigned_truncate(V); template MakeSigned checked_signed_truncate(V); template T read_value(ReadonlyBytes data); Vector pop_values(Configuration& configuration, size_t count); bool trap_if_not(bool value) { if (!value) m_do_trap = true; return m_do_trap; } bool m_do_trap { false }; }; struct DebuggerBytecodeInterpreter : public BytecodeInterpreter { virtual ~DebuggerBytecodeInterpreter() override = default; Function pre_interpret_hook; Function post_interpret_hook; private: virtual void interpret(Configuration&, InstructionPointer&, const Instruction&) override; }; }