From d0363bca019758a004fb75fbdbb1e0f46086c312 Mon Sep 17 00:00:00 2001 From: AnotherTest Date: Tue, 29 Dec 2020 08:42:02 +0330 Subject: [PATCH] LibJS: `save_state()' before creating a RulePosition Fixes #4617. --- Libraries/LibJS/Parser.cpp | 9 ++++++--- Libraries/LibJS/Parser.h | 8 ++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Libraries/LibJS/Parser.cpp b/Libraries/LibJS/Parser.cpp index 2edb9f6bf3..f70ac3b2fa 100644 --- a/Libraries/LibJS/Parser.cpp +++ b/Libraries/LibJS/Parser.cpp @@ -361,12 +361,13 @@ NonnullRefPtr Parser::parse_statement() RefPtr Parser::try_parse_arrow_function_expression(bool expect_parens) { - auto rule_start = push_start(); save_state(); m_parser_state.m_var_scopes.append(NonnullRefPtrVector()); + auto rule_start = push_start(); ArmedScopeGuard state_rollback_guard = [&] { m_parser_state.m_var_scopes.take_last(); + rule_start.disable(); load_state(); }; @@ -442,9 +443,10 @@ RefPtr Parser::try_parse_arrow_function_expression(bool expe RefPtr Parser::try_parse_labelled_statement() { - auto rule_start = push_start(); save_state(); + auto rule_start = push_start(); ArmedScopeGuard state_rollback_guard = [&] { + rule_start.disable(); load_state(); }; @@ -466,9 +468,10 @@ RefPtr Parser::try_parse_labelled_statement() RefPtr Parser::try_parse_new_target_expression() { - auto rule_start = push_start(); save_state(); + auto rule_start = push_start(); ArmedScopeGuard state_rollback_guard = [&] { + rule_start.disable(); load_state(); }; diff --git a/Libraries/LibJS/Parser.h b/Libraries/LibJS/Parser.h index 0c348924cc..22776ae959 100644 --- a/Libraries/LibJS/Parser.h +++ b/Libraries/LibJS/Parser.h @@ -172,6 +172,10 @@ private: Position position() const; struct RulePosition { + AK_MAKE_NONCOPYABLE(RulePosition); + AK_MAKE_NONMOVABLE(RulePosition); + + public: RulePosition(Parser& parser, Position position) : m_parser(parser) , m_position(position) @@ -181,16 +185,20 @@ private: ~RulePosition() { + if (!m_enabled) + return; auto last = m_parser.m_parser_state.m_rule_starts.take_last(); ASSERT(last.line == m_position.line); ASSERT(last.column == m_position.column); } const Position& position() const { return m_position; } + void disable() { m_enabled = false; } private: Parser& m_parser; Position m_position; + bool m_enabled { true }; }; [[nodiscard]] RulePosition push_start() { return { *this, position() }; }