| 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 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 733 __ mov(edx, eax); | 733 __ mov(edx, eax); |
| 734 __ mov(eax, isolate()->factory()->the_hole_value()); | 734 __ mov(eax, isolate()->factory()->the_hole_value()); |
| 735 } | 735 } |
| 736 ASSERT(prop->key()->AsLiteral() != NULL && | 736 ASSERT(prop->key()->AsLiteral() != NULL && |
| 737 prop->key()->AsLiteral()->handle()->IsSmi()); | 737 prop->key()->AsLiteral()->handle()->IsSmi()); |
| 738 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); | 738 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); |
| 739 | 739 |
| 740 Handle<Code> ic = is_strict_mode() | 740 Handle<Code> ic = is_strict_mode() |
| 741 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 741 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 742 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 742 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 743 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 743 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); |
| 744 } | 744 } |
| 745 } | 745 } |
| 746 } | 746 } |
| 747 | 747 |
| 748 | 748 |
| 749 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 749 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
| 750 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 750 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
| 751 } | 751 } |
| 752 | 752 |
| 753 | 753 |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1104 } | 1104 } |
| 1105 | 1105 |
| 1106 // All extension objects were empty and it is safe to use a global | 1106 // All extension objects were empty and it is safe to use a global |
| 1107 // load IC call. | 1107 // load IC call. |
| 1108 __ mov(eax, GlobalObjectOperand()); | 1108 __ mov(eax, GlobalObjectOperand()); |
| 1109 __ mov(ecx, slot->var()->name()); | 1109 __ mov(ecx, slot->var()->name()); |
| 1110 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1110 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1111 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1111 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
| 1112 ? RelocInfo::CODE_TARGET | 1112 ? RelocInfo::CODE_TARGET |
| 1113 : RelocInfo::CODE_TARGET_CONTEXT; | 1113 : RelocInfo::CODE_TARGET_CONTEXT; |
| 1114 EmitCallIC(ic, mode); | 1114 EmitCallIC(ic, mode, AstNode::kNoNumber); |
| 1115 } | 1115 } |
| 1116 | 1116 |
| 1117 | 1117 |
| 1118 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( | 1118 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( |
| 1119 Slot* slot, | 1119 Slot* slot, |
| 1120 Label* slow) { | 1120 Label* slow) { |
| 1121 ASSERT(slot->type() == Slot::CONTEXT); | 1121 ASSERT(slot->type() == Slot::CONTEXT); |
| 1122 Register context = esi; | 1122 Register context = esi; |
| 1123 Register temp = ebx; | 1123 Register temp = ebx; |
| 1124 | 1124 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1208 Slot* slot = var->AsSlot(); | 1208 Slot* slot = var->AsSlot(); |
| 1209 Property* property = var->AsProperty(); | 1209 Property* property = var->AsProperty(); |
| 1210 | 1210 |
| 1211 if (var->is_global() && !var->is_this()) { | 1211 if (var->is_global() && !var->is_this()) { |
| 1212 Comment cmnt(masm_, "Global variable"); | 1212 Comment cmnt(masm_, "Global variable"); |
| 1213 // Use inline caching. Variable name is passed in ecx and the global | 1213 // Use inline caching. Variable name is passed in ecx and the global |
| 1214 // object on the stack. | 1214 // object on the stack. |
| 1215 __ mov(eax, GlobalObjectOperand()); | 1215 __ mov(eax, GlobalObjectOperand()); |
| 1216 __ mov(ecx, var->name()); | 1216 __ mov(ecx, var->name()); |
| 1217 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1217 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1218 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1218 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); |
| 1219 context()->Plug(eax); | 1219 context()->Plug(eax); |
| 1220 | 1220 |
| 1221 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 1221 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
| 1222 Label done, slow; | 1222 Label done, slow; |
| 1223 | 1223 |
| 1224 // Generate code for loading from variables potentially shadowed | 1224 // Generate code for loading from variables potentially shadowed |
| 1225 // by eval-introduced variables. | 1225 // by eval-introduced variables. |
| 1226 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); | 1226 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); |
| 1227 | 1227 |
| 1228 __ bind(&slow); | 1228 __ bind(&slow); |
| (...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1784 } | 1784 } |
| 1785 case NAMED_PROPERTY: { | 1785 case NAMED_PROPERTY: { |
| 1786 __ push(eax); // Preserve value. | 1786 __ push(eax); // Preserve value. |
| 1787 VisitForAccumulatorValue(prop->obj()); | 1787 VisitForAccumulatorValue(prop->obj()); |
| 1788 __ mov(edx, eax); | 1788 __ mov(edx, eax); |
| 1789 __ pop(eax); // Restore value. | 1789 __ pop(eax); // Restore value. |
| 1790 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 1790 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
| 1791 Handle<Code> ic = is_strict_mode() | 1791 Handle<Code> ic = is_strict_mode() |
| 1792 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1792 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 1793 : isolate()->builtins()->StoreIC_Initialize(); | 1793 : isolate()->builtins()->StoreIC_Initialize(); |
| 1794 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1794 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); |
| 1795 break; | 1795 break; |
| 1796 } | 1796 } |
| 1797 case KEYED_PROPERTY: { | 1797 case KEYED_PROPERTY: { |
| 1798 __ push(eax); // Preserve value. | 1798 __ push(eax); // Preserve value. |
| 1799 if (prop->is_synthetic()) { | 1799 if (prop->is_synthetic()) { |
| 1800 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 1800 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
| 1801 ASSERT(prop->key()->AsLiteral() != NULL); | 1801 ASSERT(prop->key()->AsLiteral() != NULL); |
| 1802 { AccumulatorValueContext for_object(this); | 1802 { AccumulatorValueContext for_object(this); |
| 1803 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); | 1803 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); |
| 1804 } | 1804 } |
| 1805 __ mov(edx, eax); | 1805 __ mov(edx, eax); |
| 1806 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); | 1806 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); |
| 1807 } else { | 1807 } else { |
| 1808 VisitForStackValue(prop->obj()); | 1808 VisitForStackValue(prop->obj()); |
| 1809 VisitForAccumulatorValue(prop->key()); | 1809 VisitForAccumulatorValue(prop->key()); |
| 1810 __ mov(ecx, eax); | 1810 __ mov(ecx, eax); |
| 1811 __ pop(edx); | 1811 __ pop(edx); |
| 1812 } | 1812 } |
| 1813 __ pop(eax); // Restore value. | 1813 __ pop(eax); // Restore value. |
| 1814 Handle<Code> ic = is_strict_mode() | 1814 Handle<Code> ic = is_strict_mode() |
| 1815 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 1815 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 1816 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 1816 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 1817 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1817 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); |
| 1818 break; | 1818 break; |
| 1819 } | 1819 } |
| 1820 } | 1820 } |
| 1821 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1821 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
| 1822 context()->Plug(eax); | 1822 context()->Plug(eax); |
| 1823 } | 1823 } |
| 1824 | 1824 |
| 1825 | 1825 |
| 1826 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1826 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 1827 Token::Value op) { | 1827 Token::Value op) { |
| 1828 // Left-hand sides that rewrite to explicit property accesses do not reach | 1828 // Left-hand sides that rewrite to explicit property accesses do not reach |
| 1829 // here. | 1829 // here. |
| 1830 ASSERT(var != NULL); | 1830 ASSERT(var != NULL); |
| 1831 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1831 ASSERT(var->is_global() || var->AsSlot() != NULL); |
| 1832 | 1832 |
| 1833 if (var->is_global()) { | 1833 if (var->is_global()) { |
| 1834 ASSERT(!var->is_this()); | 1834 ASSERT(!var->is_this()); |
| 1835 // Assignment to a global variable. Use inline caching for the | 1835 // Assignment to a global variable. Use inline caching for the |
| 1836 // assignment. Right-hand-side value is passed in eax, variable name in | 1836 // assignment. Right-hand-side value is passed in eax, variable name in |
| 1837 // ecx, and the global object on the stack. | 1837 // ecx, and the global object on the stack. |
| 1838 __ mov(ecx, var->name()); | 1838 __ mov(ecx, var->name()); |
| 1839 __ mov(edx, GlobalObjectOperand()); | 1839 __ mov(edx, GlobalObjectOperand()); |
| 1840 Handle<Code> ic = is_strict_mode() | 1840 Handle<Code> ic = is_strict_mode() |
| 1841 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1841 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 1842 : isolate()->builtins()->StoreIC_Initialize(); | 1842 : isolate()->builtins()->StoreIC_Initialize(); |
| 1843 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1843 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); |
| 1844 | 1844 |
| 1845 } else if (op == Token::INIT_CONST) { | 1845 } else if (op == Token::INIT_CONST) { |
| 1846 // Like var declarations, const declarations are hoisted to function | 1846 // Like var declarations, const declarations are hoisted to function |
| 1847 // scope. However, unlike var initializers, const initializers are able | 1847 // scope. However, unlike var initializers, const initializers are able |
| 1848 // to drill a hole to that function context, even from inside a 'with' | 1848 // to drill a hole to that function context, even from inside a 'with' |
| 1849 // context. We thus bypass the normal static scope lookup. | 1849 // context. We thus bypass the normal static scope lookup. |
| 1850 Slot* slot = var->AsSlot(); | 1850 Slot* slot = var->AsSlot(); |
| 1851 Label skip; | 1851 Label skip; |
| 1852 switch (slot->type()) { | 1852 switch (slot->type()) { |
| 1853 case Slot::PARAMETER: | 1853 case Slot::PARAMETER: |
| (...skipping 2122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3976 ASSERT(!context()->IsEffect()); | 3976 ASSERT(!context()->IsEffect()); |
| 3977 ASSERT(!context()->IsTest()); | 3977 ASSERT(!context()->IsTest()); |
| 3978 | 3978 |
| 3979 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { | 3979 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { |
| 3980 Comment cmnt(masm_, "Global variable"); | 3980 Comment cmnt(masm_, "Global variable"); |
| 3981 __ mov(eax, GlobalObjectOperand()); | 3981 __ mov(eax, GlobalObjectOperand()); |
| 3982 __ mov(ecx, Immediate(proxy->name())); | 3982 __ mov(ecx, Immediate(proxy->name())); |
| 3983 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 3983 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 3984 // Use a regular load, not a contextual load, to avoid a reference | 3984 // Use a regular load, not a contextual load, to avoid a reference |
| 3985 // error. | 3985 // error. |
| 3986 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3986 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); |
| 3987 PrepareForBailout(expr, TOS_REG); | 3987 PrepareForBailout(expr, TOS_REG); |
| 3988 context()->Plug(eax); | 3988 context()->Plug(eax); |
| 3989 } else if (proxy != NULL && | 3989 } else if (proxy != NULL && |
| 3990 proxy->var()->AsSlot() != NULL && | 3990 proxy->var()->AsSlot() != NULL && |
| 3991 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { | 3991 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { |
| 3992 Label done, slow; | 3992 Label done, slow; |
| 3993 | 3993 |
| 3994 // Generate code for loading from variables potentially shadowed | 3994 // Generate code for loading from variables potentially shadowed |
| 3995 // by eval-introduced variables. | 3995 // by eval-introduced variables. |
| 3996 Slot* slot = proxy->var()->AsSlot(); | 3996 Slot* slot = proxy->var()->AsSlot(); |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4334 // And return. | 4334 // And return. |
| 4335 __ ret(0); | 4335 __ ret(0); |
| 4336 } | 4336 } |
| 4337 | 4337 |
| 4338 | 4338 |
| 4339 #undef __ | 4339 #undef __ |
| 4340 | 4340 |
| 4341 } } // namespace v8::internal | 4341 } } // namespace v8::internal |
| 4342 | 4342 |
| 4343 #endif // V8_TARGET_ARCH_IA32 | 4343 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |