| 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 1746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1757 // label. | 1757 // label. |
| 1758 int nof_escapes = node->escaping_labels()->length(); | 1758 int nof_escapes = node->escaping_labels()->length(); |
| 1759 List<LabelShadow*> shadows(1 + nof_escapes); | 1759 List<LabelShadow*> shadows(1 + nof_escapes); |
| 1760 shadows.Add(new LabelShadow(&function_return_)); | 1760 shadows.Add(new LabelShadow(&function_return_)); |
| 1761 for (int i = 0; i < nof_escapes; i++) { | 1761 for (int i = 0; i < nof_escapes; i++) { |
| 1762 shadows.Add(new LabelShadow(node->escaping_labels()->at(i))); | 1762 shadows.Add(new LabelShadow(node->escaping_labels()->at(i))); |
| 1763 } | 1763 } |
| 1764 | 1764 |
| 1765 // Generate code for the statements in the try block. | 1765 // Generate code for the statements in the try block. |
| 1766 VisitStatements(node->try_block()->statements()); | 1766 VisitStatements(node->try_block()->statements()); |
| 1767 frame_->Pop(); // Discard the result. | 1767 // Discard the code slot from the handler. |
| 1768 frame_->Pop(); |
| 1768 | 1769 |
| 1769 // Stop the introduced shadowing and count the number of required unlinks. | 1770 // Stop the introduced shadowing and count the number of required unlinks. |
| 1770 // After shadowing stops, the original labels are unshadowed and the | 1771 // After shadowing stops, the original labels are unshadowed and the |
| 1771 // LabelShadows represent the formerly shadowing labels. | 1772 // LabelShadows represent the formerly shadowing labels. |
| 1772 int nof_unlinks = 0; | 1773 int nof_unlinks = 0; |
| 1773 for (int i = 0; i <= nof_escapes; i++) { | 1774 for (int i = 0; i <= nof_escapes; i++) { |
| 1774 shadows[i]->StopShadowing(); | 1775 shadows[i]->StopShadowing(); |
| 1775 if (shadows[i]->is_linked()) nof_unlinks++; | 1776 if (shadows[i]->is_linked()) nof_unlinks++; |
| 1776 } | 1777 } |
| 1777 | 1778 |
| 1778 // Unlink from try chain. | 1779 // Unlink from try chain. |
| 1779 // TOS contains code slot | 1780 // The code slot has already been discarded, so the next index is |
| 1780 const int kNextIndex = (StackHandlerConstants::kNextOffset | 1781 // adjusted by 1. |
| 1781 + StackHandlerConstants::kAddressDisplacement) | 1782 const int kNextIndex = |
| 1782 / kPointerSize; | 1783 (StackHandlerConstants::kNextOffset / kPointerSize) - 1; |
| 1783 __ ldr(r1, frame_->Element(kNextIndex)); // read next_sp | 1784 __ ldr(r1, frame_->Element(kNextIndex)); // read next_sp |
| 1784 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); | 1785 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); |
| 1785 __ str(r1, MemOperand(r3)); | 1786 __ str(r1, MemOperand(r3)); |
| 1786 ASSERT(StackHandlerConstants::kCodeOffset == 0); // first field is code | 1787 // The code slot has already been dropped from the handler. |
| 1787 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); | 1788 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); |
| 1788 // Code slot popped. | |
| 1789 if (nof_unlinks > 0) __ b(&exit); | 1789 if (nof_unlinks > 0) __ b(&exit); |
| 1790 | 1790 |
| 1791 // Generate unlink code for the (formerly) shadowing labels that have been | 1791 // Generate unlink code for the (formerly) shadowing labels that have been |
| 1792 // jumped to. | 1792 // jumped to. |
| 1793 for (int i = 0; i <= nof_escapes; i++) { | 1793 for (int i = 0; i <= nof_escapes; i++) { |
| 1794 if (shadows[i]->is_linked()) { | 1794 if (shadows[i]->is_linked()) { |
| 1795 // Unlink from try chain; | 1795 // Unlink from try chain; |
| 1796 __ bind(shadows[i]); | 1796 __ bind(shadows[i]); |
| 1797 | 1797 |
| 1798 // Reload sp from the top handler, because some statements that we | 1798 // Reload sp from the top handler, because some statements that we |
| 1799 // break from (eg, for...in) may have left stuff on the stack. | 1799 // break from (eg, for...in) may have left stuff on the stack. |
| 1800 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); | 1800 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); |
| 1801 __ ldr(sp, MemOperand(r3)); | 1801 __ ldr(sp, MemOperand(r3)); |
| 1802 | 1802 |
| 1803 __ ldr(r1, frame_->Element(kNextIndex)); | 1803 __ ldr(r1, frame_->Element(kNextIndex)); |
| 1804 __ str(r1, MemOperand(r3)); | 1804 __ str(r1, MemOperand(r3)); |
| 1805 ASSERT(StackHandlerConstants::kCodeOffset == 0); // first field is code | 1805 // The code slot has already been dropped from the handler. |
| 1806 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); | 1806 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); |
| 1807 // Code slot popped. | |
| 1808 | 1807 |
| 1809 __ b(shadows[i]->original_label()); | 1808 __ b(shadows[i]->original_label()); |
| 1810 } | 1809 } |
| 1811 } | 1810 } |
| 1812 | 1811 |
| 1813 __ bind(&exit); | 1812 __ bind(&exit); |
| 1814 } | 1813 } |
| 1815 | 1814 |
| 1816 | 1815 |
| 1817 void CodeGenerator::VisitTryFinally(TryFinally* node) { | 1816 void CodeGenerator::VisitTryFinally(TryFinally* node) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1884 frame_->Push(r0); | 1883 frame_->Push(r0); |
| 1885 } | 1884 } |
| 1886 __ mov(r2, Operand(Smi::FromInt(JUMPING + i))); | 1885 __ mov(r2, Operand(Smi::FromInt(JUMPING + i))); |
| 1887 __ b(&unlink); | 1886 __ b(&unlink); |
| 1888 } | 1887 } |
| 1889 } | 1888 } |
| 1890 | 1889 |
| 1891 // Unlink from try chain; | 1890 // Unlink from try chain; |
| 1892 __ bind(&unlink); | 1891 __ bind(&unlink); |
| 1893 | 1892 |
| 1894 frame_->Pop(r0); // Store TOS in r0 across stack manipulation | 1893 frame_->Pop(r0); // Preserve TOS result in r0 across stack manipulation. |
| 1895 // Reload sp from the top handler, because some statements that we | 1894 // Reload sp from the top handler, because some statements that we |
| 1896 // break from (eg, for...in) may have left stuff on the stack. | 1895 // break from (eg, for...in) may have left stuff on the stack. |
| 1897 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); | 1896 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); |
| 1898 __ ldr(sp, MemOperand(r3)); | 1897 __ ldr(sp, MemOperand(r3)); |
| 1899 const int kNextIndex = (StackHandlerConstants::kNextOffset | 1898 const int kNextIndex = (StackHandlerConstants::kNextOffset |
| 1900 + StackHandlerConstants::kAddressDisplacement) | 1899 + StackHandlerConstants::kAddressDisplacement) |
| 1901 / kPointerSize; | 1900 / kPointerSize; |
| 1902 __ ldr(r1, frame_->Element(kNextIndex)); | 1901 __ ldr(r1, frame_->Element(kNextIndex)); |
| 1903 __ str(r1, MemOperand(r3)); | 1902 __ str(r1, MemOperand(r3)); |
| 1904 ASSERT(StackHandlerConstants::kCodeOffset == 0); // first field is code | 1903 ASSERT(StackHandlerConstants::kCodeOffset == 0); // first field is code |
| 1904 // The stack pointer was restored to just below the code slot (the |
| 1905 // topmost slot) of the handler, so all but the code slot need to be |
| 1906 // dropped. |
| 1905 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); | 1907 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); |
| 1906 // Code slot popped. | 1908 // Restore result to TOS. |
| 1907 frame_->Push(r0); | 1909 frame_->Push(r0); |
| 1908 | 1910 |
| 1909 // --- Finally block --- | 1911 // --- Finally block --- |
| 1910 __ bind(&finally_block); | 1912 __ bind(&finally_block); |
| 1911 | 1913 |
| 1912 // Push the state on the stack. | 1914 // Push the state on the stack. |
| 1913 frame_->Push(r2); | 1915 frame_->Push(r2); |
| 1914 | 1916 |
| 1915 // We keep two elements on the stack - the (possibly faked) result | 1917 // We keep two elements on the stack - the (possibly faked) result |
| 1916 // and the state - while evaluating the finally block. Record it, so | 1918 // and the state - while evaluating the finally block. Record it, so |
| 1917 // that a break/continue crossing this statement can restore the | 1919 // that a break/continue crossing this statement can restore the |
| 1918 // stack. | 1920 // stack. |
| 1919 const int kFinallyStackSize = 2 * kPointerSize; | 1921 const int kFinallyStackSize = 2 * kPointerSize; |
| 1920 break_stack_height_ += kFinallyStackSize; | 1922 break_stack_height_ += kFinallyStackSize; |
| 1921 | 1923 |
| 1922 // Generate code for the statements in the finally block. | 1924 // Generate code for the statements in the finally block. |
| 1923 VisitStatements(node->finally_block()->statements()); | 1925 VisitStatements(node->finally_block()->statements()); |
| 1924 | 1926 |
| 1925 // Restore state and return value or faked TOS. | 1927 // Restore state and return value or faked TOS. |
| 1926 frame_->Pop(r2); | 1928 frame_->Pop(r2); |
| 1927 frame_->Pop(r0); | 1929 frame_->Pop(r0); |
| 1928 break_stack_height_ -= kFinallyStackSize; | 1930 break_stack_height_ -= kFinallyStackSize; |
| 1929 | 1931 |
| 1930 // Generate code to jump to the right destination for all used (formerly) | 1932 // Generate code to jump to the right destination for all used (formerly) |
| 1931 // shadowing labels. | 1933 // shadowing labels. |
| 1932 for (int i = 0; i <= nof_escapes; i++) { | 1934 for (int i = 0; i <= nof_escapes; i++) { |
| 1933 if (shadows[i]->is_bound()) { | 1935 if (shadows[i]->is_bound()) { |
| 1934 __ cmp(r2, Operand(Smi::FromInt(JUMPING + i))); | 1936 __ cmp(r2, Operand(Smi::FromInt(JUMPING + i))); |
| 1935 if (shadows[i]->original_label() != &function_return_) { | 1937 __ b(eq, shadows[i]->original_label()); |
| 1936 Label next; | |
| 1937 __ b(ne, &next); | |
| 1938 __ b(shadows[i]->original_label()); | |
| 1939 __ bind(&next); | |
| 1940 } else { | |
| 1941 __ b(eq, shadows[i]->original_label()); | |
| 1942 } | |
| 1943 } | 1938 } |
| 1944 } | 1939 } |
| 1945 | 1940 |
| 1946 // Check if we need to rethrow the exception. | 1941 // Check if we need to rethrow the exception. |
| 1947 __ cmp(r2, Operand(Smi::FromInt(THROWING))); | 1942 __ cmp(r2, Operand(Smi::FromInt(THROWING))); |
| 1948 __ b(ne, &exit); | 1943 __ b(ne, &exit); |
| 1949 | 1944 |
| 1950 // Rethrow exception. | 1945 // Rethrow exception. |
| 1951 frame_->Push(r0); | 1946 frame_->Push(r0); |
| 1952 __ CallRuntime(Runtime::kReThrow, 1); | 1947 __ CallRuntime(Runtime::kReThrow, 1); |
| (...skipping 2505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4458 __ mov(r2, Operand(0)); | 4453 __ mov(r2, Operand(0)); |
| 4459 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 4454 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); |
| 4460 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), | 4455 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), |
| 4461 RelocInfo::CODE_TARGET); | 4456 RelocInfo::CODE_TARGET); |
| 4462 } | 4457 } |
| 4463 | 4458 |
| 4464 | 4459 |
| 4465 #undef __ | 4460 #undef __ |
| 4466 | 4461 |
| 4467 } } // namespace v8::internal | 4462 } } // namespace v8::internal |
| OLD | NEW |