Index: src/preparser.h |
diff --git a/src/preparser.h b/src/preparser.h |
index 517403d34733eba81ea86c7bedd38162feded389..b00cbbbd477cf2ea175fc4e62f3f180e23de5122 100644 |
--- a/src/preparser.h |
+++ b/src/preparser.h |
@@ -114,6 +114,8 @@ class ParserBase : public Traits { |
} |
protected: |
+ friend class Traits::Type::Checkpoint; |
+ |
enum AllowEvalOrArgumentsAsIdentifier { |
kAllowEvalOrArguments, |
kDontAllowEvalOrArguments |
@@ -124,6 +126,8 @@ class ParserBase : public Traits { |
PARSE_EAGERLY |
}; |
+ class ParserCheckpoint; |
+ |
// --------------------------------------------------------------------------- |
// FunctionState and BlockState together implement the parser's scope stack. |
// The parser's current scope is in scope_. BlockState and FunctionState |
@@ -219,6 +223,38 @@ class ParserBase : public Traits { |
typename Traits::Type::Factory factory_; |
friend class ParserTraits; |
+ friend class ParserCheckpoint; |
+ }; |
+ |
+ // Annoyingly, arrow functions first parse as comma expressions, then when we |
+ // see the => we have to go back and reinterpret the arguments as being formal |
+ // parameters. To do so we need to reset some of the parser state back to |
+ // what it was before the arguments were first seen. |
+ class ParserCheckpoint : public Traits::Type::Checkpoint { |
+ public: |
+ template <typename Parser> |
+ explicit ParserCheckpoint(Parser* parser) |
+ : Traits::Type::Checkpoint(parser) { |
+ function_state_ = parser->function_state_; |
+ next_materialized_literal_index_ = |
+ function_state_->next_materialized_literal_index_; |
+ next_handler_index_ = function_state_->next_handler_index_; |
+ expected_property_count_ = function_state_->expected_property_count_; |
+ } |
+ |
+ void Restore() { |
+ Traits::Type::Checkpoint::Restore(); |
+ function_state_->next_materialized_literal_index_ = |
+ next_materialized_literal_index_; |
+ function_state_->next_handler_index_ = next_handler_index_; |
+ function_state_->expected_property_count_ = expected_property_count_; |
+ } |
+ |
+ private: |
+ FunctionState* function_state_; |
+ int next_materialized_literal_index_; |
+ int next_handler_index_; |
+ int expected_property_count_; |
}; |
class ParsingModeScope BASE_EMBEDDED { |
@@ -1034,6 +1070,13 @@ class PreParserTraits { |
typedef PreParserScope Scope; |
typedef PreParserScope ScopePtr; |
+ class Checkpoint BASE_EMBEDDED { |
+ public: |
+ template <typename Parser> |
+ explicit Checkpoint(Parser* parser) {} |
+ void Restore() {} |
+ }; |
+ |
// PreParser doesn't need to store generator variables. |
typedef void GeneratorVariable; |
// No interaction with Zones. |
@@ -2006,10 +2049,12 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
} |
if (fni_ != NULL) fni_->Enter(); |
+ ParserCheckpoint checkpoint(this); |
ExpressionT expression = |
this->ParseConditionalExpression(accept_IN, CHECK_OK); |
if (allow_arrow_functions() && peek() == Token::ARROW) { |
+ checkpoint.Restore(); |
expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos, |
expression, CHECK_OK); |
return expression; |