Browse Source

LibJS: `save_state()' before creating a RulePosition

Fixes #4617.
AnotherTest 4 years ago
parent
commit
d0363bca01
2 changed files with 14 additions and 3 deletions
  1. 6 3
      Libraries/LibJS/Parser.cpp
  2. 8 0
      Libraries/LibJS/Parser.h

+ 6 - 3
Libraries/LibJS/Parser.cpp

@@ -361,12 +361,13 @@ NonnullRefPtr<Statement> Parser::parse_statement()
 
 RefPtr<FunctionExpression> Parser::try_parse_arrow_function_expression(bool expect_parens)
 {
-    auto rule_start = push_start();
     save_state();
     m_parser_state.m_var_scopes.append(NonnullRefPtrVector<VariableDeclaration>());
+    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<FunctionExpression> Parser::try_parse_arrow_function_expression(bool expe
 
 RefPtr<Statement> 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<Statement> Parser::try_parse_labelled_statement()
 
 RefPtr<MetaProperty> 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();
     };
 

+ 8 - 0
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() }; }