Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(448)

Side by Side Diff: src/parser.cc

Issue 943543002: [strong] Declaration-after-use errors. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: more fixes + tests Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698