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

LibJS/Bytecode: Move CreateVariable impl to CommonImplementations

This commit is contained in:
Simon Wanner 2023-10-29 00:21:43 +02:00 committed by Andreas Kling
parent 1d3062de9e
commit 54f1f7a51b
3 changed files with 28 additions and 27 deletions

View file

@ -423,4 +423,30 @@ MarkedVector<Value> argument_list_evaluation(Bytecode::Interpreter& interpreter)
return argument_values; return argument_values;
} }
ThrowCompletionOr<void> create_variable(VM& vm, DeprecatedFlyString const& name, Op::EnvironmentMode mode, bool is_global, bool is_immutable, bool is_strict)
{
if (mode == Op::EnvironmentMode::Lexical) {
VERIFY(!is_global);
// Note: This is papering over an issue where "FunctionDeclarationInstantiation" creates these bindings for us.
// Instead of crashing in there, we'll just raise an exception here.
if (TRY(vm.lexical_environment()->has_binding(name)))
return vm.throw_completion<InternalError>(TRY_OR_THROW_OOM(vm, String::formatted("Lexical environment already has binding '{}'", name)));
if (is_immutable)
return vm.lexical_environment()->create_immutable_binding(vm, name, is_strict);
return vm.lexical_environment()->create_mutable_binding(vm, name, is_strict);
}
if (!is_global) {
if (is_immutable)
return vm.variable_environment()->create_immutable_binding(vm, name, is_strict);
return vm.variable_environment()->create_mutable_binding(vm, name, is_strict);
}
// NOTE: CreateVariable with m_is_global set to true is expected to only be used in GlobalDeclarationInstantiation currently, which only uses "false" for "can_be_deleted".
// The only area that sets "can_be_deleted" to true is EvalDeclarationInstantiation, which is currently fully implemented in C++ and not in Bytecode.
return verify_cast<GlobalEnvironment>(vm.variable_environment())->create_global_var_binding(name, false);
}
} }

View file

@ -32,5 +32,6 @@ struct CalleeAndThis {
ThrowCompletionOr<CalleeAndThis> get_callee_and_this_from_environment(Bytecode::Interpreter&, DeprecatedFlyString const& name, u32 cache_index); ThrowCompletionOr<CalleeAndThis> get_callee_and_this_from_environment(Bytecode::Interpreter&, DeprecatedFlyString const& name, u32 cache_index);
Value new_regexp(VM&, ParsedRegex const&, DeprecatedString const& pattern, DeprecatedString const& flags); Value new_regexp(VM&, ParsedRegex const&, DeprecatedString const& pattern, DeprecatedString const& flags);
MarkedVector<Value> argument_list_evaluation(Bytecode::Interpreter&); MarkedVector<Value> argument_list_evaluation(Bytecode::Interpreter&);
ThrowCompletionOr<void> create_variable(VM&, DeprecatedFlyString const& name, Op::EnvironmentMode, bool is_global, bool is_immutable, bool is_strict);
} }

View file

@ -819,34 +819,8 @@ ThrowCompletionOr<void> EnterObjectEnvironment::execute_impl(Bytecode::Interpret
ThrowCompletionOr<void> CreateVariable::execute_impl(Bytecode::Interpreter& interpreter) const ThrowCompletionOr<void> CreateVariable::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
auto& vm = interpreter.vm();
auto const& name = interpreter.current_executable().get_identifier(m_identifier); auto const& name = interpreter.current_executable().get_identifier(m_identifier);
return create_variable(interpreter.vm(), name, m_mode, m_is_global, m_is_immutable, m_is_strict);
if (m_mode == EnvironmentMode::Lexical) {
VERIFY(!m_is_global);
// Note: This is papering over an issue where "FunctionDeclarationInstantiation" creates these bindings for us.
// Instead of crashing in there, we'll just raise an exception here.
if (TRY(vm.lexical_environment()->has_binding(name)))
return vm.throw_completion<InternalError>(TRY_OR_THROW_OOM(vm, String::formatted("Lexical environment already has binding '{}'", name)));
if (m_is_immutable)
return vm.lexical_environment()->create_immutable_binding(vm, name, m_is_strict);
else
return vm.lexical_environment()->create_mutable_binding(vm, name, m_is_strict);
} else {
if (!m_is_global) {
if (m_is_immutable)
return vm.variable_environment()->create_immutable_binding(vm, name, m_is_strict);
else
return vm.variable_environment()->create_mutable_binding(vm, name, m_is_strict);
} else {
// NOTE: CreateVariable with m_is_global set to true is expected to only be used in GlobalDeclarationInstantiation currently, which only uses "false" for "can_be_deleted".
// The only area that sets "can_be_deleted" to true is EvalDeclarationInstantiation, which is currently fully implemented in C++ and not in Bytecode.
return verify_cast<GlobalEnvironment>(vm.variable_environment())->create_global_var_binding(name, false);
}
}
return {};
} }
ThrowCompletionOr<void> SetVariable::execute_impl(Bytecode::Interpreter& interpreter) const ThrowCompletionOr<void> SetVariable::execute_impl(Bytecode::Interpreter& interpreter) const