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 |