| 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 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 722 VisitForAccumulatorValue(function); | 722 VisitForAccumulatorValue(function); |
| 723 __ pop(edx); | 723 __ pop(edx); |
| 724 } else { | 724 } else { |
| 725 __ mov(edx, eax); | 725 __ mov(edx, eax); |
| 726 __ mov(eax, isolate()->factory()->the_hole_value()); | 726 __ mov(eax, isolate()->factory()->the_hole_value()); |
| 727 } | 727 } |
| 728 ASSERT(prop->key()->AsLiteral() != NULL && | 728 ASSERT(prop->key()->AsLiteral() != NULL && |
| 729 prop->key()->AsLiteral()->handle()->IsSmi()); | 729 prop->key()->AsLiteral()->handle()->IsSmi()); |
| 730 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); | 730 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); |
| 731 | 731 |
| 732 Handle<Code> ic(isolate()->builtins()->builtin(is_strict() | 732 Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode() |
| 733 ? Builtins::KeyedStoreIC_Initialize_Strict | 733 ? Builtins::KeyedStoreIC_Initialize_Strict |
| 734 : Builtins::KeyedStoreIC_Initialize)); | 734 : Builtins::KeyedStoreIC_Initialize)); |
| 735 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 735 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 736 } | 736 } |
| 737 } | 737 } |
| 738 } | 738 } |
| 739 | 739 |
| 740 | 740 |
| 741 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 741 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
| 742 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 742 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
| (...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1371 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1371 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1372 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 1372 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
| 1373 // Fall through. | 1373 // Fall through. |
| 1374 case ObjectLiteral::Property::COMPUTED: | 1374 case ObjectLiteral::Property::COMPUTED: |
| 1375 if (key->handle()->IsSymbol()) { | 1375 if (key->handle()->IsSymbol()) { |
| 1376 if (property->emit_store()) { | 1376 if (property->emit_store()) { |
| 1377 VisitForAccumulatorValue(value); | 1377 VisitForAccumulatorValue(value); |
| 1378 __ mov(ecx, Immediate(key->handle())); | 1378 __ mov(ecx, Immediate(key->handle())); |
| 1379 __ mov(edx, Operand(esp, 0)); | 1379 __ mov(edx, Operand(esp, 0)); |
| 1380 Handle<Code> ic(isolate()->builtins()->builtin( | 1380 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1381 is_strict() ? Builtins::StoreIC_Initialize_Strict | 1381 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
| 1382 : Builtins::StoreIC_Initialize)); | 1382 : Builtins::StoreIC_Initialize)); |
| 1383 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1383 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1384 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1384 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1385 } else { | 1385 } else { |
| 1386 VisitForEffect(value); | 1386 VisitForEffect(value); |
| 1387 } | 1387 } |
| 1388 break; | 1388 break; |
| 1389 } | 1389 } |
| 1390 // Fall through. | 1390 // Fall through. |
| 1391 case ObjectLiteral::Property::PROTOTYPE: | 1391 case ObjectLiteral::Property::PROTOTYPE: |
| 1392 __ push(Operand(esp, 0)); // Duplicate receiver. | 1392 __ push(Operand(esp, 0)); // Duplicate receiver. |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1766 EmitVariableAssignment(var, Token::ASSIGN); | 1766 EmitVariableAssignment(var, Token::ASSIGN); |
| 1767 break; | 1767 break; |
| 1768 } | 1768 } |
| 1769 case NAMED_PROPERTY: { | 1769 case NAMED_PROPERTY: { |
| 1770 __ push(eax); // Preserve value. | 1770 __ push(eax); // Preserve value. |
| 1771 VisitForAccumulatorValue(prop->obj()); | 1771 VisitForAccumulatorValue(prop->obj()); |
| 1772 __ mov(edx, eax); | 1772 __ mov(edx, eax); |
| 1773 __ pop(eax); // Restore value. | 1773 __ pop(eax); // Restore value. |
| 1774 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 1774 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
| 1775 Handle<Code> ic(isolate()->builtins()->builtin( | 1775 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1776 is_strict() ? Builtins::StoreIC_Initialize_Strict | 1776 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
| 1777 : Builtins::StoreIC_Initialize)); | 1777 : Builtins::StoreIC_Initialize)); |
| 1778 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1778 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1779 break; | 1779 break; |
| 1780 } | 1780 } |
| 1781 case KEYED_PROPERTY: { | 1781 case KEYED_PROPERTY: { |
| 1782 __ push(eax); // Preserve value. | 1782 __ push(eax); // Preserve value. |
| 1783 if (prop->is_synthetic()) { | 1783 if (prop->is_synthetic()) { |
| 1784 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 1784 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
| 1785 ASSERT(prop->key()->AsLiteral() != NULL); | 1785 ASSERT(prop->key()->AsLiteral() != NULL); |
| 1786 { AccumulatorValueContext for_object(this); | 1786 { AccumulatorValueContext for_object(this); |
| 1787 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); | 1787 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); |
| 1788 } | 1788 } |
| 1789 __ mov(edx, eax); | 1789 __ mov(edx, eax); |
| 1790 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); | 1790 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); |
| 1791 } else { | 1791 } else { |
| 1792 VisitForStackValue(prop->obj()); | 1792 VisitForStackValue(prop->obj()); |
| 1793 VisitForAccumulatorValue(prop->key()); | 1793 VisitForAccumulatorValue(prop->key()); |
| 1794 __ mov(ecx, eax); | 1794 __ mov(ecx, eax); |
| 1795 __ pop(edx); | 1795 __ pop(edx); |
| 1796 } | 1796 } |
| 1797 __ pop(eax); // Restore value. | 1797 __ pop(eax); // Restore value. |
| 1798 Handle<Code> ic(isolate()->builtins()->builtin( | 1798 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1799 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict | 1799 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 1800 : Builtins::KeyedStoreIC_Initialize)); | 1800 : Builtins::KeyedStoreIC_Initialize)); |
| 1801 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1801 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1802 break; | 1802 break; |
| 1803 } | 1803 } |
| 1804 } | 1804 } |
| 1805 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1805 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
| 1806 context()->Plug(eax); | 1806 context()->Plug(eax); |
| 1807 } | 1807 } |
| 1808 | 1808 |
| 1809 | 1809 |
| 1810 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1810 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 1811 Token::Value op) { | 1811 Token::Value op) { |
| 1812 // Left-hand sides that rewrite to explicit property accesses do not reach | 1812 // Left-hand sides that rewrite to explicit property accesses do not reach |
| 1813 // here. | 1813 // here. |
| 1814 ASSERT(var != NULL); | 1814 ASSERT(var != NULL); |
| 1815 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1815 ASSERT(var->is_global() || var->AsSlot() != NULL); |
| 1816 | 1816 |
| 1817 if (var->is_global()) { | 1817 if (var->is_global()) { |
| 1818 ASSERT(!var->is_this()); | 1818 ASSERT(!var->is_this()); |
| 1819 // Assignment to a global variable. Use inline caching for the | 1819 // Assignment to a global variable. Use inline caching for the |
| 1820 // assignment. Right-hand-side value is passed in eax, variable name in | 1820 // assignment. Right-hand-side value is passed in eax, variable name in |
| 1821 // ecx, and the global object on the stack. | 1821 // ecx, and the global object on the stack. |
| 1822 __ mov(ecx, var->name()); | 1822 __ mov(ecx, var->name()); |
| 1823 __ mov(edx, GlobalObjectOperand()); | 1823 __ mov(edx, GlobalObjectOperand()); |
| 1824 Handle<Code> ic(isolate()->builtins()->builtin( | 1824 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1825 is_strict() ? Builtins::StoreIC_Initialize_Strict | 1825 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
| 1826 : Builtins::StoreIC_Initialize)); | 1826 : Builtins::StoreIC_Initialize)); |
| 1827 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1827 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1828 | 1828 |
| 1829 } else if (op == Token::INIT_CONST) { | 1829 } else if (op == Token::INIT_CONST) { |
| 1830 // Like var declarations, const declarations are hoisted to function | 1830 // Like var declarations, const declarations are hoisted to function |
| 1831 // scope. However, unlike var initializers, const initializers are able | 1831 // scope. However, unlike var initializers, const initializers are able |
| 1832 // to drill a hole to that function context, even from inside a 'with' | 1832 // to drill a hole to that function context, even from inside a 'with' |
| 1833 // context. We thus bypass the normal static scope lookup. | 1833 // context. We thus bypass the normal static scope lookup. |
| 1834 Slot* slot = var->AsSlot(); | 1834 Slot* slot = var->AsSlot(); |
| 1835 Label skip; | 1835 Label skip; |
| 1836 switch (slot->type()) { | 1836 switch (slot->type()) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1918 | 1918 |
| 1919 // Record source code position before IC call. | 1919 // Record source code position before IC call. |
| 1920 SetSourcePosition(expr->position()); | 1920 SetSourcePosition(expr->position()); |
| 1921 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 1921 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
| 1922 if (expr->ends_initialization_block()) { | 1922 if (expr->ends_initialization_block()) { |
| 1923 __ mov(edx, Operand(esp, 0)); | 1923 __ mov(edx, Operand(esp, 0)); |
| 1924 } else { | 1924 } else { |
| 1925 __ pop(edx); | 1925 __ pop(edx); |
| 1926 } | 1926 } |
| 1927 Handle<Code> ic(isolate()->builtins()->builtin( | 1927 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1928 is_strict() ? Builtins::StoreIC_Initialize_Strict | 1928 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
| 1929 : Builtins::StoreIC_Initialize)); | 1929 : Builtins::StoreIC_Initialize)); |
| 1930 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1930 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1931 | 1931 |
| 1932 // If the assignment ends an initialization block, revert to fast case. | 1932 // If the assignment ends an initialization block, revert to fast case. |
| 1933 if (expr->ends_initialization_block()) { | 1933 if (expr->ends_initialization_block()) { |
| 1934 __ push(eax); // Result of assignment, saved even if not needed. | 1934 __ push(eax); // Result of assignment, saved even if not needed. |
| 1935 __ push(Operand(esp, kPointerSize)); // Receiver is under value. | 1935 __ push(Operand(esp, kPointerSize)); // Receiver is under value. |
| 1936 __ CallRuntime(Runtime::kToFastProperties, 1); | 1936 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1937 __ pop(eax); | 1937 __ pop(eax); |
| 1938 __ Drop(1); | 1938 __ Drop(1); |
| 1939 } | 1939 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1958 | 1958 |
| 1959 __ pop(ecx); | 1959 __ pop(ecx); |
| 1960 if (expr->ends_initialization_block()) { | 1960 if (expr->ends_initialization_block()) { |
| 1961 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. | 1961 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. |
| 1962 } else { | 1962 } else { |
| 1963 __ pop(edx); | 1963 __ pop(edx); |
| 1964 } | 1964 } |
| 1965 // Record source code position before IC call. | 1965 // Record source code position before IC call. |
| 1966 SetSourcePosition(expr->position()); | 1966 SetSourcePosition(expr->position()); |
| 1967 Handle<Code> ic(isolate()->builtins()->builtin( | 1967 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1968 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict | 1968 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 1969 : Builtins::KeyedStoreIC_Initialize)); | 1969 : Builtins::KeyedStoreIC_Initialize)); |
| 1970 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1970 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1971 | 1971 |
| 1972 // If the assignment ends an initialization block, revert to fast case. | 1972 // If the assignment ends an initialization block, revert to fast case. |
| 1973 if (expr->ends_initialization_block()) { | 1973 if (expr->ends_initialization_block()) { |
| 1974 __ pop(edx); | 1974 __ pop(edx); |
| 1975 __ push(eax); // Result of assignment, saved even if not needed. | 1975 __ push(eax); // Result of assignment, saved even if not needed. |
| 1976 __ push(edx); | 1976 __ push(edx); |
| 1977 __ CallRuntime(Runtime::kToFastProperties, 1); | 1977 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1978 __ pop(eax); | 1978 __ pop(eax); |
| 1979 } | 1979 } |
| (...skipping 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3056 Label slow_case; | 3056 Label slow_case; |
| 3057 Register object = eax; | 3057 Register object = eax; |
| 3058 Register index_1 = ebx; | 3058 Register index_1 = ebx; |
| 3059 Register index_2 = ecx; | 3059 Register index_2 = ecx; |
| 3060 Register elements = edi; | 3060 Register elements = edi; |
| 3061 Register temp = edx; | 3061 Register temp = edx; |
| 3062 __ mov(object, Operand(esp, 2 * kPointerSize)); | 3062 __ mov(object, Operand(esp, 2 * kPointerSize)); |
| 3063 // Fetch the map and check if array is in fast case. | 3063 // Fetch the map and check if array is in fast case. |
| 3064 // Check that object doesn't require security checks and | 3064 // Check that object doesn't require security checks and |
| 3065 // has no indexed interceptor. | 3065 // has no indexed interceptor. |
| 3066 __ CmpObjectType(object, FIRST_JS_OBJECT_TYPE, temp); | 3066 __ CmpObjectType(object, JS_ARRAY_TYPE, temp); |
| 3067 __ j(below, &slow_case); | 3067 __ j(not_equal, &slow_case); |
| 3068 __ test_b(FieldOperand(temp, Map::kBitFieldOffset), | 3068 __ test_b(FieldOperand(temp, Map::kBitFieldOffset), |
| 3069 KeyedLoadIC::kSlowCaseBitFieldMask); | 3069 KeyedLoadIC::kSlowCaseBitFieldMask); |
| 3070 __ j(not_zero, &slow_case); | 3070 __ j(not_zero, &slow_case); |
| 3071 | 3071 |
| 3072 // Check the object's elements are in fast case and writable. | 3072 // Check the object's elements are in fast case and writable. |
| 3073 __ mov(elements, FieldOperand(object, JSObject::kElementsOffset)); | 3073 __ mov(elements, FieldOperand(object, JSObject::kElementsOffset)); |
| 3074 __ cmp(FieldOperand(elements, HeapObject::kMapOffset), | 3074 __ cmp(FieldOperand(elements, HeapObject::kMapOffset), |
| 3075 Immediate(isolate()->factory()->fixed_array_map())); | 3075 Immediate(isolate()->factory()->fixed_array_map())); |
| 3076 __ j(not_equal, &slow_case); | 3076 __ j(not_equal, &slow_case); |
| 3077 | 3077 |
| (...skipping 773 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3851 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3851 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 3852 Token::ASSIGN); | 3852 Token::ASSIGN); |
| 3853 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3853 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3854 context()->Plug(eax); | 3854 context()->Plug(eax); |
| 3855 } | 3855 } |
| 3856 break; | 3856 break; |
| 3857 case NAMED_PROPERTY: { | 3857 case NAMED_PROPERTY: { |
| 3858 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 3858 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
| 3859 __ pop(edx); | 3859 __ pop(edx); |
| 3860 Handle<Code> ic(isolate()->builtins()->builtin( | 3860 Handle<Code> ic(isolate()->builtins()->builtin( |
| 3861 is_strict() ? Builtins::StoreIC_Initialize_Strict | 3861 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
| 3862 : Builtins::StoreIC_Initialize)); | 3862 : Builtins::StoreIC_Initialize)); |
| 3863 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3863 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3864 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3864 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3865 if (expr->is_postfix()) { | 3865 if (expr->is_postfix()) { |
| 3866 if (!context()->IsEffect()) { | 3866 if (!context()->IsEffect()) { |
| 3867 context()->PlugTOS(); | 3867 context()->PlugTOS(); |
| 3868 } | 3868 } |
| 3869 } else { | 3869 } else { |
| 3870 context()->Plug(eax); | 3870 context()->Plug(eax); |
| 3871 } | 3871 } |
| 3872 break; | 3872 break; |
| 3873 } | 3873 } |
| 3874 case KEYED_PROPERTY: { | 3874 case KEYED_PROPERTY: { |
| 3875 __ pop(ecx); | 3875 __ pop(ecx); |
| 3876 __ pop(edx); | 3876 __ pop(edx); |
| 3877 Handle<Code> ic(isolate()->builtins()->builtin( | 3877 Handle<Code> ic(isolate()->builtins()->builtin( |
| 3878 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict | 3878 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 3879 : Builtins::KeyedStoreIC_Initialize)); | 3879 : Builtins::KeyedStoreIC_Initialize)); |
| 3880 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3880 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3881 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3881 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3882 if (expr->is_postfix()) { | 3882 if (expr->is_postfix()) { |
| 3883 // Result is on the stack | 3883 // Result is on the stack |
| 3884 if (!context()->IsEffect()) { | 3884 if (!context()->IsEffect()) { |
| 3885 context()->PlugTOS(); | 3885 context()->PlugTOS(); |
| 3886 } | 3886 } |
| 3887 } else { | 3887 } else { |
| 3888 context()->Plug(eax); | 3888 context()->Plug(eax); |
| 3889 } | 3889 } |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4276 // And return. | 4276 // And return. |
| 4277 __ ret(0); | 4277 __ ret(0); |
| 4278 } | 4278 } |
| 4279 | 4279 |
| 4280 | 4280 |
| 4281 #undef __ | 4281 #undef __ |
| 4282 | 4282 |
| 4283 } } // namespace v8::internal | 4283 } } // namespace v8::internal |
| 4284 | 4284 |
| 4285 #endif // V8_TARGET_ARCH_IA32 | 4285 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |