LibJS: Memoize failed calls of try_parse_arrow_function_expression()
This commit is contained in:
parent
435bd841ee
commit
8c80eb8870
Notes:
sideshowbarker
2024-07-18 20:29:30 +09:00
Author: https://github.com/sunverwerth Commit: https://github.com/SerenityOS/serenity/commit/8c80eb8870f Pull-request: https://github.com/SerenityOS/serenity/pull/6251 Issue: https://github.com/SerenityOS/serenity/issues/3349
2 changed files with 46 additions and 4 deletions
Userland/Libraries/LibJS
|
@ -627,11 +627,14 @@ NonnullRefPtr<Expression> Parser::parse_primary_expression()
|
|||
|
||||
switch (m_parser_state.m_current_token.type()) {
|
||||
case TokenType::ParenOpen: {
|
||||
auto paren_position = position();
|
||||
consume(TokenType::ParenOpen);
|
||||
if (match(TokenType::ParenClose) || match(TokenType::Identifier) || match(TokenType::TripleDot)) {
|
||||
if ((match(TokenType::ParenClose) || match(TokenType::Identifier) || match(TokenType::TripleDot)) && !try_parse_arrow_function_expression_failed_at_position(paren_position)) {
|
||||
auto arrow_function_result = try_parse_arrow_function_expression(true);
|
||||
if (!arrow_function_result.is_null())
|
||||
return arrow_function_result.release_nonnull();
|
||||
|
||||
set_try_parse_arrow_function_expression_failed_at_position(paren_position, true);
|
||||
}
|
||||
auto expression = parse_expression(0);
|
||||
consume(TokenType::ParenClose);
|
||||
|
@ -651,9 +654,13 @@ NonnullRefPtr<Expression> Parser::parse_primary_expression()
|
|||
syntax_error("'super' keyword unexpected here");
|
||||
return create_ast_node<SuperExpression>({ m_parser_state.m_current_token.filename(), rule_start.position(), position() });
|
||||
case TokenType::Identifier: {
|
||||
auto arrow_function_result = try_parse_arrow_function_expression(false);
|
||||
if (!arrow_function_result.is_null())
|
||||
return arrow_function_result.release_nonnull();
|
||||
if (!try_parse_arrow_function_expression_failed_at_position(position())) {
|
||||
auto arrow_function_result = try_parse_arrow_function_expression(false);
|
||||
if (!arrow_function_result.is_null())
|
||||
return arrow_function_result.release_nonnull();
|
||||
|
||||
set_try_parse_arrow_function_expression_failed_at_position(position(), true);
|
||||
}
|
||||
return create_ast_node<Identifier>({ m_parser_state.m_current_token.filename(), rule_start.position(), position() }, consume().value());
|
||||
}
|
||||
case TokenType::NumericLiteral:
|
||||
|
@ -2039,6 +2046,20 @@ Position Parser::position() const
|
|||
};
|
||||
}
|
||||
|
||||
bool Parser::try_parse_arrow_function_expression_failed_at_position(const Position& position) const
|
||||
{
|
||||
auto it = m_token_memoizations.find(position);
|
||||
if (it == m_token_memoizations.end())
|
||||
return false;
|
||||
|
||||
return (*it).value.try_parse_arrow_function_expression_failed;
|
||||
}
|
||||
|
||||
void Parser::set_try_parse_arrow_function_expression_failed_at_position(const Position& position, bool failed)
|
||||
{
|
||||
m_token_memoizations.set(position, { failed });
|
||||
}
|
||||
|
||||
void Parser::syntax_error(const String& message, Optional<Position> position)
|
||||
{
|
||||
if (!position.has_value())
|
||||
|
|
|
@ -147,6 +147,10 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
struct TokenMemoization {
|
||||
bool try_parse_arrow_function_expression_failed;
|
||||
};
|
||||
|
||||
private:
|
||||
friend class ScopePusher;
|
||||
|
||||
|
@ -172,6 +176,9 @@ private:
|
|||
void discard_saved_state();
|
||||
Position position() const;
|
||||
|
||||
bool try_parse_arrow_function_expression_failed_at_position(const Position&) const;
|
||||
void set_try_parse_arrow_function_expression_failed_at_position(const Position&, bool);
|
||||
|
||||
struct RulePosition {
|
||||
AK_MAKE_NONCOPYABLE(RulePosition);
|
||||
AK_MAKE_NONMOVABLE(RulePosition);
|
||||
|
@ -220,9 +227,23 @@ private:
|
|||
explicit ParserState(Lexer);
|
||||
};
|
||||
|
||||
class PositionKeyTraits {
|
||||
public:
|
||||
static int hash(const Position& position)
|
||||
{
|
||||
return int_hash(position.line) ^ int_hash(position.column);
|
||||
}
|
||||
|
||||
static bool equals(const Position& a, const Position& b)
|
||||
{
|
||||
return a.column == b.column && a.line == b.line;
|
||||
}
|
||||
};
|
||||
|
||||
Vector<Position> m_rule_starts;
|
||||
ParserState m_parser_state;
|
||||
FlyString m_filename;
|
||||
Vector<ParserState> m_saved_state;
|
||||
HashMap<Position, TokenMemoization, PositionKeyTraits> m_token_memoizations;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue