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 "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/ast-expression-rewriter.h" | 9 #include "src/ast/ast-expression-rewriter.h" |
10 #include "src/ast/ast-expression-visitor.h" | 10 #include "src/ast/ast-expression-visitor.h" |
(...skipping 3165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3176 throw_arguments->Add(result_proxy_again, zone()); | 3176 throw_arguments->Add(result_proxy_again, zone()); |
3177 Expression* throw_call = factory()->NewCallRuntime( | 3177 Expression* throw_call = factory()->NewCallRuntime( |
3178 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos); | 3178 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos); |
3179 | 3179 |
3180 return factory()->NewBinaryOperation( | 3180 return factory()->NewBinaryOperation( |
3181 Token::AND, | 3181 Token::AND, |
3182 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos), | 3182 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos), |
3183 throw_call, pos); | 3183 throw_call, pos); |
3184 } | 3184 } |
3185 | 3185 |
3186 void Parser::InitializeForEachStatement(ForEachStatement* stmt, | 3186 Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt, |
3187 Expression* each, Expression* subject, | 3187 Expression* each, |
3188 Statement* body, int each_keyword_pos) { | 3188 Expression* subject, |
3189 Statement* body, | |
3190 int each_keyword_pos) { | |
3189 ForOfStatement* for_of = stmt->AsForOfStatement(); | 3191 ForOfStatement* for_of = stmt->AsForOfStatement(); |
3190 if (for_of != NULL) { | 3192 if (for_of != NULL) { |
3191 InitializeForOfStatement(for_of, each, subject, body, each_keyword_pos); | 3193 const bool finalize = true; |
3194 return InitializeForOfStatement(for_of, each, subject, body, finalize, | |
3195 each_keyword_pos); | |
3192 } else { | 3196 } else { |
3193 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { | 3197 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { |
3194 Variable* temp = | 3198 Variable* temp = |
3195 scope_->NewTemporary(ast_value_factory()->empty_string()); | 3199 scope_->NewTemporary(ast_value_factory()->empty_string()); |
3196 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 3200 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
3197 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment( | 3201 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment( |
3198 this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy, | 3202 this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy, |
3199 kNoSourcePosition), | 3203 kNoSourcePosition), |
3200 scope_); | 3204 scope_); |
3201 auto block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition); | 3205 auto block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition); |
3202 block->statements()->Add( | 3206 block->statements()->Add( |
3203 factory()->NewExpressionStatement(assign_each, kNoSourcePosition), | 3207 factory()->NewExpressionStatement(assign_each, kNoSourcePosition), |
3204 zone()); | 3208 zone()); |
3205 block->statements()->Add(body, zone()); | 3209 block->statements()->Add(body, zone()); |
3206 body = block; | 3210 body = block; |
3207 each = factory()->NewVariableProxy(temp); | 3211 each = factory()->NewVariableProxy(temp); |
3208 } | 3212 } |
3209 stmt->AsForInStatement()->Initialize(each, subject, body); | 3213 stmt->AsForInStatement()->Initialize(each, subject, body); |
3210 } | 3214 } |
3215 return stmt; | |
3211 } | 3216 } |
3212 | 3217 |
3213 void Parser::InitializeForOfStatement(ForOfStatement* for_of, Expression* each, | 3218 Statement* Parser::InitializeForOfStatement(ForOfStatement* for_of, |
3214 Expression* iterable, Statement* body, | 3219 Expression* each, |
3215 int next_result_pos) { | 3220 Expression* iterable, |
3221 Statement* body, bool finalize, | |
3222 int next_result_pos) { | |
3223 // Create the auxiliary expressions needed for iterating over the iterable, | |
3224 // and initialize the given ForOfStatement with them. | |
3225 // If finalize is true, also instrument the loop with code that performs the | |
3226 // proper ES6 iterator finalization. In that case, the result is not | |
3227 // immediately a ForOfStatement. | |
3228 | |
3229 const int nopos = kNoSourcePosition; | |
3230 auto avfactory = ast_value_factory(); | |
3231 | |
3216 Variable* iterator = | 3232 Variable* iterator = |
3217 scope_->NewTemporary(ast_value_factory()->dot_iterator_string()); | 3233 scope_->NewTemporary(ast_value_factory()->dot_iterator_string()); |
3218 Variable* result = | 3234 Variable* result = |
3219 scope_->NewTemporary(ast_value_factory()->dot_result_string()); | 3235 scope_->NewTemporary(ast_value_factory()->dot_result_string()); |
3220 | 3236 Variable* completion = scope_->NewTemporary(avfactory->empty_string()); |
3221 Expression* assign_iterator; | |
3222 Expression* next_result; | |
3223 Expression* result_done; | |
3224 Expression* assign_each; | |
3225 | |
3226 int get_iterator_pos = iterable->position(); | |
3227 | 3237 |
3228 // iterator = iterable[Symbol.iterator]() | 3238 // iterator = iterable[Symbol.iterator]() |
3229 assign_iterator = factory()->NewAssignment( | 3239 Expression* assign_iterator; |
3230 Token::ASSIGN, factory()->NewVariableProxy(iterator), | 3240 { |
3231 GetIterator(iterable, factory(), get_iterator_pos), iterable->position()); | 3241 assign_iterator = factory()->NewAssignment( |
3242 Token::ASSIGN, factory()->NewVariableProxy(iterator), | |
3243 GetIterator(iterable, factory(), iterable->position()), | |
3244 iterable->position()); | |
3245 } | |
3232 | 3246 |
3233 // !%_IsJSReceiver(result = iterator.next()) && | 3247 // !%_IsJSReceiver(result = iterator.next()) && |
3234 // %ThrowIteratorResultNotAnObject(result) | 3248 // %ThrowIteratorResultNotAnObject(result) |
3249 Expression* next_result; | |
3235 { | 3250 { |
3236 // result = iterator.next() | |
3237 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 3251 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
3238 next_result = | 3252 next_result = |
3239 BuildIteratorNextResult(iterator_proxy, result, next_result_pos); | 3253 BuildIteratorNextResult(iterator_proxy, result, next_result_pos); |
3240 } | 3254 } |
3241 | 3255 |
3242 // result.done | 3256 // result.done |
3257 Expression* result_done; | |
3243 { | 3258 { |
3244 Expression* done_literal = factory()->NewStringLiteral( | 3259 Expression* done_literal = factory()->NewStringLiteral( |
3245 ast_value_factory()->done_string(), kNoSourcePosition); | 3260 ast_value_factory()->done_string(), kNoSourcePosition); |
3246 Expression* result_proxy = factory()->NewVariableProxy(result); | 3261 Expression* result_proxy = factory()->NewVariableProxy(result); |
3247 result_done = | 3262 result_done = |
3248 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition); | 3263 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition); |
3249 } | 3264 } |
3250 | 3265 |
3251 // each = result.value | 3266 // result.value |
3267 Expression* result_value; | |
3252 { | 3268 { |
3253 Expression* value_literal = factory()->NewStringLiteral( | 3269 Expression* value_literal = |
3254 ast_value_factory()->value_string(), kNoSourcePosition); | 3270 factory()->NewStringLiteral(avfactory->value_string(), nopos); |
3255 Expression* result_proxy = factory()->NewVariableProxy(result); | 3271 Expression* result_proxy = factory()->NewVariableProxy(result); |
3256 Expression* result_value = | 3272 result_value = factory()->NewProperty(result_proxy, value_literal, nopos); |
3257 factory()->NewProperty(result_proxy, value_literal, kNoSourcePosition); | 3273 } |
3258 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value, | 3274 |
3259 kNoSourcePosition); | 3275 // {{completion = kAbruptCompletion;}} |
3276 Statement* set_completion_abrupt; | |
3277 if (finalize) { | |
3278 Expression* proxy = factory()->NewVariableProxy(completion); | |
3279 Expression* assignment = factory()->NewAssignment( | |
3280 Token::ASSIGN, proxy, | |
3281 factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos); | |
3282 | |
3283 Block* block = factory()->NewBlock(nullptr, 1, true, nopos); | |
3284 block->statements()->Add( | |
3285 factory()->NewExpressionStatement(assignment, nopos), zone()); | |
3286 set_completion_abrupt = block; | |
3287 } | |
3288 | |
3289 // do { let tmp = #result_value; #set_completion_abrupt; tmp } | |
3290 // Expression* result_value (gets overwritten) | |
3291 if (finalize) { | |
3292 Variable* var_tmp = scope_->NewTemporary(avfactory->empty_string()); | |
3293 Expression* tmp = factory()->NewVariableProxy(var_tmp); | |
3294 Expression* assignment = | |
3295 factory()->NewAssignment(Token::ASSIGN, tmp, result_value, nopos); | |
3296 | |
3297 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); | |
3298 block->statements()->Add( | |
3299 factory()->NewExpressionStatement(assignment, nopos), zone()); | |
3300 block->statements()->Add(set_completion_abrupt, zone()); | |
3301 | |
3302 result_value = factory()->NewDoExpression(block, var_tmp, nopos); | |
3303 } | |
3304 | |
3305 // each = #result_value; | |
3306 Expression* assign_each; | |
3307 { | |
3308 assign_each = | |
3309 factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos); | |
3260 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { | 3310 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { |
3261 assign_each = PatternRewriter::RewriteDestructuringAssignment( | 3311 assign_each = PatternRewriter::RewriteDestructuringAssignment( |
3262 this, assign_each->AsAssignment(), scope_); | 3312 this, assign_each->AsAssignment(), scope_); |
3263 } | 3313 } |
3264 } | 3314 } |
3265 | 3315 |
3316 // {{completion = kNormalCompletion;}} | |
3317 Statement* set_completion_normal; | |
3318 if (finalize) { | |
3319 Expression* proxy = factory()->NewVariableProxy(completion); | |
3320 Expression* assignment = factory()->NewAssignment( | |
3321 Token::ASSIGN, proxy, | |
3322 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); | |
3323 | |
3324 Block* block = factory()->NewBlock(nullptr, 1, true, nopos); | |
3325 block->statements()->Add( | |
3326 factory()->NewExpressionStatement(assignment, nopos), zone()); | |
3327 set_completion_normal = block; | |
3328 } | |
3329 | |
3330 // { #loop-body; #set_completion_normal } | |
3331 // Statement* body (gets overwritten) | |
3332 if (finalize) { | |
3333 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); | |
3334 block->statements()->Add(body, zone()); | |
3335 block->statements()->Add(set_completion_normal, zone()); | |
3336 body = block; | |
3337 } | |
3338 | |
3266 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, | 3339 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, |
3267 assign_each); | 3340 assign_each); |
3341 return finalize | |
3342 ? ParserTraits::FinalizeForOfStatement(for_of, completion, nopos) | |
3343 : for_of; | |
3268 } | 3344 } |
3269 | 3345 |
3270 Statement* Parser::DesugarLexicalBindingsInForStatement( | 3346 Statement* Parser::DesugarLexicalBindingsInForStatement( |
3271 Scope* inner_scope, VariableMode mode, ZoneList<const AstRawString*>* names, | 3347 Scope* inner_scope, VariableMode mode, ZoneList<const AstRawString*>* names, |
3272 ForStatement* loop, Statement* init, Expression* cond, Statement* next, | 3348 ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
3273 Statement* body, bool* ok) { | 3349 Statement* body, bool* ok) { |
3274 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are | 3350 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are |
3275 // copied into a new environment. Moreover, the "next" statement must be | 3351 // copied into a new environment. Moreover, the "next" statement must be |
3276 // evaluated not in the environment of the just completed iteration but in | 3352 // evaluated not in the environment of the just completed iteration but in |
3277 // that of the upcoming one. We achieve this with the following desugaring. | 3353 // that of the upcoming one. We achieve this with the following desugaring. |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3642 } | 3718 } |
3643 | 3719 |
3644 Expect(Token::RPAREN, CHECK_OK); | 3720 Expect(Token::RPAREN, CHECK_OK); |
3645 | 3721 |
3646 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE); | 3722 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE); |
3647 body_scope->set_start_position(scanner()->location().beg_pos); | 3723 body_scope->set_start_position(scanner()->location().beg_pos); |
3648 | 3724 |
3649 Block* body_block = | 3725 Block* body_block = |
3650 factory()->NewBlock(NULL, 3, false, kNoSourcePosition); | 3726 factory()->NewBlock(NULL, 3, false, kNoSourcePosition); |
3651 | 3727 |
3728 Statement* final_loop; | |
3652 { | 3729 { |
3653 ReturnExprScope no_tail_calls(function_state_, | 3730 ReturnExprScope no_tail_calls(function_state_, |
3654 ReturnExprContext::kInsideForInOfBody); | 3731 ReturnExprContext::kInsideForInOfBody); |
3655 BlockState block_state(&scope_, body_scope); | 3732 BlockState block_state(&scope_, body_scope); |
3656 | 3733 |
3657 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); | 3734 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); |
3658 | 3735 |
3659 auto each_initialization_block = | 3736 auto each_initialization_block = |
3660 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); | 3737 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); |
3661 { | 3738 { |
3662 auto descriptor = parsing_result.descriptor; | 3739 auto descriptor = parsing_result.descriptor; |
3663 descriptor.declaration_pos = kNoSourcePosition; | 3740 descriptor.declaration_pos = kNoSourcePosition; |
3664 descriptor.initialization_pos = kNoSourcePosition; | 3741 descriptor.initialization_pos = kNoSourcePosition; |
3665 decl.initializer = factory()->NewVariableProxy(temp); | 3742 decl.initializer = factory()->NewVariableProxy(temp); |
3666 | 3743 |
3667 PatternRewriter::DeclareAndInitializeVariables( | 3744 PatternRewriter::DeclareAndInitializeVariables( |
3668 each_initialization_block, &descriptor, &decl, | 3745 each_initialization_block, &descriptor, &decl, |
3669 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings | 3746 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings |
3670 : nullptr, | 3747 : nullptr, |
3671 CHECK_OK); | 3748 CHECK_OK); |
3672 } | 3749 } |
3673 | 3750 |
3674 body_block->statements()->Add(each_initialization_block, zone()); | 3751 body_block->statements()->Add(each_initialization_block, zone()); |
3675 body_block->statements()->Add(body, zone()); | 3752 body_block->statements()->Add(body, zone()); |
3676 VariableProxy* temp_proxy = | 3753 VariableProxy* temp_proxy = |
3677 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); | 3754 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); |
3678 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block, | 3755 final_loop = InitializeForEachStatement( |
3679 each_keyword_position); | 3756 loop, temp_proxy, enumerable, body_block, each_keyword_position); |
3680 } | 3757 } |
3681 body_scope->set_end_position(scanner()->location().end_pos); | 3758 body_scope->set_end_position(scanner()->location().end_pos); |
3682 body_scope = body_scope->FinalizeBlockScope(); | 3759 body_scope = body_scope->FinalizeBlockScope(); |
3683 body_block->set_scope(body_scope); | 3760 body_block->set_scope(body_scope); |
3684 | 3761 |
3685 // Create a TDZ for any lexically-bound names. | 3762 // Create a TDZ for any lexically-bound names. |
3686 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) { | 3763 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) { |
3687 DCHECK_NULL(init_block); | 3764 DCHECK_NULL(init_block); |
3688 | 3765 |
3689 init_block = | 3766 init_block = |
3690 factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); | 3767 factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); |
3691 | 3768 |
3692 for (int i = 0; i < lexical_bindings.length(); ++i) { | 3769 for (int i = 0; i < lexical_bindings.length(); ++i) { |
3693 // TODO(adamk): This needs to be some sort of special | 3770 // TODO(adamk): This needs to be some sort of special |
3694 // INTERNAL variable that's invisible to the debugger | 3771 // INTERNAL variable that's invisible to the debugger |
3695 // but visible to everything else. | 3772 // but visible to everything else. |
3696 VariableProxy* tdz_proxy = | 3773 VariableProxy* tdz_proxy = |
3697 NewUnresolved(lexical_bindings[i], LET); | 3774 NewUnresolved(lexical_bindings[i], LET); |
3698 Declaration* tdz_decl = factory()->NewVariableDeclaration( | 3775 Declaration* tdz_decl = factory()->NewVariableDeclaration( |
3699 tdz_proxy, LET, scope_, kNoSourcePosition); | 3776 tdz_proxy, LET, scope_, kNoSourcePosition); |
3700 Variable* tdz_var = Declare( | 3777 Variable* tdz_var = Declare( |
3701 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 3778 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
3702 tdz_var->set_initializer_position(position()); | 3779 tdz_var->set_initializer_position(position()); |
3703 } | 3780 } |
3704 } | 3781 } |
3705 | 3782 |
3706 Statement* final_loop = | |
3707 loop->IsForOfStatement() | |
3708 ? FinalizeForOfStatement(loop->AsForOfStatement(), | |
3709 kNoSourcePosition) | |
3710 : loop; | |
3711 | |
3712 for_scope->set_end_position(scanner()->location().end_pos); | 3783 for_scope->set_end_position(scanner()->location().end_pos); |
3713 for_scope = for_scope->FinalizeBlockScope(); | 3784 for_scope = for_scope->FinalizeBlockScope(); |
3714 // Parsed for-in loop w/ variable declarations. | 3785 // Parsed for-in loop w/ variable declarations. |
3715 if (init_block != nullptr) { | 3786 if (init_block != nullptr) { |
3716 init_block->statements()->Add(final_loop, zone()); | 3787 init_block->statements()->Add(final_loop, zone()); |
3717 init_block->set_scope(for_scope); | 3788 init_block->set_scope(for_scope); |
3718 return init_block; | 3789 return init_block; |
3719 } else { | 3790 } else { |
3720 DCHECK_NULL(for_scope); | 3791 DCHECK_NULL(for_scope); |
3721 return final_loop; | 3792 return final_loop; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3765 RewriteNonPattern(&classifier, CHECK_OK); | 3836 RewriteNonPattern(&classifier, CHECK_OK); |
3766 } else { | 3837 } else { |
3767 enumerable = ParseExpression(true, CHECK_OK); | 3838 enumerable = ParseExpression(true, CHECK_OK); |
3768 } | 3839 } |
3769 | 3840 |
3770 Expect(Token::RPAREN, CHECK_OK); | 3841 Expect(Token::RPAREN, CHECK_OK); |
3771 | 3842 |
3772 // For legacy compat reasons, give for loops similar treatment to | 3843 // For legacy compat reasons, give for loops similar treatment to |
3773 // if statements in allowing a function declaration for a body | 3844 // if statements in allowing a function declaration for a body |
3774 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); | 3845 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); |
3775 InitializeForEachStatement(loop, expression, enumerable, body, | 3846 Statement* final_loop = InitializeForEachStatement( |
3776 each_keyword_position); | 3847 loop, expression, enumerable, body, each_keyword_position); |
3777 | |
3778 Statement* final_loop = | |
3779 loop->IsForOfStatement() | |
3780 ? FinalizeForOfStatement(loop->AsForOfStatement(), | |
3781 kNoSourcePosition) | |
3782 : loop; | |
3783 | 3848 |
3784 for_scope->set_end_position(scanner()->location().end_pos); | 3849 for_scope->set_end_position(scanner()->location().end_pos); |
3785 for_scope = for_scope->FinalizeBlockScope(); | 3850 for_scope = for_scope->FinalizeBlockScope(); |
3786 DCHECK(for_scope == nullptr); | 3851 DCHECK(for_scope == nullptr); |
3787 return final_loop; | 3852 return final_loop; |
3788 | 3853 |
3789 } else { | 3854 } else { |
3790 init = factory()->NewExpressionStatement(expression, lhs_beg_pos); | 3855 init = factory()->NewExpressionStatement(expression, lhs_beg_pos); |
3791 } | 3856 } |
3792 } | 3857 } |
(...skipping 2073 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5866 append_element_args->Add(factory()->NewVariableProxy(result), zone()); | 5931 append_element_args->Add(factory()->NewVariableProxy(result), zone()); |
5867 append_element_args->Add(factory()->NewVariableProxy(each), zone()); | 5932 append_element_args->Add(factory()->NewVariableProxy(each), zone()); |
5868 append_body = factory()->NewExpressionStatement( | 5933 append_body = factory()->NewExpressionStatement( |
5869 factory()->NewCallRuntime(Runtime::kAppendElement, | 5934 factory()->NewCallRuntime(Runtime::kAppendElement, |
5870 append_element_args, kNoSourcePosition), | 5935 append_element_args, kNoSourcePosition), |
5871 kNoSourcePosition); | 5936 kNoSourcePosition); |
5872 } | 5937 } |
5873 // for (each of spread) %AppendElement($R, each) | 5938 // for (each of spread) %AppendElement($R, each) |
5874 ForEachStatement* loop = factory()->NewForEachStatement( | 5939 ForEachStatement* loop = factory()->NewForEachStatement( |
5875 ForEachStatement::ITERATE, nullptr, kNoSourcePosition); | 5940 ForEachStatement::ITERATE, nullptr, kNoSourcePosition); |
5941 const bool finalize = false; | |
Dan Ehrenberg
2016/07/07 00:21:06
I see how in the spec, finalization is not done fo
| |
5876 InitializeForOfStatement(loop->AsForOfStatement(), | 5942 InitializeForOfStatement(loop->AsForOfStatement(), |
5877 factory()->NewVariableProxy(each), subject, | 5943 factory()->NewVariableProxy(each), subject, |
5878 append_body); | 5944 append_body, finalize); |
5879 do_block->statements()->Add(loop, zone()); | 5945 do_block->statements()->Add(loop, zone()); |
5880 } | 5946 } |
5881 } | 5947 } |
5882 // Now, rewind the original array literal to truncate everything from the | 5948 // Now, rewind the original array literal to truncate everything from the |
5883 // first spread (included) until the end. This fixes $R's initialization. | 5949 // first spread (included) until the end. This fixes $R's initialization. |
5884 lit->RewindSpreads(); | 5950 lit->RewindSpreads(); |
5885 return factory()->NewDoExpression(do_block, result, lit->position()); | 5951 return factory()->NewDoExpression(do_block, result, lit->position()); |
5886 } | 5952 } |
5887 | 5953 |
5888 | 5954 |
(...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6860 maybe_call_return = | 6926 maybe_call_return = |
6861 factory->NewIfStatement(condition, factory->NewEmptyStatement(nopos), | 6927 factory->NewIfStatement(condition, factory->NewEmptyStatement(nopos), |
6862 call_return_carefully, nopos); | 6928 call_return_carefully, nopos); |
6863 } | 6929 } |
6864 | 6930 |
6865 | 6931 |
6866 statements->Add(get_return, zone); | 6932 statements->Add(get_return, zone); |
6867 statements->Add(maybe_call_return, zone); | 6933 statements->Add(maybe_call_return, zone); |
6868 } | 6934 } |
6869 | 6935 |
6870 | 6936 Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, |
6871 Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) { | 6937 Variable* var_completion, |
6938 int pos) { | |
6872 // | 6939 // |
6873 // This function replaces the loop with the following wrapping: | 6940 // This function replaces the loop with the following wrapping: |
6874 // | 6941 // |
6875 // let each; | 6942 // completion = kNormalCompletion; |
6876 // let completion = kNormalCompletion; | |
6877 // try { | 6943 // try { |
6878 // try { | 6944 // try { |
6879 // #loop; | 6945 // #loop; |
6880 // } catch(e) { | 6946 // } catch(e) { |
6881 // if (completion === kAbruptCompletion) completion = kThrowCompletion; | 6947 // if (completion === kAbruptCompletion) completion = kThrowCompletion; |
6882 // %ReThrow(e); | 6948 // %ReThrow(e); |
6883 // } | 6949 // } |
6884 // } finally { | 6950 // } finally { |
6885 // if (!(completion === kNormalCompletion || IS_UNDEFINED(#iterator))) { | 6951 // if (!(completion === kNormalCompletion || IS_UNDEFINED(#iterator))) { |
6886 // #BuildIteratorCloseForCompletion(#iterator, completion) | 6952 // #BuildIteratorCloseForCompletion(#iterator, completion) |
6887 // } | 6953 // } |
6888 // } | 6954 // } |
6889 // | 6955 // |
6890 // where the loop's body is wrapped as follows: | 6956 // Note that the loop's body and its assign_each already contain appropriate |
6891 // | 6957 // assignments to completion (see InitializeForOfStatement). |
6892 // { | |
6893 // #loop-body | |
6894 // {{completion = kNormalCompletion;}} | |
6895 // } | |
6896 // | |
6897 // and the loop's assign_each is wrapped as follows | |
6898 // | |
6899 // do { | |
6900 // {{completion = kAbruptCompletion;}} | |
6901 // #assign-each | |
6902 // } | |
6903 // | 6958 // |
6904 | 6959 |
6905 const int nopos = kNoSourcePosition; | 6960 const int nopos = kNoSourcePosition; |
6906 auto factory = parser_->factory(); | 6961 auto factory = parser_->factory(); |
6907 auto avfactory = parser_->ast_value_factory(); | |
6908 auto scope = parser_->scope_; | |
6909 auto zone = parser_->zone(); | 6962 auto zone = parser_->zone(); |
6910 | 6963 |
6911 Variable* var_completion = scope->NewTemporary(avfactory->empty_string()); | |
6912 | |
6913 // let each; | |
6914 Variable* var_each = scope->NewTemporary(avfactory->empty_string()); | |
6915 Statement* initialize_each; | |
6916 { | |
6917 Expression* proxy = factory->NewVariableProxy(var_each); | |
6918 Expression* assignment = factory->NewAssignment( | |
6919 Token::ASSIGN, proxy, | |
6920 factory->NewUndefinedLiteral(nopos), nopos); | |
6921 initialize_each = | |
6922 factory->NewExpressionStatement(assignment, nopos); | |
6923 } | |
6924 | |
6925 // !(completion === kNormalCompletion || IS_UNDEFINED(#iterator)) | 6964 // !(completion === kNormalCompletion || IS_UNDEFINED(#iterator)) |
6926 Expression* closing_condition; | 6965 Expression* closing_condition; |
6927 { | 6966 { |
6928 Expression* lhs = factory->NewCompareOperation( | 6967 Expression* lhs = factory->NewCompareOperation( |
6929 Token::EQ_STRICT, factory->NewVariableProxy(var_completion), | 6968 Token::EQ_STRICT, factory->NewVariableProxy(var_completion), |
6930 factory->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); | 6969 factory->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); |
6931 Expression* rhs = factory->NewCompareOperation( | 6970 Expression* rhs = factory->NewCompareOperation( |
6932 Token::EQ_STRICT, factory->NewVariableProxy(loop->iterator()), | 6971 Token::EQ_STRICT, factory->NewVariableProxy(loop->iterator()), |
6933 factory->NewUndefinedLiteral(nopos), nopos); | 6972 factory->NewUndefinedLiteral(nopos), nopos); |
6934 closing_condition = factory->NewUnaryOperation( | 6973 closing_condition = factory->NewUnaryOperation( |
6935 Token::NOT, factory->NewBinaryOperation(Token::OR, lhs, rhs, nopos), | 6974 Token::NOT, factory->NewBinaryOperation(Token::OR, lhs, rhs, nopos), |
6936 nopos); | 6975 nopos); |
6937 } | 6976 } |
6938 | 6977 |
6939 // {{completion = kNormalCompletion;}} | 6978 Block* final_loop = factory->NewBlock(nullptr, 2, false, nopos); |
6940 Statement* set_completion_normal; | |
6941 { | 6979 { |
6942 Expression* proxy = factory->NewVariableProxy(var_completion); | |
6943 Expression* assignment = factory->NewAssignment( | |
6944 Token::ASSIGN, proxy, | |
6945 factory->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); | |
6946 | |
6947 Block* block = factory->NewBlock(nullptr, 1, true, nopos); | |
6948 block->statements()->Add( | |
6949 factory->NewExpressionStatement(assignment, nopos), zone); | |
6950 set_completion_normal = block; | |
6951 } | |
6952 | |
6953 // {{completion = kAbruptCompletion;}} | |
6954 Statement* set_completion_abrupt; | |
6955 { | |
6956 Expression* proxy = factory->NewVariableProxy(var_completion); | |
6957 Expression* assignment = factory->NewAssignment( | |
6958 Token::ASSIGN, proxy, | |
6959 factory->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos); | |
6960 | |
6961 Block* block = factory->NewBlock(nullptr, 1, true, nopos); | |
6962 block->statements()->Add(factory->NewExpressionStatement(assignment, nopos), | |
6963 zone); | |
6964 set_completion_abrupt = block; | |
6965 } | |
6966 | |
6967 // { #loop-body; #set_completion_normal } | |
6968 Block* new_body = factory->NewBlock(nullptr, 2, false, nopos); | |
6969 { | |
6970 new_body->statements()->Add(loop->body(), zone); | |
6971 new_body->statements()->Add(set_completion_normal, zone); | |
6972 } | |
6973 | |
6974 // { #set_completion_abrupt; #assign-each } | |
6975 Block* new_assign_each = factory->NewBlock(nullptr, 2, false, nopos); | |
6976 { | |
6977 new_assign_each->statements()->Add(set_completion_abrupt, zone); | |
6978 new_assign_each->statements()->Add( | |
6979 factory->NewExpressionStatement(loop->assign_each(), nopos), zone); | |
6980 } | |
6981 | |
6982 // Now put things together. | |
6983 | |
6984 loop->set_body(new_body); | |
6985 loop->set_assign_each( | |
6986 factory->NewDoExpression(new_assign_each, var_each, nopos)); | |
6987 | |
6988 Statement* final_loop; | |
6989 { | |
6990 Block* target = factory->NewBlock(nullptr, 3, false, nopos); | |
6991 target->statements()->Add(initialize_each, zone); | |
6992 | |
6993 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); | 6980 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); |
6994 try_block->statements()->Add(loop, zone); | 6981 try_block->statements()->Add(loop, zone); |
6995 | 6982 |
6996 FinalizeIteratorUse(var_completion, closing_condition, loop->iterator(), | 6983 FinalizeIteratorUse(var_completion, closing_condition, loop->iterator(), |
6997 try_block, target); | 6984 try_block, final_loop); |
6998 final_loop = target; | |
6999 } | 6985 } |
7000 | 6986 |
7001 return final_loop; | 6987 return final_loop; |
7002 } | 6988 } |
7003 | 6989 |
7004 | 6990 |
7005 } // namespace internal | 6991 } // namespace internal |
7006 } // namespace v8 | 6992 } // namespace v8 |
OLD | NEW |