OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 } | 80 } |
81 | 81 |
82 private: | 82 private: |
83 Element* top() { return top_; } | 83 Element* top() { return top_; } |
84 void set_top(Element* value) { top_ = value; } | 84 void set_top(Element* value) { top_ = value; } |
85 Element* top_; | 85 Element* top_; |
86 bool* ok_; | 86 bool* ok_; |
87 }; | 87 }; |
88 | 88 |
89 | 89 |
90 template <typename T, int initial_size> | |
91 class BufferedZoneList { | |
92 public: | |
93 BufferedZoneList() : list_(NULL), last_(NULL) {} | |
94 | |
95 // Adds element at end of list. This element is buffered and can | |
96 // be read using last() or removed using RemoveLast until a new Add or until | |
97 // RemoveLast or GetList has been called. | |
98 void Add(T* value) { | |
99 if (last_ != NULL) { | |
100 if (list_ == NULL) { | |
101 list_ = new ZoneList<T*>(initial_size); | |
102 } | |
103 list_->Add(last_); | |
104 } | |
105 last_ = value; | |
106 } | |
107 | |
108 T* last() { | |
109 ASSERT(last_ != NULL); | |
110 return last_; | |
111 } | |
112 | |
113 T* RemoveLast() { | |
114 ASSERT(last_ != NULL); | |
115 T* result = last_; | |
116 if (list_ != NULL && list_->length() > 0) | |
117 last_ = list_->RemoveLast(); | |
118 else | |
119 last_ = NULL; | |
120 return result; | |
121 } | |
122 | |
123 T* Get(int i) { | |
124 ASSERT(0 <= i && i < length()); | |
125 if (list_ == NULL) { | |
126 ASSERT_EQ(0, i); | |
127 return last_; | |
128 } else { | |
129 if (i == list_->length()) { | |
130 ASSERT(last_ != NULL); | |
131 return last_; | |
132 } else { | |
133 return list_->at(i); | |
134 } | |
135 } | |
136 } | |
137 | |
138 void Clear() { | |
139 list_ = NULL; | |
140 last_ = NULL; | |
141 } | |
142 | |
143 int length() { | |
144 int length = (list_ == NULL) ? 0 : list_->length(); | |
145 return length + ((last_ == NULL) ? 0 : 1); | |
146 } | |
147 | |
148 ZoneList<T*>* GetList() { | |
149 if (list_ == NULL) { | |
150 list_ = new ZoneList<T*>(initial_size); | |
151 } | |
152 if (last_ != NULL) { | |
153 list_->Add(last_); | |
154 last_ = NULL; | |
155 } | |
156 return list_; | |
157 } | |
158 | |
159 private: | |
160 ZoneList<T*>* list_; | |
161 T* last_; | |
162 }; | |
163 | |
164 | |
165 // Accumulates RegExp atoms and assertions into lists of terms and alternatives. | |
166 class RegExpBuilder: public ZoneObject { | |
167 public: | |
168 RegExpBuilder(); | |
169 void AddCharacter(uc16 character); | |
170 // "Adds" an empty expression. Does nothing except consume a | |
171 // following quantifier | |
172 void AddEmpty(); | |
173 void AddAtom(RegExpTree* tree); | |
174 void AddAssertion(RegExpTree* tree); | |
175 void NewAlternative(); // '|' | |
176 void AddQuantifierToAtom(int min, int max, RegExpQuantifier::Type type); | |
177 RegExpTree* ToRegExp(); | |
178 private: | |
179 void FlushCharacters(); | |
180 void FlushText(); | |
181 void FlushTerms(); | |
182 bool pending_empty_; | |
183 ZoneList<uc16>* characters_; | |
184 BufferedZoneList<RegExpTree, 2> terms_; | |
185 BufferedZoneList<RegExpTree, 2> text_; | |
186 BufferedZoneList<RegExpTree, 2> alternatives_; | |
187 #ifdef DEBUG | |
188 enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_; | |
189 #define LAST(x) last_added_ = x; | |
190 #else | |
191 #define LAST(x) | |
192 #endif | |
193 }; | |
194 | |
195 | |
196 RegExpBuilder::RegExpBuilder() | 90 RegExpBuilder::RegExpBuilder() |
197 : pending_empty_(false), | 91 : pending_empty_(false), |
198 characters_(NULL), | 92 characters_(NULL), |
199 terms_(), | 93 terms_(), |
200 alternatives_() | 94 alternatives_() |
201 #ifdef DEBUG | 95 #ifdef DEBUG |
202 , last_added_(ADD_NONE) | 96 , last_added_(ADD_NONE) |
203 #endif | 97 #endif |
204 {} | 98 {} |
205 | 99 |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 } else { | 239 } else { |
346 // Only call immediately after adding an atom or character! | 240 // Only call immediately after adding an atom or character! |
347 UNREACHABLE(); | 241 UNREACHABLE(); |
348 return; | 242 return; |
349 } | 243 } |
350 terms_.Add(new RegExpQuantifier(min, max, type, atom)); | 244 terms_.Add(new RegExpQuantifier(min, max, type, atom)); |
351 LAST(ADD_TERM); | 245 LAST(ADD_TERM); |
352 } | 246 } |
353 | 247 |
354 | 248 |
355 class RegExpParser { | |
356 public: | |
357 RegExpParser(FlatStringReader* in, | |
358 Handle<String>* error, | |
359 bool multiline_mode); | |
360 RegExpTree* ParsePattern(); | |
361 RegExpTree* ParseDisjunction(); | |
362 RegExpTree* ParseGroup(); | |
363 RegExpTree* ParseCharacterClass(); | |
364 | |
365 // Parses a {...,...} quantifier and stores the range in the given | |
366 // out parameters. | |
367 bool ParseIntervalQuantifier(int* min_out, int* max_out); | |
368 | |
369 // Parses and returns a single escaped character. The character | |
370 // must not be 'b' or 'B' since they are usually handle specially. | |
371 uc32 ParseClassCharacterEscape(); | |
372 | |
373 // Checks whether the following is a length-digit hexadecimal number, | |
374 // and sets the value if it is. | |
375 bool ParseHexEscape(int length, uc32* value); | |
376 | |
377 uc32 ParseControlLetterEscape(); | |
378 uc32 ParseOctalLiteral(); | |
379 | |
380 // Tries to parse the input as a back reference. If successful it | |
381 // stores the result in the output parameter and returns true. If | |
382 // it fails it will push back the characters read so the same characters | |
383 // can be reparsed. | |
384 bool ParseBackReferenceIndex(int* index_out); | |
385 | |
386 CharacterRange ParseClassAtom(uc16* char_class); | |
387 RegExpTree* ReportError(Vector<const char> message); | |
388 void Advance(); | |
389 void Advance(int dist); | |
390 void Reset(int pos); | |
391 | |
392 // Reports whether the pattern might be used as a literal search string. | |
393 // Only use if the result of the parse is a single atom node. | |
394 bool simple(); | |
395 bool contains_anchor() { return contains_anchor_; } | |
396 void set_contains_anchor() { contains_anchor_ = true; } | |
397 int captures_started() { return captures_ == NULL ? 0 : captures_->length(); } | |
398 int position() { return next_pos_ - 1; } | |
399 bool failed() { return failed_; } | |
400 | |
401 static const int kMaxCaptures = 1 << 16; | |
402 static const uc32 kEndMarker = (1 << 21); | |
403 | |
404 private: | |
405 enum SubexpressionType { | |
406 INITIAL, | |
407 CAPTURE, // All positive values represent captures. | |
408 POSITIVE_LOOKAHEAD, | |
409 NEGATIVE_LOOKAHEAD, | |
410 GROUPING | |
411 }; | |
412 | |
413 class RegExpParserState : public ZoneObject { | |
414 public: | |
415 RegExpParserState(RegExpParserState* previous_state, | |
416 SubexpressionType group_type, | |
417 int disjunction_capture_index) | |
418 : previous_state_(previous_state), | |
419 builder_(new RegExpBuilder()), | |
420 group_type_(group_type), | |
421 disjunction_capture_index_(disjunction_capture_index) {} | |
422 // Parser state of containing expression, if any. | |
423 RegExpParserState* previous_state() { return previous_state_; } | |
424 bool IsSubexpression() { return previous_state_ != NULL; } | |
425 // RegExpBuilder building this regexp's AST. | |
426 RegExpBuilder* builder() { return builder_; } | |
427 // Type of regexp being parsed (parenthesized group or entire regexp). | |
428 SubexpressionType group_type() { return group_type_; } | |
429 // Index in captures array of first capture in this sub-expression, if any. | |
430 // Also the capture index of this sub-expression itself, if group_type | |
431 // is CAPTURE. | |
432 int capture_index() { return disjunction_capture_index_; } | |
433 private: | |
434 // Linked list implementation of stack of states. | |
435 RegExpParserState* previous_state_; | |
436 // Builder for the stored disjunction. | |
437 RegExpBuilder* builder_; | |
438 // Stored disjunction type (capture, look-ahead or grouping), if any. | |
439 SubexpressionType group_type_; | |
440 // Stored disjunction's capture index (if any). | |
441 int disjunction_capture_index_; | |
442 }; | |
443 | |
444 uc32 current() { return current_; } | |
445 bool has_more() { return has_more_; } | |
446 bool has_next() { return next_pos_ < in()->length(); } | |
447 uc32 Next(); | |
448 FlatStringReader* in() { return in_; } | |
449 void ScanForCaptures(); | |
450 uc32 current_; | |
451 bool has_more_; | |
452 bool multiline_; | |
453 int next_pos_; | |
454 FlatStringReader* in_; | |
455 Handle<String>* error_; | |
456 bool simple_; | |
457 bool contains_anchor_; | |
458 ZoneList<RegExpCapture*>* captures_; | |
459 bool is_scanned_for_captures_; | |
460 // The capture count is only valid after we have scanned for captures. | |
461 int capture_count_; | |
462 bool failed_; | |
463 }; | |
464 | |
465 | |
466 // A temporary scope stores information during parsing, just like | 249 // A temporary scope stores information during parsing, just like |
467 // a plain scope. However, temporary scopes are not kept around | 250 // a plain scope. However, temporary scopes are not kept around |
468 // after parsing or referenced by syntax trees so they can be stack- | 251 // after parsing or referenced by syntax trees so they can be stack- |
469 // allocated and hence used by the pre-parser. | 252 // allocated and hence used by the pre-parser. |
470 class TemporaryScope BASE_EMBEDDED { | 253 class TemporaryScope BASE_EMBEDDED { |
471 public: | 254 public: |
472 explicit TemporaryScope(Parser* parser); | 255 explicit TemporaryScope(TemporaryScope** variable); |
473 ~TemporaryScope(); | 256 ~TemporaryScope(); |
474 | 257 |
475 int NextMaterializedLiteralIndex() { | 258 int NextMaterializedLiteralIndex() { |
476 int next_index = | 259 int next_index = |
477 materialized_literal_count_ + JSFunction::kLiteralsPrefixSize; | 260 materialized_literal_count_ + JSFunction::kLiteralsPrefixSize; |
478 materialized_literal_count_++; | 261 materialized_literal_count_++; |
479 return next_index; | 262 return next_index; |
480 } | 263 } |
481 int materialized_literal_count() { return materialized_literal_count_; } | 264 int materialized_literal_count() { return materialized_literal_count_; } |
482 | 265 |
(...skipping 28 matching lines...) Expand all Loading... |
511 | 294 |
512 // Keeps track of assignments to properties of this. Used for | 295 // Keeps track of assignments to properties of this. Used for |
513 // optimizing constructors. | 296 // optimizing constructors. |
514 bool only_simple_this_property_assignments_; | 297 bool only_simple_this_property_assignments_; |
515 Handle<FixedArray> this_property_assignments_; | 298 Handle<FixedArray> this_property_assignments_; |
516 | 299 |
517 // Captures the number of loops inside the scope. | 300 // Captures the number of loops inside the scope. |
518 int loop_count_; | 301 int loop_count_; |
519 | 302 |
520 // Bookkeeping | 303 // Bookkeeping |
521 Parser* parser_; | 304 TemporaryScope** variable_; |
522 TemporaryScope* parent_; | 305 TemporaryScope* parent_; |
523 | |
524 friend class Parser; | |
525 }; | 306 }; |
526 | 307 |
527 | 308 |
528 TemporaryScope::TemporaryScope(Parser* parser) | 309 TemporaryScope::TemporaryScope(TemporaryScope** variable) |
529 : materialized_literal_count_(0), | 310 : materialized_literal_count_(0), |
530 expected_property_count_(0), | 311 expected_property_count_(0), |
531 only_simple_this_property_assignments_(false), | 312 only_simple_this_property_assignments_(false), |
532 this_property_assignments_(Factory::empty_fixed_array()), | 313 this_property_assignments_(Factory::empty_fixed_array()), |
533 loop_count_(0), | 314 loop_count_(0), |
534 parser_(parser), | 315 variable_(variable), |
535 parent_(parser->temp_scope_) { | 316 parent_(*variable) { |
536 parser->temp_scope_ = this; | 317 *variable = this; |
537 } | 318 } |
538 | 319 |
539 | 320 |
540 TemporaryScope::~TemporaryScope() { | 321 TemporaryScope::~TemporaryScope() { |
541 parser_->temp_scope_ = parent_; | 322 *variable_ = parent_; |
542 } | 323 } |
543 | 324 |
544 | 325 |
545 // A zone list wrapper lets code either access a access a zone list | 326 // A zone list wrapper lets code either access a access a zone list |
546 // or appear to do so while actually ignoring all operations. | 327 // or appear to do so while actually ignoring all operations. |
547 template <typename T> | 328 template <typename T> |
548 class ZoneListWrapper { | 329 class ZoneListWrapper { |
549 public: | 330 public: |
550 ZoneListWrapper() : list_(NULL) { } | 331 ZoneListWrapper() : list_(NULL) { } |
551 explicit ZoneListWrapper(int size) : list_(new ZoneList<T*>(size)) { } | 332 explicit ZoneListWrapper(int size) : list_(new ZoneList<T*>(size)) { } |
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1134 | 915 |
1135 | 916 |
1136 // ---------------------------------------------------------------------------- | 917 // ---------------------------------------------------------------------------- |
1137 // Target is a support class to facilitate manipulation of the | 918 // Target is a support class to facilitate manipulation of the |
1138 // Parser's target_stack_ (the stack of potential 'break' and | 919 // Parser's target_stack_ (the stack of potential 'break' and |
1139 // 'continue' statement targets). Upon construction, a new target is | 920 // 'continue' statement targets). Upon construction, a new target is |
1140 // added; it is removed upon destruction. | 921 // added; it is removed upon destruction. |
1141 | 922 |
1142 class Target BASE_EMBEDDED { | 923 class Target BASE_EMBEDDED { |
1143 public: | 924 public: |
1144 Target(Parser* parser, AstNode* node) | 925 Target(Target** variable, AstNode* node) |
1145 : parser_(parser), node_(node), previous_(parser_->target_stack_) { | 926 : variable_(variable), node_(node), previous_(*variable) { |
1146 parser_->target_stack_ = this; | 927 *variable = this; |
1147 } | 928 } |
1148 | 929 |
1149 ~Target() { | 930 ~Target() { |
1150 parser_->target_stack_ = previous_; | 931 *variable_ = previous_; |
1151 } | 932 } |
1152 | 933 |
1153 Target* previous() { return previous_; } | 934 Target* previous() { return previous_; } |
1154 AstNode* node() { return node_; } | 935 AstNode* node() { return node_; } |
1155 | 936 |
1156 private: | 937 private: |
1157 Parser* parser_; | 938 Target** variable_; |
1158 AstNode* node_; | 939 AstNode* node_; |
1159 Target* previous_; | 940 Target* previous_; |
1160 }; | 941 }; |
1161 | 942 |
1162 | 943 |
1163 class TargetScope BASE_EMBEDDED { | 944 class TargetScope BASE_EMBEDDED { |
1164 public: | 945 public: |
1165 explicit TargetScope(Parser* parser) | 946 explicit TargetScope(Target** variable) |
1166 : parser_(parser), previous_(parser->target_stack_) { | 947 : variable_(variable), previous_(*variable) { |
1167 parser->target_stack_ = NULL; | 948 *variable = NULL; |
1168 } | 949 } |
1169 | 950 |
1170 ~TargetScope() { | 951 ~TargetScope() { |
1171 parser_->target_stack_ = previous_; | 952 *variable_ = previous_; |
1172 } | 953 } |
1173 | 954 |
1174 private: | 955 private: |
1175 Parser* parser_; | 956 Target** variable_; |
1176 Target* previous_; | 957 Target* previous_; |
1177 }; | 958 }; |
1178 | 959 |
1179 | 960 |
1180 // ---------------------------------------------------------------------------- | 961 // ---------------------------------------------------------------------------- |
1181 // LexicalScope is a support class to facilitate manipulation of the | 962 // LexicalScope is a support class to facilitate manipulation of the |
1182 // Parser's scope stack. The constructor sets the parser's top scope | 963 // Parser's scope stack. The constructor sets the parser's top scope |
1183 // to the incoming scope, and the destructor resets it. | 964 // to the incoming scope, and the destructor resets it. |
1184 | 965 |
1185 class LexicalScope BASE_EMBEDDED { | 966 class LexicalScope BASE_EMBEDDED { |
1186 public: | 967 public: |
1187 LexicalScope(Parser* parser, Scope* scope) | 968 LexicalScope(Scope** scope_variable, |
1188 : parser_(parser), | 969 int* with_nesting_level_variable, |
1189 prev_scope_(parser->top_scope_), | 970 Scope* scope) |
1190 prev_level_(parser->with_nesting_level_) { | 971 : scope_variable_(scope_variable), |
1191 parser_->top_scope_ = scope; | 972 with_nesting_level_variable_(with_nesting_level_variable), |
1192 parser_->with_nesting_level_ = 0; | 973 prev_scope_(*scope_variable), |
| 974 prev_level_(*with_nesting_level_variable) { |
| 975 *scope_variable = scope; |
| 976 *with_nesting_level_variable = 0; |
1193 } | 977 } |
1194 | 978 |
1195 ~LexicalScope() { | 979 ~LexicalScope() { |
1196 parser_->top_scope_->Leave(); | 980 (*scope_variable_)->Leave(); |
1197 parser_->top_scope_ = prev_scope_; | 981 *scope_variable_ = prev_scope_; |
1198 parser_->with_nesting_level_ = prev_level_; | 982 *with_nesting_level_variable_ = prev_level_; |
1199 } | 983 } |
1200 | 984 |
1201 private: | 985 private: |
1202 Parser* parser_; | 986 Scope** scope_variable_; |
| 987 int* with_nesting_level_variable_; |
1203 Scope* prev_scope_; | 988 Scope* prev_scope_; |
1204 int prev_level_; | 989 int prev_level_; |
1205 }; | 990 }; |
1206 | 991 |
1207 | 992 |
1208 // ---------------------------------------------------------------------------- | 993 // ---------------------------------------------------------------------------- |
1209 // The CHECK_OK macro is a convenient macro to enforce error | 994 // The CHECK_OK macro is a convenient macro to enforce error |
1210 // handling for functions that may fail (by returning !*ok). | 995 // handling for functions that may fail (by returning !*ok). |
1211 // | 996 // |
1212 // CAUTION: This macro appends extra statements after a call, | 997 // CAUTION: This macro appends extra statements after a call, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1255 unibrow::CharacterStream* stream) { | 1040 unibrow::CharacterStream* stream) { |
1256 HistogramTimerScope timer(&Counters::pre_parse); | 1041 HistogramTimerScope timer(&Counters::pre_parse); |
1257 AssertNoZoneAllocation assert_no_zone_allocation; | 1042 AssertNoZoneAllocation assert_no_zone_allocation; |
1258 AssertNoAllocation assert_no_allocation; | 1043 AssertNoAllocation assert_no_allocation; |
1259 NoHandleAllocation no_handle_allocation; | 1044 NoHandleAllocation no_handle_allocation; |
1260 scanner_.Initialize(source, stream, JAVASCRIPT); | 1045 scanner_.Initialize(source, stream, JAVASCRIPT); |
1261 ASSERT(target_stack_ == NULL); | 1046 ASSERT(target_stack_ == NULL); |
1262 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; | 1047 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; |
1263 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; | 1048 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; |
1264 DummyScope top_scope; | 1049 DummyScope top_scope; |
1265 LexicalScope scope(this, &top_scope); | 1050 LexicalScope scope(&this->top_scope_, &this->with_nesting_level_, &top_scope); |
1266 TemporaryScope temp_scope(this); | 1051 TemporaryScope temp_scope(&this->temp_scope_); |
1267 ZoneListWrapper<Statement> processor; | 1052 ZoneListWrapper<Statement> processor; |
1268 bool ok = true; | 1053 bool ok = true; |
1269 ParseSourceElements(&processor, Token::EOS, &ok); | 1054 ParseSourceElements(&processor, Token::EOS, &ok); |
1270 return !scanner().stack_overflow(); | 1055 return !scanner().stack_overflow(); |
1271 } | 1056 } |
1272 | 1057 |
1273 | 1058 |
1274 FunctionLiteral* Parser::ParseProgram(Handle<String> source, | 1059 FunctionLiteral* Parser::ParseProgram(Handle<String> source, |
1275 bool in_global_context) { | 1060 bool in_global_context) { |
1276 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); | 1061 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); |
(...skipping 13 matching lines...) Expand all Loading... |
1290 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; | 1075 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; |
1291 | 1076 |
1292 Scope::Type type = | 1077 Scope::Type type = |
1293 in_global_context | 1078 in_global_context |
1294 ? Scope::GLOBAL_SCOPE | 1079 ? Scope::GLOBAL_SCOPE |
1295 : Scope::EVAL_SCOPE; | 1080 : Scope::EVAL_SCOPE; |
1296 Handle<String> no_name = factory()->EmptySymbol(); | 1081 Handle<String> no_name = factory()->EmptySymbol(); |
1297 | 1082 |
1298 FunctionLiteral* result = NULL; | 1083 FunctionLiteral* result = NULL; |
1299 { Scope* scope = factory()->NewScope(top_scope_, type, inside_with()); | 1084 { Scope* scope = factory()->NewScope(top_scope_, type, inside_with()); |
1300 LexicalScope lexical_scope(this, scope); | 1085 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
1301 TemporaryScope temp_scope(this); | 1086 scope); |
| 1087 TemporaryScope temp_scope(&this->temp_scope_); |
1302 ZoneListWrapper<Statement> body(16); | 1088 ZoneListWrapper<Statement> body(16); |
1303 bool ok = true; | 1089 bool ok = true; |
1304 ParseSourceElements(&body, Token::EOS, &ok); | 1090 ParseSourceElements(&body, Token::EOS, &ok); |
1305 if (ok) { | 1091 if (ok) { |
1306 result = NEW(FunctionLiteral( | 1092 result = NEW(FunctionLiteral( |
1307 no_name, | 1093 no_name, |
1308 top_scope_, | 1094 top_scope_, |
1309 body.elements(), | 1095 body.elements(), |
1310 temp_scope.materialized_literal_count(), | 1096 temp_scope.materialized_literal_count(), |
1311 temp_scope.expected_property_count(), | 1097 temp_scope.expected_property_count(), |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1349 mode_ = PARSE_EAGERLY; | 1135 mode_ = PARSE_EAGERLY; |
1350 | 1136 |
1351 // Place holder for the result. | 1137 // Place holder for the result. |
1352 FunctionLiteral* result = NULL; | 1138 FunctionLiteral* result = NULL; |
1353 | 1139 |
1354 { | 1140 { |
1355 // Parse the function literal. | 1141 // Parse the function literal. |
1356 Handle<String> no_name = factory()->EmptySymbol(); | 1142 Handle<String> no_name = factory()->EmptySymbol(); |
1357 Scope* scope = | 1143 Scope* scope = |
1358 factory()->NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); | 1144 factory()->NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); |
1359 LexicalScope lexical_scope(this, scope); | 1145 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
1360 TemporaryScope temp_scope(this); | 1146 scope); |
| 1147 TemporaryScope temp_scope(&this->temp_scope_); |
1361 | 1148 |
1362 FunctionLiteralType type = | 1149 FunctionLiteralType type = |
1363 info->is_expression() ? EXPRESSION : DECLARATION; | 1150 info->is_expression() ? EXPRESSION : DECLARATION; |
1364 bool ok = true; | 1151 bool ok = true; |
1365 result = ParseFunctionLiteral(name, RelocInfo::kNoPosition, type, &ok); | 1152 result = ParseFunctionLiteral(name, RelocInfo::kNoPosition, type, &ok); |
1366 // Make sure the results agree. | 1153 // Make sure the results agree. |
1367 ASSERT(ok == (result != NULL)); | 1154 ASSERT(ok == (result != NULL)); |
1368 // The only errors should be stack overflows. | 1155 // The only errors should be stack overflows. |
1369 ASSERT(ok || scanner_.stack_overflow()); | 1156 ASSERT(ok || scanner_.stack_overflow()); |
1370 } | 1157 } |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1676 void* Parser::ParseSourceElements(ZoneListWrapper<Statement>* processor, | 1463 void* Parser::ParseSourceElements(ZoneListWrapper<Statement>* processor, |
1677 int end_token, | 1464 int end_token, |
1678 bool* ok) { | 1465 bool* ok) { |
1679 // SourceElements :: | 1466 // SourceElements :: |
1680 // (Statement)* <end_token> | 1467 // (Statement)* <end_token> |
1681 | 1468 |
1682 // Allocate a target stack to use for this set of source | 1469 // Allocate a target stack to use for this set of source |
1683 // elements. This way, all scripts and functions get their own | 1470 // elements. This way, all scripts and functions get their own |
1684 // target stack thus avoiding illegal breaks and continues across | 1471 // target stack thus avoiding illegal breaks and continues across |
1685 // functions. | 1472 // functions. |
1686 TargetScope scope(this); | 1473 TargetScope scope(&this->target_stack_); |
1687 | 1474 |
1688 ASSERT(processor != NULL); | 1475 ASSERT(processor != NULL); |
1689 InitializationBlockFinder block_finder; | 1476 InitializationBlockFinder block_finder; |
1690 ThisNamedPropertyAssigmentFinder this_property_assignment_finder; | 1477 ThisNamedPropertyAssigmentFinder this_property_assignment_finder; |
1691 while (peek() != end_token) { | 1478 while (peek() != end_token) { |
1692 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1479 Statement* stat = ParseStatement(NULL, CHECK_OK); |
1693 if (stat == NULL || stat->IsEmpty()) continue; | 1480 if (stat == NULL || stat->IsEmpty()) continue; |
1694 // We find and mark the initialization blocks on top level code only. | 1481 // We find and mark the initialization blocks on top level code only. |
1695 // This is because the optimization prevents reuse of the map transitions, | 1482 // This is because the optimization prevents reuse of the map transitions, |
1696 // so it should be used only for code that will only be run once. | 1483 // so it should be used only for code that will only be run once. |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1800 stmt = ParseThrowStatement(ok); | 1587 stmt = ParseThrowStatement(ok); |
1801 break; | 1588 break; |
1802 | 1589 |
1803 case Token::TRY: { | 1590 case Token::TRY: { |
1804 // NOTE: It is somewhat complicated to have labels on | 1591 // NOTE: It is somewhat complicated to have labels on |
1805 // try-statements. When breaking out of a try-finally statement, | 1592 // try-statements. When breaking out of a try-finally statement, |
1806 // one must take great care not to treat it as a | 1593 // one must take great care not to treat it as a |
1807 // fall-through. It is much easier just to wrap the entire | 1594 // fall-through. It is much easier just to wrap the entire |
1808 // try-statement in a statement block and put the labels there | 1595 // try-statement in a statement block and put the labels there |
1809 Block* result = NEW(Block(labels, 1, false)); | 1596 Block* result = NEW(Block(labels, 1, false)); |
1810 Target target(this, result); | 1597 Target target(&this->target_stack_, result); |
1811 TryStatement* statement = ParseTryStatement(CHECK_OK); | 1598 TryStatement* statement = ParseTryStatement(CHECK_OK); |
1812 if (statement) { | 1599 if (statement) { |
1813 statement->set_statement_pos(statement_pos); | 1600 statement->set_statement_pos(statement_pos); |
1814 } | 1601 } |
1815 if (result) result->AddStatement(statement); | 1602 if (result) result->AddStatement(statement); |
1816 return result; | 1603 return result; |
1817 } | 1604 } |
1818 | 1605 |
1819 case Token::FUNCTION: | 1606 case Token::FUNCTION: |
1820 return ParseFunctionDeclaration(ok); | 1607 return ParseFunctionDeclaration(ok); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2016 | 1803 |
2017 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1804 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
2018 // Block :: | 1805 // Block :: |
2019 // '{' Statement* '}' | 1806 // '{' Statement* '}' |
2020 | 1807 |
2021 // Note that a Block does not introduce a new execution scope! | 1808 // Note that a Block does not introduce a new execution scope! |
2022 // (ECMA-262, 3rd, 12.2) | 1809 // (ECMA-262, 3rd, 12.2) |
2023 // | 1810 // |
2024 // Construct block expecting 16 statements. | 1811 // Construct block expecting 16 statements. |
2025 Block* result = NEW(Block(labels, 16, false)); | 1812 Block* result = NEW(Block(labels, 16, false)); |
2026 Target target(this, result); | 1813 Target target(&this->target_stack_, result); |
2027 Expect(Token::LBRACE, CHECK_OK); | 1814 Expect(Token::LBRACE, CHECK_OK); |
2028 while (peek() != Token::RBRACE) { | 1815 while (peek() != Token::RBRACE) { |
2029 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1816 Statement* stat = ParseStatement(NULL, CHECK_OK); |
2030 if (stat && !stat->IsEmpty()) result->AddStatement(stat); | 1817 if (stat && !stat->IsEmpty()) result->AddStatement(stat); |
2031 } | 1818 } |
2032 Expect(Token::RBRACE, CHECK_OK); | 1819 Expect(Token::RBRACE, CHECK_OK); |
2033 return result; | 1820 return result; |
2034 } | 1821 } |
2035 | 1822 |
2036 | 1823 |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2411 | 2198 |
2412 | 2199 |
2413 Block* Parser::WithHelper(Expression* obj, | 2200 Block* Parser::WithHelper(Expression* obj, |
2414 ZoneStringList* labels, | 2201 ZoneStringList* labels, |
2415 bool is_catch_block, | 2202 bool is_catch_block, |
2416 bool* ok) { | 2203 bool* ok) { |
2417 // Parse the statement and collect escaping labels. | 2204 // Parse the statement and collect escaping labels. |
2418 ZoneList<BreakTarget*>* target_list = NEW(ZoneList<BreakTarget*>(0)); | 2205 ZoneList<BreakTarget*>* target_list = NEW(ZoneList<BreakTarget*>(0)); |
2419 TargetCollector collector(target_list); | 2206 TargetCollector collector(target_list); |
2420 Statement* stat; | 2207 Statement* stat; |
2421 { Target target(this, &collector); | 2208 { Target target(&this->target_stack_, &collector); |
2422 with_nesting_level_++; | 2209 with_nesting_level_++; |
2423 top_scope_->RecordWithStatement(); | 2210 top_scope_->RecordWithStatement(); |
2424 stat = ParseStatement(labels, CHECK_OK); | 2211 stat = ParseStatement(labels, CHECK_OK); |
2425 with_nesting_level_--; | 2212 with_nesting_level_--; |
2426 } | 2213 } |
2427 // Create resulting block with two statements. | 2214 // Create resulting block with two statements. |
2428 // 1: Evaluate the with expression. | 2215 // 1: Evaluate the with expression. |
2429 // 2: The try-finally block evaluating the body. | 2216 // 2: The try-finally block evaluating the body. |
2430 Block* result = NEW(Block(NULL, 2, false)); | 2217 Block* result = NEW(Block(NULL, 2, false)); |
2431 | 2218 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2494 return NEW(CaseClause(label, statements.elements())); | 2281 return NEW(CaseClause(label, statements.elements())); |
2495 } | 2282 } |
2496 | 2283 |
2497 | 2284 |
2498 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, | 2285 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, |
2499 bool* ok) { | 2286 bool* ok) { |
2500 // SwitchStatement :: | 2287 // SwitchStatement :: |
2501 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 2288 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
2502 | 2289 |
2503 SwitchStatement* statement = NEW(SwitchStatement(labels)); | 2290 SwitchStatement* statement = NEW(SwitchStatement(labels)); |
2504 Target target(this, statement); | 2291 Target target(&this->target_stack_, statement); |
2505 | 2292 |
2506 Expect(Token::SWITCH, CHECK_OK); | 2293 Expect(Token::SWITCH, CHECK_OK); |
2507 Expect(Token::LPAREN, CHECK_OK); | 2294 Expect(Token::LPAREN, CHECK_OK); |
2508 Expression* tag = ParseExpression(true, CHECK_OK); | 2295 Expression* tag = ParseExpression(true, CHECK_OK); |
2509 Expect(Token::RPAREN, CHECK_OK); | 2296 Expect(Token::RPAREN, CHECK_OK); |
2510 | 2297 |
2511 bool default_seen = false; | 2298 bool default_seen = false; |
2512 ZoneListWrapper<CaseClause> cases = factory()->NewList<CaseClause>(4); | 2299 ZoneListWrapper<CaseClause> cases = factory()->NewList<CaseClause>(4); |
2513 Expect(Token::LBRACE, CHECK_OK); | 2300 Expect(Token::LBRACE, CHECK_OK); |
2514 while (peek() != Token::RBRACE) { | 2301 while (peek() != Token::RBRACE) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2551 // | 2338 // |
2552 // Finally :: | 2339 // Finally :: |
2553 // 'finally' Block | 2340 // 'finally' Block |
2554 | 2341 |
2555 Expect(Token::TRY, CHECK_OK); | 2342 Expect(Token::TRY, CHECK_OK); |
2556 | 2343 |
2557 ZoneList<BreakTarget*>* target_list = NEW(ZoneList<BreakTarget*>(0)); | 2344 ZoneList<BreakTarget*>* target_list = NEW(ZoneList<BreakTarget*>(0)); |
2558 TargetCollector collector(target_list); | 2345 TargetCollector collector(target_list); |
2559 Block* try_block; | 2346 Block* try_block; |
2560 | 2347 |
2561 { Target target(this, &collector); | 2348 { Target target(&this->target_stack_, &collector); |
2562 try_block = ParseBlock(NULL, CHECK_OK); | 2349 try_block = ParseBlock(NULL, CHECK_OK); |
2563 } | 2350 } |
2564 | 2351 |
2565 Block* catch_block = NULL; | 2352 Block* catch_block = NULL; |
2566 VariableProxy* catch_var = NULL; | 2353 VariableProxy* catch_var = NULL; |
2567 Block* finally_block = NULL; | 2354 Block* finally_block = NULL; |
2568 | 2355 |
2569 Token::Value tok = peek(); | 2356 Token::Value tok = peek(); |
2570 if (tok != Token::CATCH && tok != Token::FINALLY) { | 2357 if (tok != Token::CATCH && tok != Token::FINALLY) { |
2571 ReportMessage("no_catch_or_finally", Vector<const char*>::empty()); | 2358 ReportMessage("no_catch_or_finally", Vector<const char*>::empty()); |
(...skipping 15 matching lines...) Expand all Loading... |
2587 Expect(Token::LPAREN, CHECK_OK); | 2374 Expect(Token::LPAREN, CHECK_OK); |
2588 Handle<String> name = ParseIdentifier(CHECK_OK); | 2375 Handle<String> name = ParseIdentifier(CHECK_OK); |
2589 Expect(Token::RPAREN, CHECK_OK); | 2376 Expect(Token::RPAREN, CHECK_OK); |
2590 | 2377 |
2591 if (peek() == Token::LBRACE) { | 2378 if (peek() == Token::LBRACE) { |
2592 // Allocate a temporary for holding the finally state while | 2379 // Allocate a temporary for holding the finally state while |
2593 // executing the finally block. | 2380 // executing the finally block. |
2594 catch_var = top_scope_->NewTemporary(Factory::catch_var_symbol()); | 2381 catch_var = top_scope_->NewTemporary(Factory::catch_var_symbol()); |
2595 Literal* name_literal = NEW(Literal(name)); | 2382 Literal* name_literal = NEW(Literal(name)); |
2596 Expression* obj = NEW(CatchExtensionObject(name_literal, catch_var)); | 2383 Expression* obj = NEW(CatchExtensionObject(name_literal, catch_var)); |
2597 { Target target(this, &catch_collector); | 2384 { Target target(&this->target_stack_, &catch_collector); |
2598 catch_block = WithHelper(obj, NULL, true, CHECK_OK); | 2385 catch_block = WithHelper(obj, NULL, true, CHECK_OK); |
2599 } | 2386 } |
2600 } else { | 2387 } else { |
2601 Expect(Token::LBRACE, CHECK_OK); | 2388 Expect(Token::LBRACE, CHECK_OK); |
2602 } | 2389 } |
2603 | 2390 |
2604 tok = peek(); | 2391 tok = peek(); |
2605 } | 2392 } |
2606 | 2393 |
2607 if (tok == Token::FINALLY || !has_catch) { | 2394 if (tok == Token::FINALLY || !has_catch) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2646 } | 2433 } |
2647 | 2434 |
2648 | 2435 |
2649 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, | 2436 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, |
2650 bool* ok) { | 2437 bool* ok) { |
2651 // DoStatement :: | 2438 // DoStatement :: |
2652 // 'do' Statement 'while' '(' Expression ')' ';' | 2439 // 'do' Statement 'while' '(' Expression ')' ';' |
2653 | 2440 |
2654 temp_scope_->AddLoop(); | 2441 temp_scope_->AddLoop(); |
2655 DoWhileStatement* loop = NEW(DoWhileStatement(labels)); | 2442 DoWhileStatement* loop = NEW(DoWhileStatement(labels)); |
2656 Target target(this, loop); | 2443 Target target(&this->target_stack_, loop); |
2657 | 2444 |
2658 Expect(Token::DO, CHECK_OK); | 2445 Expect(Token::DO, CHECK_OK); |
2659 Statement* body = ParseStatement(NULL, CHECK_OK); | 2446 Statement* body = ParseStatement(NULL, CHECK_OK); |
2660 Expect(Token::WHILE, CHECK_OK); | 2447 Expect(Token::WHILE, CHECK_OK); |
2661 Expect(Token::LPAREN, CHECK_OK); | 2448 Expect(Token::LPAREN, CHECK_OK); |
2662 | 2449 |
2663 if (loop != NULL) { | 2450 if (loop != NULL) { |
2664 int position = scanner().location().beg_pos; | 2451 int position = scanner().location().beg_pos; |
2665 loop->set_condition_position(position); | 2452 loop->set_condition_position(position); |
2666 } | 2453 } |
(...skipping 12 matching lines...) Expand all Loading... |
2679 return loop; | 2466 return loop; |
2680 } | 2467 } |
2681 | 2468 |
2682 | 2469 |
2683 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { | 2470 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { |
2684 // WhileStatement :: | 2471 // WhileStatement :: |
2685 // 'while' '(' Expression ')' Statement | 2472 // 'while' '(' Expression ')' Statement |
2686 | 2473 |
2687 temp_scope_->AddLoop(); | 2474 temp_scope_->AddLoop(); |
2688 WhileStatement* loop = NEW(WhileStatement(labels)); | 2475 WhileStatement* loop = NEW(WhileStatement(labels)); |
2689 Target target(this, loop); | 2476 Target target(&this->target_stack_, loop); |
2690 | 2477 |
2691 Expect(Token::WHILE, CHECK_OK); | 2478 Expect(Token::WHILE, CHECK_OK); |
2692 Expect(Token::LPAREN, CHECK_OK); | 2479 Expect(Token::LPAREN, CHECK_OK); |
2693 Expression* cond = ParseExpression(true, CHECK_OK); | 2480 Expression* cond = ParseExpression(true, CHECK_OK); |
2694 if (cond != NULL) cond->set_is_loop_condition(true); | 2481 if (cond != NULL) cond->set_is_loop_condition(true); |
2695 Expect(Token::RPAREN, CHECK_OK); | 2482 Expect(Token::RPAREN, CHECK_OK); |
2696 Statement* body = ParseStatement(NULL, CHECK_OK); | 2483 Statement* body = ParseStatement(NULL, CHECK_OK); |
2697 | 2484 |
2698 if (loop != NULL) loop->Initialize(cond, body); | 2485 if (loop != NULL) loop->Initialize(cond, body); |
2699 return loop; | 2486 return loop; |
2700 } | 2487 } |
2701 | 2488 |
2702 | 2489 |
2703 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 2490 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
2704 // ForStatement :: | 2491 // ForStatement :: |
2705 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 2492 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
2706 | 2493 |
2707 temp_scope_->AddLoop(); | 2494 temp_scope_->AddLoop(); |
2708 Statement* init = NULL; | 2495 Statement* init = NULL; |
2709 | 2496 |
2710 Expect(Token::FOR, CHECK_OK); | 2497 Expect(Token::FOR, CHECK_OK); |
2711 Expect(Token::LPAREN, CHECK_OK); | 2498 Expect(Token::LPAREN, CHECK_OK); |
2712 if (peek() != Token::SEMICOLON) { | 2499 if (peek() != Token::SEMICOLON) { |
2713 if (peek() == Token::VAR || peek() == Token::CONST) { | 2500 if (peek() == Token::VAR || peek() == Token::CONST) { |
2714 Expression* each = NULL; | 2501 Expression* each = NULL; |
2715 Block* variable_statement = | 2502 Block* variable_statement = |
2716 ParseVariableDeclarations(false, &each, CHECK_OK); | 2503 ParseVariableDeclarations(false, &each, CHECK_OK); |
2717 if (peek() == Token::IN && each != NULL) { | 2504 if (peek() == Token::IN && each != NULL) { |
2718 ForInStatement* loop = NEW(ForInStatement(labels)); | 2505 ForInStatement* loop = NEW(ForInStatement(labels)); |
2719 Target target(this, loop); | 2506 Target target(&this->target_stack_, loop); |
2720 | 2507 |
2721 Expect(Token::IN, CHECK_OK); | 2508 Expect(Token::IN, CHECK_OK); |
2722 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2509 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2723 Expect(Token::RPAREN, CHECK_OK); | 2510 Expect(Token::RPAREN, CHECK_OK); |
2724 | 2511 |
2725 Statement* body = ParseStatement(NULL, CHECK_OK); | 2512 Statement* body = ParseStatement(NULL, CHECK_OK); |
2726 if (is_pre_parsing_) { | 2513 if (is_pre_parsing_) { |
2727 return NULL; | 2514 return NULL; |
2728 } else { | 2515 } else { |
2729 loop->Initialize(each, enumerable, body); | 2516 loop->Initialize(each, enumerable, body); |
(...skipping 13 matching lines...) Expand all Loading... |
2743 if (peek() == Token::IN) { | 2530 if (peek() == Token::IN) { |
2744 // Signal a reference error if the expression is an invalid | 2531 // Signal a reference error if the expression is an invalid |
2745 // left-hand side expression. We could report this as a syntax | 2532 // left-hand side expression. We could report this as a syntax |
2746 // error here but for compatibility with JSC we choose to report | 2533 // error here but for compatibility with JSC we choose to report |
2747 // the error at runtime. | 2534 // the error at runtime. |
2748 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2535 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
2749 Handle<String> type = Factory::invalid_lhs_in_for_in_symbol(); | 2536 Handle<String> type = Factory::invalid_lhs_in_for_in_symbol(); |
2750 expression = NewThrowReferenceError(type); | 2537 expression = NewThrowReferenceError(type); |
2751 } | 2538 } |
2752 ForInStatement* loop = NEW(ForInStatement(labels)); | 2539 ForInStatement* loop = NEW(ForInStatement(labels)); |
2753 Target target(this, loop); | 2540 Target target(&this->target_stack_, loop); |
2754 | 2541 |
2755 Expect(Token::IN, CHECK_OK); | 2542 Expect(Token::IN, CHECK_OK); |
2756 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2543 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2757 Expect(Token::RPAREN, CHECK_OK); | 2544 Expect(Token::RPAREN, CHECK_OK); |
2758 | 2545 |
2759 Statement* body = ParseStatement(NULL, CHECK_OK); | 2546 Statement* body = ParseStatement(NULL, CHECK_OK); |
2760 if (loop) loop->Initialize(expression, enumerable, body); | 2547 if (loop) loop->Initialize(expression, enumerable, body); |
2761 // Parsed for-in loop. | 2548 // Parsed for-in loop. |
2762 return loop; | 2549 return loop; |
2763 | 2550 |
2764 } else { | 2551 } else { |
2765 init = NEW(ExpressionStatement(expression)); | 2552 init = NEW(ExpressionStatement(expression)); |
2766 } | 2553 } |
2767 } | 2554 } |
2768 } | 2555 } |
2769 | 2556 |
2770 // Standard 'for' loop | 2557 // Standard 'for' loop |
2771 ForStatement* loop = NEW(ForStatement(labels)); | 2558 ForStatement* loop = NEW(ForStatement(labels)); |
2772 Target target(this, loop); | 2559 Target target(&this->target_stack_, loop); |
2773 | 2560 |
2774 // Parsed initializer at this point. | 2561 // Parsed initializer at this point. |
2775 Expect(Token::SEMICOLON, CHECK_OK); | 2562 Expect(Token::SEMICOLON, CHECK_OK); |
2776 | 2563 |
2777 Expression* cond = NULL; | 2564 Expression* cond = NULL; |
2778 if (peek() != Token::SEMICOLON) { | 2565 if (peek() != Token::SEMICOLON) { |
2779 cond = ParseExpression(true, CHECK_OK); | 2566 cond = ParseExpression(true, CHECK_OK); |
2780 if (cond != NULL) cond->set_is_loop_condition(true); | 2567 if (cond != NULL) cond->set_is_loop_condition(true); |
2781 } | 2568 } |
2782 Expect(Token::SEMICOLON, CHECK_OK); | 2569 Expect(Token::SEMICOLON, CHECK_OK); |
(...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3852 // The function name, if any. | 3639 // The function name, if any. |
3853 Handle<String> function_name = factory()->EmptySymbol(); | 3640 Handle<String> function_name = factory()->EmptySymbol(); |
3854 if (is_named && (type == EXPRESSION || type == NESTED)) { | 3641 if (is_named && (type == EXPRESSION || type == NESTED)) { |
3855 function_name = name; | 3642 function_name = name; |
3856 } | 3643 } |
3857 | 3644 |
3858 int num_parameters = 0; | 3645 int num_parameters = 0; |
3859 // Parse function body. | 3646 // Parse function body. |
3860 { Scope* scope = | 3647 { Scope* scope = |
3861 factory()->NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); | 3648 factory()->NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); |
3862 LexicalScope lexical_scope(this, scope); | 3649 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
3863 TemporaryScope temp_scope(this); | 3650 scope); |
| 3651 TemporaryScope temp_scope(&this->temp_scope_); |
3864 top_scope_->SetScopeName(name); | 3652 top_scope_->SetScopeName(name); |
3865 | 3653 |
3866 // FormalParameterList :: | 3654 // FormalParameterList :: |
3867 // '(' (Identifier)*[','] ')' | 3655 // '(' (Identifier)*[','] ')' |
3868 Expect(Token::LPAREN, CHECK_OK); | 3656 Expect(Token::LPAREN, CHECK_OK); |
3869 int start_pos = scanner_.location().beg_pos; | 3657 int start_pos = scanner_.location().beg_pos; |
3870 bool done = (peek() == Token::RPAREN); | 3658 bool done = (peek() == Token::RPAREN); |
3871 while (!done) { | 3659 while (!done) { |
3872 Handle<String> param_name = ParseIdentifier(CHECK_OK); | 3660 Handle<String> param_name = ParseIdentifier(CHECK_OK); |
3873 if (!is_pre_parsing_) { | 3661 if (!is_pre_parsing_) { |
(...skipping 1336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5210 } | 4998 } |
5211 | 4999 |
5212 | 5000 |
5213 bool ScriptDataImpl::HasError() { | 5001 bool ScriptDataImpl::HasError() { |
5214 return has_error(); | 5002 return has_error(); |
5215 } | 5003 } |
5216 | 5004 |
5217 | 5005 |
5218 // Preparse, but only collect data that is immediately useful, | 5006 // Preparse, but only collect data that is immediately useful, |
5219 // even if the preparser data is only used once. | 5007 // even if the preparser data is only used once. |
5220 ScriptDataImpl* Parser::PartialPreParse(Handle<String> source, | 5008 ScriptDataImpl* ParserApi::PartialPreParse(Handle<String> source, |
5221 unibrow::CharacterStream* stream, | 5009 unibrow::CharacterStream* stream, |
5222 v8::Extension* extension) { | 5010 v8::Extension* extension) { |
5223 Handle<Script> no_script; | 5011 Handle<Script> no_script; |
5224 bool allow_natives_syntax = | 5012 bool allow_natives_syntax = |
5225 FLAG_allow_natives_syntax || Bootstrapper::IsActive(); | 5013 FLAG_allow_natives_syntax || Bootstrapper::IsActive(); |
5226 PartialPreParser parser(no_script, allow_natives_syntax, extension); | 5014 PartialPreParser parser(no_script, allow_natives_syntax, extension); |
5227 if (!parser.PreParseProgram(source, stream)) return NULL; | 5015 if (!parser.PreParseProgram(source, stream)) return NULL; |
5228 // Extract the accumulated data from the recorder as a single | 5016 // Extract the accumulated data from the recorder as a single |
5229 // contiguous vector that we are responsible for disposing. | 5017 // contiguous vector that we are responsible for disposing. |
5230 Vector<unsigned> store = parser.recorder()->ExtractData(); | 5018 Vector<unsigned> store = parser.recorder()->ExtractData(); |
5231 return new ScriptDataImpl(store); | 5019 return new ScriptDataImpl(store); |
5232 } | 5020 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5268 if (data >= symbol_data_end_) return -1; | 5056 if (data >= symbol_data_end_) return -1; |
5269 input = *data; | 5057 input = *data; |
5270 result = (result << 7) | (input & 0x7f); | 5058 result = (result << 7) | (input & 0x7f); |
5271 data++; | 5059 data++; |
5272 } | 5060 } |
5273 *source = data; | 5061 *source = data; |
5274 return result; | 5062 return result; |
5275 } | 5063 } |
5276 | 5064 |
5277 | 5065 |
5278 ScriptDataImpl* Parser::PreParse(Handle<String> source, | 5066 ScriptDataImpl* ParserApi::PreParse(Handle<String> source, |
5279 unibrow::CharacterStream* stream, | 5067 unibrow::CharacterStream* stream, |
5280 v8::Extension* extension) { | 5068 v8::Extension* extension) { |
5281 Handle<Script> no_script; | 5069 Handle<Script> no_script; |
5282 bool allow_natives_syntax = | 5070 bool allow_natives_syntax = |
5283 FLAG_allow_natives_syntax || Bootstrapper::IsActive(); | 5071 FLAG_allow_natives_syntax || Bootstrapper::IsActive(); |
5284 CompletePreParser parser(no_script, allow_natives_syntax, extension); | 5072 CompletePreParser parser(no_script, allow_natives_syntax, extension); |
5285 if (!parser.PreParseProgram(source, stream)) return NULL; | 5073 if (!parser.PreParseProgram(source, stream)) return NULL; |
5286 // Extract the accumulated data from the recorder as a single | 5074 // Extract the accumulated data from the recorder as a single |
5287 // contiguous vector that we are responsible for disposing. | 5075 // contiguous vector that we are responsible for disposing. |
5288 Vector<unsigned> store = parser.recorder()->ExtractData(); | 5076 Vector<unsigned> store = parser.recorder()->ExtractData(); |
5289 return new ScriptDataImpl(store); | 5077 return new ScriptDataImpl(store); |
5290 } | 5078 } |
5291 | 5079 |
5292 | 5080 |
5293 bool Parser::ParseRegExp(FlatStringReader* input, | 5081 bool RegExpParser::ParseRegExp(FlatStringReader* input, |
5294 bool multiline, | 5082 bool multiline, |
5295 RegExpCompileData* result) { | 5083 RegExpCompileData* result) { |
5296 ASSERT(result != NULL); | 5084 ASSERT(result != NULL); |
5297 RegExpParser parser(input, &result->error, multiline); | 5085 RegExpParser parser(input, &result->error, multiline); |
5298 RegExpTree* tree = parser.ParsePattern(); | 5086 RegExpTree* tree = parser.ParsePattern(); |
5299 if (parser.failed()) { | 5087 if (parser.failed()) { |
5300 ASSERT(tree == NULL); | 5088 ASSERT(tree == NULL); |
5301 ASSERT(!result->error.is_null()); | 5089 ASSERT(!result->error.is_null()); |
5302 } else { | 5090 } else { |
5303 ASSERT(tree != NULL); | 5091 ASSERT(tree != NULL); |
5304 ASSERT(result->error.is_null()); | 5092 ASSERT(result->error.is_null()); |
5305 result->tree = tree; | 5093 result->tree = tree; |
5306 int capture_count = parser.captures_started(); | 5094 int capture_count = parser.captures_started(); |
5307 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; | 5095 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; |
5308 result->contains_anchor = parser.contains_anchor(); | 5096 result->contains_anchor = parser.contains_anchor(); |
5309 result->capture_count = capture_count; | 5097 result->capture_count = capture_count; |
5310 } | 5098 } |
5311 return !parser.failed(); | 5099 return !parser.failed(); |
5312 } | 5100 } |
5313 | 5101 |
5314 | 5102 |
5315 bool Parser::Parse(CompilationInfo* info) { | 5103 bool ParserApi::Parse(CompilationInfo* info) { |
5316 ASSERT(info->function() == NULL); | 5104 ASSERT(info->function() == NULL); |
5317 FunctionLiteral* result = NULL; | 5105 FunctionLiteral* result = NULL; |
5318 Handle<Script> script = info->script(); | 5106 Handle<Script> script = info->script(); |
5319 if (info->is_lazy()) { | 5107 if (info->is_lazy()) { |
5320 AstBuildingParser parser(script, true, NULL, NULL); | 5108 AstBuildingParser parser(script, true, NULL, NULL); |
5321 result = parser.ParseLazy(info->shared_info()); | 5109 result = parser.ParseLazy(info->shared_info()); |
5322 } else { | 5110 } else { |
5323 bool allow_natives_syntax = | 5111 bool allow_natives_syntax = |
5324 FLAG_allow_natives_syntax || Bootstrapper::IsActive(); | 5112 FLAG_allow_natives_syntax || Bootstrapper::IsActive(); |
5325 ScriptDataImpl* pre_data = info->pre_parse_data(); | 5113 ScriptDataImpl* pre_data = info->pre_parse_data(); |
(...skipping 16 matching lines...) Expand all Loading... |
5342 } | 5130 } |
5343 } | 5131 } |
5344 | 5132 |
5345 info->SetFunction(result); | 5133 info->SetFunction(result); |
5346 return (result != NULL); | 5134 return (result != NULL); |
5347 } | 5135 } |
5348 | 5136 |
5349 #undef NEW | 5137 #undef NEW |
5350 | 5138 |
5351 } } // namespace v8::internal | 5139 } } // namespace v8::internal |
OLD | NEW |