OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 __ CallRuntime(Runtime::kDeclareContextSlot, 4); | 734 __ CallRuntime(Runtime::kDeclareContextSlot, 4); |
735 break; | 735 break; |
736 } | 736 } |
737 } | 737 } |
738 | 738 |
739 } else if (prop != NULL) { | 739 } else if (prop != NULL) { |
740 if (decl->fun() != NULL || decl->mode() == Variable::CONST) { | 740 if (decl->fun() != NULL || decl->mode() == Variable::CONST) { |
741 // We are declaring a function or constant that rewrites to a | 741 // We are declaring a function or constant that rewrites to a |
742 // property. Use (keyed) IC to set the initial value. | 742 // property. Use (keyed) IC to set the initial value. |
743 VisitForValue(prop->obj(), kStack); | 743 VisitForValue(prop->obj(), kStack); |
744 VisitForValue(prop->key(), kStack); | |
745 | |
746 if (decl->fun() != NULL) { | 744 if (decl->fun() != NULL) { |
| 745 VisitForValue(prop->key(), kStack); |
747 VisitForValue(decl->fun(), kAccumulator); | 746 VisitForValue(decl->fun(), kAccumulator); |
| 747 __ pop(ecx); |
748 } else { | 748 } else { |
| 749 VisitForValue(prop->key(), kAccumulator); |
| 750 __ mov(ecx, result_register()); |
749 __ mov(result_register(), Factory::the_hole_value()); | 751 __ mov(result_register(), Factory::the_hole_value()); |
750 } | 752 } |
| 753 __ pop(edx); |
751 | 754 |
752 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 755 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
753 __ call(ic, RelocInfo::CODE_TARGET); | 756 __ call(ic, RelocInfo::CODE_TARGET); |
754 // Absence of a test eax instruction following the call | 757 // Absence of a test eax instruction following the call |
755 // indicates that none of the load was inlined. | 758 // indicates that none of the load was inlined. |
756 __ nop(); | 759 __ nop(); |
757 | |
758 // Value in eax is ignored (declarations are statements). Receiver | |
759 // and key on stack are discarded. | |
760 __ Drop(2); | |
761 } | 760 } |
762 } | 761 } |
763 } | 762 } |
764 | 763 |
765 | 764 |
766 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 765 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
767 // Call the runtime to declare the globals. | 766 // Call the runtime to declare the globals. |
768 __ push(esi); // The context is the first argument. | 767 __ push(esi); // The context is the first argument. |
769 __ push(Immediate(pairs)); | 768 __ push(Immediate(pairs)); |
770 __ push(Immediate(Smi::FromInt(is_eval() ? 1 : 0))); | 769 __ push(Immediate(Smi::FromInt(is_eval() ? 1 : 0))); |
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1244 // change to slow case to avoid the quadratic behavior of repeatedly | 1243 // change to slow case to avoid the quadratic behavior of repeatedly |
1245 // adding fast properties. | 1244 // adding fast properties. |
1246 if (expr->starts_initialization_block()) { | 1245 if (expr->starts_initialization_block()) { |
1247 __ push(result_register()); | 1246 __ push(result_register()); |
1248 // Receiver is now under the key and value. | 1247 // Receiver is now under the key and value. |
1249 __ push(Operand(esp, 2 * kPointerSize)); | 1248 __ push(Operand(esp, 2 * kPointerSize)); |
1250 __ CallRuntime(Runtime::kToSlowProperties, 1); | 1249 __ CallRuntime(Runtime::kToSlowProperties, 1); |
1251 __ pop(result_register()); | 1250 __ pop(result_register()); |
1252 } | 1251 } |
1253 | 1252 |
| 1253 __ pop(ecx); |
| 1254 if (expr->ends_initialization_block()) { |
| 1255 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. |
| 1256 } else { |
| 1257 __ pop(edx); |
| 1258 } |
1254 // Record source code position before IC call. | 1259 // Record source code position before IC call. |
1255 SetSourcePosition(expr->position()); | 1260 SetSourcePosition(expr->position()); |
1256 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 1261 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
1257 __ call(ic, RelocInfo::CODE_TARGET); | 1262 __ call(ic, RelocInfo::CODE_TARGET); |
1258 // This nop signals to the IC that there is no inlined code at the call | 1263 // This nop signals to the IC that there is no inlined code at the call |
1259 // site for it to patch. | 1264 // site for it to patch. |
1260 __ nop(); | 1265 __ nop(); |
1261 | 1266 |
1262 // If the assignment ends an initialization block, revert to fast case. | 1267 // If the assignment ends an initialization block, revert to fast case. |
1263 if (expr->ends_initialization_block()) { | 1268 if (expr->ends_initialization_block()) { |
| 1269 __ pop(edx); |
1264 __ push(eax); // Result of assignment, saved even if not needed. | 1270 __ push(eax); // Result of assignment, saved even if not needed. |
1265 // Receiver is under the key and value. | 1271 __ push(edx); |
1266 __ push(Operand(esp, 2 * kPointerSize)); | |
1267 __ CallRuntime(Runtime::kToFastProperties, 1); | 1272 __ CallRuntime(Runtime::kToFastProperties, 1); |
1268 __ pop(eax); | 1273 __ pop(eax); |
1269 } | 1274 } |
1270 | 1275 |
1271 // Receiver and key are still on stack. | 1276 Apply(context_, eax); |
1272 DropAndApply(2, context_, eax); | |
1273 } | 1277 } |
1274 | 1278 |
1275 | 1279 |
1276 void FullCodeGenerator::VisitProperty(Property* expr) { | 1280 void FullCodeGenerator::VisitProperty(Property* expr) { |
1277 Comment cmnt(masm_, "[ Property"); | 1281 Comment cmnt(masm_, "[ Property"); |
1278 Expression* key = expr->key(); | 1282 Expression* key = expr->key(); |
1279 | 1283 |
1280 if (key->IsPropertyName()) { | 1284 if (key->IsPropertyName()) { |
1281 VisitForValue(expr->obj(), kAccumulator); | 1285 VisitForValue(expr->obj(), kAccumulator); |
1282 EmitNamedPropertyLoad(expr); | 1286 EmitNamedPropertyLoad(expr); |
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1770 if (expr->is_postfix()) { | 1774 if (expr->is_postfix()) { |
1771 if (context_ != Expression::kEffect) { | 1775 if (context_ != Expression::kEffect) { |
1772 ApplyTOS(context_); | 1776 ApplyTOS(context_); |
1773 } | 1777 } |
1774 } else { | 1778 } else { |
1775 Apply(context_, eax); | 1779 Apply(context_, eax); |
1776 } | 1780 } |
1777 break; | 1781 break; |
1778 } | 1782 } |
1779 case KEYED_PROPERTY: { | 1783 case KEYED_PROPERTY: { |
| 1784 __ pop(ecx); |
| 1785 __ pop(edx); |
1780 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 1786 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
1781 __ call(ic, RelocInfo::CODE_TARGET); | 1787 __ call(ic, RelocInfo::CODE_TARGET); |
1782 // This nop signals to the IC that there is no inlined code at the call | 1788 // This nop signals to the IC that there is no inlined code at the call |
1783 // site for it to patch. | 1789 // site for it to patch. |
1784 __ nop(); | 1790 __ nop(); |
1785 if (expr->is_postfix()) { | 1791 if (expr->is_postfix()) { |
1786 __ Drop(2); // Result is on the stack under the key and the receiver. | 1792 // Result is on the stack |
1787 if (context_ != Expression::kEffect) { | 1793 if (context_ != Expression::kEffect) { |
1788 ApplyTOS(context_); | 1794 ApplyTOS(context_); |
1789 } | 1795 } |
1790 } else { | 1796 } else { |
1791 DropAndApply(2, context_, eax); | 1797 Apply(context_, eax); |
1792 } | 1798 } |
1793 break; | 1799 break; |
1794 } | 1800 } |
1795 } | 1801 } |
1796 } | 1802 } |
1797 | 1803 |
1798 | 1804 |
1799 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { | 1805 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { |
1800 Comment cmnt(masm_, "[ BinaryOperation"); | 1806 Comment cmnt(masm_, "[ BinaryOperation"); |
1801 switch (expr->op()) { | 1807 switch (expr->op()) { |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1996 __ add(Operand(edx), Immediate(masm_->CodeObject())); | 2002 __ add(Operand(edx), Immediate(masm_->CodeObject())); |
1997 __ mov(Operand(esp, 0), edx); | 2003 __ mov(Operand(esp, 0), edx); |
1998 // And return. | 2004 // And return. |
1999 __ ret(0); | 2005 __ ret(0); |
2000 } | 2006 } |
2001 | 2007 |
2002 | 2008 |
2003 #undef __ | 2009 #undef __ |
2004 | 2010 |
2005 } } // namespace v8::internal | 2011 } } // namespace v8::internal |
OLD | NEW |