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 #include "src/bailout-reason.h" | 7 #include "src/bailout-reason.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/field-index.h" | 9 #include "src/field-index.h" |
10 #include "src/hydrogen.h" | 10 #include "src/hydrogen.h" |
(...skipping 1639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1650 | 1650 |
1651 return value; | 1651 return value; |
1652 } | 1652 } |
1653 | 1653 |
1654 | 1654 |
1655 Handle<Code> ElementsTransitionAndStoreStub::GenerateCode() { | 1655 Handle<Code> ElementsTransitionAndStoreStub::GenerateCode() { |
1656 return DoGenerateCode(this); | 1656 return DoGenerateCode(this); |
1657 } | 1657 } |
1658 | 1658 |
1659 | 1659 |
| 1660 template <> |
| 1661 HValue* CodeStubGraphBuilder<ToObjectStub>::BuildCodeStub() { |
| 1662 HValue* receiver = GetParameter(ToObjectDescriptor::kReceiverIndex); |
| 1663 // Determine the proper global constructor function required to wrap |
| 1664 // {receiver} into a JSValue, unless {receiver} is already a {JSReceiver}, in |
| 1665 // which case we just return it. Deopts to Runtime::kToObject if {receiver} |
| 1666 // is undefined or null. |
| 1667 IfBuilder receiver_is_smi(this); |
| 1668 receiver_is_smi.If<HIsSmiAndBranch>(receiver); |
| 1669 receiver_is_smi.Then(); |
| 1670 { |
| 1671 // Load native context. |
| 1672 HValue* native_context = BuildGetNativeContext(); |
| 1673 |
| 1674 // Load global Number function. |
| 1675 HValue* constructor = Add<HLoadNamedField>( |
| 1676 native_context, nullptr, |
| 1677 HObjectAccess::ForContextSlot(Context::NUMBER_FUNCTION_INDEX)); |
| 1678 Push(constructor); |
| 1679 } |
| 1680 receiver_is_smi.Else(); |
| 1681 { |
| 1682 // Determine {receiver} map and instance type. |
| 1683 HValue* receiver_map = |
| 1684 Add<HLoadNamedField>(receiver, nullptr, HObjectAccess::ForMap()); |
| 1685 HValue* receiver_instance_type = Add<HLoadNamedField>( |
| 1686 receiver_map, nullptr, HObjectAccess::ForMapInstanceType()); |
| 1687 |
| 1688 // First check whether {receiver} is already a spec object (fast case). |
| 1689 IfBuilder receiver_is_not_spec_object(this); |
| 1690 receiver_is_not_spec_object.If<HCompareNumericAndBranch>( |
| 1691 receiver_instance_type, Add<HConstant>(FIRST_SPEC_OBJECT_TYPE), |
| 1692 Token::LT); |
| 1693 receiver_is_not_spec_object.Then(); |
| 1694 { |
| 1695 // Load native context. |
| 1696 HValue* native_context = BuildGetNativeContext(); |
| 1697 |
| 1698 IfBuilder receiver_is_heap_number(this); |
| 1699 receiver_is_heap_number.If<HCompareNumericAndBranch>( |
| 1700 receiver_instance_type, Add<HConstant>(HEAP_NUMBER_TYPE), Token::EQ); |
| 1701 receiver_is_heap_number.Then(); |
| 1702 { |
| 1703 // Load global Number function. |
| 1704 HValue* constructor = Add<HLoadNamedField>( |
| 1705 native_context, nullptr, |
| 1706 HObjectAccess::ForContextSlot(Context::NUMBER_FUNCTION_INDEX)); |
| 1707 Push(constructor); |
| 1708 } |
| 1709 receiver_is_heap_number.Else(); |
| 1710 { |
| 1711 // Load boolean map (we cannot decide based on instance type, because |
| 1712 // it's ODDBALL_TYPE, which would also include null and undefined). |
| 1713 HValue* boolean_map = Add<HLoadRoot>(Heap::kBooleanMapRootIndex); |
| 1714 |
| 1715 IfBuilder receiver_is_boolean(this); |
| 1716 receiver_is_boolean.If<HCompareObjectEqAndBranch>(receiver_map, |
| 1717 boolean_map); |
| 1718 receiver_is_boolean.Then(); |
| 1719 { |
| 1720 // Load global Boolean function. |
| 1721 HValue* constructor = Add<HLoadNamedField>( |
| 1722 native_context, nullptr, |
| 1723 HObjectAccess::ForContextSlot(Context::BOOLEAN_FUNCTION_INDEX)); |
| 1724 Push(constructor); |
| 1725 } |
| 1726 receiver_is_boolean.Else(); |
| 1727 { |
| 1728 IfBuilder receiver_is_string(this); |
| 1729 receiver_is_string.If<HCompareNumericAndBranch>( |
| 1730 receiver_instance_type, Add<HConstant>(FIRST_NONSTRING_TYPE), |
| 1731 Token::LT); |
| 1732 receiver_is_string.Then(); |
| 1733 { |
| 1734 // Load global String function. |
| 1735 HValue* constructor = Add<HLoadNamedField>( |
| 1736 native_context, nullptr, |
| 1737 HObjectAccess::ForContextSlot(Context::STRING_FUNCTION_INDEX)); |
| 1738 Push(constructor); |
| 1739 } |
| 1740 receiver_is_string.Else(); |
| 1741 { |
| 1742 IfBuilder receiver_is_symbol(this); |
| 1743 receiver_is_symbol.If<HCompareNumericAndBranch>( |
| 1744 receiver_instance_type, Add<HConstant>(SYMBOL_TYPE), Token::EQ); |
| 1745 receiver_is_symbol.Then(); |
| 1746 { |
| 1747 // Load global Symbol function. |
| 1748 HValue* constructor = Add<HLoadNamedField>( |
| 1749 native_context, nullptr, HObjectAccess::ForContextSlot( |
| 1750 Context::SYMBOL_FUNCTION_INDEX)); |
| 1751 Push(constructor); |
| 1752 } |
| 1753 receiver_is_symbol.Else(); |
| 1754 { |
| 1755 IfBuilder receiver_is_float32x4(this); |
| 1756 receiver_is_float32x4.If<HCompareNumericAndBranch>( |
| 1757 receiver_instance_type, Add<HConstant>(FLOAT32X4_TYPE), |
| 1758 Token::EQ); |
| 1759 receiver_is_float32x4.Then(); |
| 1760 { |
| 1761 // Load global Float32x4 function. |
| 1762 HValue* constructor = Add<HLoadNamedField>( |
| 1763 native_context, nullptr, |
| 1764 HObjectAccess::ForContextSlot( |
| 1765 Context::FLOAT32X4_FUNCTION_INDEX)); |
| 1766 Push(constructor); |
| 1767 } |
| 1768 receiver_is_float32x4.ElseDeopt( |
| 1769 Deoptimizer::kUndefinedOrNullInToObject); |
| 1770 receiver_is_float32x4.End(); |
| 1771 } |
| 1772 receiver_is_symbol.End(); |
| 1773 } |
| 1774 receiver_is_string.End(); |
| 1775 } |
| 1776 receiver_is_boolean.End(); |
| 1777 } |
| 1778 receiver_is_heap_number.End(); |
| 1779 } |
| 1780 receiver_is_not_spec_object.Else(); |
| 1781 receiver_is_not_spec_object.Return(receiver); |
| 1782 receiver_is_not_spec_object.End(); |
| 1783 } |
| 1784 receiver_is_smi.End(); |
| 1785 // Determine the initial map for the global constructor. |
| 1786 HValue* constructor = Pop(); |
| 1787 HValue* constructor_initial_map = Add<HLoadNamedField>( |
| 1788 constructor, nullptr, HObjectAccess::ForPrototypeOrInitialMap()); |
| 1789 // Allocate and initialize a JSValue wrapper. |
| 1790 HValue* value = |
| 1791 BuildAllocate(Add<HConstant>(JSValue::kSize), HType::JSObject(), |
| 1792 JS_VALUE_TYPE, HAllocationMode()); |
| 1793 Add<HStoreNamedField>(value, HObjectAccess::ForMap(), |
| 1794 constructor_initial_map); |
| 1795 HValue* empty_fixed_array = Add<HLoadRoot>(Heap::kEmptyFixedArrayRootIndex); |
| 1796 Add<HStoreNamedField>(value, HObjectAccess::ForPropertiesPointer(), |
| 1797 empty_fixed_array); |
| 1798 Add<HStoreNamedField>(value, HObjectAccess::ForElementsPointer(), |
| 1799 empty_fixed_array); |
| 1800 Add<HStoreNamedField>( |
| 1801 value, HObjectAccess::ForObservableJSObjectOffset(JSValue::kValueOffset), |
| 1802 receiver); |
| 1803 return value; |
| 1804 } |
| 1805 |
| 1806 |
| 1807 Handle<Code> ToObjectStub::GenerateCode() { return DoGenerateCode(this); } |
| 1808 |
| 1809 |
1660 void CodeStubGraphBuilderBase::BuildCheckAndInstallOptimizedCode( | 1810 void CodeStubGraphBuilderBase::BuildCheckAndInstallOptimizedCode( |
1661 HValue* js_function, | 1811 HValue* js_function, |
1662 HValue* native_context, | 1812 HValue* native_context, |
1663 IfBuilder* builder, | 1813 IfBuilder* builder, |
1664 HValue* optimized_map, | 1814 HValue* optimized_map, |
1665 HValue* map_index) { | 1815 HValue* map_index) { |
1666 HValue* osr_ast_id_none = Add<HConstant>(BailoutId::None().ToInt()); | 1816 HValue* osr_ast_id_none = Add<HConstant>(BailoutId::None().ToInt()); |
1667 HValue* context_slot = LoadFromOptimizedCodeMap( | 1817 HValue* context_slot = LoadFromOptimizedCodeMap( |
1668 optimized_map, map_index, SharedFunctionInfo::kContextOffset); | 1818 optimized_map, map_index, SharedFunctionInfo::kContextOffset); |
1669 HValue* osr_ast_slot = LoadFromOptimizedCodeMap( | 1819 HValue* osr_ast_slot = LoadFromOptimizedCodeMap( |
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2211 return Pop(); | 2361 return Pop(); |
2212 } | 2362 } |
2213 | 2363 |
2214 | 2364 |
2215 Handle<Code> KeyedLoadGenericStub::GenerateCode() { | 2365 Handle<Code> KeyedLoadGenericStub::GenerateCode() { |
2216 return DoGenerateCode(this); | 2366 return DoGenerateCode(this); |
2217 } | 2367 } |
2218 | 2368 |
2219 } // namespace internal | 2369 } // namespace internal |
2220 } // namespace v8 | 2370 } // namespace v8 |
OLD | NEW |