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

Side by Side Diff: src/parser.cc

Issue 1177053006: [es6] Fix completion values of for loops with lexical variables (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 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
« src/ast.h ('K') | « src/ast.h ('k') | src/prettyprinter.cc » ('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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast.h" 8 #include "src/ast.h"
9 #include "src/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
(...skipping 3204 matching lines...) Expand 10 before | Expand all | Expand 10 after
3215 // We rewrite a for statement of the form 3215 // We rewrite a for statement of the form
3216 // 3216 //
3217 // labels: for (let/const x = i; cond; next) body 3217 // labels: for (let/const x = i; cond; next) body
3218 // 3218 //
3219 // into 3219 // into
3220 // 3220 //
3221 // { 3221 // {
3222 // let/const x = i; 3222 // let/const x = i;
3223 // temp_x = x; 3223 // temp_x = x;
3224 // first = 1; 3224 // first = 1;
3225 // undefined;
3225 // outer: for (;;) { 3226 // outer: for (;;) {
3227 // { // Nothing inside this block can affect the normal completion value.
rossberg 2015/06/18 05:43:21 Nit: adjust indentation. Also, the comment seems a
conradw 2015/06/18 10:53:32 rewritten
3228 // // No new lexical scope is introduced.
3226 // let/const x = temp_x; 3229 // let/const x = temp_x;
3227 // if (first == 1) { 3230 // if (first == 1) {
3228 // first = 0; 3231 // first = 0;
3229 // } else { 3232 // } else {
3230 // next; 3233 // next;
3231 // } 3234 // }
3232 // flag = 1; 3235 // flag = 1;
3236 // }
3233 // labels: for (; flag == 1; flag = 0, temp_x = x) { 3237 // labels: for (; flag == 1; flag = 0, temp_x = x) {
3234 // if (cond) { 3238 // if (cond) {
3235 // body 3239 // body
3236 // } else { 3240 // } else {
3237 // break outer; 3241 // break outer;
3238 // } 3242 // }
3239 // } 3243 // }
3240 // if (flag == 1) { 3244 // if (flag == 1) {
3241 // break; 3245 // break;
3242 // } 3246 // }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3275 first = scope_->DeclarationScope()->NewTemporary(temp_name); 3279 first = scope_->DeclarationScope()->NewTemporary(temp_name);
3276 VariableProxy* first_proxy = factory()->NewVariableProxy(first); 3280 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3277 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3281 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3278 Assignment* assignment = factory()->NewAssignment( 3282 Assignment* assignment = factory()->NewAssignment(
3279 Token::ASSIGN, first_proxy, const1, RelocInfo::kNoPosition); 3283 Token::ASSIGN, first_proxy, const1, RelocInfo::kNoPosition);
3280 Statement* assignment_statement = 3284 Statement* assignment_statement =
3281 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); 3285 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3282 outer_block->AddStatement(assignment_statement, zone()); 3286 outer_block->AddStatement(assignment_statement, zone());
3283 } 3287 }
3284 3288
3289 // make statement: undefined;
3290 outer_block->AddStatement(
3291 factory()->NewExpressionStatement(
3292 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
3293 RelocInfo::kNoPosition),
3294 zone());
3295
3285 // Make statement: outer: for (;;) 3296 // Make statement: outer: for (;;)
3286 // Note that we don't actually create the label, or set this loop up as an 3297 // Note that we don't actually create the label, or set this loop up as an
3287 // explicit break target, instead handing it directly to those nodes that 3298 // explicit break target, instead handing it directly to those nodes that
3288 // need to know about it. This should be safe because we don't run any code 3299 // need to know about it. This should be safe because we don't run any code
3289 // in this function that looks up break targets. 3300 // in this function that looks up break targets.
3290 ForStatement* outer_loop = 3301 ForStatement* outer_loop =
3291 factory()->NewForStatement(NULL, RelocInfo::kNoPosition); 3302 factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
3292 outer_block->AddStatement(outer_loop, zone()); 3303 outer_block->AddStatement(outer_loop, zone());
3293 3304
3294 outer_block->set_scope(for_scope); 3305 outer_block->set_scope(for_scope);
3295 scope_ = inner_scope; 3306 scope_ = inner_scope;
3296 3307
3297 Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false, 3308 Block* inner_block =
3298 RelocInfo::kNoPosition); 3309 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3310 Block* ignore_completion_block = factory()->NewBlock(
3311 NULL, names->length() + 2, true, RelocInfo::kNoPosition);
3299 ZoneList<Variable*> inner_vars(names->length(), zone()); 3312 ZoneList<Variable*> inner_vars(names->length(), zone());
3300 // For each let variable x: 3313 // For each let variable x:
3301 // make statement: let/const x = temp_x. 3314 // make statement: let/const x = temp_x.
3302 VariableMode mode = is_const ? CONST : LET; 3315 VariableMode mode = is_const ? CONST : LET;
3303 for (int i = 0; i < names->length(); i++) { 3316 for (int i = 0; i < names->length(); i++) {
3304 VariableProxy* proxy = NewUnresolved(names->at(i), mode); 3317 VariableProxy* proxy = NewUnresolved(names->at(i), mode);
3305 Declaration* declaration = factory()->NewVariableDeclaration( 3318 Declaration* declaration = factory()->NewVariableDeclaration(
3306 proxy, mode, scope_, RelocInfo::kNoPosition); 3319 proxy, mode, scope_, RelocInfo::kNoPosition);
3307 Declare(declaration, true, CHECK_OK); 3320 Declare(declaration, true, CHECK_OK);
3308 inner_vars.Add(declaration->proxy()->var(), zone()); 3321 inner_vars.Add(declaration->proxy()->var(), zone());
3309 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); 3322 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3310 Assignment* assignment = 3323 Assignment* assignment =
3311 factory()->NewAssignment(is_const ? Token::INIT_CONST : Token::INIT_LET, 3324 factory()->NewAssignment(is_const ? Token::INIT_CONST : Token::INIT_LET,
3312 proxy, temp_proxy, RelocInfo::kNoPosition); 3325 proxy, temp_proxy, RelocInfo::kNoPosition);
3313 Statement* assignment_statement = 3326 Statement* assignment_statement =
3314 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); 3327 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3315 DCHECK(init->position() != RelocInfo::kNoPosition); 3328 DCHECK(init->position() != RelocInfo::kNoPosition);
3316 proxy->var()->set_initializer_position(init->position()); 3329 proxy->var()->set_initializer_position(init->position());
3317 inner_block->AddStatement(assignment_statement, zone()); 3330 ignore_completion_block->AddStatement(assignment_statement, zone());
3318 } 3331 }
3319 3332
3320 // Make statement: if (first == 1) { first = 0; } else { next; } 3333 // Make statement: if (first == 1) { first = 0; } else { next; }
3321 if (next) { 3334 if (next) {
3322 DCHECK(first); 3335 DCHECK(first);
3323 Expression* compare = NULL; 3336 Expression* compare = NULL;
3324 // Make compare expression: first == 1. 3337 // Make compare expression: first == 1.
3325 { 3338 {
3326 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3339 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3327 VariableProxy* first_proxy = factory()->NewVariableProxy(first); 3340 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3328 compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1, 3341 compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
3329 RelocInfo::kNoPosition); 3342 RelocInfo::kNoPosition);
3330 } 3343 }
3331 Statement* clear_first = NULL; 3344 Statement* clear_first = NULL;
3332 // Make statement: first = 0. 3345 // Make statement: first = 0.
3333 { 3346 {
3334 VariableProxy* first_proxy = factory()->NewVariableProxy(first); 3347 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3335 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition); 3348 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3336 Assignment* assignment = factory()->NewAssignment( 3349 Assignment* assignment = factory()->NewAssignment(
3337 Token::ASSIGN, first_proxy, const0, RelocInfo::kNoPosition); 3350 Token::ASSIGN, first_proxy, const0, RelocInfo::kNoPosition);
3338 clear_first = 3351 clear_first =
3339 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); 3352 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3340 } 3353 }
3341 Statement* clear_first_or_next = factory()->NewIfStatement( 3354 Statement* clear_first_or_next = factory()->NewIfStatement(
3342 compare, clear_first, next, RelocInfo::kNoPosition); 3355 compare, clear_first, next, RelocInfo::kNoPosition);
3343 inner_block->AddStatement(clear_first_or_next, zone()); 3356 ignore_completion_block->AddStatement(clear_first_or_next, zone());
3344 } 3357 }
3345 3358
3346 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name); 3359 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name);
3347 // Make statement: flag = 1. 3360 // Make statement: flag = 1.
3348 { 3361 {
3349 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 3362 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3350 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3363 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3351 Assignment* assignment = factory()->NewAssignment( 3364 Assignment* assignment = factory()->NewAssignment(
3352 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition); 3365 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
3353 Statement* assignment_statement = 3366 Statement* assignment_statement =
3354 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); 3367 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3355 inner_block->AddStatement(assignment_statement, zone()); 3368 ignore_completion_block->AddStatement(assignment_statement, zone());
3356 } 3369 }
3357 3370 inner_block->AddStatement(ignore_completion_block, zone());
3358 // Make cond expression for main loop: flag == 1. 3371 // Make cond expression for main loop: flag == 1.
3359 Expression* flag_cond = NULL; 3372 Expression* flag_cond = NULL;
3360 { 3373 {
3361 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3374 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3362 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 3375 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3363 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, 3376 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3364 RelocInfo::kNoPosition); 3377 RelocInfo::kNoPosition);
3365 } 3378 }
3366 3379
3367 // Create chain of expressions "flag = 0, temp_x = x, ..." 3380 // Create chain of expressions "flag = 0, temp_x = x, ..."
(...skipping 27 matching lines...) Expand all
3395 // Make statement: if (cond) { body; } else { break outer; } 3408 // Make statement: if (cond) { body; } else { break outer; }
3396 Statement* body_or_stop = body; 3409 Statement* body_or_stop = body;
3397 if (cond) { 3410 if (cond) {
3398 Statement* stop = 3411 Statement* stop =
3399 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition); 3412 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3400 body_or_stop = 3413 body_or_stop =
3401 factory()->NewIfStatement(cond, body, stop, cond->position()); 3414 factory()->NewIfStatement(cond, body, stop, cond->position());
3402 } 3415 }
3403 3416
3404 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x) 3417 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
3405 // Note that we re-use the original loop node, which retains it labels 3418 // Note that we re-use the original loop node, which retains its labels
3406 // and ensures that any break or continue statements in body point to 3419 // and ensures that any break or continue statements in body point to
3407 // the right place. 3420 // the right place.
3408 loop->Initialize(NULL, flag_cond, compound_next_statement, body_or_stop); 3421 loop->Initialize(NULL, flag_cond, compound_next_statement, body_or_stop);
3409 inner_block->AddStatement(loop, zone()); 3422 inner_block->AddStatement(loop, zone());
3410 3423
3411 // Make statement: if (flag == 1) { break; } 3424 // Make statement: if (flag == 1) { break; }
3412 { 3425 {
3413 Expression* compare = NULL; 3426 Expression* compare = NULL;
3414 // Make compare expresion: flag == 1. 3427 // Make compare expresion: flag == 1.
3415 { 3428 {
(...skipping 2403 matching lines...) Expand 10 before | Expand all | Expand 10 after
5819 Expression* Parser::SpreadCallNew(Expression* function, 5832 Expression* Parser::SpreadCallNew(Expression* function,
5820 ZoneList<v8::internal::Expression*>* args, 5833 ZoneList<v8::internal::Expression*>* args,
5821 int pos) { 5834 int pos) {
5822 args->InsertAt(0, function, zone()); 5835 args->InsertAt(0, function, zone());
5823 5836
5824 return factory()->NewCallRuntime( 5837 return factory()->NewCallRuntime(
5825 ast_value_factory()->reflect_construct_string(), NULL, args, pos); 5838 ast_value_factory()->reflect_construct_string(), NULL, args, pos);
5826 } 5839 }
5827 } // namespace internal 5840 } // namespace internal
5828 } // namespace v8 5841 } // namespace v8
OLDNEW
« src/ast.h ('K') | « src/ast.h ('k') | src/prettyprinter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698