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