mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 17:47:44 +00:00
LibJS/Bytecode: Add Bytecode::Operand
An Operand is either a register, a local, or a constant (index into the executable's constant table)
This commit is contained in:
parent
c0ec924dc9
commit
3466771492
6 changed files with 85 additions and 1 deletions
|
@ -42,4 +42,10 @@ RefPtr<SourceCode> InstructionStreamIterator::source_code() const
|
||||||
return m_executable ? m_executable->source_code.ptr() : nullptr;
|
return m_executable ? m_executable->source_code.ptr() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Operand::Operand(Register reg)
|
||||||
|
: m_type(Type::Register)
|
||||||
|
, m_index(reg.index())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2021-2024, Andreas Kling <kling@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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
|
// 16.1.6 ScriptEvaluation ( scriptRecord ), https://tc39.es/ecma262/#sec-runtime-semantics-scriptevaluation
|
||||||
ThrowCompletionOr<Value> Interpreter::run(Script& script_record, JS::GCPtr<Environment> lexical_environment_override)
|
ThrowCompletionOr<Value> Interpreter::run(Script& script_record, JS::GCPtr<Environment> lexical_environment_override)
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,6 +53,7 @@ public:
|
||||||
|
|
||||||
Realm& realm();
|
Realm& realm();
|
||||||
VM& vm() { return m_vm; }
|
VM& vm() { return m_vm; }
|
||||||
|
VM const& vm() const { return m_vm; }
|
||||||
|
|
||||||
ThrowCompletionOr<Value> run(Script&, JS::GCPtr<Environment> lexical_environment_override = nullptr);
|
ThrowCompletionOr<Value> run(Script&, JS::GCPtr<Environment> lexical_environment_override = nullptr);
|
||||||
ThrowCompletionOr<Value> run(SourceTextModule&);
|
ThrowCompletionOr<Value> run(SourceTextModule&);
|
||||||
|
@ -72,6 +73,10 @@ public:
|
||||||
ALWAYS_INLINE Value& accumulator() { return reg(Register::accumulator()); }
|
ALWAYS_INLINE Value& accumulator() { return reg(Register::accumulator()); }
|
||||||
ALWAYS_INLINE Value& saved_return_value() { return reg(Register::saved_return_value()); }
|
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) { 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& saved_lexical_environment_stack() { return call_frame().saved_lexical_environments; }
|
||||||
auto& unwind_contexts() { return call_frame().unwind_contexts; }
|
auto& unwind_contexts() { return call_frame().unwind_contexts; }
|
||||||
|
|
44
Userland/Libraries/LibJS/Bytecode/Operand.h
Normal file
44
Userland/Libraries/LibJS/Bytecode/Operand.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024, Andreas Kling <kling@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Types.h>
|
||||||
|
#include <LibJS/Forward.h>
|
||||||
|
|
||||||
|
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 };
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -312,6 +312,7 @@ class Executable;
|
||||||
class Generator;
|
class Generator;
|
||||||
class Instruction;
|
class Instruction;
|
||||||
class Interpreter;
|
class Interpreter;
|
||||||
|
class Operand;
|
||||||
class RegexTable;
|
class RegexTable;
|
||||||
class Register;
|
class Register;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue