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 |