diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index 1f0a40b8273..af35cf7892c 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -1378,19 +1378,17 @@ void TryStatement::dump(int indent) const void CatchClause::dump(int indent) const { print_indent(indent); + outln("CatchClause"); m_parameter.visit( - [&](FlyString const& parameter) { - if (parameter.is_empty()) - outln("CatchClause"); - else - outln("CatchClause ({})", parameter); + [&](NonnullRefPtr const& parameter) { + parameter->dump(indent + 1); }, [&](NonnullRefPtr const& pattern) { - outln("CatchClause"); print_indent(indent); outln("(Parameter)"); pattern->dump(indent + 2); - }); + }, + [&](Empty) {}); body().dump(indent + 1); } diff --git a/Libraries/LibJS/AST.h b/Libraries/LibJS/AST.h index 741d9f519e5..901033c65ee 100644 --- a/Libraries/LibJS/AST.h +++ b/Libraries/LibJS/AST.h @@ -2075,7 +2075,7 @@ private: class CatchClause final : public ASTNode { public: - CatchClause(SourceRange source_range, FlyString parameter, NonnullRefPtr body) + CatchClause(SourceRange source_range, NonnullRefPtr parameter, NonnullRefPtr body) : ASTNode(move(source_range)) , m_parameter(move(parameter)) , m_body(move(body)) @@ -2089,13 +2089,20 @@ public: { } + CatchClause(SourceRange source_range, NonnullRefPtr body) + : ASTNode(move(source_range)) + , m_parameter(Empty {}) + , m_body(move(body)) + { + } + auto& parameter() const { return m_parameter; } BlockStatement const& body() const { return m_body; } virtual void dump(int indent) const override; private: - Variant> m_parameter; + Variant, NonnullRefPtr, Empty> m_parameter; NonnullRefPtr m_body; }; diff --git a/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Libraries/LibJS/Bytecode/ASTCodegen.cpp index ce12c6ceddf..1b2fbd7a921 100644 --- a/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -2660,14 +2660,12 @@ Bytecode::CodeGenerationErrorOr> TryStatement::generate_ bool did_create_variable_scope_for_catch_clause = false; TRY(m_handler->parameter().visit( - [&](FlyString const& parameter) -> Bytecode::CodeGenerationErrorOr { - if (!parameter.is_empty()) { - generator.begin_variable_scope(); - did_create_variable_scope_for_catch_clause = true; - auto parameter_identifier = generator.intern_identifier(parameter); - generator.emit(parameter_identifier, Bytecode::Op::EnvironmentMode::Lexical, false); - generator.emit(parameter_identifier, caught_value); - } + [&](NonnullRefPtr const& parameter) -> Bytecode::CodeGenerationErrorOr { + generator.begin_variable_scope(); + did_create_variable_scope_for_catch_clause = true; + auto parameter_identifier = generator.intern_identifier(parameter->string()); + generator.emit(parameter_identifier, Bytecode::Op::EnvironmentMode::Lexical, false); + generator.emit(parameter_identifier, caught_value); return {}; }, [&](NonnullRefPtr const& binding_pattern) -> Bytecode::CodeGenerationErrorOr { @@ -2675,6 +2673,9 @@ Bytecode::CodeGenerationErrorOr> TryStatement::generate_ did_create_variable_scope_for_catch_clause = true; TRY(binding_pattern->generate_bytecode(generator, Bytecode::Op::BindingInitializationMode::Initialize, caught_value, true)); return {}; + }, + [](Empty) -> Bytecode::CodeGenerationErrorOr { + return {}; })); auto handler_result = TRY(m_handler->body().generate_bytecode(generator)); diff --git a/Libraries/LibJS/Parser.cpp b/Libraries/LibJS/Parser.cpp index 0067ccedb60..67a712bdba6 100644 --- a/Libraries/LibJS/Parser.cpp +++ b/Libraries/LibJS/Parser.cpp @@ -105,7 +105,7 @@ public: return scope_pusher; } - static ScopePusher catch_scope(Parser& parser, RefPtr const& pattern, FlyString const& parameter) + static ScopePusher catch_scope(Parser& parser, RefPtr const& pattern, RefPtr const& parameter) { ScopePusher scope_pusher(parser, nullptr, ScopeLevel::NotTopLevel, ScopeType::Catch); if (pattern) { @@ -114,9 +114,9 @@ public: scope_pusher.m_forbidden_var_names.set(identifier.string()); scope_pusher.m_bound_names.set(identifier.string()); })); - } else if (!parameter.is_empty()) { - scope_pusher.m_var_names.set(parameter); - scope_pusher.m_bound_names.set(parameter); + } else if (parameter) { + scope_pusher.m_var_names.set(parameter->string()); + scope_pusher.m_bound_names.set(parameter->string()); } return scope_pusher; @@ -3777,7 +3777,7 @@ NonnullRefPtr Parser::parse_catch_clause() auto rule_start = push_start(); consume(TokenType::Catch); - FlyString parameter; + RefPtr parameter; RefPtr pattern_parameter; auto should_expect_parameter = false; if (match(TokenType::ParenOpen)) { @@ -3787,14 +3787,15 @@ NonnullRefPtr Parser::parse_catch_clause() if (match_identifier_name() && (!match(TokenType::Yield) || !m_state.in_generator_function_context) && (!match(TokenType::Async) || !m_state.await_expression_is_valid) - && (!match(TokenType::Await) || !m_state.in_class_static_init_block)) - parameter = consume().fly_string_value(); - else + && (!match(TokenType::Await) || !m_state.in_class_static_init_block)) { + parameter = parse_identifier(); + } else { pattern_parameter = parse_binding_pattern(AllowDuplicates::No, AllowMemberExpressions::No); + } consume(TokenType::ParenClose); } - if (should_expect_parameter && parameter.is_empty() && !pattern_parameter) + if (should_expect_parameter && !parameter && !pattern_parameter) expected("an identifier or a binding pattern"); HashTable bound_names; @@ -3808,9 +3809,9 @@ NonnullRefPtr Parser::parse_catch_clause() })); } - if (!parameter.is_empty()) { - check_identifier_name_for_assignment_validity(parameter); - bound_names.set(parameter); + if (parameter) { + check_identifier_name_for_assignment_validity(parameter->string()); + bound_names.set(parameter->string()); } ScopePusher catch_scope = ScopePusher::catch_scope(*this, pattern_parameter, parameter); @@ -3829,9 +3830,15 @@ NonnullRefPtr Parser::parse_catch_clause() move(body)); } + if (parameter) { + return create_ast_node( + { m_source_code, rule_start.position(), position() }, + parameter.release_nonnull(), + move(body)); + } + return create_ast_node( { m_source_code, rule_start.position(), position() }, - move(parameter), move(body)); }