| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 *variable_ = previous_; | 452 *variable_ = previous_; |
| 453 } | 453 } |
| 454 | 454 |
| 455 private: | 455 private: |
| 456 Target** variable_; | 456 Target** variable_; |
| 457 Target* previous_; | 457 Target* previous_; |
| 458 }; | 458 }; |
| 459 | 459 |
| 460 | 460 |
| 461 // ---------------------------------------------------------------------------- | 461 // ---------------------------------------------------------------------------- |
| 462 // LexicalScope and SaveScope are stack allocated support classes to facilitate | 462 // FunctionState and BlockState together implement the parser's scope stack. |
| 463 // anipulation of the Parser's scope stack. The constructor sets the parser's | 463 // The parser's current scope is in top_scope_. The BlockState and |
| 464 // top scope to the incoming scope, and the destructor resets it. Additionally, | 464 // FunctionState constructors push on the scope stack and the destructors |
| 465 // LexicalScope stores transient information used during parsing. | 465 // pop. They are also used to hold the parser's per-function and per-block |
| 466 // state. |
| 466 | 467 |
| 467 | 468 class Parser::BlockState BASE_EMBEDDED { |
| 468 class SaveScope BASE_EMBEDDED { | |
| 469 public: | 469 public: |
| 470 SaveScope(Parser* parser, Scope* scope) | 470 BlockState(Parser* parser, Scope* scope) |
| 471 : parser_(parser), | 471 : parser_(parser), |
| 472 previous_top_scope_(parser->top_scope_) { | 472 outer_scope_(parser->top_scope_) { |
| 473 parser->top_scope_ = scope; | 473 parser->top_scope_ = scope; |
| 474 } | 474 } |
| 475 | 475 |
| 476 ~SaveScope() { | 476 ~BlockState() { parser_->top_scope_ = outer_scope_; } |
| 477 parser_->top_scope_ = previous_top_scope_; | |
| 478 } | |
| 479 | 477 |
| 480 private: | 478 private: |
| 481 // Bookkeeping | |
| 482 Parser* parser_; | 479 Parser* parser_; |
| 483 // Previous values | 480 Scope* outer_scope_; |
| 484 Scope* previous_top_scope_; | |
| 485 }; | 481 }; |
| 486 | 482 |
| 487 | 483 |
| 488 class LexicalScope BASE_EMBEDDED { | 484 class Parser::FunctionState BASE_EMBEDDED { |
| 489 public: | 485 public: |
| 490 LexicalScope(Parser* parser, Scope* scope, Isolate* isolate); | 486 FunctionState(Parser* parser, Scope* scope, Isolate* isolate); |
| 491 ~LexicalScope(); | 487 ~FunctionState(); |
| 492 | 488 |
| 493 int NextMaterializedLiteralIndex() { | 489 int NextMaterializedLiteralIndex() { |
| 494 int next_index = | 490 return next_materialized_literal_index_++; |
| 495 materialized_literal_count_ + JSFunction::kLiteralsPrefixSize; | |
| 496 materialized_literal_count_++; | |
| 497 return next_index; | |
| 498 } | 491 } |
| 499 int materialized_literal_count() { return materialized_literal_count_; } | 492 int materialized_literal_count() { |
| 493 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; |
| 494 } |
| 500 | 495 |
| 501 void SetThisPropertyAssignmentInfo( | 496 void SetThisPropertyAssignmentInfo( |
| 502 bool only_simple_this_property_assignments, | 497 bool only_simple_this_property_assignments, |
| 503 Handle<FixedArray> this_property_assignments) { | 498 Handle<FixedArray> this_property_assignments) { |
| 504 only_simple_this_property_assignments_ = | 499 only_simple_this_property_assignments_ = |
| 505 only_simple_this_property_assignments; | 500 only_simple_this_property_assignments; |
| 506 this_property_assignments_ = this_property_assignments; | 501 this_property_assignments_ = this_property_assignments; |
| 507 } | 502 } |
| 508 bool only_simple_this_property_assignments() { | 503 bool only_simple_this_property_assignments() { |
| 509 return only_simple_this_property_assignments_; | 504 return only_simple_this_property_assignments_; |
| 510 } | 505 } |
| 511 Handle<FixedArray> this_property_assignments() { | 506 Handle<FixedArray> this_property_assignments() { |
| 512 return this_property_assignments_; | 507 return this_property_assignments_; |
| 513 } | 508 } |
| 514 | 509 |
| 515 void AddProperty() { expected_property_count_++; } | 510 void AddProperty() { expected_property_count_++; } |
| 516 int expected_property_count() { return expected_property_count_; } | 511 int expected_property_count() { return expected_property_count_; } |
| 517 | 512 |
| 518 private: | 513 private: |
| 519 // Captures the number of literals that need materialization in the | 514 // Used to assign an index to each literal that needs materialization in |
| 520 // function. Includes regexp literals, and boilerplate for object | 515 // the function. Includes regexp literals, and boilerplate for object and |
| 521 // and array literals. | 516 // array literals. |
| 522 int materialized_literal_count_; | 517 int next_materialized_literal_index_; |
| 523 | 518 |
| 524 // Properties count estimation. | 519 // Properties count estimation. |
| 525 int expected_property_count_; | 520 int expected_property_count_; |
| 526 | 521 |
| 527 // Keeps track of assignments to properties of this. Used for | 522 // Keeps track of assignments to properties of this. Used for |
| 528 // optimizing constructors. | 523 // optimizing constructors. |
| 529 bool only_simple_this_property_assignments_; | 524 bool only_simple_this_property_assignments_; |
| 530 Handle<FixedArray> this_property_assignments_; | 525 Handle<FixedArray> this_property_assignments_; |
| 531 | 526 |
| 532 // Bookkeeping | |
| 533 Parser* parser_; | 527 Parser* parser_; |
| 534 // Previous values | 528 FunctionState* outer_function_state_; |
| 535 LexicalScope* lexical_scope_parent_; | 529 Scope* outer_scope_; |
| 536 Scope* previous_scope_; | 530 unsigned saved_ast_node_id_; |
| 537 unsigned previous_ast_node_id_; | |
| 538 }; | 531 }; |
| 539 | 532 |
| 540 | 533 |
| 541 LexicalScope::LexicalScope(Parser* parser, Scope* scope, Isolate* isolate) | 534 Parser::FunctionState::FunctionState(Parser* parser, |
| 542 : materialized_literal_count_(0), | 535 Scope* scope, |
| 543 expected_property_count_(0), | 536 Isolate* isolate) |
| 544 only_simple_this_property_assignments_(false), | 537 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), |
| 545 this_property_assignments_(isolate->factory()->empty_fixed_array()), | 538 expected_property_count_(0), |
| 546 parser_(parser), | 539 only_simple_this_property_assignments_(false), |
| 547 lexical_scope_parent_(parser->lexical_scope_), | 540 this_property_assignments_(isolate->factory()->empty_fixed_array()), |
| 548 previous_scope_(parser->top_scope_), | 541 parser_(parser), |
| 549 previous_ast_node_id_(isolate->ast_node_id()) { | 542 outer_function_state_(parser->current_function_state_), |
| 543 outer_scope_(parser->top_scope_), |
| 544 saved_ast_node_id_(isolate->ast_node_id()) { |
| 550 parser->top_scope_ = scope; | 545 parser->top_scope_ = scope; |
| 551 parser->lexical_scope_ = this; | 546 parser->current_function_state_ = this; |
| 552 isolate->set_ast_node_id(AstNode::kDeclarationsId + 1); | 547 isolate->set_ast_node_id(AstNode::kDeclarationsId + 1); |
| 553 } | 548 } |
| 554 | 549 |
| 555 | 550 |
| 556 LexicalScope::~LexicalScope() { | 551 Parser::FunctionState::~FunctionState() { |
| 557 parser_->top_scope_ = previous_scope_; | 552 parser_->top_scope_ = outer_scope_; |
| 558 parser_->lexical_scope_ = lexical_scope_parent_; | 553 parser_->current_function_state_ = outer_function_state_; |
| 559 parser_->isolate()->set_ast_node_id(previous_ast_node_id_); | 554 parser_->isolate()->set_ast_node_id(saved_ast_node_id_); |
| 560 } | 555 } |
| 561 | 556 |
| 562 | 557 |
| 563 // ---------------------------------------------------------------------------- | 558 // ---------------------------------------------------------------------------- |
| 564 // The CHECK_OK macro is a convenient macro to enforce error | 559 // The CHECK_OK macro is a convenient macro to enforce error |
| 565 // handling for functions that may fail (by returning !*ok). | 560 // handling for functions that may fail (by returning !*ok). |
| 566 // | 561 // |
| 567 // CAUTION: This macro appends extra statements after a call, | 562 // CAUTION: This macro appends extra statements after a call, |
| 568 // thus it must never be used where only a single statement | 563 // thus it must never be used where only a single statement |
| 569 // is correct (e.g. an if statement branch w/o braces)! | 564 // is correct (e.g. an if statement branch w/o braces)! |
| (...skipping 15 matching lines...) Expand all Loading... |
| 585 | 580 |
| 586 Parser::Parser(Handle<Script> script, | 581 Parser::Parser(Handle<Script> script, |
| 587 bool allow_natives_syntax, | 582 bool allow_natives_syntax, |
| 588 v8::Extension* extension, | 583 v8::Extension* extension, |
| 589 ScriptDataImpl* pre_data) | 584 ScriptDataImpl* pre_data) |
| 590 : isolate_(script->GetIsolate()), | 585 : isolate_(script->GetIsolate()), |
| 591 symbol_cache_(pre_data ? pre_data->symbol_count() : 0), | 586 symbol_cache_(pre_data ? pre_data->symbol_count() : 0), |
| 592 script_(script), | 587 script_(script), |
| 593 scanner_(isolate_->unicode_cache()), | 588 scanner_(isolate_->unicode_cache()), |
| 594 top_scope_(NULL), | 589 top_scope_(NULL), |
| 595 lexical_scope_(NULL), | 590 current_function_state_(NULL), |
| 596 target_stack_(NULL), | 591 target_stack_(NULL), |
| 597 allow_natives_syntax_(allow_natives_syntax), | 592 allow_natives_syntax_(allow_natives_syntax), |
| 598 extension_(extension), | 593 extension_(extension), |
| 599 pre_data_(pre_data), | 594 pre_data_(pre_data), |
| 600 fni_(NULL), | 595 fni_(NULL), |
| 601 stack_overflow_(false), | 596 stack_overflow_(false), |
| 602 parenthesized_function_(false), | 597 parenthesized_function_(false), |
| 603 harmony_scoping_(false) { | 598 harmony_scoping_(false) { |
| 604 AstNode::ResetIds(); | 599 AstNode::ResetIds(); |
| 605 } | 600 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; | 639 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; |
| 645 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; | 640 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; |
| 646 | 641 |
| 647 ScopeType type = in_global_context ? GLOBAL_SCOPE : EVAL_SCOPE; | 642 ScopeType type = in_global_context ? GLOBAL_SCOPE : EVAL_SCOPE; |
| 648 Handle<String> no_name = isolate()->factory()->empty_symbol(); | 643 Handle<String> no_name = isolate()->factory()->empty_symbol(); |
| 649 | 644 |
| 650 FunctionLiteral* result = NULL; | 645 FunctionLiteral* result = NULL; |
| 651 { Scope* scope = NewScope(top_scope_, type); | 646 { Scope* scope = NewScope(top_scope_, type); |
| 652 scope->set_start_position(0); | 647 scope->set_start_position(0); |
| 653 scope->set_end_position(source->length()); | 648 scope->set_end_position(source->length()); |
| 654 LexicalScope lexical_scope(this, scope, isolate()); | 649 FunctionState function_state(this, scope, isolate()); |
| 655 ASSERT(top_scope_->strict_mode_flag() == kNonStrictMode); | 650 ASSERT(top_scope_->strict_mode_flag() == kNonStrictMode); |
| 656 top_scope_->SetStrictModeFlag(strict_mode); | 651 top_scope_->SetStrictModeFlag(strict_mode); |
| 657 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16); | 652 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16); |
| 658 bool ok = true; | 653 bool ok = true; |
| 659 int beg_loc = scanner().location().beg_pos; | 654 int beg_loc = scanner().location().beg_pos; |
| 660 ParseSourceElements(body, Token::EOS, &ok); | 655 ParseSourceElements(body, Token::EOS, &ok); |
| 661 if (ok && top_scope_->is_strict_mode()) { | 656 if (ok && top_scope_->is_strict_mode()) { |
| 662 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); | 657 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); |
| 663 } | 658 } |
| 664 | 659 |
| 665 if (ok && harmony_scoping_) { | 660 if (ok && harmony_scoping_) { |
| 666 CheckConflictingVarDeclarations(scope, &ok); | 661 CheckConflictingVarDeclarations(scope, &ok); |
| 667 } | 662 } |
| 668 | 663 |
| 669 if (ok) { | 664 if (ok) { |
| 670 result = new(zone()) FunctionLiteral( | 665 result = new(zone()) FunctionLiteral( |
| 671 isolate(), | 666 isolate(), |
| 672 no_name, | 667 no_name, |
| 673 top_scope_, | 668 top_scope_, |
| 674 body, | 669 body, |
| 675 lexical_scope.materialized_literal_count(), | 670 function_state.materialized_literal_count(), |
| 676 lexical_scope.expected_property_count(), | 671 function_state.expected_property_count(), |
| 677 lexical_scope.only_simple_this_property_assignments(), | 672 function_state.only_simple_this_property_assignments(), |
| 678 lexical_scope.this_property_assignments(), | 673 function_state.this_property_assignments(), |
| 679 0, | 674 0, |
| 680 FunctionLiteral::ANONYMOUS_EXPRESSION, | 675 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 681 false); // Does not have duplicate parameters. | 676 false); // Does not have duplicate parameters. |
| 682 } else if (stack_overflow_) { | 677 } else if (stack_overflow_) { |
| 683 isolate()->StackOverflow(); | 678 isolate()->StackOverflow(); |
| 684 } | 679 } |
| 685 } | 680 } |
| 686 | 681 |
| 687 // Make sure the target stack is empty. | 682 // Make sure the target stack is empty. |
| 688 ASSERT(target_stack_ == NULL); | 683 ASSERT(target_stack_ == NULL); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 | 730 |
| 736 // Place holder for the result. | 731 // Place holder for the result. |
| 737 FunctionLiteral* result = NULL; | 732 FunctionLiteral* result = NULL; |
| 738 | 733 |
| 739 { | 734 { |
| 740 // Parse the function literal. | 735 // Parse the function literal. |
| 741 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); | 736 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); |
| 742 if (!info->closure().is_null()) { | 737 if (!info->closure().is_null()) { |
| 743 scope = Scope::DeserializeScopeChain(info, scope); | 738 scope = Scope::DeserializeScopeChain(info, scope); |
| 744 } | 739 } |
| 745 LexicalScope lexical_scope(this, scope, isolate()); | 740 FunctionState function_state(this, scope, isolate()); |
| 746 ASSERT(scope->strict_mode_flag() == kNonStrictMode || | 741 ASSERT(scope->strict_mode_flag() == kNonStrictMode || |
| 747 scope->strict_mode_flag() == info->strict_mode_flag()); | 742 scope->strict_mode_flag() == info->strict_mode_flag()); |
| 748 ASSERT(info->strict_mode_flag() == shared_info->strict_mode_flag()); | 743 ASSERT(info->strict_mode_flag() == shared_info->strict_mode_flag()); |
| 749 scope->SetStrictModeFlag(shared_info->strict_mode_flag()); | 744 scope->SetStrictModeFlag(shared_info->strict_mode_flag()); |
| 750 FunctionLiteral::Type type = shared_info->is_expression() | 745 FunctionLiteral::Type type = shared_info->is_expression() |
| 751 ? (shared_info->is_anonymous() | 746 ? (shared_info->is_anonymous() |
| 752 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 747 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 753 : FunctionLiteral::NAMED_EXPRESSION) | 748 : FunctionLiteral::NAMED_EXPRESSION) |
| 754 : FunctionLiteral::DECLARATION; | 749 : FunctionLiteral::DECLARATION; |
| 755 bool ok = true; | 750 bool ok = true; |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1210 } | 1205 } |
| 1211 processor->Add(stat); | 1206 processor->Add(stat); |
| 1212 } | 1207 } |
| 1213 | 1208 |
| 1214 // Propagate the collected information on this property assignments. | 1209 // Propagate the collected information on this property assignments. |
| 1215 if (top_scope_->is_function_scope()) { | 1210 if (top_scope_->is_function_scope()) { |
| 1216 bool only_simple_this_property_assignments = | 1211 bool only_simple_this_property_assignments = |
| 1217 this_property_assignment_finder.only_simple_this_property_assignments() | 1212 this_property_assignment_finder.only_simple_this_property_assignments() |
| 1218 && top_scope_->declarations()->length() == 0; | 1213 && top_scope_->declarations()->length() == 0; |
| 1219 if (only_simple_this_property_assignments) { | 1214 if (only_simple_this_property_assignments) { |
| 1220 lexical_scope_->SetThisPropertyAssignmentInfo( | 1215 current_function_state_->SetThisPropertyAssignmentInfo( |
| 1221 only_simple_this_property_assignments, | 1216 only_simple_this_property_assignments, |
| 1222 this_property_assignment_finder.GetThisPropertyAssignments()); | 1217 this_property_assignment_finder.GetThisPropertyAssignments()); |
| 1223 } | 1218 } |
| 1224 } | 1219 } |
| 1225 return 0; | 1220 return 0; |
| 1226 } | 1221 } |
| 1227 | 1222 |
| 1228 | 1223 |
| 1229 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { | 1224 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
| 1230 // Statement :: | 1225 // Statement :: |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1602 // Block :: | 1597 // Block :: |
| 1603 // '{' SourceElement* '}' | 1598 // '{' SourceElement* '}' |
| 1604 | 1599 |
| 1605 // Construct block expecting 16 statements. | 1600 // Construct block expecting 16 statements. |
| 1606 Block* body = new(zone()) Block(isolate(), labels, 16, false); | 1601 Block* body = new(zone()) Block(isolate(), labels, 16, false); |
| 1607 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); | 1602 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); |
| 1608 | 1603 |
| 1609 // Parse the statements and collect escaping labels. | 1604 // Parse the statements and collect escaping labels. |
| 1610 Expect(Token::LBRACE, CHECK_OK); | 1605 Expect(Token::LBRACE, CHECK_OK); |
| 1611 block_scope->set_start_position(scanner().location().beg_pos); | 1606 block_scope->set_start_position(scanner().location().beg_pos); |
| 1612 { SaveScope save_scope(this, block_scope); | 1607 { BlockState block_state(this, block_scope); |
| 1613 TargetCollector collector; | 1608 TargetCollector collector; |
| 1614 Target target(&this->target_stack_, &collector); | 1609 Target target(&this->target_stack_, &collector); |
| 1615 Target target_body(&this->target_stack_, body); | 1610 Target target_body(&this->target_stack_, body); |
| 1616 InitializationBlockFinder block_finder(top_scope_, target_stack_); | 1611 InitializationBlockFinder block_finder(top_scope_, target_stack_); |
| 1617 | 1612 |
| 1618 while (peek() != Token::RBRACE) { | 1613 while (peek() != Token::RBRACE) { |
| 1619 Statement* stat = ParseSourceElement(NULL, CHECK_OK); | 1614 Statement* stat = ParseSourceElement(NULL, CHECK_OK); |
| 1620 if (stat && !stat->IsEmpty()) { | 1615 if (stat && !stat->IsEmpty()) { |
| 1621 body->AddStatement(stat); | 1616 body->AddStatement(stat); |
| 1622 block_finder.Update(stat); | 1617 block_finder.Update(stat); |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2144 return NULL; | 2139 return NULL; |
| 2145 } | 2140 } |
| 2146 | 2141 |
| 2147 Expect(Token::LPAREN, CHECK_OK); | 2142 Expect(Token::LPAREN, CHECK_OK); |
| 2148 Expression* expr = ParseExpression(true, CHECK_OK); | 2143 Expression* expr = ParseExpression(true, CHECK_OK); |
| 2149 Expect(Token::RPAREN, CHECK_OK); | 2144 Expect(Token::RPAREN, CHECK_OK); |
| 2150 | 2145 |
| 2151 top_scope_->DeclarationScope()->RecordWithStatement(); | 2146 top_scope_->DeclarationScope()->RecordWithStatement(); |
| 2152 Scope* with_scope = NewScope(top_scope_, WITH_SCOPE); | 2147 Scope* with_scope = NewScope(top_scope_, WITH_SCOPE); |
| 2153 Statement* stmt; | 2148 Statement* stmt; |
| 2154 { SaveScope save_scope(this, with_scope); | 2149 { BlockState block_state(this, with_scope); |
| 2155 with_scope->set_start_position(scanner().peek_location().beg_pos); | 2150 with_scope->set_start_position(scanner().peek_location().beg_pos); |
| 2156 stmt = ParseStatement(labels, CHECK_OK); | 2151 stmt = ParseStatement(labels, CHECK_OK); |
| 2157 with_scope->set_end_position(scanner().location().end_pos); | 2152 with_scope->set_end_position(scanner().location().end_pos); |
| 2158 } | 2153 } |
| 2159 return new(zone()) WithStatement(expr, stmt); | 2154 return new(zone()) WithStatement(expr, stmt); |
| 2160 } | 2155 } |
| 2161 | 2156 |
| 2162 | 2157 |
| 2163 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { | 2158 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { |
| 2164 // CaseClause :: | 2159 // CaseClause :: |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2291 } | 2286 } |
| 2292 | 2287 |
| 2293 Expect(Token::RPAREN, CHECK_OK); | 2288 Expect(Token::RPAREN, CHECK_OK); |
| 2294 | 2289 |
| 2295 if (peek() == Token::LBRACE) { | 2290 if (peek() == Token::LBRACE) { |
| 2296 Target target(&this->target_stack_, &catch_collector); | 2291 Target target(&this->target_stack_, &catch_collector); |
| 2297 VariableMode mode = harmony_scoping_ ? LET : VAR; | 2292 VariableMode mode = harmony_scoping_ ? LET : VAR; |
| 2298 catch_variable = | 2293 catch_variable = |
| 2299 catch_scope->DeclareLocal(name, mode, kCreatedInitialized); | 2294 catch_scope->DeclareLocal(name, mode, kCreatedInitialized); |
| 2300 | 2295 |
| 2301 SaveScope save_scope(this, catch_scope); | 2296 BlockState block_state(this, catch_scope); |
| 2302 catch_block = ParseBlock(NULL, CHECK_OK); | 2297 catch_block = ParseBlock(NULL, CHECK_OK); |
| 2303 } else { | 2298 } else { |
| 2304 Expect(Token::LBRACE, CHECK_OK); | 2299 Expect(Token::LBRACE, CHECK_OK); |
| 2305 } | 2300 } |
| 2306 catch_scope->set_end_position(scanner().location().end_pos); | 2301 catch_scope->set_end_position(scanner().location().end_pos); |
| 2307 tok = peek(); | 2302 tok = peek(); |
| 2308 } | 2303 } |
| 2309 | 2304 |
| 2310 Block* finally_block = NULL; | 2305 Block* finally_block = NULL; |
| 2311 if (tok == Token::FINALLY || catch_block == NULL) { | 2306 if (tok == Token::FINALLY || catch_block == NULL) { |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2642 // TODO(1231235): We try to estimate the set of properties set by | 2637 // TODO(1231235): We try to estimate the set of properties set by |
| 2643 // constructors. We define a new property whenever there is an | 2638 // constructors. We define a new property whenever there is an |
| 2644 // assignment to a property of 'this'. We should probably only add | 2639 // assignment to a property of 'this'. We should probably only add |
| 2645 // properties if we haven't seen them before. Otherwise we'll | 2640 // properties if we haven't seen them before. Otherwise we'll |
| 2646 // probably overestimate the number of properties. | 2641 // probably overestimate the number of properties. |
| 2647 Property* property = expression ? expression->AsProperty() : NULL; | 2642 Property* property = expression ? expression->AsProperty() : NULL; |
| 2648 if (op == Token::ASSIGN && | 2643 if (op == Token::ASSIGN && |
| 2649 property != NULL && | 2644 property != NULL && |
| 2650 property->obj()->AsVariableProxy() != NULL && | 2645 property->obj()->AsVariableProxy() != NULL && |
| 2651 property->obj()->AsVariableProxy()->is_this()) { | 2646 property->obj()->AsVariableProxy()->is_this()) { |
| 2652 lexical_scope_->AddProperty(); | 2647 current_function_state_->AddProperty(); |
| 2653 } | 2648 } |
| 2654 | 2649 |
| 2655 // If we assign a function literal to a property we pretenure the | 2650 // If we assign a function literal to a property we pretenure the |
| 2656 // literal so it can be added as a constant function property. | 2651 // literal so it can be added as a constant function property. |
| 2657 if (property != NULL && right->AsFunctionLiteral() != NULL) { | 2652 if (property != NULL && right->AsFunctionLiteral() != NULL) { |
| 2658 right->AsFunctionLiteral()->set_pretenure(true); | 2653 right->AsFunctionLiteral()->set_pretenure(); |
| 2659 } | 2654 } |
| 2660 | 2655 |
| 2661 if (fni_ != NULL) { | 2656 if (fni_ != NULL) { |
| 2662 // Check if the right hand side is a call to avoid inferring a | 2657 // Check if the right hand side is a call to avoid inferring a |
| 2663 // name if we're dealing with "a = function(){...}();"-like | 2658 // name if we're dealing with "a = function(){...}();"-like |
| 2664 // expression. | 2659 // expression. |
| 2665 if ((op == Token::INIT_VAR | 2660 if ((op == Token::INIT_VAR |
| 2666 || op == Token::INIT_CONST | 2661 || op == Token::INIT_CONST |
| 2667 || op == Token::ASSIGN) | 2662 || op == Token::ASSIGN) |
| 2668 && (right->AsCall() == NULL && right->AsCallNew() == NULL)) { | 2663 && (right->AsCall() == NULL && right->AsCallNew() == NULL)) { |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3302 elem = ParseAssignmentExpression(true, CHECK_OK); | 3297 elem = ParseAssignmentExpression(true, CHECK_OK); |
| 3303 } | 3298 } |
| 3304 values->Add(elem); | 3299 values->Add(elem); |
| 3305 if (peek() != Token::RBRACK) { | 3300 if (peek() != Token::RBRACK) { |
| 3306 Expect(Token::COMMA, CHECK_OK); | 3301 Expect(Token::COMMA, CHECK_OK); |
| 3307 } | 3302 } |
| 3308 } | 3303 } |
| 3309 Expect(Token::RBRACK, CHECK_OK); | 3304 Expect(Token::RBRACK, CHECK_OK); |
| 3310 | 3305 |
| 3311 // Update the scope information before the pre-parsing bailout. | 3306 // Update the scope information before the pre-parsing bailout. |
| 3312 int literal_index = lexical_scope_->NextMaterializedLiteralIndex(); | 3307 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); |
| 3313 | 3308 |
| 3314 // Allocate a fixed array to hold all the object literals. | 3309 // Allocate a fixed array to hold all the object literals. |
| 3315 Handle<FixedArray> object_literals = | 3310 Handle<FixedArray> object_literals = |
| 3316 isolate()->factory()->NewFixedArray(values->length(), TENURED); | 3311 isolate()->factory()->NewFixedArray(values->length(), TENURED); |
| 3317 Handle<FixedDoubleArray> double_literals; | 3312 Handle<FixedDoubleArray> double_literals; |
| 3318 ElementsKind elements_kind = FAST_SMI_ONLY_ELEMENTS; | 3313 ElementsKind elements_kind = FAST_SMI_ONLY_ELEMENTS; |
| 3319 | 3314 |
| 3320 // Fill in the literals. | 3315 // Fill in the literals. |
| 3321 bool is_simple = true; | 3316 bool is_simple = true; |
| 3322 int depth = 1; | 3317 int depth = 1; |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3782 Expect(Token::COLON, CHECK_OK); | 3777 Expect(Token::COLON, CHECK_OK); |
| 3783 Expression* value = ParseAssignmentExpression(true, CHECK_OK); | 3778 Expression* value = ParseAssignmentExpression(true, CHECK_OK); |
| 3784 | 3779 |
| 3785 ObjectLiteral::Property* property = | 3780 ObjectLiteral::Property* property = |
| 3786 new(zone()) ObjectLiteral::Property(key, value); | 3781 new(zone()) ObjectLiteral::Property(key, value); |
| 3787 | 3782 |
| 3788 // Mark object literals that contain function literals and pretenure the | 3783 // Mark object literals that contain function literals and pretenure the |
| 3789 // literal so it can be added as a constant function property. | 3784 // literal so it can be added as a constant function property. |
| 3790 if (value->AsFunctionLiteral() != NULL) { | 3785 if (value->AsFunctionLiteral() != NULL) { |
| 3791 has_function = true; | 3786 has_function = true; |
| 3792 value->AsFunctionLiteral()->set_pretenure(true); | 3787 value->AsFunctionLiteral()->set_pretenure(); |
| 3793 } | 3788 } |
| 3794 | 3789 |
| 3795 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 3790 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
| 3796 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; | 3791 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; |
| 3797 // Validate the property | 3792 // Validate the property |
| 3798 checker.CheckProperty(property, loc, CHECK_OK); | 3793 checker.CheckProperty(property, loc, CHECK_OK); |
| 3799 properties->Add(property); | 3794 properties->Add(property); |
| 3800 | 3795 |
| 3801 // TODO(1240767): Consider allowing trailing comma. | 3796 // TODO(1240767): Consider allowing trailing comma. |
| 3802 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | 3797 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
| 3803 | 3798 |
| 3804 if (fni_ != NULL) { | 3799 if (fni_ != NULL) { |
| 3805 fni_->Infer(); | 3800 fni_->Infer(); |
| 3806 fni_->Leave(); | 3801 fni_->Leave(); |
| 3807 } | 3802 } |
| 3808 } | 3803 } |
| 3809 Expect(Token::RBRACE, CHECK_OK); | 3804 Expect(Token::RBRACE, CHECK_OK); |
| 3810 | 3805 |
| 3811 // Computation of literal_index must happen before pre parse bailout. | 3806 // Computation of literal_index must happen before pre parse bailout. |
| 3812 int literal_index = lexical_scope_->NextMaterializedLiteralIndex(); | 3807 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); |
| 3813 | 3808 |
| 3814 Handle<FixedArray> constant_properties = isolate()->factory()->NewFixedArray( | 3809 Handle<FixedArray> constant_properties = isolate()->factory()->NewFixedArray( |
| 3815 number_of_boilerplate_properties * 2, TENURED); | 3810 number_of_boilerplate_properties * 2, TENURED); |
| 3816 | 3811 |
| 3817 bool is_simple = true; | 3812 bool is_simple = true; |
| 3818 bool fast_elements = true; | 3813 bool fast_elements = true; |
| 3819 int depth = 1; | 3814 int depth = 1; |
| 3820 BuildObjectLiteralConstantProperties(properties, | 3815 BuildObjectLiteralConstantProperties(properties, |
| 3821 constant_properties, | 3816 constant_properties, |
| 3822 &is_simple, | 3817 &is_simple, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3834 | 3829 |
| 3835 | 3830 |
| 3836 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { | 3831 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { |
| 3837 if (!scanner().ScanRegExpPattern(seen_equal)) { | 3832 if (!scanner().ScanRegExpPattern(seen_equal)) { |
| 3838 Next(); | 3833 Next(); |
| 3839 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); | 3834 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); |
| 3840 *ok = false; | 3835 *ok = false; |
| 3841 return NULL; | 3836 return NULL; |
| 3842 } | 3837 } |
| 3843 | 3838 |
| 3844 int literal_index = lexical_scope_->NextMaterializedLiteralIndex(); | 3839 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); |
| 3845 | 3840 |
| 3846 Handle<String> js_pattern = NextLiteralString(TENURED); | 3841 Handle<String> js_pattern = NextLiteralString(TENURED); |
| 3847 scanner().ScanRegExpFlags(); | 3842 scanner().ScanRegExpFlags(); |
| 3848 Handle<String> js_flags = NextLiteralString(TENURED); | 3843 Handle<String> js_flags = NextLiteralString(TENURED); |
| 3849 Next(); | 3844 Next(); |
| 3850 | 3845 |
| 3851 return new(zone()) RegExpLiteral( | 3846 return new(zone()) RegExpLiteral( |
| 3852 isolate(), js_pattern, js_flags, literal_index); | 3847 isolate(), js_pattern, js_flags, literal_index); |
| 3853 } | 3848 } |
| 3854 | 3849 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3902 Scope* scope = (type == FunctionLiteral::DECLARATION && !harmony_scoping_) | 3897 Scope* scope = (type == FunctionLiteral::DECLARATION && !harmony_scoping_) |
| 3903 ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE) | 3898 ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE) |
| 3904 : NewScope(top_scope_, FUNCTION_SCOPE); | 3899 : NewScope(top_scope_, FUNCTION_SCOPE); |
| 3905 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8); | 3900 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8); |
| 3906 int materialized_literal_count; | 3901 int materialized_literal_count; |
| 3907 int expected_property_count; | 3902 int expected_property_count; |
| 3908 bool only_simple_this_property_assignments; | 3903 bool only_simple_this_property_assignments; |
| 3909 Handle<FixedArray> this_property_assignments; | 3904 Handle<FixedArray> this_property_assignments; |
| 3910 bool has_duplicate_parameters = false; | 3905 bool has_duplicate_parameters = false; |
| 3911 // Parse function body. | 3906 // Parse function body. |
| 3912 { LexicalScope lexical_scope(this, scope, isolate()); | 3907 { FunctionState function_state(this, scope, isolate()); |
| 3913 top_scope_->SetScopeName(function_name); | 3908 top_scope_->SetScopeName(function_name); |
| 3914 | 3909 |
| 3915 // FormalParameterList :: | 3910 // FormalParameterList :: |
| 3916 // '(' (Identifier)*[','] ')' | 3911 // '(' (Identifier)*[','] ')' |
| 3917 Expect(Token::LPAREN, CHECK_OK); | 3912 Expect(Token::LPAREN, CHECK_OK); |
| 3918 scope->set_start_position(scanner().location().beg_pos); | 3913 scope->set_start_position(scanner().location().beg_pos); |
| 3919 Scanner::Location name_loc = Scanner::Location::invalid(); | 3914 Scanner::Location name_loc = Scanner::Location::invalid(); |
| 3920 Scanner::Location dupe_loc = Scanner::Location::invalid(); | 3915 Scanner::Location dupe_loc = Scanner::Location::invalid(); |
| 3921 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 3916 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
| 3922 | 3917 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4013 top_scope_->SetStrictModeFlag(entry.strict_mode_flag()); | 4008 top_scope_->SetStrictModeFlag(entry.strict_mode_flag()); |
| 4014 only_simple_this_property_assignments = false; | 4009 only_simple_this_property_assignments = false; |
| 4015 this_property_assignments = isolate()->factory()->empty_fixed_array(); | 4010 this_property_assignments = isolate()->factory()->empty_fixed_array(); |
| 4016 Expect(Token::RBRACE, CHECK_OK); | 4011 Expect(Token::RBRACE, CHECK_OK); |
| 4017 } | 4012 } |
| 4018 } | 4013 } |
| 4019 | 4014 |
| 4020 if (!is_lazily_compiled) { | 4015 if (!is_lazily_compiled) { |
| 4021 ParseSourceElements(body, Token::RBRACE, CHECK_OK); | 4016 ParseSourceElements(body, Token::RBRACE, CHECK_OK); |
| 4022 | 4017 |
| 4023 materialized_literal_count = lexical_scope.materialized_literal_count(); | 4018 materialized_literal_count = function_state.materialized_literal_count(); |
| 4024 expected_property_count = lexical_scope.expected_property_count(); | 4019 expected_property_count = function_state.expected_property_count(); |
| 4025 only_simple_this_property_assignments = | 4020 only_simple_this_property_assignments = |
| 4026 lexical_scope.only_simple_this_property_assignments(); | 4021 function_state.only_simple_this_property_assignments(); |
| 4027 this_property_assignments = lexical_scope.this_property_assignments(); | 4022 this_property_assignments = function_state.this_property_assignments(); |
| 4028 | 4023 |
| 4029 Expect(Token::RBRACE, CHECK_OK); | 4024 Expect(Token::RBRACE, CHECK_OK); |
| 4030 scope->set_end_position(scanner().location().end_pos); | 4025 scope->set_end_position(scanner().location().end_pos); |
| 4031 } | 4026 } |
| 4032 | 4027 |
| 4033 // Validate strict mode. | 4028 // Validate strict mode. |
| 4034 if (top_scope_->is_strict_mode()) { | 4029 if (top_scope_->is_strict_mode()) { |
| 4035 if (IsEvalOrArguments(function_name)) { | 4030 if (IsEvalOrArguments(function_name)) { |
| 4036 int start_pos = scope->start_position(); | 4031 int start_pos = scope->start_position(); |
| 4037 int position = function_token_position != RelocInfo::kNoPosition | 4032 int position = function_token_position != RelocInfo::kNoPosition |
| (...skipping 1385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5423 result = parser.ParseProgram(source, | 5418 result = parser.ParseProgram(source, |
| 5424 info->is_global(), | 5419 info->is_global(), |
| 5425 info->strict_mode_flag()); | 5420 info->strict_mode_flag()); |
| 5426 } | 5421 } |
| 5427 } | 5422 } |
| 5428 info->SetFunction(result); | 5423 info->SetFunction(result); |
| 5429 return (result != NULL); | 5424 return (result != NULL); |
| 5430 } | 5425 } |
| 5431 | 5426 |
| 5432 } } // namespace v8::internal | 5427 } } // namespace v8::internal |
| OLD | NEW |