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

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: offline feedback 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
« no previous file with comments | « 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 (;;) {
3226 // let/const x = temp_x; 3227 // { // This block's only function is to ensure that the statements it
3227 // if (first == 1) { 3228 // // contains do not affect the normal completion value. This is
3228 // first = 0; 3229 // // accomplished by setting its ignore_completion_value bit.
3229 // } else { 3230 // // No new lexical scope is introduced, so lexically scoped variables
3230 // next; 3231 // // declared here will be scoped to the outer for loop.
3232 // let/const x = temp_x;
3233 // if (first == 1) {
3234 // first = 0;
3235 // } else {
3236 // next;
3237 // }
3238 // flag = 1;
3231 // } 3239 // }
3232 // flag = 1;
3233 // labels: for (; flag == 1; flag = 0, temp_x = x) { 3240 // labels: for (; flag == 1; flag = 0, temp_x = x) {
3234 // if (cond) { 3241 // if (cond) {
3235 // body 3242 // body
3236 // } else { 3243 // } else {
3237 // break outer; 3244 // break outer;
3238 // } 3245 // }
3239 // } 3246 // }
3240 // if (flag == 1) { 3247 // if (flag == 1) {
3241 // break; 3248 // break;
3242 // } 3249 // }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3275 first = scope_->DeclarationScope()->NewTemporary(temp_name); 3282 first = scope_->DeclarationScope()->NewTemporary(temp_name);
3276 VariableProxy* first_proxy = factory()->NewVariableProxy(first); 3283 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3277 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3284 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3278 Assignment* assignment = factory()->NewAssignment( 3285 Assignment* assignment = factory()->NewAssignment(
3279 Token::ASSIGN, first_proxy, const1, RelocInfo::kNoPosition); 3286 Token::ASSIGN, first_proxy, const1, RelocInfo::kNoPosition);
3280 Statement* assignment_statement = 3287 Statement* assignment_statement =
3281 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); 3288 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3282 outer_block->AddStatement(assignment_statement, zone()); 3289 outer_block->AddStatement(assignment_statement, zone());
3283 } 3290 }
3284 3291
3292 // make statement: undefined;
3293 outer_block->AddStatement(
3294 factory()->NewExpressionStatement(
3295 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
3296 RelocInfo::kNoPosition),
3297 zone());
3298
3285 // Make statement: outer: for (;;) 3299 // Make statement: outer: for (;;)
3286 // Note that we don't actually create the label, or set this loop up as an 3300 // 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 3301 // 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 3302 // 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. 3303 // in this function that looks up break targets.
3290 ForStatement* outer_loop = 3304 ForStatement* outer_loop =
3291 factory()->NewForStatement(NULL, RelocInfo::kNoPosition); 3305 factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
3292 outer_block->AddStatement(outer_loop, zone()); 3306 outer_block->AddStatement(outer_loop, zone());
3293 3307
3294 outer_block->set_scope(for_scope); 3308 outer_block->set_scope(for_scope);
3295 scope_ = inner_scope; 3309 scope_ = inner_scope;
3296 3310
3297 Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false, 3311 Block* inner_block =
3298 RelocInfo::kNoPosition); 3312 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3313 Block* ignore_completion_block = factory()->NewBlock(
3314 NULL, names->length() + 2, true, RelocInfo::kNoPosition);
3299 ZoneList<Variable*> inner_vars(names->length(), zone()); 3315 ZoneList<Variable*> inner_vars(names->length(), zone());
3300 // For each let variable x: 3316 // For each let variable x:
3301 // make statement: let/const x = temp_x. 3317 // make statement: let/const x = temp_x.
3302 VariableMode mode = is_const ? CONST : LET; 3318 VariableMode mode = is_const ? CONST : LET;
3303 for (int i = 0; i < names->length(); i++) { 3319 for (int i = 0; i < names->length(); i++) {
3304 VariableProxy* proxy = NewUnresolved(names->at(i), mode); 3320 VariableProxy* proxy = NewUnresolved(names->at(i), mode);
3305 Declaration* declaration = factory()->NewVariableDeclaration( 3321 Declaration* declaration = factory()->NewVariableDeclaration(
3306 proxy, mode, scope_, RelocInfo::kNoPosition); 3322 proxy, mode, scope_, RelocInfo::kNoPosition);
3307 Declare(declaration, true, CHECK_OK); 3323 Declare(declaration, true, CHECK_OK);
3308 inner_vars.Add(declaration->proxy()->var(), zone()); 3324 inner_vars.Add(declaration->proxy()->var(), zone());
3309 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); 3325 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3310 Assignment* assignment = 3326 Assignment* assignment =
3311 factory()->NewAssignment(is_const ? Token::INIT_CONST : Token::INIT_LET, 3327 factory()->NewAssignment(is_const ? Token::INIT_CONST : Token::INIT_LET,
3312 proxy, temp_proxy, RelocInfo::kNoPosition); 3328 proxy, temp_proxy, RelocInfo::kNoPosition);
3313 Statement* assignment_statement = 3329 Statement* assignment_statement =
3314 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); 3330 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3315 DCHECK(init->position() != RelocInfo::kNoPosition); 3331 DCHECK(init->position() != RelocInfo::kNoPosition);
3316 proxy->var()->set_initializer_position(init->position()); 3332 proxy->var()->set_initializer_position(init->position());
3317 inner_block->AddStatement(assignment_statement, zone()); 3333 ignore_completion_block->AddStatement(assignment_statement, zone());
3318 } 3334 }
3319 3335
3320 // Make statement: if (first == 1) { first = 0; } else { next; } 3336 // Make statement: if (first == 1) { first = 0; } else { next; }
3321 if (next) { 3337 if (next) {
3322 DCHECK(first); 3338 DCHECK(first);
3323 Expression* compare = NULL; 3339 Expression* compare = NULL;
3324 // Make compare expression: first == 1. 3340 // Make compare expression: first == 1.
3325 { 3341 {
3326 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3342 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3327 VariableProxy* first_proxy = factory()->NewVariableProxy(first); 3343 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3328 compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1, 3344 compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
3329 RelocInfo::kNoPosition); 3345 RelocInfo::kNoPosition);
3330 } 3346 }
3331 Statement* clear_first = NULL; 3347 Statement* clear_first = NULL;
3332 // Make statement: first = 0. 3348 // Make statement: first = 0.
3333 { 3349 {
3334 VariableProxy* first_proxy = factory()->NewVariableProxy(first); 3350 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3335 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition); 3351 Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
3336 Assignment* assignment = factory()->NewAssignment( 3352 Assignment* assignment = factory()->NewAssignment(
3337 Token::ASSIGN, first_proxy, const0, RelocInfo::kNoPosition); 3353 Token::ASSIGN, first_proxy, const0, RelocInfo::kNoPosition);
3338 clear_first = 3354 clear_first =
3339 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); 3355 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3340 } 3356 }
3341 Statement* clear_first_or_next = factory()->NewIfStatement( 3357 Statement* clear_first_or_next = factory()->NewIfStatement(
3342 compare, clear_first, next, RelocInfo::kNoPosition); 3358 compare, clear_first, next, RelocInfo::kNoPosition);
3343 inner_block->AddStatement(clear_first_or_next, zone()); 3359 ignore_completion_block->AddStatement(clear_first_or_next, zone());
3344 } 3360 }
3345 3361
3346 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name); 3362 Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name);
3347 // Make statement: flag = 1. 3363 // Make statement: flag = 1.
3348 { 3364 {
3349 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 3365 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3350 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3366 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3351 Assignment* assignment = factory()->NewAssignment( 3367 Assignment* assignment = factory()->NewAssignment(
3352 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition); 3368 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
3353 Statement* assignment_statement = 3369 Statement* assignment_statement =
3354 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); 3370 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3355 inner_block->AddStatement(assignment_statement, zone()); 3371 ignore_completion_block->AddStatement(assignment_statement, zone());
3356 } 3372 }
3357 3373 inner_block->AddStatement(ignore_completion_block, zone());
3358 // Make cond expression for main loop: flag == 1. 3374 // Make cond expression for main loop: flag == 1.
3359 Expression* flag_cond = NULL; 3375 Expression* flag_cond = NULL;
3360 { 3376 {
3361 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3377 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
3362 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 3378 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
3363 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, 3379 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
3364 RelocInfo::kNoPosition); 3380 RelocInfo::kNoPosition);
3365 } 3381 }
3366 3382
3367 // Create chain of expressions "flag = 0, temp_x = x, ..." 3383 // Create chain of expressions "flag = 0, temp_x = x, ..."
(...skipping 27 matching lines...) Expand all
3395 // Make statement: if (cond) { body; } else { break outer; } 3411 // Make statement: if (cond) { body; } else { break outer; }
3396 Statement* body_or_stop = body; 3412 Statement* body_or_stop = body;
3397 if (cond) { 3413 if (cond) {
3398 Statement* stop = 3414 Statement* stop =
3399 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition); 3415 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
3400 body_or_stop = 3416 body_or_stop =
3401 factory()->NewIfStatement(cond, body, stop, cond->position()); 3417 factory()->NewIfStatement(cond, body, stop, cond->position());
3402 } 3418 }
3403 3419
3404 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x) 3420 // 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 3421 // 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 3422 // and ensures that any break or continue statements in body point to
3407 // the right place. 3423 // the right place.
3408 loop->Initialize(NULL, flag_cond, compound_next_statement, body_or_stop); 3424 loop->Initialize(NULL, flag_cond, compound_next_statement, body_or_stop);
3409 inner_block->AddStatement(loop, zone()); 3425 inner_block->AddStatement(loop, zone());
3410 3426
3411 // Make statement: if (flag == 1) { break; } 3427 // Make statement: if (flag == 1) { break; }
3412 { 3428 {
3413 Expression* compare = NULL; 3429 Expression* compare = NULL;
3414 // Make compare expresion: flag == 1. 3430 // Make compare expresion: flag == 1.
3415 { 3431 {
(...skipping 2403 matching lines...) Expand 10 before | Expand all | Expand 10 after
5819 Expression* Parser::SpreadCallNew(Expression* function, 5835 Expression* Parser::SpreadCallNew(Expression* function,
5820 ZoneList<v8::internal::Expression*>* args, 5836 ZoneList<v8::internal::Expression*>* args,
5821 int pos) { 5837 int pos) {
5822 args->InsertAt(0, function, zone()); 5838 args->InsertAt(0, function, zone());
5823 5839
5824 return factory()->NewCallRuntime( 5840 return factory()->NewCallRuntime(
5825 ast_value_factory()->reflect_construct_string(), NULL, args, pos); 5841 ast_value_factory()->reflect_construct_string(), NULL, args, pos);
5826 } 5842 }
5827 } // namespace internal 5843 } // namespace internal
5828 } // namespace v8 5844 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast.h ('k') | src/prettyprinter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698