| 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/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/ast/ast.h" | 10 #include "src/ast/ast.h" |
| (...skipping 2281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2292 } | 2292 } |
| 2293 | 2293 |
| 2294 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) { | 2294 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) { |
| 2295 // The harmony mode uses block elements instead of statements. | 2295 // The harmony mode uses block elements instead of statements. |
| 2296 // | 2296 // |
| 2297 // Block :: | 2297 // Block :: |
| 2298 // '{' StatementList '}' | 2298 // '{' StatementList '}' |
| 2299 | 2299 |
| 2300 // Construct block expecting 16 statements. | 2300 // Construct block expecting 16 statements. |
| 2301 Block* body = factory()->NewBlock(labels, 16, false, kNoSourcePosition); | 2301 Block* body = factory()->NewBlock(labels, 16, false, kNoSourcePosition); |
| 2302 Scope* block_scope = NewScope(BLOCK_SCOPE); | |
| 2303 | 2302 |
| 2304 // Parse the statements and collect escaping labels. | 2303 // Parse the statements and collect escaping labels. |
| 2305 Expect(Token::LBRACE, CHECK_OK); | 2304 Expect(Token::LBRACE, CHECK_OK); |
| 2306 block_scope->set_start_position(scanner()->location().beg_pos); | |
| 2307 { | 2305 { |
| 2308 BlockState block_state(&scope_state_, block_scope); | 2306 BlockState block_state(&scope_state_); |
| 2307 block_state.set_start_position(scanner()->location().beg_pos); |
| 2309 Target target(&this->target_stack_, body); | 2308 Target target(&this->target_stack_, body); |
| 2310 | 2309 |
| 2311 while (peek() != Token::RBRACE) { | 2310 while (peek() != Token::RBRACE) { |
| 2312 Statement* stat = ParseStatementListItem(CHECK_OK); | 2311 Statement* stat = ParseStatementListItem(CHECK_OK); |
| 2313 if (stat && !stat->IsEmpty()) { | 2312 if (stat && !stat->IsEmpty()) { |
| 2314 body->statements()->Add(stat, zone()); | 2313 body->statements()->Add(stat, zone()); |
| 2315 } | 2314 } |
| 2316 } | 2315 } |
| 2316 |
| 2317 Expect(Token::RBRACE, CHECK_OK); |
| 2318 block_state.set_end_position(scanner()->location().end_pos); |
| 2319 body->set_scope(block_state.FinalizedBlockScope()); |
| 2317 } | 2320 } |
| 2318 Expect(Token::RBRACE, CHECK_OK); | |
| 2319 block_scope->set_end_position(scanner()->location().end_pos); | |
| 2320 block_scope = block_scope->FinalizeBlockScope(); | |
| 2321 body->set_scope(block_scope); | |
| 2322 return body; | 2321 return body; |
| 2323 } | 2322 } |
| 2324 | 2323 |
| 2325 | 2324 |
| 2326 Block* Parser::DeclarationParsingResult::BuildInitializationBlock( | 2325 Block* Parser::DeclarationParsingResult::BuildInitializationBlock( |
| 2327 ZoneList<const AstRawString*>* names, bool* ok) { | 2326 ZoneList<const AstRawString*>* names, bool* ok) { |
| 2328 Block* result = descriptor.parser->factory()->NewBlock( | 2327 Block* result = descriptor.parser->factory()->NewBlock( |
| 2329 NULL, 1, true, descriptor.declaration_pos); | 2328 NULL, 1, true, descriptor.declaration_pos); |
| 2330 for (auto declaration : declarations) { | 2329 for (auto declaration : declarations) { |
| 2331 PatternRewriter::DeclareAndInitializeVariables( | 2330 PatternRewriter::DeclareAndInitializeVariables( |
| (...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2908 | 2907 |
| 2909 // make statement: undefined; | 2908 // make statement: undefined; |
| 2910 // This is needed so the tag isn't returned as the value, in case the switch | 2909 // This is needed so the tag isn't returned as the value, in case the switch |
| 2911 // statements don't have a value. | 2910 // statements don't have a value. |
| 2912 switch_block->statements()->Add( | 2911 switch_block->statements()->Add( |
| 2913 factory()->NewExpressionStatement( | 2912 factory()->NewExpressionStatement( |
| 2914 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition), | 2913 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition), |
| 2915 zone()); | 2914 zone()); |
| 2916 | 2915 |
| 2917 Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); | 2916 Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); |
| 2918 Scope* cases_scope = NewScope(BLOCK_SCOPE); | |
| 2919 cases_scope->SetNonlinear(); | |
| 2920 | 2917 |
| 2921 SwitchStatement* switch_statement = | 2918 SwitchStatement* switch_statement = |
| 2922 factory()->NewSwitchStatement(labels, switch_pos); | 2919 factory()->NewSwitchStatement(labels, switch_pos); |
| 2923 | 2920 |
| 2924 cases_scope->set_start_position(scanner()->location().beg_pos); | |
| 2925 { | 2921 { |
| 2926 BlockState cases_block_state(&scope_state_, cases_scope); | 2922 BlockState cases_block_state(&scope_state_); |
| 2923 cases_block_state.set_start_position(scanner()->location().beg_pos); |
| 2924 cases_block_state.SetNonlinear(); |
| 2927 Target target(&this->target_stack_, switch_statement); | 2925 Target target(&this->target_stack_, switch_statement); |
| 2928 | 2926 |
| 2929 Expression* tag_read = factory()->NewVariableProxy(tag_variable); | 2927 Expression* tag_read = factory()->NewVariableProxy(tag_variable); |
| 2930 | 2928 |
| 2931 bool default_seen = false; | 2929 bool default_seen = false; |
| 2932 ZoneList<CaseClause*>* cases = | 2930 ZoneList<CaseClause*>* cases = |
| 2933 new (zone()) ZoneList<CaseClause*>(4, zone()); | 2931 new (zone()) ZoneList<CaseClause*>(4, zone()); |
| 2934 Expect(Token::LBRACE, CHECK_OK); | 2932 Expect(Token::LBRACE, CHECK_OK); |
| 2935 while (peek() != Token::RBRACE) { | 2933 while (peek() != Token::RBRACE) { |
| 2936 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); | 2934 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); |
| 2937 cases->Add(clause, zone()); | 2935 cases->Add(clause, zone()); |
| 2938 } | 2936 } |
| 2939 switch_statement->Initialize(tag_read, cases); | 2937 switch_statement->Initialize(tag_read, cases); |
| 2940 cases_block->statements()->Add(switch_statement, zone()); | 2938 cases_block->statements()->Add(switch_statement, zone()); |
| 2939 Expect(Token::RBRACE, CHECK_OK); |
| 2940 |
| 2941 cases_block_state.set_end_position(scanner()->location().end_pos); |
| 2942 cases_block->set_scope(cases_block_state.FinalizedBlockScope()); |
| 2941 } | 2943 } |
| 2942 Expect(Token::RBRACE, CHECK_OK); | |
| 2943 | |
| 2944 cases_scope->set_end_position(scanner()->location().end_pos); | |
| 2945 cases_scope = cases_scope->FinalizeBlockScope(); | |
| 2946 cases_block->set_scope(cases_scope); | |
| 2947 | 2944 |
| 2948 switch_block->statements()->Add(cases_block, zone()); | 2945 switch_block->statements()->Add(cases_block, zone()); |
| 2949 | 2946 |
| 2950 return switch_block; | 2947 return switch_block; |
| 2951 } | 2948 } |
| 2952 | 2949 |
| 2953 | 2950 |
| 2954 Statement* Parser::ParseThrowStatement(bool* ok) { | 2951 Statement* Parser::ParseThrowStatement(bool* ok) { |
| 2955 // ThrowStatement :: | 2952 // ThrowStatement :: |
| 2956 // 'throw' Expression ';' | 2953 // 'throw' Expression ';' |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3021 { | 3018 { |
| 3022 CollectExpressionsInTailPositionToListScope | 3019 CollectExpressionsInTailPositionToListScope |
| 3023 collect_tail_call_expressions_scope( | 3020 collect_tail_call_expressions_scope( |
| 3024 function_state_, &tail_call_expressions_in_catch_block); | 3021 function_state_, &tail_call_expressions_in_catch_block); |
| 3025 BlockState block_state(&scope_state_, catch_scope); | 3022 BlockState block_state(&scope_state_, catch_scope); |
| 3026 | 3023 |
| 3027 catch_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition); | 3024 catch_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition); |
| 3028 | 3025 |
| 3029 // Create a block scope to hold any lexical declarations created | 3026 // Create a block scope to hold any lexical declarations created |
| 3030 // as part of destructuring the catch parameter. | 3027 // as part of destructuring the catch parameter. |
| 3031 Scope* block_scope = NewScope(BLOCK_SCOPE); | |
| 3032 block_scope->set_start_position(scanner()->location().beg_pos); | |
| 3033 { | 3028 { |
| 3034 BlockState block_state(&scope_state_, block_scope); | 3029 BlockState block_state(&scope_state_); |
| 3030 block_state.set_start_position(scanner()->location().beg_pos); |
| 3035 Target target(&this->target_stack_, catch_block); | 3031 Target target(&this->target_stack_, catch_block); |
| 3036 | 3032 |
| 3037 const AstRawString* name = ast_value_factory()->dot_catch_string(); | 3033 const AstRawString* name = ast_value_factory()->dot_catch_string(); |
| 3038 Expression* pattern = nullptr; | 3034 Expression* pattern = nullptr; |
| 3039 if (peek_any_identifier()) { | 3035 if (peek_any_identifier()) { |
| 3040 name = ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); | 3036 name = ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); |
| 3041 } else { | 3037 } else { |
| 3042 ExpressionClassifier pattern_classifier(this); | 3038 ExpressionClassifier pattern_classifier(this); |
| 3043 pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK); | 3039 pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK); |
| 3044 ValidateBindingPattern(&pattern_classifier, CHECK_OK); | 3040 ValidateBindingPattern(&pattern_classifier, CHECK_OK); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3090 Scanner::Location location = | 3086 Scanner::Location location = |
| 3091 position == kNoSourcePosition | 3087 position == kNoSourcePosition |
| 3092 ? Scanner::Location::invalid() | 3088 ? Scanner::Location::invalid() |
| 3093 : Scanner::Location(position, position + 1); | 3089 : Scanner::Location(position, position + 1); |
| 3094 ParserTraits::ReportMessageAt( | 3090 ParserTraits::ReportMessageAt( |
| 3095 location, MessageTemplate::kVarRedeclaration, name); | 3091 location, MessageTemplate::kVarRedeclaration, name); |
| 3096 *ok = false; | 3092 *ok = false; |
| 3097 return nullptr; | 3093 return nullptr; |
| 3098 } | 3094 } |
| 3099 } | 3095 } |
| 3096 block_state.set_end_position(scanner()->location().end_pos); |
| 3097 catch_block->set_scope(block_state.FinalizedBlockScope()); |
| 3100 } | 3098 } |
| 3101 block_scope->set_end_position(scanner()->location().end_pos); | |
| 3102 block_scope = block_scope->FinalizeBlockScope(); | |
| 3103 catch_block->set_scope(block_scope); | |
| 3104 } | 3099 } |
| 3105 | 3100 |
| 3106 catch_scope->set_end_position(scanner()->location().end_pos); | 3101 catch_scope->set_end_position(scanner()->location().end_pos); |
| 3107 tok = peek(); | 3102 tok = peek(); |
| 3108 } | 3103 } |
| 3109 | 3104 |
| 3110 Block* finally_block = NULL; | 3105 Block* finally_block = NULL; |
| 3111 DCHECK(tok == Token::FINALLY || catch_block != NULL); | 3106 DCHECK(tok == Token::FINALLY || catch_block != NULL); |
| 3112 if (tok == Token::FINALLY) { | 3107 if (tok == Token::FINALLY) { |
| 3113 Consume(Token::FINALLY); | 3108 Consume(Token::FINALLY); |
| (...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3657 bool legacy, bool* ok) { | 3652 bool legacy, bool* ok) { |
| 3658 if (is_strict(language_mode()) || peek() != Token::FUNCTION || | 3653 if (is_strict(language_mode()) || peek() != Token::FUNCTION || |
| 3659 (legacy && allow_harmony_restrictive_declarations())) { | 3654 (legacy && allow_harmony_restrictive_declarations())) { |
| 3660 return ParseSubStatement(labels, kDisallowLabelledFunctionStatement, ok); | 3655 return ParseSubStatement(labels, kDisallowLabelledFunctionStatement, ok); |
| 3661 } else { | 3656 } else { |
| 3662 if (legacy) { | 3657 if (legacy) { |
| 3663 ++use_counts_[v8::Isolate::kLegacyFunctionDeclaration]; | 3658 ++use_counts_[v8::Isolate::kLegacyFunctionDeclaration]; |
| 3664 } | 3659 } |
| 3665 // Make a block around the statement for a lexical binding | 3660 // Make a block around the statement for a lexical binding |
| 3666 // is introduced by a FunctionDeclaration. | 3661 // is introduced by a FunctionDeclaration. |
| 3667 Scope* body_scope = NewScope(BLOCK_SCOPE); | 3662 BlockState block_state(&scope_state_); |
| 3668 body_scope->set_start_position(scanner()->location().beg_pos); | 3663 block_state.set_start_position(scanner()->location().beg_pos); |
| 3669 BlockState block_state(&scope_state_, body_scope); | |
| 3670 Block* block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); | 3664 Block* block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); |
| 3671 Statement* body = ParseFunctionDeclaration(CHECK_OK); | 3665 Statement* body = ParseFunctionDeclaration(CHECK_OK); |
| 3672 block->statements()->Add(body, zone()); | 3666 block->statements()->Add(body, zone()); |
| 3673 body_scope->set_end_position(scanner()->location().end_pos); | 3667 block_state.set_end_position(scanner()->location().end_pos); |
| 3674 body_scope = body_scope->FinalizeBlockScope(); | 3668 block->set_scope(block_state.FinalizedBlockScope()); |
| 3675 block->set_scope(body_scope); | |
| 3676 return block; | 3669 return block; |
| 3677 } | 3670 } |
| 3678 } | 3671 } |
| 3679 | 3672 |
| 3680 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, | 3673 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, |
| 3681 bool* ok) { | 3674 bool* ok) { |
| 3682 int stmt_pos = peek_position(); | 3675 int stmt_pos = peek_position(); |
| 3683 Statement* init = NULL; | 3676 Statement* init = NULL; |
| 3684 ZoneList<const AstRawString*> bound_names(1, zone()); | 3677 ZoneList<const AstRawString*> bound_names(1, zone()); |
| 3685 bool bound_names_are_lexical = false; | 3678 bool bound_names_are_lexical = false; |
| 3686 | 3679 |
| 3687 // Create an in-between scope for let-bound iteration variables. | 3680 // Create an in-between scope for let-bound iteration variables. |
| 3688 Scope* for_scope = NewScope(BLOCK_SCOPE); | 3681 BlockState for_state(&scope_state_); |
| 3689 | |
| 3690 BlockState block_state(&scope_state_, for_scope); | |
| 3691 Expect(Token::FOR, CHECK_OK); | 3682 Expect(Token::FOR, CHECK_OK); |
| 3692 Expect(Token::LPAREN, CHECK_OK); | 3683 Expect(Token::LPAREN, CHECK_OK); |
| 3693 for_scope->set_start_position(scanner()->location().beg_pos); | 3684 for_state.set_start_position(scanner()->location().beg_pos); |
| 3694 for_scope->set_is_hidden(); | 3685 for_state.set_is_hidden(); |
| 3695 DeclarationParsingResult parsing_result; | 3686 DeclarationParsingResult parsing_result; |
| 3696 if (peek() != Token::SEMICOLON) { | 3687 if (peek() != Token::SEMICOLON) { |
| 3697 if (peek() == Token::VAR || peek() == Token::CONST || | 3688 if (peek() == Token::VAR || peek() == Token::CONST || |
| 3698 (peek() == Token::LET && IsNextLetKeyword())) { | 3689 (peek() == Token::LET && IsNextLetKeyword())) { |
| 3699 ParseVariableDeclarations(kForStatement, &parsing_result, nullptr, | 3690 ParseVariableDeclarations(kForStatement, &parsing_result, nullptr, |
| 3700 CHECK_OK); | 3691 CHECK_OK); |
| 3701 | 3692 |
| 3702 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; | 3693 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; |
| 3703 int each_beg_pos = scanner()->location().beg_pos; | 3694 int each_beg_pos = scanner()->location().beg_pos; |
| 3704 int each_end_pos = scanner()->location().end_pos; | 3695 int each_end_pos = scanner()->location().end_pos; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3783 if (mode == ForEachStatement::ITERATE) { | 3774 if (mode == ForEachStatement::ITERATE) { |
| 3784 ExpressionClassifier classifier(this); | 3775 ExpressionClassifier classifier(this); |
| 3785 enumerable = ParseAssignmentExpression(true, &classifier, CHECK_OK); | 3776 enumerable = ParseAssignmentExpression(true, &classifier, CHECK_OK); |
| 3786 RewriteNonPattern(&classifier, CHECK_OK); | 3777 RewriteNonPattern(&classifier, CHECK_OK); |
| 3787 } else { | 3778 } else { |
| 3788 enumerable = ParseExpression(true, CHECK_OK); | 3779 enumerable = ParseExpression(true, CHECK_OK); |
| 3789 } | 3780 } |
| 3790 | 3781 |
| 3791 Expect(Token::RPAREN, CHECK_OK); | 3782 Expect(Token::RPAREN, CHECK_OK); |
| 3792 | 3783 |
| 3793 Scope* body_scope = NewScope(BLOCK_SCOPE); | |
| 3794 body_scope->set_start_position(scanner()->location().beg_pos); | |
| 3795 | 3784 |
| 3796 Block* body_block = | 3785 Block* body_block = |
| 3797 factory()->NewBlock(NULL, 3, false, kNoSourcePosition); | 3786 factory()->NewBlock(NULL, 3, false, kNoSourcePosition); |
| 3798 | 3787 |
| 3799 Statement* final_loop; | 3788 Statement* final_loop; |
| 3800 { | 3789 { |
| 3801 ReturnExprScope no_tail_calls(function_state_, | 3790 ReturnExprScope no_tail_calls(function_state_, |
| 3802 ReturnExprContext::kInsideForInOfBody); | 3791 ReturnExprContext::kInsideForInOfBody); |
| 3803 BlockState block_state(&scope_state_, body_scope); | 3792 BlockState block_state(&scope_state_); |
| 3793 block_state.set_start_position(scanner()->location().beg_pos); |
| 3804 | 3794 |
| 3805 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); | 3795 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); |
| 3806 | 3796 |
| 3807 auto each_initialization_block = | 3797 auto each_initialization_block = |
| 3808 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); | 3798 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); |
| 3809 { | 3799 { |
| 3810 auto descriptor = parsing_result.descriptor; | 3800 auto descriptor = parsing_result.descriptor; |
| 3811 descriptor.declaration_pos = kNoSourcePosition; | 3801 descriptor.declaration_pos = kNoSourcePosition; |
| 3812 descriptor.initialization_pos = kNoSourcePosition; | 3802 descriptor.initialization_pos = kNoSourcePosition; |
| 3813 decl.initializer = factory()->NewVariableProxy(temp); | 3803 decl.initializer = factory()->NewVariableProxy(temp); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3851 } | 3841 } |
| 3852 } | 3842 } |
| 3853 } | 3843 } |
| 3854 | 3844 |
| 3855 body_block->statements()->Add(each_initialization_block, zone()); | 3845 body_block->statements()->Add(each_initialization_block, zone()); |
| 3856 body_block->statements()->Add(body, zone()); | 3846 body_block->statements()->Add(body, zone()); |
| 3857 VariableProxy* temp_proxy = | 3847 VariableProxy* temp_proxy = |
| 3858 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); | 3848 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); |
| 3859 final_loop = InitializeForEachStatement( | 3849 final_loop = InitializeForEachStatement( |
| 3860 loop, temp_proxy, enumerable, body_block, each_keyword_position); | 3850 loop, temp_proxy, enumerable, body_block, each_keyword_position); |
| 3851 block_state.set_end_position(scanner()->location().end_pos); |
| 3852 body_block->set_scope(block_state.FinalizedBlockScope()); |
| 3861 } | 3853 } |
| 3862 body_scope->set_end_position(scanner()->location().end_pos); | |
| 3863 body_scope = body_scope->FinalizeBlockScope(); | |
| 3864 body_block->set_scope(body_scope); | |
| 3865 | 3854 |
| 3866 // Create a TDZ for any lexically-bound names. | 3855 // Create a TDZ for any lexically-bound names. |
| 3867 if (bound_names_are_lexical) { | 3856 if (bound_names_are_lexical) { |
| 3868 DCHECK_NULL(init_block); | 3857 DCHECK_NULL(init_block); |
| 3869 | 3858 |
| 3870 init_block = | 3859 init_block = |
| 3871 factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); | 3860 factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); |
| 3872 | 3861 |
| 3873 for (int i = 0; i < bound_names.length(); ++i) { | 3862 for (int i = 0; i < bound_names.length(); ++i) { |
| 3874 // TODO(adamk): This needs to be some sort of special | 3863 // TODO(adamk): This needs to be some sort of special |
| 3875 // INTERNAL variable that's invisible to the debugger | 3864 // INTERNAL variable that's invisible to the debugger |
| 3876 // but visible to everything else. | 3865 // but visible to everything else. |
| 3877 VariableProxy* tdz_proxy = NewUnresolved(bound_names[i], LET); | 3866 VariableProxy* tdz_proxy = NewUnresolved(bound_names[i], LET); |
| 3878 Declaration* tdz_decl = factory()->NewVariableDeclaration( | 3867 Declaration* tdz_decl = factory()->NewVariableDeclaration( |
| 3879 tdz_proxy, LET, scope(), kNoSourcePosition); | 3868 tdz_proxy, LET, scope(), kNoSourcePosition); |
| 3880 Variable* tdz_var = Declare( | 3869 Variable* tdz_var = Declare( |
| 3881 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 3870 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
| 3882 tdz_var->set_initializer_position(position()); | 3871 tdz_var->set_initializer_position(position()); |
| 3883 } | 3872 } |
| 3884 } | 3873 } |
| 3885 | 3874 |
| 3886 for_scope->set_end_position(scanner()->location().end_pos); | 3875 for_state.set_end_position(scanner()->location().end_pos); |
| 3887 for_scope = for_scope->FinalizeBlockScope(); | 3876 Scope* for_scope = for_state.FinalizedBlockScope(); |
| 3888 // Parsed for-in loop w/ variable declarations. | 3877 // Parsed for-in loop w/ variable declarations. |
| 3889 if (init_block != nullptr) { | 3878 if (init_block != nullptr) { |
| 3890 init_block->statements()->Add(final_loop, zone()); | 3879 init_block->statements()->Add(final_loop, zone()); |
| 3891 init_block->set_scope(for_scope); | 3880 init_block->set_scope(for_scope); |
| 3892 return init_block; | 3881 return init_block; |
| 3893 } else { | 3882 } else { |
| 3894 DCHECK_NULL(for_scope); | 3883 DCHECK_NULL(for_scope); |
| 3895 return final_loop; | 3884 return final_loop; |
| 3896 } | 3885 } |
| 3897 } else { | 3886 } else { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3940 } | 3929 } |
| 3941 | 3930 |
| 3942 Expect(Token::RPAREN, CHECK_OK); | 3931 Expect(Token::RPAREN, CHECK_OK); |
| 3943 | 3932 |
| 3944 // For legacy compat reasons, give for loops similar treatment to | 3933 // For legacy compat reasons, give for loops similar treatment to |
| 3945 // if statements in allowing a function declaration for a body | 3934 // if statements in allowing a function declaration for a body |
| 3946 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); | 3935 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); |
| 3947 Statement* final_loop = InitializeForEachStatement( | 3936 Statement* final_loop = InitializeForEachStatement( |
| 3948 loop, expression, enumerable, body, each_keyword_position); | 3937 loop, expression, enumerable, body, each_keyword_position); |
| 3949 | 3938 |
| 3950 for_scope->set_end_position(scanner()->location().end_pos); | 3939 DCHECK_NULL(for_state.FinalizedBlockScope()); |
| 3951 for_scope = for_scope->FinalizeBlockScope(); | |
| 3952 DCHECK(for_scope == nullptr); | |
| 3953 return final_loop; | 3940 return final_loop; |
| 3954 | 3941 |
| 3955 } else { | 3942 } else { |
| 3956 init = factory()->NewExpressionStatement(expression, lhs_beg_pos); | 3943 init = factory()->NewExpressionStatement(expression, lhs_beg_pos); |
| 3957 } | 3944 } |
| 3958 } | 3945 } |
| 3959 } | 3946 } |
| 3960 | 3947 |
| 3961 // Standard 'for' loop | 3948 // Standard 'for' loop |
| 3962 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); | 3949 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); |
| 3963 Target target(&this->target_stack_, loop); | 3950 Target target(&this->target_stack_, loop); |
| 3964 | 3951 |
| 3965 // Parsed initializer at this point. | 3952 // Parsed initializer at this point. |
| 3966 Expect(Token::SEMICOLON, CHECK_OK); | 3953 Expect(Token::SEMICOLON, CHECK_OK); |
| 3967 | 3954 |
| 3968 Expression* cond = NULL; | 3955 Expression* cond = NULL; |
| 3969 Statement* next = NULL; | 3956 Statement* next = NULL; |
| 3970 Statement* body = NULL; | 3957 Statement* body = NULL; |
| 3971 | 3958 |
| 3972 // If there are let bindings, then condition and the next statement of the | 3959 // If there are let bindings, then condition and the next statement of the |
| 3973 // for loop must be parsed in a new scope. | 3960 // for loop must be parsed in a new scope. |
| 3974 Scope* inner_scope = scope(); | 3961 Scope* inner_scope = scope(); |
| 3962 // TODO(verwaest): Allocate this through a ScopeState as well. |
| 3975 if (bound_names_are_lexical && bound_names.length() > 0) { | 3963 if (bound_names_are_lexical && bound_names.length() > 0) { |
| 3976 inner_scope = NewScopeWithParent(for_scope, BLOCK_SCOPE); | 3964 inner_scope = NewScopeWithParent(inner_scope, BLOCK_SCOPE); |
| 3977 inner_scope->set_start_position(scanner()->location().beg_pos); | 3965 inner_scope->set_start_position(scanner()->location().beg_pos); |
| 3978 } | 3966 } |
| 3979 { | 3967 { |
| 3980 BlockState block_state(&scope_state_, inner_scope); | 3968 BlockState block_state(&scope_state_, inner_scope); |
| 3981 | 3969 |
| 3982 if (peek() != Token::SEMICOLON) { | 3970 if (peek() != Token::SEMICOLON) { |
| 3983 cond = ParseExpression(true, CHECK_OK); | 3971 cond = ParseExpression(true, CHECK_OK); |
| 3984 } | 3972 } |
| 3985 Expect(Token::SEMICOLON, CHECK_OK); | 3973 Expect(Token::SEMICOLON, CHECK_OK); |
| 3986 | 3974 |
| 3987 if (peek() != Token::RPAREN) { | 3975 if (peek() != Token::RPAREN) { |
| 3988 Expression* exp = ParseExpression(true, CHECK_OK); | 3976 Expression* exp = ParseExpression(true, CHECK_OK); |
| 3989 next = factory()->NewExpressionStatement(exp, exp->position()); | 3977 next = factory()->NewExpressionStatement(exp, exp->position()); |
| 3990 } | 3978 } |
| 3991 Expect(Token::RPAREN, CHECK_OK); | 3979 Expect(Token::RPAREN, CHECK_OK); |
| 3992 | 3980 |
| 3993 body = ParseScopedStatement(NULL, true, CHECK_OK); | 3981 body = ParseScopedStatement(NULL, true, CHECK_OK); |
| 3994 } | 3982 } |
| 3995 | 3983 |
| 3996 Statement* result = NULL; | 3984 Statement* result = NULL; |
| 3997 if (bound_names_are_lexical && bound_names.length() > 0) { | 3985 if (bound_names_are_lexical && bound_names.length() > 0) { |
| 3998 BlockState block_state(&scope_state_, for_scope); | |
| 3999 result = DesugarLexicalBindingsInForStatement( | 3986 result = DesugarLexicalBindingsInForStatement( |
| 4000 inner_scope, parsing_result.descriptor.mode, &bound_names, loop, init, | 3987 inner_scope, parsing_result.descriptor.mode, &bound_names, loop, init, |
| 4001 cond, next, body, CHECK_OK); | 3988 cond, next, body, CHECK_OK); |
| 4002 for_scope->set_end_position(scanner()->location().end_pos); | 3989 for_state.set_end_position(scanner()->location().end_pos); |
| 4003 } else { | 3990 } else { |
| 4004 for_scope->set_end_position(scanner()->location().end_pos); | 3991 for_state.set_end_position(scanner()->location().end_pos); |
| 4005 for_scope = for_scope->FinalizeBlockScope(); | 3992 Scope* for_scope = for_state.FinalizedBlockScope(); |
| 4006 if (for_scope) { | 3993 if (for_scope) { |
| 4007 // Rewrite a for statement of the form | 3994 // Rewrite a for statement of the form |
| 4008 // for (const x = i; c; n) b | 3995 // for (const x = i; c; n) b |
| 4009 // | 3996 // |
| 4010 // into | 3997 // into |
| 4011 // | 3998 // |
| 4012 // { | 3999 // { |
| 4013 // const x = i; | 4000 // const x = i; |
| 4014 // for (; c; n) b | 4001 // for (; c; n) b |
| 4015 // } | 4002 // } |
| (...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5007 Expression* Parser::ParseClassLiteral(ExpressionClassifier* classifier, | 4994 Expression* Parser::ParseClassLiteral(ExpressionClassifier* classifier, |
| 5008 const AstRawString* name, | 4995 const AstRawString* name, |
| 5009 Scanner::Location class_name_location, | 4996 Scanner::Location class_name_location, |
| 5010 bool name_is_strict_reserved, int pos, | 4997 bool name_is_strict_reserved, int pos, |
| 5011 bool* ok) { | 4998 bool* ok) { |
| 5012 // All parts of a ClassDeclaration and ClassExpression are strict code. | 4999 // All parts of a ClassDeclaration and ClassExpression are strict code. |
| 5013 if (name_is_strict_reserved) { | 5000 if (name_is_strict_reserved) { |
| 5014 ReportMessageAt(class_name_location, | 5001 ReportMessageAt(class_name_location, |
| 5015 MessageTemplate::kUnexpectedStrictReserved); | 5002 MessageTemplate::kUnexpectedStrictReserved); |
| 5016 *ok = false; | 5003 *ok = false; |
| 5017 return NULL; | 5004 return nullptr; |
| 5018 } | 5005 } |
| 5019 if (IsEvalOrArguments(name)) { | 5006 if (IsEvalOrArguments(name)) { |
| 5020 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments); | 5007 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments); |
| 5021 *ok = false; | 5008 *ok = false; |
| 5022 return NULL; | 5009 return nullptr; |
| 5023 } | 5010 } |
| 5024 | 5011 |
| 5025 Scope* block_scope = NewScope(BLOCK_SCOPE); | 5012 BlockState block_state(&scope_state_); |
| 5026 BlockState block_state(&scope_state_, block_scope); | |
| 5027 RaiseLanguageMode(STRICT); | 5013 RaiseLanguageMode(STRICT); |
| 5028 scope()->SetScopeName(name); | 5014 scope()->SetScopeName(name); |
| 5029 | 5015 |
| 5030 VariableProxy* proxy = NULL; | 5016 VariableProxy* proxy = nullptr; |
| 5031 if (name != NULL) { | 5017 if (name != nullptr) { |
| 5032 proxy = NewUnresolved(name, CONST); | 5018 proxy = NewUnresolved(name, CONST); |
| 5033 Declaration* declaration = | 5019 // TODO(verwaest): declare via block_state. |
| 5034 factory()->NewVariableDeclaration(proxy, CONST, block_scope, pos); | 5020 Declaration* declaration = factory()->NewVariableDeclaration( |
| 5021 proxy, CONST, block_state.scope(), pos); |
| 5035 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 5022 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
| 5036 } | 5023 } |
| 5037 | 5024 |
| 5038 Expression* extends = NULL; | 5025 Expression* extends = nullptr; |
| 5039 if (Check(Token::EXTENDS)) { | 5026 if (Check(Token::EXTENDS)) { |
| 5040 block_scope->set_start_position(scanner()->location().end_pos); | 5027 block_state.set_start_position(scanner()->location().end_pos); |
| 5041 ExpressionClassifier extends_classifier(this); | 5028 ExpressionClassifier extends_classifier(this); |
| 5042 extends = ParseLeftHandSideExpression(&extends_classifier, CHECK_OK); | 5029 extends = ParseLeftHandSideExpression(&extends_classifier, CHECK_OK); |
| 5043 CheckNoTailCallExpressions(&extends_classifier, CHECK_OK); | 5030 CheckNoTailCallExpressions(&extends_classifier, CHECK_OK); |
| 5044 RewriteNonPattern(&extends_classifier, CHECK_OK); | 5031 RewriteNonPattern(&extends_classifier, CHECK_OK); |
| 5045 if (classifier != nullptr) { | 5032 if (classifier != nullptr) { |
| 5046 classifier->Accumulate(&extends_classifier, | 5033 classifier->Accumulate(&extends_classifier, |
| 5047 ExpressionClassifier::ExpressionProductions); | 5034 ExpressionClassifier::ExpressionProductions); |
| 5048 } | 5035 } |
| 5049 } else { | 5036 } else { |
| 5050 block_scope->set_start_position(scanner()->location().end_pos); | 5037 block_state.set_start_position(scanner()->location().end_pos); |
| 5051 } | 5038 } |
| 5052 | 5039 |
| 5053 | 5040 |
| 5054 ClassLiteralChecker checker(this); | 5041 ClassLiteralChecker checker(this); |
| 5055 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone()); | 5042 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone()); |
| 5056 FunctionLiteral* constructor = NULL; | 5043 FunctionLiteral* constructor = nullptr; |
| 5057 bool has_seen_constructor = false; | 5044 bool has_seen_constructor = false; |
| 5058 | 5045 |
| 5059 Expect(Token::LBRACE, CHECK_OK); | 5046 Expect(Token::LBRACE, CHECK_OK); |
| 5060 | 5047 |
| 5061 const bool has_extends = extends != nullptr; | 5048 const bool has_extends = extends != nullptr; |
| 5062 while (peek() != Token::RBRACE) { | 5049 while (peek() != Token::RBRACE) { |
| 5063 if (Check(Token::SEMICOLON)) continue; | 5050 if (Check(Token::SEMICOLON)) continue; |
| 5064 FuncNameInferrer::State fni_state(fni_); | 5051 FuncNameInferrer::State fni_state(fni_); |
| 5065 const bool in_class = true; | 5052 const bool in_class = true; |
| 5066 bool is_computed_name = false; // Classes do not care about computed | 5053 bool is_computed_name = false; // Classes do not care about computed |
| 5067 // property names here. | 5054 // property names here. |
| 5068 ExpressionClassifier property_classifier(this); | 5055 ExpressionClassifier property_classifier(this); |
| 5069 const AstRawString* property_name = nullptr; | 5056 const AstRawString* property_name = nullptr; |
| 5070 ObjectLiteral::Property* property = ParsePropertyDefinition( | 5057 ObjectLiteral::Property* property = ParsePropertyDefinition( |
| 5071 &checker, in_class, has_extends, MethodKind::Normal, &is_computed_name, | 5058 &checker, in_class, has_extends, MethodKind::Normal, &is_computed_name, |
| 5072 &has_seen_constructor, &property_classifier, &property_name, CHECK_OK); | 5059 &has_seen_constructor, &property_classifier, &property_name, CHECK_OK); |
| 5073 RewriteNonPattern(&property_classifier, CHECK_OK); | 5060 RewriteNonPattern(&property_classifier, CHECK_OK); |
| 5074 if (classifier != nullptr) { | 5061 if (classifier != nullptr) { |
| 5075 classifier->Accumulate(&property_classifier, | 5062 classifier->Accumulate(&property_classifier, |
| 5076 ExpressionClassifier::ExpressionProductions); | 5063 ExpressionClassifier::ExpressionProductions); |
| 5077 } | 5064 } |
| 5078 | 5065 |
| 5079 if (has_seen_constructor && constructor == NULL) { | 5066 if (has_seen_constructor && constructor == nullptr) { |
| 5080 constructor = GetPropertyValue(property)->AsFunctionLiteral(); | 5067 constructor = GetPropertyValue(property)->AsFunctionLiteral(); |
| 5081 DCHECK_NOT_NULL(constructor); | 5068 DCHECK_NOT_NULL(constructor); |
| 5082 constructor->set_raw_name( | 5069 constructor->set_raw_name( |
| 5083 name != nullptr ? name : ast_value_factory()->empty_string()); | 5070 name != nullptr ? name : ast_value_factory()->empty_string()); |
| 5084 } else { | 5071 } else { |
| 5085 properties->Add(property, zone()); | 5072 properties->Add(property, zone()); |
| 5086 } | 5073 } |
| 5087 | 5074 |
| 5088 if (fni_ != NULL) fni_->Infer(); | 5075 if (fni_ != nullptr) fni_->Infer(); |
| 5089 | 5076 |
| 5090 if (property_name != ast_value_factory()->constructor_string()) { | 5077 if (property_name != ast_value_factory()->constructor_string()) { |
| 5091 SetFunctionNameFromPropertyName(property, property_name); | 5078 SetFunctionNameFromPropertyName(property, property_name); |
| 5092 } | 5079 } |
| 5093 } | 5080 } |
| 5094 | 5081 |
| 5095 Expect(Token::RBRACE, CHECK_OK); | 5082 Expect(Token::RBRACE, CHECK_OK); |
| 5096 int end_pos = scanner()->location().end_pos; | 5083 int end_pos = scanner()->location().end_pos; |
| 5097 | 5084 |
| 5098 if (constructor == NULL) { | 5085 if (constructor == nullptr) { |
| 5099 DCHECK_EQ(scope(), block_scope); | |
| 5100 constructor = DefaultConstructor(name, has_extends, pos, end_pos, | 5086 constructor = DefaultConstructor(name, has_extends, pos, end_pos, |
| 5101 block_scope->language_mode()); | 5087 block_state.language_mode()); |
| 5102 } | 5088 } |
| 5103 | 5089 |
| 5104 // Note that we do not finalize this block scope because it is | 5090 // Note that we do not finalize this block scope because it is |
| 5105 // used as a sentinel value indicating an anonymous class. | 5091 // used as a sentinel value indicating an anonymous class. |
| 5106 block_scope->set_end_position(end_pos); | 5092 block_state.set_end_position(end_pos); |
| 5107 | 5093 |
| 5108 if (name != NULL) { | 5094 if (name != nullptr) { |
| 5109 DCHECK_NOT_NULL(proxy); | 5095 DCHECK_NOT_NULL(proxy); |
| 5110 proxy->var()->set_initializer_position(end_pos); | 5096 proxy->var()->set_initializer_position(end_pos); |
| 5111 } | 5097 } |
| 5112 | 5098 |
| 5113 Block* do_block = factory()->NewBlock(nullptr, 1, false, pos); | 5099 Block* do_block = factory()->NewBlock(nullptr, 1, false, pos); |
| 5114 do_block->set_scope(block_scope); | |
| 5115 Variable* result_var = | 5100 Variable* result_var = |
| 5116 block_scope->NewTemporary(ast_value_factory()->empty_string()); | 5101 scope()->NewTemporary(ast_value_factory()->empty_string()); |
| 5102 do_block->set_scope(block_state.FinalizedBlockScope()); |
| 5117 DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos); | 5103 DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos); |
| 5118 | 5104 |
| 5119 ClassLiteral* class_literal = factory()->NewClassLiteral( | 5105 ClassLiteral* class_literal = factory()->NewClassLiteral( |
| 5120 proxy, extends, constructor, properties, pos, end_pos); | 5106 proxy, extends, constructor, properties, pos, end_pos); |
| 5121 | 5107 |
| 5122 do_block->statements()->Add( | 5108 do_block->statements()->Add( |
| 5123 factory()->NewExpressionStatement(class_literal, pos), zone()); | 5109 factory()->NewExpressionStatement(class_literal, pos), zone()); |
| 5124 do_expr->set_represented_function(constructor); | 5110 do_expr->set_represented_function(constructor); |
| 5125 Rewriter::Rewrite(this, scope()->ClosureScope(), do_expr, | 5111 Rewriter::Rewrite(this, scope()->ClosureScope(), do_expr, |
| 5126 ast_value_factory()); | 5112 ast_value_factory()); |
| (...skipping 1975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7102 node->Print(Isolate::Current()); | 7088 node->Print(Isolate::Current()); |
| 7103 } | 7089 } |
| 7104 #endif // DEBUG | 7090 #endif // DEBUG |
| 7105 | 7091 |
| 7106 #undef CHECK_OK | 7092 #undef CHECK_OK |
| 7107 #undef CHECK_OK_VOID | 7093 #undef CHECK_OK_VOID |
| 7108 #undef CHECK_FAILED | 7094 #undef CHECK_FAILED |
| 7109 | 7095 |
| 7110 } // namespace internal | 7096 } // namespace internal |
| 7111 } // namespace v8 | 7097 } // namespace v8 |
| OLD | NEW |