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 // 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 |