| 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 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 } else { | 239 } else { |
| 240 // Only call immediately after adding an atom or character! | 240 // Only call immediately after adding an atom or character! |
| 241 UNREACHABLE(); | 241 UNREACHABLE(); |
| 242 return; | 242 return; |
| 243 } | 243 } |
| 244 terms_.Add(new RegExpQuantifier(min, max, type, atom)); | 244 terms_.Add(new RegExpQuantifier(min, max, type, atom)); |
| 245 LAST(ADD_TERM); | 245 LAST(ADD_TERM); |
| 246 } | 246 } |
| 247 | 247 |
| 248 | 248 |
| 249 // A temporary scope stores information during parsing, just like | |
| 250 // a plain scope. However, temporary scopes are not kept around | |
| 251 // after parsing or referenced by syntax trees so they can be stack- | |
| 252 // allocated and hence used by the pre-parser. | |
| 253 class TemporaryScope BASE_EMBEDDED { | |
| 254 public: | |
| 255 explicit TemporaryScope(TemporaryScope** variable); | |
| 256 ~TemporaryScope(); | |
| 257 | |
| 258 int NextMaterializedLiteralIndex() { | |
| 259 int next_index = | |
| 260 materialized_literal_count_ + JSFunction::kLiteralsPrefixSize; | |
| 261 materialized_literal_count_++; | |
| 262 return next_index; | |
| 263 } | |
| 264 int materialized_literal_count() { return materialized_literal_count_; } | |
| 265 | |
| 266 void SetThisPropertyAssignmentInfo( | |
| 267 bool only_simple_this_property_assignments, | |
| 268 Handle<FixedArray> this_property_assignments) { | |
| 269 only_simple_this_property_assignments_ = | |
| 270 only_simple_this_property_assignments; | |
| 271 this_property_assignments_ = this_property_assignments; | |
| 272 } | |
| 273 bool only_simple_this_property_assignments() { | |
| 274 return only_simple_this_property_assignments_; | |
| 275 } | |
| 276 Handle<FixedArray> this_property_assignments() { | |
| 277 return this_property_assignments_; | |
| 278 } | |
| 279 | |
| 280 void AddProperty() { expected_property_count_++; } | |
| 281 int expected_property_count() { return expected_property_count_; } | |
| 282 | |
| 283 void AddLoop() { loop_count_++; } | |
| 284 bool ContainsLoops() const { return loop_count_ > 0; } | |
| 285 | |
| 286 private: | |
| 287 // Captures the number of literals that need materialization in the | |
| 288 // function. Includes regexp literals, and boilerplate for object | |
| 289 // and array literals. | |
| 290 int materialized_literal_count_; | |
| 291 | |
| 292 // Properties count estimation. | |
| 293 int expected_property_count_; | |
| 294 | |
| 295 // Keeps track of assignments to properties of this. Used for | |
| 296 // optimizing constructors. | |
| 297 bool only_simple_this_property_assignments_; | |
| 298 Handle<FixedArray> this_property_assignments_; | |
| 299 | |
| 300 // Captures the number of loops inside the scope. | |
| 301 int loop_count_; | |
| 302 | |
| 303 // Bookkeeping | |
| 304 TemporaryScope** variable_; | |
| 305 TemporaryScope* parent_; | |
| 306 }; | |
| 307 | |
| 308 | |
| 309 TemporaryScope::TemporaryScope(TemporaryScope** variable) | |
| 310 : materialized_literal_count_(0), | |
| 311 expected_property_count_(0), | |
| 312 only_simple_this_property_assignments_(false), | |
| 313 this_property_assignments_( | |
| 314 Isolate::Current()->factory()->empty_fixed_array()), | |
| 315 loop_count_(0), | |
| 316 variable_(variable), | |
| 317 parent_(*variable) { | |
| 318 *variable = this; | |
| 319 } | |
| 320 | |
| 321 | |
| 322 TemporaryScope::~TemporaryScope() { | |
| 323 *variable_ = parent_; | |
| 324 } | |
| 325 | |
| 326 | |
| 327 Handle<String> Parser::LookupSymbol(int symbol_id) { | 249 Handle<String> Parser::LookupSymbol(int symbol_id) { |
| 328 // Length of symbol cache is the number of identified symbols. | 250 // Length of symbol cache is the number of identified symbols. |
| 329 // If we are larger than that, or negative, it's not a cached symbol. | 251 // If we are larger than that, or negative, it's not a cached symbol. |
| 330 // This might also happen if there is no preparser symbol data, even | 252 // This might also happen if there is no preparser symbol data, even |
| 331 // if there is some preparser data. | 253 // if there is some preparser data. |
| 332 if (static_cast<unsigned>(symbol_id) | 254 if (static_cast<unsigned>(symbol_id) |
| 333 >= static_cast<unsigned>(symbol_cache_.length())) { | 255 >= static_cast<unsigned>(symbol_cache_.length())) { |
| 334 if (scanner().is_literal_ascii()) { | 256 if (scanner().is_literal_ascii()) { |
| 335 return isolate()->factory()->LookupAsciiSymbol( | 257 return isolate()->factory()->LookupAsciiSymbol( |
| 336 scanner().literal_ascii_string()); | 258 scanner().literal_ascii_string()); |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 private: | 454 private: |
| 533 Target** variable_; | 455 Target** variable_; |
| 534 Target* previous_; | 456 Target* previous_; |
| 535 }; | 457 }; |
| 536 | 458 |
| 537 | 459 |
| 538 // ---------------------------------------------------------------------------- | 460 // ---------------------------------------------------------------------------- |
| 539 // LexicalScope is a support class to facilitate manipulation of the | 461 // LexicalScope is a support class to facilitate manipulation of the |
| 540 // Parser's scope stack. The constructor sets the parser's top scope | 462 // Parser's scope stack. The constructor sets the parser's top scope |
| 541 // to the incoming scope, and the destructor resets it. | 463 // to the incoming scope, and the destructor resets it. |
| 464 // |
| 465 // Additionlaly, it stores transient information used during parsing. |
| 466 // These scopes are not kept around after parsing or referenced by syntax |
| 467 // trees so they can be stack-allocated and hence used by the pre-parser. |
| 542 | 468 |
| 543 class LexicalScope BASE_EMBEDDED { | 469 class LexicalScope BASE_EMBEDDED { |
| 544 public: | 470 public: |
| 545 LexicalScope(Scope** scope_variable, | 471 LexicalScope(Parser* parser, Scope* scope); |
| 546 int* with_nesting_level_variable, | 472 ~LexicalScope(); |
| 547 Scope* scope) | 473 |
| 548 : scope_variable_(scope_variable), | 474 int NextMaterializedLiteralIndex() { |
| 549 with_nesting_level_variable_(with_nesting_level_variable), | 475 int next_index = |
| 550 prev_scope_(*scope_variable), | 476 materialized_literal_count_ + JSFunction::kLiteralsPrefixSize; |
| 551 prev_level_(*with_nesting_level_variable) { | 477 materialized_literal_count_++; |
| 552 *scope_variable = scope; | 478 return next_index; |
| 553 *with_nesting_level_variable = 0; | 479 } |
| 480 int materialized_literal_count() { return materialized_literal_count_; } |
| 481 |
| 482 void SetThisPropertyAssignmentInfo( |
| 483 bool only_simple_this_property_assignments, |
| 484 Handle<FixedArray> this_property_assignments) { |
| 485 only_simple_this_property_assignments_ = |
| 486 only_simple_this_property_assignments; |
| 487 this_property_assignments_ = this_property_assignments; |
| 488 } |
| 489 bool only_simple_this_property_assignments() { |
| 490 return only_simple_this_property_assignments_; |
| 491 } |
| 492 Handle<FixedArray> this_property_assignments() { |
| 493 return this_property_assignments_; |
| 554 } | 494 } |
| 555 | 495 |
| 556 ~LexicalScope() { | 496 void AddProperty() { expected_property_count_++; } |
| 557 (*scope_variable_)->Leave(); | 497 int expected_property_count() { return expected_property_count_; } |
| 558 *scope_variable_ = prev_scope_; | 498 |
| 559 *with_nesting_level_variable_ = prev_level_; | 499 void AddLoop() { loop_count_++; } |
| 560 } | 500 bool ContainsLoops() const { return loop_count_ > 0; } |
| 561 | 501 |
| 562 private: | 502 private: |
| 563 Scope** scope_variable_; | 503 // Captures the number of literals that need materialization in the |
| 564 int* with_nesting_level_variable_; | 504 // function. Includes regexp literals, and boilerplate for object |
| 565 Scope* prev_scope_; | 505 // and array literals. |
| 566 int prev_level_; | 506 int materialized_literal_count_; |
| 507 |
| 508 // Properties count estimation. |
| 509 int expected_property_count_; |
| 510 |
| 511 // Keeps track of assignments to properties of this. Used for |
| 512 // optimizing constructors. |
| 513 bool only_simple_this_property_assignments_; |
| 514 Handle<FixedArray> this_property_assignments_; |
| 515 |
| 516 // Captures the number of loops inside the scope. |
| 517 int loop_count_; |
| 518 |
| 519 // Bookkeeping |
| 520 Parser* parser_; |
| 521 // Previous values |
| 522 LexicalScope* lexical_scope_parent_; |
| 523 Scope* previous_scope_; |
| 524 int previous_with_nesting_level_; |
| 567 }; | 525 }; |
| 568 | 526 |
| 527 |
| 528 LexicalScope::LexicalScope(Parser* parser, Scope* scope) |
| 529 : materialized_literal_count_(0), |
| 530 expected_property_count_(0), |
| 531 only_simple_this_property_assignments_(false), |
| 532 this_property_assignments_( |
| 533 Isolate::Current()->factory()->empty_fixed_array()), |
| 534 loop_count_(0), |
| 535 parser_(parser), |
| 536 lexical_scope_parent_(parser->lexical_scope_), |
| 537 previous_scope_(parser->top_scope_), |
| 538 previous_with_nesting_level_(parser->with_nesting_level_) { |
| 539 parser->top_scope_ = scope; |
| 540 parser->lexical_scope_ = this; |
| 541 parser->with_nesting_level_ = 0; |
| 542 } |
| 543 |
| 544 |
| 545 LexicalScope::~LexicalScope() { |
| 546 parser_->top_scope_->Leave(); |
| 547 parser_->top_scope_ = previous_scope_; |
| 548 parser_->lexical_scope_ = lexical_scope_parent_; |
| 549 parser_->with_nesting_level_ = previous_with_nesting_level_; |
| 550 } |
| 551 |
| 552 |
| 569 // ---------------------------------------------------------------------------- | 553 // ---------------------------------------------------------------------------- |
| 570 // The CHECK_OK macro is a convenient macro to enforce error | 554 // The CHECK_OK macro is a convenient macro to enforce error |
| 571 // handling for functions that may fail (by returning !*ok). | 555 // handling for functions that may fail (by returning !*ok). |
| 572 // | 556 // |
| 573 // CAUTION: This macro appends extra statements after a call, | 557 // CAUTION: This macro appends extra statements after a call, |
| 574 // thus it must never be used where only a single statement | 558 // thus it must never be used where only a single statement |
| 575 // is correct (e.g. an if statement branch w/o braces)! | 559 // is correct (e.g. an if statement branch w/o braces)! |
| 576 | 560 |
| 577 #define CHECK_OK ok); \ | 561 #define CHECK_OK ok); \ |
| 578 if (!*ok) return NULL; \ | 562 if (!*ok) return NULL; \ |
| (...skipping 13 matching lines...) Expand all Loading... |
| 592 Parser::Parser(Handle<Script> script, | 576 Parser::Parser(Handle<Script> script, |
| 593 bool allow_natives_syntax, | 577 bool allow_natives_syntax, |
| 594 v8::Extension* extension, | 578 v8::Extension* extension, |
| 595 ScriptDataImpl* pre_data) | 579 ScriptDataImpl* pre_data) |
| 596 : isolate_(script->GetIsolate()), | 580 : isolate_(script->GetIsolate()), |
| 597 symbol_cache_(pre_data ? pre_data->symbol_count() : 0), | 581 symbol_cache_(pre_data ? pre_data->symbol_count() : 0), |
| 598 script_(script), | 582 script_(script), |
| 599 scanner_(isolate_), | 583 scanner_(isolate_), |
| 600 top_scope_(NULL), | 584 top_scope_(NULL), |
| 601 with_nesting_level_(0), | 585 with_nesting_level_(0), |
| 602 temp_scope_(NULL), | 586 lexical_scope_(NULL), |
| 603 target_stack_(NULL), | 587 target_stack_(NULL), |
| 604 allow_natives_syntax_(allow_natives_syntax), | 588 allow_natives_syntax_(allow_natives_syntax), |
| 605 extension_(extension), | 589 extension_(extension), |
| 606 pre_data_(pre_data), | 590 pre_data_(pre_data), |
| 607 fni_(NULL), | 591 fni_(NULL), |
| 608 stack_overflow_(false), | 592 stack_overflow_(false), |
| 609 parenthesized_function_(false) { | 593 parenthesized_function_(false) { |
| 610 AstNode::ResetIds(); | 594 AstNode::ResetIds(); |
| 611 } | 595 } |
| 612 | 596 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; | 634 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; |
| 651 | 635 |
| 652 Scope::Type type = | 636 Scope::Type type = |
| 653 in_global_context | 637 in_global_context |
| 654 ? Scope::GLOBAL_SCOPE | 638 ? Scope::GLOBAL_SCOPE |
| 655 : Scope::EVAL_SCOPE; | 639 : Scope::EVAL_SCOPE; |
| 656 Handle<String> no_name = isolate()->factory()->empty_symbol(); | 640 Handle<String> no_name = isolate()->factory()->empty_symbol(); |
| 657 | 641 |
| 658 FunctionLiteral* result = NULL; | 642 FunctionLiteral* result = NULL; |
| 659 { Scope* scope = NewScope(top_scope_, type, inside_with()); | 643 { Scope* scope = NewScope(top_scope_, type, inside_with()); |
| 660 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 644 LexicalScope lexical_scope(this, scope); |
| 661 scope); | |
| 662 TemporaryScope temp_scope(&this->temp_scope_); | |
| 663 if (strict_mode == kStrictMode) { | 645 if (strict_mode == kStrictMode) { |
| 664 top_scope_->EnableStrictMode(); | 646 top_scope_->EnableStrictMode(); |
| 665 } | 647 } |
| 666 ZoneList<Statement*>* body = new ZoneList<Statement*>(16); | 648 ZoneList<Statement*>* body = new ZoneList<Statement*>(16); |
| 667 bool ok = true; | 649 bool ok = true; |
| 668 int beg_loc = scanner().location().beg_pos; | 650 int beg_loc = scanner().location().beg_pos; |
| 669 ParseSourceElements(body, Token::EOS, &ok); | 651 ParseSourceElements(body, Token::EOS, &ok); |
| 670 if (ok && top_scope_->is_strict_mode()) { | 652 if (ok && top_scope_->is_strict_mode()) { |
| 671 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); | 653 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); |
| 672 } | 654 } |
| 673 if (ok) { | 655 if (ok) { |
| 674 result = new FunctionLiteral( | 656 result = new FunctionLiteral( |
| 675 no_name, | 657 no_name, |
| 676 top_scope_, | 658 top_scope_, |
| 677 body, | 659 body, |
| 678 temp_scope.materialized_literal_count(), | 660 lexical_scope.materialized_literal_count(), |
| 679 temp_scope.expected_property_count(), | 661 lexical_scope.expected_property_count(), |
| 680 temp_scope.only_simple_this_property_assignments(), | 662 lexical_scope.only_simple_this_property_assignments(), |
| 681 temp_scope.this_property_assignments(), | 663 lexical_scope.this_property_assignments(), |
| 682 0, | 664 0, |
| 683 0, | 665 0, |
| 684 source->length(), | 666 source->length(), |
| 685 false, | 667 false, |
| 686 temp_scope.ContainsLoops()); | 668 lexical_scope.ContainsLoops()); |
| 687 } else if (stack_overflow_) { | 669 } else if (stack_overflow_) { |
| 688 isolate()->StackOverflow(); | 670 isolate()->StackOverflow(); |
| 689 } | 671 } |
| 690 } | 672 } |
| 691 | 673 |
| 692 // Make sure the target stack is empty. | 674 // Make sure the target stack is empty. |
| 693 ASSERT(target_stack_ == NULL); | 675 ASSERT(target_stack_ == NULL); |
| 694 | 676 |
| 695 // If there was a syntax error we have to get rid of the AST | 677 // If there was a syntax error we have to get rid of the AST |
| 696 // and it is not safe to do so before the scope has been deleted. | 678 // and it is not safe to do so before the scope has been deleted. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 // Place holder for the result. | 722 // Place holder for the result. |
| 741 FunctionLiteral* result = NULL; | 723 FunctionLiteral* result = NULL; |
| 742 | 724 |
| 743 { | 725 { |
| 744 // Parse the function literal. | 726 // Parse the function literal. |
| 745 Handle<String> no_name = isolate()->factory()->empty_symbol(); | 727 Handle<String> no_name = isolate()->factory()->empty_symbol(); |
| 746 Scope* scope = NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); | 728 Scope* scope = NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); |
| 747 if (!info->closure().is_null()) { | 729 if (!info->closure().is_null()) { |
| 748 scope = Scope::DeserializeScopeChain(info, scope); | 730 scope = Scope::DeserializeScopeChain(info, scope); |
| 749 } | 731 } |
| 750 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 732 LexicalScope lexical_scope(this, scope); |
| 751 scope); | |
| 752 TemporaryScope temp_scope(&this->temp_scope_); | |
| 753 | 733 |
| 754 if (shared_info->strict_mode()) { | 734 if (shared_info->strict_mode()) { |
| 755 top_scope_->EnableStrictMode(); | 735 top_scope_->EnableStrictMode(); |
| 756 } | 736 } |
| 757 | 737 |
| 758 FunctionLiteralType type = | 738 FunctionLiteralType type = |
| 759 shared_info->is_expression() ? EXPRESSION : DECLARATION; | 739 shared_info->is_expression() ? EXPRESSION : DECLARATION; |
| 760 bool ok = true; | 740 bool ok = true; |
| 761 result = ParseFunctionLiteral(name, | 741 result = ParseFunctionLiteral(name, |
| 762 false, // Strict mode name already checked. | 742 false, // Strict mode name already checked. |
| (...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1167 } | 1147 } |
| 1168 processor->Add(stat); | 1148 processor->Add(stat); |
| 1169 } | 1149 } |
| 1170 | 1150 |
| 1171 // Propagate the collected information on this property assignments. | 1151 // Propagate the collected information on this property assignments. |
| 1172 if (top_scope_->is_function_scope()) { | 1152 if (top_scope_->is_function_scope()) { |
| 1173 bool only_simple_this_property_assignments = | 1153 bool only_simple_this_property_assignments = |
| 1174 this_property_assignment_finder.only_simple_this_property_assignments() | 1154 this_property_assignment_finder.only_simple_this_property_assignments() |
| 1175 && top_scope_->declarations()->length() == 0; | 1155 && top_scope_->declarations()->length() == 0; |
| 1176 if (only_simple_this_property_assignments) { | 1156 if (only_simple_this_property_assignments) { |
| 1177 temp_scope_->SetThisPropertyAssignmentInfo( | 1157 lexical_scope_->SetThisPropertyAssignmentInfo( |
| 1178 only_simple_this_property_assignments, | 1158 only_simple_this_property_assignments, |
| 1179 this_property_assignment_finder.GetThisPropertyAssignments()); | 1159 this_property_assignment_finder.GetThisPropertyAssignments()); |
| 1180 } | 1160 } |
| 1181 } | 1161 } |
| 1182 return 0; | 1162 return 0; |
| 1183 } | 1163 } |
| 1184 | 1164 |
| 1185 | 1165 |
| 1186 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { | 1166 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
| 1187 // Statement :: | 1167 // Statement :: |
| (...skipping 976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2164 | 2144 |
| 2165 return result; | 2145 return result; |
| 2166 } | 2146 } |
| 2167 | 2147 |
| 2168 | 2148 |
| 2169 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, | 2149 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, |
| 2170 bool* ok) { | 2150 bool* ok) { |
| 2171 // DoStatement :: | 2151 // DoStatement :: |
| 2172 // 'do' Statement 'while' '(' Expression ')' ';' | 2152 // 'do' Statement 'while' '(' Expression ')' ';' |
| 2173 | 2153 |
| 2174 temp_scope_->AddLoop(); | 2154 lexical_scope_->AddLoop(); |
| 2175 DoWhileStatement* loop = new DoWhileStatement(labels); | 2155 DoWhileStatement* loop = new DoWhileStatement(labels); |
| 2176 Target target(&this->target_stack_, loop); | 2156 Target target(&this->target_stack_, loop); |
| 2177 | 2157 |
| 2178 Expect(Token::DO, CHECK_OK); | 2158 Expect(Token::DO, CHECK_OK); |
| 2179 Statement* body = ParseStatement(NULL, CHECK_OK); | 2159 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2180 Expect(Token::WHILE, CHECK_OK); | 2160 Expect(Token::WHILE, CHECK_OK); |
| 2181 Expect(Token::LPAREN, CHECK_OK); | 2161 Expect(Token::LPAREN, CHECK_OK); |
| 2182 | 2162 |
| 2183 if (loop != NULL) { | 2163 if (loop != NULL) { |
| 2184 int position = scanner().location().beg_pos; | 2164 int position = scanner().location().beg_pos; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2197 | 2177 |
| 2198 if (loop != NULL) loop->Initialize(cond, body); | 2178 if (loop != NULL) loop->Initialize(cond, body); |
| 2199 return loop; | 2179 return loop; |
| 2200 } | 2180 } |
| 2201 | 2181 |
| 2202 | 2182 |
| 2203 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { | 2183 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { |
| 2204 // WhileStatement :: | 2184 // WhileStatement :: |
| 2205 // 'while' '(' Expression ')' Statement | 2185 // 'while' '(' Expression ')' Statement |
| 2206 | 2186 |
| 2207 temp_scope_->AddLoop(); | 2187 lexical_scope_->AddLoop(); |
| 2208 WhileStatement* loop = new WhileStatement(labels); | 2188 WhileStatement* loop = new WhileStatement(labels); |
| 2209 Target target(&this->target_stack_, loop); | 2189 Target target(&this->target_stack_, loop); |
| 2210 | 2190 |
| 2211 Expect(Token::WHILE, CHECK_OK); | 2191 Expect(Token::WHILE, CHECK_OK); |
| 2212 Expect(Token::LPAREN, CHECK_OK); | 2192 Expect(Token::LPAREN, CHECK_OK); |
| 2213 Expression* cond = ParseExpression(true, CHECK_OK); | 2193 Expression* cond = ParseExpression(true, CHECK_OK); |
| 2214 if (cond != NULL) cond->set_is_loop_condition(true); | 2194 if (cond != NULL) cond->set_is_loop_condition(true); |
| 2215 Expect(Token::RPAREN, CHECK_OK); | 2195 Expect(Token::RPAREN, CHECK_OK); |
| 2216 Statement* body = ParseStatement(NULL, CHECK_OK); | 2196 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2217 | 2197 |
| 2218 if (loop != NULL) loop->Initialize(cond, body); | 2198 if (loop != NULL) loop->Initialize(cond, body); |
| 2219 return loop; | 2199 return loop; |
| 2220 } | 2200 } |
| 2221 | 2201 |
| 2222 | 2202 |
| 2223 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 2203 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
| 2224 // ForStatement :: | 2204 // ForStatement :: |
| 2225 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 2205 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 2226 | 2206 |
| 2227 temp_scope_->AddLoop(); | 2207 lexical_scope_->AddLoop(); |
| 2228 Statement* init = NULL; | 2208 Statement* init = NULL; |
| 2229 | 2209 |
| 2230 Expect(Token::FOR, CHECK_OK); | 2210 Expect(Token::FOR, CHECK_OK); |
| 2231 Expect(Token::LPAREN, CHECK_OK); | 2211 Expect(Token::LPAREN, CHECK_OK); |
| 2232 if (peek() != Token::SEMICOLON) { | 2212 if (peek() != Token::SEMICOLON) { |
| 2233 if (peek() == Token::VAR || peek() == Token::CONST) { | 2213 if (peek() == Token::VAR || peek() == Token::CONST) { |
| 2234 Expression* each = NULL; | 2214 Expression* each = NULL; |
| 2235 Block* variable_statement = | 2215 Block* variable_statement = |
| 2236 ParseVariableDeclarations(false, &each, CHECK_OK); | 2216 ParseVariableDeclarations(false, &each, CHECK_OK); |
| 2237 if (peek() == Token::IN && each != NULL) { | 2217 if (peek() == Token::IN && each != NULL) { |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2364 // TODO(1231235): We try to estimate the set of properties set by | 2344 // TODO(1231235): We try to estimate the set of properties set by |
| 2365 // constructors. We define a new property whenever there is an | 2345 // constructors. We define a new property whenever there is an |
| 2366 // assignment to a property of 'this'. We should probably only add | 2346 // assignment to a property of 'this'. We should probably only add |
| 2367 // properties if we haven't seen them before. Otherwise we'll | 2347 // properties if we haven't seen them before. Otherwise we'll |
| 2368 // probably overestimate the number of properties. | 2348 // probably overestimate the number of properties. |
| 2369 Property* property = expression ? expression->AsProperty() : NULL; | 2349 Property* property = expression ? expression->AsProperty() : NULL; |
| 2370 if (op == Token::ASSIGN && | 2350 if (op == Token::ASSIGN && |
| 2371 property != NULL && | 2351 property != NULL && |
| 2372 property->obj()->AsVariableProxy() != NULL && | 2352 property->obj()->AsVariableProxy() != NULL && |
| 2373 property->obj()->AsVariableProxy()->is_this()) { | 2353 property->obj()->AsVariableProxy()->is_this()) { |
| 2374 temp_scope_->AddProperty(); | 2354 lexical_scope_->AddProperty(); |
| 2375 } | 2355 } |
| 2376 | 2356 |
| 2377 // If we assign a function literal to a property we pretenure the | 2357 // If we assign a function literal to a property we pretenure the |
| 2378 // literal so it can be added as a constant function property. | 2358 // literal so it can be added as a constant function property. |
| 2379 if (property != NULL && right->AsFunctionLiteral() != NULL) { | 2359 if (property != NULL && right->AsFunctionLiteral() != NULL) { |
| 2380 right->AsFunctionLiteral()->set_pretenure(true); | 2360 right->AsFunctionLiteral()->set_pretenure(true); |
| 2381 } | 2361 } |
| 2382 | 2362 |
| 2383 if (fni_ != NULL) { | 2363 if (fni_ != NULL) { |
| 2384 // Check if the right hand side is a call to avoid inferring a | 2364 // Check if the right hand side is a call to avoid inferring a |
| (...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3006 elem = ParseAssignmentExpression(true, CHECK_OK); | 2986 elem = ParseAssignmentExpression(true, CHECK_OK); |
| 3007 } | 2987 } |
| 3008 values->Add(elem); | 2988 values->Add(elem); |
| 3009 if (peek() != Token::RBRACK) { | 2989 if (peek() != Token::RBRACK) { |
| 3010 Expect(Token::COMMA, CHECK_OK); | 2990 Expect(Token::COMMA, CHECK_OK); |
| 3011 } | 2991 } |
| 3012 } | 2992 } |
| 3013 Expect(Token::RBRACK, CHECK_OK); | 2993 Expect(Token::RBRACK, CHECK_OK); |
| 3014 | 2994 |
| 3015 // Update the scope information before the pre-parsing bailout. | 2995 // Update the scope information before the pre-parsing bailout. |
| 3016 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); | 2996 int literal_index = lexical_scope_->NextMaterializedLiteralIndex(); |
| 3017 | 2997 |
| 3018 // Allocate a fixed array with all the literals. | 2998 // Allocate a fixed array with all the literals. |
| 3019 Handle<FixedArray> literals = | 2999 Handle<FixedArray> literals = |
| 3020 isolate()->factory()->NewFixedArray(values->length(), TENURED); | 3000 isolate()->factory()->NewFixedArray(values->length(), TENURED); |
| 3021 | 3001 |
| 3022 // Fill in the literals. | 3002 // Fill in the literals. |
| 3023 bool is_simple = true; | 3003 bool is_simple = true; |
| 3024 int depth = 1; | 3004 int depth = 1; |
| 3025 for (int i = 0, n = values->length(); i < n; i++) { | 3005 for (int i = 0, n = values->length(); i < n; i++) { |
| 3026 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral(); | 3006 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral(); |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3438 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | 3418 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
| 3439 | 3419 |
| 3440 if (fni_ != NULL) { | 3420 if (fni_ != NULL) { |
| 3441 fni_->Infer(); | 3421 fni_->Infer(); |
| 3442 fni_->Leave(); | 3422 fni_->Leave(); |
| 3443 } | 3423 } |
| 3444 } | 3424 } |
| 3445 Expect(Token::RBRACE, CHECK_OK); | 3425 Expect(Token::RBRACE, CHECK_OK); |
| 3446 | 3426 |
| 3447 // Computation of literal_index must happen before pre parse bailout. | 3427 // Computation of literal_index must happen before pre parse bailout. |
| 3448 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); | 3428 int literal_index = lexical_scope_->NextMaterializedLiteralIndex(); |
| 3449 | 3429 |
| 3450 Handle<FixedArray> constant_properties = isolate()->factory()->NewFixedArray( | 3430 Handle<FixedArray> constant_properties = isolate()->factory()->NewFixedArray( |
| 3451 number_of_boilerplate_properties * 2, TENURED); | 3431 number_of_boilerplate_properties * 2, TENURED); |
| 3452 | 3432 |
| 3453 bool is_simple = true; | 3433 bool is_simple = true; |
| 3454 bool fast_elements = true; | 3434 bool fast_elements = true; |
| 3455 int depth = 1; | 3435 int depth = 1; |
| 3456 BuildObjectLiteralConstantProperties(properties, | 3436 BuildObjectLiteralConstantProperties(properties, |
| 3457 constant_properties, | 3437 constant_properties, |
| 3458 &is_simple, | 3438 &is_simple, |
| 3459 &fast_elements, | 3439 &fast_elements, |
| 3460 &depth); | 3440 &depth); |
| 3461 return new ObjectLiteral(constant_properties, | 3441 return new ObjectLiteral(constant_properties, |
| 3462 properties, | 3442 properties, |
| 3463 literal_index, | 3443 literal_index, |
| 3464 is_simple, | 3444 is_simple, |
| 3465 fast_elements, | 3445 fast_elements, |
| 3466 depth); | 3446 depth); |
| 3467 } | 3447 } |
| 3468 | 3448 |
| 3469 | 3449 |
| 3470 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { | 3450 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { |
| 3471 if (!scanner().ScanRegExpPattern(seen_equal)) { | 3451 if (!scanner().ScanRegExpPattern(seen_equal)) { |
| 3472 Next(); | 3452 Next(); |
| 3473 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); | 3453 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); |
| 3474 *ok = false; | 3454 *ok = false; |
| 3475 return NULL; | 3455 return NULL; |
| 3476 } | 3456 } |
| 3477 | 3457 |
| 3478 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); | 3458 int literal_index = lexical_scope_->NextMaterializedLiteralIndex(); |
| 3479 | 3459 |
| 3480 Handle<String> js_pattern = NextLiteralString(TENURED); | 3460 Handle<String> js_pattern = NextLiteralString(TENURED); |
| 3481 scanner().ScanRegExpFlags(); | 3461 scanner().ScanRegExpFlags(); |
| 3482 Handle<String> js_flags = NextLiteralString(TENURED); | 3462 Handle<String> js_flags = NextLiteralString(TENURED); |
| 3483 Next(); | 3463 Next(); |
| 3484 | 3464 |
| 3485 return new RegExpLiteral(js_pattern, js_flags, literal_index); | 3465 return new RegExpLiteral(js_pattern, js_flags, literal_index); |
| 3486 } | 3466 } |
| 3487 | 3467 |
| 3488 | 3468 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3522 // The function name, if any. | 3502 // The function name, if any. |
| 3523 Handle<String> function_name = isolate()->factory()->empty_symbol(); | 3503 Handle<String> function_name = isolate()->factory()->empty_symbol(); |
| 3524 if (is_named && (type == EXPRESSION || type == NESTED)) { | 3504 if (is_named && (type == EXPRESSION || type == NESTED)) { |
| 3525 function_name = name; | 3505 function_name = name; |
| 3526 } | 3506 } |
| 3527 | 3507 |
| 3528 int num_parameters = 0; | 3508 int num_parameters = 0; |
| 3529 // Parse function body. | 3509 // Parse function body. |
| 3530 { Scope* scope = | 3510 { Scope* scope = |
| 3531 NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); | 3511 NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); |
| 3532 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 3512 LexicalScope lexical_scope(this, scope); |
| 3533 scope); | |
| 3534 TemporaryScope temp_scope(&this->temp_scope_); | |
| 3535 top_scope_->SetScopeName(name); | 3513 top_scope_->SetScopeName(name); |
| 3536 | 3514 |
| 3537 // FormalParameterList :: | 3515 // FormalParameterList :: |
| 3538 // '(' (Identifier)*[','] ')' | 3516 // '(' (Identifier)*[','] ')' |
| 3539 Expect(Token::LPAREN, CHECK_OK); | 3517 Expect(Token::LPAREN, CHECK_OK); |
| 3540 int start_pos = scanner().location().beg_pos; | 3518 int start_pos = scanner().location().beg_pos; |
| 3541 Scanner::Location name_loc = Scanner::NoLocation(); | 3519 Scanner::Location name_loc = Scanner::NoLocation(); |
| 3542 Scanner::Location dupe_loc = Scanner::NoLocation(); | 3520 Scanner::Location dupe_loc = Scanner::NoLocation(); |
| 3543 Scanner::Location reserved_loc = Scanner::NoLocation(); | 3521 Scanner::Location reserved_loc = Scanner::NoLocation(); |
| 3544 | 3522 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3622 // Seek to position just before terminal '}'. | 3600 // Seek to position just before terminal '}'. |
| 3623 scanner().SeekForward(end_pos - 1); | 3601 scanner().SeekForward(end_pos - 1); |
| 3624 materialized_literal_count = entry.literal_count(); | 3602 materialized_literal_count = entry.literal_count(); |
| 3625 expected_property_count = entry.property_count(); | 3603 expected_property_count = entry.property_count(); |
| 3626 only_simple_this_property_assignments = false; | 3604 only_simple_this_property_assignments = false; |
| 3627 this_property_assignments = isolate()->factory()->empty_fixed_array(); | 3605 this_property_assignments = isolate()->factory()->empty_fixed_array(); |
| 3628 Expect(Token::RBRACE, CHECK_OK); | 3606 Expect(Token::RBRACE, CHECK_OK); |
| 3629 } else { | 3607 } else { |
| 3630 ParseSourceElements(body, Token::RBRACE, CHECK_OK); | 3608 ParseSourceElements(body, Token::RBRACE, CHECK_OK); |
| 3631 | 3609 |
| 3632 materialized_literal_count = temp_scope.materialized_literal_count(); | 3610 materialized_literal_count = lexical_scope.materialized_literal_count(); |
| 3633 expected_property_count = temp_scope.expected_property_count(); | 3611 expected_property_count = lexical_scope.expected_property_count(); |
| 3634 only_simple_this_property_assignments = | 3612 only_simple_this_property_assignments = |
| 3635 temp_scope.only_simple_this_property_assignments(); | 3613 lexical_scope.only_simple_this_property_assignments(); |
| 3636 this_property_assignments = temp_scope.this_property_assignments(); | 3614 this_property_assignments = lexical_scope.this_property_assignments(); |
| 3637 | 3615 |
| 3638 Expect(Token::RBRACE, CHECK_OK); | 3616 Expect(Token::RBRACE, CHECK_OK); |
| 3639 end_pos = scanner().location().end_pos; | 3617 end_pos = scanner().location().end_pos; |
| 3640 } | 3618 } |
| 3641 | 3619 |
| 3642 // Validate strict mode. | 3620 // Validate strict mode. |
| 3643 if (top_scope_->is_strict_mode()) { | 3621 if (top_scope_->is_strict_mode()) { |
| 3644 if (IsEvalOrArguments(name)) { | 3622 if (IsEvalOrArguments(name)) { |
| 3645 int position = function_token_position != RelocInfo::kNoPosition | 3623 int position = function_token_position != RelocInfo::kNoPosition |
| 3646 ? function_token_position | 3624 ? function_token_position |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3687 top_scope_, | 3665 top_scope_, |
| 3688 body, | 3666 body, |
| 3689 materialized_literal_count, | 3667 materialized_literal_count, |
| 3690 expected_property_count, | 3668 expected_property_count, |
| 3691 only_simple_this_property_assignments, | 3669 only_simple_this_property_assignments, |
| 3692 this_property_assignments, | 3670 this_property_assignments, |
| 3693 num_parameters, | 3671 num_parameters, |
| 3694 start_pos, | 3672 start_pos, |
| 3695 end_pos, | 3673 end_pos, |
| 3696 function_name->length() > 0, | 3674 function_name->length() > 0, |
| 3697 temp_scope.ContainsLoops()); | 3675 lexical_scope.ContainsLoops()); |
| 3698 function_literal->set_function_token_position(function_token_position); | 3676 function_literal->set_function_token_position(function_token_position); |
| 3699 | 3677 |
| 3700 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); | 3678 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); |
| 3701 return function_literal; | 3679 return function_literal; |
| 3702 } | 3680 } |
| 3703 } | 3681 } |
| 3704 | 3682 |
| 3705 | 3683 |
| 3706 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3684 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 3707 // CallRuntime :: | 3685 // CallRuntime :: |
| (...skipping 1447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5155 info->is_global(), | 5133 info->is_global(), |
| 5156 info->StrictMode()); | 5134 info->StrictMode()); |
| 5157 } | 5135 } |
| 5158 } | 5136 } |
| 5159 | 5137 |
| 5160 info->SetFunction(result); | 5138 info->SetFunction(result); |
| 5161 return (result != NULL); | 5139 return (result != NULL); |
| 5162 } | 5140 } |
| 5163 | 5141 |
| 5164 } } // namespace v8::internal | 5142 } } // namespace v8::internal |
| OLD | NEW |