Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: src/preparser.h

Issue 437393004: Rewind additional parser state when reinterpreting arrow arguments (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_PREPARSER_H 5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H 6 #define V8_PREPARSER_H
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/func-name-inferrer.h" 10 #include "src/func-name-inferrer.h"
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; } 107 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; }
108 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } 108 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
109 void set_allow_harmony_scoping(bool allow) { 109 void set_allow_harmony_scoping(bool allow) {
110 scanner()->SetHarmonyScoping(allow); 110 scanner()->SetHarmonyScoping(allow);
111 } 111 }
112 void set_allow_harmony_numeric_literals(bool allow) { 112 void set_allow_harmony_numeric_literals(bool allow) {
113 scanner()->SetHarmonyNumericLiterals(allow); 113 scanner()->SetHarmonyNumericLiterals(allow);
114 } 114 }
115 115
116 protected: 116 protected:
117 friend class Traits::Type::Checkpoint;
118
117 enum AllowEvalOrArgumentsAsIdentifier { 119 enum AllowEvalOrArgumentsAsIdentifier {
118 kAllowEvalOrArguments, 120 kAllowEvalOrArguments,
119 kDontAllowEvalOrArguments 121 kDontAllowEvalOrArguments
120 }; 122 };
121 123
122 enum Mode { 124 enum Mode {
123 PARSE_LAZILY, 125 PARSE_LAZILY,
124 PARSE_EAGERLY 126 PARSE_EAGERLY
125 }; 127 };
126 128
129 class ParserCheckpoint;
130
127 // --------------------------------------------------------------------------- 131 // ---------------------------------------------------------------------------
128 // FunctionState and BlockState together implement the parser's scope stack. 132 // FunctionState and BlockState together implement the parser's scope stack.
129 // The parser's current scope is in scope_. BlockState and FunctionState 133 // The parser's current scope is in scope_. BlockState and FunctionState
130 // constructors push on the scope stack and the destructors pop. They are also 134 // constructors push on the scope stack and the destructors pop. They are also
131 // used to hold the parser's per-function and per-block state. 135 // used to hold the parser's per-function and per-block state.
132 class BlockState BASE_EMBEDDED { 136 class BlockState BASE_EMBEDDED {
133 public: 137 public:
134 BlockState(typename Traits::Type::Scope** scope_stack, 138 BlockState(typename Traits::Type::Scope** scope_stack,
135 typename Traits::Type::Scope* scope) 139 typename Traits::Type::Scope* scope)
136 : scope_stack_(scope_stack), 140 : scope_stack_(scope_stack),
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 216
213 FunctionState** function_state_stack_; 217 FunctionState** function_state_stack_;
214 FunctionState* outer_function_state_; 218 FunctionState* outer_function_state_;
215 typename Traits::Type::Scope** scope_stack_; 219 typename Traits::Type::Scope** scope_stack_;
216 typename Traits::Type::Scope* outer_scope_; 220 typename Traits::Type::Scope* outer_scope_;
217 int saved_ast_node_id_; // Only used by ParserTraits. 221 int saved_ast_node_id_; // Only used by ParserTraits.
218 typename Traits::Type::Zone* extra_param_; 222 typename Traits::Type::Zone* extra_param_;
219 typename Traits::Type::Factory factory_; 223 typename Traits::Type::Factory factory_;
220 224
221 friend class ParserTraits; 225 friend class ParserTraits;
226 friend class ParserCheckpoint;
227 };
228
229 // Annoyingly, arrow functions first parse as comma expressions, then when we
230 // see the => we have to go back and reinterpret the arguments as being formal
231 // parameters. To do so we need to reset some of the parser state back to
232 // what it was before the arguments were first seen.
233 class ParserCheckpoint : public Traits::Type::Checkpoint {
234 public:
235 ParserCheckpoint() : Traits::Type::Checkpoint() {}
236
237 void Save(ParserBase* parser) {
238 Traits::Type::Checkpoint::Save(parser);
239 function_state_ = parser->function_state_;
240 next_materialized_literal_index_ =
241 function_state_->next_materialized_literal_index_;
242 next_handler_index_ = function_state_->next_handler_index_;
243 expected_property_count_ = function_state_->expected_property_count_;
244 }
245
246 void Restore() {
247 Traits::Type::Checkpoint::Restore();
248 function_state_->next_materialized_literal_index_ =
249 next_materialized_literal_index_;
250 function_state_->next_handler_index_ = next_handler_index_;
251 function_state_->expected_property_count_ = expected_property_count_;
252 }
253
254 private:
255 FunctionState* function_state_;
256 int next_materialized_literal_index_;
257 int next_handler_index_;
258 int expected_property_count_;
222 }; 259 };
223 260
224 class ParsingModeScope BASE_EMBEDDED { 261 class ParsingModeScope BASE_EMBEDDED {
225 public: 262 public:
226 ParsingModeScope(ParserBase* parser, Mode mode) 263 ParsingModeScope(ParserBase* parser, Mode mode)
227 : parser_(parser), 264 : parser_(parser),
228 old_mode_(parser->mode()) { 265 old_mode_(parser->mode()) {
229 parser_->mode_ = mode; 266 parser_->mode_ = mode;
230 } 267 }
231 ~ParsingModeScope() { 268 ~ParsingModeScope() {
(...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after
1014 // dummy method right in this class. 1051 // dummy method right in this class.
1015 PreParserFactory* visitor() { return this; } 1052 PreParserFactory* visitor() { return this; }
1016 BailoutReason dont_optimize_reason() { return kNoReason; } 1053 BailoutReason dont_optimize_reason() { return kNoReason; }
1017 int* ast_properties() { 1054 int* ast_properties() {
1018 static int dummy = 42; 1055 static int dummy = 42;
1019 return &dummy; 1056 return &dummy;
1020 } 1057 }
1021 }; 1058 };
1022 1059
1023 1060
1061 class PreParserCheckpoint BASE_EMBEDDED {
1062 public:
1063 PreParserCheckpoint() {}
1064 template <typename Parser>
1065 void Save(Parser* parser) {}
1066 void Restore() {}
1067 };
1068
1069
1024 class PreParser; 1070 class PreParser;
1025 1071
1026 class PreParserTraits { 1072 class PreParserTraits {
1027 public: 1073 public:
1028 struct Type { 1074 struct Type {
1029 // TODO(marja): To be removed. The Traits object should contain all the data 1075 // TODO(marja): To be removed. The Traits object should contain all the data
1030 // it needs. 1076 // it needs.
1031 typedef PreParser* Parser; 1077 typedef PreParser* Parser;
1032 1078
1033 // Used by FunctionState and BlockState. 1079 // Used by FunctionState and BlockState.
1034 typedef PreParserScope Scope; 1080 typedef PreParserScope Scope;
1035 typedef PreParserScope ScopePtr; 1081 typedef PreParserScope ScopePtr;
1082 typedef PreParserCheckpoint Checkpoint;
1036 1083
1037 // PreParser doesn't need to store generator variables. 1084 // PreParser doesn't need to store generator variables.
1038 typedef void GeneratorVariable; 1085 typedef void GeneratorVariable;
1039 // No interaction with Zones. 1086 // No interaction with Zones.
1040 typedef void Zone; 1087 typedef void Zone;
1041 1088
1042 typedef int AstProperties; 1089 typedef int AstProperties;
1043 typedef Vector<PreParserIdentifier> ParameterIdentifierVector; 1090 typedef Vector<PreParserIdentifier> ParameterIdentifierVector;
1044 1091
1045 // Return types for traversing functions. 1092 // Return types for traversing functions.
(...skipping 948 matching lines...) Expand 10 before | Expand all | Expand 10 after
1994 // YieldExpression 2041 // YieldExpression
1995 // LeftHandSideExpression AssignmentOperator AssignmentExpression 2042 // LeftHandSideExpression AssignmentOperator AssignmentExpression
1996 2043
1997 Scanner::Location lhs_location = scanner()->peek_location(); 2044 Scanner::Location lhs_location = scanner()->peek_location();
1998 2045
1999 if (peek() == Token::YIELD && is_generator()) { 2046 if (peek() == Token::YIELD && is_generator()) {
2000 return this->ParseYieldExpression(ok); 2047 return this->ParseYieldExpression(ok);
2001 } 2048 }
2002 2049
2003 if (fni_ != NULL) fni_->Enter(); 2050 if (fni_ != NULL) fni_->Enter();
2051 ParserCheckpoint checkpoint;
2052 checkpoint.Save(this);
rossberg 2014/08/05 13:51:31 Why the separate Save method instead of just Pa
2004 ExpressionT expression = 2053 ExpressionT expression =
2005 this->ParseConditionalExpression(accept_IN, CHECK_OK); 2054 this->ParseConditionalExpression(accept_IN, CHECK_OK);
2006 2055
2007 if (allow_arrow_functions() && peek() == Token::ARROW) { 2056 if (allow_arrow_functions() && peek() == Token::ARROW) {
2057 checkpoint.Restore();
2008 expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos, 2058 expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos,
2009 expression, CHECK_OK); 2059 expression, CHECK_OK);
2010 return expression; 2060 return expression;
2011 } 2061 }
2012 2062
2013 if (!Token::IsAssignmentOp(peek())) { 2063 if (!Token::IsAssignmentOp(peek())) {
2014 if (fni_ != NULL) fni_->Leave(); 2064 if (fni_ != NULL) fni_->Leave();
2015 // Parsed conditional expression only (no assignment). 2065 // Parsed conditional expression only (no assignment).
2016 return expression; 2066 return expression;
2017 } 2067 }
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after
2604 parser()->ReportMessage("accessor_get_set"); 2654 parser()->ReportMessage("accessor_get_set");
2605 } 2655 }
2606 *ok = false; 2656 *ok = false;
2607 } 2657 }
2608 } 2658 }
2609 2659
2610 2660
2611 } } // v8::internal 2661 } } // v8::internal
2612 2662
2613 #endif // V8_PREPARSER_H 2663 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « src/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698