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 |