| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1483 Expression* expression = node->expression(); | 1483 Expression* expression = node->expression(); |
| 1484 expression->MarkAsStatement(); | 1484 expression->MarkAsStatement(); |
| 1485 Load(expression); | 1485 Load(expression); |
| 1486 // Remove the lingering expression result from the top of stack. | 1486 // Remove the lingering expression result from the top of stack. |
| 1487 frame_->Drop(); | 1487 frame_->Drop(); |
| 1488 } | 1488 } |
| 1489 | 1489 |
| 1490 | 1490 |
| 1491 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) { | 1491 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) { |
| 1492 ASSERT(!in_spilled_code()); | 1492 ASSERT(!in_spilled_code()); |
| 1493 VirtualFrame::SpilledScope spilled_scope(this); | |
| 1494 Comment cmnt(masm_, "// EmptyStatement"); | 1493 Comment cmnt(masm_, "// EmptyStatement"); |
| 1495 CodeForStatement(node); | 1494 CodeForStatement(node); |
| 1496 // nothing to do | 1495 // nothing to do |
| 1497 } | 1496 } |
| 1498 | 1497 |
| 1499 | 1498 |
| 1500 void CodeGenerator::VisitIfStatement(IfStatement* node) { | 1499 void CodeGenerator::VisitIfStatement(IfStatement* node) { |
| 1501 ASSERT(!in_spilled_code()); | 1500 ASSERT(!in_spilled_code()); |
| 1502 VirtualFrame::SpilledScope spilled_scope(this); | |
| 1503 Comment cmnt(masm_, "[ IfStatement"); | 1501 Comment cmnt(masm_, "[ IfStatement"); |
| 1504 // Generate different code depending on which parts of the if statement | 1502 // Generate different code depending on which parts of the if statement |
| 1505 // are present or not. | 1503 // are present or not. |
| 1506 bool has_then_stm = node->HasThenStatement(); | 1504 bool has_then_stm = node->HasThenStatement(); |
| 1507 bool has_else_stm = node->HasElseStatement(); | 1505 bool has_else_stm = node->HasElseStatement(); |
| 1508 | 1506 |
| 1509 CodeForStatement(node); | 1507 CodeForStatement(node); |
| 1510 JumpTarget exit(this); | 1508 JumpTarget exit(this); |
| 1511 if (has_then_stm && has_else_stm) { | 1509 if (has_then_stm && has_else_stm) { |
| 1512 JumpTarget then(this); | 1510 JumpTarget then(this); |
| 1513 JumpTarget else_(this); | 1511 JumpTarget else_(this); |
| 1514 // if (cond) | 1512 LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &else_, true); |
| 1515 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, | |
| 1516 &then, &else_, true); | |
| 1517 // An invalid frame here indicates that the code for the condition | |
| 1518 // cannot fall-through, i.e. it caused unconditional jumps to the | |
| 1519 // targets. | |
| 1520 if (has_valid_frame()) { | 1513 if (has_valid_frame()) { |
| 1514 // We have fallen through from the condition (with a value in cc_reg). |
| 1515 // Emit a branch if false around the then block and compile both |
| 1516 // blocks. |
| 1521 Branch(false, &else_); | 1517 Branch(false, &else_); |
| 1522 } | 1518 } |
| 1523 // then | 1519 if (then.is_linked()) { |
| 1524 if (has_valid_frame() || then.is_linked()) { | |
| 1525 // If control flow can reach the then part via fall-through from the | |
| 1526 // test or a branch to the target, compile it. | |
| 1527 then.Bind(); | 1520 then.Bind(); |
| 1528 VisitAndSpill(node->then_statement()); | |
| 1529 } | 1521 } |
| 1530 // A NULL frame here indicates that control did not fall out of the then | |
| 1531 // statement, it escaped on all branches. In that case, a jump to the | |
| 1532 // exit label would be dead code (and impossible, because we don't have | |
| 1533 // a current virtual frame to set at the exit label). | |
| 1534 if (has_valid_frame()) { | 1522 if (has_valid_frame()) { |
| 1523 // We have fallen through from the condition or reached here by a |
| 1524 // direct jump to the then target. |
| 1525 Visit(node->then_statement()); |
| 1526 } |
| 1527 if (has_valid_frame() && else_.is_linked()) { |
| 1528 // We have fallen through from the then block and we need to compile |
| 1529 // the else block. Emit an unconditional jump around it. |
| 1535 exit.Jump(); | 1530 exit.Jump(); |
| 1536 } | 1531 } |
| 1537 // else | |
| 1538 if (else_.is_linked()) { | 1532 if (else_.is_linked()) { |
| 1539 // Control flow for if-then-else does not fall-through to the else | |
| 1540 // part, it can only reach here via jump if at all. | |
| 1541 else_.Bind(); | 1533 else_.Bind(); |
| 1542 VisitAndSpill(node->else_statement()); | 1534 Visit(node->else_statement()); |
| 1543 } | 1535 } |
| 1544 | 1536 |
| 1545 } else if (has_then_stm) { | 1537 } else if (has_then_stm) { |
| 1546 ASSERT(!has_else_stm); | 1538 ASSERT(!has_else_stm); |
| 1547 JumpTarget then(this); | 1539 JumpTarget then(this); |
| 1548 // if (cond) | 1540 LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &exit, true); |
| 1549 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, | |
| 1550 &then, &exit, true); | |
| 1551 if (has_valid_frame()) { | 1541 if (has_valid_frame()) { |
| 1542 // We have fallen through from the condition (with a value in cc_reg). |
| 1543 // Emit a branch if false around the then block. |
| 1552 Branch(false, &exit); | 1544 Branch(false, &exit); |
| 1553 } | 1545 } |
| 1554 // then | 1546 if (then.is_linked()) { |
| 1555 if (has_valid_frame() || then.is_linked()) { | |
| 1556 then.Bind(); | 1547 then.Bind(); |
| 1557 VisitAndSpill(node->then_statement()); | 1548 } |
| 1549 if (has_valid_frame()) { |
| 1550 // We have fallen through from the condition or reached here by a |
| 1551 // direct jump to the then target. |
| 1552 Visit(node->then_statement()); |
| 1558 } | 1553 } |
| 1559 | 1554 |
| 1560 } else if (has_else_stm) { | 1555 } else if (has_else_stm) { |
| 1561 ASSERT(!has_then_stm); | 1556 ASSERT(!has_then_stm); |
| 1562 JumpTarget else_(this); | 1557 JumpTarget else_(this); |
| 1563 // if (!cond) | 1558 LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &exit, &else_, true); |
| 1564 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, | |
| 1565 &exit, &else_, true); | |
| 1566 if (has_valid_frame()) { | 1559 if (has_valid_frame()) { |
| 1560 // We have fallen through from the condition (with a value in cc_reg). |
| 1561 // Emit a branch if true around the else block. |
| 1567 Branch(true, &exit); | 1562 Branch(true, &exit); |
| 1568 } | 1563 } |
| 1569 // else | 1564 if (else_.is_linked()) { |
| 1570 if (has_valid_frame() || else_.is_linked()) { | |
| 1571 else_.Bind(); | 1565 else_.Bind(); |
| 1572 VisitAndSpill(node->else_statement()); | 1566 } |
| 1567 if (has_valid_frame()) { |
| 1568 // We have fallen through from the condition or reached here by a |
| 1569 // direct jump to the else target. |
| 1570 Visit(node->else_statement()); |
| 1573 } | 1571 } |
| 1574 | 1572 |
| 1575 } else { | 1573 } else { |
| 1576 ASSERT(!has_then_stm && !has_else_stm); | 1574 ASSERT(!has_then_stm && !has_else_stm); |
| 1577 // if (cond) | 1575 // We only care about the condition's side effects (not its value or |
| 1578 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, | 1576 // control flow effect). LoadCondition is called without forcing a |
| 1579 &exit, &exit, false); | 1577 // value into cc_reg. |
| 1578 LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &exit, &exit, false); |
| 1580 if (has_valid_frame()) { | 1579 if (has_valid_frame()) { |
| 1580 // Control flow can fall off the end of the condition. We discard its |
| 1581 // value, which may be in cc_reg or else on top of the virtual frame. |
| 1581 if (has_cc()) { | 1582 if (has_cc()) { |
| 1582 cc_reg_ = no_condition; | 1583 cc_reg_ = no_condition; |
| 1583 } else { | 1584 } else { |
| 1584 // No cc value set up, that means the boolean was pushed. | |
| 1585 // Pop it again, since it is not going to be used. | |
| 1586 frame_->Drop(); | 1585 frame_->Drop(); |
| 1587 } | 1586 } |
| 1588 } | 1587 } |
| 1589 } | 1588 } |
| 1590 | 1589 |
| 1591 // end | |
| 1592 if (exit.is_linked()) { | 1590 if (exit.is_linked()) { |
| 1593 exit.Bind(); | 1591 exit.Bind(); |
| 1594 } | 1592 } |
| 1595 } | 1593 } |
| 1596 | 1594 |
| 1597 | 1595 |
| 1598 void CodeGenerator::CleanStack(int num_bytes) { | 1596 void CodeGenerator::CleanStack(int num_bytes) { |
| 1599 ASSERT(num_bytes % kPointerSize == 0); | 1597 ASSERT(num_bytes % kPointerSize == 0); |
| 1600 frame_->Drop(num_bytes / kPointerSize); | 1598 frame_->Drop(num_bytes / kPointerSize); |
| 1601 } | 1599 } |
| (...skipping 4185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5787 | 5785 |
| 5788 // Slow-case: Go through the JavaScript implementation. | 5786 // Slow-case: Go through the JavaScript implementation. |
| 5789 __ bind(&slow); | 5787 __ bind(&slow); |
| 5790 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 5788 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
| 5791 } | 5789 } |
| 5792 | 5790 |
| 5793 | 5791 |
| 5794 #undef __ | 5792 #undef __ |
| 5795 | 5793 |
| 5796 } } // namespace v8::internal | 5794 } } // namespace v8::internal |
| OLD | NEW |