diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index 50cb9ecb15..2c662597b8 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -779,14 +779,16 @@ Completion ForStatement::loop_evaluation(Interpreter& interpreter, Vectoris_constant_declaration(); - declaration->for_each_bound_name([&](auto const& name) { + // NOTE: Due to the use of MUST with `create_immutable_binding` and `create_mutable_binding` below, + // an exception should not result from `for_each_bound_name`. + MUST(declaration->for_each_bound_name([&](auto const& name) { if (is_const) { MUST(loop_env->create_immutable_binding(vm, name, true)); } else { MUST(loop_env->create_mutable_binding(vm, name, false)); ++per_iteration_bindings_size; } - }); + })); interpreter.vm().running_execution_context().lexical_environment = loop_env; } @@ -979,7 +981,9 @@ struct ForInOfHeadState { // 14.7.5.4 Runtime Semantics: ForDeclarationBindingInstantiation, https://tc39.es/ecma262/#sec-runtime-semantics-fordeclarationbindinginstantiation // 1. For each element name of the BoundNames of ForBinding, do - for_declaration.for_each_bound_name([&](auto const& name) { + // NOTE: Due to the use of MUST with `create_immutable_binding` and `create_mutable_binding` below, + // an exception should not result from `for_each_bound_name`. + MUST(for_declaration.for_each_bound_name([&](auto const& name) { if (first_name.is_empty()) first_name = name; @@ -993,7 +997,7 @@ struct ForInOfHeadState { // i. Perform ! environment.CreateMutableBinding(name, false). MUST(iteration_environment->create_mutable_binding(vm, name, false)); } - }); + })); interpreter.vm().running_execution_context().lexical_environment = iteration_environment; if (!destructuring) { @@ -1074,18 +1078,20 @@ static ThrowCompletionOr for_in_of_head_execute(Interpreter& i } else { state.lhs_kind = ForInOfHeadState::LexicalBinding; new_environment = new_declarative_environment(*interpreter.lexical_environment()); - variable_declaration.for_each_bound_name([&](auto const& name) { + // NOTE: Due to the use of MUST with `create_mutable_binding` below, an exception should not result from `for_each_bound_name`. + MUST(variable_declaration.for_each_bound_name([&](auto const& name) { MUST(new_environment->create_mutable_binding(vm, name, false)); - }); + })); } } else { VERIFY(is(ast_ptr->ptr())); auto& declaration = static_cast(*(*ast_ptr)); state.lhs_kind = ForInOfHeadState::LexicalBinding; new_environment = new_declarative_environment(*interpreter.lexical_environment()); - declaration.for_each_bound_name([&](auto const& name) { + // NOTE: Due to the use of MUST with `create_mutable_binding` below, an exception should not result from `for_each_bound_name`. + MUST(declaration.for_each_bound_name([&](auto const& name) { MUST(new_environment->create_mutable_binding(vm, name, false)); - }); + })); } if (new_environment) { @@ -2071,7 +2077,7 @@ ThrowCompletionOr ClassExpression::class_definition_e class_constructor->add_private_method(private_method); for (auto& method : static_private_methods) - class_constructor->private_method_or_accessor_add(move(method)); + TRY(class_constructor->private_method_or_accessor_add(move(method))); for (auto& element : static_elements) { TRY(element.visit( @@ -3983,10 +3989,11 @@ Completion TryStatement::execute(Interpreter& interpreter) const }, [&](NonnullRefPtr const& pattern) { // 3. For each element argName of the BoundNames of CatchParameter, do - pattern->for_each_bound_name([&](auto& name) { + // NOTE: Due to the use of MUST with `create_mutable_binding` below, an exception should not result from `for_each_bound_name`. + MUST(pattern->for_each_bound_name([&](auto& name) { // a. Perform ! catchEnv.CreateMutableBinding(argName, false). MUST(catch_environment->create_mutable_binding(vm, name, false)); - }); + })); }); // 4. Set the running execution context's LexicalEnvironment to catchEnv. @@ -4725,16 +4732,19 @@ void ScopeNode::block_declaration_instantiation(Interpreter& interpreter, Enviro VERIFY(environment); auto* private_environment = vm.running_execution_context().private_environment; // Note: All the calls here are ! and thus we do not need to TRY this callback. - for_each_lexically_scoped_declaration([&](Declaration const& declaration) { + // We use MUST to ensure it does not throw and to avoid discarding the returned ThrowCompletionOr. + MUST(for_each_lexically_scoped_declaration([&](Declaration const& declaration) { auto is_constant_declaration = declaration.is_constant_declaration(); - declaration.for_each_bound_name([&](auto const& name) { + // NOTE: Due to the use of MUST with `create_immutable_binding` and `create_mutable_binding` below, + // an exception should not result from `for_each_bound_name`. + MUST(declaration.for_each_bound_name([&](auto const& name) { if (is_constant_declaration) { MUST(environment->create_immutable_binding(vm, name, true)); } else { if (!MUST(environment->has_binding(name))) MUST(environment->create_mutable_binding(vm, name, false)); } - }); + })); if (is(declaration)) { auto& function_declaration = static_cast(declaration); @@ -4742,7 +4752,7 @@ void ScopeNode::block_declaration_instantiation(Interpreter& interpreter, Enviro VERIFY(is(*environment)); static_cast(*environment).initialize_or_set_mutable_binding({}, vm, function_declaration.name(), function); } - }); + })); } // 16.1.7 GlobalDeclarationInstantiation ( script, env ), https://tc39.es/ecma262/#sec-globaldeclarationinstantiation diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index 33d65f41c4..44df9c5cb0 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -44,7 +44,8 @@ Bytecode::CodeGenerationErrorOr ScopeNode::generate_bytecode(Bytecode::Gen (void)for_each_lexically_scoped_declaration([&](Declaration const& declaration) -> ThrowCompletionOr { auto is_constant_declaration = declaration.is_constant_declaration(); - declaration.for_each_bound_name([&](auto const& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(declaration.for_each_bound_name([&](auto const& name) { auto index = generator.intern_identifier(name); // NOTE: BlockDeclarationInstantiation takes as input the new lexical environment that was created and checks if there is a binding for the current name only in this new scope. // For example: `{ let a = 1; { let a = 2; } }`. The second `a` will shadow the first `a` instead of re-initializing or setting it. @@ -52,7 +53,7 @@ Bytecode::CodeGenerationErrorOr ScopeNode::generate_bytecode(Bytecode::Gen generator.register_binding(index); generator.emit(index, Bytecode::Op::EnvironmentMode::Lexical, is_constant_declaration); } - }); + })); if (is(declaration)) { auto& function_declaration = static_cast(declaration); @@ -257,13 +258,14 @@ Bytecode::CodeGenerationErrorOr ScopeNode::generate_bytecode(Bytecode::Gen // FIXME: Implement this boi correctly. (void)for_each_lexically_scoped_declaration([&](Declaration const& declaration) -> ThrowCompletionOr { auto is_constant_declaration = declaration.is_constant_declaration(); - declaration.for_each_bound_name([&](auto const& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(declaration.for_each_bound_name([&](auto const& name) { auto index = generator.intern_identifier(name); if (is_constant_declaration || !generator.has_binding(index)) { generator.register_binding(index); generator.emit(index, Bytecode::Op::EnvironmentMode::Lexical, is_constant_declaration); } - }); + })); if (is(declaration)) { auto& function_declaration = static_cast(declaration); @@ -1001,11 +1003,12 @@ Bytecode::CodeGenerationErrorOr ForStatement::generate_labelled_evaluation generator.begin_variable_scope(Bytecode::Generator::BindingMode::Lexical, Bytecode::Generator::SurroundingScopeKind::Block); bool is_const = variable_declaration.is_constant_declaration(); - variable_declaration.for_each_bound_name([&](auto const& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(variable_declaration.for_each_bound_name([&](auto const& name) { auto index = generator.intern_identifier(name); generator.register_binding(index); generator.emit(index, Bytecode::Op::EnvironmentMode::Lexical, is_const); - }); + })); } } @@ -2475,12 +2478,13 @@ static Bytecode::CodeGenerationErrorOr for_in_of_he // b. Let newEnv be NewDeclarativeEnvironment(oldEnv). generator.begin_variable_scope(); // c. For each String name of uninitializedBoundNames, do - variable_declaration.for_each_bound_name([&](auto const& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(variable_declaration.for_each_bound_name([&](auto const& name) { // i. Perform ! newEnv.CreateMutableBinding(name, false). auto identifier = generator.intern_identifier(name); generator.register_binding(identifier); generator.emit(identifier, Bytecode::Op::EnvironmentMode::Lexical, false); - }); + })); // d. Set the running execution context's LexicalEnvironment to newEnv. // NOTE: Done by CreateEnvironment. } @@ -2634,7 +2638,8 @@ static Bytecode::CodeGenerationErrorOr for_in_of_body_evaluation(Bytecode: // NOTE: We just made it. auto& variable_declaration = static_cast(*lhs.get>()); // 2. For each element name of the BoundNames of ForBinding, do - variable_declaration.for_each_bound_name([&](auto const& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(variable_declaration.for_each_bound_name([&](auto const& name) { auto identifier = generator.intern_identifier(name); generator.register_binding(identifier, Bytecode::Generator::BindingMode::Lexical); // a. If IsConstantDeclaration of LetOrConst is true, then @@ -2647,7 +2652,7 @@ static Bytecode::CodeGenerationErrorOr for_in_of_body_evaluation(Bytecode: // i. Perform ! environment.CreateMutableBinding(name, false). generator.emit(identifier, Bytecode::Op::EnvironmentMode::Lexical, false); } - }); + })); // 3. Return unused. // NOTE: No need to do that as we've inlined this. diff --git a/Userland/Libraries/LibJS/Parser.cpp b/Userland/Libraries/LibJS/Parser.cpp index 503048b651..1261498211 100644 --- a/Userland/Libraries/LibJS/Parser.cpp +++ b/Userland/Libraries/LibJS/Parser.cpp @@ -70,9 +70,10 @@ public: scope_pusher.m_forbidden_lexical_names.set(name); }, [&](NonnullRefPtr const& binding_pattern) { - binding_pattern->for_each_bound_name([&](auto const& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(binding_pattern->for_each_bound_name([&](auto const& name) { scope_pusher.m_forbidden_lexical_names.set(name); - }); + })); }); } return scope_pusher; @@ -94,9 +95,10 @@ public: if (init && is(*init)) { auto& variable_declaration = static_cast(*init); if (variable_declaration.declaration_kind() != DeclarationKind::Var) { - variable_declaration.for_each_bound_name([&](auto const& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(variable_declaration.for_each_bound_name([&](auto const& name) { scope_pusher.m_forbidden_var_names.set(name); - }); + })); } } @@ -107,9 +109,10 @@ public: { ScopePusher scope_pusher(parser, nullptr, ScopeLevel::NotTopLevel); if (pattern) { - pattern->for_each_bound_name([&](auto const& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(pattern->for_each_bound_name([&](auto const& name) { scope_pusher.m_forbidden_var_names.set(name); - }); + })); } else if (!parameter.is_empty()) { scope_pusher.m_var_names.set(parameter); } @@ -129,17 +132,19 @@ public: void add_declaration(NonnullRefPtr declaration) { if (declaration->is_lexical_declaration()) { - declaration->for_each_bound_name([&](auto const& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(declaration->for_each_bound_name([&](auto const& name) { if (m_var_names.contains(name) || m_forbidden_lexical_names.contains(name) || m_function_names.contains(name)) throw_identifier_declared(name, declaration); if (m_lexical_names.set(name) != AK::HashSetResult::InsertedNewEntry) throw_identifier_declared(name, declaration); - }); + })); m_node->add_lexical_declaration(move(declaration)); } else if (!declaration->is_function_declaration()) { - declaration->for_each_bound_name([&](auto const& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(declaration->for_each_bound_name([&](auto const& name) { ScopePusher* pusher = this; while (true) { if (pusher->m_lexical_names.contains(name) @@ -156,16 +161,17 @@ public: } VERIFY(pusher->is_top_level() && pusher->m_node); pusher->m_node->add_var_scoped_declaration(declaration); - }); + })); VERIFY(m_top_level_scope); m_top_level_scope->m_node->add_var_scoped_declaration(move(declaration)); } else { if (m_scope_level != ScopeLevel::NotTopLevel && m_scope_level != ScopeLevel::ModuleTopLevel) { // Only non-top levels and Module don't var declare the top functions - declaration->for_each_bound_name([&](auto const& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(declaration->for_each_bound_name([&](auto const& name) { m_var_names.set(name); - }); + })); m_node->add_var_scoped_declaration(move(declaration)); } else { VERIFY(is(*declaration)); @@ -567,16 +573,18 @@ void Parser::parse_module(Program& program) auto const& exported_name = entry.local_or_import_name; bool found = false; - program.for_each_lexically_declared_name([&](auto const& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(program.for_each_lexically_declared_name([&](auto const& name) { if (name == exported_name) found = true; - }); + })); if (found) continue; - program.for_each_var_declared_name([&](auto const& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(program.for_each_var_declared_name([&](auto const& name) { if (name == exported_name) found = true; - }); + })); for (auto& import : program.imports()) { if (import.has_bound_name(exported_name)) { found = true; @@ -2532,7 +2540,8 @@ NonnullRefPtr Parser::parse_function_body(Vector const& binding) { - binding->for_each_bound_name([&](auto& bound_name) { + // NOTE: Nothing in the callback throws an exception. + MUST(binding->for_each_bound_name([&](auto& bound_name) { if (function_kind == FunctionKind::Generator && bound_name == "yield"sv) syntax_error("Parameter name 'yield' not allowed in this context"); @@ -2546,7 +2555,7 @@ NonnullRefPtr Parser::parse_function_body(Vector Parser::parse_formal_parameters(int& function_length, }, [&](NonnullRefPtr const& bindings) { bool found_duplicate = false; - bindings->for_each_bound_name([&](auto& bound_name) { + // NOTE: Nothing in the callback throws an exception. + MUST(bindings->for_each_bound_name([&](auto& bound_name) { if (bound_name == parameter_name) found_duplicate = true; - }); + })); return found_duplicate; }); @@ -2951,14 +2961,15 @@ RefPtr Parser::parse_binding_pattern(Parser::AllowDuplicat pattern->kind = kind; Vector bound_names; - pattern->for_each_bound_name([&](auto& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(pattern->for_each_bound_name([&](auto& name) { if (allow_duplicates == AllowDuplicates::No) { if (bound_names.contains_slow(name)) syntax_error("Duplicate parameter names in bindings"); bound_names.append(name); } check_identifier_name_for_assignment_validity(name); - }); + })); return pattern; } @@ -3018,10 +3029,11 @@ NonnullRefPtr Parser::parse_variable_declaration(IsFo Variant, NonnullRefPtr, Empty> target {}; if (auto pattern = parse_binding_pattern(declaration_kind != DeclarationKind::Var ? AllowDuplicates::No : AllowDuplicates::Yes, AllowMemberExpressions::No)) { if ((declaration_kind == DeclarationKind::Let || declaration_kind == DeclarationKind::Const)) { - pattern->for_each_bound_name([this](auto& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(pattern->for_each_bound_name([this](auto& name) { if (name == "let"sv) syntax_error("Lexical binding may not be called 'let'"); - }); + })); } target = pattern.release_nonnull(); @@ -3454,11 +3466,12 @@ NonnullRefPtr Parser::parse_catch_clause() HashTable bound_names; if (pattern_parameter) { - pattern_parameter->for_each_bound_name( + // NOTE: Nothing in the callback throws an exception. + MUST(pattern_parameter->for_each_bound_name( [&](auto& name) { check_identifier_name_for_assignment_validity(name); bound_names.set(name); - }); + })); } if (!parameter.is_empty()) { @@ -3469,10 +3482,11 @@ NonnullRefPtr Parser::parse_catch_clause() ScopePusher catch_scope = ScopePusher::catch_scope(*this, pattern_parameter, parameter); auto body = parse_block_statement(); - body->for_each_lexically_declared_name([&](auto const& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(body->for_each_lexically_declared_name([&](auto const& name) { if (bound_names.contains(name)) syntax_error(DeprecatedString::formatted("Identifier '{}' already declared as catch parameter", name)); - }); + })); if (pattern_parameter) { return create_ast_node( @@ -3612,10 +3626,11 @@ NonnullRefPtr Parser::parse_for_statement() } else { // This does not follow the normal declaration structure so we need additional checks. HashTable bound_names; - declaration->for_each_bound_name([&](auto const& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(declaration->for_each_bound_name([&](auto const& name) { if (bound_names.set(name) != AK::HashSetResult::InsertedNewEntry) syntax_error(DeprecatedString::formatted("Identifier '{}' already declared in for loop initializer", name), declaration->source_range().start); - }); + })); } if (match_for_in_of()) { @@ -4650,9 +4665,10 @@ NonnullRefPtr Parser::parse_export_statement(Program& pro entries_with_location.append({ ExportEntry::named_export(identifier->string(), identifier->string()), identifier->source_range().start }); }, [&](NonnullRefPtr const& binding) { - binding->for_each_bound_name([&](auto& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(binding->for_each_bound_name([&](auto& name) { entries_with_location.append({ ExportEntry::named_export(name, name), decl_position }); - }); + })); }); } } @@ -4667,9 +4683,10 @@ NonnullRefPtr Parser::parse_export_statement(Program& pro entries_with_location.append({ ExportEntry::named_export(identifier->string(), identifier->string()), identifier->source_range().start }); }, [&](NonnullRefPtr const& binding) { - binding->for_each_bound_name([&](auto& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(binding->for_each_bound_name([&](auto& name) { entries_with_location.append({ ExportEntry::named_export(name, name), variable_position }); - }); + })); }); } expression = variable_declaration; diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp index 375cde6517..6c04dd0d02 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp @@ -355,10 +355,11 @@ ThrowCompletionOr ECMAScriptFunctionObject::function_declaration_instantia if (pattern->contains_expression()) has_parameter_expressions = true; - pattern->for_each_bound_name([&](auto& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(pattern->for_each_bound_name([&](auto& name) { if (parameter_names.set(name) != AK::HashSetResult::InsertedNewEntry) has_duplicates = true; - }); + })); }); } @@ -374,10 +375,11 @@ ThrowCompletionOr ECMAScriptFunctionObject::function_declaration_instantia Vector functions_to_initialize; if (scope_body) { - scope_body->for_each_var_function_declaration_in_reverse_order([&](FunctionDeclaration const& function) { + // NOTE: Nothing in the callback throws an exception. + MUST(scope_body->for_each_var_function_declaration_in_reverse_order([&](FunctionDeclaration const& function) { if (function_names.set(function.name()) == AK::HashSetResult::InsertedNewEntry) functions_to_initialize.append(function); - }); + })); auto const& arguments_name = vm.names.arguments.as_string(); @@ -385,10 +387,11 @@ ThrowCompletionOr ECMAScriptFunctionObject::function_declaration_instantia arguments_object_needed = false; if (!has_parameter_expressions && arguments_object_needed) { - scope_body->for_each_lexically_declared_name([&](auto const& name) { + // NOTE: Nothing in the callback throws an exception. + MUST(scope_body->for_each_lexically_declared_name([&](auto const& name) { if (name == arguments_name) arguments_object_needed = false; - }); + })); } } else { arguments_object_needed = false; @@ -489,12 +492,14 @@ ThrowCompletionOr ECMAScriptFunctionObject::function_declaration_instantia if (!has_parameter_expressions) { if (scope_body) { - scope_body->for_each_var_declared_name([&](auto const& name) { + // NOTE: Due to the use of MUST with `create_mutable_binding` and `initialize_binding` below, + // an exception should not result from `for_each_var_declared_name`. + MUST(scope_body->for_each_var_declared_name([&](auto const& name) { if (!parameter_names.contains(name) && instantiated_var_names.set(name) == AK::HashSetResult::InsertedNewEntry) { MUST(environment->create_mutable_binding(vm, name, false)); MUST(environment->initialize_binding(vm, name, js_undefined(), Environment::InitializeBindingHint::Normal)); } - }); + })); } var_environment = environment; } else { @@ -502,7 +507,9 @@ ThrowCompletionOr ECMAScriptFunctionObject::function_declaration_instantia callee_context.variable_environment = var_environment; if (scope_body) { - scope_body->for_each_var_declared_name([&](auto const& name) { + // NOTE: Due to the use of MUST with `create_mutable_binding`, `get_binding_value` and `initialize_binding` below, + // an exception should not result from `for_each_var_declared_name`. + MUST(scope_body->for_each_var_declared_name([&](auto const& name) { if (instantiated_var_names.set(name) != AK::HashSetResult::InsertedNewEntry) return; MUST(var_environment->create_mutable_binding(vm, name, false)); @@ -514,13 +521,15 @@ ThrowCompletionOr ECMAScriptFunctionObject::function_declaration_instantia initial_value = MUST(environment->get_binding_value(vm, name, false)); MUST(var_environment->initialize_binding(vm, name, initial_value, Environment::InitializeBindingHint::Normal)); - }); + })); } } // B.3.2.1 Changes to FunctionDeclarationInstantiation, https://tc39.es/ecma262/#sec-web-compat-functiondeclarationinstantiation if (!m_strict && scope_body) { - scope_body->for_each_function_hoistable_with_annexB_extension([&](FunctionDeclaration& function_declaration) { + // NOTE: Due to the use of MUST with `create_mutable_binding` and `initialize_binding` below, + // an exception should not result from `for_each_function_hoistable_with_annexB_extension`. + MUST(scope_body->for_each_function_hoistable_with_annexB_extension([&](FunctionDeclaration& function_declaration) { auto& function_name = function_declaration.name(); if (parameter_names.contains(function_name)) return; @@ -532,7 +541,7 @@ ThrowCompletionOr ECMAScriptFunctionObject::function_declaration_instantia } function_declaration.set_should_do_additional_annexB_steps(); - }); + })); } GCPtr lex_environment; @@ -565,14 +574,17 @@ ThrowCompletionOr ECMAScriptFunctionObject::function_declaration_instantia return {}; if (!Bytecode::Interpreter::current()) { - scope_body->for_each_lexically_scoped_declaration([&](Declaration const& declaration) { - declaration.for_each_bound_name([&](auto const& name) { + // NOTE: Due to the use of MUST in the callback, an exception should not result from `for_each_lexically_scoped_declaration`. + MUST(scope_body->for_each_lexically_scoped_declaration([&](Declaration const& declaration) { + // NOTE: Due to the use of MUST with `create_immutable_binding` and `create_mutable_binding` below, + // an exception should not result from `for_each_bound_name`. + MUST(declaration.for_each_bound_name([&](auto const& name) { if (declaration.is_constant_declaration()) MUST(lex_environment->create_immutable_binding(vm, name, true)); else MUST(lex_environment->create_mutable_binding(vm, name, false)); - }); - }); + })); + })); } auto* private_environment = callee_context.private_environment; diff --git a/Userland/Libraries/LibJS/SourceTextModule.cpp b/Userland/Libraries/LibJS/SourceTextModule.cpp index 89a30312b2..43b0306285 100644 --- a/Userland/Libraries/LibJS/SourceTextModule.cpp +++ b/Userland/Libraries/LibJS/SourceTextModule.cpp @@ -436,7 +436,9 @@ ThrowCompletionOr SourceTextModule::initialize_environment(VM& vm) // 21. For each element d of varDeclarations, do // a. For each element dn of the BoundNames of d, do - m_ecmascript_code->for_each_var_declared_name([&](auto const& name) { + // NOTE: Due to the use of MUST with `create_mutable_binding` and `initialize_binding` below, + // an exception should not result from `for_each_var_declared_name`. + MUST(m_ecmascript_code->for_each_var_declared_name([&](auto const& name) { // i. If dn is not an element of declaredVarNames, then if (!declared_var_names.contains_slow(name)) { // 1. Perform ! env.CreateMutableBinding(dn, false). @@ -448,7 +450,7 @@ ThrowCompletionOr SourceTextModule::initialize_environment(VM& vm) // 3. Append dn to declaredVarNames. declared_var_names.empend(name); } - }); + })); // 22. Let lexDeclarations be the LexicallyScopedDeclarations of code. // Note: We only loop through them in step 24. @@ -457,9 +459,12 @@ ThrowCompletionOr SourceTextModule::initialize_environment(VM& vm) PrivateEnvironment* private_environment = nullptr; // 24. For each element d of lexDeclarations, do - m_ecmascript_code->for_each_lexically_scoped_declaration([&](Declaration const& declaration) { + // NOTE: Due to the use of MUST in the callback, an exception should not result from `for_each_lexically_scoped_declaration`. + MUST(m_ecmascript_code->for_each_lexically_scoped_declaration([&](Declaration const& declaration) { // a. For each element dn of the BoundNames of d, do - declaration.for_each_bound_name([&](DeprecatedFlyString const& name) { + // NOTE: Due to the use of MUST with `create_immutable_binding`, `create_mutable_binding` and `initialize_binding` below, + // an exception should not result from `for_each_bound_name`. + MUST(declaration.for_each_bound_name([&](DeprecatedFlyString const& name) { // i. If IsConstantDeclaration of d is true, then if (declaration.is_constant_declaration()) { // 1. Perform ! env.CreateImmutableBinding(dn, true). @@ -487,8 +492,8 @@ ThrowCompletionOr SourceTextModule::initialize_environment(VM& vm) // 2. Perform ! env.InitializeBinding(dn, fo, normal). MUST(environment->initialize_binding(vm, name, function, Environment::InitializeBindingHint::Normal)); } - }); - }); + })); + })); // Note: The default export name is also part of the local lexical declarations but // instead of making that a special case in the parser we just check it here.