diff --git a/Userland/Libraries/LibJS/Bytecode/Instruction.cpp b/Userland/Libraries/LibJS/Bytecode/Instruction.cpp index 37ad9f8939..58e44ba1bb 100644 --- a/Userland/Libraries/LibJS/Bytecode/Instruction.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Instruction.cpp @@ -42,4 +42,10 @@ RefPtr InstructionStreamIterator::source_code() const return m_executable ? m_executable->source_code.ptr() : nullptr; } +Operand::Operand(Register reg) + : m_type(Type::Register) + , m_index(reg.index()) +{ +} + } diff --git a/Userland/Libraries/LibJS/Bytecode/Instruction.h b/Userland/Libraries/LibJS/Bytecode/Instruction.h index b0a6b37cf8..54d4758983 100644 --- a/Userland/Libraries/LibJS/Bytecode/Instruction.h +++ b/Userland/Libraries/LibJS/Bytecode/Instruction.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Andreas Kling + * Copyright (c) 2021-2024, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp index 0da0426136..d33b2a6e30 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -67,6 +67,34 @@ void Interpreter::visit_edges(Cell::Visitor& visitor) } } +Value Interpreter::get(Operand op) const +{ + switch (op.type()) { + case Operand::Type::Register: + return reg(Register { op.index() }); + case Operand::Type::Local: + return vm().running_execution_context().locals[op.index()]; + case Operand::Type::Constant: + return current_executable().constants[op.index()]; + } + VERIFY_NOT_REACHED(); +} + +void Interpreter::set(Operand op, Value value) +{ + switch (op.type()) { + case Operand::Type::Register: + reg(Register { op.index() }) = value; + return; + case Operand::Type::Local: + vm().running_execution_context().locals[op.index()] = value; + return; + case Operand::Type::Constant: + VERIFY_NOT_REACHED(); + } + VERIFY_NOT_REACHED(); +} + // 16.1.6 ScriptEvaluation ( scriptRecord ), https://tc39.es/ecma262/#sec-runtime-semantics-scriptevaluation ThrowCompletionOr Interpreter::run(Script& script_record, JS::GCPtr lexical_environment_override) { diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.h b/Userland/Libraries/LibJS/Bytecode/Interpreter.h index 2b819ca0a2..595cd3437d 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.h +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.h @@ -53,6 +53,7 @@ public: Realm& realm(); VM& vm() { return m_vm; } + VM const& vm() const { return m_vm; } ThrowCompletionOr run(Script&, JS::GCPtr lexical_environment_override = nullptr); ThrowCompletionOr run(SourceTextModule&); @@ -72,6 +73,10 @@ public: ALWAYS_INLINE Value& accumulator() { return reg(Register::accumulator()); } ALWAYS_INLINE Value& saved_return_value() { return reg(Register::saved_return_value()); } Value& reg(Register const& r) { return registers()[r.index()]; } + Value reg(Register const& r) const { return registers()[r.index()]; } + + [[nodiscard]] Value get(Operand) const; + void set(Operand, Value); auto& saved_lexical_environment_stack() { return call_frame().saved_lexical_environments; } auto& unwind_contexts() { return call_frame().unwind_contexts; } diff --git a/Userland/Libraries/LibJS/Bytecode/Operand.h b/Userland/Libraries/LibJS/Bytecode/Operand.h new file mode 100644 index 0000000000..560111af25 --- /dev/null +++ b/Userland/Libraries/LibJS/Bytecode/Operand.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace JS::Bytecode { + +class Operand { +public: + enum class Type { + Register, + Local, + Constant, + }; + + [[nodiscard]] bool operator==(Operand const&) const = default; + + explicit Operand(Type type, u32 index) + : m_type(type) + , m_index(index) + { + } + + explicit Operand(Register); + + [[nodiscard]] bool is_register() const { return m_type == Type::Register; } + [[nodiscard]] bool is_local() const { return m_type == Type::Local; } + [[nodiscard]] bool is_constant() const { return m_type == Type::Constant; } + + [[nodiscard]] Type type() const { return m_type; } + [[nodiscard]] u32 index() const { return m_index; } + +private: + Type m_type {}; + u32 m_index { 0 }; +}; + +} diff --git a/Userland/Libraries/LibJS/Forward.h b/Userland/Libraries/LibJS/Forward.h index 591a78f199..49c58be2ad 100644 --- a/Userland/Libraries/LibJS/Forward.h +++ b/Userland/Libraries/LibJS/Forward.h @@ -312,6 +312,7 @@ class Executable; class Generator; class Instruction; class Interpreter; +class Operand; class RegexTable; class Register; }