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 |