1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 06:48:12 +00:00

LibJS: Update bytecode generator to use local variables

- Update ECMAScriptFunctionObject::function_declaration_instantiation
  to initialize local variables
- Introduce GetLocal, SetLocal, TypeofLocal that will be used to
  operate on local variables.
- Update bytecode generator to emit instructions for local variables
This commit is contained in:
Aliaksandr Kalenik 2023-07-05 02:17:10 +02:00 committed by Andreas Kling
parent 0daff637e2
commit ae3a7fd4b8
8 changed files with 170 additions and 37 deletions

View file

@ -422,6 +422,17 @@ ThrowCompletionOr<void> GetVariable::execute_impl(Bytecode::Interpreter& interpr
return {};
}
ThrowCompletionOr<void> GetLocal::execute_impl(Bytecode::Interpreter& interpreter) const
{
auto& vm = interpreter.vm();
if (vm.running_execution_context().local_variables[m_index].is_empty()) {
auto const& variable_name = vm.running_execution_context().function->local_variables_names()[m_index];
return interpreter.vm().throw_completion<ReferenceError>(ErrorType::BindingNotInitialized, variable_name);
}
interpreter.accumulator() = vm.running_execution_context().local_variables[m_index];
return {};
}
ThrowCompletionOr<void> DeleteVariable::execute_impl(Bytecode::Interpreter& interpreter) const
{
auto& vm = interpreter.vm();
@ -506,6 +517,12 @@ ThrowCompletionOr<void> SetVariable::execute_impl(Bytecode::Interpreter& interpr
return {};
}
ThrowCompletionOr<void> SetLocal::execute_impl(Bytecode::Interpreter& interpreter) const
{
interpreter.vm().running_execution_context().local_variables[m_index] = interpreter.accumulator();
return {};
}
ThrowCompletionOr<void> GetById::execute_impl(Bytecode::Interpreter& interpreter) const
{
auto& vm = interpreter.vm();
@ -1240,6 +1257,14 @@ ThrowCompletionOr<void> TypeofVariable::execute_impl(Bytecode::Interpreter& inte
return {};
}
ThrowCompletionOr<void> TypeofLocal::execute_impl(Bytecode::Interpreter& interpreter) const
{
auto& vm = interpreter.vm();
auto const& value = vm.running_execution_context().local_variables[m_index];
interpreter.accumulator() = MUST_OR_THROW_OOM(PrimitiveString::create(vm, value.typeof()));
return {};
}
ThrowCompletionOr<void> ToNumeric::execute_impl(Bytecode::Interpreter& interpreter) const
{
interpreter.accumulator() = TRY(interpreter.accumulator().to_numeric(interpreter.vm()));
@ -1335,6 +1360,11 @@ DeprecatedString GetVariable::to_deprecated_string_impl(Bytecode::Executable con
return DeprecatedString::formatted("GetVariable {} ({})", m_identifier, executable.identifier_table->get(m_identifier));
}
DeprecatedString GetLocal::to_deprecated_string_impl(Bytecode::Executable const&) const
{
return DeprecatedString::formatted("GetLocal {}", m_index);
}
DeprecatedString DeleteVariable::to_deprecated_string_impl(Bytecode::Executable const& executable) const
{
return DeprecatedString::formatted("DeleteVariable {} ({})", m_identifier, executable.identifier_table->get(m_identifier));
@ -1365,6 +1395,11 @@ DeprecatedString SetVariable::to_deprecated_string_impl(Bytecode::Executable con
return DeprecatedString::formatted("SetVariable env:{} init:{} {} ({})", mode_string, initialization_mode_name, m_identifier, executable.identifier_table->get(m_identifier));
}
DeprecatedString SetLocal::to_deprecated_string_impl(Bytecode::Executable const&) const
{
return DeprecatedString::formatted("SetLocal {}", m_index);
}
DeprecatedString PutById::to_deprecated_string_impl(Bytecode::Executable const& executable) const
{
auto kind = m_kind == PropertyKind::Getter
@ -1652,6 +1687,11 @@ DeprecatedString TypeofVariable::to_deprecated_string_impl(Bytecode::Executable
return DeprecatedString::formatted("TypeofVariable {} ({})", m_identifier, executable.identifier_table->get(m_identifier));
}
DeprecatedString TypeofLocal::to_deprecated_string_impl(Bytecode::Executable const&) const
{
return DeprecatedString::formatted("TypeofLocal {}", m_index);
}
DeprecatedString ToNumeric::to_deprecated_string_impl(Bytecode::Executable const&) const
{
return "ToNumeric"sv;