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

Side by Side Diff: src/parsing/parser.cc

Issue 2119353002: [parser] Fix bug in for-of desugaring. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: gsave Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/parser.h ('k') | test/cctest/interpreter/bytecode_expectations/ForOf.golden » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | test/cctest/interpreter/bytecode_expectations/ForOf.golden » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698