Chromium Code Reviews| 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 1616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1627 | 1627 |
| 1628 VisitStatements(node->catch_block()->statements()); | 1628 VisitStatements(node->catch_block()->statements()); |
| 1629 __ b(&exit); | 1629 __ b(&exit); |
| 1630 | 1630 |
| 1631 | 1631 |
| 1632 // --- Try block --- | 1632 // --- Try block --- |
| 1633 __ bind(&try_block); | 1633 __ bind(&try_block); |
| 1634 | 1634 |
| 1635 __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER); | 1635 __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER); |
| 1636 | 1636 |
| 1637 // Introduce shadow labels for all escapes from the try block, | 1637 // Shadow the labels for all escapes from the try block, including |
| 1638 // including returns. We should probably try to unify the escaping | 1638 // returns. During shadowing, the origianl label is hidden as the |
|
iposva
2008/10/22 18:34:33
origianl -> original
| |
| 1639 // labels and the return label. | 1639 // LabelShadow and operations on the original actually affect the |
| 1640 // shadowing label. | |
| 1641 // | |
| 1642 // We should probably try to unify the escaping labels and the return | |
| 1643 // label. | |
| 1640 int nof_escapes = node->escaping_labels()->length(); | 1644 int nof_escapes = node->escaping_labels()->length(); |
| 1641 List<LabelShadow*> shadows(1 + nof_escapes); | 1645 List<LabelShadow*> shadows(1 + nof_escapes); |
| 1642 shadows.Add(new LabelShadow(&function_return_)); | 1646 shadows.Add(new LabelShadow(&function_return_)); |
| 1643 for (int i = 0; i < nof_escapes; i++) { | 1647 for (int i = 0; i < nof_escapes; i++) { |
| 1644 shadows.Add(new LabelShadow(node->escaping_labels()->at(i))); | 1648 shadows.Add(new LabelShadow(node->escaping_labels()->at(i))); |
| 1645 } | 1649 } |
| 1646 | 1650 |
| 1647 // Generate code for the statements in the try block. | 1651 // Generate code for the statements in the try block. |
| 1648 VisitStatements(node->try_block()->statements()); | 1652 VisitStatements(node->try_block()->statements()); |
| 1649 __ pop(r0); // Discard the result. | 1653 __ pop(r0); // Discard the result. |
| 1650 | 1654 |
| 1651 // Stop the introduced shadowing and count the number of required unlinks. | 1655 // Stop the introduced shadowing and count the number of required unlinks. |
| 1656 // After shadowing stops, the original labels are unshadowed and the | |
| 1657 // LabelShadows represent the formerly shadowing labels. | |
| 1652 int nof_unlinks = 0; | 1658 int nof_unlinks = 0; |
| 1653 for (int i = 0; i <= nof_escapes; i++) { | 1659 for (int i = 0; i <= nof_escapes; i++) { |
| 1654 shadows[i]->StopShadowing(); | 1660 shadows[i]->StopShadowing(); |
| 1655 if (shadows[i]->is_linked()) nof_unlinks++; | 1661 if (shadows[i]->is_linked()) nof_unlinks++; |
| 1656 } | 1662 } |
| 1657 | 1663 |
| 1658 // Unlink from try chain. | 1664 // Unlink from try chain. |
| 1659 // TOS contains code slot | 1665 // TOS contains code slot |
| 1660 const int kNextOffset = StackHandlerConstants::kNextOffset + | 1666 const int kNextOffset = StackHandlerConstants::kNextOffset + |
| 1661 StackHandlerConstants::kAddressDisplacement; | 1667 StackHandlerConstants::kAddressDisplacement; |
| 1662 __ ldr(r1, MemOperand(sp, kNextOffset)); // read next_sp | 1668 __ ldr(r1, MemOperand(sp, kNextOffset)); // read next_sp |
| 1663 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); | 1669 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); |
| 1664 __ str(r1, MemOperand(r3)); | 1670 __ str(r1, MemOperand(r3)); |
| 1665 ASSERT(StackHandlerConstants::kCodeOffset == 0); // first field is code | 1671 ASSERT(StackHandlerConstants::kCodeOffset == 0); // first field is code |
| 1666 __ add(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); | 1672 __ add(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); |
| 1667 // Code slot popped. | 1673 // Code slot popped. |
| 1668 if (nof_unlinks > 0) __ b(&exit); | 1674 if (nof_unlinks > 0) __ b(&exit); |
| 1669 | 1675 |
| 1670 // Generate unlink code for all used shadow labels. | 1676 // Generate unlink code for the (formerly) shadowing labels that have been |
| 1677 // jumped to. | |
| 1671 for (int i = 0; i <= nof_escapes; i++) { | 1678 for (int i = 0; i <= nof_escapes; i++) { |
| 1672 if (shadows[i]->is_linked()) { | 1679 if (shadows[i]->is_linked()) { |
| 1673 // Unlink from try chain; | 1680 // Unlink from try chain; |
| 1674 __ bind(shadows[i]); | 1681 __ bind(shadows[i]); |
| 1675 | 1682 |
| 1676 // Reload sp from the top handler, because some statements that we | 1683 // Reload sp from the top handler, because some statements that we |
| 1677 // break from (eg, for...in) may have left stuff on the stack. | 1684 // break from (eg, for...in) may have left stuff on the stack. |
| 1678 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); | 1685 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); |
| 1679 __ ldr(sp, MemOperand(r3)); | 1686 __ ldr(sp, MemOperand(r3)); |
| 1680 | 1687 |
| 1681 __ ldr(r1, MemOperand(sp, kNextOffset)); | 1688 __ ldr(r1, MemOperand(sp, kNextOffset)); |
| 1682 __ str(r1, MemOperand(r3)); | 1689 __ str(r1, MemOperand(r3)); |
| 1683 ASSERT(StackHandlerConstants::kCodeOffset == 0); // first field is code | 1690 ASSERT(StackHandlerConstants::kCodeOffset == 0); // first field is code |
| 1684 __ add(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); | 1691 __ add(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); |
| 1685 // Code slot popped. | 1692 // Code slot popped. |
| 1686 | 1693 |
| 1687 __ b(shadows[i]->shadowed()); | 1694 __ b(shadows[i]->original_label()); |
| 1688 } | 1695 } |
| 1689 } | 1696 } |
| 1690 | 1697 |
| 1691 __ bind(&exit); | 1698 __ bind(&exit); |
| 1692 } | 1699 } |
| 1693 | 1700 |
| 1694 | 1701 |
| 1695 void CodeGenerator::VisitTryFinally(TryFinally* node) { | 1702 void CodeGenerator::VisitTryFinally(TryFinally* node) { |
| 1696 Comment cmnt(masm_, "[ TryFinally"); | 1703 Comment cmnt(masm_, "[ TryFinally"); |
| 1697 | 1704 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1708 // In case of thrown exceptions, this is where we continue. | 1715 // In case of thrown exceptions, this is where we continue. |
| 1709 __ mov(r2, Operand(Smi::FromInt(THROWING))); | 1716 __ mov(r2, Operand(Smi::FromInt(THROWING))); |
| 1710 __ b(&finally_block); | 1717 __ b(&finally_block); |
| 1711 | 1718 |
| 1712 | 1719 |
| 1713 // --- Try block --- | 1720 // --- Try block --- |
| 1714 __ bind(&try_block); | 1721 __ bind(&try_block); |
| 1715 | 1722 |
| 1716 __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); | 1723 __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); |
| 1717 | 1724 |
| 1718 // Introduce shadow labels for all escapes from the try block, | 1725 // Shadow the labels for all escapes from the try block, including |
| 1719 // including returns. We should probably try to unify the escaping | 1726 // returns. Shadowing hides the original label as the LabelShadow and |
| 1720 // labels and the return label. | 1727 // operations on the original actually affect the shadowing label. |
| 1728 // | |
| 1729 // We should probably try to unify the escaping labels and the return | |
| 1730 // label. | |
| 1721 int nof_escapes = node->escaping_labels()->length(); | 1731 int nof_escapes = node->escaping_labels()->length(); |
| 1722 List<LabelShadow*> shadows(1 + nof_escapes); | 1732 List<LabelShadow*> shadows(1 + nof_escapes); |
| 1723 shadows.Add(new LabelShadow(&function_return_)); | 1733 shadows.Add(new LabelShadow(&function_return_)); |
| 1724 for (int i = 0; i < nof_escapes; i++) { | 1734 for (int i = 0; i < nof_escapes; i++) { |
| 1725 shadows.Add(new LabelShadow(node->escaping_labels()->at(i))); | 1735 shadows.Add(new LabelShadow(node->escaping_labels()->at(i))); |
| 1726 } | 1736 } |
| 1727 | 1737 |
| 1728 // Generate code for the statements in the try block. | 1738 // Generate code for the statements in the try block. |
| 1729 VisitStatements(node->try_block()->statements()); | 1739 VisitStatements(node->try_block()->statements()); |
| 1730 | 1740 |
| 1731 // Stop the introduced shadowing and count the number of required | 1741 // Stop the introduced shadowing and count the number of required unlinks. |
| 1732 // unlinks. | 1742 // After shadowing stops, the original labels are unshadowed and the |
| 1743 // LabelShadows represent the formerly shadowing labels. | |
| 1733 int nof_unlinks = 0; | 1744 int nof_unlinks = 0; |
| 1734 for (int i = 0; i <= nof_escapes; i++) { | 1745 for (int i = 0; i <= nof_escapes; i++) { |
| 1735 shadows[i]->StopShadowing(); | 1746 shadows[i]->StopShadowing(); |
| 1736 if (shadows[i]->is_linked()) nof_unlinks++; | 1747 if (shadows[i]->is_linked()) nof_unlinks++; |
| 1737 } | 1748 } |
| 1738 | 1749 |
| 1739 // Set the state on the stack to FALLING. | 1750 // Set the state on the stack to FALLING. |
| 1740 __ mov(r0, Operand(Factory::undefined_value())); // fake TOS | 1751 __ mov(r0, Operand(Factory::undefined_value())); // fake TOS |
| 1741 __ push(r0); | 1752 __ push(r0); |
| 1742 __ mov(r2, Operand(Smi::FromInt(FALLING))); | 1753 __ mov(r2, Operand(Smi::FromInt(FALLING))); |
| 1743 if (nof_unlinks > 0) __ b(&unlink); | 1754 if (nof_unlinks > 0) __ b(&unlink); |
| 1744 | 1755 |
| 1745 // Generate code that sets the state for all used shadow labels. | 1756 // Generate code to set the state for the (formerly) shadowing labels that |
| 1757 // have been jumped to. | |
| 1746 for (int i = 0; i <= nof_escapes; i++) { | 1758 for (int i = 0; i <= nof_escapes; i++) { |
| 1747 if (shadows[i]->is_linked()) { | 1759 if (shadows[i]->is_linked()) { |
| 1748 __ bind(shadows[i]); | 1760 __ bind(shadows[i]); |
| 1749 if (shadows[i]->shadowed() == &function_return_) { | 1761 if (shadows[i]->original_label() == &function_return_) { |
| 1750 __ push(r0); // Materialize the return value on the stack | 1762 // If this label shadowed the function return, materialize the |
| 1763 // return value on the stack. | |
| 1764 __ push(r0); | |
| 1751 } else { | 1765 } else { |
| 1752 // Fake TOS for break and continue (not return). | 1766 // Fake TOS for labels that shadowed breaks and continues. |
| 1753 __ mov(r0, Operand(Factory::undefined_value())); | 1767 __ mov(r0, Operand(Factory::undefined_value())); |
| 1754 __ push(r0); | 1768 __ push(r0); |
| 1755 } | 1769 } |
| 1756 __ mov(r2, Operand(Smi::FromInt(JUMPING + i))); | 1770 __ mov(r2, Operand(Smi::FromInt(JUMPING + i))); |
| 1757 __ b(&unlink); | 1771 __ b(&unlink); |
| 1758 } | 1772 } |
| 1759 } | 1773 } |
| 1760 | 1774 |
| 1761 // Unlink from try chain; | 1775 // Unlink from try chain; |
| 1762 __ bind(&unlink); | 1776 __ bind(&unlink); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1789 break_stack_height_ += kFinallyStackSize; | 1803 break_stack_height_ += kFinallyStackSize; |
| 1790 | 1804 |
| 1791 // Generate code for the statements in the finally block. | 1805 // Generate code for the statements in the finally block. |
| 1792 VisitStatements(node->finally_block()->statements()); | 1806 VisitStatements(node->finally_block()->statements()); |
| 1793 | 1807 |
| 1794 // Restore state and return value or faked TOS. | 1808 // Restore state and return value or faked TOS. |
| 1795 __ pop(r2); | 1809 __ pop(r2); |
| 1796 __ pop(r0); | 1810 __ pop(r0); |
| 1797 break_stack_height_ -= kFinallyStackSize; | 1811 break_stack_height_ -= kFinallyStackSize; |
| 1798 | 1812 |
| 1799 // Generate code that jumps to the right destination for all used | 1813 // Generate code to jump to the right destination for all used (formerly) |
| 1800 // shadow labels. | 1814 // shadowing labels. |
| 1801 for (int i = 0; i <= nof_escapes; i++) { | 1815 for (int i = 0; i <= nof_escapes; i++) { |
| 1802 if (shadows[i]->is_bound()) { | 1816 if (shadows[i]->is_bound()) { |
| 1803 __ cmp(r2, Operand(Smi::FromInt(JUMPING + i))); | 1817 __ cmp(r2, Operand(Smi::FromInt(JUMPING + i))); |
| 1804 if (shadows[i]->shadowed() != &function_return_) { | 1818 if (shadows[i]->original_label() != &function_return_) { |
| 1805 Label next; | 1819 Label next; |
| 1806 __ b(ne, &next); | 1820 __ b(ne, &next); |
| 1807 __ b(shadows[i]->shadowed()); | 1821 __ b(shadows[i]->original_label()); |
| 1808 __ bind(&next); | 1822 __ bind(&next); |
| 1809 } else { | 1823 } else { |
| 1810 __ b(eq, shadows[i]->shadowed()); | 1824 __ b(eq, shadows[i]->original_label()); |
| 1811 } | 1825 } |
| 1812 } | 1826 } |
| 1813 } | 1827 } |
| 1814 | 1828 |
| 1815 // Check if we need to rethrow the exception. | 1829 // Check if we need to rethrow the exception. |
| 1816 __ cmp(r2, Operand(Smi::FromInt(THROWING))); | 1830 __ cmp(r2, Operand(Smi::FromInt(THROWING))); |
| 1817 __ b(ne, &exit); | 1831 __ b(ne, &exit); |
| 1818 | 1832 |
| 1819 // Rethrow exception. | 1833 // Rethrow exception. |
| 1820 __ push(r0); | 1834 __ push(r0); |
| (...skipping 2351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4172 // Slow-case: Non-function called. | 4186 // Slow-case: Non-function called. |
| 4173 __ bind(&slow); | 4187 __ bind(&slow); |
| 4174 __ mov(r0, Operand(argc_)); // Setup the number of arguments. | 4188 __ mov(r0, Operand(argc_)); // Setup the number of arguments. |
| 4175 __ InvokeBuiltin(Builtins::CALL_NON_FUNCTION, JUMP_JS); | 4189 __ InvokeBuiltin(Builtins::CALL_NON_FUNCTION, JUMP_JS); |
| 4176 } | 4190 } |
| 4177 | 4191 |
| 4178 | 4192 |
| 4179 #undef __ | 4193 #undef __ |
| 4180 | 4194 |
| 4181 } } // namespace v8::internal | 4195 } } // namespace v8::internal |
| OLD | NEW |