diff options
Diffstat (limited to 'Userland/Libraries/LibJS')
10 files changed, 43 insertions, 39 deletions
diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index afa9b3fe15..4f8897981b 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -545,7 +545,7 @@ Value ForStatement::execute(Interpreter& interpreter, GlobalObject& global_objec if (declaration.declaration_kind() == DeclarationKind::Const) { loop_environment->create_immutable_binding(global_object, name, true); } else { - loop_environment->create_mutable_binding(global_object, name, false); + MUST(loop_environment->create_mutable_binding(global_object, name, false)); let_declarations.append(name); } return IterationDecision::Continue; @@ -571,7 +571,7 @@ Value ForStatement::execute(Interpreter& interpreter, GlobalObject& global_objec VERIFY(outer); auto* this_iteration_env = new_declarative_environment(*outer); for (auto& name : let_declarations) { - this_iteration_env->create_mutable_binding(global_object, name, false); + MUST(this_iteration_env->create_mutable_binding(global_object, name, false)); auto last_value = last_iteration_env->get_binding_value(global_object, name, true); if (auto* exception = interpreter.exception()) return throw_completion(exception->value()); @@ -685,7 +685,7 @@ struct ForInOfHeadState { if (for_declaration.declaration_kind() == DeclarationKind::Const) iteration_environment->create_immutable_binding(global_object, name, false); else - iteration_environment->create_mutable_binding(global_object, name, true); + MUST(iteration_environment->create_mutable_binding(global_object, name, true)); }); interpreter.vm().running_execution_context().lexical_environment = iteration_environment; @@ -766,7 +766,7 @@ static ThrowCompletionOr<ForInOfHeadState> for_in_of_head_execute(Interpreter& i state.lhs_kind = ForInOfHeadState::LexicalBinding; new_environment = new_declarative_environment(*interpreter.lexical_environment()); variable_declaration.for_each_bound_name([&](auto const& name) { - new_environment->create_mutable_binding(global_object, name, false); + MUST(new_environment->create_mutable_binding(global_object, name, false)); }); } @@ -2770,11 +2770,11 @@ Value TryStatement::execute(Interpreter& interpreter, GlobalObject& global_objec m_handler->parameter().visit( [&](FlyString const& parameter) { - catch_scope->create_mutable_binding(global_object, parameter, false); + MUST(catch_scope->create_mutable_binding(global_object, parameter, false)); }, [&](NonnullRefPtr<BindingPattern> const& pattern) { pattern->for_each_bound_name([&](auto& name) { - catch_scope->create_mutable_binding(global_object, name, false); + MUST(catch_scope->create_mutable_binding(global_object, name, false)); }); }); @@ -3191,7 +3191,7 @@ void ScopeNode::block_declaration_instantiation(GlobalObject& global_object, Env environment->create_immutable_binding(global_object, name, true); } else { if (!MUST(environment->has_binding(name))) - environment->create_mutable_binding(global_object, name, false); + MUST(environment->create_mutable_binding(global_object, name, false)); } }); @@ -3329,7 +3329,7 @@ ThrowCompletionOr<void> Program::global_declaration_instantiation(Interpreter& i if (declaration.is_constant_declaration()) global_environment.create_immutable_binding(global_object, name, true); else - global_environment.create_mutable_binding(global_object, name, false); + (void)global_environment.create_mutable_binding(global_object, name, false); if (interpreter.exception()) return IterationDecision::Break; diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp index fa6e1b59d4..c2b3e1a43d 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp @@ -629,7 +629,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& glo return IterationDecision::Break; } else { if (!MUST(variable_environment->has_binding(function_name))) { - variable_environment->create_mutable_binding(global_object, function_name, true); + MUST(variable_environment->create_mutable_binding(global_object, function_name, true)); variable_environment->initialize_binding(global_object, function_name, js_undefined()); VERIFY(!vm.exception()); } @@ -680,7 +680,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& glo if (declaration.is_constant_declaration()) lexical_environment->create_immutable_binding(global_object, name, true); else - lexical_environment->create_mutable_binding(global_object, name, false); + (void)lexical_environment->create_mutable_binding(global_object, name, false); if (vm.exception()) return IterationDecision::Break; return IterationDecision::Continue; @@ -703,9 +703,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& glo auto binding_exists = MUST(variable_environment->has_binding(declaration.name())); if (!binding_exists) { - variable_environment->create_mutable_binding(global_object, declaration.name(), true); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + TRY(variable_environment->create_mutable_binding(global_object, declaration.name(), true)); variable_environment->initialize_binding(global_object, declaration.name(), function); } else { variable_environment->set_mutable_binding(global_object, declaration.name(), function, false); @@ -724,9 +722,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& glo auto binding_exists = MUST(variable_environment->has_binding(var_name)); if (!binding_exists) { - variable_environment->create_mutable_binding(global_object, var_name, true); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + TRY(variable_environment->create_mutable_binding(global_object, var_name, true)); variable_environment->initialize_binding(global_object, var_name, js_undefined()); if (auto* exception = vm.exception()) return throw_completion(exception->value()); diff --git a/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp b/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp index 417f1040d1..ad5d91e930 100644 --- a/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp +++ b/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp @@ -46,8 +46,9 @@ ThrowCompletionOr<bool> DeclarativeEnvironment::has_binding(FlyString const& nam } // 9.1.1.1.2 CreateMutableBinding ( N, D ), https://tc39.es/ecma262/#sec-declarative-environment-records-createmutablebinding-n-d -void DeclarativeEnvironment::create_mutable_binding(GlobalObject&, FlyString const& name, bool can_be_deleted) +ThrowCompletionOr<void> DeclarativeEnvironment::create_mutable_binding(GlobalObject&, FlyString const& name, bool can_be_deleted) { + // 2. Create a mutable binding in envRec for N and record that it is uninitialized. If D is true, record that the newly created binding may be deleted by a subsequent DeleteBinding call. m_bindings.append(Binding { .value = {}, .strict = false, @@ -56,7 +57,12 @@ void DeclarativeEnvironment::create_mutable_binding(GlobalObject&, FlyString con .initialized = false, }); auto result = m_names.set(name, m_bindings.size() - 1); + + // 1. Assert: envRec does not already have a binding for N. VERIFY(result == AK::HashSetResult::InsertedNewEntry); + + // 3. Return NormalCompletion(empty). + return {}; } // 9.1.1.1.3 CreateImmutableBinding ( N, S ), https://tc39.es/ecma262/#sec-declarative-environment-records-createimmutablebinding-n-s @@ -93,7 +99,7 @@ void DeclarativeEnvironment::set_mutable_binding(GlobalObject& global_object, Fl global_object.vm().throw_exception<ReferenceError>(global_object, ErrorType::UnknownIdentifier, name); return; } - create_mutable_binding(global_object, name, true); + (void)create_mutable_binding(global_object, name, true); initialize_binding(global_object, name, value); return; } diff --git a/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.h b/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.h index a2eb60c191..bf850633d7 100644 --- a/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.h +++ b/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.h @@ -23,7 +23,7 @@ public: virtual ~DeclarativeEnvironment() override; virtual ThrowCompletionOr<bool> has_binding(FlyString const& name, Optional<size_t>* = nullptr) const override; - virtual void create_mutable_binding(GlobalObject&, FlyString const& name, bool can_be_deleted) override; + virtual ThrowCompletionOr<void> create_mutable_binding(GlobalObject&, FlyString const& name, bool can_be_deleted) override; virtual void create_immutable_binding(GlobalObject&, FlyString const& name, bool strict) override; virtual void initialize_binding(GlobalObject&, FlyString const& name, Value) override; virtual void set_mutable_binding(GlobalObject&, FlyString const& name, Value, bool strict) override; diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp index 1bdd1386da..3e91172b79 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp @@ -360,7 +360,7 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia if (MUST(environment->has_binding(parameter_name))) continue; - environment->create_mutable_binding(global_object(), parameter_name, false); + MUST(environment->create_mutable_binding(global_object(), parameter_name, false)); if (has_duplicates) environment->initialize_binding(global_object(), parameter_name, js_undefined()); VERIFY(!vm.exception()); @@ -376,7 +376,7 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia if (is_strict_mode()) environment->create_immutable_binding(global_object(), vm.names.arguments.as_string(), false); else - environment->create_mutable_binding(global_object(), vm.names.arguments.as_string(), false); + MUST(environment->create_mutable_binding(global_object(), vm.names.arguments.as_string(), false)); environment->initialize_binding(global_object(), vm.names.arguments.as_string(), arguments_object); parameter_names.set(vm.names.arguments.as_string()); @@ -445,7 +445,7 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia if (scope_body) { scope_body->for_each_var_declared_name([&](auto const& name) { if (!parameter_names.contains(name) && instantiated_var_names.set(name) == AK::HashSetResult::InsertedNewEntry) { - environment->create_mutable_binding(global_object(), name, false); + MUST(environment->create_mutable_binding(global_object(), name, false)); environment->initialize_binding(global_object(), name, js_undefined()); } }); @@ -459,7 +459,7 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia scope_body->for_each_var_declared_name([&](auto const& name) { if (instantiated_var_names.set(name) != AK::HashSetResult::InsertedNewEntry) return IterationDecision::Continue; - var_environment->create_mutable_binding(global_object(), name, false); + MUST(var_environment->create_mutable_binding(global_object(), name, false)); Value initial_value; if (!parameter_names.contains(name) || function_names.contains(name)) @@ -482,8 +482,7 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia return IterationDecision::Continue; // The spec says 'initializedBindings' here but that does not exist and it then adds it to 'instantiatedVarNames' so it probably means 'instantiatedVarNames'. if (!instantiated_var_names.contains(function_name) && function_name != vm.names.arguments.as_string()) { - var_environment->create_mutable_binding(global_object(), function_name, false); - VERIFY(!vm.exception()); + MUST(var_environment->create_mutable_binding(global_object(), function_name, false)); var_environment->initialize_binding(global_object(), function_name, js_undefined()); instantiated_var_names.set(function_name); } @@ -527,7 +526,7 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia if (declaration.is_constant_declaration()) lex_environment->create_immutable_binding(global_object(), name, true); else - lex_environment->create_mutable_binding(global_object(), name, false); + MUST(lex_environment->create_mutable_binding(global_object(), name, false)); return IterationDecision::Continue; }); }); diff --git a/Userland/Libraries/LibJS/Runtime/Environment.h b/Userland/Libraries/LibJS/Runtime/Environment.h index bfab780217..3312cd949f 100644 --- a/Userland/Libraries/LibJS/Runtime/Environment.h +++ b/Userland/Libraries/LibJS/Runtime/Environment.h @@ -34,7 +34,7 @@ public: virtual Object* with_base_object() const { return nullptr; } virtual ThrowCompletionOr<bool> has_binding([[maybe_unused]] FlyString const& name, [[maybe_unused]] Optional<size_t>* out_index = nullptr) const { return false; } - virtual void create_mutable_binding(GlobalObject&, [[maybe_unused]] FlyString const& name, [[maybe_unused]] bool can_be_deleted) { } + virtual ThrowCompletionOr<void> create_mutable_binding(GlobalObject&, [[maybe_unused]] FlyString const& name, [[maybe_unused]] bool can_be_deleted) { return {}; } virtual void create_immutable_binding(GlobalObject&, [[maybe_unused]] FlyString const& name, [[maybe_unused]] bool strict) { } virtual void initialize_binding(GlobalObject&, [[maybe_unused]] FlyString const& name, Value) { } virtual void set_mutable_binding(GlobalObject&, [[maybe_unused]] FlyString const& name, Value, [[maybe_unused]] bool strict) { } diff --git a/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp b/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp index 5e50373e81..1d43ec6c6a 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp +++ b/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp @@ -52,13 +52,15 @@ ThrowCompletionOr<bool> GlobalEnvironment::has_binding(FlyString const& name, Op } // 9.1.1.4.2 CreateMutableBinding ( N, D ), https://tc39.es/ecma262/#sec-global-environment-records-createmutablebinding-n-d -void GlobalEnvironment::create_mutable_binding(GlobalObject& global_object, FlyString const& name, bool can_be_deleted) +ThrowCompletionOr<void> GlobalEnvironment::create_mutable_binding(GlobalObject& global_object, FlyString const& name, bool can_be_deleted) { - if (MUST(m_declarative_record->has_binding(name))) { - global_object.vm().throw_exception<TypeError>(global_object, ErrorType::FixmeAddAnErrorString); - return; - } - m_declarative_record->create_mutable_binding(global_object, name, can_be_deleted); + // 1. Let DclRec be envRec.[[DeclarativeRecord]]. + // 2. If DclRec.HasBinding(N) is true, throw a TypeError exception. + if (MUST(m_declarative_record->has_binding(name))) + return vm().throw_completion<TypeError>(global_object, ErrorType::FixmeAddAnErrorString); + + // 3. Return DclRec.CreateMutableBinding(N, D). + return m_declarative_record->create_mutable_binding(global_object, name, can_be_deleted); } // 9.1.1.4.3 CreateImmutableBinding ( N, S ), https://tc39.es/ecma262/#sec-global-environment-records-createimmutablebinding-n-s @@ -179,8 +181,8 @@ void GlobalEnvironment::create_global_var_binding(FlyString const& name, bool ca return; auto extensible = extensible_or_error.release_value(); if (!has_property && extensible) { - m_object_record->create_mutable_binding(m_object_record->global_object(), name, can_be_deleted); - if (vm.exception()) + auto result = m_object_record->create_mutable_binding(m_object_record->global_object(), name, can_be_deleted); + if (result.is_error()) return; m_object_record->initialize_binding(m_object_record->global_object(), name, js_undefined()); if (vm.exception()) diff --git a/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.h b/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.h index 7fc10f53ca..fa96cdcbe1 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.h +++ b/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.h @@ -20,7 +20,7 @@ public: virtual ThrowCompletionOr<Value> get_this_binding(GlobalObject&) const final; virtual ThrowCompletionOr<bool> has_binding(FlyString const& name, Optional<size_t>* = nullptr) const override; - virtual void create_mutable_binding(GlobalObject&, FlyString const& name, bool can_be_deleted) override; + virtual ThrowCompletionOr<void> create_mutable_binding(GlobalObject&, FlyString const& name, bool can_be_deleted) override; virtual void create_immutable_binding(GlobalObject&, FlyString const& name, bool strict) override; virtual void initialize_binding(GlobalObject&, FlyString const& name, Value) override; virtual void set_mutable_binding(GlobalObject&, FlyString const& name, Value, bool strict) override; diff --git a/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp b/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp index 301c398885..80f4230ae4 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp +++ b/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp @@ -60,11 +60,12 @@ ThrowCompletionOr<bool> ObjectEnvironment::has_binding(FlyString const& name, Op } // 9.1.1.2.2 CreateMutableBinding ( N, D ), https://tc39.es/ecma262/#sec-object-environment-records-createmutablebinding-n-d -void ObjectEnvironment::create_mutable_binding(GlobalObject&, FlyString const& name, bool can_be_deleted) +ThrowCompletionOr<void> ObjectEnvironment::create_mutable_binding(GlobalObject&, FlyString const& name, bool can_be_deleted) { // 1. Let bindingObject be envRec.[[BindingObject]]. // 2. Return ? DefinePropertyOrThrow(bindingObject, N, PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D }). - MUST(m_binding_object.define_property_or_throw(name, { .value = js_undefined(), .writable = true, .enumerable = true, .configurable = can_be_deleted })); + TRY(m_binding_object.define_property_or_throw(name, { .value = js_undefined(), .writable = true, .enumerable = true, .configurable = can_be_deleted })); + return {}; } // 9.1.1.2.3 CreateImmutableBinding ( N, S ), https://tc39.es/ecma262/#sec-object-environment-records-createimmutablebinding-n-s diff --git a/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.h b/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.h index 951955649c..ea4d4c4ab8 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.h +++ b/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.h @@ -21,7 +21,7 @@ public: ObjectEnvironment(Object& binding_object, IsWithEnvironment, Environment* outer_environment); virtual ThrowCompletionOr<bool> has_binding(FlyString const& name, Optional<size_t>* = nullptr) const override; - virtual void create_mutable_binding(GlobalObject&, FlyString const& name, bool can_be_deleted) override; + virtual ThrowCompletionOr<void> create_mutable_binding(GlobalObject&, FlyString const& name, bool can_be_deleted) override; virtual void create_immutable_binding(GlobalObject&, FlyString const& name, bool strict) override; virtual void initialize_binding(GlobalObject&, FlyString const& name, Value) override; virtual void set_mutable_binding(GlobalObject&, FlyString const& name, Value, bool strict) override; |