OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/hydrogen.h" | 5 #include "src/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 2014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2025 isolate()->factory()->empty_string(), | 2025 isolate()->factory()->empty_string(), |
2026 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache), | 2026 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache), |
2027 1)); | 2027 1)); |
2028 } | 2028 } |
2029 if_found.End(); | 2029 if_found.End(); |
2030 | 2030 |
2031 return Pop(); | 2031 return Pop(); |
2032 } | 2032 } |
2033 | 2033 |
2034 | 2034 |
| 2035 HValue* HGraphBuilder::BuildToObject(HValue* receiver) { |
| 2036 NoObservableSideEffectsScope scope(this); |
| 2037 |
| 2038 // Create a joinable continuation. |
| 2039 HIfContinuation wrap(graph()->CreateBasicBlock(), |
| 2040 graph()->CreateBasicBlock()); |
| 2041 |
| 2042 // Determine the proper global constructor function required to wrap |
| 2043 // {receiver} into a JSValue, unless {receiver} is already a {JSReceiver}, in |
| 2044 // which case we just return it. Deopts to Runtime::kToObject if {receiver} |
| 2045 // is undefined or null. |
| 2046 IfBuilder receiver_is_smi(this); |
| 2047 receiver_is_smi.If<HIsSmiAndBranch>(receiver); |
| 2048 receiver_is_smi.Then(); |
| 2049 { |
| 2050 // Load native context. |
| 2051 HValue* native_context = BuildGetNativeContext(); |
| 2052 |
| 2053 // Load global Number function. |
| 2054 HValue* constructor = Add<HLoadNamedField>( |
| 2055 native_context, nullptr, |
| 2056 HObjectAccess::ForContextSlot(Context::NUMBER_FUNCTION_INDEX)); |
| 2057 Push(constructor); |
| 2058 } |
| 2059 receiver_is_smi.Else(); |
| 2060 { |
| 2061 // Determine {receiver} map and instance type. |
| 2062 HValue* receiver_map = |
| 2063 Add<HLoadNamedField>(receiver, nullptr, HObjectAccess::ForMap()); |
| 2064 HValue* receiver_instance_type = Add<HLoadNamedField>( |
| 2065 receiver_map, nullptr, HObjectAccess::ForMapInstanceType()); |
| 2066 |
| 2067 // First check whether {receiver} is already a spec object (fast case). |
| 2068 IfBuilder receiver_is_not_spec_object(this); |
| 2069 receiver_is_not_spec_object.If<HCompareNumericAndBranch>( |
| 2070 receiver_instance_type, Add<HConstant>(FIRST_SPEC_OBJECT_TYPE), |
| 2071 Token::LT); |
| 2072 receiver_is_not_spec_object.Then(); |
| 2073 { |
| 2074 // Load native context. |
| 2075 HValue* native_context = BuildGetNativeContext(); |
| 2076 |
| 2077 IfBuilder receiver_is_heap_number(this); |
| 2078 receiver_is_heap_number.If<HCompareNumericAndBranch>( |
| 2079 receiver_instance_type, Add<HConstant>(HEAP_NUMBER_TYPE), Token::EQ); |
| 2080 receiver_is_heap_number.Then(); |
| 2081 { |
| 2082 // Load global Number function. |
| 2083 HValue* constructor = Add<HLoadNamedField>( |
| 2084 native_context, nullptr, |
| 2085 HObjectAccess::ForContextSlot(Context::NUMBER_FUNCTION_INDEX)); |
| 2086 Push(constructor); |
| 2087 } |
| 2088 receiver_is_heap_number.Else(); |
| 2089 { |
| 2090 // Load boolean map (we cannot decide based on instance type, because |
| 2091 // it's ODDBALL_TYPE, which would also include null and undefined). |
| 2092 HValue* boolean_map = Add<HLoadRoot>(Heap::kBooleanMapRootIndex); |
| 2093 |
| 2094 IfBuilder receiver_is_boolean(this); |
| 2095 receiver_is_boolean.If<HCompareObjectEqAndBranch>(receiver_map, |
| 2096 boolean_map); |
| 2097 receiver_is_boolean.Then(); |
| 2098 { |
| 2099 // Load global Boolean function. |
| 2100 HValue* constructor = Add<HLoadNamedField>( |
| 2101 native_context, nullptr, |
| 2102 HObjectAccess::ForContextSlot(Context::BOOLEAN_FUNCTION_INDEX)); |
| 2103 Push(constructor); |
| 2104 } |
| 2105 receiver_is_boolean.Else(); |
| 2106 { |
| 2107 IfBuilder receiver_is_string(this); |
| 2108 receiver_is_string.If<HCompareNumericAndBranch>( |
| 2109 receiver_instance_type, Add<HConstant>(FIRST_NONSTRING_TYPE), |
| 2110 Token::LT); |
| 2111 receiver_is_string.Then(); |
| 2112 { |
| 2113 // Load global String function. |
| 2114 HValue* constructor = Add<HLoadNamedField>( |
| 2115 native_context, nullptr, |
| 2116 HObjectAccess::ForContextSlot(Context::STRING_FUNCTION_INDEX)); |
| 2117 Push(constructor); |
| 2118 } |
| 2119 receiver_is_string.Else(); |
| 2120 { |
| 2121 IfBuilder receiver_is_symbol(this); |
| 2122 receiver_is_symbol.If<HCompareNumericAndBranch>( |
| 2123 receiver_instance_type, Add<HConstant>(SYMBOL_TYPE), Token::EQ); |
| 2124 receiver_is_symbol.Then(); |
| 2125 { |
| 2126 // Load global Symbol function. |
| 2127 HValue* constructor = Add<HLoadNamedField>( |
| 2128 native_context, nullptr, HObjectAccess::ForContextSlot( |
| 2129 Context::SYMBOL_FUNCTION_INDEX)); |
| 2130 Push(constructor); |
| 2131 } |
| 2132 receiver_is_symbol.Else(); |
| 2133 { |
| 2134 IfBuilder receiver_is_float32x4(this); |
| 2135 receiver_is_float32x4.If<HCompareNumericAndBranch>( |
| 2136 receiver_instance_type, Add<HConstant>(FLOAT32X4_TYPE), |
| 2137 Token::EQ); |
| 2138 receiver_is_float32x4.Then(); |
| 2139 { |
| 2140 // Load global Float32x4 function. |
| 2141 HValue* constructor = Add<HLoadNamedField>( |
| 2142 native_context, nullptr, |
| 2143 HObjectAccess::ForContextSlot( |
| 2144 Context::FLOAT32X4_FUNCTION_INDEX)); |
| 2145 Push(constructor); |
| 2146 } |
| 2147 receiver_is_float32x4.ElseDeopt( |
| 2148 Deoptimizer::kUndefinedOrNullInToObject); |
| 2149 receiver_is_float32x4.JoinContinuation(&wrap); |
| 2150 } |
| 2151 receiver_is_symbol.JoinContinuation(&wrap); |
| 2152 } |
| 2153 receiver_is_string.JoinContinuation(&wrap); |
| 2154 } |
| 2155 receiver_is_boolean.JoinContinuation(&wrap); |
| 2156 } |
| 2157 receiver_is_heap_number.JoinContinuation(&wrap); |
| 2158 } |
| 2159 receiver_is_not_spec_object.JoinContinuation(&wrap); |
| 2160 } |
| 2161 receiver_is_smi.JoinContinuation(&wrap); |
| 2162 |
| 2163 // Wrap the receiver if necessary. |
| 2164 IfBuilder if_wrap(this, &wrap); |
| 2165 if_wrap.Then(); |
| 2166 { |
| 2167 // Determine the initial map for the global constructor. |
| 2168 HValue* constructor = Pop(); |
| 2169 HValue* constructor_initial_map = Add<HLoadNamedField>( |
| 2170 constructor, nullptr, HObjectAccess::ForPrototypeOrInitialMap()); |
| 2171 // Allocate and initialize a JSValue wrapper. |
| 2172 HValue* value = |
| 2173 BuildAllocate(Add<HConstant>(JSValue::kSize), HType::JSObject(), |
| 2174 JS_VALUE_TYPE, HAllocationMode()); |
| 2175 Add<HStoreNamedField>(value, HObjectAccess::ForMap(), |
| 2176 constructor_initial_map); |
| 2177 HValue* empty_fixed_array = Add<HLoadRoot>(Heap::kEmptyFixedArrayRootIndex); |
| 2178 Add<HStoreNamedField>(value, HObjectAccess::ForPropertiesPointer(), |
| 2179 empty_fixed_array); |
| 2180 Add<HStoreNamedField>(value, HObjectAccess::ForElementsPointer(), |
| 2181 empty_fixed_array); |
| 2182 Add<HStoreNamedField>(value, HObjectAccess::ForObservableJSObjectOffset( |
| 2183 JSValue::kValueOffset), |
| 2184 receiver); |
| 2185 Push(value); |
| 2186 } |
| 2187 if_wrap.Else(); |
| 2188 { Push(receiver); } |
| 2189 if_wrap.End(); |
| 2190 return Pop(); |
| 2191 } |
| 2192 |
| 2193 |
2035 HAllocate* HGraphBuilder::BuildAllocate( | 2194 HAllocate* HGraphBuilder::BuildAllocate( |
2036 HValue* object_size, | 2195 HValue* object_size, |
2037 HType type, | 2196 HType type, |
2038 InstanceType instance_type, | 2197 InstanceType instance_type, |
2039 HAllocationMode allocation_mode) { | 2198 HAllocationMode allocation_mode) { |
2040 // Compute the effective allocation size. | 2199 // Compute the effective allocation size. |
2041 HValue* size = object_size; | 2200 HValue* size = object_size; |
2042 if (allocation_mode.CreateAllocationMementos()) { | 2201 if (allocation_mode.CreateAllocationMementos()) { |
2043 size = AddUncasted<HAdd>(size, Add<HConstant>(AllocationMemento::kSize)); | 2202 size = AddUncasted<HAdd>(size, Add<HConstant>(AllocationMemento::kSize)); |
2044 size->ClearFlag(HValue::kCanOverflow); | 2203 size->ClearFlag(HValue::kCanOverflow); |
(...skipping 11275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13320 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13479 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13321 } | 13480 } |
13322 | 13481 |
13323 #ifdef DEBUG | 13482 #ifdef DEBUG |
13324 graph_->Verify(false); // No full verify. | 13483 graph_->Verify(false); // No full verify. |
13325 #endif | 13484 #endif |
13326 } | 13485 } |
13327 | 13486 |
13328 } // namespace internal | 13487 } // namespace internal |
13329 } // namespace v8 | 13488 } // namespace v8 |
OLD | NEW |