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