| 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 |