| Index: src/full-codegen.cc
|
| ===================================================================
|
| --- src/full-codegen.cc (revision 5336)
|
| +++ src/full-codegen.cc (working copy)
|
| @@ -317,6 +317,33 @@
|
| }
|
|
|
|
|
| +void FullCodeGenerator::PrepareTest(Label* materialize_true,
|
| + Label* materialize_false,
|
| + Label** if_true,
|
| + Label** if_false,
|
| + Label** fall_through) {
|
| + switch (context_) {
|
| + case Expression::kUninitialized:
|
| + UNREACHABLE();
|
| + break;
|
| + case Expression::kEffect:
|
| + // In an effect context, the true and the false case branch to the
|
| + // same label.
|
| + *if_true = *if_false = *fall_through = materialize_true;
|
| + break;
|
| + case Expression::kValue:
|
| + *if_true = *fall_through = materialize_true;
|
| + *if_false = materialize_false;
|
| + break;
|
| + case Expression::kTest:
|
| + *if_true = true_label_;
|
| + *if_false = false_label_;
|
| + *fall_through = fall_through_;
|
| + break;
|
| + }
|
| +}
|
| +
|
| +
|
| void FullCodeGenerator::VisitDeclarations(
|
| ZoneList<Declaration*>* declarations) {
|
| int length = declarations->length();
|
| @@ -521,13 +548,13 @@
|
| case Expression::kUninitialized:
|
| UNREACHABLE();
|
| case Expression::kEffect:
|
| - VisitForControl(expr->left(), &done, &eval_right);
|
| + VisitForControl(expr->left(), &done, &eval_right, &eval_right);
|
| break;
|
| case Expression::kValue:
|
| VisitLogicalForValue(expr->left(), expr->op(), location_, &done);
|
| break;
|
| case Expression::kTest:
|
| - VisitForControl(expr->left(), true_label_, &eval_right);
|
| + VisitForControl(expr->left(), true_label_, &eval_right, &eval_right);
|
| break;
|
| }
|
| } else {
|
| @@ -536,13 +563,13 @@
|
| case Expression::kUninitialized:
|
| UNREACHABLE();
|
| case Expression::kEffect:
|
| - VisitForControl(expr->left(), &eval_right, &done);
|
| + VisitForControl(expr->left(), &eval_right, &done, &eval_right);
|
| break;
|
| case Expression::kValue:
|
| VisitLogicalForValue(expr->left(), expr->op(), location_, &done);
|
| break;
|
| case Expression::kTest:
|
| - VisitForControl(expr->left(), &eval_right, false_label_);
|
| + VisitForControl(expr->left(), &eval_right, false_label_, &eval_right);
|
| break;
|
| }
|
| }
|
| @@ -618,16 +645,19 @@
|
| SetStatementPosition(stmt);
|
| Label then_part, else_part, done;
|
|
|
| - // Do not worry about optimizing for empty then or else bodies.
|
| - VisitForControl(stmt->condition(), &then_part, &else_part);
|
| + if (stmt->HasElseStatement()) {
|
| + VisitForControl(stmt->condition(), &then_part, &else_part, &then_part);
|
| + __ bind(&then_part);
|
| + Visit(stmt->then_statement());
|
| + __ jmp(&done);
|
|
|
| - __ bind(&then_part);
|
| - Visit(stmt->then_statement());
|
| - __ jmp(&done);
|
| -
|
| - __ bind(&else_part);
|
| - Visit(stmt->else_statement());
|
| -
|
| + __ bind(&else_part);
|
| + Visit(stmt->else_statement());
|
| + } else {
|
| + VisitForControl(stmt->condition(), &then_part, &done, &then_part);
|
| + __ bind(&then_part);
|
| + Visit(stmt->then_statement());
|
| + }
|
| __ bind(&done);
|
| }
|
|
|
| @@ -715,7 +745,7 @@
|
| void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
|
| Comment cmnt(masm_, "[ DoWhileStatement");
|
| SetStatementPosition(stmt);
|
| - Label body, stack_limit_hit, stack_check_success;
|
| + Label body, stack_limit_hit, stack_check_success, done;
|
|
|
| Iteration loop_statement(this, stmt);
|
| increment_loop_depth();
|
| @@ -727,21 +757,24 @@
|
| __ StackLimitCheck(&stack_limit_hit);
|
| __ bind(&stack_check_success);
|
|
|
| + // Record the position of the do while condition and make sure it is
|
| + // possible to break on the condition.
|
| __ bind(loop_statement.continue_target());
|
| -
|
| - // Record the position of the do while condition and make sure it is possible
|
| - // to break on the condition.
|
| SetExpressionPosition(stmt->cond(), stmt->condition_position());
|
| + VisitForControl(stmt->cond(),
|
| + &body,
|
| + loop_statement.break_target(),
|
| + loop_statement.break_target());
|
|
|
| - VisitForControl(stmt->cond(), &body, loop_statement.break_target());
|
| + __ bind(loop_statement.break_target());
|
| + __ jmp(&done);
|
|
|
| __ bind(&stack_limit_hit);
|
| StackCheckStub stack_stub;
|
| __ CallStub(&stack_stub);
|
| __ jmp(&stack_check_success);
|
|
|
| - __ bind(loop_statement.break_target());
|
| -
|
| + __ bind(&done);
|
| decrement_loop_depth();
|
| }
|
|
|
| @@ -756,25 +789,28 @@
|
| // Emit the test at the bottom of the loop.
|
| __ jmp(loop_statement.continue_target());
|
|
|
| + __ bind(&stack_limit_hit);
|
| + StackCheckStub stack_stub;
|
| + __ CallStub(&stack_stub);
|
| + __ jmp(&stack_check_success);
|
| +
|
| __ bind(&body);
|
| Visit(stmt->body());
|
| + __ bind(loop_statement.continue_target());
|
|
|
| - __ bind(loop_statement.continue_target());
|
| - // Emit the statement position here as this is where the while statement code
|
| - // starts.
|
| + // Emit the statement position here as this is where the while
|
| + // statement code starts.
|
| SetStatementPosition(stmt);
|
|
|
| // Check stack before looping.
|
| __ StackLimitCheck(&stack_limit_hit);
|
| __ bind(&stack_check_success);
|
|
|
| - VisitForControl(stmt->cond(), &body, loop_statement.break_target());
|
| + VisitForControl(stmt->cond(),
|
| + &body,
|
| + loop_statement.break_target(),
|
| + loop_statement.break_target());
|
|
|
| - __ bind(&stack_limit_hit);
|
| - StackCheckStub stack_stub;
|
| - __ CallStub(&stack_stub);
|
| - __ jmp(&stack_check_success);
|
| -
|
| __ bind(loop_statement.break_target());
|
| decrement_loop_depth();
|
| }
|
| @@ -793,6 +829,11 @@
|
| // Emit the test at the bottom of the loop (even if empty).
|
| __ jmp(&test);
|
|
|
| + __ bind(&stack_limit_hit);
|
| + StackCheckStub stack_stub;
|
| + __ CallStub(&stack_stub);
|
| + __ jmp(&stack_check_success);
|
| +
|
| __ bind(&body);
|
| Visit(stmt->body());
|
|
|
| @@ -804,8 +845,8 @@
|
| }
|
|
|
| __ bind(&test);
|
| - // Emit the statement position here as this is where the for statement code
|
| - // starts.
|
| + // Emit the statement position here as this is where the for
|
| + // statement code starts.
|
| SetStatementPosition(stmt);
|
|
|
| // Check stack before looping.
|
| @@ -813,16 +854,14 @@
|
| __ bind(&stack_check_success);
|
|
|
| if (stmt->cond() != NULL) {
|
| - VisitForControl(stmt->cond(), &body, loop_statement.break_target());
|
| + VisitForControl(stmt->cond(),
|
| + &body,
|
| + loop_statement.break_target(),
|
| + loop_statement.break_target());
|
| } else {
|
| __ jmp(&body);
|
| }
|
|
|
| - __ bind(&stack_limit_hit);
|
| - StackCheckStub stack_stub;
|
| - __ CallStub(&stack_stub);
|
| - __ jmp(&stack_check_success);
|
| -
|
| __ bind(loop_statement.break_target());
|
| decrement_loop_depth();
|
| }
|
| @@ -949,7 +988,7 @@
|
| void FullCodeGenerator::VisitConditional(Conditional* expr) {
|
| Comment cmnt(masm_, "[ Conditional");
|
| Label true_case, false_case, done;
|
| - VisitForControl(expr->condition(), &true_case, &false_case);
|
| + VisitForControl(expr->condition(), &true_case, &false_case, &true_case);
|
|
|
| __ bind(&true_case);
|
| SetExpressionPosition(expr->then_expression(),
|
|
|