diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp index ed86aff623..8a2a062049 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -178,6 +178,9 @@ ThrowCompletionOr Interpreter::run(SourceTextModule& module) void Interpreter::run_bytecode() { + auto* locals = vm().running_execution_context().local_variables.data(); + auto* registers = this->registers().data(); + auto& accumulator = this->accumulator(); for (;;) { start: auto pc = InstructionStreamIterator { m_current_block->instruction_stream(), m_current_executable }; @@ -192,23 +195,45 @@ void Interpreter::run_bytecode() auto& instruction = *pc; switch (instruction.type()) { + case Instruction::Type::GetLocal: { + auto& local = locals[static_cast(instruction).index()]; + if (local.is_empty()) { + auto const& variable_name = vm().running_execution_context().function->local_variables_names()[static_cast(instruction).index()]; + result = vm().throw_completion(ErrorType::BindingNotInitialized, variable_name); + break; + } + accumulator = local; + break; + } + case Instruction::Type::SetLocal: + locals[static_cast(instruction).index()] = accumulator; + break; + case Instruction::Type::Load: + accumulator = registers[static_cast(instruction).src().index()]; + break; + case Instruction::Type::Store: + registers[static_cast(instruction).dst().index()] = accumulator; + break; + case Instruction::Type::LoadImmediate: + accumulator = static_cast(instruction).value(); + break; case Instruction::Type::Jump: m_current_block = &static_cast(instruction).true_target()->block(); goto start; case Instruction::Type::JumpConditional: - if (accumulator().to_boolean()) + if (accumulator.to_boolean()) m_current_block = &static_cast(instruction).true_target()->block(); else m_current_block = &static_cast(instruction).false_target()->block(); goto start; case Instruction::Type::JumpNullish: - if (accumulator().is_nullish()) + if (accumulator.is_nullish()) m_current_block = &static_cast(instruction).true_target()->block(); else m_current_block = &static_cast(instruction).false_target()->block(); goto start; case Instruction::Type::JumpUndefined: - if (accumulator().is_undefined()) + if (accumulator.is_undefined()) m_current_block = &static_cast(instruction).true_target()->block(); else m_current_block = &static_cast(instruction).false_target()->block(); @@ -257,7 +282,7 @@ void Interpreter::run_bytecode() m_current_block = unwind_context.handler; unwind_context.handler_called = true; - accumulator() = reg(Register::exception()); + accumulator = reg(Register::exception()); reg(Register::exception()) = {}; goto start; } diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h index 78885aee61..7894e67b35 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.h +++ b/Userland/Libraries/LibJS/Bytecode/Op.h @@ -40,6 +40,8 @@ public: ThrowCompletionOr execute_impl(Bytecode::Interpreter&) const; DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const; + Register src() const { return m_src; } + private: Register m_src; }; @@ -55,6 +57,8 @@ public: ThrowCompletionOr execute_impl(Bytecode::Interpreter&) const; DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const; + Value value() const { return m_value; } + private: Value m_value; };