Skip to content

Commit

Permalink
LibJS: Memoize failed calls of try_parse_arrow_function_expression()
Browse files Browse the repository at this point in the history
  • Loading branch information
sunverwerth authored and awesomekling committed Apr 12, 2021
1 parent 435bd84 commit 8c80eb8
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 4 deletions.
29 changes: 25 additions & 4 deletions Userland/Libraries/LibJS/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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:
Expand Down Expand Up @@ -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())
Expand Down
21 changes: 21 additions & 0 deletions Userland/Libraries/LibJS/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ class Parser {
}
}

struct TokenMemoization {
bool try_parse_arrow_function_expression_failed;
};

private:
friend class ScopePusher;

Expand All @@ -172,6 +176,9 @@ class Parser {
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);
Expand Down Expand Up @@ -220,9 +227,23 @@ class Parser {
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;
};
}

0 comments on commit 8c80eb8

Please sign in to comment.