OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 1720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1731 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1731 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
1732 // Fall through. | 1732 // Fall through. |
1733 case ObjectLiteral::Property::COMPUTED: { | 1733 case ObjectLiteral::Property::COMPUTED: { |
1734 // It is safe to use [[Put]] here because the boilerplate already | 1734 // It is safe to use [[Put]] here because the boilerplate already |
1735 // contains computed properties with an uninitialized value. | 1735 // contains computed properties with an uninitialized value. |
1736 if (key->value()->IsInternalizedString()) { | 1736 if (key->value()->IsInternalizedString()) { |
1737 if (property->emit_store()) { | 1737 if (property->emit_store()) { |
1738 VisitForValue(property->value()); | 1738 VisitForValue(property->value()); |
1739 FrameStateBeforeAndAfter states(this, property->value()->id()); | 1739 FrameStateBeforeAndAfter states(this, property->value()->id()); |
1740 Node* value = environment()->Pop(); | 1740 Node* value = environment()->Pop(); |
| 1741 Node* literal = environment()->Top(); |
1741 Handle<Name> name = key->AsPropertyName(); | 1742 Handle<Name> name = key->AsPropertyName(); |
1742 VectorSlotPair feedback = | 1743 VectorSlotPair feedback = |
1743 CreateVectorSlotPair(property->GetSlot(0)); | 1744 CreateVectorSlotPair(property->GetSlot(0)); |
1744 Node* store = BuildNamedStore(literal, name, value, feedback); | 1745 Node* store = BuildNamedStore(literal, name, value, feedback); |
1745 states.AddToNode(store, key->id(), | 1746 states.AddToNode(store, key->id(), |
1746 OutputFrameStateCombine::Ignore()); | 1747 OutputFrameStateCombine::Ignore()); |
1747 BuildSetHomeObject(value, literal, property, 1); | 1748 BuildSetHomeObject(value, literal, property, 1); |
1748 } else { | 1749 } else { |
1749 VisitForEffect(property->value()); | 1750 VisitForEffect(property->value()); |
1750 } | 1751 } |
1751 break; | 1752 break; |
1752 } | 1753 } |
1753 environment()->Push(literal); // Duplicate receiver. | 1754 environment()->Push(environment()->Top()); // Duplicate receiver. |
1754 VisitForValue(property->key()); | 1755 VisitForValue(property->key()); |
1755 VisitForValue(property->value()); | 1756 VisitForValue(property->value()); |
1756 Node* value = environment()->Pop(); | 1757 Node* value = environment()->Pop(); |
1757 Node* key = environment()->Pop(); | 1758 Node* key = environment()->Pop(); |
1758 Node* receiver = environment()->Pop(); | 1759 Node* receiver = environment()->Pop(); |
1759 if (property->emit_store()) { | 1760 if (property->emit_store()) { |
1760 Node* language = jsgraph()->Constant(SLOPPY); | 1761 Node* language = jsgraph()->Constant(SLOPPY); |
1761 const Operator* op = | 1762 const Operator* op = |
1762 javascript()->CallRuntime(Runtime::kSetProperty, 4); | 1763 javascript()->CallRuntime(Runtime::kSetProperty, 4); |
1763 Node* set_property = NewNode(op, receiver, key, value, language); | 1764 Node* set_property = NewNode(op, receiver, key, value, language); |
1764 // SetProperty should not lazy deopt on an object literal. | 1765 // SetProperty should not lazy deopt on an object literal. |
1765 PrepareFrameState(set_property, BailoutId::None()); | 1766 PrepareFrameState(set_property, BailoutId::None()); |
1766 BuildSetHomeObject(value, receiver, property); | 1767 BuildSetHomeObject(value, receiver, property); |
1767 } | 1768 } |
1768 break; | 1769 break; |
1769 } | 1770 } |
1770 case ObjectLiteral::Property::PROTOTYPE: { | 1771 case ObjectLiteral::Property::PROTOTYPE: { |
1771 environment()->Push(literal); // Duplicate receiver. | 1772 environment()->Push(environment()->Top()); // Duplicate receiver. |
1772 VisitForValue(property->value()); | 1773 VisitForValue(property->value()); |
1773 Node* value = environment()->Pop(); | 1774 Node* value = environment()->Pop(); |
1774 Node* receiver = environment()->Pop(); | 1775 Node* receiver = environment()->Pop(); |
1775 DCHECK(property->emit_store()); | 1776 DCHECK(property->emit_store()); |
1776 const Operator* op = | 1777 const Operator* op = |
1777 javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2); | 1778 javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2); |
1778 Node* set_prototype = NewNode(op, receiver, value); | 1779 Node* set_prototype = NewNode(op, receiver, value); |
1779 // SetPrototype should not lazy deopt on an object literal. | 1780 // SetPrototype should not lazy deopt on an object literal. |
1780 PrepareFrameState(set_prototype, BailoutId::None()); | 1781 PrepareFrameState(set_prototype, BailoutId::None()); |
1781 break; | 1782 break; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1817 // with the first computed property name and continues with all properties to | 1818 // with the first computed property name and continues with all properties to |
1818 // its right. All the code from above initializes the static component of the | 1819 // its right. All the code from above initializes the static component of the |
1819 // object literal, and arranges for the map of the result to reflect the | 1820 // object literal, and arranges for the map of the result to reflect the |
1820 // static order in which the keys appear. For the dynamic properties, we | 1821 // static order in which the keys appear. For the dynamic properties, we |
1821 // compile them into a series of "SetOwnProperty" runtime calls. This will | 1822 // compile them into a series of "SetOwnProperty" runtime calls. This will |
1822 // preserve insertion order. | 1823 // preserve insertion order. |
1823 for (; property_index < expr->properties()->length(); property_index++) { | 1824 for (; property_index < expr->properties()->length(); property_index++) { |
1824 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1825 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
1825 | 1826 |
1826 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1827 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
1827 environment()->Push(literal); // Duplicate receiver. | 1828 environment()->Push(environment()->Top()); // Duplicate receiver. |
1828 VisitForValue(property->value()); | 1829 VisitForValue(property->value()); |
1829 Node* value = environment()->Pop(); | 1830 Node* value = environment()->Pop(); |
1830 Node* receiver = environment()->Pop(); | 1831 Node* receiver = environment()->Pop(); |
1831 const Operator* op = | 1832 const Operator* op = |
1832 javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2); | 1833 javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2); |
1833 Node* call = NewNode(op, receiver, value); | 1834 Node* call = NewNode(op, receiver, value); |
1834 PrepareFrameState(call, BailoutId::None()); | 1835 PrepareFrameState(call, BailoutId::None()); |
1835 continue; | 1836 continue; |
1836 } | 1837 } |
1837 | 1838 |
1838 environment()->Push(literal); // Duplicate receiver. | 1839 environment()->Push(environment()->Top()); // Duplicate receiver. |
1839 VisitForValue(property->key()); | 1840 VisitForValue(property->key()); |
1840 Node* name = BuildToName(environment()->Pop(), | 1841 Node* name = BuildToName(environment()->Pop(), |
1841 expr->GetIdForProperty(property_index)); | 1842 expr->GetIdForProperty(property_index)); |
1842 environment()->Push(name); | 1843 environment()->Push(name); |
1843 VisitForValue(property->value()); | 1844 VisitForValue(property->value()); |
1844 Node* value = environment()->Pop(); | 1845 Node* value = environment()->Pop(); |
1845 Node* key = environment()->Pop(); | 1846 Node* key = environment()->Pop(); |
1846 Node* receiver = environment()->Pop(); | 1847 Node* receiver = environment()->Pop(); |
1847 BuildSetHomeObject(value, receiver, property); | 1848 BuildSetHomeObject(value, receiver, property); |
1848 switch (property->kind()) { | 1849 switch (property->kind()) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1926 Expression* subexpr = expr->values()->at(array_index); | 1927 Expression* subexpr = expr->values()->at(array_index); |
1927 if (subexpr->IsSpread()) break; | 1928 if (subexpr->IsSpread()) break; |
1928 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 1929 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
1929 | 1930 |
1930 VisitForValue(subexpr); | 1931 VisitForValue(subexpr); |
1931 { | 1932 { |
1932 FrameStateBeforeAndAfter states(this, subexpr->id()); | 1933 FrameStateBeforeAndAfter states(this, subexpr->id()); |
1933 VectorSlotPair pair = CreateVectorSlotPair(expr->LiteralFeedbackSlot()); | 1934 VectorSlotPair pair = CreateVectorSlotPair(expr->LiteralFeedbackSlot()); |
1934 Node* value = environment()->Pop(); | 1935 Node* value = environment()->Pop(); |
1935 Node* index = jsgraph()->Constant(array_index); | 1936 Node* index = jsgraph()->Constant(array_index); |
| 1937 Node* literal = environment()->Peek(1); |
1936 Node* store = BuildKeyedStore(literal, index, value, pair); | 1938 Node* store = BuildKeyedStore(literal, index, value, pair); |
1937 states.AddToNode(store, expr->GetIdForElement(array_index), | 1939 states.AddToNode(store, expr->GetIdForElement(array_index), |
1938 OutputFrameStateCombine::Ignore()); | 1940 OutputFrameStateCombine::Ignore()); |
1939 } | 1941 } |
1940 } | 1942 } |
1941 | 1943 |
1942 // In case the array literal contains spread expressions it has two parts. The | 1944 // In case the array literal contains spread expressions it has two parts. The |
1943 // first part is the "static" array which has a literal index is handled | 1945 // first part is the "static" array which has a literal index is handled |
1944 // above. The second part is the part after the first spread expression | 1946 // above. The second part is the part after the first spread expression |
1945 // (inclusive) and these elements gets appended to the array. Note that the | 1947 // (inclusive) and these elements gets appended to the array. Note that the |
(...skipping 2350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4296 // Phi does not exist yet, introduce one. | 4298 // Phi does not exist yet, introduce one. |
4297 value = NewPhi(inputs, value, control); | 4299 value = NewPhi(inputs, value, control); |
4298 value->ReplaceInput(inputs - 1, other); | 4300 value->ReplaceInput(inputs - 1, other); |
4299 } | 4301 } |
4300 return value; | 4302 return value; |
4301 } | 4303 } |
4302 | 4304 |
4303 } // namespace compiler | 4305 } // namespace compiler |
4304 } // namespace internal | 4306 } // namespace internal |
4305 } // namespace v8 | 4307 } // namespace v8 |
OLD | NEW |