Chromium Code Reviews| Index: src/preparser.h |
| diff --git a/src/preparser.h b/src/preparser.h |
| index ff6bd2728c929e865e90d137cf9040177b8b5e9f..183fb91e84d85ea6ee3e059bc4258461193d9a9d 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,39 @@ 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: |
| + ParserCheckpoint() : Traits::Type::Checkpoint() {} |
| + |
| + void Save(ParserBase* parser) { |
| + Traits::Type::Checkpoint::Save(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 { |
| @@ -1021,6 +1058,15 @@ class PreParserFactory { |
| }; |
| +class PreParserCheckpoint BASE_EMBEDDED { |
| + public: |
| + PreParserCheckpoint() {} |
| + template <typename Parser> |
| + void Save(Parser* parser) {} |
| + void Restore() {} |
| +}; |
| + |
| + |
| class PreParser; |
| class PreParserTraits { |
| @@ -1033,6 +1079,7 @@ class PreParserTraits { |
| // Used by FunctionState and BlockState. |
| typedef PreParserScope Scope; |
| typedef PreParserScope ScopePtr; |
| + typedef PreParserCheckpoint Checkpoint; |
| // PreParser doesn't need to store generator variables. |
| typedef void GeneratorVariable; |
| @@ -2001,10 +2048,13 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| } |
| if (fni_ != NULL) fni_->Enter(); |
| + ParserCheckpoint checkpoint; |
| + checkpoint.Save(this); |
|
rossberg
2014/08/05 13:51:31
Why the separate Save method instead of just
Pa
|
| 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; |