| 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 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 725 VisitForAccumulatorValue(function); | 725 VisitForAccumulatorValue(function); |
| 726 __ pop(edx); | 726 __ pop(edx); |
| 727 } else { | 727 } else { |
| 728 __ mov(edx, eax); | 728 __ mov(edx, eax); |
| 729 __ mov(eax, isolate()->factory()->the_hole_value()); | 729 __ mov(eax, isolate()->factory()->the_hole_value()); |
| 730 } | 730 } |
| 731 ASSERT(prop->key()->AsLiteral() != NULL && | 731 ASSERT(prop->key()->AsLiteral() != NULL && |
| 732 prop->key()->AsLiteral()->handle()->IsSmi()); | 732 prop->key()->AsLiteral()->handle()->IsSmi()); |
| 733 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); | 733 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); |
| 734 | 734 |
| 735 Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode() | 735 Builtins::Name builtin = is_strict_mode() |
| 736 ? Builtins::KeyedStoreIC_Initialize_Strict | 736 ? Builtins::KeyedStoreIC_Initialize_Strict |
| 737 : Builtins::KeyedStoreIC_Initialize)); | 737 : Builtins::KeyedStoreIC_Initialize; |
| 738 Handle<Code> ic = Builtins::builtin(builtin, isolate()); |
| 738 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 739 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 739 } | 740 } |
| 740 } | 741 } |
| 741 } | 742 } |
| 742 | 743 |
| 743 | 744 |
| 744 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 745 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
| 745 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 746 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
| 746 } | 747 } |
| 747 | 748 |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1095 __ mov(temp, ContextOperand(temp, Context::CLOSURE_INDEX)); | 1096 __ mov(temp, ContextOperand(temp, Context::CLOSURE_INDEX)); |
| 1096 __ mov(temp, FieldOperand(temp, JSFunction::kContextOffset)); | 1097 __ mov(temp, FieldOperand(temp, JSFunction::kContextOffset)); |
| 1097 __ jmp(&next); | 1098 __ jmp(&next); |
| 1098 __ bind(&fast); | 1099 __ bind(&fast); |
| 1099 } | 1100 } |
| 1100 | 1101 |
| 1101 // All extension objects were empty and it is safe to use a global | 1102 // All extension objects were empty and it is safe to use a global |
| 1102 // load IC call. | 1103 // load IC call. |
| 1103 __ mov(eax, GlobalObjectOperand()); | 1104 __ mov(eax, GlobalObjectOperand()); |
| 1104 __ mov(ecx, slot->var()->name()); | 1105 __ mov(ecx, slot->var()->name()); |
| 1105 Handle<Code> ic(isolate()->builtins()->builtin( | 1106 Handle<Code> ic = Builtins::builtin(Builtins::LoadIC_Initialize, isolate()); |
| 1106 Builtins::LoadIC_Initialize)); | |
| 1107 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1107 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
| 1108 ? RelocInfo::CODE_TARGET | 1108 ? RelocInfo::CODE_TARGET |
| 1109 : RelocInfo::CODE_TARGET_CONTEXT; | 1109 : RelocInfo::CODE_TARGET_CONTEXT; |
| 1110 EmitCallIC(ic, mode); | 1110 EmitCallIC(ic, mode); |
| 1111 } | 1111 } |
| 1112 | 1112 |
| 1113 | 1113 |
| 1114 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( | 1114 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( |
| 1115 Slot* slot, | 1115 Slot* slot, |
| 1116 Label* slow) { | 1116 Label* slow) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1179 key_literal != NULL && | 1179 key_literal != NULL && |
| 1180 obj_proxy->IsArguments() && | 1180 obj_proxy->IsArguments() && |
| 1181 key_literal->handle()->IsSmi()) { | 1181 key_literal->handle()->IsSmi()) { |
| 1182 // Load arguments object if there are no eval-introduced | 1182 // Load arguments object if there are no eval-introduced |
| 1183 // variables. Then load the argument from the arguments | 1183 // variables. Then load the argument from the arguments |
| 1184 // object using keyed load. | 1184 // object using keyed load. |
| 1185 __ mov(edx, | 1185 __ mov(edx, |
| 1186 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), | 1186 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), |
| 1187 slow)); | 1187 slow)); |
| 1188 __ mov(eax, Immediate(key_literal->handle())); | 1188 __ mov(eax, Immediate(key_literal->handle())); |
| 1189 Handle<Code> ic(isolate()->builtins()->builtin( | 1189 Handle<Code> ic = |
| 1190 Builtins::KeyedLoadIC_Initialize)); | 1190 Builtins::builtin(Builtins::KeyedLoadIC_Initialize, isolate()); |
| 1191 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1191 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1192 __ jmp(done); | 1192 __ jmp(done); |
| 1193 } | 1193 } |
| 1194 } | 1194 } |
| 1195 } | 1195 } |
| 1196 } | 1196 } |
| 1197 } | 1197 } |
| 1198 | 1198 |
| 1199 | 1199 |
| 1200 void FullCodeGenerator::EmitVariableLoad(Variable* var) { | 1200 void FullCodeGenerator::EmitVariableLoad(Variable* var) { |
| 1201 // Four cases: non-this global variables, lookup slots, all other | 1201 // Four cases: non-this global variables, lookup slots, all other |
| 1202 // types of slots, and parameters that rewrite to explicit property | 1202 // types of slots, and parameters that rewrite to explicit property |
| 1203 // accesses on the arguments object. | 1203 // accesses on the arguments object. |
| 1204 Slot* slot = var->AsSlot(); | 1204 Slot* slot = var->AsSlot(); |
| 1205 Property* property = var->AsProperty(); | 1205 Property* property = var->AsProperty(); |
| 1206 | 1206 |
| 1207 if (var->is_global() && !var->is_this()) { | 1207 if (var->is_global() && !var->is_this()) { |
| 1208 Comment cmnt(masm_, "Global variable"); | 1208 Comment cmnt(masm_, "Global variable"); |
| 1209 // Use inline caching. Variable name is passed in ecx and the global | 1209 // Use inline caching. Variable name is passed in ecx and the global |
| 1210 // object on the stack. | 1210 // object on the stack. |
| 1211 __ mov(eax, GlobalObjectOperand()); | 1211 __ mov(eax, GlobalObjectOperand()); |
| 1212 __ mov(ecx, var->name()); | 1212 __ mov(ecx, var->name()); |
| 1213 Handle<Code> ic(isolate()->builtins()->builtin( | 1213 Handle<Code> ic = |
| 1214 Builtins::LoadIC_Initialize)); | 1214 Builtins::builtin(Builtins::LoadIC_Initialize, isolate()); |
| 1215 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1215 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1216 context()->Plug(eax); | 1216 context()->Plug(eax); |
| 1217 | 1217 |
| 1218 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 1218 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
| 1219 Label done, slow; | 1219 Label done, slow; |
| 1220 | 1220 |
| 1221 // Generate code for loading from variables potentially shadowed | 1221 // Generate code for loading from variables potentially shadowed |
| 1222 // by eval-introduced variables. | 1222 // by eval-introduced variables. |
| 1223 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); | 1223 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); |
| 1224 | 1224 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1267 | 1267 |
| 1268 // Assert that the key is a smi. | 1268 // Assert that the key is a smi. |
| 1269 Literal* key_literal = property->key()->AsLiteral(); | 1269 Literal* key_literal = property->key()->AsLiteral(); |
| 1270 ASSERT_NOT_NULL(key_literal); | 1270 ASSERT_NOT_NULL(key_literal); |
| 1271 ASSERT(key_literal->handle()->IsSmi()); | 1271 ASSERT(key_literal->handle()->IsSmi()); |
| 1272 | 1272 |
| 1273 // Load the key. | 1273 // Load the key. |
| 1274 __ mov(eax, Immediate(key_literal->handle())); | 1274 __ mov(eax, Immediate(key_literal->handle())); |
| 1275 | 1275 |
| 1276 // Do a keyed property load. | 1276 // Do a keyed property load. |
| 1277 Handle<Code> ic(isolate()->builtins()->builtin( | 1277 Handle<Code> ic = Builtins::builtin(Builtins::KeyedLoadIC_Initialize, |
| 1278 Builtins::KeyedLoadIC_Initialize)); | 1278 isolate()); |
| 1279 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1279 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1280 | 1280 |
| 1281 // Drop key and object left on the stack by IC. | 1281 // Drop key and object left on the stack by IC. |
| 1282 context()->Plug(eax); | 1282 context()->Plug(eax); |
| 1283 } | 1283 } |
| 1284 } | 1284 } |
| 1285 | 1285 |
| 1286 | 1286 |
| 1287 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1287 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 1288 Comment cmnt(masm_, "[ RegExpLiteral"); | 1288 Comment cmnt(masm_, "[ RegExpLiteral"); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1379 switch (property->kind()) { | 1379 switch (property->kind()) { |
| 1380 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1380 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1381 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 1381 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
| 1382 // Fall through. | 1382 // Fall through. |
| 1383 case ObjectLiteral::Property::COMPUTED: | 1383 case ObjectLiteral::Property::COMPUTED: |
| 1384 if (key->handle()->IsSymbol()) { | 1384 if (key->handle()->IsSymbol()) { |
| 1385 if (property->emit_store()) { | 1385 if (property->emit_store()) { |
| 1386 VisitForAccumulatorValue(value); | 1386 VisitForAccumulatorValue(value); |
| 1387 __ mov(ecx, Immediate(key->handle())); | 1387 __ mov(ecx, Immediate(key->handle())); |
| 1388 __ mov(edx, Operand(esp, 0)); | 1388 __ mov(edx, Operand(esp, 0)); |
| 1389 Handle<Code> ic(isolate()->builtins()->builtin( | 1389 Builtins::Name builtin = is_strict_mode() |
| 1390 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 1390 ? Builtins::StoreIC_Initialize_Strict |
| 1391 : Builtins::StoreIC_Initialize)); | 1391 : Builtins::StoreIC_Initialize; |
| 1392 Handle<Code> ic = Builtins::builtin(builtin, isolate()); |
| 1392 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1393 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1393 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1394 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1394 } else { | 1395 } else { |
| 1395 VisitForEffect(value); | 1396 VisitForEffect(value); |
| 1396 } | 1397 } |
| 1397 break; | 1398 break; |
| 1398 } | 1399 } |
| 1399 // Fall through. | 1400 // Fall through. |
| 1400 case ObjectLiteral::Property::PROTOTYPE: | 1401 case ObjectLiteral::Property::PROTOTYPE: |
| 1401 __ push(Operand(esp, 0)); // Duplicate receiver. | 1402 __ push(Operand(esp, 0)); // Duplicate receiver. |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1630 EmitKeyedPropertyAssignment(expr); | 1631 EmitKeyedPropertyAssignment(expr); |
| 1631 break; | 1632 break; |
| 1632 } | 1633 } |
| 1633 } | 1634 } |
| 1634 | 1635 |
| 1635 | 1636 |
| 1636 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1637 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 1637 SetSourcePosition(prop->position()); | 1638 SetSourcePosition(prop->position()); |
| 1638 Literal* key = prop->key()->AsLiteral(); | 1639 Literal* key = prop->key()->AsLiteral(); |
| 1639 __ mov(ecx, Immediate(key->handle())); | 1640 __ mov(ecx, Immediate(key->handle())); |
| 1640 Handle<Code> ic(isolate()->builtins()->builtin( | 1641 Handle<Code> ic = Builtins::builtin(Builtins::LoadIC_Initialize, isolate()); |
| 1641 Builtins::LoadIC_Initialize)); | |
| 1642 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1642 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1643 } | 1643 } |
| 1644 | 1644 |
| 1645 | 1645 |
| 1646 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1646 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 1647 SetSourcePosition(prop->position()); | 1647 SetSourcePosition(prop->position()); |
| 1648 Handle<Code> ic(isolate()->builtins()->builtin( | 1648 Handle<Code> ic = |
| 1649 Builtins::KeyedLoadIC_Initialize)); | 1649 Builtins::builtin(Builtins::KeyedLoadIC_Initialize, isolate()); |
| 1650 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1650 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1651 } | 1651 } |
| 1652 | 1652 |
| 1653 | 1653 |
| 1654 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, | 1654 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, |
| 1655 Token::Value op, | 1655 Token::Value op, |
| 1656 OverwriteMode mode, | 1656 OverwriteMode mode, |
| 1657 Expression* left, | 1657 Expression* left, |
| 1658 Expression* right) { | 1658 Expression* right) { |
| 1659 // Do combined smi check of the operands. Left operand is on the | 1659 // Do combined smi check of the operands. Left operand is on the |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1780 EffectContext context(this); | 1780 EffectContext context(this); |
| 1781 EmitVariableAssignment(var, Token::ASSIGN); | 1781 EmitVariableAssignment(var, Token::ASSIGN); |
| 1782 break; | 1782 break; |
| 1783 } | 1783 } |
| 1784 case NAMED_PROPERTY: { | 1784 case NAMED_PROPERTY: { |
| 1785 __ push(eax); // Preserve value. | 1785 __ push(eax); // Preserve value. |
| 1786 VisitForAccumulatorValue(prop->obj()); | 1786 VisitForAccumulatorValue(prop->obj()); |
| 1787 __ mov(edx, eax); | 1787 __ mov(edx, eax); |
| 1788 __ pop(eax); // Restore value. | 1788 __ pop(eax); // Restore value. |
| 1789 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 1789 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
| 1790 Handle<Code> ic(isolate()->builtins()->builtin( | 1790 Builtins::Name builtin = is_strict_mode() |
| 1791 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 1791 ? Builtins::StoreIC_Initialize_Strict |
| 1792 : Builtins::StoreIC_Initialize)); | 1792 : Builtins::StoreIC_Initialize; |
| 1793 Handle<Code> ic = Builtins::builtin(builtin, isolate()); |
| 1793 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1794 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1794 break; | 1795 break; |
| 1795 } | 1796 } |
| 1796 case KEYED_PROPERTY: { | 1797 case KEYED_PROPERTY: { |
| 1797 __ push(eax); // Preserve value. | 1798 __ push(eax); // Preserve value. |
| 1798 if (prop->is_synthetic()) { | 1799 if (prop->is_synthetic()) { |
| 1799 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 1800 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
| 1800 ASSERT(prop->key()->AsLiteral() != NULL); | 1801 ASSERT(prop->key()->AsLiteral() != NULL); |
| 1801 { AccumulatorValueContext for_object(this); | 1802 { AccumulatorValueContext for_object(this); |
| 1802 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); | 1803 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); |
| 1803 } | 1804 } |
| 1804 __ mov(edx, eax); | 1805 __ mov(edx, eax); |
| 1805 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); | 1806 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); |
| 1806 } else { | 1807 } else { |
| 1807 VisitForStackValue(prop->obj()); | 1808 VisitForStackValue(prop->obj()); |
| 1808 VisitForAccumulatorValue(prop->key()); | 1809 VisitForAccumulatorValue(prop->key()); |
| 1809 __ mov(ecx, eax); | 1810 __ mov(ecx, eax); |
| 1810 __ pop(edx); | 1811 __ pop(edx); |
| 1811 } | 1812 } |
| 1812 __ pop(eax); // Restore value. | 1813 __ pop(eax); // Restore value. |
| 1813 Handle<Code> ic(isolate()->builtins()->builtin( | 1814 Builtins::Name builtin = is_strict_mode() |
| 1814 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 1815 ? Builtins::KeyedStoreIC_Initialize_Strict |
| 1815 : Builtins::KeyedStoreIC_Initialize)); | 1816 : Builtins::KeyedStoreIC_Initialize; |
| 1817 Handle<Code> ic = Builtins::builtin(builtin, isolate()); |
| 1816 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1818 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1817 break; | 1819 break; |
| 1818 } | 1820 } |
| 1819 } | 1821 } |
| 1820 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1822 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
| 1821 context()->Plug(eax); | 1823 context()->Plug(eax); |
| 1822 } | 1824 } |
| 1823 | 1825 |
| 1824 | 1826 |
| 1825 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1827 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 1826 Token::Value op) { | 1828 Token::Value op) { |
| 1827 // Left-hand sides that rewrite to explicit property accesses do not reach | 1829 // Left-hand sides that rewrite to explicit property accesses do not reach |
| 1828 // here. | 1830 // here. |
| 1829 ASSERT(var != NULL); | 1831 ASSERT(var != NULL); |
| 1830 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1832 ASSERT(var->is_global() || var->AsSlot() != NULL); |
| 1831 | 1833 |
| 1832 if (var->is_global()) { | 1834 if (var->is_global()) { |
| 1833 ASSERT(!var->is_this()); | 1835 ASSERT(!var->is_this()); |
| 1834 // Assignment to a global variable. Use inline caching for the | 1836 // Assignment to a global variable. Use inline caching for the |
| 1835 // assignment. Right-hand-side value is passed in eax, variable name in | 1837 // assignment. Right-hand-side value is passed in eax, variable name in |
| 1836 // ecx, and the global object on the stack. | 1838 // ecx, and the global object on the stack. |
| 1837 __ mov(ecx, var->name()); | 1839 __ mov(ecx, var->name()); |
| 1838 __ mov(edx, GlobalObjectOperand()); | 1840 __ mov(edx, GlobalObjectOperand()); |
| 1839 Handle<Code> ic(isolate()->builtins()->builtin( | 1841 Builtins::Name builtin = is_strict_mode() |
| 1840 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 1842 ? Builtins::StoreIC_Initialize_Strict |
| 1841 : Builtins::StoreIC_Initialize)); | 1843 : Builtins::StoreIC_Initialize; |
| 1844 Handle<Code> ic = Builtins::builtin(builtin, isolate()); |
| 1842 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1845 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1843 | 1846 |
| 1844 } else if (op == Token::INIT_CONST) { | 1847 } else if (op == Token::INIT_CONST) { |
| 1845 // Like var declarations, const declarations are hoisted to function | 1848 // Like var declarations, const declarations are hoisted to function |
| 1846 // scope. However, unlike var initializers, const initializers are able | 1849 // scope. However, unlike var initializers, const initializers are able |
| 1847 // to drill a hole to that function context, even from inside a 'with' | 1850 // to drill a hole to that function context, even from inside a 'with' |
| 1848 // context. We thus bypass the normal static scope lookup. | 1851 // context. We thus bypass the normal static scope lookup. |
| 1849 Slot* slot = var->AsSlot(); | 1852 Slot* slot = var->AsSlot(); |
| 1850 Label skip; | 1853 Label skip; |
| 1851 switch (slot->type()) { | 1854 switch (slot->type()) { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1932 } | 1935 } |
| 1933 | 1936 |
| 1934 // Record source code position before IC call. | 1937 // Record source code position before IC call. |
| 1935 SetSourcePosition(expr->position()); | 1938 SetSourcePosition(expr->position()); |
| 1936 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 1939 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
| 1937 if (expr->ends_initialization_block()) { | 1940 if (expr->ends_initialization_block()) { |
| 1938 __ mov(edx, Operand(esp, 0)); | 1941 __ mov(edx, Operand(esp, 0)); |
| 1939 } else { | 1942 } else { |
| 1940 __ pop(edx); | 1943 __ pop(edx); |
| 1941 } | 1944 } |
| 1942 Handle<Code> ic(isolate()->builtins()->builtin( | 1945 Builtins::Name builtin = is_strict_mode() |
| 1943 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 1946 ? Builtins::StoreIC_Initialize_Strict |
| 1944 : Builtins::StoreIC_Initialize)); | 1947 : Builtins::StoreIC_Initialize; |
| 1948 Handle<Code> ic = Builtins::builtin(builtin, isolate()); |
| 1945 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1949 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1946 | 1950 |
| 1947 // If the assignment ends an initialization block, revert to fast case. | 1951 // If the assignment ends an initialization block, revert to fast case. |
| 1948 if (expr->ends_initialization_block()) { | 1952 if (expr->ends_initialization_block()) { |
| 1949 __ push(eax); // Result of assignment, saved even if not needed. | 1953 __ push(eax); // Result of assignment, saved even if not needed. |
| 1950 __ push(Operand(esp, kPointerSize)); // Receiver is under value. | 1954 __ push(Operand(esp, kPointerSize)); // Receiver is under value. |
| 1951 __ CallRuntime(Runtime::kToFastProperties, 1); | 1955 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1952 __ pop(eax); | 1956 __ pop(eax); |
| 1953 __ Drop(1); | 1957 __ Drop(1); |
| 1954 } | 1958 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1972 } | 1976 } |
| 1973 | 1977 |
| 1974 __ pop(ecx); | 1978 __ pop(ecx); |
| 1975 if (expr->ends_initialization_block()) { | 1979 if (expr->ends_initialization_block()) { |
| 1976 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. | 1980 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. |
| 1977 } else { | 1981 } else { |
| 1978 __ pop(edx); | 1982 __ pop(edx); |
| 1979 } | 1983 } |
| 1980 // Record source code position before IC call. | 1984 // Record source code position before IC call. |
| 1981 SetSourcePosition(expr->position()); | 1985 SetSourcePosition(expr->position()); |
| 1982 Handle<Code> ic(isolate()->builtins()->builtin( | 1986 Builtins::Name builtin = is_strict_mode() |
| 1983 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 1987 ? Builtins::KeyedStoreIC_Initialize_Strict |
| 1984 : Builtins::KeyedStoreIC_Initialize)); | 1988 : Builtins::KeyedStoreIC_Initialize; |
| 1989 Handle<Code> ic = Builtins::builtin(builtin, isolate()); |
| 1985 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1990 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1986 | 1991 |
| 1987 // If the assignment ends an initialization block, revert to fast case. | 1992 // If the assignment ends an initialization block, revert to fast case. |
| 1988 if (expr->ends_initialization_block()) { | 1993 if (expr->ends_initialization_block()) { |
| 1989 __ pop(edx); | 1994 __ pop(edx); |
| 1990 __ push(eax); // Result of assignment, saved even if not needed. | 1995 __ push(eax); // Result of assignment, saved even if not needed. |
| 1991 __ push(edx); | 1996 __ push(edx); |
| 1992 __ CallRuntime(Runtime::kToFastProperties, 1); | 1997 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1993 __ pop(eax); | 1998 __ pop(eax); |
| 1994 } | 1999 } |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2250 MemOperand operand = EmitSlotSearch(slot, edx); | 2255 MemOperand operand = EmitSlotSearch(slot, edx); |
| 2251 __ mov(edx, operand); | 2256 __ mov(edx, operand); |
| 2252 | 2257 |
| 2253 ASSERT(prop->key()->AsLiteral() != NULL); | 2258 ASSERT(prop->key()->AsLiteral() != NULL); |
| 2254 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); | 2259 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); |
| 2255 __ mov(eax, prop->key()->AsLiteral()->handle()); | 2260 __ mov(eax, prop->key()->AsLiteral()->handle()); |
| 2256 | 2261 |
| 2257 // Record source code position for IC call. | 2262 // Record source code position for IC call. |
| 2258 SetSourcePosition(prop->position()); | 2263 SetSourcePosition(prop->position()); |
| 2259 | 2264 |
| 2260 Handle<Code> ic(isolate()->builtins()->builtin( | 2265 Handle<Code> ic = |
| 2261 Builtins::KeyedLoadIC_Initialize)); | 2266 Builtins::builtin(Builtins::KeyedLoadIC_Initialize, isolate()); |
| 2262 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2267 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 2263 // Push result (function). | 2268 // Push result (function). |
| 2264 __ push(eax); | 2269 __ push(eax); |
| 2265 // Push Global receiver. | 2270 // Push Global receiver. |
| 2266 __ mov(ecx, GlobalObjectOperand()); | 2271 __ mov(ecx, GlobalObjectOperand()); |
| 2267 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); | 2272 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); |
| 2268 EmitCallWithStub(expr); | 2273 EmitCallWithStub(expr); |
| 2269 } else { | 2274 } else { |
| 2270 { PreservePositionScope scope(masm()->positions_recorder()); | 2275 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2271 VisitForStackValue(prop->obj()); | 2276 VisitForStackValue(prop->obj()); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2319 } | 2324 } |
| 2320 | 2325 |
| 2321 // Call the construct call builtin that handles allocation and | 2326 // Call the construct call builtin that handles allocation and |
| 2322 // constructor invocation. | 2327 // constructor invocation. |
| 2323 SetSourcePosition(expr->position()); | 2328 SetSourcePosition(expr->position()); |
| 2324 | 2329 |
| 2325 // Load function and argument count into edi and eax. | 2330 // Load function and argument count into edi and eax. |
| 2326 __ Set(eax, Immediate(arg_count)); | 2331 __ Set(eax, Immediate(arg_count)); |
| 2327 __ mov(edi, Operand(esp, arg_count * kPointerSize)); | 2332 __ mov(edi, Operand(esp, arg_count * kPointerSize)); |
| 2328 | 2333 |
| 2329 Handle<Code> construct_builtin(isolate()->builtins()->builtin( | 2334 Handle<Code> construct_builtin = |
| 2330 Builtins::JSConstructCall)); | 2335 Builtins::builtin(Builtins::JSConstructCall, isolate()); |
| 2331 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL); | 2336 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL); |
| 2332 context()->Plug(eax); | 2337 context()->Plug(eax); |
| 2333 } | 2338 } |
| 2334 | 2339 |
| 2335 | 2340 |
| 2336 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { | 2341 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { |
| 2337 ASSERT(args->length() == 1); | 2342 ASSERT(args->length() == 1); |
| 2338 | 2343 |
| 2339 VisitForAccumulatorValue(args->at(0)); | 2344 VisitForAccumulatorValue(args->at(0)); |
| 2340 | 2345 |
| (...skipping 1525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3866 // Perform the assignment as if via '='. | 3871 // Perform the assignment as if via '='. |
| 3867 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3872 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 3868 Token::ASSIGN); | 3873 Token::ASSIGN); |
| 3869 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3874 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3870 context()->Plug(eax); | 3875 context()->Plug(eax); |
| 3871 } | 3876 } |
| 3872 break; | 3877 break; |
| 3873 case NAMED_PROPERTY: { | 3878 case NAMED_PROPERTY: { |
| 3874 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 3879 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
| 3875 __ pop(edx); | 3880 __ pop(edx); |
| 3876 Handle<Code> ic(isolate()->builtins()->builtin( | 3881 Builtins::Name builtin = is_strict_mode() |
| 3877 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 3882 ? Builtins::StoreIC_Initialize_Strict |
| 3878 : Builtins::StoreIC_Initialize)); | 3883 : Builtins::StoreIC_Initialize; |
| 3884 Handle<Code> ic = Builtins::builtin(builtin, isolate()); |
| 3879 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3885 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3880 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3886 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3881 if (expr->is_postfix()) { | 3887 if (expr->is_postfix()) { |
| 3882 if (!context()->IsEffect()) { | 3888 if (!context()->IsEffect()) { |
| 3883 context()->PlugTOS(); | 3889 context()->PlugTOS(); |
| 3884 } | 3890 } |
| 3885 } else { | 3891 } else { |
| 3886 context()->Plug(eax); | 3892 context()->Plug(eax); |
| 3887 } | 3893 } |
| 3888 break; | 3894 break; |
| 3889 } | 3895 } |
| 3890 case KEYED_PROPERTY: { | 3896 case KEYED_PROPERTY: { |
| 3891 __ pop(ecx); | 3897 __ pop(ecx); |
| 3892 __ pop(edx); | 3898 __ pop(edx); |
| 3893 Handle<Code> ic(isolate()->builtins()->builtin( | 3899 Builtins::Name builtin = is_strict_mode() |
| 3894 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 3900 ? Builtins::KeyedStoreIC_Initialize_Strict |
| 3895 : Builtins::KeyedStoreIC_Initialize)); | 3901 : Builtins::KeyedStoreIC_Initialize; |
| 3902 Handle<Code> ic = Builtins::builtin(builtin, isolate()); |
| 3896 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3903 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3897 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3904 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3898 if (expr->is_postfix()) { | 3905 if (expr->is_postfix()) { |
| 3899 // Result is on the stack | 3906 // Result is on the stack |
| 3900 if (!context()->IsEffect()) { | 3907 if (!context()->IsEffect()) { |
| 3901 context()->PlugTOS(); | 3908 context()->PlugTOS(); |
| 3902 } | 3909 } |
| 3903 } else { | 3910 } else { |
| 3904 context()->Plug(eax); | 3911 context()->Plug(eax); |
| 3905 } | 3912 } |
| 3906 break; | 3913 break; |
| 3907 } | 3914 } |
| 3908 } | 3915 } |
| 3909 } | 3916 } |
| 3910 | 3917 |
| 3911 | 3918 |
| 3912 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 3919 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 3913 VariableProxy* proxy = expr->AsVariableProxy(); | 3920 VariableProxy* proxy = expr->AsVariableProxy(); |
| 3914 ASSERT(!context()->IsEffect()); | 3921 ASSERT(!context()->IsEffect()); |
| 3915 ASSERT(!context()->IsTest()); | 3922 ASSERT(!context()->IsTest()); |
| 3916 | 3923 |
| 3917 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { | 3924 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { |
| 3918 Comment cmnt(masm_, "Global variable"); | 3925 Comment cmnt(masm_, "Global variable"); |
| 3919 __ mov(eax, GlobalObjectOperand()); | 3926 __ mov(eax, GlobalObjectOperand()); |
| 3920 __ mov(ecx, Immediate(proxy->name())); | 3927 __ mov(ecx, Immediate(proxy->name())); |
| 3921 Handle<Code> ic(isolate()->builtins()->builtin( | 3928 Handle<Code> ic = Builtins::builtin(Builtins::LoadIC_Initialize, isolate()); |
| 3922 Builtins::LoadIC_Initialize)); | |
| 3923 // Use a regular load, not a contextual load, to avoid a reference | 3929 // Use a regular load, not a contextual load, to avoid a reference |
| 3924 // error. | 3930 // error. |
| 3925 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3931 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3926 PrepareForBailout(expr, TOS_REG); | 3932 PrepareForBailout(expr, TOS_REG); |
| 3927 context()->Plug(eax); | 3933 context()->Plug(eax); |
| 3928 } else if (proxy != NULL && | 3934 } else if (proxy != NULL && |
| 3929 proxy->var()->AsSlot() != NULL && | 3935 proxy->var()->AsSlot() != NULL && |
| 3930 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { | 3936 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { |
| 3931 Label done, slow; | 3937 Label done, slow; |
| 3932 | 3938 |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4292 // And return. | 4298 // And return. |
| 4293 __ ret(0); | 4299 __ ret(0); |
| 4294 } | 4300 } |
| 4295 | 4301 |
| 4296 | 4302 |
| 4297 #undef __ | 4303 #undef __ |
| 4298 | 4304 |
| 4299 } } // namespace v8::internal | 4305 } } // namespace v8::internal |
| 4300 | 4306 |
| 4301 #endif // V8_TARGET_ARCH_IA32 | 4307 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |