| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 VisitForAccumulatorValue(function); | 720 VisitForAccumulatorValue(function); |
| 721 __ pop(edx); | 721 __ pop(edx); |
| 722 } else { | 722 } else { |
| 723 __ mov(edx, eax); | 723 __ mov(edx, eax); |
| 724 __ mov(eax, Factory::the_hole_value()); | 724 __ mov(eax, Factory::the_hole_value()); |
| 725 } | 725 } |
| 726 ASSERT(prop->key()->AsLiteral() != NULL && | 726 ASSERT(prop->key()->AsLiteral() != NULL && |
| 727 prop->key()->AsLiteral()->handle()->IsSmi()); | 727 prop->key()->AsLiteral()->handle()->IsSmi()); |
| 728 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); | 728 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); |
| 729 | 729 |
| 730 Handle<Code> ic(Builtins::builtin(is_strict() | 730 Handle<Code> ic(Builtins::builtin( |
| 731 ? Builtins::KeyedStoreIC_Initialize_Strict | 731 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 732 : Builtins::KeyedStoreIC_Initialize)); | 732 : Builtins::KeyedStoreIC_Initialize)); |
| 733 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 733 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 734 } | 734 } |
| 735 } | 735 } |
| 736 } | 736 } |
| 737 | 737 |
| 738 | 738 |
| 739 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 739 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
| 740 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 740 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
| 741 } | 741 } |
| 742 | 742 |
| (...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1365 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1365 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1366 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 1366 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
| 1367 // Fall through. | 1367 // Fall through. |
| 1368 case ObjectLiteral::Property::COMPUTED: | 1368 case ObjectLiteral::Property::COMPUTED: |
| 1369 if (key->handle()->IsSymbol()) { | 1369 if (key->handle()->IsSymbol()) { |
| 1370 if (property->emit_store()) { | 1370 if (property->emit_store()) { |
| 1371 VisitForAccumulatorValue(value); | 1371 VisitForAccumulatorValue(value); |
| 1372 __ mov(ecx, Immediate(key->handle())); | 1372 __ mov(ecx, Immediate(key->handle())); |
| 1373 __ mov(edx, Operand(esp, 0)); | 1373 __ mov(edx, Operand(esp, 0)); |
| 1374 Handle<Code> ic(Builtins::builtin( | 1374 Handle<Code> ic(Builtins::builtin( |
| 1375 is_strict() ? Builtins::StoreIC_Initialize_Strict | 1375 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
| 1376 : Builtins::StoreIC_Initialize)); | 1376 : Builtins::StoreIC_Initialize)); |
| 1377 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1377 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1378 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1378 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1379 } else { | 1379 } else { |
| 1380 VisitForEffect(value); | 1380 VisitForEffect(value); |
| 1381 } | 1381 } |
| 1382 break; | 1382 break; |
| 1383 } | 1383 } |
| 1384 // Fall through. | 1384 // Fall through. |
| 1385 case ObjectLiteral::Property::PROTOTYPE: | 1385 case ObjectLiteral::Property::PROTOTYPE: |
| 1386 __ push(Operand(esp, 0)); // Duplicate receiver. | 1386 __ push(Operand(esp, 0)); // Duplicate receiver. |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1757 EmitVariableAssignment(var, Token::ASSIGN); | 1757 EmitVariableAssignment(var, Token::ASSIGN); |
| 1758 break; | 1758 break; |
| 1759 } | 1759 } |
| 1760 case NAMED_PROPERTY: { | 1760 case NAMED_PROPERTY: { |
| 1761 __ push(eax); // Preserve value. | 1761 __ push(eax); // Preserve value. |
| 1762 VisitForAccumulatorValue(prop->obj()); | 1762 VisitForAccumulatorValue(prop->obj()); |
| 1763 __ mov(edx, eax); | 1763 __ mov(edx, eax); |
| 1764 __ pop(eax); // Restore value. | 1764 __ pop(eax); // Restore value. |
| 1765 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 1765 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
| 1766 Handle<Code> ic(Builtins::builtin( | 1766 Handle<Code> ic(Builtins::builtin( |
| 1767 is_strict() ? Builtins::StoreIC_Initialize_Strict | 1767 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
| 1768 : Builtins::StoreIC_Initialize)); | 1768 : Builtins::StoreIC_Initialize)); |
| 1769 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1769 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1770 break; | 1770 break; |
| 1771 } | 1771 } |
| 1772 case KEYED_PROPERTY: { | 1772 case KEYED_PROPERTY: { |
| 1773 __ push(eax); // Preserve value. | 1773 __ push(eax); // Preserve value. |
| 1774 if (prop->is_synthetic()) { | 1774 if (prop->is_synthetic()) { |
| 1775 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 1775 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
| 1776 ASSERT(prop->key()->AsLiteral() != NULL); | 1776 ASSERT(prop->key()->AsLiteral() != NULL); |
| 1777 { AccumulatorValueContext for_object(this); | 1777 { AccumulatorValueContext for_object(this); |
| 1778 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); | 1778 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); |
| 1779 } | 1779 } |
| 1780 __ mov(edx, eax); | 1780 __ mov(edx, eax); |
| 1781 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); | 1781 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); |
| 1782 } else { | 1782 } else { |
| 1783 VisitForStackValue(prop->obj()); | 1783 VisitForStackValue(prop->obj()); |
| 1784 VisitForAccumulatorValue(prop->key()); | 1784 VisitForAccumulatorValue(prop->key()); |
| 1785 __ mov(ecx, eax); | 1785 __ mov(ecx, eax); |
| 1786 __ pop(edx); | 1786 __ pop(edx); |
| 1787 } | 1787 } |
| 1788 __ pop(eax); // Restore value. | 1788 __ pop(eax); // Restore value. |
| 1789 Handle<Code> ic(Builtins::builtin( | 1789 Handle<Code> ic(Builtins::builtin( |
| 1790 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict | 1790 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 1791 : Builtins::KeyedStoreIC_Initialize)); | 1791 : Builtins::KeyedStoreIC_Initialize)); |
| 1792 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1792 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1793 break; | 1793 break; |
| 1794 } | 1794 } |
| 1795 } | 1795 } |
| 1796 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1796 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
| 1797 context()->Plug(eax); | 1797 context()->Plug(eax); |
| 1798 } | 1798 } |
| 1799 | 1799 |
| 1800 | 1800 |
| 1801 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1801 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 1802 Token::Value op) { | 1802 Token::Value op) { |
| 1803 // Left-hand sides that rewrite to explicit property accesses do not reach | 1803 // Left-hand sides that rewrite to explicit property accesses do not reach |
| 1804 // here. | 1804 // here. |
| 1805 ASSERT(var != NULL); | 1805 ASSERT(var != NULL); |
| 1806 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1806 ASSERT(var->is_global() || var->AsSlot() != NULL); |
| 1807 | 1807 |
| 1808 if (var->is_global()) { | 1808 if (var->is_global()) { |
| 1809 ASSERT(!var->is_this()); | 1809 ASSERT(!var->is_this()); |
| 1810 // Assignment to a global variable. Use inline caching for the | 1810 // Assignment to a global variable. Use inline caching for the |
| 1811 // assignment. Right-hand-side value is passed in eax, variable name in | 1811 // assignment. Right-hand-side value is passed in eax, variable name in |
| 1812 // ecx, and the global object on the stack. | 1812 // ecx, and the global object on the stack. |
| 1813 __ mov(ecx, var->name()); | 1813 __ mov(ecx, var->name()); |
| 1814 __ mov(edx, GlobalObjectOperand()); | 1814 __ mov(edx, GlobalObjectOperand()); |
| 1815 Handle<Code> ic(Builtins::builtin( | 1815 Handle<Code> ic(Builtins::builtin( |
| 1816 is_strict() ? Builtins::StoreIC_Initialize_Strict | 1816 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
| 1817 : Builtins::StoreIC_Initialize)); | 1817 : Builtins::StoreIC_Initialize)); |
| 1818 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1818 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1819 | 1819 |
| 1820 } else if (op == Token::INIT_CONST) { | 1820 } else if (op == Token::INIT_CONST) { |
| 1821 // Like var declarations, const declarations are hoisted to function | 1821 // Like var declarations, const declarations are hoisted to function |
| 1822 // scope. However, unlike var initializers, const initializers are able | 1822 // scope. However, unlike var initializers, const initializers are able |
| 1823 // to drill a hole to that function context, even from inside a 'with' | 1823 // to drill a hole to that function context, even from inside a 'with' |
| 1824 // context. We thus bypass the normal static scope lookup. | 1824 // context. We thus bypass the normal static scope lookup. |
| 1825 Slot* slot = var->AsSlot(); | 1825 Slot* slot = var->AsSlot(); |
| 1826 Label skip; | 1826 Label skip; |
| 1827 switch (slot->type()) { | 1827 switch (slot->type()) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1909 | 1909 |
| 1910 // Record source code position before IC call. | 1910 // Record source code position before IC call. |
| 1911 SetSourcePosition(expr->position()); | 1911 SetSourcePosition(expr->position()); |
| 1912 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 1912 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
| 1913 if (expr->ends_initialization_block()) { | 1913 if (expr->ends_initialization_block()) { |
| 1914 __ mov(edx, Operand(esp, 0)); | 1914 __ mov(edx, Operand(esp, 0)); |
| 1915 } else { | 1915 } else { |
| 1916 __ pop(edx); | 1916 __ pop(edx); |
| 1917 } | 1917 } |
| 1918 Handle<Code> ic(Builtins::builtin( | 1918 Handle<Code> ic(Builtins::builtin( |
| 1919 is_strict() ? Builtins::StoreIC_Initialize_Strict | 1919 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
| 1920 : Builtins::StoreIC_Initialize)); | 1920 : Builtins::StoreIC_Initialize)); |
| 1921 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1921 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1922 | 1922 |
| 1923 // If the assignment ends an initialization block, revert to fast case. | 1923 // If the assignment ends an initialization block, revert to fast case. |
| 1924 if (expr->ends_initialization_block()) { | 1924 if (expr->ends_initialization_block()) { |
| 1925 __ push(eax); // Result of assignment, saved even if not needed. | 1925 __ push(eax); // Result of assignment, saved even if not needed. |
| 1926 __ push(Operand(esp, kPointerSize)); // Receiver is under value. | 1926 __ push(Operand(esp, kPointerSize)); // Receiver is under value. |
| 1927 __ CallRuntime(Runtime::kToFastProperties, 1); | 1927 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1928 __ pop(eax); | 1928 __ pop(eax); |
| 1929 __ Drop(1); | 1929 __ Drop(1); |
| 1930 } | 1930 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1949 | 1949 |
| 1950 __ pop(ecx); | 1950 __ pop(ecx); |
| 1951 if (expr->ends_initialization_block()) { | 1951 if (expr->ends_initialization_block()) { |
| 1952 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. | 1952 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. |
| 1953 } else { | 1953 } else { |
| 1954 __ pop(edx); | 1954 __ pop(edx); |
| 1955 } | 1955 } |
| 1956 // Record source code position before IC call. | 1956 // Record source code position before IC call. |
| 1957 SetSourcePosition(expr->position()); | 1957 SetSourcePosition(expr->position()); |
| 1958 Handle<Code> ic(Builtins::builtin( | 1958 Handle<Code> ic(Builtins::builtin( |
| 1959 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict | 1959 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 1960 : Builtins::KeyedStoreIC_Initialize)); | 1960 : Builtins::KeyedStoreIC_Initialize)); |
| 1961 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1961 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1962 | 1962 |
| 1963 // If the assignment ends an initialization block, revert to fast case. | 1963 // If the assignment ends an initialization block, revert to fast case. |
| 1964 if (expr->ends_initialization_block()) { | 1964 if (expr->ends_initialization_block()) { |
| 1965 __ pop(edx); | 1965 __ pop(edx); |
| 1966 __ push(eax); // Result of assignment, saved even if not needed. | 1966 __ push(eax); // Result of assignment, saved even if not needed. |
| 1967 __ push(edx); | 1967 __ push(edx); |
| 1968 __ CallRuntime(Runtime::kToFastProperties, 1); | 1968 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1969 __ pop(eax); | 1969 __ pop(eax); |
| 1970 } | 1970 } |
| (...skipping 1865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3836 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3836 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 3837 Token::ASSIGN); | 3837 Token::ASSIGN); |
| 3838 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3838 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3839 context()->Plug(eax); | 3839 context()->Plug(eax); |
| 3840 } | 3840 } |
| 3841 break; | 3841 break; |
| 3842 case NAMED_PROPERTY: { | 3842 case NAMED_PROPERTY: { |
| 3843 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 3843 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
| 3844 __ pop(edx); | 3844 __ pop(edx); |
| 3845 Handle<Code> ic(Builtins::builtin( | 3845 Handle<Code> ic(Builtins::builtin( |
| 3846 is_strict() ? Builtins::StoreIC_Initialize_Strict | 3846 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
| 3847 : Builtins::StoreIC_Initialize)); | 3847 : Builtins::StoreIC_Initialize)); |
| 3848 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3848 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3849 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3849 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3850 if (expr->is_postfix()) { | 3850 if (expr->is_postfix()) { |
| 3851 if (!context()->IsEffect()) { | 3851 if (!context()->IsEffect()) { |
| 3852 context()->PlugTOS(); | 3852 context()->PlugTOS(); |
| 3853 } | 3853 } |
| 3854 } else { | 3854 } else { |
| 3855 context()->Plug(eax); | 3855 context()->Plug(eax); |
| 3856 } | 3856 } |
| 3857 break; | 3857 break; |
| 3858 } | 3858 } |
| 3859 case KEYED_PROPERTY: { | 3859 case KEYED_PROPERTY: { |
| 3860 __ pop(ecx); | 3860 __ pop(ecx); |
| 3861 __ pop(edx); | 3861 __ pop(edx); |
| 3862 Handle<Code> ic(Builtins::builtin( | 3862 Handle<Code> ic(Builtins::builtin( |
| 3863 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict | 3863 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 3864 : Builtins::KeyedStoreIC_Initialize)); | 3864 : Builtins::KeyedStoreIC_Initialize)); |
| 3865 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3865 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3866 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3866 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3867 if (expr->is_postfix()) { | 3867 if (expr->is_postfix()) { |
| 3868 // Result is on the stack | 3868 // Result is on the stack |
| 3869 if (!context()->IsEffect()) { | 3869 if (!context()->IsEffect()) { |
| 3870 context()->PlugTOS(); | 3870 context()->PlugTOS(); |
| 3871 } | 3871 } |
| 3872 } else { | 3872 } else { |
| 3873 context()->Plug(eax); | 3873 context()->Plug(eax); |
| 3874 } | 3874 } |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4260 // And return. | 4260 // And return. |
| 4261 __ ret(0); | 4261 __ ret(0); |
| 4262 } | 4262 } |
| 4263 | 4263 |
| 4264 | 4264 |
| 4265 #undef __ | 4265 #undef __ |
| 4266 | 4266 |
| 4267 } } // namespace v8::internal | 4267 } } // namespace v8::internal |
| 4268 | 4268 |
| 4269 #endif // V8_TARGET_ARCH_IA32 | 4269 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |