| 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 |