| OLD | NEW |
| 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/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
| 11 #include "src/func-name-inferrer.h" | 11 #include "src/func-name-inferrer.h" |
| 12 #include "src/hashmap.h" | 12 #include "src/hashmap.h" |
| 13 #include "src/scanner.h" | 13 #include "src/scanner.h" |
| 14 #include "src/scopes.h" | 14 #include "src/scopes.h" |
| 15 #include "src/token.h" | 15 #include "src/token.h" |
| 16 #include "src/zone.h" |
| 16 | 17 |
| 17 namespace v8 { | 18 namespace v8 { |
| 18 namespace internal { | 19 namespace internal { |
| 19 | 20 |
| 20 // Common base class shared between parser and pre-parser. Traits encapsulate | 21 // Common base class shared between parser and pre-parser. Traits encapsulate |
| 21 // the differences between Parser and PreParser: | 22 // the differences between Parser and PreParser: |
| 22 | 23 |
| 23 // - Return types: For example, Parser functions return Expression* and | 24 // - Return types: For example, Parser functions return Expression* and |
| 24 // PreParser functions return PreParserExpression. | 25 // PreParser functions return PreParserExpression. |
| 25 | 26 |
| 26 // - Creating parse tree nodes: Parser generates an AST during the recursive | 27 // - Creating parse tree nodes: Parser generates an AST during the recursive |
| 27 // descent. PreParser doesn't create a tree. Instead, it passes around minimal | 28 // descent. PreParser doesn't create a tree. Instead, it passes around minimal |
| 28 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain | 29 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain |
| 29 // just enough data for the upper layer functions. PreParserFactory is | 30 // just enough data for the upper layer functions. PreParserFactory is |
| 30 // responsible for creating these dummy objects. It provides a similar kind of | 31 // responsible for creating these dummy objects. It provides a similar kind of |
| 31 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is | 32 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is |
| 32 // used. | 33 // used. |
| 33 | 34 |
| 34 // - Miscellaneous other tasks interleaved with the recursive descent. For | 35 // - Miscellaneous other tasks interleaved with the recursive descent. For |
| 35 // example, Parser keeps track of which function literals should be marked as | 36 // example, Parser keeps track of which function literals should be marked as |
| 36 // pretenured, and PreParser doesn't care. | 37 // pretenured, and PreParser doesn't care. |
| 37 | 38 |
| 38 // The traits are expected to contain the following typedefs: | 39 // The traits are expected to contain the following typedefs: |
| 39 // struct Traits { | 40 // struct Traits { |
| 40 // // In particular... | 41 // // In particular... |
| 41 // struct Type { | 42 // struct Type { |
| 42 // // Used by FunctionState and BlockState. | 43 // // Used by FunctionState and BlockState. |
| 43 // typedef Scope; | 44 // typedef Scope; |
| 44 // typedef GeneratorVariable; | 45 // typedef GeneratorVariable; |
| 45 // typedef Zone; | |
| 46 // // Return types for traversing functions. | 46 // // Return types for traversing functions. |
| 47 // typedef Identifier; | 47 // typedef Identifier; |
| 48 // typedef Expression; | 48 // typedef Expression; |
| 49 // typedef FunctionLiteral; | 49 // typedef FunctionLiteral; |
| 50 // typedef ClassLiteral; | 50 // typedef ClassLiteral; |
| 51 // typedef ObjectLiteralProperty; | 51 // typedef ObjectLiteralProperty; |
| 52 // typedef Literal; | 52 // typedef Literal; |
| 53 // typedef ExpressionList; | 53 // typedef ExpressionList; |
| 54 // typedef PropertyList; | 54 // typedef PropertyList; |
| 55 // // For constructing objects returned by the traversing functions. | 55 // // For constructing objects returned by the traversing functions. |
| 56 // typedef Factory; | 56 // typedef Factory; |
| 57 // }; | 57 // }; |
| 58 // // ... | 58 // // ... |
| 59 // }; | 59 // }; |
| 60 | 60 |
| 61 template <typename Traits> | 61 template <typename Traits> |
| 62 class ParserBase : public Traits { | 62 class ParserBase : public Traits { |
| 63 public: | 63 public: |
| 64 // Shorten type names defined by Traits. | 64 // Shorten type names defined by Traits. |
| 65 typedef typename Traits::Type::Expression ExpressionT; | 65 typedef typename Traits::Type::Expression ExpressionT; |
| 66 typedef typename Traits::Type::Identifier IdentifierT; | 66 typedef typename Traits::Type::Identifier IdentifierT; |
| 67 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; | 67 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; |
| 68 typedef typename Traits::Type::Literal LiteralT; | 68 typedef typename Traits::Type::Literal LiteralT; |
| 69 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; | 69 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; |
| 70 | 70 |
| 71 ParserBase(Scanner* scanner, uintptr_t stack_limit, v8::Extension* extension, | 71 ParserBase(Scanner* scanner, uintptr_t stack_limit, v8::Extension* extension, |
| 72 ParserRecorder* log, typename Traits::Type::Zone* zone, | 72 ParserRecorder* log, Zone* zone, |
| 73 typename Traits::Type::Parser this_object) | 73 typename Traits::Type::Parser this_object) |
| 74 : Traits(this_object), | 74 : Traits(this_object), |
| 75 parenthesized_function_(false), | 75 parenthesized_function_(false), |
| 76 scope_(NULL), | 76 scope_(NULL), |
| 77 function_state_(NULL), | 77 function_state_(NULL), |
| 78 extension_(extension), | 78 extension_(extension), |
| 79 fni_(NULL), | 79 fni_(NULL), |
| 80 log_(log), | 80 log_(log), |
| 81 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. | 81 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. |
| 82 stack_limit_(stack_limit), | 82 stack_limit_(stack_limit), |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 void set_allow_harmony_object_literals(bool allow) { | 119 void set_allow_harmony_object_literals(bool allow) { |
| 120 allow_harmony_object_literals_ = allow; | 120 allow_harmony_object_literals_ = allow; |
| 121 } | 121 } |
| 122 | 122 |
| 123 protected: | 123 protected: |
| 124 enum AllowEvalOrArgumentsAsIdentifier { | 124 enum AllowEvalOrArgumentsAsIdentifier { |
| 125 kAllowEvalOrArguments, | 125 kAllowEvalOrArguments, |
| 126 kDontAllowEvalOrArguments | 126 kDontAllowEvalOrArguments |
| 127 }; | 127 }; |
| 128 | 128 |
| 129 enum Mode { | 129 enum Mode { PARSE_LAZILY, PARSE_EAGERLY, PARSE_INNER_FUNCTION_LAZILY }; |
| 130 PARSE_LAZILY, | |
| 131 PARSE_EAGERLY | |
| 132 }; | |
| 133 | 130 |
| 134 class Checkpoint; | 131 class Checkpoint; |
| 135 class ObjectLiteralChecker; | 132 class ObjectLiteralChecker; |
| 136 | 133 |
| 137 // --------------------------------------------------------------------------- | 134 // --------------------------------------------------------------------------- |
| 138 // FunctionState and BlockState together implement the parser's scope stack. | 135 // FunctionState and BlockState together implement the parser's scope stack. |
| 139 // The parser's current scope is in scope_. BlockState and FunctionState | 136 // The parser's current scope is in scope_. BlockState and FunctionState |
| 140 // constructors push on the scope stack and the destructors pop. They are also | 137 // constructors push on the scope stack and the destructors pop. They are also |
| 141 // used to hold the parser's per-function and per-block state. | 138 // used to hold the parser's per-function and per-block state. |
| 142 class BlockState BASE_EMBEDDED { | 139 class BlockState BASE_EMBEDDED { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 bool is_generator_; | 207 bool is_generator_; |
| 211 // For generators, this variable may hold the generator object. It variable | 208 // For generators, this variable may hold the generator object. It variable |
| 212 // is used by yield expressions and return statements. It is not necessary | 209 // is used by yield expressions and return statements. It is not necessary |
| 213 // for generator functions to have this variable set. | 210 // for generator functions to have this variable set. |
| 214 Variable* generator_object_variable_; | 211 Variable* generator_object_variable_; |
| 215 | 212 |
| 216 FunctionState** function_state_stack_; | 213 FunctionState** function_state_stack_; |
| 217 FunctionState* outer_function_state_; | 214 FunctionState* outer_function_state_; |
| 218 typename Traits::Type::Scope** scope_stack_; | 215 typename Traits::Type::Scope** scope_stack_; |
| 219 typename Traits::Type::Scope* outer_scope_; | 216 typename Traits::Type::Scope* outer_scope_; |
| 220 typename Traits::Type::Zone* extra_param_; | |
| 221 typename Traits::Type::Factory* factory_; | 217 typename Traits::Type::Factory* factory_; |
| 222 | 218 |
| 223 friend class ParserTraits; | 219 friend class ParserTraits; |
| 224 friend class Checkpoint; | 220 friend class Checkpoint; |
| 225 }; | 221 }; |
| 226 | 222 |
| 227 // Annoyingly, arrow functions first parse as comma expressions, then when we | 223 // Annoyingly, arrow functions first parse as comma expressions, then when we |
| 228 // see the => we have to go back and reinterpret the arguments as being formal | 224 // see the => we have to go back and reinterpret the arguments as being formal |
| 229 // parameters. To do so we need to reset some of the parser state back to | 225 // parameters. To do so we need to reset some of the parser state back to |
| 230 // what it was before the arguments were first seen. | 226 // what it was before the arguments were first seen. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 ParserBase* parser_; | 263 ParserBase* parser_; |
| 268 Mode old_mode_; | 264 Mode old_mode_; |
| 269 }; | 265 }; |
| 270 | 266 |
| 271 Scanner* scanner() const { return scanner_; } | 267 Scanner* scanner() const { return scanner_; } |
| 272 int position() { return scanner_->location().beg_pos; } | 268 int position() { return scanner_->location().beg_pos; } |
| 273 int peek_position() { return scanner_->peek_location().beg_pos; } | 269 int peek_position() { return scanner_->peek_location().beg_pos; } |
| 274 bool stack_overflow() const { return stack_overflow_; } | 270 bool stack_overflow() const { return stack_overflow_; } |
| 275 void set_stack_overflow() { stack_overflow_ = true; } | 271 void set_stack_overflow() { stack_overflow_ = true; } |
| 276 Mode mode() const { return mode_; } | 272 Mode mode() const { return mode_; } |
| 277 typename Traits::Type::Zone* zone() const { return zone_; } | 273 Zone* zone() const { return zone_; } |
| 278 | 274 |
| 279 INLINE(Token::Value peek()) { | 275 INLINE(Token::Value peek()) { |
| 280 if (stack_overflow_) return Token::ILLEGAL; | 276 if (stack_overflow_) return Token::ILLEGAL; |
| 281 return scanner()->peek(); | 277 return scanner()->peek(); |
| 282 } | 278 } |
| 283 | 279 |
| 284 INLINE(Token::Value Next()) { | 280 INLINE(Token::Value Next()) { |
| 285 if (stack_overflow_) return Token::ILLEGAL; | 281 if (stack_overflow_) return Token::ILLEGAL; |
| 286 { | 282 { |
| 287 if (GetCurrentStackPosition() < stack_limit_) { | 283 if (GetCurrentStackPosition() < stack_limit_) { |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 | 565 |
| 570 private: | 566 private: |
| 571 Scanner* scanner_; | 567 Scanner* scanner_; |
| 572 bool stack_overflow_; | 568 bool stack_overflow_; |
| 573 | 569 |
| 574 bool allow_lazy_; | 570 bool allow_lazy_; |
| 575 bool allow_natives_syntax_; | 571 bool allow_natives_syntax_; |
| 576 bool allow_arrow_functions_; | 572 bool allow_arrow_functions_; |
| 577 bool allow_harmony_object_literals_; | 573 bool allow_harmony_object_literals_; |
| 578 | 574 |
| 579 typename Traits::Type::Zone* zone_; // Only used by Parser. | 575 Zone* zone_; |
| 580 }; | 576 }; |
| 581 | 577 |
| 582 | 578 |
| 583 class PreParserIdentifier { | 579 class PreParserIdentifier { |
| 584 public: | 580 public: |
| 585 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 581 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
| 586 static PreParserIdentifier Default() { | 582 static PreParserIdentifier Default() { |
| 587 return PreParserIdentifier(kUnknownIdentifier); | 583 return PreParserIdentifier(kUnknownIdentifier); |
| 588 } | 584 } |
| 589 static PreParserIdentifier Eval() { | 585 static PreParserIdentifier Eval() { |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 927 public: | 923 public: |
| 928 // These functions make list->Add(some_expression) work as no-ops. | 924 // These functions make list->Add(some_expression) work as no-ops. |
| 929 PreParserStatementList() {} | 925 PreParserStatementList() {} |
| 930 PreParserStatementList* operator->() { return this; } | 926 PreParserStatementList* operator->() { return this; } |
| 931 void Add(PreParserStatement, void*) {} | 927 void Add(PreParserStatement, void*) {} |
| 932 }; | 928 }; |
| 933 | 929 |
| 934 | 930 |
| 935 class PreParserScope { | 931 class PreParserScope { |
| 936 public: | 932 public: |
| 937 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type, | 933 PreParserScope(PreParserScope* outer_scope, ScopeType scope_type, Zone* zone, |
| 938 void* = NULL) | 934 bool log_identifiers) |
| 939 : scope_type_(scope_type) { | 935 : outer_scope_(outer_scope), |
| 936 scope_type_(scope_type), |
| 937 zone_(zone), |
| 938 declared_variables_(NULL), |
| 939 unbound_variables_(NULL) { |
| 940 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; | 940 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; |
| 941 if (log_identifiers && is_declaration_scope()) { |
| 942 ZoneAllocationPolicy allocator(zone); |
| 943 declared_variables_ = new (zone->New(sizeof(ZoneHashMap))) |
| 944 ZoneHashMap(ZoneHashMap::PointersMatch, |
| 945 ZoneHashMap::kDefaultHashMapCapacity, allocator); |
| 946 unbound_variables_ = new (zone->New(sizeof(ZoneHashMap))) |
| 947 ZoneHashMap(ZoneHashMap::PointersMatch, |
| 948 ZoneHashMap::kDefaultHashMapCapacity, allocator); |
| 949 } |
| 941 } | 950 } |
| 942 | 951 |
| 952 ~PreParserScope(); |
| 953 |
| 943 ScopeType type() { return scope_type_; } | 954 ScopeType type() { return scope_type_; } |
| 944 StrictMode strict_mode() const { return strict_mode_; } | 955 StrictMode strict_mode() const { return strict_mode_; } |
| 945 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } | 956 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } |
| 946 void SetScopeName(PreParserIdentifier name) {} | 957 void SetScopeName(PreParserIdentifier name) {} |
| 947 | 958 |
| 948 // When PreParser is in use, lazy compilation is already being done, | 959 // When PreParser is in use, lazy compilation is already being done, |
| 949 // things cannot get lazier than that. | 960 // things cannot get lazier than that. |
| 950 bool AllowsLazyCompilation() const { return false; } | 961 bool AllowsLazyCompilation() const { return false; } |
| 951 | 962 |
| 952 void set_start_position(int position) {} | 963 void set_start_position(int position) {} |
| 953 void set_end_position(int position) {} | 964 void set_end_position(int position) {} |
| 954 | 965 |
| 955 bool IsDeclared(const PreParserIdentifier& identifier) const { return false; } | 966 bool IsDeclared(const PreParserIdentifier& identifier) const { return false; } |
| 956 void DeclareParameter(const PreParserIdentifier& identifier, VariableMode) {} | 967 void DeclareParameter(const PreParserIdentifier& identifier, VariableMode) {} |
| 957 void RecordArgumentsUsage() {} | 968 void RecordArgumentsUsage() {} |
| 958 void RecordThisUsage() {} | 969 void RecordThisUsage() {} |
| 959 | 970 |
| 971 bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; } |
| 972 bool is_function_scope() const { |
| 973 return scope_type_ == FUNCTION_SCOPE || scope_type_ == ARROW_SCOPE; |
| 974 } |
| 975 bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; } |
| 976 bool is_global_scope() const { return scope_type_ == GLOBAL_SCOPE; } |
| 977 bool is_declaration_scope() const { |
| 978 return is_eval_scope() || is_function_scope() || is_module_scope() || |
| 979 is_global_scope(); |
| 980 } |
| 981 |
| 982 // The scope immediately surrounding this scope, or NULL. |
| 983 PreParserScope* outer_scope() const { return outer_scope_; } |
| 984 |
| 985 // Walk up the scope chain and return the scope where var declarations will be |
| 986 // hoisted to (could be this). |
| 987 PreParserScope* DeclarationScope(); |
| 988 |
| 989 // Record a variable declaration in the current declaration scope |
| 990 void Declare(const AstRawString* identifier); |
| 991 |
| 992 // Record the usage of a variable in an identifier expression. If the variable |
| 993 // was not declared in this scope, we report it to the full parser so it will |
| 994 // be context-allocated. |
| 995 void RecordVariableUsage(const AstRawString* identifier); |
| 996 |
| 997 void LogUnboundVariables(ParserRecorder* recorder); |
| 998 |
| 960 // Allow scope->Foo() to work. | 999 // Allow scope->Foo() to work. |
| 961 PreParserScope* operator->() { return this; } | 1000 PreParserScope* operator->() { return this; } |
| 962 | 1001 |
| 963 private: | 1002 private: |
| 1003 PreParserScope* outer_scope_; |
| 964 ScopeType scope_type_; | 1004 ScopeType scope_type_; |
| 965 StrictMode strict_mode_; | 1005 StrictMode strict_mode_; |
| 1006 Zone* zone_; |
| 1007 ZoneHashMap* declared_variables_; |
| 1008 ZoneHashMap* unbound_variables_; |
| 966 }; | 1009 }; |
| 967 | 1010 |
| 968 | 1011 |
| 969 class PreParserFactory { | 1012 class PreParserFactory { |
| 970 public: | 1013 public: |
| 971 explicit PreParserFactory(void* unused_value_factory) {} | 1014 explicit PreParserFactory(void* unused_value_factory) {} |
| 972 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, | 1015 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, |
| 973 int pos) { | 1016 int pos) { |
| 974 return PreParserExpression::Default(); | 1017 return PreParserExpression::Default(); |
| 975 } | 1018 } |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1104 | 1147 |
| 1105 class PreParserTraits { | 1148 class PreParserTraits { |
| 1106 public: | 1149 public: |
| 1107 struct Type { | 1150 struct Type { |
| 1108 // TODO(marja): To be removed. The Traits object should contain all the data | 1151 // TODO(marja): To be removed. The Traits object should contain all the data |
| 1109 // it needs. | 1152 // it needs. |
| 1110 typedef PreParser* Parser; | 1153 typedef PreParser* Parser; |
| 1111 | 1154 |
| 1112 // Used by FunctionState and BlockState. | 1155 // Used by FunctionState and BlockState. |
| 1113 typedef PreParserScope Scope; | 1156 typedef PreParserScope Scope; |
| 1114 typedef PreParserScope ScopePtr; | 1157 typedef PreParserScope ScopePtr; // Return type of NewScope() |
| 1115 inline static Scope* ptr_to_scope(ScopePtr& scope) { return &scope; } | 1158 inline static Scope* ptr_to_scope(ScopePtr& scope) { return &scope; } |
| 1116 | 1159 |
| 1117 // PreParser doesn't need to store generator variables. | 1160 // PreParser doesn't need to store generator variables. |
| 1118 typedef void GeneratorVariable; | 1161 typedef void GeneratorVariable; |
| 1119 // No interaction with Zones. | |
| 1120 typedef void Zone; | |
| 1121 | 1162 |
| 1122 typedef int AstProperties; | 1163 typedef int AstProperties; |
| 1123 typedef Vector<PreParserIdentifier> ParameterIdentifierVector; | 1164 typedef Vector<PreParserIdentifier> ParameterIdentifierVector; |
| 1124 | 1165 |
| 1125 // Return types for traversing functions. | 1166 // Return types for traversing functions. |
| 1126 typedef PreParserIdentifier Identifier; | 1167 typedef PreParserIdentifier Identifier; |
| 1127 typedef PreParserExpression Expression; | 1168 typedef PreParserExpression Expression; |
| 1128 typedef PreParserExpression YieldExpression; | 1169 typedef PreParserExpression YieldExpression; |
| 1129 typedef PreParserExpression FunctionLiteral; | 1170 typedef PreParserExpression FunctionLiteral; |
| 1130 typedef PreParserExpression ClassLiteral; | 1171 typedef PreParserExpression ClassLiteral; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1203 UNREACHABLE(); | 1244 UNREACHABLE(); |
| 1204 } | 1245 } |
| 1205 | 1246 |
| 1206 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( | 1247 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( |
| 1207 PreParserScope* scope, PreParserExpression property, bool* has_function) { | 1248 PreParserScope* scope, PreParserExpression property, bool* has_function) { |
| 1208 } | 1249 } |
| 1209 | 1250 |
| 1210 static void CheckAssigningFunctionLiteralToProperty( | 1251 static void CheckAssigningFunctionLiteralToProperty( |
| 1211 PreParserExpression left, PreParserExpression right) {} | 1252 PreParserExpression left, PreParserExpression right) {} |
| 1212 | 1253 |
| 1213 // PreParser doesn't need to keep track of eval calls. | 1254 // Need to record direct calls to eval so every variable in the enclosing |
| 1214 static void CheckPossibleEvalCall(PreParserExpression expression, | 1255 // scope gets allocated |
| 1215 PreParserScope* scope) {} | 1256 void CheckPossibleEvalCall(PreParserExpression expression, |
| 1257 PreParserScope* scope); |
| 1216 | 1258 |
| 1217 static PreParserExpression MarkExpressionAsAssigned( | 1259 static PreParserExpression MarkExpressionAsAssigned( |
| 1218 PreParserExpression expression) { | 1260 PreParserExpression expression) { |
| 1219 // TODO(marja): To be able to produce the same errors, the preparser needs | 1261 // TODO(marja): To be able to produce the same errors, the preparser needs |
| 1220 // to start tracking which expressions are variables and which are assigned. | 1262 // to start tracking which expressions are variables and which are assigned. |
| 1221 return expression; | 1263 return expression; |
| 1222 } | 1264 } |
| 1223 | 1265 |
| 1266 void RecordCurrentSymbolAsIdentifierExpression(); |
| 1267 |
| 1224 bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x, | 1268 bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x, |
| 1225 PreParserExpression y, | 1269 PreParserExpression y, |
| 1226 Token::Value op, | 1270 Token::Value op, |
| 1227 int pos, | 1271 int pos, |
| 1228 PreParserFactory* factory) { | 1272 PreParserFactory* factory) { |
| 1229 return false; | 1273 return false; |
| 1230 } | 1274 } |
| 1231 | 1275 |
| 1232 PreParserExpression BuildUnaryExpression(PreParserExpression expression, | 1276 PreParserExpression BuildUnaryExpression(PreParserExpression expression, |
| 1233 Token::Value op, int pos, | 1277 Token::Value op, int pos, |
| 1234 PreParserFactory* factory) { | 1278 PreParserFactory* factory) { |
| 1235 return PreParserExpression::Default(); | 1279 return PreParserExpression::Default(); |
| 1236 } | 1280 } |
| 1237 | 1281 |
| 1238 PreParserExpression NewThrowReferenceError(const char* type, int pos) { | 1282 PreParserExpression NewThrowReferenceError(const char* type, int pos) { |
| 1239 return PreParserExpression::Default(); | 1283 return PreParserExpression::Default(); |
| 1240 } | 1284 } |
| 1241 PreParserExpression NewThrowSyntaxError( | 1285 PreParserExpression NewThrowSyntaxError( |
| 1242 const char* type, Handle<Object> arg, int pos) { | 1286 const char* type, Handle<Object> arg, int pos) { |
| 1243 return PreParserExpression::Default(); | 1287 return PreParserExpression::Default(); |
| 1244 } | 1288 } |
| 1245 PreParserExpression NewThrowTypeError( | 1289 PreParserExpression NewThrowTypeError( |
| 1246 const char* type, Handle<Object> arg, int pos) { | 1290 const char* type, Handle<Object> arg, int pos) { |
| 1247 return PreParserExpression::Default(); | 1291 return PreParserExpression::Default(); |
| 1248 } | 1292 } |
| 1249 PreParserScope NewScope(PreParserScope* outer_scope, ScopeType scope_type) { | 1293 inline PreParserScope NewScope(PreParserScope* outer_scope, |
| 1250 return PreParserScope(outer_scope, scope_type); | 1294 ScopeType scope_type); |
| 1251 } | |
| 1252 | 1295 |
| 1253 // Reporting errors. | 1296 // Reporting errors. |
| 1254 void ReportMessageAt(Scanner::Location location, | 1297 void ReportMessageAt(Scanner::Location location, |
| 1255 const char* message, | 1298 const char* message, |
| 1256 const char* arg = NULL, | 1299 const char* arg = NULL, |
| 1257 bool is_reference_error = false); | 1300 bool is_reference_error = false); |
| 1258 void ReportMessageAt(int start_pos, | 1301 void ReportMessageAt(int start_pos, |
| 1259 int end_pos, | 1302 int end_pos, |
| 1260 const char* message, | 1303 const char* message, |
| 1261 const char* arg = NULL, | 1304 const char* arg = NULL, |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1332 | 1375 |
| 1333 PreParserExpression ExpressionFromString(int pos, | 1376 PreParserExpression ExpressionFromString(int pos, |
| 1334 Scanner* scanner, | 1377 Scanner* scanner, |
| 1335 PreParserFactory* factory = NULL); | 1378 PreParserFactory* factory = NULL); |
| 1336 | 1379 |
| 1337 PreParserExpression GetIterator(PreParserExpression iterable, | 1380 PreParserExpression GetIterator(PreParserExpression iterable, |
| 1338 PreParserFactory* factory) { | 1381 PreParserFactory* factory) { |
| 1339 return PreParserExpression::Default(); | 1382 return PreParserExpression::Default(); |
| 1340 } | 1383 } |
| 1341 | 1384 |
| 1342 static PreParserExpressionList NewExpressionList(int size, void* zone) { | 1385 static PreParserExpressionList NewExpressionList(int size, Zone* zone) { |
| 1343 return PreParserExpressionList(); | 1386 return PreParserExpressionList(); |
| 1344 } | 1387 } |
| 1345 | 1388 |
| 1346 static PreParserStatementList NewStatementList(int size, void* zone) { | 1389 static PreParserStatementList NewStatementList(int size, Zone* zone) { |
| 1347 return PreParserStatementList(); | 1390 return PreParserStatementList(); |
| 1348 } | 1391 } |
| 1349 | 1392 |
| 1350 static PreParserExpressionList NewPropertyList(int size, void* zone) { | 1393 static PreParserExpressionList NewPropertyList(int size, Zone* zone) { |
| 1351 return PreParserExpressionList(); | 1394 return PreParserExpressionList(); |
| 1352 } | 1395 } |
| 1353 | 1396 |
| 1354 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name, | 1397 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name, |
| 1355 int* materialized_literal_count, | 1398 int* materialized_literal_count, |
| 1356 int* expected_property_count, bool* ok) { | 1399 int* expected_property_count, bool* ok) { |
| 1357 UNREACHABLE(); | 1400 UNREACHABLE(); |
| 1358 } | 1401 } |
| 1359 | 1402 |
| 1360 V8_INLINE PreParserStatementList | 1403 V8_INLINE PreParserStatementList |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1405 public: | 1448 public: |
| 1406 typedef PreParserIdentifier Identifier; | 1449 typedef PreParserIdentifier Identifier; |
| 1407 typedef PreParserExpression Expression; | 1450 typedef PreParserExpression Expression; |
| 1408 typedef PreParserStatement Statement; | 1451 typedef PreParserStatement Statement; |
| 1409 | 1452 |
| 1410 enum PreParseResult { | 1453 enum PreParseResult { |
| 1411 kPreParseStackOverflow, | 1454 kPreParseStackOverflow, |
| 1412 kPreParseSuccess | 1455 kPreParseSuccess |
| 1413 }; | 1456 }; |
| 1414 | 1457 |
| 1415 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) | 1458 PreParser(Scanner* scanner, ParserRecorder* log, |
| 1416 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, | 1459 AstValueFactory* ast_value_factory, Zone* zone, |
| 1417 this) {} | 1460 uintptr_t stack_limit) |
| 1461 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, zone, |
| 1462 this), |
| 1463 ast_value_factory_(ast_value_factory), |
| 1464 log_identifiers_(false) {} |
| 1418 | 1465 |
| 1419 // Pre-parse the program from the character stream; returns true on | 1466 // Pre-parse the program from the character stream; returns true on |
| 1420 // success (even if parsing failed, the pre-parse data successfully | 1467 // success (even if parsing failed, the pre-parse data successfully |
| 1421 // captured the syntax error), and false if a stack-overflow happened | 1468 // captured the syntax error), and false if a stack-overflow happened |
| 1422 // during parsing. | 1469 // during parsing. |
| 1423 PreParseResult PreParseProgram() { | 1470 PreParseResult PreParseProgram() { |
| 1424 PreParserScope scope(scope_, GLOBAL_SCOPE); | 1471 PreParserScope scope = NewScope(scope_, GLOBAL_SCOPE); |
| 1425 PreParserFactory factory(NULL); | 1472 PreParserFactory factory(NULL); |
| 1426 FunctionState top_scope(&function_state_, &scope_, &scope, &factory); | 1473 FunctionState top_scope(&function_state_, &scope_, &scope, &factory); |
| 1427 bool ok = true; | 1474 bool ok = true; |
| 1428 int start_position = scanner()->peek_location().beg_pos; | 1475 int start_position = scanner()->peek_location().beg_pos; |
| 1429 ParseSourceElements(Token::EOS, &ok); | 1476 ParseSourceElements(Token::EOS, &ok); |
| 1430 if (stack_overflow()) return kPreParseStackOverflow; | 1477 if (stack_overflow()) return kPreParseStackOverflow; |
| 1431 if (!ok) { | 1478 if (!ok) { |
| 1432 ReportUnexpectedToken(scanner()->current_token()); | 1479 ReportUnexpectedToken(scanner()->current_token()); |
| 1433 } else if (scope_->strict_mode() == STRICT) { | 1480 } else if (scope_->strict_mode() == STRICT) { |
| 1434 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); | 1481 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); |
| 1435 } | 1482 } |
| 1436 return kPreParseSuccess; | 1483 return kPreParseSuccess; |
| 1437 } | 1484 } |
| 1438 | 1485 |
| 1439 // Parses a single function literal, from the opening parentheses before | 1486 // Parses a single function literal, from the opening parentheses before |
| 1440 // parameters to the closing brace after the body. | 1487 // parameters to the closing brace after the body. |
| 1441 // Returns a FunctionEntry describing the body of the function in enough | 1488 // Returns a FunctionEntry describing the body of the function in enough |
| 1442 // detail that it can be lazily compiled. | 1489 // detail that it can be lazily compiled. |
| 1443 // The scanner is expected to have matched the "function" or "function*" | 1490 // The scanner is expected to have matched the "function" or "function*" |
| 1444 // keyword and parameters, and have consumed the initial '{'. | 1491 // keyword and parameters, and have consumed the initial '{'. |
| 1445 // At return, unless an error occurred, the scanner is positioned before the | 1492 // At return, unless an error occurred, the scanner is positioned before the |
| 1446 // the final '}'. | 1493 // the final '}'. |
| 1447 PreParseResult PreParseLazyFunction(StrictMode strict_mode, | 1494 PreParseResult PreParseLazyFunction(StrictMode strict_mode, bool is_generator, |
| 1448 bool is_generator, | 1495 bool log_identifiers, |
| 1449 ParserRecorder* log); | 1496 ParserRecorder* log); |
| 1450 | 1497 |
| 1451 private: | 1498 private: |
| 1452 friend class PreParserTraits; | 1499 friend class PreParserTraits; |
| 1453 | 1500 |
| 1454 // These types form an algebra over syntactic categories that is just | 1501 // These types form an algebra over syntactic categories that is just |
| 1455 // rich enough to let us recognize and propagate the constructs that | 1502 // rich enough to let us recognize and propagate the constructs that |
| 1456 // are either being counted in the preparser data, or is important | 1503 // are either being counted in the preparser data, or is important |
| 1457 // to throw the correct syntax error exceptions. | 1504 // to throw the correct syntax error exceptions. |
| 1458 | 1505 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1514 Variable* fvar, Token::Value fvar_init_op, | 1561 Variable* fvar, Token::Value fvar_init_op, |
| 1515 bool is_generator, bool* ok); | 1562 bool is_generator, bool* ok); |
| 1516 | 1563 |
| 1517 Expression ParseFunctionLiteral( | 1564 Expression ParseFunctionLiteral( |
| 1518 Identifier name, Scanner::Location function_name_location, | 1565 Identifier name, Scanner::Location function_name_location, |
| 1519 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, | 1566 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, |
| 1520 FunctionLiteral::FunctionType function_type, | 1567 FunctionLiteral::FunctionType function_type, |
| 1521 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); | 1568 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); |
| 1522 void ParseLazyFunctionLiteralBody(bool* ok); | 1569 void ParseLazyFunctionLiteralBody(bool* ok); |
| 1523 | 1570 |
| 1571 PreParserScope NewScope(PreParserScope* outer_scope, ScopeType scope_type) { |
| 1572 return PreParserScope(outer_scope, scope_type, zone(), log_identifiers_); |
| 1573 } |
| 1574 |
| 1524 bool CheckInOrOf(bool accept_OF); | 1575 bool CheckInOrOf(bool accept_OF); |
| 1576 |
| 1577 AstValueFactory* ast_value_factory_; |
| 1578 bool log_identifiers_; |
| 1525 }; | 1579 }; |
| 1526 | 1580 |
| 1527 | 1581 |
| 1528 PreParserStatementList PreParser::ParseEagerFunctionBody( | 1582 PreParserStatementList PreParser::ParseEagerFunctionBody( |
| 1529 PreParserIdentifier function_name, int pos, Variable* fvar, | 1583 PreParserIdentifier function_name, int pos, Variable* fvar, |
| 1530 Token::Value fvar_init_op, bool is_generator, bool* ok) { | 1584 Token::Value fvar_init_op, bool is_generator, bool* ok) { |
| 1531 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1585 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 1532 | 1586 |
| 1533 ParseSourceElements(Token::RBRACE, ok); | 1587 ParseSourceElements(Token::RBRACE, ok); |
| 1534 if (!*ok) return PreParserStatementList(); | 1588 if (!*ok) return PreParserStatementList(); |
| 1535 | 1589 |
| 1536 Expect(Token::RBRACE, ok); | 1590 Expect(Token::RBRACE, ok); |
| 1537 return PreParserStatementList(); | 1591 return PreParserStatementList(); |
| 1538 } | 1592 } |
| 1539 | 1593 |
| 1540 | 1594 |
| 1541 PreParserStatementList PreParserTraits::ParseEagerFunctionBody( | 1595 PreParserStatementList PreParserTraits::ParseEagerFunctionBody( |
| 1542 PreParserIdentifier function_name, int pos, Variable* fvar, | 1596 PreParserIdentifier function_name, int pos, Variable* fvar, |
| 1543 Token::Value fvar_init_op, bool is_generator, bool* ok) { | 1597 Token::Value fvar_init_op, bool is_generator, bool* ok) { |
| 1544 return pre_parser_->ParseEagerFunctionBody(function_name, pos, fvar, | 1598 return pre_parser_->ParseEagerFunctionBody(function_name, pos, fvar, |
| 1545 fvar_init_op, is_generator, ok); | 1599 fvar_init_op, is_generator, ok); |
| 1546 } | 1600 } |
| 1547 | 1601 |
| 1548 | 1602 |
| 1603 PreParserScope PreParserTraits::NewScope(PreParserScope* outer_scope, |
| 1604 ScopeType scope_type) { |
| 1605 return pre_parser_->NewScope(outer_scope, scope_type); |
| 1606 } |
| 1607 |
| 1608 |
| 1549 template <class Traits> | 1609 template <class Traits> |
| 1550 ParserBase<Traits>::FunctionState::FunctionState( | 1610 ParserBase<Traits>::FunctionState::FunctionState( |
| 1551 FunctionState** function_state_stack, | 1611 FunctionState** function_state_stack, |
| 1552 typename Traits::Type::Scope** scope_stack, | 1612 typename Traits::Type::Scope** scope_stack, |
| 1553 typename Traits::Type::Scope* scope, | 1613 typename Traits::Type::Scope* scope, |
| 1554 typename Traits::Type::Factory* factory) | 1614 typename Traits::Type::Factory* factory) |
| 1555 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | 1615 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), |
| 1556 next_handler_index_(0), | 1616 next_handler_index_(0), |
| 1557 expected_property_count_(0), | 1617 expected_property_count_(0), |
| 1558 is_generator_(false), | 1618 is_generator_(false), |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1760 Next(); | 1820 Next(); |
| 1761 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); | 1821 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); |
| 1762 break; | 1822 break; |
| 1763 | 1823 |
| 1764 case Token::IDENTIFIER: | 1824 case Token::IDENTIFIER: |
| 1765 case Token::LET: | 1825 case Token::LET: |
| 1766 case Token::YIELD: | 1826 case Token::YIELD: |
| 1767 case Token::FUTURE_STRICT_RESERVED_WORD: { | 1827 case Token::FUTURE_STRICT_RESERVED_WORD: { |
| 1768 // Using eval or arguments in this context is OK even in strict mode. | 1828 // Using eval or arguments in this context is OK even in strict mode. |
| 1769 IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1829 IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 1830 this->RecordCurrentSymbolAsIdentifierExpression(); |
| 1770 result = this->ExpressionFromIdentifier(name, pos, scope_, factory()); | 1831 result = this->ExpressionFromIdentifier(name, pos, scope_, factory()); |
| 1771 break; | 1832 break; |
| 1772 } | 1833 } |
| 1773 | 1834 |
| 1774 case Token::STRING: { | 1835 case Token::STRING: { |
| 1775 Consume(Token::STRING); | 1836 Consume(Token::STRING); |
| 1776 result = this->ExpressionFromString(pos, scanner(), factory()); | 1837 result = this->ExpressionFromString(pos, scanner(), factory()); |
| 1777 break; | 1838 break; |
| 1778 } | 1839 } |
| 1779 | 1840 |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2011 FunctionKind::kNormalFunction, RelocInfo::kNoPosition, | 2072 FunctionKind::kNormalFunction, RelocInfo::kNoPosition, |
| 2012 FunctionLiteral::ANONYMOUS_EXPRESSION, | 2073 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 2013 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, | 2074 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, |
| 2014 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2075 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2015 return factory()->NewObjectLiteralProperty(is_get, value, next_pos, | 2076 return factory()->NewObjectLiteralProperty(is_get, value, next_pos, |
| 2016 is_static); | 2077 is_static); |
| 2017 | 2078 |
| 2018 } else if (!in_class && allow_harmony_object_literals_ && | 2079 } else if (!in_class && allow_harmony_object_literals_ && |
| 2019 Token::IsIdentifier(name_token, strict_mode(), | 2080 Token::IsIdentifier(name_token, strict_mode(), |
| 2020 this->is_generator())) { | 2081 this->is_generator())) { |
| 2082 this->RecordCurrentSymbolAsIdentifierExpression(); |
| 2021 value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory()); | 2083 value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory()); |
| 2022 | 2084 |
| 2023 } else { | 2085 } else { |
| 2024 Token::Value next = Next(); | 2086 Token::Value next = Next(); |
| 2025 ReportUnexpectedToken(next); | 2087 ReportUnexpectedToken(next); |
| 2026 *ok = false; | 2088 *ok = false; |
| 2027 return this->EmptyObjectLiteralProperty(); | 2089 return this->EmptyObjectLiteralProperty(); |
| 2028 } | 2090 } |
| 2029 | 2091 |
| 2030 uint32_t index; | 2092 uint32_t index; |
| (...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2827 DCHECK(IsAccessorAccessorConflict(old_type, type)); | 2889 DCHECK(IsAccessorAccessorConflict(old_type, type)); |
| 2828 // Both accessors of the same type. | 2890 // Both accessors of the same type. |
| 2829 parser()->ReportMessage("accessor_get_set"); | 2891 parser()->ReportMessage("accessor_get_set"); |
| 2830 } | 2892 } |
| 2831 *ok = false; | 2893 *ok = false; |
| 2832 } | 2894 } |
| 2833 } | 2895 } |
| 2834 } } // v8::internal | 2896 } } // v8::internal |
| 2835 | 2897 |
| 2836 #endif // V8_PREPARSER_H | 2898 #endif // V8_PREPARSER_H |
| OLD | NEW |