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(), |
rossberg
2015/02/24 15:52:40
Hm, I'm confused, why is this the right init posit
marja
2015/02/24 18:05:40
Argh, this was only working because the position i
| |
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 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2032 const AstRawString* name = | 2029 const AstRawString* name = |
2033 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 2030 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
2034 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(), | 2031 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(), |
2035 is_strict_reserved, pos, CHECK_OK); | 2032 is_strict_reserved, pos, CHECK_OK); |
2036 | 2033 |
2037 VariableMode mode = is_strong(language_mode()) ? CONST : LET; | 2034 VariableMode mode = is_strong(language_mode()) ? CONST : LET; |
2038 VariableProxy* proxy = NewUnresolved(name, mode); | 2035 VariableProxy* proxy = NewUnresolved(name, mode); |
2039 Declaration* declaration = | 2036 Declaration* declaration = |
2040 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); | 2037 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); |
2041 Declare(declaration, true, CHECK_OK); | 2038 Declare(declaration, true, CHECK_OK); |
2042 proxy->var()->set_initializer_position(pos); | 2039 proxy->var()->set_initializer_position(pos); |
rossberg
2015/02/24 15:52:40
I'm surprised that this isn't a problem, since 'po
marja
2015/02/24 18:05:40
This isn't the problem for the
class C extends C
rossberg
2015/02/25 13:17:27
I see, because it is immediately shadowed in the c
marja
2015/02/25 13:25:03
Okay, did that. So here position() is at the end o
rossberg
2015/02/25 13:29:08
Why, the outer C is a completely separate variable
| |
2043 | 2040 |
2044 Token::Value init_op = | 2041 Token::Value init_op = |
2045 is_strong(language_mode()) ? Token::INIT_CONST : Token::INIT_LET; | 2042 is_strong(language_mode()) ? Token::INIT_CONST : Token::INIT_LET; |
2046 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos); | 2043 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos); |
2047 Statement* assignment_statement = | 2044 Statement* assignment_statement = |
2048 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); | 2045 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); |
2049 if (names) names->Add(name, zone()); | 2046 if (names) names->Add(name, zone()); |
2050 return assignment_statement; | 2047 return assignment_statement; |
2051 } | 2048 } |
2052 | 2049 |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2295 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 2292 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
2296 // Don't infer if it is "a = function(){...}();"-like expression. | 2293 // Don't infer if it is "a = function(){...}();"-like expression. |
2297 if (fni_ != NULL && | 2294 if (fni_ != NULL && |
2298 value->AsCall() == NULL && | 2295 value->AsCall() == NULL && |
2299 value->AsCallNew() == NULL) { | 2296 value->AsCallNew() == NULL) { |
2300 fni_->Infer(); | 2297 fni_->Infer(); |
2301 } else { | 2298 } else { |
2302 fni_->RemoveLastFunction(); | 2299 fni_->RemoveLastFunction(); |
2303 } | 2300 } |
2304 if (decl_props != NULL) *decl_props = kHasInitializers; | 2301 if (decl_props != NULL) *decl_props = kHasInitializers; |
2305 } | 2302 // Record the end position of the initializer. |
2306 | 2303 if (proxy->is_resolved()) { |
2307 // Record the end position of the initializer. | 2304 proxy->var()->set_initializer_position(scanner()->location().end_pos); |
2308 if (proxy->is_resolved()) { | 2305 } |
2309 proxy->var()->set_initializer_position(position()); | 2306 } else { |
2307 // Record the end position of the initializer. | |
2308 if (proxy->is_resolved()) { | |
2309 proxy->var()->set_initializer_position(position()); | |
2310 } | |
2310 } | 2311 } |
2311 | 2312 |
2312 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. | 2313 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. |
2313 if (value == NULL && needs_init) { | 2314 if (value == NULL && needs_init) { |
2314 value = GetLiteralUndefined(position()); | 2315 value = GetLiteralUndefined(position()); |
2315 } | 2316 } |
2316 | 2317 |
2317 // Global variable declarations must be compiled in a specific | 2318 // Global variable declarations must be compiled in a specific |
2318 // way. When the script containing the global variable declaration | 2319 // way. When the script containing the global variable declaration |
2319 // is entered, the global variable must be declared, so that if it | 2320 // is entered, the global variable must be declared, so that if it |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2804 if (tok == Token::CATCH) { | 2805 if (tok == Token::CATCH) { |
2805 Consume(Token::CATCH); | 2806 Consume(Token::CATCH); |
2806 | 2807 |
2807 Expect(Token::LPAREN, CHECK_OK); | 2808 Expect(Token::LPAREN, CHECK_OK); |
2808 catch_scope = NewScope(scope_, CATCH_SCOPE); | 2809 catch_scope = NewScope(scope_, CATCH_SCOPE); |
2809 catch_scope->set_start_position(scanner()->location().beg_pos); | 2810 catch_scope->set_start_position(scanner()->location().beg_pos); |
2810 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2811 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
2811 | 2812 |
2812 Expect(Token::RPAREN, CHECK_OK); | 2813 Expect(Token::RPAREN, CHECK_OK); |
2813 | 2814 |
2814 catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized); | 2815 catch_variable = catch_scope->DeclareLocal( |
2816 name, VAR, kCreatedInitialized, scanner()->location().beg_pos, false); | |
2815 BlockState block_state(&scope_, catch_scope); | 2817 BlockState block_state(&scope_, catch_scope); |
2816 catch_block = ParseBlock(NULL, CHECK_OK); | 2818 catch_block = ParseBlock(NULL, CHECK_OK); |
2817 | 2819 |
2818 catch_scope->set_end_position(scanner()->location().end_pos); | 2820 catch_scope->set_end_position(scanner()->location().end_pos); |
2819 tok = peek(); | 2821 tok = peek(); |
2820 } | 2822 } |
2821 | 2823 |
2822 Block* finally_block = NULL; | 2824 Block* finally_block = NULL; |
2823 DCHECK(tok == Token::FINALLY || catch_block != NULL); | 2825 DCHECK(tok == Token::FINALLY || catch_block != NULL); |
2824 if (tok == Token::FINALLY) { | 2826 if (tok == Token::FINALLY) { |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3096 | 3098 |
3097 Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false, | 3099 Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false, |
3098 RelocInfo::kNoPosition); | 3100 RelocInfo::kNoPosition); |
3099 int pos = scanner()->location().beg_pos; | 3101 int pos = scanner()->location().beg_pos; |
3100 ZoneList<Variable*> inner_vars(names->length(), zone()); | 3102 ZoneList<Variable*> inner_vars(names->length(), zone()); |
3101 | 3103 |
3102 // For each let variable x: | 3104 // For each let variable x: |
3103 // make statement: let x = temp_x. | 3105 // make statement: let x = temp_x. |
3104 for (int i = 0; i < names->length(); i++) { | 3106 for (int i = 0; i < names->length(); i++) { |
3105 VariableProxy* proxy = NewUnresolved(names->at(i), LET); | 3107 VariableProxy* proxy = NewUnresolved(names->at(i), LET); |
3106 Declaration* declaration = | 3108 Declaration* declaration = factory()->NewVariableDeclaration( |
3107 factory()->NewVariableDeclaration(proxy, LET, scope_, pos); | 3109 proxy, LET, scope_, RelocInfo::kNoPosition); |
3108 Declare(declaration, true, CHECK_OK); | 3110 Declare(declaration, true, CHECK_OK); |
3109 inner_vars.Add(declaration->proxy()->var(), zone()); | 3111 inner_vars.Add(declaration->proxy()->var(), zone()); |
3110 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); | 3112 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); |
3111 Assignment* assignment = factory()->NewAssignment( | 3113 Assignment* assignment = factory()->NewAssignment( |
3112 Token::INIT_LET, proxy, temp_proxy, pos); | 3114 Token::INIT_LET, proxy, temp_proxy, pos); |
3113 Statement* assignment_statement = factory()->NewExpressionStatement( | 3115 Statement* assignment_statement = |
3114 assignment, pos); | 3116 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); |
3115 proxy->var()->set_initializer_position(pos); | 3117 proxy->var()->set_initializer_position(init->position()); |
3116 inner_block->AddStatement(assignment_statement, zone()); | 3118 inner_block->AddStatement(assignment_statement, zone()); |
3117 } | 3119 } |
3118 | 3120 |
3119 // Make statement: if (first == 1) { first = 0; } else { next; } | 3121 // Make statement: if (first == 1) { first = 0; } else { next; } |
3120 if (next) { | 3122 if (next) { |
3121 DCHECK(first); | 3123 DCHECK(first); |
3122 Expression* compare = NULL; | 3124 Expression* compare = NULL; |
3123 // Make compare expression: first == 1. | 3125 // Make compare expression: first == 1. |
3124 { | 3126 { |
3125 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); | 3127 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3253 if (peek() != Token::SEMICOLON) { | 3255 if (peek() != Token::SEMICOLON) { |
3254 if (peek() == Token::VAR || | 3256 if (peek() == Token::VAR || |
3255 (peek() == Token::CONST && is_sloppy(language_mode()))) { | 3257 (peek() == Token::CONST && is_sloppy(language_mode()))) { |
3256 const AstRawString* name = NULL; | 3258 const AstRawString* name = NULL; |
3257 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3259 VariableDeclarationProperties decl_props = kHasNoInitializers; |
3258 Block* variable_statement = | 3260 Block* variable_statement = |
3259 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 3261 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
3260 CHECK_OK); | 3262 CHECK_OK); |
3261 bool accept_OF = decl_props == kHasNoInitializers; | 3263 bool accept_OF = decl_props == kHasNoInitializers; |
3262 ForEachStatement::VisitMode mode; | 3264 ForEachStatement::VisitMode mode; |
3263 int each_pos = position(); | 3265 int each_beg_pos = scanner()->location().beg_pos; |
3266 int each_end_pos = scanner()->location().end_pos; | |
3264 | 3267 |
3265 if (name != NULL && CheckInOrOf(accept_OF, &mode, ok)) { | 3268 if (name != NULL && CheckInOrOf(accept_OF, &mode, ok)) { |
3266 if (!*ok) return nullptr; | 3269 if (!*ok) return nullptr; |
3267 ForEachStatement* loop = | 3270 ForEachStatement* loop = |
3268 factory()->NewForEachStatement(mode, labels, stmt_pos); | 3271 factory()->NewForEachStatement(mode, labels, stmt_pos); |
3269 Target target(&this->target_stack_, loop); | 3272 Target target(&this->target_stack_, loop); |
3270 | 3273 |
3271 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3274 Expression* enumerable = ParseExpression(true, CHECK_OK); |
3272 Expect(Token::RPAREN, CHECK_OK); | 3275 Expect(Token::RPAREN, CHECK_OK); |
3273 | 3276 |
3274 VariableProxy* each = scope_->NewUnresolved(factory(), name, each_pos); | 3277 VariableProxy* each = |
3278 scope_->NewUnresolved(factory(), name, each_beg_pos, each_end_pos); | |
3275 Statement* body = ParseSubStatement(NULL, CHECK_OK); | 3279 Statement* body = ParseSubStatement(NULL, CHECK_OK); |
3276 InitializeForEachStatement(loop, each, enumerable, body); | 3280 InitializeForEachStatement(loop, each, enumerable, body); |
3277 Block* result = | 3281 Block* result = |
3278 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 3282 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
3279 result->AddStatement(variable_statement, zone()); | 3283 result->AddStatement(variable_statement, zone()); |
3280 result->AddStatement(loop, zone()); | 3284 result->AddStatement(loop, zone()); |
3281 scope_ = saved_scope; | 3285 scope_ = saved_scope; |
3282 for_scope->set_end_position(scanner()->location().end_pos); | 3286 for_scope->set_end_position(scanner()->location().end_pos); |
3283 for_scope = for_scope->FinalizeBlockScope(); | 3287 for_scope = for_scope->FinalizeBlockScope(); |
3284 DCHECK(for_scope == NULL); | 3288 DCHECK(for_scope == NULL); |
3285 // Parsed for-in loop w/ variable/const declaration. | 3289 // Parsed for-in loop w/ variable/const declaration. |
3286 return result; | 3290 return result; |
3287 } else { | 3291 } else { |
3288 init = variable_statement; | 3292 init = variable_statement; |
3289 } | 3293 } |
3290 } else if ((peek() == Token::LET || peek() == Token::CONST) && | 3294 } else if ((peek() == Token::LET || peek() == Token::CONST) && |
3291 is_strict(language_mode())) { | 3295 is_strict(language_mode())) { |
3292 bool is_const = peek() == Token::CONST; | 3296 bool is_const = peek() == Token::CONST; |
3293 const AstRawString* name = NULL; | 3297 const AstRawString* name = NULL; |
3294 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3298 VariableDeclarationProperties decl_props = kHasNoInitializers; |
3295 Block* variable_statement = | 3299 Block* variable_statement = |
3296 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, | 3300 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, |
3297 &name, CHECK_OK); | 3301 &name, CHECK_OK); |
3298 bool accept_IN = name != NULL && decl_props != kHasInitializers; | 3302 bool accept_IN = name != NULL && decl_props != kHasInitializers; |
3299 bool accept_OF = decl_props == kHasNoInitializers; | 3303 bool accept_OF = decl_props == kHasNoInitializers; |
3300 ForEachStatement::VisitMode mode; | 3304 ForEachStatement::VisitMode mode; |
3301 int each_pos = position(); | 3305 int each_beg_pos = scanner()->location().beg_pos; |
3306 int each_end_pos = scanner()->location().end_pos; | |
3302 | 3307 |
3303 if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) { | 3308 if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) { |
3304 if (!*ok) return nullptr; | 3309 if (!*ok) return nullptr; |
3305 | 3310 |
3306 // Rewrite a for-in statement of the form | 3311 // Rewrite a for-in statement of the form |
3307 // | 3312 // |
3308 // for (let/const x in e) b | 3313 // for (let/const x in e) b |
3309 // | 3314 // |
3310 // into | 3315 // into |
3311 // | 3316 // |
3312 // <let x' be a temporary variable> | 3317 // <let x' be a temporary variable> |
3313 // for (x' in e) { | 3318 // for (x' in e) { |
3314 // let/const x; | 3319 // let/const x; |
3315 // x = x'; | 3320 // x = x'; |
3316 // b; | 3321 // b; |
3317 // } | 3322 // } |
3318 | 3323 |
3319 // TODO(keuchel): Move the temporary variable to the block scope, after | 3324 // TODO(keuchel): Move the temporary variable to the block scope, after |
3320 // implementing stack allocated block scoped variables. | 3325 // implementing stack allocated block scoped variables. |
3321 Variable* temp = scope_->DeclarationScope()->NewTemporary( | 3326 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
3322 ast_value_factory()->dot_for_string()); | 3327 ast_value_factory()->dot_for_string()); |
3323 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp, each_pos); | 3328 VariableProxy* temp_proxy = |
3329 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); | |
3324 ForEachStatement* loop = | 3330 ForEachStatement* loop = |
3325 factory()->NewForEachStatement(mode, labels, stmt_pos); | 3331 factory()->NewForEachStatement(mode, labels, stmt_pos); |
3326 Target target(&this->target_stack_, loop); | 3332 Target target(&this->target_stack_, loop); |
3327 | 3333 |
3328 // The expression does not see the loop variable. | 3334 // The expression does not see the loop variable. |
3329 scope_ = saved_scope; | 3335 scope_ = saved_scope; |
3330 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3336 Expression* enumerable = ParseExpression(true, CHECK_OK); |
3331 scope_ = for_scope; | 3337 scope_ = for_scope; |
3332 Expect(Token::RPAREN, CHECK_OK); | 3338 Expect(Token::RPAREN, CHECK_OK); |
3333 | 3339 |
3334 VariableProxy* each = scope_->NewUnresolved(factory(), name, each_pos); | 3340 VariableProxy* each = |
3341 scope_->NewUnresolved(factory(), name, each_beg_pos, each_end_pos); | |
3335 Statement* body = ParseSubStatement(NULL, CHECK_OK); | 3342 Statement* body = ParseSubStatement(NULL, CHECK_OK); |
3336 Block* body_block = | 3343 Block* body_block = |
3337 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); | 3344 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); |
3338 Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN; | 3345 Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN; |
3339 Assignment* assignment = factory()->NewAssignment( | 3346 Assignment* assignment = factory()->NewAssignment( |
3340 init_op, each, temp_proxy, RelocInfo::kNoPosition); | 3347 init_op, each, temp_proxy, RelocInfo::kNoPosition); |
3341 Statement* assignment_statement = factory()->NewExpressionStatement( | 3348 Statement* assignment_statement = factory()->NewExpressionStatement( |
3342 assignment, RelocInfo::kNoPosition); | 3349 assignment, RelocInfo::kNoPosition); |
3343 body_block->AddStatement(variable_statement, zone()); | 3350 body_block->AddStatement(variable_statement, zone()); |
3344 body_block->AddStatement(assignment_statement, zone()); | 3351 body_block->AddStatement(assignment_statement, zone()); |
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4108 block_scope->set_start_position(scanner()->location().end_pos); | 4115 block_scope->set_start_position(scanner()->location().end_pos); |
4109 } | 4116 } |
4110 | 4117 |
4111 | 4118 |
4112 ClassLiteralChecker checker(this); | 4119 ClassLiteralChecker checker(this); |
4113 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone()); | 4120 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone()); |
4114 FunctionLiteral* constructor = NULL; | 4121 FunctionLiteral* constructor = NULL; |
4115 bool has_seen_constructor = false; | 4122 bool has_seen_constructor = false; |
4116 | 4123 |
4117 Expect(Token::LBRACE, CHECK_OK); | 4124 Expect(Token::LBRACE, CHECK_OK); |
4125 int body_beg_pos = scanner()->location().beg_pos; | |
4126 | |
4118 const bool has_extends = extends != nullptr; | 4127 const bool has_extends = extends != nullptr; |
4119 while (peek() != Token::RBRACE) { | 4128 while (peek() != Token::RBRACE) { |
4120 if (Check(Token::SEMICOLON)) continue; | 4129 if (Check(Token::SEMICOLON)) continue; |
4121 if (fni_ != NULL) fni_->Enter(); | 4130 if (fni_ != NULL) fni_->Enter(); |
4122 const bool in_class = true; | 4131 const bool in_class = true; |
4123 const bool is_static = false; | 4132 const bool is_static = false; |
4124 bool is_computed_name = false; // Classes do not care about computed | 4133 bool is_computed_name = false; // Classes do not care about computed |
4125 // property names here. | 4134 // property names here. |
4126 ObjectLiteral::Property* property = ParsePropertyDefinition( | 4135 ObjectLiteral::Property* property = ParsePropertyDefinition( |
4127 &checker, in_class, has_extends, is_static, &is_computed_name, | 4136 &checker, in_class, has_extends, is_static, &is_computed_name, |
(...skipping 19 matching lines...) Expand all Loading... | |
4147 constructor = | 4156 constructor = |
4148 DefaultConstructor(extends != NULL, block_scope, pos, end_pos); | 4157 DefaultConstructor(extends != NULL, block_scope, pos, end_pos); |
4149 } | 4158 } |
4150 | 4159 |
4151 block_scope->set_end_position(end_pos); | 4160 block_scope->set_end_position(end_pos); |
4152 block_scope = block_scope->FinalizeBlockScope(); | 4161 block_scope = block_scope->FinalizeBlockScope(); |
4153 | 4162 |
4154 if (name != NULL) { | 4163 if (name != NULL) { |
4155 DCHECK_NOT_NULL(proxy); | 4164 DCHECK_NOT_NULL(proxy); |
4156 DCHECK_NOT_NULL(block_scope); | 4165 DCHECK_NOT_NULL(block_scope); |
4157 proxy->var()->set_initializer_position(end_pos); | 4166 proxy->var()->set_initializer_position(body_beg_pos); |
4158 } | 4167 } |
4159 | 4168 |
4160 return factory()->NewClassLiteral(name, block_scope, proxy, extends, | 4169 return factory()->NewClassLiteral(name, block_scope, proxy, extends, |
4161 constructor, properties, pos, end_pos); | 4170 constructor, properties, pos, end_pos); |
4162 } | 4171 } |
4163 | 4172 |
4164 | 4173 |
4165 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4174 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
4166 // CallRuntime :: | 4175 // CallRuntime :: |
4167 // '%' Identifier Arguments | 4176 // '%' Identifier Arguments |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4286 script->set_source_url(*source_url); | 4295 script->set_source_url(*source_url); |
4287 } | 4296 } |
4288 if (scanner_.source_mapping_url()->length() > 0) { | 4297 if (scanner_.source_mapping_url()->length() > 0) { |
4289 Handle<String> source_mapping_url = | 4298 Handle<String> source_mapping_url = |
4290 scanner_.source_mapping_url()->Internalize(isolate); | 4299 scanner_.source_mapping_url()->Internalize(isolate); |
4291 script->set_source_mapping_url(*source_mapping_url); | 4300 script->set_source_mapping_url(*source_mapping_url); |
4292 } | 4301 } |
4293 } | 4302 } |
4294 | 4303 |
4295 | 4304 |
4296 void Parser::ThrowPendingError(Isolate* isolate, Handle<Script> script) { | |
4297 DCHECK(ast_value_factory()->IsInternalized()); | |
4298 if (has_pending_error_) { | |
4299 MessageLocation location(script, pending_error_location_.beg_pos, | |
4300 pending_error_location_.end_pos); | |
4301 Factory* factory = isolate->factory(); | |
4302 bool has_arg = | |
4303 pending_error_arg_ != NULL || pending_error_char_arg_ != NULL; | |
4304 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0); | |
4305 if (pending_error_arg_ != NULL) { | |
4306 Handle<String> arg_string = pending_error_arg_->string(); | |
4307 elements->set(0, *arg_string); | |
4308 } else if (pending_error_char_arg_ != NULL) { | |
4309 Handle<String> arg_string = | |
4310 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_)) | |
4311 .ToHandleChecked(); | |
4312 elements->set(0, *arg_string); | |
4313 } | |
4314 isolate->debug()->OnCompileError(script); | |
4315 | |
4316 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | |
4317 Handle<Object> error; | |
4318 switch (pending_error_type_) { | |
4319 case kReferenceError: | |
4320 error = factory->NewReferenceError(pending_error_message_, array); | |
4321 break; | |
4322 case kSyntaxError: | |
4323 error = factory->NewSyntaxError(pending_error_message_, array); | |
4324 break; | |
4325 } | |
4326 | |
4327 Handle<JSObject> jserror = Handle<JSObject>::cast(error); | |
4328 | |
4329 Handle<Name> key_start_pos = factory->error_start_pos_symbol(); | |
4330 JSObject::SetProperty(jserror, key_start_pos, | |
4331 handle(Smi::FromInt(location.start_pos()), isolate), | |
4332 SLOPPY).Check(); | |
4333 | |
4334 Handle<Name> key_end_pos = factory->error_end_pos_symbol(); | |
4335 JSObject::SetProperty(jserror, key_end_pos, | |
4336 handle(Smi::FromInt(location.end_pos()), isolate), | |
4337 SLOPPY).Check(); | |
4338 | |
4339 Handle<Name> key_script = factory->error_script_symbol(); | |
4340 JSObject::SetProperty(jserror, key_script, script, SLOPPY).Check(); | |
4341 | |
4342 isolate->Throw(*error, &location); | |
4343 } | |
4344 } | |
4345 | |
4346 | |
4347 void Parser::Internalize(Isolate* isolate, Handle<Script> script, bool error) { | 4305 void Parser::Internalize(Isolate* isolate, Handle<Script> script, bool error) { |
4348 // Internalize strings. | 4306 // Internalize strings. |
4349 ast_value_factory()->Internalize(isolate); | 4307 ast_value_factory()->Internalize(isolate); |
4350 | 4308 |
4351 // Error processing. | 4309 // Error processing. |
4352 if (error) { | 4310 if (error) { |
4353 if (stack_overflow()) { | 4311 if (stack_overflow()) { |
4354 isolate->StackOverflow(); | 4312 isolate->StackOverflow(); |
4355 } else { | 4313 } else { |
4356 ThrowPendingError(isolate, script); | 4314 DCHECK(pending_error_handler_.has_pending_error()); |
4315 pending_error_handler_.ThrowPendingError(isolate, script); | |
4357 } | 4316 } |
4358 } | 4317 } |
4359 | 4318 |
4360 // Move statistics to Isolate. | 4319 // Move statistics to Isolate. |
4361 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 4320 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
4362 ++feature) { | 4321 ++feature) { |
4363 for (int i = 0; i < use_counts_[feature]; ++i) { | 4322 for (int i = 0; i < use_counts_[feature]; ++i) { |
4364 isolate->CountUsage(v8::Isolate::UseCounterFeature(feature)); | 4323 isolate->CountUsage(v8::Isolate::UseCounterFeature(feature)); |
4365 } | 4324 } |
4366 } | 4325 } |
(...skipping 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5485 } else { | 5444 } else { |
5486 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); | 5445 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); |
5487 running_hash = StringHasher::ComputeRunningHash(running_hash, data, | 5446 running_hash = StringHasher::ComputeRunningHash(running_hash, data, |
5488 raw_string->length()); | 5447 raw_string->length()); |
5489 } | 5448 } |
5490 } | 5449 } |
5491 | 5450 |
5492 return running_hash; | 5451 return running_hash; |
5493 } | 5452 } |
5494 } } // namespace v8::internal | 5453 } } // namespace v8::internal |
OLD | NEW |