| 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 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 unsigned ScriptDataImpl::Read(int position) { | 400 unsigned ScriptDataImpl::Read(int position) { |
| 401 return store_[PreparseDataConstants::kHeaderSize + position]; | 401 return store_[PreparseDataConstants::kHeaderSize + position]; |
| 402 } | 402 } |
| 403 | 403 |
| 404 | 404 |
| 405 unsigned* ScriptDataImpl::ReadAddress(int position) { | 405 unsigned* ScriptDataImpl::ReadAddress(int position) { |
| 406 return &store_[PreparseDataConstants::kHeaderSize + position]; | 406 return &store_[PreparseDataConstants::kHeaderSize + position]; |
| 407 } | 407 } |
| 408 | 408 |
| 409 | 409 |
| 410 Scope* Parser::NewScope(Scope* parent, Scope::Type type, bool inside_with) { | 410 Scope* Parser::NewScope(Scope* parent, ScopeType type) { |
| 411 Scope* result = new(zone()) Scope(parent, type); | 411 Scope* result = new(zone()) Scope(parent, type); |
| 412 result->Initialize(inside_with); | 412 result->Initialize(); |
| 413 return result; | 413 return result; |
| 414 } | 414 } |
| 415 | 415 |
| 416 | 416 |
| 417 // ---------------------------------------------------------------------------- | 417 // ---------------------------------------------------------------------------- |
| 418 // Target is a support class to facilitate manipulation of the | 418 // Target is a support class to facilitate manipulation of the |
| 419 // Parser's target_stack_ (the stack of potential 'break' and | 419 // Parser's target_stack_ (the stack of potential 'break' and |
| 420 // 'continue' statement targets). Upon construction, a new target is | 420 // 'continue' statement targets). Upon construction, a new target is |
| 421 // added; it is removed upon destruction. | 421 // added; it is removed upon destruction. |
| 422 | 422 |
| (...skipping 29 matching lines...) Expand all 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 is a support class to facilitate manipulation of the | 462 // LexicalScope and SaveScope are stack allocated support classes to facilitate |
| 463 // Parser's scope stack. The constructor sets the parser's top scope | 463 // anipulation of the Parser's scope stack. The constructor sets the parser's |
| 464 // to the incoming scope, and the destructor resets it. | 464 // top scope to the incoming scope, and the destructor resets it. Additionally, |
| 465 // | 465 // LexicalScope stores transient information used during parsing. |
| 466 // Additionally, it stores transient information used during parsing. | 466 |
| 467 // These scopes are not kept around after parsing or referenced by syntax | 467 |
| 468 // trees so they can be stack-allocated and hence used by the pre-parser. | 468 class SaveScope BASE_EMBEDDED { |
| 469 public: |
| 470 SaveScope(Parser* parser, Scope* scope) |
| 471 : parser_(parser), |
| 472 previous_top_scope_(parser->top_scope_) { |
| 473 parser->top_scope_ = scope; |
| 474 } |
| 475 |
| 476 ~SaveScope() { |
| 477 parser_->top_scope_ = previous_top_scope_; |
| 478 } |
| 479 |
| 480 private: |
| 481 // Bookkeeping |
| 482 Parser* parser_; |
| 483 // Previous values |
| 484 Scope* previous_top_scope_; |
| 485 }; |
| 486 |
| 469 | 487 |
| 470 class LexicalScope BASE_EMBEDDED { | 488 class LexicalScope BASE_EMBEDDED { |
| 471 public: | 489 public: |
| 472 LexicalScope(Parser* parser, Scope* scope, Isolate* isolate); | 490 LexicalScope(Parser* parser, Scope* scope, Isolate* isolate); |
| 473 ~LexicalScope(); | 491 ~LexicalScope(); |
| 474 | 492 |
| 475 int NextMaterializedLiteralIndex() { | 493 int NextMaterializedLiteralIndex() { |
| 476 int next_index = | 494 int next_index = |
| 477 materialized_literal_count_ + JSFunction::kLiteralsPrefixSize; | 495 materialized_literal_count_ + JSFunction::kLiteralsPrefixSize; |
| 478 materialized_literal_count_++; | 496 materialized_literal_count_++; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 509 // Keeps track of assignments to properties of this. Used for | 527 // Keeps track of assignments to properties of this. Used for |
| 510 // optimizing constructors. | 528 // optimizing constructors. |
| 511 bool only_simple_this_property_assignments_; | 529 bool only_simple_this_property_assignments_; |
| 512 Handle<FixedArray> this_property_assignments_; | 530 Handle<FixedArray> this_property_assignments_; |
| 513 | 531 |
| 514 // Bookkeeping | 532 // Bookkeeping |
| 515 Parser* parser_; | 533 Parser* parser_; |
| 516 // Previous values | 534 // Previous values |
| 517 LexicalScope* lexical_scope_parent_; | 535 LexicalScope* lexical_scope_parent_; |
| 518 Scope* previous_scope_; | 536 Scope* previous_scope_; |
| 519 int previous_with_nesting_level_; | |
| 520 unsigned previous_ast_node_id_; | 537 unsigned previous_ast_node_id_; |
| 521 }; | 538 }; |
| 522 | 539 |
| 523 | 540 |
| 524 LexicalScope::LexicalScope(Parser* parser, Scope* scope, Isolate* isolate) | 541 LexicalScope::LexicalScope(Parser* parser, Scope* scope, Isolate* isolate) |
| 525 : materialized_literal_count_(0), | 542 : materialized_literal_count_(0), |
| 526 expected_property_count_(0), | 543 expected_property_count_(0), |
| 527 only_simple_this_property_assignments_(false), | 544 only_simple_this_property_assignments_(false), |
| 528 this_property_assignments_(isolate->factory()->empty_fixed_array()), | 545 this_property_assignments_(isolate->factory()->empty_fixed_array()), |
| 529 parser_(parser), | 546 parser_(parser), |
| 530 lexical_scope_parent_(parser->lexical_scope_), | 547 lexical_scope_parent_(parser->lexical_scope_), |
| 531 previous_scope_(parser->top_scope_), | 548 previous_scope_(parser->top_scope_), |
| 532 previous_with_nesting_level_(parser->with_nesting_level_), | |
| 533 previous_ast_node_id_(isolate->ast_node_id()) { | 549 previous_ast_node_id_(isolate->ast_node_id()) { |
| 534 parser->top_scope_ = scope; | 550 parser->top_scope_ = scope; |
| 535 parser->lexical_scope_ = this; | 551 parser->lexical_scope_ = this; |
| 536 parser->with_nesting_level_ = 0; | |
| 537 isolate->set_ast_node_id(AstNode::kDeclarationsId + 1); | 552 isolate->set_ast_node_id(AstNode::kDeclarationsId + 1); |
| 538 } | 553 } |
| 539 | 554 |
| 540 | 555 |
| 541 LexicalScope::~LexicalScope() { | 556 LexicalScope::~LexicalScope() { |
| 542 parser_->top_scope_ = previous_scope_; | 557 parser_->top_scope_ = previous_scope_; |
| 543 parser_->lexical_scope_ = lexical_scope_parent_; | 558 parser_->lexical_scope_ = lexical_scope_parent_; |
| 544 parser_->with_nesting_level_ = previous_with_nesting_level_; | |
| 545 parser_->isolate()->set_ast_node_id(previous_ast_node_id_); | 559 parser_->isolate()->set_ast_node_id(previous_ast_node_id_); |
| 546 } | 560 } |
| 547 | 561 |
| 548 | 562 |
| 549 // ---------------------------------------------------------------------------- | 563 // ---------------------------------------------------------------------------- |
| 550 // The CHECK_OK macro is a convenient macro to enforce error | 564 // The CHECK_OK macro is a convenient macro to enforce error |
| 551 // handling for functions that may fail (by returning !*ok). | 565 // handling for functions that may fail (by returning !*ok). |
| 552 // | 566 // |
| 553 // CAUTION: This macro appends extra statements after a call, | 567 // CAUTION: This macro appends extra statements after a call, |
| 554 // thus it must never be used where only a single statement | 568 // thus it must never be used where only a single statement |
| (...skipping 16 matching lines...) Expand all Loading... |
| 571 | 585 |
| 572 Parser::Parser(Handle<Script> script, | 586 Parser::Parser(Handle<Script> script, |
| 573 bool allow_natives_syntax, | 587 bool allow_natives_syntax, |
| 574 v8::Extension* extension, | 588 v8::Extension* extension, |
| 575 ScriptDataImpl* pre_data) | 589 ScriptDataImpl* pre_data) |
| 576 : isolate_(script->GetIsolate()), | 590 : isolate_(script->GetIsolate()), |
| 577 symbol_cache_(pre_data ? pre_data->symbol_count() : 0), | 591 symbol_cache_(pre_data ? pre_data->symbol_count() : 0), |
| 578 script_(script), | 592 script_(script), |
| 579 scanner_(isolate_->unicode_cache()), | 593 scanner_(isolate_->unicode_cache()), |
| 580 top_scope_(NULL), | 594 top_scope_(NULL), |
| 581 with_nesting_level_(0), | |
| 582 lexical_scope_(NULL), | 595 lexical_scope_(NULL), |
| 583 target_stack_(NULL), | 596 target_stack_(NULL), |
| 584 allow_natives_syntax_(allow_natives_syntax), | 597 allow_natives_syntax_(allow_natives_syntax), |
| 585 extension_(extension), | 598 extension_(extension), |
| 586 pre_data_(pre_data), | 599 pre_data_(pre_data), |
| 587 fni_(NULL), | 600 fni_(NULL), |
| 588 stack_overflow_(false), | 601 stack_overflow_(false), |
| 589 parenthesized_function_(false), | 602 parenthesized_function_(false), |
| 590 harmony_scoping_(false) { | 603 harmony_scoping_(false) { |
| 591 AstNode::ResetIds(); | 604 AstNode::ResetIds(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 616 scanner_.Initialize(&stream); | 629 scanner_.Initialize(&stream); |
| 617 return DoParseProgram(source, in_global_context, strict_mode, &zone_scope); | 630 return DoParseProgram(source, in_global_context, strict_mode, &zone_scope); |
| 618 } | 631 } |
| 619 } | 632 } |
| 620 | 633 |
| 621 | 634 |
| 622 FunctionLiteral* Parser::DoParseProgram(Handle<String> source, | 635 FunctionLiteral* Parser::DoParseProgram(Handle<String> source, |
| 623 bool in_global_context, | 636 bool in_global_context, |
| 624 StrictModeFlag strict_mode, | 637 StrictModeFlag strict_mode, |
| 625 ZoneScope* zone_scope) { | 638 ZoneScope* zone_scope) { |
| 639 ASSERT(top_scope_ == NULL); |
| 626 ASSERT(target_stack_ == NULL); | 640 ASSERT(target_stack_ == NULL); |
| 627 if (pre_data_ != NULL) pre_data_->Initialize(); | 641 if (pre_data_ != NULL) pre_data_->Initialize(); |
| 628 | 642 |
| 629 // Compute the parsing mode. | 643 // Compute the parsing mode. |
| 630 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; | 644 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; |
| 631 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; | 645 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; |
| 632 | 646 |
| 633 Scope::Type type = | 647 ScopeType type = in_global_context ? GLOBAL_SCOPE : EVAL_SCOPE; |
| 634 in_global_context | |
| 635 ? Scope::GLOBAL_SCOPE | |
| 636 : Scope::EVAL_SCOPE; | |
| 637 Handle<String> no_name = isolate()->factory()->empty_symbol(); | 648 Handle<String> no_name = isolate()->factory()->empty_symbol(); |
| 638 | 649 |
| 639 FunctionLiteral* result = NULL; | 650 FunctionLiteral* result = NULL; |
| 640 { Scope* scope = NewScope(top_scope_, type, inside_with()); | 651 { Scope* scope = NewScope(top_scope_, type); |
| 652 scope->set_start_position(0); |
| 653 scope->set_end_position(source->length()); |
| 641 LexicalScope lexical_scope(this, scope, isolate()); | 654 LexicalScope lexical_scope(this, scope, isolate()); |
| 642 if (strict_mode == kStrictMode) { | 655 ASSERT(top_scope_->strict_mode_flag() == kNonStrictMode); |
| 643 top_scope_->EnableStrictMode(); | 656 top_scope_->SetStrictModeFlag(strict_mode); |
| 644 } | |
| 645 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16); | 657 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16); |
| 646 bool ok = true; | 658 bool ok = true; |
| 647 int beg_loc = scanner().location().beg_pos; | 659 int beg_loc = scanner().location().beg_pos; |
| 648 ParseSourceElements(body, Token::EOS, &ok); | 660 ParseSourceElements(body, Token::EOS, &ok); |
| 649 if (ok && top_scope_->is_strict_mode()) { | 661 if (ok && top_scope_->is_strict_mode()) { |
| 650 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); | 662 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); |
| 651 } | 663 } |
| 652 | 664 |
| 653 if (ok && harmony_scoping_) { | 665 if (ok && harmony_scoping_) { |
| 654 CheckConflictingVarDeclarations(scope, &ok); | 666 CheckConflictingVarDeclarations(scope, &ok); |
| 655 } | 667 } |
| 656 | 668 |
| 657 if (ok) { | 669 if (ok) { |
| 658 result = new(zone()) FunctionLiteral( | 670 result = new(zone()) FunctionLiteral( |
| 659 isolate(), | 671 isolate(), |
| 660 no_name, | 672 no_name, |
| 661 top_scope_, | 673 top_scope_, |
| 662 body, | 674 body, |
| 663 lexical_scope.materialized_literal_count(), | 675 lexical_scope.materialized_literal_count(), |
| 664 lexical_scope.expected_property_count(), | 676 lexical_scope.expected_property_count(), |
| 665 lexical_scope.only_simple_this_property_assignments(), | 677 lexical_scope.only_simple_this_property_assignments(), |
| 666 lexical_scope.this_property_assignments(), | 678 lexical_scope.this_property_assignments(), |
| 667 0, | 679 0, |
| 668 0, | |
| 669 source->length(), | |
| 670 FunctionLiteral::ANONYMOUS_EXPRESSION, | 680 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 671 false); // Does not have duplicate parameters. | 681 false); // Does not have duplicate parameters. |
| 672 } else if (stack_overflow_) { | 682 } else if (stack_overflow_) { |
| 673 isolate()->StackOverflow(); | 683 isolate()->StackOverflow(); |
| 674 } | 684 } |
| 675 } | 685 } |
| 676 | 686 |
| 677 // Make sure the target stack is empty. | 687 // Make sure the target stack is empty. |
| 678 ASSERT(target_stack_ == NULL); | 688 ASSERT(target_stack_ == NULL); |
| 679 | 689 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 707 return result; | 717 return result; |
| 708 } | 718 } |
| 709 } | 719 } |
| 710 | 720 |
| 711 | 721 |
| 712 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info, | 722 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info, |
| 713 UC16CharacterStream* source, | 723 UC16CharacterStream* source, |
| 714 ZoneScope* zone_scope) { | 724 ZoneScope* zone_scope) { |
| 715 Handle<SharedFunctionInfo> shared_info = info->shared_info(); | 725 Handle<SharedFunctionInfo> shared_info = info->shared_info(); |
| 716 scanner_.Initialize(source); | 726 scanner_.Initialize(source); |
| 727 ASSERT(top_scope_ == NULL); |
| 717 ASSERT(target_stack_ == NULL); | 728 ASSERT(target_stack_ == NULL); |
| 718 | 729 |
| 719 Handle<String> name(String::cast(shared_info->name())); | 730 Handle<String> name(String::cast(shared_info->name())); |
| 720 fni_ = new(zone()) FuncNameInferrer(isolate()); | 731 fni_ = new(zone()) FuncNameInferrer(isolate()); |
| 721 fni_->PushEnclosingName(name); | 732 fni_->PushEnclosingName(name); |
| 722 | 733 |
| 723 mode_ = PARSE_EAGERLY; | 734 mode_ = PARSE_EAGERLY; |
| 724 | 735 |
| 725 // Place holder for the result. | 736 // Place holder for the result. |
| 726 FunctionLiteral* result = NULL; | 737 FunctionLiteral* result = NULL; |
| 727 | 738 |
| 728 { | 739 { |
| 729 // Parse the function literal. | 740 // Parse the function literal. |
| 730 Scope* scope = NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); | 741 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); |
| 731 if (!info->closure().is_null()) { | 742 if (!info->closure().is_null()) { |
| 732 scope = Scope::DeserializeScopeChain(info, scope); | 743 scope = Scope::DeserializeScopeChain(info, scope); |
| 733 } | 744 } |
| 734 LexicalScope lexical_scope(this, scope, isolate()); | 745 LexicalScope lexical_scope(this, scope, isolate()); |
| 735 | 746 ASSERT(scope->strict_mode_flag() == kNonStrictMode || |
| 736 if (shared_info->strict_mode()) { | 747 scope->strict_mode_flag() == info->strict_mode_flag()); |
| 737 top_scope_->EnableStrictMode(); | 748 ASSERT(info->strict_mode_flag() == shared_info->strict_mode_flag()); |
| 738 } | 749 scope->SetStrictModeFlag(shared_info->strict_mode_flag()); |
| 739 | |
| 740 FunctionLiteral::Type type = shared_info->is_expression() | 750 FunctionLiteral::Type type = shared_info->is_expression() |
| 741 ? (shared_info->is_anonymous() | 751 ? (shared_info->is_anonymous() |
| 742 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 752 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 743 : FunctionLiteral::NAMED_EXPRESSION) | 753 : FunctionLiteral::NAMED_EXPRESSION) |
| 744 : FunctionLiteral::DECLARATION; | 754 : FunctionLiteral::DECLARATION; |
| 745 bool ok = true; | 755 bool ok = true; |
| 746 result = ParseFunctionLiteral(name, | 756 result = ParseFunctionLiteral(name, |
| 747 false, // Strict mode name already checked. | 757 false, // Strict mode name already checked. |
| 748 RelocInfo::kNoPosition, | 758 RelocInfo::kNoPosition, |
| 749 type, | 759 type, |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1121 Statement* Parser::ParseSourceElement(ZoneStringList* labels, | 1131 Statement* Parser::ParseSourceElement(ZoneStringList* labels, |
| 1122 bool* ok) { | 1132 bool* ok) { |
| 1123 // (Ecma 262 5th Edition, clause 14): | 1133 // (Ecma 262 5th Edition, clause 14): |
| 1124 // SourceElement: | 1134 // SourceElement: |
| 1125 // Statement | 1135 // Statement |
| 1126 // FunctionDeclaration | 1136 // FunctionDeclaration |
| 1127 // | 1137 // |
| 1128 // In harmony mode we allow additionally the following productions | 1138 // In harmony mode we allow additionally the following productions |
| 1129 // SourceElement: | 1139 // SourceElement: |
| 1130 // LetDeclaration | 1140 // LetDeclaration |
| 1141 // ConstDeclaration |
| 1131 | 1142 |
| 1132 if (peek() == Token::FUNCTION) { | 1143 if (peek() == Token::FUNCTION) { |
| 1133 return ParseFunctionDeclaration(ok); | 1144 return ParseFunctionDeclaration(ok); |
| 1134 } else if (peek() == Token::LET) { | 1145 } else if (peek() == Token::LET || peek() == Token::CONST) { |
| 1135 return ParseVariableStatement(kSourceElement, ok); | 1146 return ParseVariableStatement(kSourceElement, ok); |
| 1136 } else { | |
| 1137 return ParseStatement(labels, ok); | |
| 1138 } | 1147 } |
| 1148 return ParseStatement(labels, ok); |
| 1139 } | 1149 } |
| 1140 | 1150 |
| 1141 | 1151 |
| 1142 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, | 1152 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
| 1143 int end_token, | 1153 int end_token, |
| 1144 bool* ok) { | 1154 bool* ok) { |
| 1145 // SourceElements :: | 1155 // SourceElements :: |
| 1146 // (SourceElement)* <end_token> | 1156 // (SourceElement)* <end_token> |
| 1147 | 1157 |
| 1148 // Allocate a target stack to use for this set of source | 1158 // Allocate a target stack to use for this set of source |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1176 if ((e_stat = stat->AsExpressionStatement()) != NULL && | 1186 if ((e_stat = stat->AsExpressionStatement()) != NULL && |
| 1177 (literal = e_stat->expression()->AsLiteral()) != NULL && | 1187 (literal = e_stat->expression()->AsLiteral()) != NULL && |
| 1178 literal->handle()->IsString()) { | 1188 literal->handle()->IsString()) { |
| 1179 Handle<String> directive = Handle<String>::cast(literal->handle()); | 1189 Handle<String> directive = Handle<String>::cast(literal->handle()); |
| 1180 | 1190 |
| 1181 // Check "use strict" directive (ES5 14.1). | 1191 // Check "use strict" directive (ES5 14.1). |
| 1182 if (!top_scope_->is_strict_mode() && | 1192 if (!top_scope_->is_strict_mode() && |
| 1183 directive->Equals(isolate()->heap()->use_strict()) && | 1193 directive->Equals(isolate()->heap()->use_strict()) && |
| 1184 token_loc.end_pos - token_loc.beg_pos == | 1194 token_loc.end_pos - token_loc.beg_pos == |
| 1185 isolate()->heap()->use_strict()->length() + 2) { | 1195 isolate()->heap()->use_strict()->length() + 2) { |
| 1186 top_scope_->EnableStrictMode(); | 1196 top_scope_->SetStrictModeFlag(kStrictMode); |
| 1187 // "use strict" is the only directive for now. | 1197 // "use strict" is the only directive for now. |
| 1188 directive_prologue = false; | 1198 directive_prologue = false; |
| 1189 } | 1199 } |
| 1190 } else { | 1200 } else { |
| 1191 // End of the directive prologue. | 1201 // End of the directive prologue. |
| 1192 directive_prologue = false; | 1202 directive_prologue = false; |
| 1193 } | 1203 } |
| 1194 } | 1204 } |
| 1195 | 1205 |
| 1196 block_finder.Update(stat); | 1206 block_finder.Update(stat); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1314 } | 1324 } |
| 1315 | 1325 |
| 1316 case Token::FUNCTION: { | 1326 case Token::FUNCTION: { |
| 1317 // FunctionDeclaration is only allowed in the context of SourceElements | 1327 // FunctionDeclaration is only allowed in the context of SourceElements |
| 1318 // (Ecma 262 5th Edition, clause 14): | 1328 // (Ecma 262 5th Edition, clause 14): |
| 1319 // SourceElement: | 1329 // SourceElement: |
| 1320 // Statement | 1330 // Statement |
| 1321 // FunctionDeclaration | 1331 // FunctionDeclaration |
| 1322 // Common language extension is to allow function declaration in place | 1332 // Common language extension is to allow function declaration in place |
| 1323 // of any statement. This language extension is disabled in strict mode. | 1333 // of any statement. This language extension is disabled in strict mode. |
| 1324 if (top_scope_->is_strict_mode()) { | 1334 if (top_scope_->is_strict_mode() || harmony_scoping_) { |
| 1325 ReportMessageAt(scanner().peek_location(), "strict_function", | 1335 ReportMessageAt(scanner().peek_location(), "strict_function", |
| 1326 Vector<const char*>::empty()); | 1336 Vector<const char*>::empty()); |
| 1327 *ok = false; | 1337 *ok = false; |
| 1328 return NULL; | 1338 return NULL; |
| 1329 } | 1339 } |
| 1330 return ParseFunctionDeclaration(ok); | 1340 return ParseFunctionDeclaration(ok); |
| 1331 } | 1341 } |
| 1332 | 1342 |
| 1333 case Token::DEBUGGER: | 1343 case Token::DEBUGGER: |
| 1334 stmt = ParseDebuggerStatement(ok); | 1344 stmt = ParseDebuggerStatement(ok); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1346 | 1356 |
| 1347 VariableProxy* Parser::Declare(Handle<String> name, | 1357 VariableProxy* Parser::Declare(Handle<String> name, |
| 1348 VariableMode mode, | 1358 VariableMode mode, |
| 1349 FunctionLiteral* fun, | 1359 FunctionLiteral* fun, |
| 1350 bool resolve, | 1360 bool resolve, |
| 1351 bool* ok) { | 1361 bool* ok) { |
| 1352 Variable* var = NULL; | 1362 Variable* var = NULL; |
| 1353 // If we are inside a function, a declaration of a var/const variable is a | 1363 // If we are inside a function, a declaration of a var/const variable is a |
| 1354 // truly local variable, and the scope of the variable is always the function | 1364 // truly local variable, and the scope of the variable is always the function |
| 1355 // scope. | 1365 // scope. |
| 1366 // Let/const variables in harmony mode are always added to the immediately |
| 1367 // enclosing scope. |
| 1368 Scope* declaration_scope = (mode == LET || mode == CONST_HARMONY) |
| 1369 ? top_scope_ : top_scope_->DeclarationScope(); |
| 1356 | 1370 |
| 1357 // If a function scope exists, then we can statically declare this | 1371 // If a function scope exists, then we can statically declare this |
| 1358 // variable and also set its mode. In any case, a Declaration node | 1372 // variable and also set its mode. In any case, a Declaration node |
| 1359 // will be added to the scope so that the declaration can be added | 1373 // will be added to the scope so that the declaration can be added |
| 1360 // to the corresponding activation frame at runtime if necessary. | 1374 // to the corresponding activation frame at runtime if necessary. |
| 1361 // For instance declarations inside an eval scope need to be added | 1375 // For instance declarations inside an eval scope need to be added |
| 1362 // to the calling function context. | 1376 // to the calling function context. |
| 1363 // Similarly, strict mode eval scope does not leak variable declarations to | 1377 // Similarly, strict mode eval scope does not leak variable declarations to |
| 1364 // the caller's scope so we declare all locals, too. | 1378 // the caller's scope so we declare all locals, too. |
| 1365 | 1379 // Also for block scoped let/const bindings the variable can be |
| 1366 Scope* declaration_scope = mode == LET ? top_scope_ | 1380 // statically declared. |
| 1367 : top_scope_->DeclarationScope(); | |
| 1368 if (declaration_scope->is_function_scope() || | 1381 if (declaration_scope->is_function_scope() || |
| 1369 declaration_scope->is_strict_mode_eval_scope() || | 1382 declaration_scope->is_strict_mode_eval_scope() || |
| 1370 declaration_scope->is_block_scope()) { | 1383 declaration_scope->is_block_scope()) { |
| 1371 // Declare the variable in the function scope. | 1384 // Declare the variable in the function scope. |
| 1372 var = declaration_scope->LocalLookup(name); | 1385 var = declaration_scope->LocalLookup(name); |
| 1373 if (var == NULL) { | 1386 if (var == NULL) { |
| 1374 // Declare the name. | 1387 // Declare the name. |
| 1375 var = declaration_scope->DeclareLocal(name, mode); | 1388 var = declaration_scope->DeclareLocal(name, mode); |
| 1376 } else { | 1389 } else { |
| 1377 // The name was declared in this scope before; check for conflicting | 1390 // The name was declared in this scope before; check for conflicting |
| 1378 // re-declarations. We have a conflict if either of the declarations is | 1391 // re-declarations. We have a conflict if either of the declarations is |
| 1379 // not a var. There is similar code in runtime.cc in the Declare | 1392 // not a var. There is similar code in runtime.cc in the Declare |
| 1380 // functions. The function CheckNonConflictingScope checks for conflicting | 1393 // functions. The function CheckNonConflictingScope checks for conflicting |
| 1381 // var and let bindings from different scopes whereas this is a check for | 1394 // var and let bindings from different scopes whereas this is a check for |
| 1382 // conflicting declarations within the same scope. This check also covers | 1395 // conflicting declarations within the same scope. This check also covers |
| 1383 // | 1396 // |
| 1384 // function () { let x; { var x; } } | 1397 // function () { let x; { var x; } } |
| 1385 // | 1398 // |
| 1386 // because the var declaration is hoisted to the function scope where 'x' | 1399 // because the var declaration is hoisted to the function scope where 'x' |
| 1387 // is already bound. | 1400 // is already bound. |
| 1388 if ((mode != VAR) || (var->mode() != VAR)) { | 1401 if ((mode != VAR) || (var->mode() != VAR)) { |
| 1389 // We only have vars, consts and lets in declarations. | 1402 // We only have vars, consts and lets in declarations. |
| 1390 ASSERT(var->mode() == VAR || | 1403 ASSERT(var->mode() == VAR || |
| 1391 var->mode() == CONST || | 1404 var->mode() == CONST || |
| 1405 var->mode() == CONST_HARMONY || |
| 1392 var->mode() == LET); | 1406 var->mode() == LET); |
| 1393 if (harmony_scoping_) { | 1407 if (harmony_scoping_) { |
| 1394 // In harmony mode we treat re-declarations as early errors. See | 1408 // In harmony mode we treat re-declarations as early errors. See |
| 1395 // ES5 16 for a definition of early errors. | 1409 // ES5 16 for a definition of early errors. |
| 1396 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | 1410 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
| 1397 const char* elms[2] = { "Variable", *c_string }; | 1411 const char* elms[2] = { "Variable", *c_string }; |
| 1398 Vector<const char*> args(elms, 2); | 1412 Vector<const char*> args(elms, 2); |
| 1399 ReportMessage("redeclaration", args); | 1413 ReportMessage("redeclaration", args); |
| 1400 *ok = false; | 1414 *ok = false; |
| 1401 return NULL; | 1415 return NULL; |
| 1402 } | 1416 } |
| 1403 const char* type = (var->mode() == VAR) ? "var" : | 1417 const char* type = (var->mode() == VAR) |
| 1404 (var->mode() == CONST) ? "const" : "let"; | 1418 ? "var" : var->is_const_mode() ? "const" : "let"; |
| 1405 Handle<String> type_string = | 1419 Handle<String> type_string = |
| 1406 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); | 1420 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); |
| 1407 Expression* expression = | 1421 Expression* expression = |
| 1408 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), | 1422 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), |
| 1409 type_string, name); | 1423 type_string, name); |
| 1410 declaration_scope->SetIllegalRedeclaration(expression); | 1424 declaration_scope->SetIllegalRedeclaration(expression); |
| 1411 } | 1425 } |
| 1412 } | 1426 } |
| 1413 } | 1427 } |
| 1414 | 1428 |
| 1415 // We add a declaration node for every declaration. The compiler | 1429 // We add a declaration node for every declaration. The compiler |
| 1416 // will only generate code if necessary. In particular, declarations | 1430 // will only generate code if necessary. In particular, declarations |
| 1417 // for inner local variables that do not represent functions won't | 1431 // for inner local variables that do not represent functions won't |
| 1418 // result in any generated code. | 1432 // result in any generated code. |
| 1419 // | 1433 // |
| 1420 // Note that we always add an unresolved proxy even if it's not | 1434 // Note that we always add an unresolved proxy even if it's not |
| 1421 // used, simply because we don't know in this method (w/o extra | 1435 // used, simply because we don't know in this method (w/o extra |
| 1422 // parameters) if the proxy is needed or not. The proxy will be | 1436 // parameters) if the proxy is needed or not. The proxy will be |
| 1423 // bound during variable resolution time unless it was pre-bound | 1437 // bound during variable resolution time unless it was pre-bound |
| 1424 // below. | 1438 // below. |
| 1425 // | 1439 // |
| 1426 // WARNING: This will lead to multiple declaration nodes for the | 1440 // WARNING: This will lead to multiple declaration nodes for the |
| 1427 // same variable if it is declared several times. This is not a | 1441 // same variable if it is declared several times. This is not a |
| 1428 // semantic issue as long as we keep the source order, but it may be | 1442 // semantic issue as long as we keep the source order, but it may be |
| 1429 // a performance issue since it may lead to repeated | 1443 // a performance issue since it may lead to repeated |
| 1430 // Runtime::DeclareContextSlot() calls. | 1444 // Runtime::DeclareContextSlot() calls. |
| 1431 VariableProxy* proxy = declaration_scope->NewUnresolved( | 1445 VariableProxy* proxy = declaration_scope->NewUnresolved( |
| 1432 name, false, scanner().location().beg_pos); | 1446 name, scanner().location().beg_pos); |
| 1433 declaration_scope->AddDeclaration( | 1447 declaration_scope->AddDeclaration( |
| 1434 new(zone()) Declaration(proxy, mode, fun, top_scope_)); | 1448 new(zone()) Declaration(proxy, mode, fun, top_scope_)); |
| 1435 | 1449 |
| 1436 // For global const variables we bind the proxy to a variable. | 1450 // For global const variables we bind the proxy to a variable. |
| 1437 if (mode == CONST && declaration_scope->is_global_scope()) { | 1451 if ((mode == CONST || mode == CONST_HARMONY) && |
| 1452 declaration_scope->is_global_scope()) { |
| 1438 ASSERT(resolve); // should be set by all callers | 1453 ASSERT(resolve); // should be set by all callers |
| 1439 Variable::Kind kind = Variable::NORMAL; | 1454 Variable::Kind kind = Variable::NORMAL; |
| 1440 var = new(zone()) Variable(declaration_scope, name, CONST, true, kind); | 1455 var = new(zone()) Variable(declaration_scope, name, CONST, true, kind); |
| 1441 } | 1456 } |
| 1442 | 1457 |
| 1443 // If requested and we have a local variable, bind the proxy to the variable | 1458 // If requested and we have a local variable, bind the proxy to the variable |
| 1444 // at parse-time. This is used for functions (and consts) declared inside | 1459 // at parse-time. This is used for functions (and consts) declared inside |
| 1445 // statements: the corresponding function (or const) variable must be in the | 1460 // statements: the corresponding function (or const) variable must be in the |
| 1446 // function scope and not a statement-local scope, e.g. as provided with a | 1461 // function scope and not a statement-local scope, e.g. as provided with a |
| 1447 // 'with' statement: | 1462 // 'with' statement: |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1575 | 1590 |
| 1576 | 1591 |
| 1577 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { | 1592 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
| 1578 // The harmony mode uses source elements instead of statements. | 1593 // The harmony mode uses source elements instead of statements. |
| 1579 // | 1594 // |
| 1580 // Block :: | 1595 // Block :: |
| 1581 // '{' SourceElement* '}' | 1596 // '{' SourceElement* '}' |
| 1582 | 1597 |
| 1583 // Construct block expecting 16 statements. | 1598 // Construct block expecting 16 statements. |
| 1584 Block* body = new(zone()) Block(isolate(), labels, 16, false); | 1599 Block* body = new(zone()) Block(isolate(), labels, 16, false); |
| 1585 Scope* saved_scope = top_scope_; | 1600 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); |
| 1586 Scope* block_scope = NewScope(top_scope_, | |
| 1587 Scope::BLOCK_SCOPE, | |
| 1588 inside_with()); | |
| 1589 if (top_scope_->is_strict_mode()) { | |
| 1590 block_scope->EnableStrictMode(); | |
| 1591 } | |
| 1592 top_scope_ = block_scope; | |
| 1593 | 1601 |
| 1594 // Parse the statements and collect escaping labels. | 1602 // Parse the statements and collect escaping labels. |
| 1595 TargetCollector collector; | |
| 1596 Target target(&this->target_stack_, &collector); | |
| 1597 Expect(Token::LBRACE, CHECK_OK); | 1603 Expect(Token::LBRACE, CHECK_OK); |
| 1598 { | 1604 block_scope->set_start_position(scanner().location().beg_pos); |
| 1605 { SaveScope save_scope(this, block_scope); |
| 1606 TargetCollector collector; |
| 1607 Target target(&this->target_stack_, &collector); |
| 1599 Target target_body(&this->target_stack_, body); | 1608 Target target_body(&this->target_stack_, body); |
| 1600 InitializationBlockFinder block_finder(top_scope_, target_stack_); | 1609 InitializationBlockFinder block_finder(top_scope_, target_stack_); |
| 1601 | 1610 |
| 1602 while (peek() != Token::RBRACE) { | 1611 while (peek() != Token::RBRACE) { |
| 1603 Statement* stat = ParseSourceElement(NULL, CHECK_OK); | 1612 Statement* stat = ParseSourceElement(NULL, CHECK_OK); |
| 1604 if (stat && !stat->IsEmpty()) { | 1613 if (stat && !stat->IsEmpty()) { |
| 1605 body->AddStatement(stat); | 1614 body->AddStatement(stat); |
| 1606 block_finder.Update(stat); | 1615 block_finder.Update(stat); |
| 1607 } | 1616 } |
| 1608 } | 1617 } |
| 1609 } | 1618 } |
| 1610 Expect(Token::RBRACE, CHECK_OK); | 1619 Expect(Token::RBRACE, CHECK_OK); |
| 1611 top_scope_ = saved_scope; | 1620 block_scope->set_end_position(scanner().location().end_pos); |
| 1612 | |
| 1613 block_scope = block_scope->FinalizeBlockScope(); | 1621 block_scope = block_scope->FinalizeBlockScope(); |
| 1614 body->set_block_scope(block_scope); | 1622 body->set_block_scope(block_scope); |
| 1615 return body; | 1623 return body; |
| 1616 } | 1624 } |
| 1617 | 1625 |
| 1618 | 1626 |
| 1619 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, | 1627 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
| 1620 bool* ok) { | 1628 bool* ok) { |
| 1621 // VariableStatement :: | 1629 // VariableStatement :: |
| 1622 // VariableDeclarations ';' | 1630 // VariableDeclarations ';' |
| 1623 | 1631 |
| 1624 Handle<String> ignore; | 1632 Handle<String> ignore; |
| 1625 Block* result = ParseVariableDeclarations(var_context, | 1633 Block* result = ParseVariableDeclarations(var_context, |
| 1634 NULL, |
| 1626 &ignore, | 1635 &ignore, |
| 1627 CHECK_OK); | 1636 CHECK_OK); |
| 1628 ExpectSemicolon(CHECK_OK); | 1637 ExpectSemicolon(CHECK_OK); |
| 1629 return result; | 1638 return result; |
| 1630 } | 1639 } |
| 1631 | 1640 |
| 1632 | 1641 |
| 1633 bool Parser::IsEvalOrArguments(Handle<String> string) { | 1642 bool Parser::IsEvalOrArguments(Handle<String> string) { |
| 1634 return string.is_identical_to(isolate()->factory()->eval_symbol()) || | 1643 return string.is_identical_to(isolate()->factory()->eval_symbol()) || |
| 1635 string.is_identical_to(isolate()->factory()->arguments_symbol()); | 1644 string.is_identical_to(isolate()->factory()->arguments_symbol()); |
| 1636 } | 1645 } |
| 1637 | 1646 |
| 1638 | 1647 |
| 1639 // If the variable declaration declares exactly one non-const | 1648 // If the variable declaration declares exactly one non-const |
| 1640 // variable, then *var is set to that variable. In all other cases, | 1649 // variable, then *var is set to that variable. In all other cases, |
| 1641 // *var is untouched; in particular, it is the caller's responsibility | 1650 // *var is untouched; in particular, it is the caller's responsibility |
| 1642 // to initialize it properly. This mechanism is used for the parsing | 1651 // to initialize it properly. This mechanism is used for the parsing |
| 1643 // of 'for-in' loops. | 1652 // of 'for-in' loops. |
| 1644 Block* Parser::ParseVariableDeclarations(VariableDeclarationContext var_context, | 1653 Block* Parser::ParseVariableDeclarations( |
| 1645 Handle<String>* out, | 1654 VariableDeclarationContext var_context, |
| 1646 bool* ok) { | 1655 VariableDeclarationProperties* decl_props, |
| 1656 Handle<String>* out, |
| 1657 bool* ok) { |
| 1647 // VariableDeclarations :: | 1658 // VariableDeclarations :: |
| 1648 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] | 1659 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] |
| 1649 | 1660 // |
| 1661 // The ES6 Draft Rev3 specifies the following grammar for const declarations |
| 1662 // |
| 1663 // ConstDeclaration :: |
| 1664 // const ConstBinding (',' ConstBinding)* ';' |
| 1665 // ConstBinding :: |
| 1666 // Identifier '=' AssignmentExpression |
| 1667 // |
| 1668 // TODO(ES6): |
| 1669 // ConstBinding :: |
| 1670 // BindingPattern '=' AssignmentExpression |
| 1650 VariableMode mode = VAR; | 1671 VariableMode mode = VAR; |
| 1651 // True if the binding needs initialization. 'let' and 'const' declared | 1672 // True if the binding needs initialization. 'let' and 'const' declared |
| 1652 // bindings are created uninitialized by their declaration nodes and | 1673 // bindings are created uninitialized by their declaration nodes and |
| 1653 // need initialization. 'var' declared bindings are always initialized | 1674 // need initialization. 'var' declared bindings are always initialized |
| 1654 // immediately by their declaration nodes. | 1675 // immediately by their declaration nodes. |
| 1655 bool needs_init = false; | 1676 bool needs_init = false; |
| 1656 bool is_const = false; | 1677 bool is_const = false; |
| 1657 Token::Value init_op = Token::INIT_VAR; | 1678 Token::Value init_op = Token::INIT_VAR; |
| 1658 if (peek() == Token::VAR) { | 1679 if (peek() == Token::VAR) { |
| 1659 Consume(Token::VAR); | 1680 Consume(Token::VAR); |
| 1660 } else if (peek() == Token::CONST) { | 1681 } else if (peek() == Token::CONST) { |
| 1661 Consume(Token::CONST); | 1682 Consume(Token::CONST); |
| 1662 if (top_scope_->is_strict_mode()) { | 1683 if (harmony_scoping_) { |
| 1684 if (var_context != kSourceElement && |
| 1685 var_context != kForStatement) { |
| 1686 // In harmony mode 'const' declarations are only allowed in source |
| 1687 // element positions. |
| 1688 ReportMessage("unprotected_const", Vector<const char*>::empty()); |
| 1689 *ok = false; |
| 1690 return NULL; |
| 1691 } |
| 1692 mode = CONST_HARMONY; |
| 1693 init_op = Token::INIT_CONST_HARMONY; |
| 1694 } else if (top_scope_->is_strict_mode()) { |
| 1663 ReportMessage("strict_const", Vector<const char*>::empty()); | 1695 ReportMessage("strict_const", Vector<const char*>::empty()); |
| 1664 *ok = false; | 1696 *ok = false; |
| 1665 return NULL; | 1697 return NULL; |
| 1698 } else { |
| 1699 mode = CONST; |
| 1700 init_op = Token::INIT_CONST; |
| 1666 } | 1701 } |
| 1667 mode = CONST; | |
| 1668 is_const = true; | 1702 is_const = true; |
| 1669 needs_init = true; | 1703 needs_init = true; |
| 1670 init_op = Token::INIT_CONST; | |
| 1671 } else if (peek() == Token::LET) { | 1704 } else if (peek() == Token::LET) { |
| 1672 Consume(Token::LET); | 1705 Consume(Token::LET); |
| 1673 if (var_context != kSourceElement && | 1706 if (var_context != kSourceElement && |
| 1674 var_context != kForStatement) { | 1707 var_context != kForStatement) { |
| 1708 // Let declarations are only allowed in source element positions. |
| 1675 ASSERT(var_context == kStatement); | 1709 ASSERT(var_context == kStatement); |
| 1676 ReportMessage("unprotected_let", Vector<const char*>::empty()); | 1710 ReportMessage("unprotected_let", Vector<const char*>::empty()); |
| 1677 *ok = false; | 1711 *ok = false; |
| 1678 return NULL; | 1712 return NULL; |
| 1679 } | 1713 } |
| 1680 mode = LET; | 1714 mode = LET; |
| 1681 needs_init = true; | 1715 needs_init = true; |
| 1682 init_op = Token::INIT_LET; | 1716 init_op = Token::INIT_LET; |
| 1683 } else { | 1717 } else { |
| 1684 UNREACHABLE(); // by current callers | 1718 UNREACHABLE(); // by current callers |
| 1685 } | 1719 } |
| 1686 | 1720 |
| 1687 Scope* declaration_scope = (mode == LET) | 1721 Scope* declaration_scope = (mode == LET || mode == CONST_HARMONY) |
| 1688 ? top_scope_ : top_scope_->DeclarationScope(); | 1722 ? top_scope_ : top_scope_->DeclarationScope(); |
| 1689 // The scope of a var/const declared variable anywhere inside a function | 1723 // The scope of a var/const declared variable anywhere inside a function |
| 1690 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can | 1724 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can |
| 1691 // transform a source-level var/const declaration into a (Function) | 1725 // transform a source-level var/const declaration into a (Function) |
| 1692 // Scope declaration, and rewrite the source-level initialization into an | 1726 // Scope declaration, and rewrite the source-level initialization into an |
| 1693 // assignment statement. We use a block to collect multiple assignments. | 1727 // assignment statement. We use a block to collect multiple assignments. |
| 1694 // | 1728 // |
| 1695 // We mark the block as initializer block because we don't want the | 1729 // We mark the block as initializer block because we don't want the |
| 1696 // rewriter to add a '.result' assignment to such a block (to get compliant | 1730 // rewriter to add a '.result' assignment to such a block (to get compliant |
| 1697 // behavior for code such as print(eval('var x = 7')), and for cosmetic | 1731 // behavior for code such as print(eval('var x = 7')), and for cosmetic |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1722 // assignment for variables and constants because the value must be assigned | 1756 // assignment for variables and constants because the value must be assigned |
| 1723 // when the variable is encountered in the source. But the variable/constant | 1757 // when the variable is encountered in the source. But the variable/constant |
| 1724 // is declared (and set to 'undefined') upon entering the function within | 1758 // is declared (and set to 'undefined') upon entering the function within |
| 1725 // which the variable or constant is declared. Only function variables have | 1759 // which the variable or constant is declared. Only function variables have |
| 1726 // an initial value in the declaration (because they are initialized upon | 1760 // an initial value in the declaration (because they are initialized upon |
| 1727 // entering the function). | 1761 // entering the function). |
| 1728 // | 1762 // |
| 1729 // If we have a const declaration, in an inner scope, the proxy is always | 1763 // If we have a const declaration, in an inner scope, the proxy is always |
| 1730 // bound to the declared variable (independent of possibly surrounding with | 1764 // bound to the declared variable (independent of possibly surrounding with |
| 1731 // statements). | 1765 // statements). |
| 1732 Declare(name, mode, NULL, is_const /* always bound for CONST! */, | 1766 // For let/const declarations in harmony mode, we can also immediately |
| 1733 CHECK_OK); | 1767 // pre-resolve the proxy because it resides in the same scope as the |
| 1768 // declaration. |
| 1769 Declare(name, mode, NULL, mode != VAR, CHECK_OK); |
| 1734 nvars++; | 1770 nvars++; |
| 1735 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { | 1771 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { |
| 1736 ReportMessageAt(scanner().location(), "too_many_variables", | 1772 ReportMessageAt(scanner().location(), "too_many_variables", |
| 1737 Vector<const char*>::empty()); | 1773 Vector<const char*>::empty()); |
| 1738 *ok = false; | 1774 *ok = false; |
| 1739 return NULL; | 1775 return NULL; |
| 1740 } | 1776 } |
| 1741 | 1777 |
| 1742 // Parse initialization expression if present and/or needed. A | 1778 // Parse initialization expression if present and/or needed. A |
| 1743 // declaration of the form: | 1779 // declaration of the form: |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1762 // | 1798 // |
| 1763 // const c; c = x; | 1799 // const c; c = x; |
| 1764 // | 1800 // |
| 1765 // The "variable" c initialized to x is the same as the declared | 1801 // The "variable" c initialized to x is the same as the declared |
| 1766 // one - there is no re-lookup (see the last parameter of the | 1802 // one - there is no re-lookup (see the last parameter of the |
| 1767 // Declare() call above). | 1803 // Declare() call above). |
| 1768 | 1804 |
| 1769 Scope* initialization_scope = is_const ? declaration_scope : top_scope_; | 1805 Scope* initialization_scope = is_const ? declaration_scope : top_scope_; |
| 1770 Expression* value = NULL; | 1806 Expression* value = NULL; |
| 1771 int position = -1; | 1807 int position = -1; |
| 1772 if (peek() == Token::ASSIGN) { | 1808 // Harmony consts have non-optional initializers. |
| 1809 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) { |
| 1773 Expect(Token::ASSIGN, CHECK_OK); | 1810 Expect(Token::ASSIGN, CHECK_OK); |
| 1774 position = scanner().location().beg_pos; | 1811 position = scanner().location().beg_pos; |
| 1775 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 1812 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
| 1776 // Don't infer if it is "a = function(){...}();"-like expression. | 1813 // Don't infer if it is "a = function(){...}();"-like expression. |
| 1777 if (fni_ != NULL && | 1814 if (fni_ != NULL && |
| 1778 value->AsCall() == NULL && | 1815 value->AsCall() == NULL && |
| 1779 value->AsCallNew() == NULL) { | 1816 value->AsCallNew() == NULL) { |
| 1780 fni_->Infer(); | 1817 fni_->Infer(); |
| 1781 } else { | 1818 } else { |
| 1782 fni_->RemoveLastFunction(); | 1819 fni_->RemoveLastFunction(); |
| 1783 } | 1820 } |
| 1821 if (decl_props != NULL) *decl_props = kHasInitializers; |
| 1784 } | 1822 } |
| 1785 | 1823 |
| 1786 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. | 1824 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. |
| 1787 if (value == NULL && needs_init) { | 1825 if (value == NULL && needs_init) { |
| 1788 value = GetLiteralUndefined(); | 1826 value = GetLiteralUndefined(); |
| 1789 } | 1827 } |
| 1790 | 1828 |
| 1791 // Global variable declarations must be compiled in a specific | 1829 // Global variable declarations must be compiled in a specific |
| 1792 // way. When the script containing the global variable declaration | 1830 // way. When the script containing the global variable declaration |
| 1793 // is entered, the global variable must be declared, so that if it | 1831 // is entered, the global variable must be declared, so that if it |
| 1794 // doesn't exist (not even in a prototype of the global object) it | 1832 // doesn't exist (not even in a prototype of the global object) it |
| 1795 // gets created with an initial undefined value. This is handled | 1833 // gets created with an initial undefined value. This is handled |
| 1796 // by the declarations part of the function representing the | 1834 // by the declarations part of the function representing the |
| 1797 // top-level global code; see Runtime::DeclareGlobalVariable. If | 1835 // top-level global code; see Runtime::DeclareGlobalVariable. If |
| 1798 // it already exists (in the object or in a prototype), it is | 1836 // it already exists (in the object or in a prototype), it is |
| 1799 // *not* touched until the variable declaration statement is | 1837 // *not* touched until the variable declaration statement is |
| 1800 // executed. | 1838 // executed. |
| 1801 // | 1839 // |
| 1802 // Executing the variable declaration statement will always | 1840 // Executing the variable declaration statement will always |
| 1803 // guarantee to give the global object a "local" variable; a | 1841 // guarantee to give the global object a "local" variable; a |
| 1804 // variable defined in the global object and not in any | 1842 // variable defined in the global object and not in any |
| 1805 // prototype. This way, global variable declarations can shadow | 1843 // prototype. This way, global variable declarations can shadow |
| 1806 // properties in the prototype chain, but only after the variable | 1844 // properties in the prototype chain, but only after the variable |
| 1807 // declaration statement has been executed. This is important in | 1845 // declaration statement has been executed. This is important in |
| 1808 // browsers where the global object (window) has lots of | 1846 // browsers where the global object (window) has lots of |
| 1809 // properties defined in prototype objects. | 1847 // properties defined in prototype objects. |
| 1810 | |
| 1811 if (initialization_scope->is_global_scope()) { | 1848 if (initialization_scope->is_global_scope()) { |
| 1812 // Compute the arguments for the runtime call. | 1849 // Compute the arguments for the runtime call. |
| 1813 ZoneList<Expression*>* arguments = new(zone()) ZoneList<Expression*>(3); | 1850 ZoneList<Expression*>* arguments = new(zone()) ZoneList<Expression*>(3); |
| 1814 // We have at least 1 parameter. | 1851 // We have at least 1 parameter. |
| 1815 arguments->Add(NewLiteral(name)); | 1852 arguments->Add(NewLiteral(name)); |
| 1816 CallRuntime* initialize; | 1853 CallRuntime* initialize; |
| 1817 | 1854 |
| 1818 if (is_const) { | 1855 if (is_const) { |
| 1819 arguments->Add(value); | 1856 arguments->Add(value); |
| 1820 value = NULL; // zap the value to avoid the unnecessary assignment | 1857 value = NULL; // zap the value to avoid the unnecessary assignment |
| 1821 | 1858 |
| 1822 // Construct the call to Runtime_InitializeConstGlobal | 1859 // Construct the call to Runtime_InitializeConstGlobal |
| 1823 // and add it to the initialization statement block. | 1860 // and add it to the initialization statement block. |
| 1824 // Note that the function does different things depending on | 1861 // Note that the function does different things depending on |
| 1825 // the number of arguments (1 or 2). | 1862 // the number of arguments (1 or 2). |
| 1826 initialize = | 1863 initialize = |
| 1827 new(zone()) CallRuntime( | 1864 new(zone()) CallRuntime( |
| 1828 isolate(), | 1865 isolate(), |
| 1829 isolate()->factory()->InitializeConstGlobal_symbol(), | 1866 isolate()->factory()->InitializeConstGlobal_symbol(), |
| 1830 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), | 1867 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), |
| 1831 arguments); | 1868 arguments); |
| 1832 } else { | 1869 } else { |
| 1833 // Add strict mode. | 1870 // Add strict mode. |
| 1834 // We may want to pass singleton to avoid Literal allocations. | 1871 // We may want to pass singleton to avoid Literal allocations. |
| 1835 StrictModeFlag flag = initialization_scope->is_strict_mode() | 1872 StrictModeFlag flag = initialization_scope->strict_mode_flag(); |
| 1836 ? kStrictMode | |
| 1837 : kNonStrictMode; | |
| 1838 arguments->Add(NewNumberLiteral(flag)); | 1873 arguments->Add(NewNumberLiteral(flag)); |
| 1839 | 1874 |
| 1840 // Be careful not to assign a value to the global variable if | 1875 // Be careful not to assign a value to the global variable if |
| 1841 // we're in a with. The initialization value should not | 1876 // we're in a with. The initialization value should not |
| 1842 // necessarily be stored in the global object in that case, | 1877 // necessarily be stored in the global object in that case, |
| 1843 // which is why we need to generate a separate assignment node. | 1878 // which is why we need to generate a separate assignment node. |
| 1844 if (value != NULL && !inside_with()) { | 1879 if (value != NULL && !inside_with()) { |
| 1845 arguments->Add(value); | 1880 arguments->Add(value); |
| 1846 value = NULL; // zap the value to avoid the unnecessary assignment | 1881 value = NULL; // zap the value to avoid the unnecessary assignment |
| 1847 } | 1882 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1864 // Add an assignment node to the initialization statement block if we still | 1899 // Add an assignment node to the initialization statement block if we still |
| 1865 // have a pending initialization value. We must distinguish between | 1900 // have a pending initialization value. We must distinguish between |
| 1866 // different kinds of declarations: 'var' initializations are simply | 1901 // different kinds of declarations: 'var' initializations are simply |
| 1867 // assignments (with all the consequences if they are inside a 'with' | 1902 // assignments (with all the consequences if they are inside a 'with' |
| 1868 // statement - they may change a 'with' object property). Constant | 1903 // statement - they may change a 'with' object property). Constant |
| 1869 // initializations always assign to the declared constant which is | 1904 // initializations always assign to the declared constant which is |
| 1870 // always at the function scope level. This is only relevant for | 1905 // always at the function scope level. This is only relevant for |
| 1871 // dynamically looked-up variables and constants (the start context | 1906 // dynamically looked-up variables and constants (the start context |
| 1872 // for constant lookups is always the function context, while it is | 1907 // for constant lookups is always the function context, while it is |
| 1873 // the top context for var declared variables). Sigh... | 1908 // the top context for var declared variables). Sigh... |
| 1874 // For 'let' declared variables the initialization is in the same scope | 1909 // For 'let' and 'const' declared variables in harmony mode the |
| 1875 // as the declaration. Thus dynamic lookups are unnecessary even if the | 1910 // initialization is in the same scope as the declaration. Thus dynamic |
| 1876 // block scope is inside a with. | 1911 // lookups are unnecessary even if the block scope is inside a with. |
| 1877 if (value != NULL) { | 1912 if (value != NULL) { |
| 1878 bool in_with = (mode == VAR) ? inside_with() : false; | 1913 VariableProxy* proxy = initialization_scope->NewUnresolved(name); |
| 1879 VariableProxy* proxy = | |
| 1880 initialization_scope->NewUnresolved(name, in_with); | |
| 1881 Assignment* assignment = | 1914 Assignment* assignment = |
| 1882 new(zone()) Assignment(isolate(), init_op, proxy, value, position); | 1915 new(zone()) Assignment(isolate(), init_op, proxy, value, position); |
| 1883 if (block) { | 1916 block->AddStatement(new(zone()) ExpressionStatement(assignment)); |
| 1884 block->AddStatement(new(zone()) ExpressionStatement(assignment)); | |
| 1885 } | |
| 1886 } | 1917 } |
| 1887 | 1918 |
| 1888 if (fni_ != NULL) fni_->Leave(); | 1919 if (fni_ != NULL) fni_->Leave(); |
| 1889 } while (peek() == Token::COMMA); | 1920 } while (peek() == Token::COMMA); |
| 1890 | 1921 |
| 1891 // If there was a single non-const declaration, return it in the output | 1922 // If there was a single non-const declaration, return it in the output |
| 1892 // parameter for possible use by for/in. | 1923 // parameter for possible use by for/in. |
| 1893 if (nvars == 1 && !is_const) { | 1924 if (nvars == 1 && !is_const) { |
| 1894 *out = name; | 1925 *out = name; |
| 1895 } | 1926 } |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2098 if (top_scope_->is_strict_mode()) { | 2129 if (top_scope_->is_strict_mode()) { |
| 2099 ReportMessage("strict_mode_with", Vector<const char*>::empty()); | 2130 ReportMessage("strict_mode_with", Vector<const char*>::empty()); |
| 2100 *ok = false; | 2131 *ok = false; |
| 2101 return NULL; | 2132 return NULL; |
| 2102 } | 2133 } |
| 2103 | 2134 |
| 2104 Expect(Token::LPAREN, CHECK_OK); | 2135 Expect(Token::LPAREN, CHECK_OK); |
| 2105 Expression* expr = ParseExpression(true, CHECK_OK); | 2136 Expression* expr = ParseExpression(true, CHECK_OK); |
| 2106 Expect(Token::RPAREN, CHECK_OK); | 2137 Expect(Token::RPAREN, CHECK_OK); |
| 2107 | 2138 |
| 2108 ++with_nesting_level_; | |
| 2109 top_scope_->DeclarationScope()->RecordWithStatement(); | 2139 top_scope_->DeclarationScope()->RecordWithStatement(); |
| 2110 Statement* stmt = ParseStatement(labels, CHECK_OK); | 2140 Scope* with_scope = NewScope(top_scope_, WITH_SCOPE); |
| 2111 --with_nesting_level_; | 2141 Statement* stmt; |
| 2142 { SaveScope save_scope(this, with_scope); |
| 2143 with_scope->set_start_position(scanner().peek_location().beg_pos); |
| 2144 stmt = ParseStatement(labels, CHECK_OK); |
| 2145 with_scope->set_end_position(scanner().location().end_pos); |
| 2146 } |
| 2112 return new(zone()) WithStatement(expr, stmt); | 2147 return new(zone()) WithStatement(expr, stmt); |
| 2113 } | 2148 } |
| 2114 | 2149 |
| 2115 | 2150 |
| 2116 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { | 2151 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { |
| 2117 // CaseClause :: | 2152 // CaseClause :: |
| 2118 // 'case' Expression ':' Statement* | 2153 // 'case' Expression ':' Statement* |
| 2119 // 'default' ':' Statement* | 2154 // 'default' ':' Statement* |
| 2120 | 2155 |
| 2121 Expression* label = NULL; // NULL expression indicates default case | 2156 Expression* label = NULL; // NULL expression indicates default case |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2226 // always collect the targets. | 2261 // always collect the targets. |
| 2227 TargetCollector catch_collector; | 2262 TargetCollector catch_collector; |
| 2228 Scope* catch_scope = NULL; | 2263 Scope* catch_scope = NULL; |
| 2229 Variable* catch_variable = NULL; | 2264 Variable* catch_variable = NULL; |
| 2230 Block* catch_block = NULL; | 2265 Block* catch_block = NULL; |
| 2231 Handle<String> name; | 2266 Handle<String> name; |
| 2232 if (tok == Token::CATCH) { | 2267 if (tok == Token::CATCH) { |
| 2233 Consume(Token::CATCH); | 2268 Consume(Token::CATCH); |
| 2234 | 2269 |
| 2235 Expect(Token::LPAREN, CHECK_OK); | 2270 Expect(Token::LPAREN, CHECK_OK); |
| 2271 catch_scope = NewScope(top_scope_, CATCH_SCOPE); |
| 2272 catch_scope->set_start_position(scanner().location().beg_pos); |
| 2236 name = ParseIdentifier(CHECK_OK); | 2273 name = ParseIdentifier(CHECK_OK); |
| 2237 | 2274 |
| 2238 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { | 2275 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { |
| 2239 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); | 2276 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); |
| 2240 *ok = false; | 2277 *ok = false; |
| 2241 return NULL; | 2278 return NULL; |
| 2242 } | 2279 } |
| 2243 | 2280 |
| 2244 Expect(Token::RPAREN, CHECK_OK); | 2281 Expect(Token::RPAREN, CHECK_OK); |
| 2245 | 2282 |
| 2246 if (peek() == Token::LBRACE) { | 2283 if (peek() == Token::LBRACE) { |
| 2247 Target target(&this->target_stack_, &catch_collector); | 2284 Target target(&this->target_stack_, &catch_collector); |
| 2248 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with()); | |
| 2249 if (top_scope_->is_strict_mode()) { | |
| 2250 catch_scope->EnableStrictMode(); | |
| 2251 } | |
| 2252 VariableMode mode = harmony_scoping_ ? LET : VAR; | 2285 VariableMode mode = harmony_scoping_ ? LET : VAR; |
| 2253 catch_variable = catch_scope->DeclareLocal(name, mode); | 2286 catch_variable = catch_scope->DeclareLocal(name, mode); |
| 2254 | 2287 |
| 2255 Scope* saved_scope = top_scope_; | 2288 SaveScope save_scope(this, catch_scope); |
| 2256 top_scope_ = catch_scope; | |
| 2257 catch_block = ParseBlock(NULL, CHECK_OK); | 2289 catch_block = ParseBlock(NULL, CHECK_OK); |
| 2258 top_scope_ = saved_scope; | |
| 2259 } else { | 2290 } else { |
| 2260 Expect(Token::LBRACE, CHECK_OK); | 2291 Expect(Token::LBRACE, CHECK_OK); |
| 2261 } | 2292 } |
| 2262 | 2293 catch_scope->set_end_position(scanner().location().end_pos); |
| 2263 tok = peek(); | 2294 tok = peek(); |
| 2264 } | 2295 } |
| 2265 | 2296 |
| 2266 Block* finally_block = NULL; | 2297 Block* finally_block = NULL; |
| 2267 if (tok == Token::FINALLY || catch_block == NULL) { | 2298 if (tok == Token::FINALLY || catch_block == NULL) { |
| 2268 Consume(Token::FINALLY); | 2299 Consume(Token::FINALLY); |
| 2269 finally_block = ParseBlock(NULL, CHECK_OK); | 2300 finally_block = ParseBlock(NULL, CHECK_OK); |
| 2270 } | 2301 } |
| 2271 | 2302 |
| 2272 // Simplify the AST nodes by converting: | 2303 // Simplify the AST nodes by converting: |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2358 return loop; | 2389 return loop; |
| 2359 } | 2390 } |
| 2360 | 2391 |
| 2361 | 2392 |
| 2362 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 2393 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
| 2363 // ForStatement :: | 2394 // ForStatement :: |
| 2364 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 2395 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 2365 | 2396 |
| 2366 Statement* init = NULL; | 2397 Statement* init = NULL; |
| 2367 | 2398 |
| 2399 // Create an in-between scope for let-bound iteration variables. |
| 2400 Scope* saved_scope = top_scope_; |
| 2401 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); |
| 2402 top_scope_ = for_scope; |
| 2403 |
| 2368 Expect(Token::FOR, CHECK_OK); | 2404 Expect(Token::FOR, CHECK_OK); |
| 2369 Expect(Token::LPAREN, CHECK_OK); | 2405 Expect(Token::LPAREN, CHECK_OK); |
| 2406 for_scope->set_start_position(scanner().location().beg_pos); |
| 2370 if (peek() != Token::SEMICOLON) { | 2407 if (peek() != Token::SEMICOLON) { |
| 2371 if (peek() == Token::VAR || peek() == Token::CONST) { | 2408 if (peek() == Token::VAR || peek() == Token::CONST) { |
| 2372 Handle<String> name; | 2409 Handle<String> name; |
| 2373 Block* variable_statement = | 2410 Block* variable_statement = |
| 2374 ParseVariableDeclarations(kForStatement, &name, CHECK_OK); | 2411 ParseVariableDeclarations(kForStatement, NULL, &name, CHECK_OK); |
| 2375 | 2412 |
| 2376 if (peek() == Token::IN && !name.is_null()) { | 2413 if (peek() == Token::IN && !name.is_null()) { |
| 2377 VariableProxy* each = top_scope_->NewUnresolved(name, inside_with()); | 2414 VariableProxy* each = top_scope_->NewUnresolved(name); |
| 2378 ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels); | 2415 ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels); |
| 2379 Target target(&this->target_stack_, loop); | 2416 Target target(&this->target_stack_, loop); |
| 2380 | 2417 |
| 2381 Expect(Token::IN, CHECK_OK); | 2418 Expect(Token::IN, CHECK_OK); |
| 2382 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2419 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2383 Expect(Token::RPAREN, CHECK_OK); | 2420 Expect(Token::RPAREN, CHECK_OK); |
| 2384 | 2421 |
| 2385 Statement* body = ParseStatement(NULL, CHECK_OK); | 2422 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2386 loop->Initialize(each, enumerable, body); | 2423 loop->Initialize(each, enumerable, body); |
| 2387 Block* result = new(zone()) Block(isolate(), NULL, 2, false); | 2424 Block* result = new(zone()) Block(isolate(), NULL, 2, false); |
| 2388 result->AddStatement(variable_statement); | 2425 result->AddStatement(variable_statement); |
| 2389 result->AddStatement(loop); | 2426 result->AddStatement(loop); |
| 2427 top_scope_ = saved_scope; |
| 2428 for_scope->set_end_position(scanner().location().end_pos); |
| 2429 for_scope = for_scope->FinalizeBlockScope(); |
| 2430 ASSERT(for_scope == NULL); |
| 2390 // Parsed for-in loop w/ variable/const declaration. | 2431 // Parsed for-in loop w/ variable/const declaration. |
| 2391 return result; | 2432 return result; |
| 2392 } else { | 2433 } else { |
| 2393 init = variable_statement; | 2434 init = variable_statement; |
| 2394 } | 2435 } |
| 2436 } else if (peek() == Token::LET) { |
| 2437 Handle<String> name; |
| 2438 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 2439 Block* variable_statement = |
| 2440 ParseVariableDeclarations(kForStatement, |
| 2441 &decl_props, |
| 2442 &name, |
| 2443 CHECK_OK); |
| 2444 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; |
| 2445 if (peek() == Token::IN && accept_IN) { |
| 2446 // Rewrite a for-in statement of the form |
| 2447 // |
| 2448 // for (let x in e) b |
| 2449 // |
| 2450 // into |
| 2451 // |
| 2452 // <let x' be a temporary variable> |
| 2453 // for (x' in e) { |
| 2454 // let x; |
| 2455 // x = x'; |
| 2456 // b; |
| 2457 // } |
| 2395 | 2458 |
| 2459 // TODO(keuchel): Move the temporary variable to the block scope, after |
| 2460 // implementing stack allocated block scoped variables. |
| 2461 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(name); |
| 2462 VariableProxy* temp_proxy = new(zone()) VariableProxy(isolate(), temp); |
| 2463 VariableProxy* each = top_scope_->NewUnresolved(name, inside_with()); |
| 2464 ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels); |
| 2465 Target target(&this->target_stack_, loop); |
| 2466 |
| 2467 Expect(Token::IN, CHECK_OK); |
| 2468 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2469 Expect(Token::RPAREN, CHECK_OK); |
| 2470 |
| 2471 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2472 Block* body_block = new(zone()) Block(isolate(), NULL, 3, false); |
| 2473 Assignment* assignment = new(zone()) Assignment(isolate(), |
| 2474 Token::ASSIGN, |
| 2475 each, |
| 2476 temp_proxy, |
| 2477 RelocInfo::kNoPosition); |
| 2478 Statement* assignment_statement = |
| 2479 new(zone()) ExpressionStatement(assignment); |
| 2480 body_block->AddStatement(variable_statement); |
| 2481 body_block->AddStatement(assignment_statement); |
| 2482 body_block->AddStatement(body); |
| 2483 loop->Initialize(temp_proxy, enumerable, body_block); |
| 2484 top_scope_ = saved_scope; |
| 2485 for_scope->set_end_position(scanner().location().end_pos); |
| 2486 for_scope = for_scope->FinalizeBlockScope(); |
| 2487 body_block->set_block_scope(for_scope); |
| 2488 // Parsed for-in loop w/ let declaration. |
| 2489 return loop; |
| 2490 |
| 2491 } else { |
| 2492 init = variable_statement; |
| 2493 } |
| 2396 } else { | 2494 } else { |
| 2397 Expression* expression = ParseExpression(false, CHECK_OK); | 2495 Expression* expression = ParseExpression(false, CHECK_OK); |
| 2398 if (peek() == Token::IN) { | 2496 if (peek() == Token::IN) { |
| 2399 // Signal a reference error if the expression is an invalid | 2497 // Signal a reference error if the expression is an invalid |
| 2400 // left-hand side expression. We could report this as a syntax | 2498 // left-hand side expression. We could report this as a syntax |
| 2401 // error here but for compatibility with JSC we choose to report | 2499 // error here but for compatibility with JSC we choose to report |
| 2402 // the error at runtime. | 2500 // the error at runtime. |
| 2403 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2501 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2404 Handle<String> type = | 2502 Handle<String> type = |
| 2405 isolate()->factory()->invalid_lhs_in_for_in_symbol(); | 2503 isolate()->factory()->invalid_lhs_in_for_in_symbol(); |
| 2406 expression = NewThrowReferenceError(type); | 2504 expression = NewThrowReferenceError(type); |
| 2407 } | 2505 } |
| 2408 ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels); | 2506 ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels); |
| 2409 Target target(&this->target_stack_, loop); | 2507 Target target(&this->target_stack_, loop); |
| 2410 | 2508 |
| 2411 Expect(Token::IN, CHECK_OK); | 2509 Expect(Token::IN, CHECK_OK); |
| 2412 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2510 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2413 Expect(Token::RPAREN, CHECK_OK); | 2511 Expect(Token::RPAREN, CHECK_OK); |
| 2414 | 2512 |
| 2415 Statement* body = ParseStatement(NULL, CHECK_OK); | 2513 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2416 if (loop) loop->Initialize(expression, enumerable, body); | 2514 if (loop) loop->Initialize(expression, enumerable, body); |
| 2515 top_scope_ = saved_scope; |
| 2516 for_scope->set_end_position(scanner().location().end_pos); |
| 2517 for_scope = for_scope->FinalizeBlockScope(); |
| 2518 ASSERT(for_scope == NULL); |
| 2417 // Parsed for-in loop. | 2519 // Parsed for-in loop. |
| 2418 return loop; | 2520 return loop; |
| 2419 | 2521 |
| 2420 } else { | 2522 } else { |
| 2421 init = new(zone()) ExpressionStatement(expression); | 2523 init = new(zone()) ExpressionStatement(expression); |
| 2422 } | 2524 } |
| 2423 } | 2525 } |
| 2424 } | 2526 } |
| 2425 | 2527 |
| 2426 // Standard 'for' loop | 2528 // Standard 'for' loop |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2437 Expect(Token::SEMICOLON, CHECK_OK); | 2539 Expect(Token::SEMICOLON, CHECK_OK); |
| 2438 | 2540 |
| 2439 Statement* next = NULL; | 2541 Statement* next = NULL; |
| 2440 if (peek() != Token::RPAREN) { | 2542 if (peek() != Token::RPAREN) { |
| 2441 Expression* exp = ParseExpression(true, CHECK_OK); | 2543 Expression* exp = ParseExpression(true, CHECK_OK); |
| 2442 next = new(zone()) ExpressionStatement(exp); | 2544 next = new(zone()) ExpressionStatement(exp); |
| 2443 } | 2545 } |
| 2444 Expect(Token::RPAREN, CHECK_OK); | 2546 Expect(Token::RPAREN, CHECK_OK); |
| 2445 | 2547 |
| 2446 Statement* body = ParseStatement(NULL, CHECK_OK); | 2548 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2447 if (loop) loop->Initialize(init, cond, next, body); | 2549 top_scope_ = saved_scope; |
| 2448 return loop; | 2550 for_scope->set_end_position(scanner().location().end_pos); |
| 2551 for_scope = for_scope->FinalizeBlockScope(); |
| 2552 if (for_scope != NULL) { |
| 2553 // Rewrite a for statement of the form |
| 2554 // |
| 2555 // for (let x = i; c; n) b |
| 2556 // |
| 2557 // into |
| 2558 // |
| 2559 // { |
| 2560 // let x = i; |
| 2561 // for (; c; n) b |
| 2562 // } |
| 2563 ASSERT(init != NULL); |
| 2564 Block* result = new(zone()) Block(isolate(), NULL, 2, false); |
| 2565 result->AddStatement(init); |
| 2566 result->AddStatement(loop); |
| 2567 result->set_block_scope(for_scope); |
| 2568 if (loop) loop->Initialize(NULL, cond, next, body); |
| 2569 return result; |
| 2570 } else { |
| 2571 if (loop) loop->Initialize(init, cond, next, body); |
| 2572 return loop; |
| 2573 } |
| 2449 } | 2574 } |
| 2450 | 2575 |
| 2451 | 2576 |
| 2452 // Precedence = 1 | 2577 // Precedence = 1 |
| 2453 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { | 2578 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { |
| 2454 // Expression :: | 2579 // Expression :: |
| 2455 // AssignmentExpression | 2580 // AssignmentExpression |
| 2456 // Expression ',' AssignmentExpression | 2581 // Expression ',' AssignmentExpression |
| 2457 | 2582 |
| 2458 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2583 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| (...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3058 case Token::FALSE_LITERAL: | 3183 case Token::FALSE_LITERAL: |
| 3059 Consume(Token::FALSE_LITERAL); | 3184 Consume(Token::FALSE_LITERAL); |
| 3060 result = new(zone()) Literal( | 3185 result = new(zone()) Literal( |
| 3061 isolate(), isolate()->factory()->false_value()); | 3186 isolate(), isolate()->factory()->false_value()); |
| 3062 break; | 3187 break; |
| 3063 | 3188 |
| 3064 case Token::IDENTIFIER: | 3189 case Token::IDENTIFIER: |
| 3065 case Token::FUTURE_STRICT_RESERVED_WORD: { | 3190 case Token::FUTURE_STRICT_RESERVED_WORD: { |
| 3066 Handle<String> name = ParseIdentifier(CHECK_OK); | 3191 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 3067 if (fni_ != NULL) fni_->PushVariableName(name); | 3192 if (fni_ != NULL) fni_->PushVariableName(name); |
| 3068 result = top_scope_->NewUnresolved(name, | 3193 result = top_scope_->NewUnresolved(name, scanner().location().beg_pos); |
| 3069 inside_with(), | |
| 3070 scanner().location().beg_pos); | |
| 3071 break; | 3194 break; |
| 3072 } | 3195 } |
| 3073 | 3196 |
| 3074 case Token::NUMBER: { | 3197 case Token::NUMBER: { |
| 3075 Consume(Token::NUMBER); | 3198 Consume(Token::NUMBER); |
| 3076 ASSERT(scanner().is_literal_ascii()); | 3199 ASSERT(scanner().is_literal_ascii()); |
| 3077 double value = StringToDouble(isolate()->unicode_cache(), | 3200 double value = StringToDouble(isolate()->unicode_cache(), |
| 3078 scanner().literal_ascii_string(), | 3201 scanner().literal_ascii_string(), |
| 3079 ALLOW_HEX | ALLOW_OCTALS); | 3202 ALLOW_HEX | ALLOW_OCTALS); |
| 3080 result = NewNumberLiteral(value); | 3203 result = NewNumberLiteral(value); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3177 values->Add(elem); | 3300 values->Add(elem); |
| 3178 if (peek() != Token::RBRACK) { | 3301 if (peek() != Token::RBRACK) { |
| 3179 Expect(Token::COMMA, CHECK_OK); | 3302 Expect(Token::COMMA, CHECK_OK); |
| 3180 } | 3303 } |
| 3181 } | 3304 } |
| 3182 Expect(Token::RBRACK, CHECK_OK); | 3305 Expect(Token::RBRACK, CHECK_OK); |
| 3183 | 3306 |
| 3184 // Update the scope information before the pre-parsing bailout. | 3307 // Update the scope information before the pre-parsing bailout. |
| 3185 int literal_index = lexical_scope_->NextMaterializedLiteralIndex(); | 3308 int literal_index = lexical_scope_->NextMaterializedLiteralIndex(); |
| 3186 | 3309 |
| 3187 // Allocate a fixed array with all the literals. | 3310 // Allocate a fixed array to hold all the object literals. |
| 3188 Handle<FixedArray> literals = | 3311 Handle<FixedArray> object_literals = |
| 3189 isolate()->factory()->NewFixedArray(values->length(), TENURED); | 3312 isolate()->factory()->NewFixedArray(values->length(), TENURED); |
| 3313 Handle<FixedDoubleArray> double_literals; |
| 3314 ElementsKind elements_kind = FAST_SMI_ONLY_ELEMENTS; |
| 3190 | 3315 |
| 3191 // Fill in the literals. | 3316 // Fill in the literals. |
| 3192 bool is_simple = true; | 3317 bool is_simple = true; |
| 3193 int depth = 1; | 3318 int depth = 1; |
| 3194 for (int i = 0, n = values->length(); i < n; i++) { | 3319 for (int i = 0, n = values->length(); i < n; i++) { |
| 3195 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral(); | 3320 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral(); |
| 3196 if (m_literal != NULL && m_literal->depth() + 1 > depth) { | 3321 if (m_literal != NULL && m_literal->depth() + 1 > depth) { |
| 3197 depth = m_literal->depth() + 1; | 3322 depth = m_literal->depth() + 1; |
| 3198 } | 3323 } |
| 3199 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i)); | 3324 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i)); |
| 3200 if (boilerplate_value->IsUndefined()) { | 3325 if (boilerplate_value->IsUndefined()) { |
| 3201 literals->set_the_hole(i); | 3326 object_literals->set_the_hole(i); |
| 3327 if (elements_kind == FAST_DOUBLE_ELEMENTS) { |
| 3328 double_literals->set_the_hole(i); |
| 3329 } |
| 3202 is_simple = false; | 3330 is_simple = false; |
| 3203 } else { | 3331 } else { |
| 3204 literals->set(i, *boilerplate_value); | 3332 // Examine each literal element, and adjust the ElementsKind if the |
| 3333 // literal element is not of a type that can be stored in the current |
| 3334 // ElementsKind. Start with FAST_SMI_ONLY_ELEMENTS, and transition to |
| 3335 // FAST_DOUBLE_ELEMENTS and FAST_ELEMENTS as necessary. Always remember |
| 3336 // the tagged value, no matter what the ElementsKind is in case we |
| 3337 // ultimately end up in FAST_ELEMENTS. |
| 3338 object_literals->set(i, *boilerplate_value); |
| 3339 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { |
| 3340 // Smi only elements. Notice if a transition to FAST_DOUBLE_ELEMENTS or |
| 3341 // FAST_ELEMENTS is required. |
| 3342 if (!boilerplate_value->IsSmi()) { |
| 3343 if (boilerplate_value->IsNumber() && FLAG_smi_only_arrays) { |
| 3344 // Allocate a double array on the FAST_DOUBLE_ELEMENTS transition to |
| 3345 // avoid over-allocating in TENURED space. |
| 3346 double_literals = isolate()->factory()->NewFixedDoubleArray( |
| 3347 values->length(), TENURED); |
| 3348 // Copy the contents of the FAST_SMI_ONLY_ELEMENT array to the |
| 3349 // FAST_DOUBLE_ELEMENTS array so that they are in sync. |
| 3350 for (int j = 0; j < i; ++j) { |
| 3351 Object* smi_value = object_literals->get(j); |
| 3352 if (smi_value->IsTheHole()) { |
| 3353 double_literals->set_the_hole(j); |
| 3354 } else { |
| 3355 double_literals->set(j, Smi::cast(smi_value)->value()); |
| 3356 } |
| 3357 } |
| 3358 double_literals->set(i, boilerplate_value->Number()); |
| 3359 elements_kind = FAST_DOUBLE_ELEMENTS; |
| 3360 } else { |
| 3361 elements_kind = FAST_ELEMENTS; |
| 3362 } |
| 3363 } |
| 3364 } else if (elements_kind == FAST_DOUBLE_ELEMENTS) { |
| 3365 // Continue to store double values in to FAST_DOUBLE_ELEMENTS arrays |
| 3366 // until the first value is seen that can't be stored as a double. |
| 3367 if (boilerplate_value->IsNumber()) { |
| 3368 double_literals->set(i, boilerplate_value->Number()); |
| 3369 } else { |
| 3370 elements_kind = FAST_ELEMENTS; |
| 3371 } |
| 3372 } |
| 3205 } | 3373 } |
| 3206 } | 3374 } |
| 3207 | 3375 |
| 3208 // Simple and shallow arrays can be lazily copied, we transform the | 3376 // Simple and shallow arrays can be lazily copied, we transform the |
| 3209 // elements array to a copy-on-write array. | 3377 // elements array to a copy-on-write array. |
| 3210 if (is_simple && depth == 1 && values->length() > 0) { | 3378 if (is_simple && depth == 1 && values->length() > 0 && |
| 3211 literals->set_map(isolate()->heap()->fixed_cow_array_map()); | 3379 elements_kind != FAST_DOUBLE_ELEMENTS) { |
| 3380 object_literals->set_map(isolate()->heap()->fixed_cow_array_map()); |
| 3212 } | 3381 } |
| 3213 | 3382 |
| 3383 Handle<FixedArrayBase> element_values = elements_kind == FAST_DOUBLE_ELEMENTS |
| 3384 ? Handle<FixedArrayBase>(double_literals) |
| 3385 : Handle<FixedArrayBase>(object_literals); |
| 3386 |
| 3387 // Remember both the literal's constant values as well as the ElementsKind |
| 3388 // in a 2-element FixedArray. |
| 3389 Handle<FixedArray> literals = |
| 3390 isolate()->factory()->NewFixedArray(2, TENURED); |
| 3391 |
| 3392 literals->set(0, Smi::FromInt(elements_kind)); |
| 3393 literals->set(1, *element_values); |
| 3394 |
| 3214 return new(zone()) ArrayLiteral( | 3395 return new(zone()) ArrayLiteral( |
| 3215 isolate(), literals, values, literal_index, is_simple, depth); | 3396 isolate(), literals, values, literal_index, is_simple, depth); |
| 3216 } | 3397 } |
| 3217 | 3398 |
| 3218 | 3399 |
| 3219 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { | 3400 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { |
| 3220 return property != NULL && | 3401 return property != NULL && |
| 3221 property->kind() != ObjectLiteral::Property::PROTOTYPE; | 3402 property->kind() != ObjectLiteral::Property::PROTOTYPE; |
| 3222 } | 3403 } |
| 3223 | 3404 |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3708 // We want a non-null handle as the function name. | 3889 // We want a non-null handle as the function name. |
| 3709 if (should_infer_name) { | 3890 if (should_infer_name) { |
| 3710 function_name = isolate()->factory()->empty_symbol(); | 3891 function_name = isolate()->factory()->empty_symbol(); |
| 3711 } | 3892 } |
| 3712 | 3893 |
| 3713 int num_parameters = 0; | 3894 int num_parameters = 0; |
| 3714 // Function declarations are function scoped in normal mode, so they are | 3895 // Function declarations are function scoped in normal mode, so they are |
| 3715 // hoisted. In harmony block scoping mode they are block scoped, so they | 3896 // hoisted. In harmony block scoping mode they are block scoped, so they |
| 3716 // are not hoisted. | 3897 // are not hoisted. |
| 3717 Scope* scope = (type == FunctionLiteral::DECLARATION && !harmony_scoping_) | 3898 Scope* scope = (type == FunctionLiteral::DECLARATION && !harmony_scoping_) |
| 3718 ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false) | 3899 ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE) |
| 3719 : NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); | 3900 : NewScope(top_scope_, FUNCTION_SCOPE); |
| 3720 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8); | 3901 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8); |
| 3721 int materialized_literal_count; | 3902 int materialized_literal_count; |
| 3722 int expected_property_count; | 3903 int expected_property_count; |
| 3723 int start_pos; | |
| 3724 int end_pos; | |
| 3725 bool only_simple_this_property_assignments; | 3904 bool only_simple_this_property_assignments; |
| 3726 Handle<FixedArray> this_property_assignments; | 3905 Handle<FixedArray> this_property_assignments; |
| 3727 bool has_duplicate_parameters = false; | 3906 bool has_duplicate_parameters = false; |
| 3728 // Parse function body. | 3907 // Parse function body. |
| 3729 { LexicalScope lexical_scope(this, scope, isolate()); | 3908 { LexicalScope lexical_scope(this, scope, isolate()); |
| 3730 top_scope_->SetScopeName(function_name); | 3909 top_scope_->SetScopeName(function_name); |
| 3731 | 3910 |
| 3732 // FormalParameterList :: | 3911 // FormalParameterList :: |
| 3733 // '(' (Identifier)*[','] ')' | 3912 // '(' (Identifier)*[','] ')' |
| 3734 Expect(Token::LPAREN, CHECK_OK); | 3913 Expect(Token::LPAREN, CHECK_OK); |
| 3735 start_pos = scanner().location().beg_pos; | 3914 scope->set_start_position(scanner().location().beg_pos); |
| 3736 Scanner::Location name_loc = Scanner::Location::invalid(); | 3915 Scanner::Location name_loc = Scanner::Location::invalid(); |
| 3737 Scanner::Location dupe_loc = Scanner::Location::invalid(); | 3916 Scanner::Location dupe_loc = Scanner::Location::invalid(); |
| 3738 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 3917 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
| 3739 | 3918 |
| 3740 bool done = (peek() == Token::RPAREN); | 3919 bool done = (peek() == Token::RPAREN); |
| 3741 while (!done) { | 3920 while (!done) { |
| 3742 bool is_strict_reserved = false; | 3921 bool is_strict_reserved = false; |
| 3743 Handle<String> param_name = | 3922 Handle<String> param_name = |
| 3744 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, | 3923 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, |
| 3745 CHECK_OK); | 3924 CHECK_OK); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3771 | 3950 |
| 3772 Expect(Token::LBRACE, CHECK_OK); | 3951 Expect(Token::LBRACE, CHECK_OK); |
| 3773 | 3952 |
| 3774 // If we have a named function expression, we add a local variable | 3953 // If we have a named function expression, we add a local variable |
| 3775 // declaration to the body of the function with the name of the | 3954 // declaration to the body of the function with the name of the |
| 3776 // function and let it refer to the function itself (closure). | 3955 // function and let it refer to the function itself (closure). |
| 3777 // NOTE: We create a proxy and resolve it here so that in the | 3956 // NOTE: We create a proxy and resolve it here so that in the |
| 3778 // future we can change the AST to only refer to VariableProxies | 3957 // future we can change the AST to only refer to VariableProxies |
| 3779 // instead of Variables and Proxis as is the case now. | 3958 // instead of Variables and Proxis as is the case now. |
| 3780 if (type == FunctionLiteral::NAMED_EXPRESSION) { | 3959 if (type == FunctionLiteral::NAMED_EXPRESSION) { |
| 3781 Variable* fvar = top_scope_->DeclareFunctionVar(function_name); | 3960 VariableMode fvar_mode; |
| 3782 VariableProxy* fproxy = | 3961 Token::Value fvar_init_op; |
| 3783 top_scope_->NewUnresolved(function_name, inside_with()); | 3962 if (harmony_scoping_) { |
| 3963 fvar_mode = CONST_HARMONY; |
| 3964 fvar_init_op = Token::INIT_CONST_HARMONY; |
| 3965 } else { |
| 3966 fvar_mode = CONST; |
| 3967 fvar_init_op = Token::INIT_CONST; |
| 3968 } |
| 3969 Variable* fvar = top_scope_->DeclareFunctionVar(function_name, fvar_mode); |
| 3970 VariableProxy* fproxy = top_scope_->NewUnresolved(function_name); |
| 3784 fproxy->BindTo(fvar); | 3971 fproxy->BindTo(fvar); |
| 3785 body->Add(new(zone()) ExpressionStatement( | 3972 body->Add(new(zone()) ExpressionStatement( |
| 3786 new(zone()) Assignment(isolate(), | 3973 new(zone()) Assignment(isolate(), |
| 3787 Token::INIT_CONST, | 3974 fvar_init_op, |
| 3788 fproxy, | 3975 fproxy, |
| 3789 new(zone()) ThisFunction(isolate()), | 3976 new(zone()) ThisFunction(isolate()), |
| 3790 RelocInfo::kNoPosition))); | 3977 RelocInfo::kNoPosition))); |
| 3791 } | 3978 } |
| 3792 | 3979 |
| 3793 // Determine if the function will be lazily compiled. The mode can only | 3980 // Determine if the function will be lazily compiled. The mode can only |
| 3794 // be PARSE_LAZILY if the --lazy flag is true. We will not lazily | 3981 // be PARSE_LAZILY if the --lazy flag is true. We will not lazily |
| 3795 // compile if we do not have preparser data for the function. | 3982 // compile if we do not have preparser data for the function. |
| 3796 bool is_lazily_compiled = (mode() == PARSE_LAZILY && | 3983 bool is_lazily_compiled = (mode() == PARSE_LAZILY && |
| 3797 top_scope_->outer_scope()->is_global_scope() && | 3984 top_scope_->outer_scope()->is_global_scope() && |
| 3798 top_scope_->HasTrivialOuterContext() && | 3985 top_scope_->HasTrivialOuterContext() && |
| 3799 !parenthesized_function_ && | 3986 !parenthesized_function_ && |
| 3800 pre_data() != NULL); | 3987 pre_data() != NULL); |
| 3801 parenthesized_function_ = false; // The bit was set for this function only. | 3988 parenthesized_function_ = false; // The bit was set for this function only. |
| 3802 | 3989 |
| 3803 if (is_lazily_compiled) { | 3990 if (is_lazily_compiled) { |
| 3804 int function_block_pos = scanner().location().beg_pos; | 3991 int function_block_pos = scanner().location().beg_pos; |
| 3805 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos); | 3992 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos); |
| 3806 if (!entry.is_valid()) { | 3993 if (!entry.is_valid()) { |
| 3807 // There is no preparser data for the function, we will not lazily | 3994 // There is no preparser data for the function, we will not lazily |
| 3808 // compile after all. | 3995 // compile after all. |
| 3809 is_lazily_compiled = false; | 3996 is_lazily_compiled = false; |
| 3810 } else { | 3997 } else { |
| 3811 end_pos = entry.end_pos(); | 3998 scope->set_end_position(entry.end_pos()); |
| 3812 if (end_pos <= function_block_pos) { | 3999 if (scope->end_position() <= function_block_pos) { |
| 3813 // End position greater than end of stream is safe, and hard to check. | 4000 // End position greater than end of stream is safe, and hard to check. |
| 3814 ReportInvalidPreparseData(function_name, CHECK_OK); | 4001 ReportInvalidPreparseData(function_name, CHECK_OK); |
| 3815 } | 4002 } |
| 3816 isolate()->counters()->total_preparse_skipped()->Increment( | 4003 isolate()->counters()->total_preparse_skipped()->Increment( |
| 3817 end_pos - function_block_pos); | 4004 scope->end_position() - function_block_pos); |
| 3818 // Seek to position just before terminal '}'. | 4005 // Seek to position just before terminal '}'. |
| 3819 scanner().SeekForward(end_pos - 1); | 4006 scanner().SeekForward(scope->end_position() - 1); |
| 3820 materialized_literal_count = entry.literal_count(); | 4007 materialized_literal_count = entry.literal_count(); |
| 3821 expected_property_count = entry.property_count(); | 4008 expected_property_count = entry.property_count(); |
| 3822 if (entry.strict_mode()) top_scope_->EnableStrictMode(); | 4009 if (entry.strict_mode()) top_scope_->SetStrictModeFlag(kStrictMode); |
| 3823 only_simple_this_property_assignments = false; | 4010 only_simple_this_property_assignments = false; |
| 3824 this_property_assignments = isolate()->factory()->empty_fixed_array(); | 4011 this_property_assignments = isolate()->factory()->empty_fixed_array(); |
| 3825 Expect(Token::RBRACE, CHECK_OK); | 4012 Expect(Token::RBRACE, CHECK_OK); |
| 3826 } | 4013 } |
| 3827 } | 4014 } |
| 3828 | 4015 |
| 3829 if (!is_lazily_compiled) { | 4016 if (!is_lazily_compiled) { |
| 3830 ParseSourceElements(body, Token::RBRACE, CHECK_OK); | 4017 ParseSourceElements(body, Token::RBRACE, CHECK_OK); |
| 3831 | 4018 |
| 3832 materialized_literal_count = lexical_scope.materialized_literal_count(); | 4019 materialized_literal_count = lexical_scope.materialized_literal_count(); |
| 3833 expected_property_count = lexical_scope.expected_property_count(); | 4020 expected_property_count = lexical_scope.expected_property_count(); |
| 3834 only_simple_this_property_assignments = | 4021 only_simple_this_property_assignments = |
| 3835 lexical_scope.only_simple_this_property_assignments(); | 4022 lexical_scope.only_simple_this_property_assignments(); |
| 3836 this_property_assignments = lexical_scope.this_property_assignments(); | 4023 this_property_assignments = lexical_scope.this_property_assignments(); |
| 3837 | 4024 |
| 3838 Expect(Token::RBRACE, CHECK_OK); | 4025 Expect(Token::RBRACE, CHECK_OK); |
| 3839 end_pos = scanner().location().end_pos; | 4026 scope->set_end_position(scanner().location().end_pos); |
| 3840 } | 4027 } |
| 3841 | 4028 |
| 3842 // Validate strict mode. | 4029 // Validate strict mode. |
| 3843 if (top_scope_->is_strict_mode()) { | 4030 if (top_scope_->is_strict_mode()) { |
| 3844 if (IsEvalOrArguments(function_name)) { | 4031 if (IsEvalOrArguments(function_name)) { |
| 4032 int start_pos = scope->start_position(); |
| 3845 int position = function_token_position != RelocInfo::kNoPosition | 4033 int position = function_token_position != RelocInfo::kNoPosition |
| 3846 ? function_token_position | 4034 ? function_token_position |
| 3847 : (start_pos > 0 ? start_pos - 1 : start_pos); | 4035 : (start_pos > 0 ? start_pos - 1 : start_pos); |
| 3848 Scanner::Location location = Scanner::Location(position, start_pos); | 4036 Scanner::Location location = Scanner::Location(position, start_pos); |
| 3849 ReportMessageAt(location, | 4037 ReportMessageAt(location, |
| 3850 "strict_function_name", Vector<const char*>::empty()); | 4038 "strict_function_name", Vector<const char*>::empty()); |
| 3851 *ok = false; | 4039 *ok = false; |
| 3852 return NULL; | 4040 return NULL; |
| 3853 } | 4041 } |
| 3854 if (name_loc.IsValid()) { | 4042 if (name_loc.IsValid()) { |
| 3855 ReportMessageAt(name_loc, "strict_param_name", | 4043 ReportMessageAt(name_loc, "strict_param_name", |
| 3856 Vector<const char*>::empty()); | 4044 Vector<const char*>::empty()); |
| 3857 *ok = false; | 4045 *ok = false; |
| 3858 return NULL; | 4046 return NULL; |
| 3859 } | 4047 } |
| 3860 if (dupe_loc.IsValid()) { | 4048 if (dupe_loc.IsValid()) { |
| 3861 ReportMessageAt(dupe_loc, "strict_param_dupe", | 4049 ReportMessageAt(dupe_loc, "strict_param_dupe", |
| 3862 Vector<const char*>::empty()); | 4050 Vector<const char*>::empty()); |
| 3863 *ok = false; | 4051 *ok = false; |
| 3864 return NULL; | 4052 return NULL; |
| 3865 } | 4053 } |
| 3866 if (name_is_strict_reserved) { | 4054 if (name_is_strict_reserved) { |
| 4055 int start_pos = scope->start_position(); |
| 3867 int position = function_token_position != RelocInfo::kNoPosition | 4056 int position = function_token_position != RelocInfo::kNoPosition |
| 3868 ? function_token_position | 4057 ? function_token_position |
| 3869 : (start_pos > 0 ? start_pos - 1 : start_pos); | 4058 : (start_pos > 0 ? start_pos - 1 : start_pos); |
| 3870 Scanner::Location location = Scanner::Location(position, start_pos); | 4059 Scanner::Location location = Scanner::Location(position, start_pos); |
| 3871 ReportMessageAt(location, "strict_reserved_word", | 4060 ReportMessageAt(location, "strict_reserved_word", |
| 3872 Vector<const char*>::empty()); | 4061 Vector<const char*>::empty()); |
| 3873 *ok = false; | 4062 *ok = false; |
| 3874 return NULL; | 4063 return NULL; |
| 3875 } | 4064 } |
| 3876 if (reserved_loc.IsValid()) { | 4065 if (reserved_loc.IsValid()) { |
| 3877 ReportMessageAt(reserved_loc, "strict_reserved_word", | 4066 ReportMessageAt(reserved_loc, "strict_reserved_word", |
| 3878 Vector<const char*>::empty()); | 4067 Vector<const char*>::empty()); |
| 3879 *ok = false; | 4068 *ok = false; |
| 3880 return NULL; | 4069 return NULL; |
| 3881 } | 4070 } |
| 3882 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); | 4071 CheckOctalLiteral(scope->start_position(), |
| 4072 scope->end_position(), |
| 4073 CHECK_OK); |
| 3883 } | 4074 } |
| 3884 } | 4075 } |
| 3885 | 4076 |
| 3886 if (harmony_scoping_) { | 4077 if (harmony_scoping_) { |
| 3887 CheckConflictingVarDeclarations(scope, CHECK_OK); | 4078 CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 3888 } | 4079 } |
| 3889 | 4080 |
| 3890 FunctionLiteral* function_literal = | 4081 FunctionLiteral* function_literal = |
| 3891 new(zone()) FunctionLiteral(isolate(), | 4082 new(zone()) FunctionLiteral(isolate(), |
| 3892 function_name, | 4083 function_name, |
| 3893 scope, | 4084 scope, |
| 3894 body, | 4085 body, |
| 3895 materialized_literal_count, | 4086 materialized_literal_count, |
| 3896 expected_property_count, | 4087 expected_property_count, |
| 3897 only_simple_this_property_assignments, | 4088 only_simple_this_property_assignments, |
| 3898 this_property_assignments, | 4089 this_property_assignments, |
| 3899 num_parameters, | 4090 num_parameters, |
| 3900 start_pos, | |
| 3901 end_pos, | |
| 3902 type, | 4091 type, |
| 3903 has_duplicate_parameters); | 4092 has_duplicate_parameters); |
| 3904 function_literal->set_function_token_position(function_token_position); | 4093 function_literal->set_function_token_position(function_token_position); |
| 3905 | 4094 |
| 3906 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 4095 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
| 3907 return function_literal; | 4096 return function_literal; |
| 3908 } | 4097 } |
| 3909 | 4098 |
| 3910 | 4099 |
| 3911 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4100 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| (...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5112 result = (result << 7) | (input & 0x7f); | 5301 result = (result << 7) | (input & 0x7f); |
| 5113 data++; | 5302 data++; |
| 5114 } | 5303 } |
| 5115 *source = data; | 5304 *source = data; |
| 5116 return result; | 5305 return result; |
| 5117 } | 5306 } |
| 5118 | 5307 |
| 5119 | 5308 |
| 5120 // Create a Scanner for the preparser to use as input, and preparse the source. | 5309 // Create a Scanner for the preparser to use as input, and preparse the source. |
| 5121 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source, | 5310 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source, |
| 5122 bool allow_lazy, | 5311 int flags, |
| 5123 ParserRecorder* recorder, | 5312 ParserRecorder* recorder) { |
| 5124 bool harmony_scoping) { | |
| 5125 Isolate* isolate = Isolate::Current(); | 5313 Isolate* isolate = Isolate::Current(); |
| 5126 JavaScriptScanner scanner(isolate->unicode_cache()); | 5314 JavaScriptScanner scanner(isolate->unicode_cache()); |
| 5127 scanner.SetHarmonyScoping(harmony_scoping); | 5315 scanner.SetHarmonyScoping((flags & kHarmonyScoping) != 0); |
| 5128 scanner.Initialize(source); | 5316 scanner.Initialize(source); |
| 5129 intptr_t stack_limit = isolate->stack_guard()->real_climit(); | 5317 intptr_t stack_limit = isolate->stack_guard()->real_climit(); |
| 5130 if (!preparser::PreParser::PreParseProgram(&scanner, | 5318 if (!preparser::PreParser::PreParseProgram(&scanner, |
| 5131 recorder, | 5319 recorder, |
| 5132 allow_lazy, | 5320 flags, |
| 5133 stack_limit)) { | 5321 stack_limit)) { |
| 5134 isolate->StackOverflow(); | 5322 isolate->StackOverflow(); |
| 5135 return NULL; | 5323 return NULL; |
| 5136 } | 5324 } |
| 5137 | 5325 |
| 5138 // Extract the accumulated data from the recorder as a single | 5326 // Extract the accumulated data from the recorder as a single |
| 5139 // contiguous vector that we are responsible for disposing. | 5327 // contiguous vector that we are responsible for disposing. |
| 5140 Vector<unsigned> store = recorder->ExtractData(); | 5328 Vector<unsigned> store = recorder->ExtractData(); |
| 5141 return new ScriptDataImpl(store); | 5329 return new ScriptDataImpl(store); |
| 5142 } | 5330 } |
| 5143 | 5331 |
| 5144 | 5332 |
| 5145 // Preparse, but only collect data that is immediately useful, | 5333 // Preparse, but only collect data that is immediately useful, |
| 5146 // even if the preparser data is only used once. | 5334 // even if the preparser data is only used once. |
| 5147 ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source, | 5335 ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source, |
| 5148 v8::Extension* extension, | 5336 v8::Extension* extension, |
| 5149 bool harmony_scoping) { | 5337 int flags) { |
| 5150 bool allow_lazy = FLAG_lazy && (extension == NULL); | 5338 bool allow_lazy = FLAG_lazy && (extension == NULL); |
| 5151 if (!allow_lazy) { | 5339 if (!allow_lazy) { |
| 5152 // Partial preparsing is only about lazily compiled functions. | 5340 // Partial preparsing is only about lazily compiled functions. |
| 5153 // If we don't allow lazy compilation, the log data will be empty. | 5341 // If we don't allow lazy compilation, the log data will be empty. |
| 5154 return NULL; | 5342 return NULL; |
| 5155 } | 5343 } |
| 5344 flags |= kAllowLazy; |
| 5156 PartialParserRecorder recorder; | 5345 PartialParserRecorder recorder; |
| 5157 return DoPreParse(source, allow_lazy, &recorder, harmony_scoping); | 5346 return DoPreParse(source, flags, &recorder); |
| 5158 } | 5347 } |
| 5159 | 5348 |
| 5160 | 5349 |
| 5161 ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source, | 5350 ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source, |
| 5162 v8::Extension* extension, | 5351 v8::Extension* extension, |
| 5163 bool harmony_scoping) { | 5352 int flags) { |
| 5164 Handle<Script> no_script; | 5353 Handle<Script> no_script; |
| 5165 bool allow_lazy = FLAG_lazy && (extension == NULL); | 5354 if (FLAG_lazy && (extension == NULL)) { |
| 5355 flags |= kAllowLazy; |
| 5356 } |
| 5166 CompleteParserRecorder recorder; | 5357 CompleteParserRecorder recorder; |
| 5167 return DoPreParse(source, allow_lazy, &recorder, harmony_scoping); | 5358 return DoPreParse(source, flags, &recorder); |
| 5168 } | 5359 } |
| 5169 | 5360 |
| 5170 | 5361 |
| 5171 bool RegExpParser::ParseRegExp(FlatStringReader* input, | 5362 bool RegExpParser::ParseRegExp(FlatStringReader* input, |
| 5172 bool multiline, | 5363 bool multiline, |
| 5173 RegExpCompileData* result) { | 5364 RegExpCompileData* result) { |
| 5174 ASSERT(result != NULL); | 5365 ASSERT(result != NULL); |
| 5175 RegExpParser parser(input, &result->error, multiline); | 5366 RegExpParser parser(input, &result->error, multiline); |
| 5176 RegExpTree* tree = parser.ParsePattern(); | 5367 RegExpTree* tree = parser.ParsePattern(); |
| 5177 if (parser.failed()) { | 5368 if (parser.failed()) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5220 DeleteArray(message); | 5411 DeleteArray(message); |
| 5221 for (int i = 0; i < args.length(); i++) { | 5412 for (int i = 0; i < args.length(); i++) { |
| 5222 DeleteArray(args[i]); | 5413 DeleteArray(args[i]); |
| 5223 } | 5414 } |
| 5224 DeleteArray(args.start()); | 5415 DeleteArray(args.start()); |
| 5225 ASSERT(info->isolate()->has_pending_exception()); | 5416 ASSERT(info->isolate()->has_pending_exception()); |
| 5226 } else { | 5417 } else { |
| 5227 Handle<String> source = Handle<String>(String::cast(script->source())); | 5418 Handle<String> source = Handle<String>(String::cast(script->source())); |
| 5228 result = parser.ParseProgram(source, | 5419 result = parser.ParseProgram(source, |
| 5229 info->is_global(), | 5420 info->is_global(), |
| 5230 info->StrictMode()); | 5421 info->strict_mode_flag()); |
| 5231 } | 5422 } |
| 5232 } | 5423 } |
| 5233 info->SetFunction(result); | 5424 info->SetFunction(result); |
| 5234 return (result != NULL); | 5425 return (result != NULL); |
| 5235 } | 5426 } |
| 5236 | 5427 |
| 5237 } } // namespace v8::internal | 5428 } } // namespace v8::internal |
| OLD | NEW |