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 |