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 |