OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 } | 457 } |
458 | 458 |
459 private: | 459 private: |
460 Target** variable_; | 460 Target** variable_; |
461 Target* previous_; | 461 Target* previous_; |
462 }; | 462 }; |
463 | 463 |
464 | 464 |
465 // ---------------------------------------------------------------------------- | 465 // ---------------------------------------------------------------------------- |
466 // FunctionState and BlockState together implement the parser's scope stack. | 466 // FunctionState and BlockState together implement the parser's scope stack. |
467 // The parser's current scope is in top_scope_. The BlockState and | 467 // The parser's current scope is in scope_. The BlockState and |
468 // FunctionState constructors push on the scope stack and the destructors | 468 // FunctionState constructors push on the scope stack and the destructors |
469 // pop. They are also used to hold the parser's per-function and per-block | 469 // pop. They are also used to hold the parser's per-function and per-block |
470 // state. | 470 // state. |
471 | 471 |
472 class Parser::BlockState BASE_EMBEDDED { | 472 class Parser::BlockState BASE_EMBEDDED { |
473 public: | 473 public: |
474 BlockState(Parser* parser, Scope* scope) | 474 BlockState(Scope** scope_stack, Scope* scope) |
475 : parser_(parser), | 475 : scope_stack_(scope_stack), |
476 outer_scope_(parser->top_scope_) { | 476 outer_scope_(*scope_stack) { |
477 parser->top_scope_ = scope; | 477 *scope_stack = scope; |
478 } | 478 } |
479 | 479 |
480 ~BlockState() { parser_->top_scope_ = outer_scope_; } | 480 ~BlockState() { *scope_stack_ = outer_scope_; } |
481 | 481 |
482 private: | 482 private: |
483 Parser* parser_; | 483 Scope** scope_stack_; |
484 Scope* outer_scope_; | 484 Scope* outer_scope_; |
485 }; | 485 }; |
486 | 486 |
487 | 487 |
488 Parser::FunctionState::FunctionState(Parser* parser, Scope* scope) | 488 Parser::FunctionState::FunctionState(FunctionState** function_state_stack, |
| 489 Scope** scope_stack, Scope* scope, |
| 490 Zone* zone) |
489 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | 491 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), |
490 next_handler_index_(0), | 492 next_handler_index_(0), |
491 expected_property_count_(0), | 493 expected_property_count_(0), |
492 generator_object_variable_(NULL), | 494 generator_object_variable_(NULL), |
493 parser_(parser), | 495 function_state_stack_(function_state_stack), |
494 outer_function_state_(parser->current_function_state_), | 496 outer_function_state_(*function_state_stack), |
495 outer_scope_(parser->top_scope_), | 497 scope_stack_(scope_stack), |
496 saved_ast_node_id_(parser->zone()->isolate()->ast_node_id()), | 498 outer_scope_(*scope_stack), |
497 factory_(parser->zone()) { | 499 isolate_(zone->isolate()), |
498 parser->top_scope_ = scope; | 500 saved_ast_node_id_(isolate_->ast_node_id()), |
499 parser->current_function_state_ = this; | 501 factory_(zone) { |
500 parser->zone()->isolate()->set_ast_node_id(BailoutId::FirstUsable().ToInt()); | 502 *scope_stack_ = scope; |
| 503 *function_state_stack = this; |
| 504 isolate_->set_ast_node_id(BailoutId::FirstUsable().ToInt()); |
501 } | 505 } |
502 | 506 |
503 | 507 |
504 Parser::FunctionState::~FunctionState() { | 508 Parser::FunctionState::~FunctionState() { |
505 parser_->top_scope_ = outer_scope_; | 509 *scope_stack_ = outer_scope_; |
506 parser_->current_function_state_ = outer_function_state_; | 510 *function_state_stack_ = outer_function_state_; |
507 if (outer_function_state_ != NULL) { | 511 if (outer_function_state_ != NULL) { |
508 parser_->isolate()->set_ast_node_id(saved_ast_node_id_); | 512 isolate_->set_ast_node_id(saved_ast_node_id_); |
509 } | 513 } |
510 } | 514 } |
511 | 515 |
512 | 516 |
513 // ---------------------------------------------------------------------------- | 517 // ---------------------------------------------------------------------------- |
514 // The CHECK_OK macro is a convenient macro to enforce error | 518 // The CHECK_OK macro is a convenient macro to enforce error |
515 // handling for functions that may fail (by returning !*ok). | 519 // handling for functions that may fail (by returning !*ok). |
516 // | 520 // |
517 // CAUTION: This macro appends extra statements after a call, | 521 // CAUTION: This macro appends extra statements after a call, |
518 // thus it must never be used where only a single statement | 522 // thus it must never be used where only a single statement |
519 // is correct (e.g. an if statement branch w/o braces)! | 523 // is correct (e.g. an if statement branch w/o braces)! |
520 | 524 |
521 #define CHECK_OK ok); \ | 525 #define CHECK_OK ok); \ |
522 if (!*ok) return NULL; \ | 526 if (!*ok) return NULL; \ |
523 ((void)0 | 527 ((void)0 |
524 #define DUMMY ) // to make indentation work | 528 #define DUMMY ) // to make indentation work |
525 #undef DUMMY | 529 #undef DUMMY |
526 | 530 |
527 #define CHECK_FAILED /**/); \ | 531 #define CHECK_FAILED /**/); \ |
528 if (failed_) return NULL; \ | 532 if (failed_) return NULL; \ |
529 ((void)0 | 533 ((void)0 |
530 #define DUMMY ) // to make indentation work | 534 #define DUMMY ) // to make indentation work |
531 #undef DUMMY | 535 #undef DUMMY |
532 | 536 |
533 // ---------------------------------------------------------------------------- | 537 // ---------------------------------------------------------------------------- |
534 // Implementation of Parser | 538 // Implementation of Parser |
535 | 539 |
536 bool ParserTraits::is_classic_mode() const { | 540 bool ParserTraits::is_classic_mode() const { |
537 return parser_->top_scope_->is_classic_mode(); | 541 return parser_->scope_->is_classic_mode(); |
538 } | 542 } |
539 | 543 |
540 | 544 |
541 bool ParserTraits::is_generator() const { | 545 bool ParserTraits::is_generator() const { |
542 return parser_->current_function_state_->is_generator(); | 546 return parser_->function_state_->is_generator(); |
543 } | 547 } |
544 | 548 |
545 | 549 |
546 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { | 550 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { |
547 return identifier.is_identical_to( | 551 return identifier.is_identical_to( |
548 parser_->isolate()->factory()->eval_string()) || | 552 parser_->isolate()->factory()->eval_string()) || |
549 identifier.is_identical_to( | 553 identifier.is_identical_to( |
550 parser_->isolate()->factory()->arguments_string()); | 554 parser_->isolate()->factory()->arguments_string()); |
551 } | 555 } |
552 | 556 |
553 | 557 |
554 int ParserTraits::NextMaterializedLiteralIndex() { | 558 int ParserTraits::NextMaterializedLiteralIndex() { |
555 return parser_->current_function_state_->NextMaterializedLiteralIndex(); | 559 return parser_->function_state_->NextMaterializedLiteralIndex(); |
556 } | 560 } |
557 | 561 |
558 | 562 |
559 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 563 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
560 const char* message, | 564 const char* message, |
561 Vector<const char*> args) { | 565 Vector<const char*> args) { |
562 MessageLocation location(parser_->script_, | 566 MessageLocation location(parser_->script_, |
563 source_location.beg_pos, | 567 source_location.beg_pos, |
564 source_location.end_pos); | 568 source_location.end_pos); |
565 Factory* factory = parser_->isolate()->factory(); | 569 Factory* factory = parser_->isolate()->factory(); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 | 633 |
630 Parser::Parser(CompilationInfo* info) | 634 Parser::Parser(CompilationInfo* info) |
631 : ParserBase<ParserTraits>(&scanner_, | 635 : ParserBase<ParserTraits>(&scanner_, |
632 info->isolate()->stack_guard()->real_climit(), | 636 info->isolate()->stack_guard()->real_climit(), |
633 this), | 637 this), |
634 isolate_(info->isolate()), | 638 isolate_(info->isolate()), |
635 symbol_cache_(0, info->zone()), | 639 symbol_cache_(0, info->zone()), |
636 script_(info->script()), | 640 script_(info->script()), |
637 scanner_(isolate_->unicode_cache()), | 641 scanner_(isolate_->unicode_cache()), |
638 reusable_preparser_(NULL), | 642 reusable_preparser_(NULL), |
639 top_scope_(NULL), | 643 scope_(NULL), |
640 original_scope_(NULL), | 644 original_scope_(NULL), |
641 current_function_state_(NULL), | 645 function_state_(NULL), |
642 target_stack_(NULL), | 646 target_stack_(NULL), |
643 extension_(info->extension()), | 647 extension_(info->extension()), |
644 pre_parse_data_(NULL), | 648 pre_parse_data_(NULL), |
645 fni_(NULL), | 649 fni_(NULL), |
646 zone_(info->zone()), | 650 zone_(info->zone()), |
647 info_(info) { | 651 info_(info) { |
648 ASSERT(!script_.is_null()); | 652 ASSERT(!script_.is_null()); |
649 isolate_->set_ast_node_id(0); | 653 isolate_->set_ast_node_id(0); |
650 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 654 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
651 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 655 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 PrintF("[parsing script"); | 702 PrintF("[parsing script"); |
699 } | 703 } |
700 PrintF(" - took %0.3f ms]\n", ms); | 704 PrintF(" - took %0.3f ms]\n", ms); |
701 } | 705 } |
702 return result; | 706 return result; |
703 } | 707 } |
704 | 708 |
705 | 709 |
706 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, | 710 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
707 Handle<String> source) { | 711 Handle<String> source) { |
708 ASSERT(top_scope_ == NULL); | 712 ASSERT(scope_ == NULL); |
709 ASSERT(target_stack_ == NULL); | 713 ASSERT(target_stack_ == NULL); |
710 if (pre_parse_data_ != NULL) pre_parse_data_->Initialize(); | 714 if (pre_parse_data_ != NULL) pre_parse_data_->Initialize(); |
711 | 715 |
712 Handle<String> no_name = isolate()->factory()->empty_string(); | 716 Handle<String> no_name = isolate()->factory()->empty_string(); |
713 | 717 |
714 FunctionLiteral* result = NULL; | 718 FunctionLiteral* result = NULL; |
715 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); | 719 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
716 info->SetGlobalScope(scope); | 720 info->SetGlobalScope(scope); |
717 if (!info->context().is_null()) { | 721 if (!info->context().is_null()) { |
718 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); | 722 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); |
719 } | 723 } |
720 original_scope_ = scope; | 724 original_scope_ = scope; |
721 if (info->is_eval()) { | 725 if (info->is_eval()) { |
722 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { | 726 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { |
723 scope = NewScope(scope, EVAL_SCOPE); | 727 scope = NewScope(scope, EVAL_SCOPE); |
724 } | 728 } |
725 } else if (info->is_global()) { | 729 } else if (info->is_global()) { |
726 scope = NewScope(scope, GLOBAL_SCOPE); | 730 scope = NewScope(scope, GLOBAL_SCOPE); |
727 } | 731 } |
728 scope->set_start_position(0); | 732 scope->set_start_position(0); |
729 scope->set_end_position(source->length()); | 733 scope->set_end_position(source->length()); |
730 | 734 |
731 // Compute the parsing mode. | 735 // Compute the parsing mode. |
732 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; | 736 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; |
733 if (allow_natives_syntax() || | 737 if (allow_natives_syntax() || |
734 extension_ != NULL || | 738 extension_ != NULL || |
735 scope->is_eval_scope()) { | 739 scope->is_eval_scope()) { |
736 mode = PARSE_EAGERLY; | 740 mode = PARSE_EAGERLY; |
737 } | 741 } |
738 ParsingModeScope parsing_mode(this, mode); | 742 ParsingModeScope parsing_mode(this, mode); |
739 | 743 |
740 // Enters 'scope'. | 744 // Enters 'scope'. |
741 FunctionState function_state(this, scope); | 745 FunctionState function_state(&function_state_, &scope_, scope, zone()); |
742 | 746 |
743 top_scope_->SetLanguageMode(info->language_mode()); | 747 scope_->SetLanguageMode(info->language_mode()); |
744 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 748 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
745 bool ok = true; | 749 bool ok = true; |
746 int beg_pos = scanner().location().beg_pos; | 750 int beg_pos = scanner().location().beg_pos; |
747 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); | 751 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); |
748 if (ok && !top_scope_->is_classic_mode()) { | 752 if (ok && !scope_->is_classic_mode()) { |
749 CheckOctalLiteral(beg_pos, scanner().location().end_pos, &ok); | 753 CheckOctalLiteral(beg_pos, scanner().location().end_pos, &ok); |
750 } | 754 } |
751 | 755 |
752 if (ok && is_extended_mode()) { | 756 if (ok && is_extended_mode()) { |
753 CheckConflictingVarDeclarations(top_scope_, &ok); | 757 CheckConflictingVarDeclarations(scope_, &ok); |
754 } | 758 } |
755 | 759 |
756 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 760 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
757 if (body->length() != 1 || | 761 if (body->length() != 1 || |
758 !body->at(0)->IsExpressionStatement() || | 762 !body->at(0)->IsExpressionStatement() || |
759 !body->at(0)->AsExpressionStatement()-> | 763 !body->at(0)->AsExpressionStatement()-> |
760 expression()->IsFunctionLiteral()) { | 764 expression()->IsFunctionLiteral()) { |
761 ReportMessage("single_function_literal", Vector<const char*>::empty()); | 765 ReportMessage("single_function_literal", Vector<const char*>::empty()); |
762 ok = false; | 766 ok = false; |
763 } | 767 } |
764 } | 768 } |
765 | 769 |
766 if (ok) { | 770 if (ok) { |
767 result = factory()->NewFunctionLiteral( | 771 result = factory()->NewFunctionLiteral( |
768 no_name, | 772 no_name, |
769 top_scope_, | 773 scope_, |
770 body, | 774 body, |
771 function_state.materialized_literal_count(), | 775 function_state.materialized_literal_count(), |
772 function_state.expected_property_count(), | 776 function_state.expected_property_count(), |
773 function_state.handler_count(), | 777 function_state.handler_count(), |
774 0, | 778 0, |
775 FunctionLiteral::kNoDuplicateParameters, | 779 FunctionLiteral::kNoDuplicateParameters, |
776 FunctionLiteral::ANONYMOUS_EXPRESSION, | 780 FunctionLiteral::ANONYMOUS_EXPRESSION, |
777 FunctionLiteral::kGlobalOrEval, | 781 FunctionLiteral::kGlobalOrEval, |
778 FunctionLiteral::kNotParenthesized, | 782 FunctionLiteral::kNotParenthesized, |
779 FunctionLiteral::kNotGenerator, | 783 FunctionLiteral::kNotGenerator, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); | 829 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); |
826 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); | 830 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); |
827 } | 831 } |
828 return result; | 832 return result; |
829 } | 833 } |
830 | 834 |
831 | 835 |
832 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { | 836 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { |
833 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 837 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); |
834 scanner_.Initialize(source); | 838 scanner_.Initialize(source); |
835 ASSERT(top_scope_ == NULL); | 839 ASSERT(scope_ == NULL); |
836 ASSERT(target_stack_ == NULL); | 840 ASSERT(target_stack_ == NULL); |
837 | 841 |
838 Handle<String> name(String::cast(shared_info->name())); | 842 Handle<String> name(String::cast(shared_info->name())); |
839 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 843 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
840 fni_->PushEnclosingName(name); | 844 fni_->PushEnclosingName(name); |
841 | 845 |
842 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 846 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
843 | 847 |
844 // Place holder for the result. | 848 // Place holder for the result. |
845 FunctionLiteral* result = NULL; | 849 FunctionLiteral* result = NULL; |
846 | 850 |
847 { | 851 { |
848 // Parse the function literal. | 852 // Parse the function literal. |
849 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); | 853 Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
850 info()->SetGlobalScope(scope); | 854 info()->SetGlobalScope(scope); |
851 if (!info()->closure().is_null()) { | 855 if (!info()->closure().is_null()) { |
852 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, | 856 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, |
853 zone()); | 857 zone()); |
854 } | 858 } |
855 original_scope_ = scope; | 859 original_scope_ = scope; |
856 FunctionState function_state(this, scope); | 860 FunctionState function_state(&function_state_, &scope_, scope, zone()); |
857 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode()); | 861 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode()); |
858 ASSERT(scope->language_mode() != EXTENDED_MODE || | 862 ASSERT(scope->language_mode() != EXTENDED_MODE || |
859 info()->is_extended_mode()); | 863 info()->is_extended_mode()); |
860 ASSERT(info()->language_mode() == shared_info->language_mode()); | 864 ASSERT(info()->language_mode() == shared_info->language_mode()); |
861 scope->SetLanguageMode(shared_info->language_mode()); | 865 scope->SetLanguageMode(shared_info->language_mode()); |
862 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 866 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
863 ? (shared_info->is_anonymous() | 867 ? (shared_info->is_anonymous() |
864 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 868 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
865 : FunctionLiteral::NAMED_EXPRESSION) | 869 : FunctionLiteral::NAMED_EXPRESSION) |
866 : FunctionLiteral::DECLARATION; | 870 : FunctionLiteral::DECLARATION; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
927 // A shot at a directive. | 931 // A shot at a directive. |
928 ExpressionStatement* e_stat; | 932 ExpressionStatement* e_stat; |
929 Literal* literal; | 933 Literal* literal; |
930 // Still processing directive prologue? | 934 // Still processing directive prologue? |
931 if ((e_stat = stat->AsExpressionStatement()) != NULL && | 935 if ((e_stat = stat->AsExpressionStatement()) != NULL && |
932 (literal = e_stat->expression()->AsLiteral()) != NULL && | 936 (literal = e_stat->expression()->AsLiteral()) != NULL && |
933 literal->value()->IsString()) { | 937 literal->value()->IsString()) { |
934 Handle<String> directive = Handle<String>::cast(literal->value()); | 938 Handle<String> directive = Handle<String>::cast(literal->value()); |
935 | 939 |
936 // Check "use strict" directive (ES5 14.1). | 940 // Check "use strict" directive (ES5 14.1). |
937 if (top_scope_->is_classic_mode() && | 941 if (scope_->is_classic_mode() && |
938 directive->Equals(isolate()->heap()->use_strict_string()) && | 942 directive->Equals(isolate()->heap()->use_strict_string()) && |
939 token_loc.end_pos - token_loc.beg_pos == | 943 token_loc.end_pos - token_loc.beg_pos == |
940 isolate()->heap()->use_strict_string()->length() + 2) { | 944 isolate()->heap()->use_strict_string()->length() + 2) { |
941 // TODO(mstarzinger): Global strict eval calls, need their own scope | 945 // TODO(mstarzinger): Global strict eval calls, need their own scope |
942 // as specified in ES5 10.4.2(3). The correct fix would be to always | 946 // as specified in ES5 10.4.2(3). The correct fix would be to always |
943 // add this scope in DoParseProgram(), but that requires adaptations | 947 // add this scope in DoParseProgram(), but that requires adaptations |
944 // all over the code base, so we go with a quick-fix for now. | 948 // all over the code base, so we go with a quick-fix for now. |
945 // In the same manner, we have to patch the parsing mode. | 949 // In the same manner, we have to patch the parsing mode. |
946 if (is_eval && !top_scope_->is_eval_scope()) { | 950 if (is_eval && !scope_->is_eval_scope()) { |
947 ASSERT(top_scope_->is_global_scope()); | 951 ASSERT(scope_->is_global_scope()); |
948 Scope* scope = NewScope(top_scope_, EVAL_SCOPE); | 952 Scope* scope = NewScope(scope_, EVAL_SCOPE); |
949 scope->set_start_position(top_scope_->start_position()); | 953 scope->set_start_position(scope_->start_position()); |
950 scope->set_end_position(top_scope_->end_position()); | 954 scope->set_end_position(scope_->end_position()); |
951 top_scope_ = scope; | 955 scope_ = scope; |
952 mode_ = PARSE_EAGERLY; | 956 mode_ = PARSE_EAGERLY; |
953 } | 957 } |
954 // TODO(ES6): Fix entering extended mode, once it is specified. | 958 // TODO(ES6): Fix entering extended mode, once it is specified. |
955 top_scope_->SetLanguageMode(allow_harmony_scoping() | 959 scope_->SetLanguageMode(allow_harmony_scoping() |
956 ? EXTENDED_MODE : STRICT_MODE); | 960 ? EXTENDED_MODE : STRICT_MODE); |
957 // "use strict" is the only directive for now. | 961 // "use strict" is the only directive for now. |
958 directive_prologue = false; | 962 directive_prologue = false; |
959 } | 963 } |
960 } else { | 964 } else { |
961 // End of the directive prologue. | 965 // End of the directive prologue. |
962 directive_prologue = false; | 966 directive_prologue = false; |
963 } | 967 } |
964 } | 968 } |
965 | 969 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1026 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1030 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
1027 | 1031 |
1028 #ifdef DEBUG | 1032 #ifdef DEBUG |
1029 if (FLAG_print_interface_details) | 1033 if (FLAG_print_interface_details) |
1030 PrintF("# Module %s...\n", name->ToAsciiArray()); | 1034 PrintF("# Module %s...\n", name->ToAsciiArray()); |
1031 #endif | 1035 #endif |
1032 | 1036 |
1033 Module* module = ParseModule(CHECK_OK); | 1037 Module* module = ParseModule(CHECK_OK); |
1034 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); | 1038 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); |
1035 Declaration* declaration = | 1039 Declaration* declaration = |
1036 factory()->NewModuleDeclaration(proxy, module, top_scope_, pos); | 1040 factory()->NewModuleDeclaration(proxy, module, scope_, pos); |
1037 Declare(declaration, true, CHECK_OK); | 1041 Declare(declaration, true, CHECK_OK); |
1038 | 1042 |
1039 #ifdef DEBUG | 1043 #ifdef DEBUG |
1040 if (FLAG_print_interface_details) | 1044 if (FLAG_print_interface_details) |
1041 PrintF("# Module %s.\n", name->ToAsciiArray()); | 1045 PrintF("# Module %s.\n", name->ToAsciiArray()); |
1042 | 1046 |
1043 if (FLAG_print_interfaces) { | 1047 if (FLAG_print_interfaces) { |
1044 PrintF("module %s : ", name->ToAsciiArray()); | 1048 PrintF("module %s : ", name->ToAsciiArray()); |
1045 module->interface()->Print(); | 1049 module->interface()->Print(); |
1046 } | 1050 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1084 Module* Parser::ParseModuleLiteral(bool* ok) { | 1088 Module* Parser::ParseModuleLiteral(bool* ok) { |
1085 // Module: | 1089 // Module: |
1086 // '{' ModuleElement '}' | 1090 // '{' ModuleElement '}' |
1087 | 1091 |
1088 int pos = peek_position(); | 1092 int pos = peek_position(); |
1089 // Construct block expecting 16 statements. | 1093 // Construct block expecting 16 statements. |
1090 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); | 1094 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); |
1091 #ifdef DEBUG | 1095 #ifdef DEBUG |
1092 if (FLAG_print_interface_details) PrintF("# Literal "); | 1096 if (FLAG_print_interface_details) PrintF("# Literal "); |
1093 #endif | 1097 #endif |
1094 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); | 1098 Scope* scope = NewScope(scope_, MODULE_SCOPE); |
1095 | 1099 |
1096 Expect(Token::LBRACE, CHECK_OK); | 1100 Expect(Token::LBRACE, CHECK_OK); |
1097 scope->set_start_position(scanner().location().beg_pos); | 1101 scope->set_start_position(scanner().location().beg_pos); |
1098 scope->SetLanguageMode(EXTENDED_MODE); | 1102 scope->SetLanguageMode(EXTENDED_MODE); |
1099 | 1103 |
1100 { | 1104 { |
1101 BlockState block_state(this, scope); | 1105 BlockState block_state(&scope_, scope); |
1102 TargetCollector collector(zone()); | 1106 TargetCollector collector(zone()); |
1103 Target target(&this->target_stack_, &collector); | 1107 Target target(&this->target_stack_, &collector); |
1104 Target target_body(&this->target_stack_, body); | 1108 Target target_body(&this->target_stack_, body); |
1105 | 1109 |
1106 while (peek() != Token::RBRACE) { | 1110 while (peek() != Token::RBRACE) { |
1107 Statement* stat = ParseModuleElement(NULL, CHECK_OK); | 1111 Statement* stat = ParseModuleElement(NULL, CHECK_OK); |
1108 if (stat && !stat->IsEmpty()) { | 1112 if (stat && !stat->IsEmpty()) { |
1109 body->AddStatement(stat, zone()); | 1113 body->AddStatement(stat, zone()); |
1110 } | 1114 } |
1111 } | 1115 } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1175 Module* Parser::ParseModuleVariable(bool* ok) { | 1179 Module* Parser::ParseModuleVariable(bool* ok) { |
1176 // ModulePath: | 1180 // ModulePath: |
1177 // Identifier | 1181 // Identifier |
1178 | 1182 |
1179 int pos = peek_position(); | 1183 int pos = peek_position(); |
1180 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1184 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
1181 #ifdef DEBUG | 1185 #ifdef DEBUG |
1182 if (FLAG_print_interface_details) | 1186 if (FLAG_print_interface_details) |
1183 PrintF("# Module variable %s ", name->ToAsciiArray()); | 1187 PrintF("# Module variable %s ", name->ToAsciiArray()); |
1184 #endif | 1188 #endif |
1185 VariableProxy* proxy = top_scope_->NewUnresolved( | 1189 VariableProxy* proxy = scope_->NewUnresolved( |
1186 factory(), name, Interface::NewModule(zone()), | 1190 factory(), name, Interface::NewModule(zone()), |
1187 scanner().location().beg_pos); | 1191 scanner().location().beg_pos); |
1188 | 1192 |
1189 return factory()->NewModuleVariable(proxy, pos); | 1193 return factory()->NewModuleVariable(proxy, pos); |
1190 } | 1194 } |
1191 | 1195 |
1192 | 1196 |
1193 Module* Parser::ParseModuleUrl(bool* ok) { | 1197 Module* Parser::ParseModuleUrl(bool* ok) { |
1194 // Module: | 1198 // Module: |
1195 // String | 1199 // String |
1196 | 1200 |
1197 int pos = peek_position(); | 1201 int pos = peek_position(); |
1198 Expect(Token::STRING, CHECK_OK); | 1202 Expect(Token::STRING, CHECK_OK); |
1199 Handle<String> symbol = GetSymbol(); | 1203 Handle<String> symbol = GetSymbol(); |
1200 | 1204 |
1201 // TODO(ES6): Request JS resource from environment... | 1205 // TODO(ES6): Request JS resource from environment... |
1202 | 1206 |
1203 #ifdef DEBUG | 1207 #ifdef DEBUG |
1204 if (FLAG_print_interface_details) PrintF("# Url "); | 1208 if (FLAG_print_interface_details) PrintF("# Url "); |
1205 #endif | 1209 #endif |
1206 | 1210 |
1207 // Create an empty literal as long as the feature isn't finished. | 1211 // Create an empty literal as long as the feature isn't finished. |
1208 USE(symbol); | 1212 USE(symbol); |
1209 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); | 1213 Scope* scope = NewScope(scope_, MODULE_SCOPE); |
1210 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); | 1214 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
1211 body->set_scope(scope); | 1215 body->set_scope(scope); |
1212 Interface* interface = scope->interface(); | 1216 Interface* interface = scope->interface(); |
1213 Module* result = factory()->NewModuleLiteral(body, interface, pos); | 1217 Module* result = factory()->NewModuleLiteral(body, interface, pos); |
1214 interface->Freeze(ok); | 1218 interface->Freeze(ok); |
1215 ASSERT(*ok); | 1219 ASSERT(*ok); |
1216 interface->Unify(scope->interface(), zone(), ok); | 1220 interface->Unify(scope->interface(), zone(), ok); |
1217 ASSERT(*ok); | 1221 ASSERT(*ok); |
1218 return result; | 1222 return result; |
1219 } | 1223 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1271 PrintF("module: "); | 1275 PrintF("module: "); |
1272 module->interface()->Print(); | 1276 module->interface()->Print(); |
1273 } | 1277 } |
1274 #endif | 1278 #endif |
1275 ParserTraits::ReportMessage("invalid_module_path", | 1279 ParserTraits::ReportMessage("invalid_module_path", |
1276 Vector<Handle<String> >(&name, 1)); | 1280 Vector<Handle<String> >(&name, 1)); |
1277 return NULL; | 1281 return NULL; |
1278 } | 1282 } |
1279 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); | 1283 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); |
1280 Declaration* declaration = | 1284 Declaration* declaration = |
1281 factory()->NewImportDeclaration(proxy, module, top_scope_, pos); | 1285 factory()->NewImportDeclaration(proxy, module, scope_, pos); |
1282 Declare(declaration, true, CHECK_OK); | 1286 Declare(declaration, true, CHECK_OK); |
1283 } | 1287 } |
1284 | 1288 |
1285 return block; | 1289 return block; |
1286 } | 1290 } |
1287 | 1291 |
1288 | 1292 |
1289 Statement* Parser::ParseExportDeclaration(bool* ok) { | 1293 Statement* Parser::ParseExportDeclaration(bool* ok) { |
1290 // ExportDeclaration: | 1294 // ExportDeclaration: |
1291 // 'export' Identifier (',' Identifier)* ';' | 1295 // 'export' Identifier (',' Identifier)* ';' |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1331 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK); | 1335 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK); |
1332 break; | 1336 break; |
1333 | 1337 |
1334 default: | 1338 default: |
1335 *ok = false; | 1339 *ok = false; |
1336 ReportUnexpectedToken(scanner().current_token()); | 1340 ReportUnexpectedToken(scanner().current_token()); |
1337 return NULL; | 1341 return NULL; |
1338 } | 1342 } |
1339 | 1343 |
1340 // Extract declared names into export declarations and interface. | 1344 // Extract declared names into export declarations and interface. |
1341 Interface* interface = top_scope_->interface(); | 1345 Interface* interface = scope_->interface(); |
1342 for (int i = 0; i < names.length(); ++i) { | 1346 for (int i = 0; i < names.length(); ++i) { |
1343 #ifdef DEBUG | 1347 #ifdef DEBUG |
1344 if (FLAG_print_interface_details) | 1348 if (FLAG_print_interface_details) |
1345 PrintF("# Export %s ", names[i]->ToAsciiArray()); | 1349 PrintF("# Export %s ", names[i]->ToAsciiArray()); |
1346 #endif | 1350 #endif |
1347 Interface* inner = Interface::NewUnknown(zone()); | 1351 Interface* inner = Interface::NewUnknown(zone()); |
1348 interface->Add(names[i], inner, zone(), CHECK_OK); | 1352 interface->Add(names[i], inner, zone(), CHECK_OK); |
1349 if (!*ok) | 1353 if (!*ok) |
1350 return NULL; | 1354 return NULL; |
1351 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); | 1355 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); |
1352 USE(proxy); | 1356 USE(proxy); |
1353 // TODO(rossberg): Rethink whether we actually need to store export | 1357 // TODO(rossberg): Rethink whether we actually need to store export |
1354 // declarations (for compilation?). | 1358 // declarations (for compilation?). |
1355 // ExportDeclaration* declaration = | 1359 // ExportDeclaration* declaration = |
1356 // factory()->NewExportDeclaration(proxy, top_scope_, position); | 1360 // factory()->NewExportDeclaration(proxy, scope_, position); |
1357 // top_scope_->AddDeclaration(declaration); | 1361 // scope_->AddDeclaration(declaration); |
1358 } | 1362 } |
1359 | 1363 |
1360 ASSERT(result != NULL); | 1364 ASSERT(result != NULL); |
1361 return result; | 1365 return result; |
1362 } | 1366 } |
1363 | 1367 |
1364 | 1368 |
1365 Statement* Parser::ParseBlockElement(ZoneStringList* labels, | 1369 Statement* Parser::ParseBlockElement(ZoneStringList* labels, |
1366 bool* ok) { | 1370 bool* ok) { |
1367 // (Ecma 262 5th Edition, clause 14): | 1371 // (Ecma 262 5th Edition, clause 14): |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1473 // (Ecma 262 5th Edition, clause 14): | 1477 // (Ecma 262 5th Edition, clause 14): |
1474 // SourceElement: | 1478 // SourceElement: |
1475 // Statement | 1479 // Statement |
1476 // FunctionDeclaration | 1480 // FunctionDeclaration |
1477 // Common language extension is to allow function declaration in place | 1481 // Common language extension is to allow function declaration in place |
1478 // of any statement. This language extension is disabled in strict mode. | 1482 // of any statement. This language extension is disabled in strict mode. |
1479 // | 1483 // |
1480 // In Harmony mode, this case also handles the extension: | 1484 // In Harmony mode, this case also handles the extension: |
1481 // Statement: | 1485 // Statement: |
1482 // GeneratorDeclaration | 1486 // GeneratorDeclaration |
1483 if (!top_scope_->is_classic_mode()) { | 1487 if (!scope_->is_classic_mode()) { |
1484 ReportMessageAt(scanner().peek_location(), "strict_function"); | 1488 ReportMessageAt(scanner().peek_location(), "strict_function"); |
1485 *ok = false; | 1489 *ok = false; |
1486 return NULL; | 1490 return NULL; |
1487 } | 1491 } |
1488 return ParseFunctionDeclaration(NULL, ok); | 1492 return ParseFunctionDeclaration(NULL, ok); |
1489 } | 1493 } |
1490 | 1494 |
1491 case Token::DEBUGGER: | 1495 case Token::DEBUGGER: |
1492 return ParseDebuggerStatement(ok); | 1496 return ParseDebuggerStatement(ok); |
1493 | 1497 |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1693 // isn't lazily compiled. The extension structures are only | 1697 // isn't lazily compiled. The extension structures are only |
1694 // accessible while parsing the first time not when reparsing | 1698 // accessible while parsing the first time not when reparsing |
1695 // because of lazy compilation. | 1699 // because of lazy compilation. |
1696 DeclarationScope(VAR)->ForceEagerCompilation(); | 1700 DeclarationScope(VAR)->ForceEagerCompilation(); |
1697 | 1701 |
1698 // TODO(1240846): It's weird that native function declarations are | 1702 // TODO(1240846): It's weird that native function declarations are |
1699 // introduced dynamically when we meet their declarations, whereas | 1703 // introduced dynamically when we meet their declarations, whereas |
1700 // other functions are set up when entering the surrounding scope. | 1704 // other functions are set up when entering the surrounding scope. |
1701 VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue()); | 1705 VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue()); |
1702 Declaration* declaration = | 1706 Declaration* declaration = |
1703 factory()->NewVariableDeclaration(proxy, VAR, top_scope_, pos); | 1707 factory()->NewVariableDeclaration(proxy, VAR, scope_, pos); |
1704 Declare(declaration, true, CHECK_OK); | 1708 Declare(declaration, true, CHECK_OK); |
1705 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( | 1709 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( |
1706 name, extension_, RelocInfo::kNoPosition); | 1710 name, extension_, RelocInfo::kNoPosition); |
1707 return factory()->NewExpressionStatement( | 1711 return factory()->NewExpressionStatement( |
1708 factory()->NewAssignment( | 1712 factory()->NewAssignment( |
1709 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), | 1713 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), |
1710 pos); | 1714 pos); |
1711 } | 1715 } |
1712 | 1716 |
1713 | 1717 |
(...skipping 15 matching lines...) Expand all Loading... |
1729 is_generator, | 1733 is_generator, |
1730 pos, | 1734 pos, |
1731 FunctionLiteral::DECLARATION, | 1735 FunctionLiteral::DECLARATION, |
1732 CHECK_OK); | 1736 CHECK_OK); |
1733 // Even if we're not at the top-level of the global or a function | 1737 // Even if we're not at the top-level of the global or a function |
1734 // scope, we treat it as such and introduce the function with its | 1738 // scope, we treat it as such and introduce the function with its |
1735 // initial value upon entering the corresponding scope. | 1739 // initial value upon entering the corresponding scope. |
1736 // In extended mode, a function behaves as a lexical binding, except in the | 1740 // In extended mode, a function behaves as a lexical binding, except in the |
1737 // global scope. | 1741 // global scope. |
1738 VariableMode mode = | 1742 VariableMode mode = |
1739 is_extended_mode() && !top_scope_->is_global_scope() ? LET : VAR; | 1743 is_extended_mode() && !scope_->is_global_scope() ? LET : VAR; |
1740 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); | 1744 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); |
1741 Declaration* declaration = | 1745 Declaration* declaration = |
1742 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_, pos); | 1746 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); |
1743 Declare(declaration, true, CHECK_OK); | 1747 Declare(declaration, true, CHECK_OK); |
1744 if (names) names->Add(name, zone()); | 1748 if (names) names->Add(name, zone()); |
1745 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 1749 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
1746 } | 1750 } |
1747 | 1751 |
1748 | 1752 |
1749 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1753 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
1750 if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok); | 1754 if (scope_->is_extended_mode()) return ParseScopedBlock(labels, ok); |
1751 | 1755 |
1752 // Block :: | 1756 // Block :: |
1753 // '{' Statement* '}' | 1757 // '{' Statement* '}' |
1754 | 1758 |
1755 // Note that a Block does not introduce a new execution scope! | 1759 // Note that a Block does not introduce a new execution scope! |
1756 // (ECMA-262, 3rd, 12.2) | 1760 // (ECMA-262, 3rd, 12.2) |
1757 // | 1761 // |
1758 // Construct block expecting 16 statements. | 1762 // Construct block expecting 16 statements. |
1759 Block* result = | 1763 Block* result = |
1760 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1764 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
(...skipping 12 matching lines...) Expand all Loading... |
1773 | 1777 |
1774 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { | 1778 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
1775 // The harmony mode uses block elements instead of statements. | 1779 // The harmony mode uses block elements instead of statements. |
1776 // | 1780 // |
1777 // Block :: | 1781 // Block :: |
1778 // '{' BlockElement* '}' | 1782 // '{' BlockElement* '}' |
1779 | 1783 |
1780 // Construct block expecting 16 statements. | 1784 // Construct block expecting 16 statements. |
1781 Block* body = | 1785 Block* body = |
1782 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1786 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
1783 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); | 1787 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); |
1784 | 1788 |
1785 // Parse the statements and collect escaping labels. | 1789 // Parse the statements and collect escaping labels. |
1786 Expect(Token::LBRACE, CHECK_OK); | 1790 Expect(Token::LBRACE, CHECK_OK); |
1787 block_scope->set_start_position(scanner().location().beg_pos); | 1791 block_scope->set_start_position(scanner().location().beg_pos); |
1788 { BlockState block_state(this, block_scope); | 1792 { BlockState block_state(&scope_, block_scope); |
1789 TargetCollector collector(zone()); | 1793 TargetCollector collector(zone()); |
1790 Target target(&this->target_stack_, &collector); | 1794 Target target(&this->target_stack_, &collector); |
1791 Target target_body(&this->target_stack_, body); | 1795 Target target_body(&this->target_stack_, body); |
1792 | 1796 |
1793 while (peek() != Token::RBRACE) { | 1797 while (peek() != Token::RBRACE) { |
1794 Statement* stat = ParseBlockElement(NULL, CHECK_OK); | 1798 Statement* stat = ParseBlockElement(NULL, CHECK_OK); |
1795 if (stat && !stat->IsEmpty()) { | 1799 if (stat && !stat->IsEmpty()) { |
1796 body->AddStatement(stat, zone()); | 1800 body->AddStatement(stat, zone()); |
1797 } | 1801 } |
1798 } | 1802 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1860 // | 1864 // |
1861 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' | 1865 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' |
1862 // | 1866 // |
1863 // * It is a Syntax Error if the code that matches this production is not | 1867 // * It is a Syntax Error if the code that matches this production is not |
1864 // contained in extended code. | 1868 // contained in extended code. |
1865 // | 1869 // |
1866 // However disallowing const in classic mode will break compatibility with | 1870 // However disallowing const in classic mode will break compatibility with |
1867 // existing pages. Therefore we keep allowing const with the old | 1871 // existing pages. Therefore we keep allowing const with the old |
1868 // non-harmony semantics in classic mode. | 1872 // non-harmony semantics in classic mode. |
1869 Consume(Token::CONST); | 1873 Consume(Token::CONST); |
1870 switch (top_scope_->language_mode()) { | 1874 switch (scope_->language_mode()) { |
1871 case CLASSIC_MODE: | 1875 case CLASSIC_MODE: |
1872 mode = CONST; | 1876 mode = CONST; |
1873 init_op = Token::INIT_CONST; | 1877 init_op = Token::INIT_CONST; |
1874 break; | 1878 break; |
1875 case STRICT_MODE: | 1879 case STRICT_MODE: |
1876 ReportMessage("strict_const", Vector<const char*>::empty()); | 1880 ReportMessage("strict_const", Vector<const char*>::empty()); |
1877 *ok = false; | 1881 *ok = false; |
1878 return NULL; | 1882 return NULL; |
1879 case EXTENDED_MODE: | 1883 case EXTENDED_MODE: |
1880 if (var_context == kStatement) { | 1884 if (var_context == kStatement) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1953 // If we have a const declaration, in an inner scope, the proxy is always | 1957 // If we have a const declaration, in an inner scope, the proxy is always |
1954 // bound to the declared variable (independent of possibly surrounding with | 1958 // bound to the declared variable (independent of possibly surrounding with |
1955 // statements). | 1959 // statements). |
1956 // For let/const declarations in harmony mode, we can also immediately | 1960 // For let/const declarations in harmony mode, we can also immediately |
1957 // pre-resolve the proxy because it resides in the same scope as the | 1961 // pre-resolve the proxy because it resides in the same scope as the |
1958 // declaration. | 1962 // declaration. |
1959 Interface* interface = | 1963 Interface* interface = |
1960 is_const ? Interface::NewConst() : Interface::NewValue(); | 1964 is_const ? Interface::NewConst() : Interface::NewValue(); |
1961 VariableProxy* proxy = NewUnresolved(name, mode, interface); | 1965 VariableProxy* proxy = NewUnresolved(name, mode, interface); |
1962 Declaration* declaration = | 1966 Declaration* declaration = |
1963 factory()->NewVariableDeclaration(proxy, mode, top_scope_, pos); | 1967 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); |
1964 Declare(declaration, mode != VAR, CHECK_OK); | 1968 Declare(declaration, mode != VAR, CHECK_OK); |
1965 nvars++; | 1969 nvars++; |
1966 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { | 1970 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { |
1967 ReportMessageAt(scanner().location(), "too_many_variables"); | 1971 ReportMessageAt(scanner().location(), "too_many_variables"); |
1968 *ok = false; | 1972 *ok = false; |
1969 return NULL; | 1973 return NULL; |
1970 } | 1974 } |
1971 if (names) names->Add(name, zone()); | 1975 if (names) names->Add(name, zone()); |
1972 | 1976 |
1973 // Parse initialization expression if present and/or needed. A | 1977 // Parse initialization expression if present and/or needed. A |
1974 // declaration of the form: | 1978 // declaration of the form: |
1975 // | 1979 // |
1976 // var v = x; | 1980 // var v = x; |
1977 // | 1981 // |
1978 // is syntactic sugar for: | 1982 // is syntactic sugar for: |
1979 // | 1983 // |
1980 // var v; v = x; | 1984 // var v; v = x; |
1981 // | 1985 // |
1982 // In particular, we need to re-lookup 'v' (in top_scope_, not | 1986 // In particular, we need to re-lookup 'v' (in scope_, not |
1983 // declaration_scope) as it may be a different 'v' than the 'v' in the | 1987 // declaration_scope) as it may be a different 'v' than the 'v' in the |
1984 // declaration (e.g., if we are inside a 'with' statement or 'catch' | 1988 // declaration (e.g., if we are inside a 'with' statement or 'catch' |
1985 // block). | 1989 // block). |
1986 // | 1990 // |
1987 // However, note that const declarations are different! A const | 1991 // However, note that const declarations are different! A const |
1988 // declaration of the form: | 1992 // declaration of the form: |
1989 // | 1993 // |
1990 // const c = x; | 1994 // const c = x; |
1991 // | 1995 // |
1992 // is *not* syntactic sugar for: | 1996 // is *not* syntactic sugar for: |
1993 // | 1997 // |
1994 // const c; c = x; | 1998 // const c; c = x; |
1995 // | 1999 // |
1996 // The "variable" c initialized to x is the same as the declared | 2000 // The "variable" c initialized to x is the same as the declared |
1997 // one - there is no re-lookup (see the last parameter of the | 2001 // one - there is no re-lookup (see the last parameter of the |
1998 // Declare() call above). | 2002 // Declare() call above). |
1999 | 2003 |
2000 Scope* initialization_scope = is_const ? declaration_scope : top_scope_; | 2004 Scope* initialization_scope = is_const ? declaration_scope : scope_; |
2001 Expression* value = NULL; | 2005 Expression* value = NULL; |
2002 int pos = -1; | 2006 int pos = -1; |
2003 // Harmony consts have non-optional initializers. | 2007 // Harmony consts have non-optional initializers. |
2004 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) { | 2008 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) { |
2005 Expect(Token::ASSIGN, CHECK_OK); | 2009 Expect(Token::ASSIGN, CHECK_OK); |
2006 pos = position(); | 2010 pos = position(); |
2007 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 2011 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
2008 // Don't infer if it is "a = function(){...}();"-like expression. | 2012 // Don't infer if it is "a = function(){...}();"-like expression. |
2009 if (fni_ != NULL && | 2013 if (fni_ != NULL && |
2010 value->AsCall() == NULL && | 2014 value->AsCall() == NULL && |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2181 *ok = false; | 2185 *ok = false; |
2182 return NULL; | 2186 return NULL; |
2183 } | 2187 } |
2184 if (labels == NULL) { | 2188 if (labels == NULL) { |
2185 labels = new(zone()) ZoneStringList(4, zone()); | 2189 labels = new(zone()) ZoneStringList(4, zone()); |
2186 } | 2190 } |
2187 labels->Add(label, zone()); | 2191 labels->Add(label, zone()); |
2188 // Remove the "ghost" variable that turned out to be a label | 2192 // Remove the "ghost" variable that turned out to be a label |
2189 // from the top scope. This way, we don't try to resolve it | 2193 // from the top scope. This way, we don't try to resolve it |
2190 // during the scope processing. | 2194 // during the scope processing. |
2191 top_scope_->RemoveUnresolved(var); | 2195 scope_->RemoveUnresolved(var); |
2192 Expect(Token::COLON, CHECK_OK); | 2196 Expect(Token::COLON, CHECK_OK); |
2193 return ParseStatement(labels, ok); | 2197 return ParseStatement(labels, ok); |
2194 } | 2198 } |
2195 | 2199 |
2196 // If we have an extension, we allow a native function declaration. | 2200 // If we have an extension, we allow a native function declaration. |
2197 // A native function declaration starts with "native function" with | 2201 // A native function declaration starts with "native function" with |
2198 // no line-terminator between the two words. | 2202 // no line-terminator between the two words. |
2199 if (extension_ != NULL && | 2203 if (extension_ != NULL && |
2200 peek() == Token::FUNCTION && | 2204 peek() == Token::FUNCTION && |
2201 !scanner().HasAnyLineTerminatorBeforeNext() && | 2205 !scanner().HasAnyLineTerminatorBeforeNext() && |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2331 tok == Token::SEMICOLON || | 2335 tok == Token::SEMICOLON || |
2332 tok == Token::RBRACE || | 2336 tok == Token::RBRACE || |
2333 tok == Token::EOS) { | 2337 tok == Token::EOS) { |
2334 return_value = GetLiteralUndefined(position()); | 2338 return_value = GetLiteralUndefined(position()); |
2335 } else { | 2339 } else { |
2336 return_value = ParseExpression(true, CHECK_OK); | 2340 return_value = ParseExpression(true, CHECK_OK); |
2337 } | 2341 } |
2338 ExpectSemicolon(CHECK_OK); | 2342 ExpectSemicolon(CHECK_OK); |
2339 if (is_generator()) { | 2343 if (is_generator()) { |
2340 Expression* generator = factory()->NewVariableProxy( | 2344 Expression* generator = factory()->NewVariableProxy( |
2341 current_function_state_->generator_object_variable()); | 2345 function_state_->generator_object_variable()); |
2342 Expression* yield = factory()->NewYield( | 2346 Expression* yield = factory()->NewYield( |
2343 generator, return_value, Yield::FINAL, pos); | 2347 generator, return_value, Yield::FINAL, pos); |
2344 result = factory()->NewExpressionStatement(yield, pos); | 2348 result = factory()->NewExpressionStatement(yield, pos); |
2345 } else { | 2349 } else { |
2346 result = factory()->NewReturnStatement(return_value, pos); | 2350 result = factory()->NewReturnStatement(return_value, pos); |
2347 } | 2351 } |
2348 | 2352 |
2349 // An ECMAScript program is considered syntactically incorrect if it | 2353 // An ECMAScript program is considered syntactically incorrect if it |
2350 // contains a return statement that is not within the body of a | 2354 // contains a return statement that is not within the body of a |
2351 // function. See ECMA-262, section 12.9, page 67. | 2355 // function. See ECMA-262, section 12.9, page 67. |
2352 // | 2356 // |
2353 // To be consistent with KJS we report the syntax error at runtime. | 2357 // To be consistent with KJS we report the syntax error at runtime. |
2354 Scope* declaration_scope = top_scope_->DeclarationScope(); | 2358 Scope* declaration_scope = scope_->DeclarationScope(); |
2355 if (declaration_scope->is_global_scope() || | 2359 if (declaration_scope->is_global_scope() || |
2356 declaration_scope->is_eval_scope()) { | 2360 declaration_scope->is_eval_scope()) { |
2357 Handle<String> message = isolate()->factory()->illegal_return_string(); | 2361 Handle<String> message = isolate()->factory()->illegal_return_string(); |
2358 Expression* throw_error = | 2362 Expression* throw_error = |
2359 NewThrowSyntaxError(message, Handle<Object>::null()); | 2363 NewThrowSyntaxError(message, Handle<Object>::null()); |
2360 return factory()->NewExpressionStatement(throw_error, pos); | 2364 return factory()->NewExpressionStatement(throw_error, pos); |
2361 } | 2365 } |
2362 return result; | 2366 return result; |
2363 } | 2367 } |
2364 | 2368 |
2365 | 2369 |
2366 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 2370 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
2367 // WithStatement :: | 2371 // WithStatement :: |
2368 // 'with' '(' Expression ')' Statement | 2372 // 'with' '(' Expression ')' Statement |
2369 | 2373 |
2370 Expect(Token::WITH, CHECK_OK); | 2374 Expect(Token::WITH, CHECK_OK); |
2371 int pos = position(); | 2375 int pos = position(); |
2372 | 2376 |
2373 if (!top_scope_->is_classic_mode()) { | 2377 if (!scope_->is_classic_mode()) { |
2374 ReportMessage("strict_mode_with", Vector<const char*>::empty()); | 2378 ReportMessage("strict_mode_with", Vector<const char*>::empty()); |
2375 *ok = false; | 2379 *ok = false; |
2376 return NULL; | 2380 return NULL; |
2377 } | 2381 } |
2378 | 2382 |
2379 Expect(Token::LPAREN, CHECK_OK); | 2383 Expect(Token::LPAREN, CHECK_OK); |
2380 Expression* expr = ParseExpression(true, CHECK_OK); | 2384 Expression* expr = ParseExpression(true, CHECK_OK); |
2381 Expect(Token::RPAREN, CHECK_OK); | 2385 Expect(Token::RPAREN, CHECK_OK); |
2382 | 2386 |
2383 top_scope_->DeclarationScope()->RecordWithStatement(); | 2387 scope_->DeclarationScope()->RecordWithStatement(); |
2384 Scope* with_scope = NewScope(top_scope_, WITH_SCOPE); | 2388 Scope* with_scope = NewScope(scope_, WITH_SCOPE); |
2385 Statement* stmt; | 2389 Statement* stmt; |
2386 { BlockState block_state(this, with_scope); | 2390 { BlockState block_state(&scope_, with_scope); |
2387 with_scope->set_start_position(scanner().peek_location().beg_pos); | 2391 with_scope->set_start_position(scanner().peek_location().beg_pos); |
2388 stmt = ParseStatement(labels, CHECK_OK); | 2392 stmt = ParseStatement(labels, CHECK_OK); |
2389 with_scope->set_end_position(scanner().location().end_pos); | 2393 with_scope->set_end_position(scanner().location().end_pos); |
2390 } | 2394 } |
2391 return factory()->NewWithStatement(with_scope, expr, stmt, pos); | 2395 return factory()->NewWithStatement(with_scope, expr, stmt, pos); |
2392 } | 2396 } |
2393 | 2397 |
2394 | 2398 |
2395 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { | 2399 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { |
2396 // CaseClause :: | 2400 // CaseClause :: |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2508 // always collect the targets. | 2512 // always collect the targets. |
2509 TargetCollector catch_collector(zone()); | 2513 TargetCollector catch_collector(zone()); |
2510 Scope* catch_scope = NULL; | 2514 Scope* catch_scope = NULL; |
2511 Variable* catch_variable = NULL; | 2515 Variable* catch_variable = NULL; |
2512 Block* catch_block = NULL; | 2516 Block* catch_block = NULL; |
2513 Handle<String> name; | 2517 Handle<String> name; |
2514 if (tok == Token::CATCH) { | 2518 if (tok == Token::CATCH) { |
2515 Consume(Token::CATCH); | 2519 Consume(Token::CATCH); |
2516 | 2520 |
2517 Expect(Token::LPAREN, CHECK_OK); | 2521 Expect(Token::LPAREN, CHECK_OK); |
2518 catch_scope = NewScope(top_scope_, CATCH_SCOPE); | 2522 catch_scope = NewScope(scope_, CATCH_SCOPE); |
2519 catch_scope->set_start_position(scanner().location().beg_pos); | 2523 catch_scope->set_start_position(scanner().location().beg_pos); |
2520 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2524 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
2521 | 2525 |
2522 Expect(Token::RPAREN, CHECK_OK); | 2526 Expect(Token::RPAREN, CHECK_OK); |
2523 | 2527 |
2524 Target target(&this->target_stack_, &catch_collector); | 2528 Target target(&this->target_stack_, &catch_collector); |
2525 VariableMode mode = is_extended_mode() ? LET : VAR; | 2529 VariableMode mode = is_extended_mode() ? LET : VAR; |
2526 catch_variable = | 2530 catch_variable = |
2527 catch_scope->DeclareLocal(name, mode, kCreatedInitialized); | 2531 catch_scope->DeclareLocal(name, mode, kCreatedInitialized); |
2528 | 2532 |
2529 BlockState block_state(this, catch_scope); | 2533 BlockState block_state(&scope_, catch_scope); |
2530 catch_block = ParseBlock(NULL, CHECK_OK); | 2534 catch_block = ParseBlock(NULL, CHECK_OK); |
2531 | 2535 |
2532 catch_scope->set_end_position(scanner().location().end_pos); | 2536 catch_scope->set_end_position(scanner().location().end_pos); |
2533 tok = peek(); | 2537 tok = peek(); |
2534 } | 2538 } |
2535 | 2539 |
2536 Block* finally_block = NULL; | 2540 Block* finally_block = NULL; |
2537 ASSERT(tok == Token::FINALLY || catch_block != NULL); | 2541 ASSERT(tok == Token::FINALLY || catch_block != NULL); |
2538 if (tok == Token::FINALLY) { | 2542 if (tok == Token::FINALLY) { |
2539 Consume(Token::FINALLY); | 2543 Consume(Token::FINALLY); |
2540 finally_block = ParseBlock(NULL, CHECK_OK); | 2544 finally_block = ParseBlock(NULL, CHECK_OK); |
2541 } | 2545 } |
2542 | 2546 |
2543 // Simplify the AST nodes by converting: | 2547 // Simplify the AST nodes by converting: |
2544 // 'try B0 catch B1 finally B2' | 2548 // 'try B0 catch B1 finally B2' |
2545 // to: | 2549 // to: |
2546 // 'try { try B0 catch B1 } finally B2' | 2550 // 'try { try B0 catch B1 } finally B2' |
2547 | 2551 |
2548 if (catch_block != NULL && finally_block != NULL) { | 2552 if (catch_block != NULL && finally_block != NULL) { |
2549 // If we have both, create an inner try/catch. | 2553 // If we have both, create an inner try/catch. |
2550 ASSERT(catch_scope != NULL && catch_variable != NULL); | 2554 ASSERT(catch_scope != NULL && catch_variable != NULL); |
2551 int index = current_function_state_->NextHandlerIndex(); | 2555 int index = function_state_->NextHandlerIndex(); |
2552 TryCatchStatement* statement = factory()->NewTryCatchStatement( | 2556 TryCatchStatement* statement = factory()->NewTryCatchStatement( |
2553 index, try_block, catch_scope, catch_variable, catch_block, | 2557 index, try_block, catch_scope, catch_variable, catch_block, |
2554 RelocInfo::kNoPosition); | 2558 RelocInfo::kNoPosition); |
2555 statement->set_escaping_targets(try_collector.targets()); | 2559 statement->set_escaping_targets(try_collector.targets()); |
2556 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); | 2560 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
2557 try_block->AddStatement(statement, zone()); | 2561 try_block->AddStatement(statement, zone()); |
2558 catch_block = NULL; // Clear to indicate it's been handled. | 2562 catch_block = NULL; // Clear to indicate it's been handled. |
2559 } | 2563 } |
2560 | 2564 |
2561 TryStatement* result = NULL; | 2565 TryStatement* result = NULL; |
2562 if (catch_block != NULL) { | 2566 if (catch_block != NULL) { |
2563 ASSERT(finally_block == NULL); | 2567 ASSERT(finally_block == NULL); |
2564 ASSERT(catch_scope != NULL && catch_variable != NULL); | 2568 ASSERT(catch_scope != NULL && catch_variable != NULL); |
2565 int index = current_function_state_->NextHandlerIndex(); | 2569 int index = function_state_->NextHandlerIndex(); |
2566 result = factory()->NewTryCatchStatement( | 2570 result = factory()->NewTryCatchStatement( |
2567 index, try_block, catch_scope, catch_variable, catch_block, pos); | 2571 index, try_block, catch_scope, catch_variable, catch_block, pos); |
2568 } else { | 2572 } else { |
2569 ASSERT(finally_block != NULL); | 2573 ASSERT(finally_block != NULL); |
2570 int index = current_function_state_->NextHandlerIndex(); | 2574 int index = function_state_->NextHandlerIndex(); |
2571 result = factory()->NewTryFinallyStatement( | 2575 result = factory()->NewTryFinallyStatement( |
2572 index, try_block, finally_block, pos); | 2576 index, try_block, finally_block, pos); |
2573 // Combine the jump targets of the try block and the possible catch block. | 2577 // Combine the jump targets of the try block and the possible catch block. |
2574 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); | 2578 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); |
2575 } | 2579 } |
2576 | 2580 |
2577 result->set_escaping_targets(try_collector.targets()); | 2581 result->set_escaping_targets(try_collector.targets()); |
2578 return result; | 2582 return result; |
2579 } | 2583 } |
2580 | 2584 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2640 | 2644 |
2641 | 2645 |
2642 void Parser::InitializeForEachStatement(ForEachStatement* stmt, | 2646 void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
2643 Expression* each, | 2647 Expression* each, |
2644 Expression* subject, | 2648 Expression* subject, |
2645 Statement* body) { | 2649 Statement* body) { |
2646 ForOfStatement* for_of = stmt->AsForOfStatement(); | 2650 ForOfStatement* for_of = stmt->AsForOfStatement(); |
2647 | 2651 |
2648 if (for_of != NULL) { | 2652 if (for_of != NULL) { |
2649 Factory* heap_factory = isolate()->factory(); | 2653 Factory* heap_factory = isolate()->factory(); |
2650 Variable* iterator = top_scope_->DeclarationScope()->NewTemporary( | 2654 Variable* iterator = scope_->DeclarationScope()->NewTemporary( |
2651 heap_factory->dot_iterator_string()); | 2655 heap_factory->dot_iterator_string()); |
2652 Variable* result = top_scope_->DeclarationScope()->NewTemporary( | 2656 Variable* result = scope_->DeclarationScope()->NewTemporary( |
2653 heap_factory->dot_result_string()); | 2657 heap_factory->dot_result_string()); |
2654 | 2658 |
2655 Expression* assign_iterator; | 2659 Expression* assign_iterator; |
2656 Expression* next_result; | 2660 Expression* next_result; |
2657 Expression* result_done; | 2661 Expression* result_done; |
2658 Expression* assign_each; | 2662 Expression* assign_each; |
2659 | 2663 |
2660 // var iterator = iterable; | 2664 // var iterator = iterable; |
2661 { | 2665 { |
2662 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2666 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2709 | 2713 |
2710 | 2714 |
2711 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 2715 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
2712 // ForStatement :: | 2716 // ForStatement :: |
2713 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 2717 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
2714 | 2718 |
2715 int pos = peek_position(); | 2719 int pos = peek_position(); |
2716 Statement* init = NULL; | 2720 Statement* init = NULL; |
2717 | 2721 |
2718 // Create an in-between scope for let-bound iteration variables. | 2722 // Create an in-between scope for let-bound iteration variables. |
2719 Scope* saved_scope = top_scope_; | 2723 Scope* saved_scope = scope_; |
2720 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); | 2724 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); |
2721 top_scope_ = for_scope; | 2725 scope_ = for_scope; |
2722 | 2726 |
2723 Expect(Token::FOR, CHECK_OK); | 2727 Expect(Token::FOR, CHECK_OK); |
2724 Expect(Token::LPAREN, CHECK_OK); | 2728 Expect(Token::LPAREN, CHECK_OK); |
2725 for_scope->set_start_position(scanner().location().beg_pos); | 2729 for_scope->set_start_position(scanner().location().beg_pos); |
2726 if (peek() != Token::SEMICOLON) { | 2730 if (peek() != Token::SEMICOLON) { |
2727 if (peek() == Token::VAR || peek() == Token::CONST) { | 2731 if (peek() == Token::VAR || peek() == Token::CONST) { |
2728 bool is_const = peek() == Token::CONST; | 2732 bool is_const = peek() == Token::CONST; |
2729 Handle<String> name; | 2733 Handle<String> name; |
2730 VariableDeclarationProperties decl_props = kHasNoInitializers; | 2734 VariableDeclarationProperties decl_props = kHasNoInitializers; |
2731 Block* variable_statement = | 2735 Block* variable_statement = |
2732 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 2736 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
2733 CHECK_OK); | 2737 CHECK_OK); |
2734 bool accept_OF = decl_props == kHasNoInitializers; | 2738 bool accept_OF = decl_props == kHasNoInitializers; |
2735 ForEachStatement::VisitMode mode; | 2739 ForEachStatement::VisitMode mode; |
2736 | 2740 |
2737 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { | 2741 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { |
2738 Interface* interface = | 2742 Interface* interface = |
2739 is_const ? Interface::NewConst() : Interface::NewValue(); | 2743 is_const ? Interface::NewConst() : Interface::NewValue(); |
2740 ForEachStatement* loop = | 2744 ForEachStatement* loop = |
2741 factory()->NewForEachStatement(mode, labels, pos); | 2745 factory()->NewForEachStatement(mode, labels, pos); |
2742 Target target(&this->target_stack_, loop); | 2746 Target target(&this->target_stack_, loop); |
2743 | 2747 |
2744 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2748 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2745 Expect(Token::RPAREN, CHECK_OK); | 2749 Expect(Token::RPAREN, CHECK_OK); |
2746 | 2750 |
2747 VariableProxy* each = | 2751 VariableProxy* each = |
2748 top_scope_->NewUnresolved(factory(), name, interface); | 2752 scope_->NewUnresolved(factory(), name, interface); |
2749 Statement* body = ParseStatement(NULL, CHECK_OK); | 2753 Statement* body = ParseStatement(NULL, CHECK_OK); |
2750 InitializeForEachStatement(loop, each, enumerable, body); | 2754 InitializeForEachStatement(loop, each, enumerable, body); |
2751 Block* result = | 2755 Block* result = |
2752 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 2756 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
2753 result->AddStatement(variable_statement, zone()); | 2757 result->AddStatement(variable_statement, zone()); |
2754 result->AddStatement(loop, zone()); | 2758 result->AddStatement(loop, zone()); |
2755 top_scope_ = saved_scope; | 2759 scope_ = saved_scope; |
2756 for_scope->set_end_position(scanner().location().end_pos); | 2760 for_scope->set_end_position(scanner().location().end_pos); |
2757 for_scope = for_scope->FinalizeBlockScope(); | 2761 for_scope = for_scope->FinalizeBlockScope(); |
2758 ASSERT(for_scope == NULL); | 2762 ASSERT(for_scope == NULL); |
2759 // Parsed for-in loop w/ variable/const declaration. | 2763 // Parsed for-in loop w/ variable/const declaration. |
2760 return result; | 2764 return result; |
2761 } else { | 2765 } else { |
2762 init = variable_statement; | 2766 init = variable_statement; |
2763 } | 2767 } |
2764 } else if (peek() == Token::LET) { | 2768 } else if (peek() == Token::LET) { |
2765 Handle<String> name; | 2769 Handle<String> name; |
(...skipping 18 matching lines...) Expand all Loading... |
2784 // x = x'; | 2788 // x = x'; |
2785 // b; | 2789 // b; |
2786 // } | 2790 // } |
2787 | 2791 |
2788 // TODO(keuchel): Move the temporary variable to the block scope, after | 2792 // TODO(keuchel): Move the temporary variable to the block scope, after |
2789 // implementing stack allocated block scoped variables. | 2793 // implementing stack allocated block scoped variables. |
2790 Factory* heap_factory = isolate()->factory(); | 2794 Factory* heap_factory = isolate()->factory(); |
2791 Handle<String> tempstr = | 2795 Handle<String> tempstr = |
2792 heap_factory->NewConsString(heap_factory->dot_for_string(), name); | 2796 heap_factory->NewConsString(heap_factory->dot_for_string(), name); |
2793 Handle<String> tempname = heap_factory->InternalizeString(tempstr); | 2797 Handle<String> tempname = heap_factory->InternalizeString(tempstr); |
2794 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname); | 2798 Variable* temp = scope_->DeclarationScope()->NewTemporary(tempname); |
2795 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 2799 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
2796 ForEachStatement* loop = | 2800 ForEachStatement* loop = |
2797 factory()->NewForEachStatement(mode, labels, pos); | 2801 factory()->NewForEachStatement(mode, labels, pos); |
2798 Target target(&this->target_stack_, loop); | 2802 Target target(&this->target_stack_, loop); |
2799 | 2803 |
2800 // The expression does not see the loop variable. | 2804 // The expression does not see the loop variable. |
2801 top_scope_ = saved_scope; | 2805 scope_ = saved_scope; |
2802 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2806 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2803 top_scope_ = for_scope; | 2807 scope_ = for_scope; |
2804 Expect(Token::RPAREN, CHECK_OK); | 2808 Expect(Token::RPAREN, CHECK_OK); |
2805 | 2809 |
2806 VariableProxy* each = | 2810 VariableProxy* each = |
2807 top_scope_->NewUnresolved(factory(), name, Interface::NewValue()); | 2811 scope_->NewUnresolved(factory(), name, Interface::NewValue()); |
2808 Statement* body = ParseStatement(NULL, CHECK_OK); | 2812 Statement* body = ParseStatement(NULL, CHECK_OK); |
2809 Block* body_block = | 2813 Block* body_block = |
2810 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); | 2814 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); |
2811 Assignment* assignment = factory()->NewAssignment( | 2815 Assignment* assignment = factory()->NewAssignment( |
2812 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); | 2816 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); |
2813 Statement* assignment_statement = factory()->NewExpressionStatement( | 2817 Statement* assignment_statement = factory()->NewExpressionStatement( |
2814 assignment, RelocInfo::kNoPosition); | 2818 assignment, RelocInfo::kNoPosition); |
2815 body_block->AddStatement(variable_statement, zone()); | 2819 body_block->AddStatement(variable_statement, zone()); |
2816 body_block->AddStatement(assignment_statement, zone()); | 2820 body_block->AddStatement(assignment_statement, zone()); |
2817 body_block->AddStatement(body, zone()); | 2821 body_block->AddStatement(body, zone()); |
2818 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); | 2822 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); |
2819 top_scope_ = saved_scope; | 2823 scope_ = saved_scope; |
2820 for_scope->set_end_position(scanner().location().end_pos); | 2824 for_scope->set_end_position(scanner().location().end_pos); |
2821 for_scope = for_scope->FinalizeBlockScope(); | 2825 for_scope = for_scope->FinalizeBlockScope(); |
2822 body_block->set_scope(for_scope); | 2826 body_block->set_scope(for_scope); |
2823 // Parsed for-in loop w/ let declaration. | 2827 // Parsed for-in loop w/ let declaration. |
2824 return loop; | 2828 return loop; |
2825 | 2829 |
2826 } else { | 2830 } else { |
2827 init = variable_statement; | 2831 init = variable_statement; |
2828 } | 2832 } |
2829 } else { | 2833 } else { |
(...skipping 13 matching lines...) Expand all Loading... |
2843 } | 2847 } |
2844 ForEachStatement* loop = | 2848 ForEachStatement* loop = |
2845 factory()->NewForEachStatement(mode, labels, pos); | 2849 factory()->NewForEachStatement(mode, labels, pos); |
2846 Target target(&this->target_stack_, loop); | 2850 Target target(&this->target_stack_, loop); |
2847 | 2851 |
2848 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2852 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2849 Expect(Token::RPAREN, CHECK_OK); | 2853 Expect(Token::RPAREN, CHECK_OK); |
2850 | 2854 |
2851 Statement* body = ParseStatement(NULL, CHECK_OK); | 2855 Statement* body = ParseStatement(NULL, CHECK_OK); |
2852 InitializeForEachStatement(loop, expression, enumerable, body); | 2856 InitializeForEachStatement(loop, expression, enumerable, body); |
2853 top_scope_ = saved_scope; | 2857 scope_ = saved_scope; |
2854 for_scope->set_end_position(scanner().location().end_pos); | 2858 for_scope->set_end_position(scanner().location().end_pos); |
2855 for_scope = for_scope->FinalizeBlockScope(); | 2859 for_scope = for_scope->FinalizeBlockScope(); |
2856 ASSERT(for_scope == NULL); | 2860 ASSERT(for_scope == NULL); |
2857 // Parsed for-in loop. | 2861 // Parsed for-in loop. |
2858 return loop; | 2862 return loop; |
2859 | 2863 |
2860 } else { | 2864 } else { |
2861 init = factory()->NewExpressionStatement( | 2865 init = factory()->NewExpressionStatement( |
2862 expression, RelocInfo::kNoPosition); | 2866 expression, RelocInfo::kNoPosition); |
2863 } | 2867 } |
(...skipping 14 matching lines...) Expand all Loading... |
2878 Expect(Token::SEMICOLON, CHECK_OK); | 2882 Expect(Token::SEMICOLON, CHECK_OK); |
2879 | 2883 |
2880 Statement* next = NULL; | 2884 Statement* next = NULL; |
2881 if (peek() != Token::RPAREN) { | 2885 if (peek() != Token::RPAREN) { |
2882 Expression* exp = ParseExpression(true, CHECK_OK); | 2886 Expression* exp = ParseExpression(true, CHECK_OK); |
2883 next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition); | 2887 next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition); |
2884 } | 2888 } |
2885 Expect(Token::RPAREN, CHECK_OK); | 2889 Expect(Token::RPAREN, CHECK_OK); |
2886 | 2890 |
2887 Statement* body = ParseStatement(NULL, CHECK_OK); | 2891 Statement* body = ParseStatement(NULL, CHECK_OK); |
2888 top_scope_ = saved_scope; | 2892 scope_ = saved_scope; |
2889 for_scope->set_end_position(scanner().location().end_pos); | 2893 for_scope->set_end_position(scanner().location().end_pos); |
2890 for_scope = for_scope->FinalizeBlockScope(); | 2894 for_scope = for_scope->FinalizeBlockScope(); |
2891 if (for_scope != NULL) { | 2895 if (for_scope != NULL) { |
2892 // Rewrite a for statement of the form | 2896 // Rewrite a for statement of the form |
2893 // | 2897 // |
2894 // for (let x = i; c; n) b | 2898 // for (let x = i; c; n) b |
2895 // | 2899 // |
2896 // into | 2900 // into |
2897 // | 2901 // |
2898 // { | 2902 // { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2954 // side expression. We could report this as a syntax error here but | 2958 // side expression. We could report this as a syntax error here but |
2955 // for compatibility with JSC we choose to report the error at | 2959 // for compatibility with JSC we choose to report the error at |
2956 // runtime. | 2960 // runtime. |
2957 // TODO(ES5): Should change parsing for spec conformance. | 2961 // TODO(ES5): Should change parsing for spec conformance. |
2958 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2962 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
2959 Handle<String> message = | 2963 Handle<String> message = |
2960 isolate()->factory()->invalid_lhs_in_assignment_string(); | 2964 isolate()->factory()->invalid_lhs_in_assignment_string(); |
2961 expression = NewThrowReferenceError(message); | 2965 expression = NewThrowReferenceError(message); |
2962 } | 2966 } |
2963 | 2967 |
2964 if (!top_scope_->is_classic_mode()) { | 2968 if (!scope_->is_classic_mode()) { |
2965 // Assignment to eval or arguments is disallowed in strict mode. | 2969 // Assignment to eval or arguments is disallowed in strict mode. |
2966 CheckStrictModeLValue(expression, CHECK_OK); | 2970 CheckStrictModeLValue(expression, CHECK_OK); |
2967 } | 2971 } |
2968 MarkAsLValue(expression); | 2972 MarkAsLValue(expression); |
2969 | 2973 |
2970 Token::Value op = Next(); // Get assignment operator. | 2974 Token::Value op = Next(); // Get assignment operator. |
2971 int pos = position(); | 2975 int pos = position(); |
2972 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2976 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
2973 | 2977 |
2974 // TODO(1231235): We try to estimate the set of properties set by | 2978 // TODO(1231235): We try to estimate the set of properties set by |
2975 // constructors. We define a new property whenever there is an | 2979 // constructors. We define a new property whenever there is an |
2976 // assignment to a property of 'this'. We should probably only add | 2980 // assignment to a property of 'this'. We should probably only add |
2977 // properties if we haven't seen them before. Otherwise we'll | 2981 // properties if we haven't seen them before. Otherwise we'll |
2978 // probably overestimate the number of properties. | 2982 // probably overestimate the number of properties. |
2979 Property* property = expression ? expression->AsProperty() : NULL; | 2983 Property* property = expression ? expression->AsProperty() : NULL; |
2980 if (op == Token::ASSIGN && | 2984 if (op == Token::ASSIGN && |
2981 property != NULL && | 2985 property != NULL && |
2982 property->obj()->AsVariableProxy() != NULL && | 2986 property->obj()->AsVariableProxy() != NULL && |
2983 property->obj()->AsVariableProxy()->is_this()) { | 2987 property->obj()->AsVariableProxy()->is_this()) { |
2984 current_function_state_->AddProperty(); | 2988 function_state_->AddProperty(); |
2985 } | 2989 } |
2986 | 2990 |
2987 // If we assign a function literal to a property we pretenure the | 2991 // If we assign a function literal to a property we pretenure the |
2988 // literal so it can be added as a constant function property. | 2992 // literal so it can be added as a constant function property. |
2989 if (property != NULL && right->AsFunctionLiteral() != NULL) { | 2993 if (property != NULL && right->AsFunctionLiteral() != NULL) { |
2990 right->AsFunctionLiteral()->set_pretenure(); | 2994 right->AsFunctionLiteral()->set_pretenure(); |
2991 } | 2995 } |
2992 | 2996 |
2993 if (fni_ != NULL) { | 2997 if (fni_ != NULL) { |
2994 // Check if the right hand side is a call to avoid inferring a | 2998 // Check if the right hand side is a call to avoid inferring a |
(...skipping 15 matching lines...) Expand all Loading... |
3010 | 3014 |
3011 | 3015 |
3012 Expression* Parser::ParseYieldExpression(bool* ok) { | 3016 Expression* Parser::ParseYieldExpression(bool* ok) { |
3013 // YieldExpression :: | 3017 // YieldExpression :: |
3014 // 'yield' '*'? AssignmentExpression | 3018 // 'yield' '*'? AssignmentExpression |
3015 int pos = peek_position(); | 3019 int pos = peek_position(); |
3016 Expect(Token::YIELD, CHECK_OK); | 3020 Expect(Token::YIELD, CHECK_OK); |
3017 Yield::Kind kind = | 3021 Yield::Kind kind = |
3018 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; | 3022 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; |
3019 Expression* generator_object = factory()->NewVariableProxy( | 3023 Expression* generator_object = factory()->NewVariableProxy( |
3020 current_function_state_->generator_object_variable()); | 3024 function_state_->generator_object_variable()); |
3021 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); | 3025 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); |
3022 Yield* yield = factory()->NewYield(generator_object, expression, kind, pos); | 3026 Yield* yield = factory()->NewYield(generator_object, expression, kind, pos); |
3023 if (kind == Yield::DELEGATING) { | 3027 if (kind == Yield::DELEGATING) { |
3024 yield->set_index(current_function_state_->NextHandlerIndex()); | 3028 yield->set_index(function_state_->NextHandlerIndex()); |
3025 } | 3029 } |
3026 return yield; | 3030 return yield; |
3027 } | 3031 } |
3028 | 3032 |
3029 | 3033 |
3030 // Precedence = 3 | 3034 // Precedence = 3 |
3031 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { | 3035 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { |
3032 // ConditionalExpression :: | 3036 // ConditionalExpression :: |
3033 // LogicalOrExpression | 3037 // LogicalOrExpression |
3034 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 3038 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3178 return factory()->NewNumberLiteral(-value, pos); | 3182 return factory()->NewNumberLiteral(-value, pos); |
3179 case Token::BIT_NOT: | 3183 case Token::BIT_NOT: |
3180 return factory()->NewNumberLiteral(~DoubleToInt32(value), pos); | 3184 return factory()->NewNumberLiteral(~DoubleToInt32(value), pos); |
3181 default: | 3185 default: |
3182 break; | 3186 break; |
3183 } | 3187 } |
3184 } | 3188 } |
3185 } | 3189 } |
3186 | 3190 |
3187 // "delete identifier" is a syntax error in strict mode. | 3191 // "delete identifier" is a syntax error in strict mode. |
3188 if (op == Token::DELETE && !top_scope_->is_classic_mode()) { | 3192 if (op == Token::DELETE && !scope_->is_classic_mode()) { |
3189 VariableProxy* operand = expression->AsVariableProxy(); | 3193 VariableProxy* operand = expression->AsVariableProxy(); |
3190 if (operand != NULL && !operand->is_this()) { | 3194 if (operand != NULL && !operand->is_this()) { |
3191 ReportMessage("strict_delete", Vector<const char*>::empty()); | 3195 ReportMessage("strict_delete", Vector<const char*>::empty()); |
3192 *ok = false; | 3196 *ok = false; |
3193 return NULL; | 3197 return NULL; |
3194 } | 3198 } |
3195 } | 3199 } |
3196 | 3200 |
3197 // Desugar '+foo' into 'foo*1', this enables the collection of type feedback | 3201 // Desugar '+foo' into 'foo*1', this enables the collection of type feedback |
3198 // without any special stub and the multiplication is removed later in | 3202 // without any special stub and the multiplication is removed later in |
(...skipping 27 matching lines...) Expand all Loading... |
3226 // Signal a reference error if the expression is an invalid | 3230 // Signal a reference error if the expression is an invalid |
3227 // left-hand side expression. We could report this as a syntax | 3231 // left-hand side expression. We could report this as a syntax |
3228 // error here but for compatibility with JSC we choose to report the | 3232 // error here but for compatibility with JSC we choose to report the |
3229 // error at runtime. | 3233 // error at runtime. |
3230 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3234 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
3231 Handle<String> message = | 3235 Handle<String> message = |
3232 isolate()->factory()->invalid_lhs_in_prefix_op_string(); | 3236 isolate()->factory()->invalid_lhs_in_prefix_op_string(); |
3233 expression = NewThrowReferenceError(message); | 3237 expression = NewThrowReferenceError(message); |
3234 } | 3238 } |
3235 | 3239 |
3236 if (!top_scope_->is_classic_mode()) { | 3240 if (!scope_->is_classic_mode()) { |
3237 // Prefix expression operand in strict mode may not be eval or arguments. | 3241 // Prefix expression operand in strict mode may not be eval or arguments. |
3238 CheckStrictModeLValue(expression, CHECK_OK); | 3242 CheckStrictModeLValue(expression, CHECK_OK); |
3239 } | 3243 } |
3240 MarkAsLValue(expression); | 3244 MarkAsLValue(expression); |
3241 | 3245 |
3242 return factory()->NewCountOperation(op, | 3246 return factory()->NewCountOperation(op, |
3243 true /* prefix */, | 3247 true /* prefix */, |
3244 expression, | 3248 expression, |
3245 position()); | 3249 position()); |
3246 | 3250 |
(...skipping 13 matching lines...) Expand all Loading... |
3260 // Signal a reference error if the expression is an invalid | 3264 // Signal a reference error if the expression is an invalid |
3261 // left-hand side expression. We could report this as a syntax | 3265 // left-hand side expression. We could report this as a syntax |
3262 // error here but for compatibility with JSC we choose to report the | 3266 // error here but for compatibility with JSC we choose to report the |
3263 // error at runtime. | 3267 // error at runtime. |
3264 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3268 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
3265 Handle<String> message = | 3269 Handle<String> message = |
3266 isolate()->factory()->invalid_lhs_in_postfix_op_string(); | 3270 isolate()->factory()->invalid_lhs_in_postfix_op_string(); |
3267 expression = NewThrowReferenceError(message); | 3271 expression = NewThrowReferenceError(message); |
3268 } | 3272 } |
3269 | 3273 |
3270 if (!top_scope_->is_classic_mode()) { | 3274 if (!scope_->is_classic_mode()) { |
3271 // Postfix expression operand in strict mode may not be eval or arguments. | 3275 // Postfix expression operand in strict mode may not be eval or arguments. |
3272 CheckStrictModeLValue(expression, CHECK_OK); | 3276 CheckStrictModeLValue(expression, CHECK_OK); |
3273 } | 3277 } |
3274 MarkAsLValue(expression); | 3278 MarkAsLValue(expression); |
3275 | 3279 |
3276 Token::Value next = Next(); | 3280 Token::Value next = Next(); |
3277 expression = | 3281 expression = |
3278 factory()->NewCountOperation(next, | 3282 factory()->NewCountOperation(next, |
3279 false /* postfix */, | 3283 false /* postfix */, |
3280 expression, | 3284 expression, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3331 // Keep track of eval() calls since they disable all local variable | 3335 // Keep track of eval() calls since they disable all local variable |
3332 // optimizations. | 3336 // optimizations. |
3333 // The calls that need special treatment are the | 3337 // The calls that need special treatment are the |
3334 // direct eval calls. These calls are all of the form eval(...), with | 3338 // direct eval calls. These calls are all of the form eval(...), with |
3335 // no explicit receiver. | 3339 // no explicit receiver. |
3336 // These calls are marked as potentially direct eval calls. Whether | 3340 // These calls are marked as potentially direct eval calls. Whether |
3337 // they are actually direct calls to eval is determined at run time. | 3341 // they are actually direct calls to eval is determined at run time. |
3338 VariableProxy* callee = result->AsVariableProxy(); | 3342 VariableProxy* callee = result->AsVariableProxy(); |
3339 if (callee != NULL && | 3343 if (callee != NULL && |
3340 callee->IsVariable(isolate()->factory()->eval_string())) { | 3344 callee->IsVariable(isolate()->factory()->eval_string())) { |
3341 top_scope_->DeclarationScope()->RecordEvalCall(); | 3345 scope_->DeclarationScope()->RecordEvalCall(); |
3342 } | 3346 } |
3343 result = factory()->NewCall(result, args, pos); | 3347 result = factory()->NewCall(result, args, pos); |
3344 if (fni_ != NULL) fni_->RemoveLastFunction(); | 3348 if (fni_ != NULL) fni_->RemoveLastFunction(); |
3345 break; | 3349 break; |
3346 } | 3350 } |
3347 | 3351 |
3348 case Token::PERIOD: { | 3352 case Token::PERIOD: { |
3349 Consume(Token::PERIOD); | 3353 Consume(Token::PERIOD); |
3350 int pos = position(); | 3354 int pos = position(); |
3351 Handle<String> name = ParseIdentifierName(CHECK_OK); | 3355 Handle<String> name = ParseIdentifierName(CHECK_OK); |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3515 // ArrayLiteral | 3519 // ArrayLiteral |
3516 // ObjectLiteral | 3520 // ObjectLiteral |
3517 // RegExpLiteral | 3521 // RegExpLiteral |
3518 // '(' Expression ')' | 3522 // '(' Expression ')' |
3519 | 3523 |
3520 int pos = peek_position(); | 3524 int pos = peek_position(); |
3521 Expression* result = NULL; | 3525 Expression* result = NULL; |
3522 switch (peek()) { | 3526 switch (peek()) { |
3523 case Token::THIS: { | 3527 case Token::THIS: { |
3524 Consume(Token::THIS); | 3528 Consume(Token::THIS); |
3525 result = factory()->NewVariableProxy(top_scope_->receiver()); | 3529 result = factory()->NewVariableProxy(scope_->receiver()); |
3526 break; | 3530 break; |
3527 } | 3531 } |
3528 | 3532 |
3529 case Token::NULL_LITERAL: | 3533 case Token::NULL_LITERAL: |
3530 Consume(Token::NULL_LITERAL); | 3534 Consume(Token::NULL_LITERAL); |
3531 result = factory()->NewLiteral(isolate()->factory()->null_value(), pos); | 3535 result = factory()->NewLiteral(isolate()->factory()->null_value(), pos); |
3532 break; | 3536 break; |
3533 | 3537 |
3534 case Token::TRUE_LITERAL: | 3538 case Token::TRUE_LITERAL: |
3535 Consume(Token::TRUE_LITERAL); | 3539 Consume(Token::TRUE_LITERAL); |
(...skipping 10 matching lines...) Expand all Loading... |
3546 case Token::FUTURE_STRICT_RESERVED_WORD: { | 3550 case Token::FUTURE_STRICT_RESERVED_WORD: { |
3547 // Using eval or arguments in this context is OK even in strict mode. | 3551 // Using eval or arguments in this context is OK even in strict mode. |
3548 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 3552 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
3549 if (fni_ != NULL) fni_->PushVariableName(name); | 3553 if (fni_ != NULL) fni_->PushVariableName(name); |
3550 // The name may refer to a module instance object, so its type is unknown. | 3554 // The name may refer to a module instance object, so its type is unknown. |
3551 #ifdef DEBUG | 3555 #ifdef DEBUG |
3552 if (FLAG_print_interface_details) | 3556 if (FLAG_print_interface_details) |
3553 PrintF("# Variable %s ", name->ToAsciiArray()); | 3557 PrintF("# Variable %s ", name->ToAsciiArray()); |
3554 #endif | 3558 #endif |
3555 Interface* interface = Interface::NewUnknown(zone()); | 3559 Interface* interface = Interface::NewUnknown(zone()); |
3556 result = top_scope_->NewUnresolved(factory(), name, interface, pos); | 3560 result = scope_->NewUnresolved(factory(), name, interface, pos); |
3557 break; | 3561 break; |
3558 } | 3562 } |
3559 | 3563 |
3560 case Token::NUMBER: { | 3564 case Token::NUMBER: { |
3561 Consume(Token::NUMBER); | 3565 Consume(Token::NUMBER); |
3562 ASSERT(scanner().is_literal_ascii()); | 3566 ASSERT(scanner().is_literal_ascii()); |
3563 double value = StringToDouble(isolate()->unicode_cache(), | 3567 double value = StringToDouble(isolate()->unicode_cache(), |
3564 scanner().literal_ascii_string(), | 3568 scanner().literal_ascii_string(), |
3565 ALLOW_HEX | ALLOW_OCTAL | | 3569 ALLOW_HEX | ALLOW_OCTAL | |
3566 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); | 3570 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3636 elem = ParseAssignmentExpression(true, CHECK_OK); | 3640 elem = ParseAssignmentExpression(true, CHECK_OK); |
3637 } | 3641 } |
3638 values->Add(elem, zone()); | 3642 values->Add(elem, zone()); |
3639 if (peek() != Token::RBRACK) { | 3643 if (peek() != Token::RBRACK) { |
3640 Expect(Token::COMMA, CHECK_OK); | 3644 Expect(Token::COMMA, CHECK_OK); |
3641 } | 3645 } |
3642 } | 3646 } |
3643 Expect(Token::RBRACK, CHECK_OK); | 3647 Expect(Token::RBRACK, CHECK_OK); |
3644 | 3648 |
3645 // Update the scope information before the pre-parsing bailout. | 3649 // Update the scope information before the pre-parsing bailout. |
3646 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); | 3650 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
3647 | 3651 |
3648 return factory()->NewArrayLiteral(values, literal_index, pos); | 3652 return factory()->NewArrayLiteral(values, literal_index, pos); |
3649 } | 3653 } |
3650 | 3654 |
3651 | 3655 |
3652 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { | 3656 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { |
3653 if (expression->AsLiteral() != NULL) return true; | 3657 if (expression->AsLiteral() != NULL) return true; |
3654 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); | 3658 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); |
3655 return lit != NULL && lit->is_simple(); | 3659 return lit != NULL && lit->is_simple(); |
3656 } | 3660 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3698 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 3702 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
3699 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 3703 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
3700 // )*[','] '}' | 3704 // )*[','] '}' |
3701 | 3705 |
3702 int pos = peek_position(); | 3706 int pos = peek_position(); |
3703 ZoneList<ObjectLiteral::Property*>* properties = | 3707 ZoneList<ObjectLiteral::Property*>* properties = |
3704 new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone()); | 3708 new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone()); |
3705 int number_of_boilerplate_properties = 0; | 3709 int number_of_boilerplate_properties = 0; |
3706 bool has_function = false; | 3710 bool has_function = false; |
3707 | 3711 |
3708 ObjectLiteralChecker checker(this, top_scope_->language_mode()); | 3712 ObjectLiteralChecker checker(this, scope_->language_mode()); |
3709 | 3713 |
3710 Expect(Token::LBRACE, CHECK_OK); | 3714 Expect(Token::LBRACE, CHECK_OK); |
3711 | 3715 |
3712 while (peek() != Token::RBRACE) { | 3716 while (peek() != Token::RBRACE) { |
3713 if (fni_ != NULL) fni_->Enter(); | 3717 if (fni_ != NULL) fni_->Enter(); |
3714 | 3718 |
3715 Literal* key = NULL; | 3719 Literal* key = NULL; |
3716 Token::Value next = peek(); | 3720 Token::Value next = peek(); |
3717 int next_pos = peek_position(); | 3721 int next_pos = peek_position(); |
3718 | 3722 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3819 | 3823 |
3820 Expect(Token::COLON, CHECK_OK); | 3824 Expect(Token::COLON, CHECK_OK); |
3821 Expression* value = ParseAssignmentExpression(true, CHECK_OK); | 3825 Expression* value = ParseAssignmentExpression(true, CHECK_OK); |
3822 | 3826 |
3823 ObjectLiteral::Property* property = | 3827 ObjectLiteral::Property* property = |
3824 factory()->NewObjectLiteralProperty(key, value); | 3828 factory()->NewObjectLiteralProperty(key, value); |
3825 | 3829 |
3826 // Mark top-level object literals that contain function literals and | 3830 // Mark top-level object literals that contain function literals and |
3827 // pretenure the literal so it can be added as a constant function | 3831 // pretenure the literal so it can be added as a constant function |
3828 // property. | 3832 // property. |
3829 if (top_scope_->DeclarationScope()->is_global_scope() && | 3833 if (scope_->DeclarationScope()->is_global_scope() && |
3830 value->AsFunctionLiteral() != NULL) { | 3834 value->AsFunctionLiteral() != NULL) { |
3831 has_function = true; | 3835 has_function = true; |
3832 value->AsFunctionLiteral()->set_pretenure(); | 3836 value->AsFunctionLiteral()->set_pretenure(); |
3833 } | 3837 } |
3834 | 3838 |
3835 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 3839 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
3836 if (ObjectLiteral::IsBoilerplateProperty(property)) { | 3840 if (ObjectLiteral::IsBoilerplateProperty(property)) { |
3837 number_of_boilerplate_properties++; | 3841 number_of_boilerplate_properties++; |
3838 } | 3842 } |
3839 properties->Add(property, zone()); | 3843 properties->Add(property, zone()); |
3840 | 3844 |
3841 // TODO(1240767): Consider allowing trailing comma. | 3845 // TODO(1240767): Consider allowing trailing comma. |
3842 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | 3846 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
3843 | 3847 |
3844 if (fni_ != NULL) { | 3848 if (fni_ != NULL) { |
3845 fni_->Infer(); | 3849 fni_->Infer(); |
3846 fni_->Leave(); | 3850 fni_->Leave(); |
3847 } | 3851 } |
3848 } | 3852 } |
3849 Expect(Token::RBRACE, CHECK_OK); | 3853 Expect(Token::RBRACE, CHECK_OK); |
3850 | 3854 |
3851 // Computation of literal_index must happen before pre parse bailout. | 3855 // Computation of literal_index must happen before pre parse bailout. |
3852 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); | 3856 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
3853 | 3857 |
3854 return factory()->NewObjectLiteral(properties, | 3858 return factory()->NewObjectLiteral(properties, |
3855 literal_index, | 3859 literal_index, |
3856 number_of_boilerplate_properties, | 3860 number_of_boilerplate_properties, |
3857 has_function, | 3861 has_function, |
3858 pos); | 3862 pos); |
3859 } | 3863 } |
3860 | 3864 |
3861 | 3865 |
3862 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { | 3866 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4020 // either information available directly, especially not when lazily compiling | 4024 // either information available directly, especially not when lazily compiling |
4021 // a function like 'g'. We hence rely on the following invariants: | 4025 // a function like 'g'. We hence rely on the following invariants: |
4022 // - (1) is the case iff the innermost scope of the deserialized scope chain | 4026 // - (1) is the case iff the innermost scope of the deserialized scope chain |
4023 // under which we compile is _not_ a declaration scope. This holds because | 4027 // under which we compile is _not_ a declaration scope. This holds because |
4024 // in all normal cases, function declarations are fully hoisted to a | 4028 // in all normal cases, function declarations are fully hoisted to a |
4025 // declaration scope and compiled relative to that. | 4029 // declaration scope and compiled relative to that. |
4026 // - (2) is the case iff the current declaration scope is still the original | 4030 // - (2) is the case iff the current declaration scope is still the original |
4027 // one relative to the deserialized scope chain. Otherwise we must be | 4031 // one relative to the deserialized scope chain. Otherwise we must be |
4028 // compiling a function in an inner declaration scope in the eval, e.g. a | 4032 // compiling a function in an inner declaration scope in the eval, e.g. a |
4029 // nested function, and hoisting works normally relative to that. | 4033 // nested function, and hoisting works normally relative to that. |
4030 Scope* declaration_scope = top_scope_->DeclarationScope(); | 4034 Scope* declaration_scope = scope_->DeclarationScope(); |
4031 Scope* original_declaration_scope = original_scope_->DeclarationScope(); | 4035 Scope* original_declaration_scope = original_scope_->DeclarationScope(); |
4032 Scope* scope = | 4036 Scope* scope = |
4033 function_type == FunctionLiteral::DECLARATION && !is_extended_mode() && | 4037 function_type == FunctionLiteral::DECLARATION && !is_extended_mode() && |
4034 (original_scope_ == original_declaration_scope || | 4038 (original_scope_ == original_declaration_scope || |
4035 declaration_scope != original_declaration_scope) | 4039 declaration_scope != original_declaration_scope) |
4036 ? NewScope(declaration_scope, FUNCTION_SCOPE) | 4040 ? NewScope(declaration_scope, FUNCTION_SCOPE) |
4037 : NewScope(top_scope_, FUNCTION_SCOPE); | 4041 : NewScope(scope_, FUNCTION_SCOPE); |
4038 ZoneList<Statement*>* body = NULL; | 4042 ZoneList<Statement*>* body = NULL; |
4039 int materialized_literal_count = -1; | 4043 int materialized_literal_count = -1; |
4040 int expected_property_count = -1; | 4044 int expected_property_count = -1; |
4041 int handler_count = 0; | 4045 int handler_count = 0; |
4042 FunctionLiteral::ParameterFlag duplicate_parameters = | 4046 FunctionLiteral::ParameterFlag duplicate_parameters = |
4043 FunctionLiteral::kNoDuplicateParameters; | 4047 FunctionLiteral::kNoDuplicateParameters; |
4044 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ | 4048 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ |
4045 ? FunctionLiteral::kIsParenthesized | 4049 ? FunctionLiteral::kIsParenthesized |
4046 : FunctionLiteral::kNotParenthesized; | 4050 : FunctionLiteral::kNotParenthesized; |
4047 FunctionLiteral::IsGeneratorFlag generator = is_generator | 4051 FunctionLiteral::IsGeneratorFlag generator = is_generator |
4048 ? FunctionLiteral::kIsGenerator | 4052 ? FunctionLiteral::kIsGenerator |
4049 : FunctionLiteral::kNotGenerator; | 4053 : FunctionLiteral::kNotGenerator; |
4050 DeferredFeedbackSlotProcessor* slot_processor; | 4054 DeferredFeedbackSlotProcessor* slot_processor; |
4051 AstProperties ast_properties; | 4055 AstProperties ast_properties; |
4052 BailoutReason dont_optimize_reason = kNoReason; | 4056 BailoutReason dont_optimize_reason = kNoReason; |
4053 // Parse function body. | 4057 // Parse function body. |
4054 { FunctionState function_state(this, scope); | 4058 { FunctionState function_state(&function_state_, &scope_, scope, zone()); |
4055 top_scope_->SetScopeName(function_name); | 4059 scope_->SetScopeName(function_name); |
4056 | 4060 |
4057 if (is_generator) { | 4061 if (is_generator) { |
4058 // For generators, allocating variables in contexts is currently a win | 4062 // For generators, allocating variables in contexts is currently a win |
4059 // because it minimizes the work needed to suspend and resume an | 4063 // because it minimizes the work needed to suspend and resume an |
4060 // activation. | 4064 // activation. |
4061 top_scope_->ForceContextAllocation(); | 4065 scope_->ForceContextAllocation(); |
4062 | 4066 |
4063 // Calling a generator returns a generator object. That object is stored | 4067 // Calling a generator returns a generator object. That object is stored |
4064 // in a temporary variable, a definition that is used by "yield" | 4068 // in a temporary variable, a definition that is used by "yield" |
4065 // expressions. Presence of a variable for the generator object in the | 4069 // expressions. Presence of a variable for the generator object in the |
4066 // FunctionState indicates that this function is a generator. | 4070 // FunctionState indicates that this function is a generator. |
4067 Variable* temp = top_scope_->DeclarationScope()->NewTemporary( | 4071 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
4068 isolate()->factory()->dot_generator_object_string()); | 4072 isolate()->factory()->dot_generator_object_string()); |
4069 function_state.set_generator_object_variable(temp); | 4073 function_state.set_generator_object_variable(temp); |
4070 } | 4074 } |
4071 | 4075 |
4072 // FormalParameterList :: | 4076 // FormalParameterList :: |
4073 // '(' (Identifier)*[','] ')' | 4077 // '(' (Identifier)*[','] ')' |
4074 Expect(Token::LPAREN, CHECK_OK); | 4078 Expect(Token::LPAREN, CHECK_OK); |
4075 scope->set_start_position(scanner().location().beg_pos); | 4079 scope->set_start_position(scanner().location().beg_pos); |
4076 | 4080 |
4077 // We don't yet know if the function will be strict, so we cannot yet | 4081 // We don't yet know if the function will be strict, so we cannot yet |
4078 // produce errors for parameter names or duplicates. However, we remember | 4082 // produce errors for parameter names or duplicates. However, we remember |
4079 // the locations of these errors if they occur and produce the errors later. | 4083 // the locations of these errors if they occur and produce the errors later. |
4080 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); | 4084 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); |
4081 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | 4085 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); |
4082 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 4086 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
4083 | 4087 |
4084 bool done = (peek() == Token::RPAREN); | 4088 bool done = (peek() == Token::RPAREN); |
4085 while (!done) { | 4089 while (!done) { |
4086 bool is_strict_reserved = false; | 4090 bool is_strict_reserved = false; |
4087 Handle<String> param_name = | 4091 Handle<String> param_name = |
4088 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 4092 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
4089 | 4093 |
4090 // Store locations for possible future error reports. | 4094 // Store locations for possible future error reports. |
4091 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { | 4095 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { |
4092 eval_args_error_log = scanner().location(); | 4096 eval_args_error_log = scanner().location(); |
4093 } | 4097 } |
4094 if (!reserved_loc.IsValid() && is_strict_reserved) { | 4098 if (!reserved_loc.IsValid() && is_strict_reserved) { |
4095 reserved_loc = scanner().location(); | 4099 reserved_loc = scanner().location(); |
4096 } | 4100 } |
4097 if (!dupe_error_loc.IsValid() && top_scope_->IsDeclared(param_name)) { | 4101 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { |
4098 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; | 4102 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; |
4099 dupe_error_loc = scanner().location(); | 4103 dupe_error_loc = scanner().location(); |
4100 } | 4104 } |
4101 | 4105 |
4102 top_scope_->DeclareParameter(param_name, VAR); | 4106 scope_->DeclareParameter(param_name, VAR); |
4103 num_parameters++; | 4107 num_parameters++; |
4104 if (num_parameters > Code::kMaxArguments) { | 4108 if (num_parameters > Code::kMaxArguments) { |
4105 ReportMessageAt(scanner().location(), "too_many_parameters"); | 4109 ReportMessageAt(scanner().location(), "too_many_parameters"); |
4106 *ok = false; | 4110 *ok = false; |
4107 return NULL; | 4111 return NULL; |
4108 } | 4112 } |
4109 done = (peek() == Token::RPAREN); | 4113 done = (peek() == Token::RPAREN); |
4110 if (!done) Expect(Token::COMMA, CHECK_OK); | 4114 if (!done) Expect(Token::COMMA, CHECK_OK); |
4111 } | 4115 } |
4112 Expect(Token::RPAREN, CHECK_OK); | 4116 Expect(Token::RPAREN, CHECK_OK); |
4113 | 4117 |
4114 Expect(Token::LBRACE, CHECK_OK); | 4118 Expect(Token::LBRACE, CHECK_OK); |
4115 | 4119 |
4116 // If we have a named function expression, we add a local variable | 4120 // If we have a named function expression, we add a local variable |
4117 // declaration to the body of the function with the name of the | 4121 // declaration to the body of the function with the name of the |
4118 // function and let it refer to the function itself (closure). | 4122 // function and let it refer to the function itself (closure). |
4119 // NOTE: We create a proxy and resolve it here so that in the | 4123 // NOTE: We create a proxy and resolve it here so that in the |
4120 // future we can change the AST to only refer to VariableProxies | 4124 // future we can change the AST to only refer to VariableProxies |
4121 // instead of Variables and Proxis as is the case now. | 4125 // instead of Variables and Proxis as is the case now. |
4122 Variable* fvar = NULL; | 4126 Variable* fvar = NULL; |
4123 Token::Value fvar_init_op = Token::INIT_CONST; | 4127 Token::Value fvar_init_op = Token::INIT_CONST; |
4124 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 4128 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
4125 if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY; | 4129 if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY; |
4126 VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST; | 4130 VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST; |
4127 fvar = new(zone()) Variable(top_scope_, | 4131 fvar = new(zone()) Variable(scope_, |
4128 function_name, fvar_mode, true /* is valid LHS */, | 4132 function_name, fvar_mode, true /* is valid LHS */, |
4129 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); | 4133 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); |
4130 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 4134 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
4131 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( | 4135 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
4132 proxy, fvar_mode, top_scope_, RelocInfo::kNoPosition); | 4136 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); |
4133 top_scope_->DeclareFunctionVar(fvar_declaration); | 4137 scope_->DeclareFunctionVar(fvar_declaration); |
4134 } | 4138 } |
4135 | 4139 |
4136 // Determine whether the function will be lazily compiled. | 4140 // Determine whether the function will be lazily compiled. |
4137 // The heuristics are: | 4141 // The heuristics are: |
4138 // - It must not have been prohibited by the caller to Parse (some callers | 4142 // - It must not have been prohibited by the caller to Parse (some callers |
4139 // need a full AST). | 4143 // need a full AST). |
4140 // - The outer scope must allow lazy compilation of inner functions. | 4144 // - The outer scope must allow lazy compilation of inner functions. |
4141 // - The function mustn't be a function expression with an open parenthesis | 4145 // - The function mustn't be a function expression with an open parenthesis |
4142 // before; we consider that a hint that the function will be called | 4146 // before; we consider that a hint that the function will be called |
4143 // immediately, and it would be a waste of time to make it lazily | 4147 // immediately, and it would be a waste of time to make it lazily |
4144 // compiled. | 4148 // compiled. |
4145 // These are all things we can know at this point, without looking at the | 4149 // These are all things we can know at this point, without looking at the |
4146 // function itself. | 4150 // function itself. |
4147 bool is_lazily_compiled = (mode() == PARSE_LAZILY && | 4151 bool is_lazily_compiled = (mode() == PARSE_LAZILY && |
4148 top_scope_->AllowsLazyCompilation() && | 4152 scope_->AllowsLazyCompilation() && |
4149 !parenthesized_function_); | 4153 !parenthesized_function_); |
4150 parenthesized_function_ = false; // The bit was set for this function only. | 4154 parenthesized_function_ = false; // The bit was set for this function only. |
4151 | 4155 |
4152 if (is_lazily_compiled) { | 4156 if (is_lazily_compiled) { |
4153 int function_block_pos = position(); | 4157 int function_block_pos = position(); |
4154 FunctionEntry entry; | 4158 FunctionEntry entry; |
4155 if (pre_parse_data_ != NULL) { | 4159 if (pre_parse_data_ != NULL) { |
4156 // If we have pre_parse_data_, we use it to skip parsing the function | 4160 // If we have pre_parse_data_, we use it to skip parsing the function |
4157 // body. The preparser data contains the information we need to | 4161 // body. The preparser data contains the information we need to |
4158 // construct the lazy function. | 4162 // construct the lazy function. |
4159 entry = pre_parse_data()->GetFunctionEntry(function_block_pos); | 4163 entry = pre_parse_data()->GetFunctionEntry(function_block_pos); |
4160 if (entry.is_valid()) { | 4164 if (entry.is_valid()) { |
4161 if (entry.end_pos() <= function_block_pos) { | 4165 if (entry.end_pos() <= function_block_pos) { |
4162 // End position greater than end of stream is safe, and hard | 4166 // End position greater than end of stream is safe, and hard |
4163 // to check. | 4167 // to check. |
4164 ReportInvalidPreparseData(function_name, CHECK_OK); | 4168 ReportInvalidPreparseData(function_name, CHECK_OK); |
4165 } | 4169 } |
4166 scanner().SeekForward(entry.end_pos() - 1); | 4170 scanner().SeekForward(entry.end_pos() - 1); |
4167 | 4171 |
4168 scope->set_end_position(entry.end_pos()); | 4172 scope->set_end_position(entry.end_pos()); |
4169 Expect(Token::RBRACE, CHECK_OK); | 4173 Expect(Token::RBRACE, CHECK_OK); |
4170 isolate()->counters()->total_preparse_skipped()->Increment( | 4174 isolate()->counters()->total_preparse_skipped()->Increment( |
4171 scope->end_position() - function_block_pos); | 4175 scope->end_position() - function_block_pos); |
4172 materialized_literal_count = entry.literal_count(); | 4176 materialized_literal_count = entry.literal_count(); |
4173 expected_property_count = entry.property_count(); | 4177 expected_property_count = entry.property_count(); |
4174 top_scope_->SetLanguageMode(entry.language_mode()); | 4178 scope_->SetLanguageMode(entry.language_mode()); |
4175 } else { | 4179 } else { |
4176 is_lazily_compiled = false; | 4180 is_lazily_compiled = false; |
4177 } | 4181 } |
4178 } else { | 4182 } else { |
4179 // With no preparser data, we partially parse the function, without | 4183 // With no preparser data, we partially parse the function, without |
4180 // building an AST. This gathers the data needed to build a lazy | 4184 // building an AST. This gathers the data needed to build a lazy |
4181 // function. | 4185 // function. |
4182 SingletonLogger logger; | 4186 SingletonLogger logger; |
4183 PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger); | 4187 PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger); |
4184 if (result == PreParser::kPreParseStackOverflow) { | 4188 if (result == PreParser::kPreParseStackOverflow) { |
(...skipping 14 matching lines...) Expand all Loading... |
4199 args); | 4203 args); |
4200 *ok = false; | 4204 *ok = false; |
4201 return NULL; | 4205 return NULL; |
4202 } | 4206 } |
4203 scope->set_end_position(logger.end()); | 4207 scope->set_end_position(logger.end()); |
4204 Expect(Token::RBRACE, CHECK_OK); | 4208 Expect(Token::RBRACE, CHECK_OK); |
4205 isolate()->counters()->total_preparse_skipped()->Increment( | 4209 isolate()->counters()->total_preparse_skipped()->Increment( |
4206 scope->end_position() - function_block_pos); | 4210 scope->end_position() - function_block_pos); |
4207 materialized_literal_count = logger.literals(); | 4211 materialized_literal_count = logger.literals(); |
4208 expected_property_count = logger.properties(); | 4212 expected_property_count = logger.properties(); |
4209 top_scope_->SetLanguageMode(logger.language_mode()); | 4213 scope_->SetLanguageMode(logger.language_mode()); |
4210 } | 4214 } |
4211 } | 4215 } |
4212 | 4216 |
4213 if (!is_lazily_compiled) { | 4217 if (!is_lazily_compiled) { |
4214 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 4218 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
4215 body = new(zone()) ZoneList<Statement*>(8, zone()); | 4219 body = new(zone()) ZoneList<Statement*>(8, zone()); |
4216 if (fvar != NULL) { | 4220 if (fvar != NULL) { |
4217 VariableProxy* fproxy = top_scope_->NewUnresolved( | 4221 VariableProxy* fproxy = scope_->NewUnresolved( |
4218 factory(), function_name, Interface::NewConst()); | 4222 factory(), function_name, Interface::NewConst()); |
4219 fproxy->BindTo(fvar); | 4223 fproxy->BindTo(fvar); |
4220 body->Add(factory()->NewExpressionStatement( | 4224 body->Add(factory()->NewExpressionStatement( |
4221 factory()->NewAssignment(fvar_init_op, | 4225 factory()->NewAssignment(fvar_init_op, |
4222 fproxy, | 4226 fproxy, |
4223 factory()->NewThisFunction(pos), | 4227 factory()->NewThisFunction(pos), |
4224 RelocInfo::kNoPosition), | 4228 RelocInfo::kNoPosition), |
4225 RelocInfo::kNoPosition), zone()); | 4229 RelocInfo::kNoPosition), zone()); |
4226 } | 4230 } |
4227 | 4231 |
4228 // For generators, allocate and yield an iterator on function entry. | 4232 // For generators, allocate and yield an iterator on function entry. |
4229 if (is_generator) { | 4233 if (is_generator) { |
4230 ZoneList<Expression*>* arguments = | 4234 ZoneList<Expression*>* arguments = |
4231 new(zone()) ZoneList<Expression*>(0, zone()); | 4235 new(zone()) ZoneList<Expression*>(0, zone()); |
4232 CallRuntime* allocation = factory()->NewCallRuntime( | 4236 CallRuntime* allocation = factory()->NewCallRuntime( |
4233 isolate()->factory()->empty_string(), | 4237 isolate()->factory()->empty_string(), |
4234 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), | 4238 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), |
4235 arguments, pos); | 4239 arguments, pos); |
4236 VariableProxy* init_proxy = factory()->NewVariableProxy( | 4240 VariableProxy* init_proxy = factory()->NewVariableProxy( |
4237 current_function_state_->generator_object_variable()); | 4241 function_state_->generator_object_variable()); |
4238 Assignment* assignment = factory()->NewAssignment( | 4242 Assignment* assignment = factory()->NewAssignment( |
4239 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); | 4243 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); |
4240 VariableProxy* get_proxy = factory()->NewVariableProxy( | 4244 VariableProxy* get_proxy = factory()->NewVariableProxy( |
4241 current_function_state_->generator_object_variable()); | 4245 function_state_->generator_object_variable()); |
4242 Yield* yield = factory()->NewYield( | 4246 Yield* yield = factory()->NewYield( |
4243 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); | 4247 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); |
4244 body->Add(factory()->NewExpressionStatement( | 4248 body->Add(factory()->NewExpressionStatement( |
4245 yield, RelocInfo::kNoPosition), zone()); | 4249 yield, RelocInfo::kNoPosition), zone()); |
4246 } | 4250 } |
4247 | 4251 |
4248 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); | 4252 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); |
4249 | 4253 |
4250 if (is_generator) { | 4254 if (is_generator) { |
4251 VariableProxy* get_proxy = factory()->NewVariableProxy( | 4255 VariableProxy* get_proxy = factory()->NewVariableProxy( |
4252 current_function_state_->generator_object_variable()); | 4256 function_state_->generator_object_variable()); |
4253 Expression *undefined = factory()->NewLiteral( | 4257 Expression *undefined = factory()->NewLiteral( |
4254 isolate()->factory()->undefined_value(), RelocInfo::kNoPosition); | 4258 isolate()->factory()->undefined_value(), RelocInfo::kNoPosition); |
4255 Yield* yield = factory()->NewYield( | 4259 Yield* yield = factory()->NewYield( |
4256 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); | 4260 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); |
4257 body->Add(factory()->NewExpressionStatement( | 4261 body->Add(factory()->NewExpressionStatement( |
4258 yield, RelocInfo::kNoPosition), zone()); | 4262 yield, RelocInfo::kNoPosition), zone()); |
4259 } | 4263 } |
4260 | 4264 |
4261 materialized_literal_count = function_state.materialized_literal_count(); | 4265 materialized_literal_count = function_state.materialized_literal_count(); |
4262 expected_property_count = function_state.expected_property_count(); | 4266 expected_property_count = function_state.expected_property_count(); |
4263 handler_count = function_state.handler_count(); | 4267 handler_count = function_state.handler_count(); |
4264 | 4268 |
4265 Expect(Token::RBRACE, CHECK_OK); | 4269 Expect(Token::RBRACE, CHECK_OK); |
4266 scope->set_end_position(scanner().location().end_pos); | 4270 scope->set_end_position(scanner().location().end_pos); |
4267 } | 4271 } |
4268 | 4272 |
4269 // Validate strict mode. We can do this only after parsing the function, | 4273 // Validate strict mode. We can do this only after parsing the function, |
4270 // since the function can declare itself strict. | 4274 // since the function can declare itself strict. |
4271 if (!top_scope_->is_classic_mode()) { | 4275 if (!scope_->is_classic_mode()) { |
4272 if (IsEvalOrArguments(function_name)) { | 4276 if (IsEvalOrArguments(function_name)) { |
4273 ReportMessageAt(function_name_location, "strict_eval_arguments"); | 4277 ReportMessageAt(function_name_location, "strict_eval_arguments"); |
4274 *ok = false; | 4278 *ok = false; |
4275 return NULL; | 4279 return NULL; |
4276 } | 4280 } |
4277 if (name_is_strict_reserved) { | 4281 if (name_is_strict_reserved) { |
4278 ReportMessageAt(function_name_location, "unexpected_strict_reserved"); | 4282 ReportMessageAt(function_name_location, "unexpected_strict_reserved"); |
4279 *ok = false; | 4283 *ok = false; |
4280 return NULL; | 4284 return NULL; |
4281 } | 4285 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4342 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 4346 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
4343 reusable_preparser_->set_allow_modules(allow_modules()); | 4347 reusable_preparser_->set_allow_modules(allow_modules()); |
4344 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); | 4348 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
4345 reusable_preparser_->set_allow_lazy(true); | 4349 reusable_preparser_->set_allow_lazy(true); |
4346 reusable_preparser_->set_allow_generators(allow_generators()); | 4350 reusable_preparser_->set_allow_generators(allow_generators()); |
4347 reusable_preparser_->set_allow_for_of(allow_for_of()); | 4351 reusable_preparser_->set_allow_for_of(allow_for_of()); |
4348 reusable_preparser_->set_allow_harmony_numeric_literals( | 4352 reusable_preparser_->set_allow_harmony_numeric_literals( |
4349 allow_harmony_numeric_literals()); | 4353 allow_harmony_numeric_literals()); |
4350 } | 4354 } |
4351 PreParser::PreParseResult result = | 4355 PreParser::PreParseResult result = |
4352 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), | 4356 reusable_preparser_->PreParseLazyFunction(scope_->language_mode(), |
4353 is_generator(), | 4357 is_generator(), |
4354 logger); | 4358 logger); |
4355 return result; | 4359 return result; |
4356 } | 4360 } |
4357 | 4361 |
4358 | 4362 |
4359 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4363 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
4360 // CallRuntime :: | 4364 // CallRuntime :: |
4361 // '%' Identifier Arguments | 4365 // '%' Identifier Arguments |
4362 | 4366 |
4363 int pos = peek_position(); | 4367 int pos = peek_position(); |
4364 Expect(Token::MOD, CHECK_OK); | 4368 Expect(Token::MOD, CHECK_OK); |
4365 // Allow "eval" or "arguments" for backward compatibility. | 4369 // Allow "eval" or "arguments" for backward compatibility. |
4366 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 4370 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
4367 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 4371 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
4368 | 4372 |
4369 if (extension_ != NULL) { | 4373 if (extension_ != NULL) { |
4370 // The extension structures are only accessible while parsing the | 4374 // The extension structures are only accessible while parsing the |
4371 // very first time not when reparsing because of lazy compilation. | 4375 // very first time not when reparsing because of lazy compilation. |
4372 top_scope_->DeclarationScope()->ForceEagerCompilation(); | 4376 scope_->DeclarationScope()->ForceEagerCompilation(); |
4373 } | 4377 } |
4374 | 4378 |
4375 const Runtime::Function* function = Runtime::FunctionForName(name); | 4379 const Runtime::Function* function = Runtime::FunctionForName(name); |
4376 | 4380 |
4377 // Check for built-in IS_VAR macro. | 4381 // Check for built-in IS_VAR macro. |
4378 if (function != NULL && | 4382 if (function != NULL && |
4379 function->intrinsic_type == Runtime::RUNTIME && | 4383 function->intrinsic_type == Runtime::RUNTIME && |
4380 function->function_id == Runtime::kIS_VAR) { | 4384 function->function_id == Runtime::kIS_VAR) { |
4381 // %IS_VAR(x) evaluates to x if x is a variable, | 4385 // %IS_VAR(x) evaluates to x if x is a variable, |
4382 // leads to a parse error otherwise. Could be implemented as an | 4386 // leads to a parse error otherwise. Could be implemented as an |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4430 : NULL; | 4434 : NULL; |
4431 | 4435 |
4432 if (proxy != NULL) proxy->MarkAsLValue(); | 4436 if (proxy != NULL) proxy->MarkAsLValue(); |
4433 } | 4437 } |
4434 | 4438 |
4435 | 4439 |
4436 // Checks LHS expression for assignment and prefix/postfix increment/decrement | 4440 // Checks LHS expression for assignment and prefix/postfix increment/decrement |
4437 // in strict mode. | 4441 // in strict mode. |
4438 void Parser::CheckStrictModeLValue(Expression* expression, | 4442 void Parser::CheckStrictModeLValue(Expression* expression, |
4439 bool* ok) { | 4443 bool* ok) { |
4440 ASSERT(!top_scope_->is_classic_mode()); | 4444 ASSERT(!scope_->is_classic_mode()); |
4441 VariableProxy* lhs = expression != NULL | 4445 VariableProxy* lhs = expression != NULL |
4442 ? expression->AsVariableProxy() | 4446 ? expression->AsVariableProxy() |
4443 : NULL; | 4447 : NULL; |
4444 | 4448 |
4445 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | 4449 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
4446 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); | 4450 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); |
4447 *ok = false; | 4451 *ok = false; |
4448 } | 4452 } |
4449 } | 4453 } |
4450 | 4454 |
(...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5525 ASSERT(info()->isolate()->has_pending_exception()); | 5529 ASSERT(info()->isolate()->has_pending_exception()); |
5526 } else { | 5530 } else { |
5527 result = ParseProgram(); | 5531 result = ParseProgram(); |
5528 } | 5532 } |
5529 } | 5533 } |
5530 info()->SetFunction(result); | 5534 info()->SetFunction(result); |
5531 return (result != NULL); | 5535 return (result != NULL); |
5532 } | 5536 } |
5533 | 5537 |
5534 } } // namespace v8::internal | 5538 } } // namespace v8::internal |
OLD | NEW |