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