Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/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 |