diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index 3d4dd78688..5213de5964 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -1479,12 +1479,7 @@ Value ClassDeclaration::execute(Interpreter& interpreter, GlobalObject& global_o VERIFY(!name.is_empty()); auto class_constructor = TRY_OR_DISCARD(m_class_expression->class_definition_evaluation(interpreter, global_object, name, name)); - if (interpreter.lexical_environment()) { - MUST(interpreter.lexical_environment()->initialize_binding(global_object, name, class_constructor)); - } else { - auto reference = interpreter.vm().resolve_binding(name); - TRY_OR_DISCARD(reference.put_value(global_object, class_constructor)); - } + TRY_OR_DISCARD(initialize_bound_name(global_object, name, class_constructor, interpreter.lexical_environment())); return {}; } diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp index e25fec3952..769cf84c40 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp @@ -199,6 +199,31 @@ ThrowCompletionOr get_function_realm(GlobalObject& global_object, Functi return vm.current_realm(); } +// 8.5.2.1 InitializeBoundName ( name, value, environment ), 8.5.2.1 InitializeBoundName ( name, value, environment ) +ThrowCompletionOr initialize_bound_name(GlobalObject& global_object, FlyString const& name, Value value, Environment* environment) +{ + auto& vm = global_object.vm(); + + // 1. If environment is not undefined, then + if (environment) { + // a. Perform environment.InitializeBinding(name, value). + MUST(environment->initialize_binding(global_object, name, value)); + + // b. Return NormalCompletion(undefined). + return {}; + } + // 2. Else, + else { + // a. Let lhs be ResolveBinding(name). + auto lhs = vm.resolve_binding(name); + + // b. Return ? PutValue(lhs, value). + return TRY(lhs.put_value(global_object, value)); + } + + VERIFY_NOT_REACHED(); +} + // 10.1.6.2 IsCompatiblePropertyDescriptor ( Extensible, Desc, Current ), https://tc39.es/ecma262/#sec-iscompatiblepropertydescriptor bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const& descriptor, Optional const& current) { diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h index de155d7e78..989cc9bfa7 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h @@ -30,6 +30,7 @@ ThrowCompletionOr length_of_array_like(GlobalObject&, Object const&); ThrowCompletionOr create_list_from_array_like(GlobalObject&, Value, Function(Value)> = {}); ThrowCompletionOr species_constructor(GlobalObject&, Object const&, FunctionObject& default_constructor); ThrowCompletionOr get_function_realm(GlobalObject&, FunctionObject const&); +ThrowCompletionOr initialize_bound_name(GlobalObject&, FlyString const&, Value, Environment*); bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const&, Optional const& current); bool validate_and_apply_property_descriptor(Object*, PropertyKey const&, bool extensible, PropertyDescriptor const&, Optional const& current); ThrowCompletionOr get_prototype_from_constructor(GlobalObject&, FunctionObject const& constructor, Object* (GlobalObject::*intrinsic_default_prototype)()); diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index 4028303155..b4ac310959 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/Userland/Libraries/LibJS/Runtime/VM.cpp @@ -180,13 +180,7 @@ ThrowCompletionOr VM::binding_initialization(FlyString const& target, Valu { // 1. Let name be StringValue of Identifier. // 2. Return ? InitializeBoundName(name, value, environment). - // TODO: Use the right AO here - if (environment) { - MUST(environment->initialize_binding(global_object, target, value)); - return {}; - } - auto reference = resolve_binding(target); - return reference.put_value(global_object, value); + return initialize_bound_name(global_object, target, value, environment); } // 8.5.2 Runtime Semantics: BindingInitialization, https://tc39.es/ecma262/#sec-runtime-semantics-bindinginitialization