OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X87 | 7 #if V8_TARGET_ARCH_X87 |
8 | 8 |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 1608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1619 // If result_saved is true the result is on top of the stack. If | 1619 // If result_saved is true the result is on top of the stack. If |
1620 // result_saved is false the result is in eax. | 1620 // result_saved is false the result is in eax. |
1621 bool result_saved = false; | 1621 bool result_saved = false; |
1622 | 1622 |
1623 // Mark all computed expressions that are bound to a key that | 1623 // Mark all computed expressions that are bound to a key that |
1624 // is shadowed by a later occurrence of the same key. For the | 1624 // is shadowed by a later occurrence of the same key. For the |
1625 // marked expressions, no store code is emitted. | 1625 // marked expressions, no store code is emitted. |
1626 expr->CalculateEmitStore(zone()); | 1626 expr->CalculateEmitStore(zone()); |
1627 | 1627 |
1628 AccessorTable accessor_table(zone()); | 1628 AccessorTable accessor_table(zone()); |
1629 for (int i = 0; i < expr->properties()->length(); i++) { | 1629 int property_index = 0; |
1630 ObjectLiteral::Property* property = expr->properties()->at(i); | 1630 for (; property_index < expr->properties()->length(); property_index++) { |
| 1631 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
1631 if (property->IsCompileTimeValue()) continue; | 1632 if (property->IsCompileTimeValue()) continue; |
| 1633 if (property->kind() == ObjectLiteral::Property::COMPUTED_NAME) break; |
1632 | 1634 |
1633 Literal* key = property->key(); | 1635 Literal* key = property->key()->AsLiteral(); |
1634 Expression* value = property->value(); | 1636 Expression* value = property->value(); |
1635 if (!result_saved) { | 1637 if (!result_saved) { |
1636 __ push(eax); // Save result on the stack | 1638 __ push(eax); // Save result on the stack |
1637 result_saved = true; | 1639 result_saved = true; |
1638 } | 1640 } |
1639 switch (property->kind()) { | 1641 switch (property->kind()) { |
1640 case ObjectLiteral::Property::CONSTANT: | 1642 case ObjectLiteral::Property::CONSTANT: |
| 1643 case ObjectLiteral::Property::COMPUTED_NAME: |
1641 UNREACHABLE(); | 1644 UNREACHABLE(); |
1642 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1645 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1643 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 1646 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
1644 // Fall through. | 1647 // Fall through. |
1645 case ObjectLiteral::Property::COMPUTED: | 1648 case ObjectLiteral::Property::COMPUTED: |
1646 if (key->value()->IsInternalizedString()) { | 1649 if (key->value()->IsInternalizedString()) { |
1647 if (property->emit_store()) { | 1650 if (property->emit_store()) { |
1648 VisitForAccumulatorValue(value); | 1651 VisitForAccumulatorValue(value); |
1649 __ mov(ecx, Immediate(key->value())); | 1652 __ mov(ecx, Immediate(key->value())); |
1650 __ mov(edx, Operand(esp, 0)); | 1653 __ mov(edx, Operand(esp, 0)); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1689 it != accessor_table.end(); | 1692 it != accessor_table.end(); |
1690 ++it) { | 1693 ++it) { |
1691 __ push(Operand(esp, 0)); // Duplicate receiver. | 1694 __ push(Operand(esp, 0)); // Duplicate receiver. |
1692 VisitForStackValue(it->first); | 1695 VisitForStackValue(it->first); |
1693 EmitAccessor(it->second->getter); | 1696 EmitAccessor(it->second->getter); |
1694 EmitAccessor(it->second->setter); | 1697 EmitAccessor(it->second->setter); |
1695 __ push(Immediate(Smi::FromInt(NONE))); | 1698 __ push(Immediate(Smi::FromInt(NONE))); |
1696 __ CallRuntime(Runtime::kDefineOrRedefineAccessorProperty, 5); | 1699 __ CallRuntime(Runtime::kDefineOrRedefineAccessorProperty, 5); |
1697 } | 1700 } |
1698 | 1701 |
| 1702 // Object literals have two parts. The "static" part on the left contains no |
| 1703 // computed property names, and so we can compute its map ahead of time; see |
| 1704 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
| 1705 // starts with the first computed property name, and continues with all |
| 1706 // properties to its right. All the code from above initializes the static |
| 1707 // component of the object literal, and arranges for the map of the result to |
| 1708 // reflect the static order in which the keys appear. For the dynamic |
| 1709 // properties, we compile them into a series of "SetOwnProperty" runtime |
| 1710 // calls. This will preserve insertion order. |
| 1711 for (; property_index < expr->properties()->length(); property_index++) { |
| 1712 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1713 |
| 1714 Expression* key = property->key(); |
| 1715 Expression* value = property->value(); |
| 1716 if (!result_saved) { |
| 1717 __ push(eax); // Save result on the stack |
| 1718 result_saved = true; |
| 1719 } |
| 1720 |
| 1721 switch (property->kind()) { |
| 1722 case ObjectLiteral::Property::CONSTANT: |
| 1723 case ObjectLiteral::Property::COMPUTED_NAME: |
| 1724 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1725 case ObjectLiteral::Property::COMPUTED: |
| 1726 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1727 VisitForStackValue(key); |
| 1728 VisitForStackValue(value); |
| 1729 if (property->emit_store()) { |
| 1730 __ CallRuntime(Runtime::kSetOwnProperty, 3); |
| 1731 } else { |
| 1732 __ Drop(3); |
| 1733 } |
| 1734 break; |
| 1735 case ObjectLiteral::Property::PROTOTYPE: |
| 1736 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1737 VisitForStackValue(value); |
| 1738 if (property->emit_store()) { |
| 1739 __ CallRuntime(Runtime::kSetPrototype, 2); |
| 1740 } else { |
| 1741 __ Drop(2); |
| 1742 } |
| 1743 break; |
| 1744 // TODO(wingo): Allow computed names for accessor properties. Currently |
| 1745 // disallowed by the parser. |
| 1746 case ObjectLiteral::Property::GETTER: { |
| 1747 ObjectLiteral::Accessors *accessors = |
| 1748 accessor_table.lookup(key->AsLiteral())->second; |
| 1749 accessors->getter = value; |
| 1750 |
| 1751 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1752 VisitForStackValue(key); |
| 1753 EmitAccessor(accessors->getter); |
| 1754 EmitAccessor(accessors->setter); |
| 1755 __ push(Immediate(Smi::FromInt(NONE))); |
| 1756 __ CallRuntime(Runtime::kDefineOrRedefineAccessorProperty, 5); |
| 1757 break; |
| 1758 } |
| 1759 case ObjectLiteral::Property::SETTER: { |
| 1760 ObjectLiteral::Accessors *accessors = |
| 1761 accessor_table.lookup(key->AsLiteral())->second; |
| 1762 accessors->setter = value; |
| 1763 |
| 1764 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1765 VisitForStackValue(key); |
| 1766 EmitAccessor(accessors->getter); |
| 1767 EmitAccessor(accessors->setter); |
| 1768 __ push(Immediate(Smi::FromInt(NONE))); |
| 1769 __ CallRuntime(Runtime::kDefineOrRedefineAccessorProperty, 5); |
| 1770 break; |
| 1771 } |
| 1772 } |
| 1773 } |
| 1774 |
1699 if (expr->has_function()) { | 1775 if (expr->has_function()) { |
1700 ASSERT(result_saved); | 1776 ASSERT(result_saved); |
1701 __ push(Operand(esp, 0)); | 1777 __ push(Operand(esp, 0)); |
1702 __ CallRuntime(Runtime::kToFastProperties, 1); | 1778 __ CallRuntime(Runtime::kToFastProperties, 1); |
1703 } | 1779 } |
1704 | 1780 |
1705 if (result_saved) { | 1781 if (result_saved) { |
1706 context()->PlugTOS(); | 1782 context()->PlugTOS(); |
1707 } else { | 1783 } else { |
1708 context()->Plug(eax); | 1784 context()->Plug(eax); |
(...skipping 3087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4796 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4872 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4797 Assembler::target_address_at(call_target_address, | 4873 Assembler::target_address_at(call_target_address, |
4798 unoptimized_code)); | 4874 unoptimized_code)); |
4799 return OSR_AFTER_STACK_CHECK; | 4875 return OSR_AFTER_STACK_CHECK; |
4800 } | 4876 } |
4801 | 4877 |
4802 | 4878 |
4803 } } // namespace v8::internal | 4879 } } // namespace v8::internal |
4804 | 4880 |
4805 #endif // V8_TARGET_ARCH_X87 | 4881 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |