OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast.h" | 8 #include "src/ast.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
601 | 601 |
602 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 602 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
603 const char* message, const char* arg, | 603 const char* message, const char* arg, |
604 ParseErrorType error_type) { | 604 ParseErrorType error_type) { |
605 if (parser_->stack_overflow()) { | 605 if (parser_->stack_overflow()) { |
606 // Suppress the error message (syntax error or such) in the presence of a | 606 // Suppress the error message (syntax error or such) in the presence of a |
607 // stack overflow. The isolate allows only one pending exception at at time | 607 // stack overflow. The isolate allows only one pending exception at at time |
608 // and we want to report the stack overflow later. | 608 // and we want to report the stack overflow later. |
609 return; | 609 return; |
610 } | 610 } |
611 parser_->has_pending_error_ = true; | 611 parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos, |
612 parser_->pending_error_location_ = source_location; | 612 source_location.end_pos, |
613 parser_->pending_error_message_ = message; | 613 message, arg, error_type); |
614 parser_->pending_error_char_arg_ = arg; | |
615 parser_->pending_error_arg_ = NULL; | |
616 parser_->pending_error_type_ = error_type; | |
617 } | 614 } |
618 | 615 |
619 | 616 |
620 void ParserTraits::ReportMessage(const char* message, const char* arg, | 617 void ParserTraits::ReportMessage(const char* message, const char* arg, |
621 ParseErrorType error_type) { | 618 ParseErrorType error_type) { |
622 Scanner::Location source_location = parser_->scanner()->location(); | 619 Scanner::Location source_location = parser_->scanner()->location(); |
623 ReportMessageAt(source_location, message, arg, error_type); | 620 ReportMessageAt(source_location, message, arg, error_type); |
624 } | 621 } |
625 | 622 |
626 | 623 |
627 void ParserTraits::ReportMessage(const char* message, const AstRawString* arg, | 624 void ParserTraits::ReportMessage(const char* message, const AstRawString* arg, |
628 ParseErrorType error_type) { | 625 ParseErrorType error_type) { |
629 Scanner::Location source_location = parser_->scanner()->location(); | 626 Scanner::Location source_location = parser_->scanner()->location(); |
630 ReportMessageAt(source_location, message, arg, error_type); | 627 ReportMessageAt(source_location, message, arg, error_type); |
631 } | 628 } |
632 | 629 |
633 | 630 |
634 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 631 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
635 const char* message, const AstRawString* arg, | 632 const char* message, const AstRawString* arg, |
636 ParseErrorType error_type) { | 633 ParseErrorType error_type) { |
637 if (parser_->stack_overflow()) { | 634 if (parser_->stack_overflow()) { |
638 // Suppress the error message (syntax error or such) in the presence of a | 635 // Suppress the error message (syntax error or such) in the presence of a |
639 // stack overflow. The isolate allows only one pending exception at at time | 636 // stack overflow. The isolate allows only one pending exception at at time |
640 // and we want to report the stack overflow later. | 637 // and we want to report the stack overflow later. |
641 return; | 638 return; |
642 } | 639 } |
643 parser_->has_pending_error_ = true; | 640 parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos, |
644 parser_->pending_error_location_ = source_location; | 641 source_location.end_pos, |
645 parser_->pending_error_message_ = message; | 642 message, arg, error_type); |
646 parser_->pending_error_char_arg_ = NULL; | |
647 parser_->pending_error_arg_ = arg; | |
648 parser_->pending_error_type_ = error_type; | |
649 } | 643 } |
650 | 644 |
651 | 645 |
652 const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) { | 646 const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) { |
653 const AstRawString* result = | 647 const AstRawString* result = |
654 parser_->scanner()->CurrentSymbol(parser_->ast_value_factory()); | 648 parser_->scanner()->CurrentSymbol(parser_->ast_value_factory()); |
655 DCHECK(result != NULL); | 649 DCHECK(result != NULL); |
656 return result; | 650 return result; |
657 } | 651 } |
658 | 652 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
705 return factory->NewNumberLiteral(value, pos); | 699 return factory->NewNumberLiteral(value, pos); |
706 } | 700 } |
707 default: | 701 default: |
708 DCHECK(false); | 702 DCHECK(false); |
709 } | 703 } |
710 return NULL; | 704 return NULL; |
711 } | 705 } |
712 | 706 |
713 | 707 |
714 Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name, | 708 Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name, |
715 int pos, Scope* scope, | 709 int start_position, |
710 int end_position, | |
711 Scope* scope, | |
716 AstNodeFactory* factory) { | 712 AstNodeFactory* factory) { |
717 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); | 713 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); |
718 | 714 |
719 // Arrow function parameters are parsed as an expression. When | 715 // Arrow function parameters are parsed as an expression. When |
720 // parsing lazily, it is enough to create a VariableProxy in order | 716 // parsing lazily, it is enough to create a VariableProxy in order |
721 // for Traits::DeclareArrowParametersFromExpression() to be able to | 717 // for Traits::DeclareArrowParametersFromExpression() to be able to |
722 // pick the names of the parameters. | 718 // pick the names of the parameters. |
723 return parser_->parsing_lazy_arrow_parameters_ | 719 return parser_->parsing_lazy_arrow_parameters_ |
724 ? factory->NewVariableProxy(name, false, pos) | 720 ? factory->NewVariableProxy(name, false, start_position, |
725 : scope->NewUnresolved(factory, name, pos); | 721 end_position) |
722 : scope->NewUnresolved(factory, name, start_position, | |
723 end_position); | |
726 } | 724 } |
727 | 725 |
728 | 726 |
729 Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner, | 727 Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner, |
730 AstNodeFactory* factory) { | 728 AstNodeFactory* factory) { |
731 const AstRawString* symbol = GetSymbol(scanner); | 729 const AstRawString* symbol = GetSymbol(scanner); |
732 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); | 730 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); |
733 return factory->NewStringLiteral(symbol, pos); | 731 return factory->NewStringLiteral(symbol, pos); |
734 } | 732 } |
735 | 733 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
782 : ParserBase<ParserTraits>(info->zone(), &scanner_, stack_limit, | 780 : ParserBase<ParserTraits>(info->zone(), &scanner_, stack_limit, |
783 info->extension(), info->ast_value_factory(), | 781 info->extension(), info->ast_value_factory(), |
784 NULL, this), | 782 NULL, this), |
785 scanner_(unicode_cache), | 783 scanner_(unicode_cache), |
786 reusable_preparser_(NULL), | 784 reusable_preparser_(NULL), |
787 original_scope_(NULL), | 785 original_scope_(NULL), |
788 target_stack_(NULL), | 786 target_stack_(NULL), |
789 compile_options_(info->compile_options()), | 787 compile_options_(info->compile_options()), |
790 cached_parse_data_(NULL), | 788 cached_parse_data_(NULL), |
791 parsing_lazy_arrow_parameters_(false), | 789 parsing_lazy_arrow_parameters_(false), |
792 has_pending_error_(false), | |
793 pending_error_message_(NULL), | |
794 pending_error_arg_(NULL), | |
795 pending_error_char_arg_(NULL), | |
796 pending_error_type_(kSyntaxError), | |
797 total_preparse_skipped_(0), | 790 total_preparse_skipped_(0), |
798 pre_parse_timer_(NULL), | 791 pre_parse_timer_(NULL), |
799 parsing_on_main_thread_(true) { | 792 parsing_on_main_thread_(true) { |
800 // Even though we were passed CompilationInfo, we should not store it in | 793 // Even though we were passed CompilationInfo, we should not store it in |
801 // Parser - this makes sure that Isolate is not accidentally accessed via | 794 // Parser - this makes sure that Isolate is not accidentally accessed via |
802 // CompilationInfo during background parsing. | 795 // CompilationInfo during background parsing. |
803 DCHECK(!info->script().is_null() || info->source_stream() != NULL); | 796 DCHECK(!info->script().is_null() || info->source_stream() != NULL); |
804 set_allow_lazy(false); // Must be explicitly enabled. | 797 set_allow_lazy(false); // Must be explicitly enabled. |
805 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); | 798 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); |
806 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 799 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
(...skipping 978 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1785 } | 1778 } |
1786 | 1779 |
1787 | 1780 |
1788 VariableProxy* Parser::NewUnresolved(const AstRawString* name, | 1781 VariableProxy* Parser::NewUnresolved(const AstRawString* name, |
1789 VariableMode mode) { | 1782 VariableMode mode) { |
1790 // If we are inside a function, a declaration of a var/const variable is a | 1783 // If we are inside a function, a declaration of a var/const variable is a |
1791 // truly local variable, and the scope of the variable is always the function | 1784 // truly local variable, and the scope of the variable is always the function |
1792 // scope. | 1785 // scope. |
1793 // Let/const variables in harmony mode are always added to the immediately | 1786 // Let/const variables in harmony mode are always added to the immediately |
1794 // enclosing scope. | 1787 // enclosing scope. |
1795 return DeclarationScope(mode)->NewUnresolved(factory(), name, position()); | 1788 return DeclarationScope(mode)->NewUnresolved(factory(), name, |
1789 scanner()->location().beg_pos, | |
1790 scanner()->location().end_pos); | |
1796 } | 1791 } |
1797 | 1792 |
1798 | 1793 |
1799 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { | 1794 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { |
1800 VariableProxy* proxy = declaration->proxy(); | 1795 VariableProxy* proxy = declaration->proxy(); |
1801 DCHECK(proxy->raw_name() != NULL); | 1796 DCHECK(proxy->raw_name() != NULL); |
1802 const AstRawString* name = proxy->raw_name(); | 1797 const AstRawString* name = proxy->raw_name(); |
1803 VariableMode mode = declaration->mode(); | 1798 VariableMode mode = declaration->mode(); |
1804 Scope* declaration_scope = DeclarationScope(mode); | 1799 Scope* declaration_scope = DeclarationScope(mode); |
1805 Variable* var = NULL; | 1800 Variable* var = NULL; |
1806 | 1801 |
1807 // If a suitable scope exists, then we can statically declare this | 1802 // If a suitable scope exists, then we can statically declare this |
1808 // variable and also set its mode. In any case, a Declaration node | 1803 // variable and also set its mode. In any case, a Declaration node |
1809 // will be added to the scope so that the declaration can be added | 1804 // will be added to the scope so that the declaration can be added |
1810 // to the corresponding activation frame at runtime if necessary. | 1805 // to the corresponding activation frame at runtime if necessary. |
1811 // For instance declarations inside an eval scope need to be added | 1806 // For instance declarations inside an eval scope need to be added |
1812 // to the calling function context. | 1807 // to the calling function context. |
1813 // Similarly, strict mode eval scope does not leak variable declarations to | 1808 // Similarly, strict mode eval scope does not leak variable declarations to |
1814 // the caller's scope so we declare all locals, too. | 1809 // the caller's scope so we declare all locals, too. |
1815 if (declaration_scope->is_function_scope() || | 1810 if (declaration_scope->is_function_scope() || |
1816 declaration_scope->is_strict_eval_scope() || | 1811 declaration_scope->is_strict_eval_scope() || |
1817 declaration_scope->is_block_scope() || | 1812 declaration_scope->is_block_scope() || |
1818 declaration_scope->is_module_scope() || | 1813 declaration_scope->is_module_scope() || |
1819 declaration_scope->is_script_scope()) { | 1814 declaration_scope->is_script_scope()) { |
1820 // Declare the variable in the declaration scope. | 1815 // Declare the variable in the declaration scope. |
1821 var = declaration_scope->LookupLocal(name); | 1816 var = declaration_scope->LookupLocal(name); |
1822 if (var == NULL) { | 1817 if (var == NULL) { |
1823 // Declare the name. | 1818 // Declare the name. |
1824 var = declaration_scope->DeclareLocal( | 1819 var = declaration_scope->DeclareLocal( |
1825 name, mode, declaration->initialization(), kNotAssigned); | 1820 name, mode, declaration->initialization(), declaration->position(), |
1826 } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode()) | 1821 declaration->IsFunctionDeclaration(), kNotAssigned); |
1827 || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) && | 1822 } else if (IsLexicalVariableMode(mode) || |
1828 !declaration_scope->is_script_scope())) { | 1823 IsLexicalVariableMode(var->mode()) || |
1824 ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) && | |
1825 !declaration_scope->is_script_scope())) { | |
1829 // The name was declared in this scope before; check for conflicting | 1826 // The name was declared in this scope before; check for conflicting |
1830 // re-declarations. We have a conflict if either of the declarations is | 1827 // re-declarations. We have a conflict if either of the declarations is |
1831 // not a var (in script scope, we also have to ignore legacy const for | 1828 // not a var (in script scope, we also have to ignore legacy const for |
1832 // compatibility). There is similar code in runtime.cc in the Declare | 1829 // compatibility). There is similar code in runtime.cc in the Declare |
1833 // functions. The function CheckConflictingVarDeclarations checks for | 1830 // functions. The function CheckConflictingVarDeclarations checks for |
1834 // var and let bindings from different scopes whereas this is a check for | 1831 // var and let bindings from different scopes whereas this is a check for |
1835 // conflicting declarations within the same scope. This check also covers | 1832 // conflicting declarations within the same scope. This check also covers |
1836 // the special case | 1833 // the special case |
1837 // | 1834 // |
1838 // function () { let x; { var x; } } | 1835 // function () { let x; { var x; } } |
(...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2804 if (tok == Token::CATCH) { | 2801 if (tok == Token::CATCH) { |
2805 Consume(Token::CATCH); | 2802 Consume(Token::CATCH); |
2806 | 2803 |
2807 Expect(Token::LPAREN, CHECK_OK); | 2804 Expect(Token::LPAREN, CHECK_OK); |
2808 catch_scope = NewScope(scope_, CATCH_SCOPE); | 2805 catch_scope = NewScope(scope_, CATCH_SCOPE); |
2809 catch_scope->set_start_position(scanner()->location().beg_pos); | 2806 catch_scope->set_start_position(scanner()->location().beg_pos); |
2810 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2807 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
2811 | 2808 |
2812 Expect(Token::RPAREN, CHECK_OK); | 2809 Expect(Token::RPAREN, CHECK_OK); |
2813 | 2810 |
2814 catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized); | 2811 catch_variable = catch_scope->DeclareLocal( |
2812 name, VAR, kCreatedInitialized, scanner()->location().beg_pos, false); | |
2815 BlockState block_state(&scope_, catch_scope); | 2813 BlockState block_state(&scope_, catch_scope); |
2816 catch_block = ParseBlock(NULL, CHECK_OK); | 2814 catch_block = ParseBlock(NULL, CHECK_OK); |
2817 | 2815 |
2818 catch_scope->set_end_position(scanner()->location().end_pos); | 2816 catch_scope->set_end_position(scanner()->location().end_pos); |
2819 tok = peek(); | 2817 tok = peek(); |
2820 } | 2818 } |
2821 | 2819 |
2822 Block* finally_block = NULL; | 2820 Block* finally_block = NULL; |
2823 DCHECK(tok == Token::FINALLY || catch_block != NULL); | 2821 DCHECK(tok == Token::FINALLY || catch_block != NULL); |
2824 if (tok == Token::FINALLY) { | 2822 if (tok == Token::FINALLY) { |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3070 | 3068 |
3071 Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false, | 3069 Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false, |
3072 RelocInfo::kNoPosition); | 3070 RelocInfo::kNoPosition); |
3073 int pos = scanner()->location().beg_pos; | 3071 int pos = scanner()->location().beg_pos; |
3074 ZoneList<Variable*> inner_vars(names->length(), zone()); | 3072 ZoneList<Variable*> inner_vars(names->length(), zone()); |
3075 | 3073 |
3076 // For each let variable x: | 3074 // For each let variable x: |
3077 // make statement: let x = temp_x. | 3075 // make statement: let x = temp_x. |
3078 for (int i = 0; i < names->length(); i++) { | 3076 for (int i = 0; i < names->length(); i++) { |
3079 VariableProxy* proxy = NewUnresolved(names->at(i), LET); | 3077 VariableProxy* proxy = NewUnresolved(names->at(i), LET); |
3080 Declaration* declaration = | 3078 Declaration* declaration = factory()->NewVariableDeclaration( |
3081 factory()->NewVariableDeclaration(proxy, LET, scope_, pos); | 3079 proxy, LET, scope_, RelocInfo::kNoPosition); |
3082 Declare(declaration, true, CHECK_OK); | 3080 Declare(declaration, true, CHECK_OK); |
3083 inner_vars.Add(declaration->proxy()->var(), zone()); | 3081 inner_vars.Add(declaration->proxy()->var(), zone()); |
3084 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); | 3082 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); |
3085 Assignment* assignment = factory()->NewAssignment( | 3083 Assignment* assignment = factory()->NewAssignment( |
3086 Token::INIT_LET, proxy, temp_proxy, pos); | 3084 Token::INIT_LET, proxy, temp_proxy, pos); |
3087 Statement* assignment_statement = factory()->NewExpressionStatement( | 3085 Statement* assignment_statement = |
3088 assignment, pos); | 3086 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); |
3089 proxy->var()->set_initializer_position(pos); | 3087 proxy->var()->set_initializer_position(pos); |
3090 inner_block->AddStatement(assignment_statement, zone()); | 3088 inner_block->AddStatement(assignment_statement, zone()); |
3091 } | 3089 } |
3092 | 3090 |
3093 // Make statement: if (first == 1) { first = 0; } else { next; } | 3091 // Make statement: if (first == 1) { first = 0; } else { next; } |
3094 if (next) { | 3092 if (next) { |
3095 DCHECK(first); | 3093 DCHECK(first); |
3096 Expression* compare = NULL; | 3094 Expression* compare = NULL; |
3097 // Make compare expression: first == 1. | 3095 // Make compare expression: first == 1. |
3098 { | 3096 { |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3227 if (peek() != Token::SEMICOLON) { | 3225 if (peek() != Token::SEMICOLON) { |
3228 if (peek() == Token::VAR || | 3226 if (peek() == Token::VAR || |
3229 (peek() == Token::CONST && is_sloppy(language_mode()))) { | 3227 (peek() == Token::CONST && is_sloppy(language_mode()))) { |
3230 const AstRawString* name = NULL; | 3228 const AstRawString* name = NULL; |
3231 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3229 VariableDeclarationProperties decl_props = kHasNoInitializers; |
3232 Block* variable_statement = | 3230 Block* variable_statement = |
3233 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 3231 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
3234 CHECK_OK); | 3232 CHECK_OK); |
3235 bool accept_OF = decl_props == kHasNoInitializers; | 3233 bool accept_OF = decl_props == kHasNoInitializers; |
3236 ForEachStatement::VisitMode mode; | 3234 ForEachStatement::VisitMode mode; |
3237 int each_pos = position(); | 3235 int each_beg_pos = scanner()->location().beg_pos; |
3236 int each_end_pos = scanner()->location().end_pos; | |
3238 | 3237 |
3239 if (name != NULL && CheckInOrOf(accept_OF, &mode, ok)) { | 3238 if (name != NULL && CheckInOrOf(accept_OF, &mode, ok)) { |
3240 if (!*ok) return nullptr; | 3239 if (!*ok) return nullptr; |
3241 ForEachStatement* loop = | 3240 ForEachStatement* loop = |
3242 factory()->NewForEachStatement(mode, labels, stmt_pos); | 3241 factory()->NewForEachStatement(mode, labels, stmt_pos); |
3243 Target target(&this->target_stack_, loop); | 3242 Target target(&this->target_stack_, loop); |
3244 | 3243 |
3245 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3244 Expression* enumerable = ParseExpression(true, CHECK_OK); |
3246 Expect(Token::RPAREN, CHECK_OK); | 3245 Expect(Token::RPAREN, CHECK_OK); |
3247 | 3246 |
3248 VariableProxy* each = scope_->NewUnresolved(factory(), name, each_pos); | 3247 VariableProxy* each = |
3248 scope_->NewUnresolved(factory(), name, each_beg_pos, each_end_pos); | |
3249 Statement* body = ParseSubStatement(NULL, CHECK_OK); | 3249 Statement* body = ParseSubStatement(NULL, CHECK_OK); |
3250 InitializeForEachStatement(loop, each, enumerable, body); | 3250 InitializeForEachStatement(loop, each, enumerable, body); |
3251 Block* result = | 3251 Block* result = |
3252 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 3252 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
3253 result->AddStatement(variable_statement, zone()); | 3253 result->AddStatement(variable_statement, zone()); |
3254 result->AddStatement(loop, zone()); | 3254 result->AddStatement(loop, zone()); |
3255 scope_ = saved_scope; | 3255 scope_ = saved_scope; |
3256 for_scope->set_end_position(scanner()->location().end_pos); | 3256 for_scope->set_end_position(scanner()->location().end_pos); |
3257 for_scope = for_scope->FinalizeBlockScope(); | 3257 for_scope = for_scope->FinalizeBlockScope(); |
3258 DCHECK(for_scope == NULL); | 3258 DCHECK(for_scope == NULL); |
3259 // Parsed for-in loop w/ variable/const declaration. | 3259 // Parsed for-in loop w/ variable/const declaration. |
3260 return result; | 3260 return result; |
3261 } else { | 3261 } else { |
3262 init = variable_statement; | 3262 init = variable_statement; |
3263 } | 3263 } |
3264 } else if ((peek() == Token::LET || peek() == Token::CONST) && | 3264 } else if ((peek() == Token::LET || peek() == Token::CONST) && |
3265 is_strict(language_mode())) { | 3265 is_strict(language_mode())) { |
3266 bool is_const = peek() == Token::CONST; | 3266 bool is_const = peek() == Token::CONST; |
3267 const AstRawString* name = NULL; | 3267 const AstRawString* name = NULL; |
3268 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3268 VariableDeclarationProperties decl_props = kHasNoInitializers; |
3269 Block* variable_statement = | 3269 Block* variable_statement = |
3270 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, | 3270 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, |
3271 &name, CHECK_OK); | 3271 &name, CHECK_OK); |
3272 bool accept_IN = name != NULL && decl_props != kHasInitializers; | 3272 bool accept_IN = name != NULL && decl_props != kHasInitializers; |
3273 bool accept_OF = decl_props == kHasNoInitializers; | 3273 bool accept_OF = decl_props == kHasNoInitializers; |
3274 ForEachStatement::VisitMode mode; | 3274 ForEachStatement::VisitMode mode; |
3275 int each_pos = position(); | 3275 int each_beg_pos = scanner()->location().beg_pos; |
3276 int each_end_pos = scanner()->location().end_pos; | |
3276 | 3277 |
3277 if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) { | 3278 if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) { |
3278 if (!*ok) return nullptr; | 3279 if (!*ok) return nullptr; |
3279 | 3280 |
3280 // Rewrite a for-in statement of the form | 3281 // Rewrite a for-in statement of the form |
3281 // | 3282 // |
3282 // for (let/const x in e) b | 3283 // for (let/const x in e) b |
3283 // | 3284 // |
3284 // into | 3285 // into |
3285 // | 3286 // |
3286 // <let x' be a temporary variable> | 3287 // <let x' be a temporary variable> |
3287 // for (x' in e) { | 3288 // for (x' in e) { |
3288 // let/const x; | 3289 // let/const x; |
3289 // x = x'; | 3290 // x = x'; |
3290 // b; | 3291 // b; |
3291 // } | 3292 // } |
3292 | 3293 |
3293 // TODO(keuchel): Move the temporary variable to the block scope, after | 3294 // TODO(keuchel): Move the temporary variable to the block scope, after |
3294 // implementing stack allocated block scoped variables. | 3295 // implementing stack allocated block scoped variables. |
3295 Variable* temp = scope_->DeclarationScope()->NewTemporary( | 3296 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
3296 ast_value_factory()->dot_for_string()); | 3297 ast_value_factory()->dot_for_string()); |
3297 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp, each_pos); | 3298 VariableProxy* temp_proxy = |
3299 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); | |
3298 ForEachStatement* loop = | 3300 ForEachStatement* loop = |
3299 factory()->NewForEachStatement(mode, labels, stmt_pos); | 3301 factory()->NewForEachStatement(mode, labels, stmt_pos); |
3300 Target target(&this->target_stack_, loop); | 3302 Target target(&this->target_stack_, loop); |
3301 | 3303 |
3302 // The expression does not see the loop variable. | 3304 // The expression does not see the loop variable. |
3303 scope_ = saved_scope; | 3305 scope_ = saved_scope; |
3304 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3306 Expression* enumerable = ParseExpression(true, CHECK_OK); |
3305 scope_ = for_scope; | 3307 scope_ = for_scope; |
3306 Expect(Token::RPAREN, CHECK_OK); | 3308 Expect(Token::RPAREN, CHECK_OK); |
3307 | 3309 |
3308 VariableProxy* each = scope_->NewUnresolved(factory(), name, each_pos); | 3310 VariableProxy* each = |
3311 scope_->NewUnresolved(factory(), name, each_beg_pos, each_end_pos); | |
3309 Statement* body = ParseSubStatement(NULL, CHECK_OK); | 3312 Statement* body = ParseSubStatement(NULL, CHECK_OK); |
3310 Block* body_block = | 3313 Block* body_block = |
3311 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); | 3314 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); |
3312 Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN; | 3315 Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN; |
3313 Assignment* assignment = factory()->NewAssignment( | 3316 Assignment* assignment = factory()->NewAssignment( |
3314 init_op, each, temp_proxy, RelocInfo::kNoPosition); | 3317 init_op, each, temp_proxy, RelocInfo::kNoPosition); |
3315 Statement* assignment_statement = factory()->NewExpressionStatement( | 3318 Statement* assignment_statement = factory()->NewExpressionStatement( |
3316 assignment, RelocInfo::kNoPosition); | 3319 assignment, RelocInfo::kNoPosition); |
3317 body_block->AddStatement(variable_statement, zone()); | 3320 body_block->AddStatement(variable_statement, zone()); |
3318 body_block->AddStatement(assignment_statement, zone()); | 3321 body_block->AddStatement(assignment_statement, zone()); |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3740 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 3743 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
3741 if (allow_harmony_scoping() && is_strict(language_mode())) { | 3744 if (allow_harmony_scoping() && is_strict(language_mode())) { |
3742 fvar_init_op = Token::INIT_CONST; | 3745 fvar_init_op = Token::INIT_CONST; |
3743 } | 3746 } |
3744 VariableMode fvar_mode = | 3747 VariableMode fvar_mode = |
3745 allow_harmony_scoping() && is_strict(language_mode()) ? CONST | 3748 allow_harmony_scoping() && is_strict(language_mode()) ? CONST |
3746 : CONST_LEGACY; | 3749 : CONST_LEGACY; |
3747 DCHECK(function_name != NULL); | 3750 DCHECK(function_name != NULL); |
3748 fvar = new (zone()) | 3751 fvar = new (zone()) |
3749 Variable(scope_, function_name, fvar_mode, true /* is valid LHS */, | 3752 Variable(scope_, function_name, fvar_mode, true /* is valid LHS */, |
3750 Variable::NORMAL, kCreatedInitialized, kNotAssigned); | 3753 Variable::FUNCTION, kCreatedInitialized, kNotAssigned); |
rossberg
2015/02/23 13:45:26
Note that this is not a function declaration, but
marja
2015/02/24 13:29:34
Done, in addition did the same change in Scope::Lo
| |
3751 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 3754 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
3752 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( | 3755 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
3753 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); | 3756 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); |
3754 scope_->DeclareFunctionVar(fvar_declaration); | 3757 scope_->DeclareFunctionVar(fvar_declaration); |
3755 } | 3758 } |
3756 | 3759 |
3757 // Determine if the function can be parsed lazily. Lazy parsing is different | 3760 // Determine if the function can be parsed lazily. Lazy parsing is different |
3758 // from lazy compilation; we need to parse more eagerly than we compile. | 3761 // from lazy compilation; we need to parse more eagerly than we compile. |
3759 | 3762 |
3760 // We can only parse lazily if we also compile lazily. The heuristics for | 3763 // We can only parse lazily if we also compile lazily. The heuristics for |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4260 script->set_source_url(*source_url); | 4263 script->set_source_url(*source_url); |
4261 } | 4264 } |
4262 if (scanner_.source_mapping_url()->length() > 0) { | 4265 if (scanner_.source_mapping_url()->length() > 0) { |
4263 Handle<String> source_mapping_url = | 4266 Handle<String> source_mapping_url = |
4264 scanner_.source_mapping_url()->Internalize(isolate); | 4267 scanner_.source_mapping_url()->Internalize(isolate); |
4265 script->set_source_mapping_url(*source_mapping_url); | 4268 script->set_source_mapping_url(*source_mapping_url); |
4266 } | 4269 } |
4267 } | 4270 } |
4268 | 4271 |
4269 | 4272 |
4270 void Parser::ThrowPendingError(Isolate* isolate, Handle<Script> script) { | |
4271 DCHECK(ast_value_factory()->IsInternalized()); | |
4272 if (has_pending_error_) { | |
4273 MessageLocation location(script, pending_error_location_.beg_pos, | |
4274 pending_error_location_.end_pos); | |
4275 Factory* factory = isolate->factory(); | |
4276 bool has_arg = | |
4277 pending_error_arg_ != NULL || pending_error_char_arg_ != NULL; | |
4278 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0); | |
4279 if (pending_error_arg_ != NULL) { | |
4280 Handle<String> arg_string = pending_error_arg_->string(); | |
4281 elements->set(0, *arg_string); | |
4282 } else if (pending_error_char_arg_ != NULL) { | |
4283 Handle<String> arg_string = | |
4284 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_)) | |
4285 .ToHandleChecked(); | |
4286 elements->set(0, *arg_string); | |
4287 } | |
4288 isolate->debug()->OnCompileError(script); | |
4289 | |
4290 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | |
4291 Handle<Object> error; | |
4292 MaybeHandle<Object> maybe_error; | |
4293 switch (pending_error_type_) { | |
4294 case kReferenceError: | |
4295 maybe_error = factory->NewReferenceError(pending_error_message_, array); | |
4296 break; | |
4297 case kSyntaxError: | |
4298 maybe_error = factory->NewSyntaxError(pending_error_message_, array); | |
4299 break; | |
4300 } | |
4301 DCHECK(!maybe_error.is_null() || isolate->has_pending_exception()); | |
4302 | |
4303 if (maybe_error.ToHandle(&error)) { | |
4304 Handle<JSObject> jserror = Handle<JSObject>::cast(error); | |
4305 | |
4306 Handle<Name> key_start_pos = factory->error_start_pos_symbol(); | |
4307 JSObject::SetProperty(jserror, key_start_pos, | |
4308 handle(Smi::FromInt(location.start_pos()), isolate), | |
4309 SLOPPY).Check(); | |
4310 | |
4311 Handle<Name> key_end_pos = factory->error_end_pos_symbol(); | |
4312 JSObject::SetProperty(jserror, key_end_pos, | |
4313 handle(Smi::FromInt(location.end_pos()), isolate), | |
4314 SLOPPY).Check(); | |
4315 | |
4316 Handle<Name> key_script = factory->error_script_symbol(); | |
4317 JSObject::SetProperty(jserror, key_script, script, SLOPPY).Check(); | |
4318 | |
4319 isolate->Throw(*error, &location); | |
4320 } | |
4321 } | |
4322 } | |
4323 | |
4324 | |
4325 void Parser::Internalize(Isolate* isolate, Handle<Script> script, bool error) { | 4273 void Parser::Internalize(Isolate* isolate, Handle<Script> script, bool error) { |
4326 // Internalize strings. | 4274 // Internalize strings. |
4327 ast_value_factory()->Internalize(isolate); | 4275 ast_value_factory()->Internalize(isolate); |
4328 | 4276 |
4329 // Error processing. | 4277 // Error processing. |
4330 if (error) { | 4278 if (error) { |
4331 if (stack_overflow()) { | 4279 if (stack_overflow()) { |
4332 isolate->StackOverflow(); | 4280 isolate->StackOverflow(); |
4333 } else { | 4281 } else { |
4334 ThrowPendingError(isolate, script); | 4282 DCHECK(pending_error_handler_.has_pending_error()); |
4283 pending_error_handler_.ThrowPendingError(isolate, script); | |
4335 } | 4284 } |
4336 } | 4285 } |
4337 | 4286 |
4338 // Move statistics to Isolate. | 4287 // Move statistics to Isolate. |
4339 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 4288 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
4340 ++feature) { | 4289 ++feature) { |
4341 for (int i = 0; i < use_counts_[feature]; ++i) { | 4290 for (int i = 0; i < use_counts_[feature]; ++i) { |
4342 isolate->CountUsage(v8::Isolate::UseCounterFeature(feature)); | 4291 isolate->CountUsage(v8::Isolate::UseCounterFeature(feature)); |
4343 } | 4292 } |
4344 } | 4293 } |
(...skipping 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5463 } else { | 5412 } else { |
5464 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); | 5413 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); |
5465 running_hash = StringHasher::ComputeRunningHash(running_hash, data, | 5414 running_hash = StringHasher::ComputeRunningHash(running_hash, data, |
5466 raw_string->length()); | 5415 raw_string->length()); |
5467 } | 5416 } |
5468 } | 5417 } |
5469 | 5418 |
5470 return running_hash; | 5419 return running_hash; |
5471 } | 5420 } |
5472 } } // namespace v8::internal | 5421 } } // namespace v8::internal |
OLD | NEW |