summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Libraries/LibJS')
-rw-r--r--Userland/Libraries/LibJS/AST.cpp16
-rw-r--r--Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp12
-rw-r--r--Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp10
-rw-r--r--Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.h2
-rw-r--r--Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp13
-rw-r--r--Userland/Libraries/LibJS/Runtime/Environment.h2
-rw-r--r--Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp18
-rw-r--r--Userland/Libraries/LibJS/Runtime/GlobalEnvironment.h2
-rw-r--r--Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp5
-rw-r--r--Userland/Libraries/LibJS/Runtime/ObjectEnvironment.h2
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;