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