| Index: src/full-codegen.cc
|
| diff --git a/src/full-codegen.cc b/src/full-codegen.cc
|
| index 01f2fafefa6429e66ca7644893a368c9bdde0dc6..237cdd62901d8deb5723efe112a0080e8b7373c5 100644
|
| --- a/src/full-codegen.cc
|
| +++ b/src/full-codegen.cc
|
| @@ -136,21 +136,19 @@ void BreakableStatementChecker::VisitWhileStatement(WhileStatement* stmt) {
|
|
|
|
|
| void BreakableStatementChecker::VisitForStatement(ForStatement* stmt) {
|
| - // Mark for statements breakable if the condition expression is.
|
| - if (stmt->cond() != NULL) {
|
| - Visit(stmt->cond());
|
| - }
|
| + // We set positions for both init and condition, if they exist.
|
| + if (stmt->cond() != NULL || stmt->init() != NULL) is_breakable_ = true;
|
| }
|
|
|
|
|
| void BreakableStatementChecker::VisitForInStatement(ForInStatement* stmt) {
|
| - // Mark for in statements breakable if the enumerable expression is.
|
| - Visit(stmt->enumerable());
|
| + // For-in is breakable because we set the position for the enumerable.
|
| + is_breakable_ = true;
|
| }
|
|
|
|
|
| void BreakableStatementChecker::VisitForOfStatement(ForOfStatement* stmt) {
|
| - // For-of is breakable because of the next() call.
|
| + // For-of is breakable because we set the position for the next() call.
|
| is_breakable_ = true;
|
| }
|
|
|
| @@ -1345,6 +1343,7 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
|
| SetStatementPosition(stmt);
|
|
|
| if (stmt->init() != NULL) {
|
| + SetStatementPosition(stmt->init());
|
| Visit(stmt->init());
|
| }
|
|
|
| @@ -1359,6 +1358,7 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
|
| PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
|
| __ bind(loop_statement.continue_label());
|
| if (stmt->next() != NULL) {
|
| + SetStatementPosition(stmt->next());
|
| Visit(stmt->next());
|
| }
|
|
|
| @@ -1371,6 +1371,7 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
|
|
|
| __ bind(&test);
|
| if (stmt->cond() != NULL) {
|
| + SetExpressionPosition(stmt->cond());
|
| VisitForControl(stmt->cond(),
|
| &body,
|
| loop_statement.break_label(),
|
| @@ -1385,6 +1386,47 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
|
| }
|
|
|
|
|
| +void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
|
| + Comment cmnt(masm_, "[ ForOfStatement");
|
| + SetStatementPosition(stmt);
|
| +
|
| + Iteration loop_statement(this, stmt);
|
| + increment_loop_depth();
|
| +
|
| + // var iterator = iterable[Symbol.iterator]();
|
| + VisitForEffect(stmt->assign_iterator());
|
| +
|
| + // Loop entry.
|
| + __ bind(loop_statement.continue_label());
|
| +
|
| + // result = iterator.next()
|
| + SetExpressionPosition(stmt->next_result());
|
| + VisitForEffect(stmt->next_result());
|
| +
|
| + // if (result.done) break;
|
| + Label result_not_done;
|
| + VisitForControl(stmt->result_done(), loop_statement.break_label(),
|
| + &result_not_done, &result_not_done);
|
| + __ bind(&result_not_done);
|
| +
|
| + // each = result.value
|
| + VisitForEffect(stmt->assign_each());
|
| +
|
| + // Generate code for the body of the loop.
|
| + Visit(stmt->body());
|
| +
|
| + // Check stack before looping.
|
| + PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
|
| + EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label());
|
| + __ jmp(loop_statement.continue_label());
|
| +
|
| + // Exit and decrement the loop depth.
|
| + PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
|
| + __ bind(loop_statement.break_label());
|
| + decrement_loop_depth();
|
| +}
|
| +
|
| +
|
| void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
|
| Comment cmnt(masm_, "[ TryCatchStatement");
|
| SetStatementPosition(stmt);
|
|
|