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(), |
|
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 |