| Index: src/x64/codegen-x64.cc
|
| ===================================================================
|
| --- src/x64/codegen-x64.cc (revision 3045)
|
| +++ src/x64/codegen-x64.cc (working copy)
|
| @@ -1292,288 +1292,335 @@
|
| }
|
|
|
|
|
| -void CodeGenerator::VisitLoopStatement(LoopStatement* node) {
|
| +void CodeGenerator::VisitDoWhileStatement(DoWhileStatement* node) {
|
| ASSERT(!in_spilled_code());
|
| - Comment cmnt(masm_, "[ LoopStatement");
|
| + Comment cmnt(masm_, "[ DoWhileStatement");
|
| CodeForStatementPosition(node);
|
| node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
|
| + JumpTarget body(JumpTarget::BIDIRECTIONAL);
|
| + IncrementLoopNesting();
|
|
|
| - // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a
|
| - // known result for the test expression, with no side effects.
|
| - enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW;
|
| - if (node->cond() == NULL) {
|
| - ASSERT(node->type() == LoopStatement::FOR_LOOP);
|
| - info = ALWAYS_TRUE;
|
| - } else {
|
| - Literal* lit = node->cond()->AsLiteral();
|
| - if (lit != NULL) {
|
| - if (lit->IsTrue()) {
|
| - info = ALWAYS_TRUE;
|
| - } else if (lit->IsFalse()) {
|
| - info = ALWAYS_FALSE;
|
| + ConditionAnalysis info = AnalyzeCondition(node->cond());
|
| + // Label the top of the loop for the backward jump if necessary.
|
| + switch (info) {
|
| + case ALWAYS_TRUE:
|
| + // Use the continue target.
|
| + node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
|
| + node->continue_target()->Bind();
|
| + break;
|
| + case ALWAYS_FALSE:
|
| + // No need to label it.
|
| + node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
|
| + break;
|
| + case DONT_KNOW:
|
| + // Continue is the test, so use the backward body target.
|
| + node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
|
| + body.Bind();
|
| + break;
|
| + }
|
| +
|
| + CheckStack(); // TODO(1222600): ignore if body contains calls.
|
| + Visit(node->body());
|
| +
|
| + // Compile the test.
|
| + switch (info) {
|
| + case ALWAYS_TRUE:
|
| + // If control flow can fall off the end of the body, jump back
|
| + // to the top and bind the break target at the exit.
|
| + if (has_valid_frame()) {
|
| + node->continue_target()->Jump();
|
| }
|
| - }
|
| + if (node->break_target()->is_linked()) {
|
| + node->break_target()->Bind();
|
| + }
|
| + break;
|
| + case ALWAYS_FALSE:
|
| + // We may have had continues or breaks in the body.
|
| + if (node->continue_target()->is_linked()) {
|
| + node->continue_target()->Bind();
|
| + }
|
| + if (node->break_target()->is_linked()) {
|
| + node->break_target()->Bind();
|
| + }
|
| + break;
|
| + case DONT_KNOW:
|
| + // We have to compile the test expression if it can be reached by
|
| + // control flow falling out of the body or via continue.
|
| + if (node->continue_target()->is_linked()) {
|
| + node->continue_target()->Bind();
|
| + }
|
| + if (has_valid_frame()) {
|
| + ControlDestination dest(&body, node->break_target(), false);
|
| + LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
|
| + }
|
| + if (node->break_target()->is_linked()) {
|
| + node->break_target()->Bind();
|
| + }
|
| + break;
|
| }
|
|
|
| - switch (node->type()) {
|
| - case LoopStatement::DO_LOOP: {
|
| - JumpTarget body(JumpTarget::BIDIRECTIONAL);
|
| - IncrementLoopNesting();
|
| + DecrementLoopNesting();
|
| + node->continue_target()->Unuse();
|
| + node->break_target()->Unuse();
|
| +}
|
|
|
| - // Label the top of the loop for the backward jump if necessary.
|
| - if (info == ALWAYS_TRUE) {
|
| - // Use the continue target.
|
| +
|
| +void CodeGenerator::VisitWhileStatement(WhileStatement* node) {
|
| + ASSERT(!in_spilled_code());
|
| + Comment cmnt(masm_, "[ WhileStatement");
|
| + CodeForStatementPosition(node);
|
| +
|
| + // If the condition is always false and has no side effects, we do not
|
| + // need to compile anything.
|
| + ConditionAnalysis info = AnalyzeCondition(node->cond());
|
| + if (info == ALWAYS_FALSE) return;
|
| +
|
| + // Do not duplicate conditions that may have function literal
|
| + // subexpressions. This can cause us to compile the function literal
|
| + // twice.
|
| + bool test_at_bottom = !node->may_have_function_literal();
|
| + node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
|
| + IncrementLoopNesting();
|
| + JumpTarget body;
|
| + if (test_at_bottom) {
|
| + body.set_direction(JumpTarget::BIDIRECTIONAL);
|
| + }
|
| +
|
| + // Based on the condition analysis, compile the test as necessary.
|
| + switch (info) {
|
| + case ALWAYS_TRUE:
|
| + // We will not compile the test expression. Label the top of the
|
| + // loop with the continue target.
|
| + node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
|
| + node->continue_target()->Bind();
|
| + break;
|
| + case DONT_KNOW: {
|
| + if (test_at_bottom) {
|
| + // Continue is the test at the bottom, no need to label the test
|
| + // at the top. The body is a backward target.
|
| + node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
|
| + } else {
|
| + // Label the test at the top as the continue target. The body
|
| + // is a forward-only target.
|
| node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
|
| node->continue_target()->Bind();
|
| - } else if (info == ALWAYS_FALSE) {
|
| - // No need to label it.
|
| - node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
|
| - } else {
|
| - // Continue is the test, so use the backward body target.
|
| - ASSERT(info == DONT_KNOW);
|
| - node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
|
| - body.Bind();
|
| }
|
| + // Compile the test with the body as the true target and preferred
|
| + // fall-through and with the break target as the false target.
|
| + ControlDestination dest(&body, node->break_target(), true);
|
| + LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
|
|
|
| - CheckStack(); // TODO(1222600): ignore if body contains calls.
|
| - Visit(node->body());
|
| -
|
| - // Compile the test.
|
| - if (info == ALWAYS_TRUE) {
|
| - // If control flow can fall off the end of the body, jump back
|
| - // to the top and bind the break target at the exit.
|
| - if (has_valid_frame()) {
|
| - node->continue_target()->Jump();
|
| + if (dest.false_was_fall_through()) {
|
| + // If we got the break target as fall-through, the test may have
|
| + // been unconditionally false (if there are no jumps to the
|
| + // body).
|
| + if (!body.is_linked()) {
|
| + DecrementLoopNesting();
|
| + return;
|
| }
|
| - if (node->break_target()->is_linked()) {
|
| - node->break_target()->Bind();
|
| - }
|
|
|
| - } else if (info == ALWAYS_FALSE) {
|
| - // We may have had continues or breaks in the body.
|
| - if (node->continue_target()->is_linked()) {
|
| - node->continue_target()->Bind();
|
| - }
|
| - if (node->break_target()->is_linked()) {
|
| - node->break_target()->Bind();
|
| - }
|
| + // Otherwise, jump around the body on the fall through and then
|
| + // bind the body target.
|
| + node->break_target()->Unuse();
|
| + node->break_target()->Jump();
|
| + body.Bind();
|
| + }
|
| + break;
|
| + }
|
| + case ALWAYS_FALSE:
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
|
|
| - } else {
|
| - ASSERT(info == DONT_KNOW);
|
| - // We have to compile the test expression if it can be reached by
|
| - // control flow falling out of the body or via continue.
|
| + CheckStack(); // TODO(1222600): ignore if body contains calls.
|
| + Visit(node->body());
|
| +
|
| + // Based on the condition analysis, compile the backward jump as
|
| + // necessary.
|
| + switch (info) {
|
| + case ALWAYS_TRUE:
|
| + // The loop body has been labeled with the continue target.
|
| + if (has_valid_frame()) {
|
| + node->continue_target()->Jump();
|
| + }
|
| + break;
|
| + case DONT_KNOW:
|
| + if (test_at_bottom) {
|
| + // If we have chosen to recompile the test at the bottom,
|
| + // then it is the continue target.
|
| if (node->continue_target()->is_linked()) {
|
| node->continue_target()->Bind();
|
| }
|
| if (has_valid_frame()) {
|
| + // The break target is the fall-through (body is a backward
|
| + // jump from here and thus an invalid fall-through).
|
| ControlDestination dest(&body, node->break_target(), false);
|
| LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
|
| }
|
| - if (node->break_target()->is_linked()) {
|
| - node->break_target()->Bind();
|
| + } else {
|
| + // If we have chosen not to recompile the test at the
|
| + // bottom, jump back to the one at the top.
|
| + if (has_valid_frame()) {
|
| + node->continue_target()->Jump();
|
| }
|
| }
|
| break;
|
| - }
|
| + case ALWAYS_FALSE:
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
|
|
| - case LoopStatement::WHILE_LOOP: {
|
| - // Do not duplicate conditions that may have function literal
|
| - // subexpressions. This can cause us to compile the function
|
| - // literal twice.
|
| - bool test_at_bottom = !node->may_have_function_literal();
|
| + // The break target may be already bound (by the condition), or there
|
| + // may not be a valid frame. Bind it only if needed.
|
| + if (node->break_target()->is_linked()) {
|
| + node->break_target()->Bind();
|
| + }
|
| + DecrementLoopNesting();
|
| +}
|
|
|
| - IncrementLoopNesting();
|
|
|
| - // If the condition is always false and has no side effects, we
|
| - // do not need to compile anything.
|
| - if (info == ALWAYS_FALSE) break;
|
| +void CodeGenerator::VisitForStatement(ForStatement* node) {
|
| + ASSERT(!in_spilled_code());
|
| + Comment cmnt(masm_, "[ ForStatement");
|
| + CodeForStatementPosition(node);
|
|
|
| - JumpTarget body;
|
| - if (test_at_bottom) {
|
| - body.set_direction(JumpTarget::BIDIRECTIONAL);
|
| - }
|
| + // Compile the init expression if present.
|
| + if (node->init() != NULL) {
|
| + Visit(node->init());
|
| + }
|
|
|
| - // Based on the condition analysis, compile the test as necessary.
|
| - if (info == ALWAYS_TRUE) {
|
| - // We will not compile the test expression. Label the top of
|
| - // the loop with the continue target.
|
| + // If the condition is always false and has no side effects, we do not
|
| + // need to compile anything else.
|
| + ConditionAnalysis info = AnalyzeCondition(node->cond());
|
| + if (info == ALWAYS_FALSE) return;
|
| +
|
| + // Do not duplicate conditions that may have function literal
|
| + // subexpressions. This can cause us to compile the function literal
|
| + // twice.
|
| + bool test_at_bottom = !node->may_have_function_literal();
|
| + node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
|
| + IncrementLoopNesting();
|
| +
|
| + // Target for backward edge if no test at the bottom, otherwise
|
| + // unused.
|
| + JumpTarget loop(JumpTarget::BIDIRECTIONAL);
|
| +
|
| + // Target for backward edge if there is a test at the bottom,
|
| + // otherwise used as target for test at the top.
|
| + JumpTarget body;
|
| + if (test_at_bottom) {
|
| + body.set_direction(JumpTarget::BIDIRECTIONAL);
|
| + }
|
| +
|
| + // Based on the condition analysis, compile the test as necessary.
|
| + switch (info) {
|
| + case ALWAYS_TRUE:
|
| + // We will not compile the test expression. Label the top of the
|
| + // loop.
|
| + if (node->next() == NULL) {
|
| + // Use the continue target if there is no update expression.
|
| node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
|
| node->continue_target()->Bind();
|
| } else {
|
| - ASSERT(info == DONT_KNOW); // ALWAYS_FALSE cannot reach here.
|
| - if (test_at_bottom) {
|
| - // Continue is the test at the bottom, no need to label the
|
| - // test at the top. The body is a backward target.
|
| - node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
|
| - } else {
|
| - // Label the test at the top as the continue target. The
|
| - // body is a forward-only target.
|
| - node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
|
| - node->continue_target()->Bind();
|
| - }
|
| - // Compile the test with the body as the true target and
|
| - // preferred fall-through and with the break target as the
|
| - // false target.
|
| - ControlDestination dest(&body, node->break_target(), true);
|
| - LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
|
| -
|
| - if (dest.false_was_fall_through()) {
|
| - // If we got the break target as fall-through, the test may
|
| - // have been unconditionally false (if there are no jumps to
|
| - // the body).
|
| - if (!body.is_linked()) break;
|
| -
|
| - // Otherwise, jump around the body on the fall through and
|
| - // then bind the body target.
|
| - node->break_target()->Unuse();
|
| - node->break_target()->Jump();
|
| - body.Bind();
|
| - }
|
| + // Otherwise use the backward loop target.
|
| + node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
|
| + loop.Bind();
|
| }
|
| + break;
|
| + case DONT_KNOW: {
|
| + if (test_at_bottom) {
|
| + // Continue is either the update expression or the test at the
|
| + // bottom, no need to label the test at the top.
|
| + node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
|
| + } else if (node->next() == NULL) {
|
| + // We are not recompiling the test at the bottom and there is no
|
| + // update expression.
|
| + node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
|
| + node->continue_target()->Bind();
|
| + } else {
|
| + // We are not recompiling the test at the bottom and there is an
|
| + // update expression.
|
| + node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
|
| + loop.Bind();
|
| + }
|
|
|
| - CheckStack(); // TODO(1222600): ignore if body contains calls.
|
| - Visit(node->body());
|
| + // Compile the test with the body as the true target and preferred
|
| + // fall-through and with the break target as the false target.
|
| + ControlDestination dest(&body, node->break_target(), true);
|
| + LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
|
|
|
| - // Based on the condition analysis, compile the backward jump as
|
| - // necessary.
|
| - if (info == ALWAYS_TRUE) {
|
| - // The loop body has been labeled with the continue target.
|
| - if (has_valid_frame()) {
|
| - node->continue_target()->Jump();
|
| + if (dest.false_was_fall_through()) {
|
| + // If we got the break target as fall-through, the test may have
|
| + // been unconditionally false (if there are no jumps to the
|
| + // body).
|
| + if (!body.is_linked()) {
|
| + DecrementLoopNesting();
|
| + return;
|
| }
|
| - } else {
|
| - ASSERT(info == DONT_KNOW); // ALWAYS_FALSE cannot reach here.
|
| - if (test_at_bottom) {
|
| - // If we have chosen to recompile the test at the bottom,
|
| - // then it is the continue target.
|
| - if (node->continue_target()->is_linked()) {
|
| - node->continue_target()->Bind();
|
| - }
|
| - if (has_valid_frame()) {
|
| - // The break target is the fall-through (body is a backward
|
| - // jump from here and thus an invalid fall-through).
|
| - ControlDestination dest(&body, node->break_target(), false);
|
| - LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
|
| - }
|
| - } else {
|
| - // If we have chosen not to recompile the test at the
|
| - // bottom, jump back to the one at the top.
|
| - if (has_valid_frame()) {
|
| - node->continue_target()->Jump();
|
| - }
|
| - }
|
| - }
|
|
|
| - // The break target may be already bound (by the condition), or
|
| - // there may not be a valid frame. Bind it only if needed.
|
| - if (node->break_target()->is_linked()) {
|
| - node->break_target()->Bind();
|
| + // Otherwise, jump around the body on the fall through and then
|
| + // bind the body target.
|
| + node->break_target()->Unuse();
|
| + node->break_target()->Jump();
|
| + body.Bind();
|
| }
|
| break;
|
| }
|
| + case ALWAYS_FALSE:
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
|
|
| - case LoopStatement::FOR_LOOP: {
|
| - // Do not duplicate conditions that may have function literal
|
| - // subexpressions. This can cause us to compile the function
|
| - // literal twice.
|
| - bool test_at_bottom = !node->may_have_function_literal();
|
| + CheckStack(); // TODO(1222600): ignore if body contains calls.
|
| + Visit(node->body());
|
|
|
| - // Compile the init expression if present.
|
| - if (node->init() != NULL) {
|
| - Visit(node->init());
|
| - }
|
| + // If there is an update expression, compile it if necessary.
|
| + if (node->next() != NULL) {
|
| + if (node->continue_target()->is_linked()) {
|
| + node->continue_target()->Bind();
|
| + }
|
|
|
| - IncrementLoopNesting();
|
| + // Control can reach the update by falling out of the body or by a
|
| + // continue.
|
| + if (has_valid_frame()) {
|
| + // Record the source position of the statement as this code which
|
| + // is after the code for the body actually belongs to the loop
|
| + // statement and not the body.
|
| + CodeForStatementPosition(node);
|
| + Visit(node->next());
|
| + }
|
| + }
|
|
|
| - // If the condition is always false and has no side effects, we
|
| - // do not need to compile anything else.
|
| - if (info == ALWAYS_FALSE) break;
|
| -
|
| - // Target for backward edge if no test at the bottom, otherwise
|
| - // unused.
|
| - JumpTarget loop(JumpTarget::BIDIRECTIONAL);
|
| -
|
| - // Target for backward edge if there is a test at the bottom,
|
| - // otherwise used as target for test at the top.
|
| - JumpTarget body;
|
| - if (test_at_bottom) {
|
| - body.set_direction(JumpTarget::BIDIRECTIONAL);
|
| - }
|
| -
|
| - // Based on the condition analysis, compile the test as necessary.
|
| - if (info == ALWAYS_TRUE) {
|
| - // We will not compile the test expression. Label the top of
|
| - // the loop.
|
| + // Based on the condition analysis, compile the backward jump as
|
| + // necessary.
|
| + switch (info) {
|
| + case ALWAYS_TRUE:
|
| + if (has_valid_frame()) {
|
| if (node->next() == NULL) {
|
| - // Use the continue target if there is no update expression.
|
| - node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
|
| - node->continue_target()->Bind();
|
| + node->continue_target()->Jump();
|
| } else {
|
| - // Otherwise use the backward loop target.
|
| - node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
|
| - loop.Bind();
|
| + loop.Jump();
|
| }
|
| - } else {
|
| - ASSERT(info == DONT_KNOW);
|
| - if (test_at_bottom) {
|
| - // Continue is either the update expression or the test at
|
| - // the bottom, no need to label the test at the top.
|
| - node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
|
| - } else if (node->next() == NULL) {
|
| - // We are not recompiling the test at the bottom and there
|
| - // is no update expression.
|
| - node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
|
| - node->continue_target()->Bind();
|
| - } else {
|
| - // We are not recompiling the test at the bottom and there
|
| - // is an update expression.
|
| - node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
|
| - loop.Bind();
|
| - }
|
| -
|
| - // Compile the test with the body as the true target and
|
| - // preferred fall-through and with the break target as the
|
| - // false target.
|
| - ControlDestination dest(&body, node->break_target(), true);
|
| - LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
|
| -
|
| - if (dest.false_was_fall_through()) {
|
| - // If we got the break target as fall-through, the test may
|
| - // have been unconditionally false (if there are no jumps to
|
| - // the body).
|
| - if (!body.is_linked()) break;
|
| -
|
| - // Otherwise, jump around the body on the fall through and
|
| - // then bind the body target.
|
| - node->break_target()->Unuse();
|
| - node->break_target()->Jump();
|
| - body.Bind();
|
| - }
|
| }
|
| -
|
| - CheckStack(); // TODO(1222600): ignore if body contains calls.
|
| - Visit(node->body());
|
| -
|
| - // If there is an update expression, compile it if necessary.
|
| - if (node->next() != NULL) {
|
| + break;
|
| + case DONT_KNOW:
|
| + if (test_at_bottom) {
|
| if (node->continue_target()->is_linked()) {
|
| + // We can have dangling jumps to the continue target if there
|
| + // was no update expression.
|
| node->continue_target()->Bind();
|
| }
|
| -
|
| - // Control can reach the update by falling out of the body or
|
| - // by a continue.
|
| + // Control can reach the test at the bottom by falling out of
|
| + // the body, by a continue in the body, or from the update
|
| + // expression.
|
| if (has_valid_frame()) {
|
| - // Record the source position of the statement as this code
|
| - // which is after the code for the body actually belongs to
|
| - // the loop statement and not the body.
|
| - CodeForStatementPosition(node);
|
| - Visit(node->next());
|
| + // The break target is the fall-through (body is a backward
|
| + // jump from here).
|
| + ControlDestination dest(&body, node->break_target(), false);
|
| + LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
|
| }
|
| - }
|
| -
|
| - // Based on the condition analysis, compile the backward jump as
|
| - // necessary.
|
| - if (info == ALWAYS_TRUE) {
|
| + } else {
|
| + // Otherwise, jump back to the test at the top.
|
| if (has_valid_frame()) {
|
| if (node->next() == NULL) {
|
| node->continue_target()->Jump();
|
| @@ -1581,47 +1628,19 @@
|
| loop.Jump();
|
| }
|
| }
|
| - } else {
|
| - ASSERT(info == DONT_KNOW); // ALWAYS_FALSE cannot reach here.
|
| - if (test_at_bottom) {
|
| - if (node->continue_target()->is_linked()) {
|
| - // We can have dangling jumps to the continue target if
|
| - // there was no update expression.
|
| - node->continue_target()->Bind();
|
| - }
|
| - // Control can reach the test at the bottom by falling out
|
| - // of the body, by a continue in the body, or from the
|
| - // update expression.
|
| - if (has_valid_frame()) {
|
| - // The break target is the fall-through (body is a
|
| - // backward jump from here).
|
| - ControlDestination dest(&body, node->break_target(), false);
|
| - LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &dest, true);
|
| - }
|
| - } else {
|
| - // Otherwise, jump back to the test at the top.
|
| - if (has_valid_frame()) {
|
| - if (node->next() == NULL) {
|
| - node->continue_target()->Jump();
|
| - } else {
|
| - loop.Jump();
|
| - }
|
| - }
|
| - }
|
| }
|
| -
|
| - // The break target may be already bound (by the condition), or
|
| - // there may not be a valid frame. Bind it only if needed.
|
| - if (node->break_target()->is_linked()) {
|
| - node->break_target()->Bind();
|
| - }
|
| break;
|
| - }
|
| + case ALWAYS_FALSE:
|
| + UNREACHABLE();
|
| + break;
|
| }
|
|
|
| + // The break target may be already bound (by the condition), or there
|
| + // may not be a valid frame. Bind it only if needed.
|
| + if (node->break_target()->is_linked()) {
|
| + node->break_target()->Bind();
|
| + }
|
| DecrementLoopNesting();
|
| - node->continue_target()->Unuse();
|
| - node->break_target()->Unuse();
|
| }
|
|
|
|
|
| @@ -1813,10 +1832,10 @@
|
| node->break_target()->Unuse();
|
| }
|
|
|
| -void CodeGenerator::VisitTryCatch(TryCatch* node) {
|
| +void CodeGenerator::VisitTryCatchStatement(TryCatchStatement* node) {
|
| ASSERT(!in_spilled_code());
|
| VirtualFrame::SpilledScope spilled_scope;
|
| - Comment cmnt(masm_, "[ TryCatch");
|
| + Comment cmnt(masm_, "[ TryCatchStatement");
|
| CodeForStatementPosition(node);
|
|
|
| JumpTarget try_block;
|
| @@ -1952,10 +1971,10 @@
|
| }
|
|
|
|
|
| -void CodeGenerator::VisitTryFinally(TryFinally* node) {
|
| +void CodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* node) {
|
| ASSERT(!in_spilled_code());
|
| VirtualFrame::SpilledScope spilled_scope;
|
| - Comment cmnt(masm_, "[ TryFinally");
|
| + Comment cmnt(masm_, "[ TryFinallyStatement");
|
| CodeForStatementPosition(node);
|
|
|
| // State: Used to keep track of reason for entering the finally
|
|
|