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