Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/builtins/builtins.h" | 5 #include "src/builtins/builtins.h" |
| 6 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
| 7 | 7 |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/contexts.h" | |
| 9 #include "src/elements.h" | 10 #include "src/elements.h" |
| 10 | 11 |
| 11 namespace v8 { | 12 namespace v8 { |
| 12 namespace internal { | 13 namespace internal { |
| 13 | 14 |
| 14 namespace { | 15 namespace { |
| 15 | 16 |
| 16 inline bool ClampedToInteger(Isolate* isolate, Object* object, int* out) { | 17 inline bool ClampedToInteger(Isolate* isolate, Object* object, int* out) { |
| 17 // This is an extended version of ECMA-262 7.1.11 handling signed values | 18 // This is an extended version of ECMA-262 7.1.11 handling signed values |
| 18 // Try to convert object to a number and clamp values to [kMinInt, kMaxInt] | 19 // Try to convert object to a number and clamp values to [kMinInt, kMaxInt] |
| (...skipping 2041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2060 assembler->Return(assembler->ChangeInt32ToTagged(index_var.value())); | 2061 assembler->Return(assembler->ChangeInt32ToTagged(index_var.value())); |
| 2061 | 2062 |
| 2062 assembler->Bind(&return_not_found); | 2063 assembler->Bind(&return_not_found); |
| 2063 assembler->Return(assembler->NumberConstant(-1)); | 2064 assembler->Return(assembler->NumberConstant(-1)); |
| 2064 | 2065 |
| 2065 assembler->Bind(&call_runtime); | 2066 assembler->Bind(&call_runtime); |
| 2066 assembler->Return(assembler->CallRuntime(Runtime::kArrayIndexOf, context, | 2067 assembler->Return(assembler->CallRuntime(Runtime::kArrayIndexOf, context, |
| 2067 array, search_element, start_from)); | 2068 array, search_element, start_from)); |
| 2068 } | 2069 } |
| 2069 | 2070 |
| 2071 void Builtins::Generate_ArrayPrototypeValues(CodeStubAssembler* assembler) { | |
|
Benedikt Meurer
2016/10/13 05:07:19
Do you plan to do a separate TypedArrayPrototypeVa
caitp
2016/10/13 22:32:43
I've made it so that the triplet methods (keys/val
| |
| 2072 typedef compiler::Node Node; | |
| 2073 typedef CodeStubAssembler::Label Label; | |
| 2074 typedef CodeStubAssembler::Variable Variable; | |
| 2075 | |
| 2076 Variable var_array(assembler, MachineRepresentation::kTagged); | |
| 2077 Variable var_result(assembler, MachineRepresentation::kTagged); | |
|
Benedikt Meurer
2016/10/13 05:07:20
This seems to be unused.
caitp
2016/10/13 22:32:43
I _think_ this is no longer an issue after the big
| |
| 2078 Variable var_map(assembler, MachineRepresentation::kTagged); | |
| 2079 Variable var_map_index(assembler, MachineType::PointerRepresentation()); | |
| 2080 | |
| 2081 Label call_to_object(assembler); | |
| 2082 Label check_instance_type(assembler); | |
| 2083 Label if_isfastarray(assembler); | |
| 2084 Label if_isgeneric(assembler); | |
| 2085 Label allocate_array_iterator(assembler); | |
| 2086 Label allocate_typed_array_iterator(assembler); | |
| 2087 | |
| 2088 Node* receiver = assembler->Parameter(0); | |
|
caitp
2016/10/13 00:13:36
For reasons I don't completely understand, the for
Benedikt Meurer
2016/10/13 05:07:19
Hm, this looks like a bug somewhere. You could rep
Yang
2016/10/13 13:52:37
Doesn't ring a bell, sorry. But I'm not all that s
caitp
2016/10/13 16:12:58
It turns out, including the receiver in the intern
| |
| 2089 Node* context = assembler->Parameter(3); | |
| 2090 Node* native_context = assembler->LoadNativeContext(context); | |
| 2091 | |
| 2092 var_array.Bind(receiver); | |
| 2093 var_result.Bind(assembler->UndefinedConstant()); | |
| 2094 var_map.Bind(assembler->UndefinedConstant()); | |
| 2095 var_map_index.Bind(assembler->IntPtrConstant(0)); | |
|
Benedikt Meurer
2016/10/13 05:07:19
You don't need to bind var_map / var_map_index her
caitp
2016/10/13 22:32:43
This still happens in the new version, in CodeStub
| |
| 2096 | |
| 2097 assembler->Branch(assembler->TaggedIsSmi(var_array.value()), &call_to_object, | |
| 2098 &check_instance_type); | |
| 2099 assembler->Bind(&check_instance_type); | |
| 2100 { | |
| 2101 var_map.Bind(assembler->LoadMap(var_array.value())); | |
| 2102 Node* instance_type = assembler->LoadMapInstanceType(var_map.value()); | |
| 2103 assembler->GotoIf( | |
| 2104 assembler->Int32LessThan( | |
| 2105 instance_type, assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE)), | |
| 2106 &call_to_object); | |
| 2107 | |
| 2108 assembler->GotoIf( | |
| 2109 assembler->WordEqual(instance_type, | |
| 2110 assembler->Int32Constant(JS_TYPED_ARRAY_TYPE)), | |
| 2111 &allocate_typed_array_iterator); | |
| 2112 | |
| 2113 assembler->BranchIfFastJSArray(var_array.value(), context, &if_isfastarray, | |
| 2114 &if_isgeneric); | |
| 2115 } | |
| 2116 | |
| 2117 assembler->Bind(&if_isfastarray); | |
| 2118 { | |
| 2119 Node* map_index = assembler->IntPtrAdd( | |
|
Benedikt Meurer
2016/10/13 05:07:19
Neat! But please add some STATIC_ASSERTs to guard
caitp
2016/10/13 22:32:43
ah, I think I added some comments to this stuff, b
| |
| 2120 assembler->IntPtrConstant(Context::FAST_ARRAY_VALUE_ITERATOR_MAP_INDEX), | |
| 2121 assembler->LoadMapElementsKind(assembler->LoadMap(var_array.value()))); | |
| 2122 assembler->Assert(assembler->IntPtrLessThan( | |
| 2123 map_index, assembler->IntPtrConstant( | |
| 2124 Context::GENERIC_ARRAY_VALUE_ITERATOR_MAP_INDEX))); | |
| 2125 | |
| 2126 var_map_index.Bind(map_index); | |
| 2127 assembler->Goto(&allocate_array_iterator); | |
| 2128 } | |
| 2129 | |
| 2130 assembler->Bind(&call_to_object); | |
| 2131 { | |
| 2132 Callable callable = CodeFactory::ToObject(assembler->isolate()); | |
| 2133 Node* result = assembler->CallStub(callable, context, var_array.value()); | |
| 2134 var_map.Bind(assembler->LoadMap(result)); | |
| 2135 var_array.Bind(result); | |
| 2136 assembler->Goto(&if_isgeneric); | |
| 2137 } | |
| 2138 | |
| 2139 assembler->Bind(&if_isgeneric); | |
| 2140 { | |
| 2141 Node* map_index = | |
| 2142 assembler->IntPtrConstant(Context::FAST_ARRAY_VALUE_ITERATOR_MAP_INDEX); | |
| 2143 | |
| 2144 var_map_index.Bind(map_index); | |
| 2145 assembler->Goto(&allocate_array_iterator); | |
| 2146 } | |
| 2147 | |
| 2148 assembler->Bind(&allocate_array_iterator); | |
| 2149 { | |
| 2150 Node* iterator = assembler->Allocate(JSArrayIterator::kSize); | |
|
Benedikt Meurer
2016/10/13 05:07:19
Can you add a helper method AllocateArrayIterator(
caitp
2016/10/13 22:32:44
I've added CodeStubAssembler::AllocateJSArrayItera
| |
| 2151 Node* map = assembler->LoadFixedArrayElement( | |
| 2152 native_context, var_map_index.value(), 0, | |
| 2153 CodeStubAssembler::INTPTR_PARAMETERS); | |
| 2154 assembler->StoreMapNoWriteBarrier(iterator, map); | |
| 2155 assembler->StoreObjectFieldRoot(iterator, | |
| 2156 JSIteratorResult::kPropertiesOffset, | |
| 2157 Heap::kEmptyFixedArrayRootIndex); | |
| 2158 assembler->StoreObjectFieldRoot(iterator, JSIteratorResult::kElementsOffset, | |
| 2159 Heap::kEmptyFixedArrayRootIndex); | |
| 2160 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2161 iterator, JSArrayIterator::kIteratedObjectOffset, var_array.value()); | |
| 2162 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2163 iterator, JSArrayIterator::kNextIndexOffset, | |
| 2164 assembler->SmiConstant(Smi::FromInt(0))); | |
| 2165 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2166 iterator, JSArrayIterator::kIteratedObjectMapOffset, var_map.value()); | |
| 2167 assembler->Return(iterator); | |
| 2168 } | |
| 2169 | |
| 2170 assembler->Bind(&allocate_typed_array_iterator); | |
| 2171 { | |
| 2172 Node* map_index = assembler->IntPtrAdd( | |
| 2173 assembler->IntPtrConstant( | |
| 2174 Context::UINT8_ARRAY_VALUE_ITERATOR_MAP_INDEX), | |
| 2175 assembler->Int32Sub(assembler->LoadMapElementsKind( | |
| 2176 assembler->LoadMap(var_array.value())), | |
| 2177 assembler->Int32Constant(UINT8_ELEMENTS))); | |
| 2178 Node* map = assembler->LoadFixedArrayElement( | |
| 2179 native_context, map_index, 0, CodeStubAssembler::INTPTR_PARAMETERS); | |
| 2180 Node* iterator = assembler->Allocate(JSTypedArrayIterator::kSize); | |
| 2181 assembler->StoreMapNoWriteBarrier(iterator, map); | |
| 2182 assembler->StoreObjectFieldRoot(iterator, | |
| 2183 JSTypedArrayIterator::kPropertiesOffset, | |
| 2184 Heap::kEmptyFixedArrayRootIndex); | |
| 2185 assembler->StoreObjectFieldRoot(iterator, | |
| 2186 JSTypedArrayIterator::kElementsOffset, | |
| 2187 Heap::kEmptyFixedArrayRootIndex); | |
| 2188 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2189 iterator, JSTypedArrayIterator::kIteratedObjectOffset, | |
| 2190 var_array.value()); | |
| 2191 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2192 iterator, JSTypedArrayIterator::kNextIndexOffset, | |
| 2193 assembler->SmiConstant(Smi::FromInt(0))); | |
| 2194 assembler->Return(iterator); | |
| 2195 } | |
| 2196 } | |
| 2197 | |
| 2198 void Builtins::Generate_ArrayPrototypeEntries(CodeStubAssembler* assembler) { | |
|
Benedikt Meurer
2016/10/13 05:07:19
Can you unify this with the ArrayPrototypeValues a
caitp
2016/10/13 22:32:43
Done in CodeStubAssembler::CreateArrayIterator()
| |
| 2199 typedef compiler::Node Node; | |
| 2200 typedef CodeStubAssembler::Label Label; | |
| 2201 typedef CodeStubAssembler::Variable Variable; | |
| 2202 | |
| 2203 Variable var_array(assembler, MachineRepresentation::kTagged); | |
| 2204 Variable var_result(assembler, MachineRepresentation::kTagged); | |
| 2205 Variable var_map(assembler, MachineRepresentation::kTagged); | |
| 2206 Variable var_map_index(assembler, MachineType::PointerRepresentation()); | |
| 2207 | |
| 2208 Label call_to_object(assembler); | |
| 2209 Label check_instance_type(assembler); | |
| 2210 Label if_isfastarray(assembler); | |
| 2211 Label if_isgeneric(assembler); | |
| 2212 Label allocate_array_iterator(assembler); | |
| 2213 Label allocate_typed_array_iterator(assembler); | |
| 2214 | |
| 2215 Node* receiver = assembler->Parameter(0); | |
| 2216 Node* context = assembler->Parameter(3); | |
| 2217 Node* native_context = assembler->LoadNativeContext(context); | |
| 2218 | |
| 2219 var_array.Bind(receiver); | |
| 2220 var_result.Bind(assembler->UndefinedConstant()); | |
| 2221 var_map.Bind(assembler->UndefinedConstant()); | |
| 2222 var_map_index.Bind(assembler->IntPtrConstant(0)); | |
| 2223 | |
| 2224 assembler->Branch(assembler->TaggedIsSmi(var_array.value()), &call_to_object, | |
| 2225 &check_instance_type); | |
| 2226 assembler->Bind(&check_instance_type); | |
| 2227 { | |
| 2228 var_map.Bind(assembler->LoadMap(var_array.value())); | |
| 2229 Node* instance_type = assembler->LoadMapInstanceType(var_map.value()); | |
| 2230 assembler->GotoIf( | |
| 2231 assembler->Int32LessThan( | |
| 2232 instance_type, assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE)), | |
| 2233 &call_to_object); | |
| 2234 | |
| 2235 assembler->GotoIf( | |
| 2236 assembler->WordEqual(instance_type, | |
| 2237 assembler->Int32Constant(JS_TYPED_ARRAY_TYPE)), | |
| 2238 &allocate_typed_array_iterator); | |
| 2239 | |
| 2240 assembler->BranchIfFastJSArray(var_array.value(), context, &if_isfastarray, | |
| 2241 &if_isgeneric); | |
| 2242 } | |
| 2243 | |
| 2244 assembler->Bind(&if_isfastarray); | |
| 2245 { | |
| 2246 Node* map_index = assembler->IntPtrAdd( | |
| 2247 assembler->IntPtrConstant( | |
| 2248 Context::FAST_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX), | |
| 2249 assembler->LoadMapElementsKind(assembler->LoadMap(var_array.value()))); | |
| 2250 assembler->Assert(assembler->IntPtrLessThan( | |
| 2251 map_index, assembler->IntPtrConstant( | |
| 2252 Context::GENERIC_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX))); | |
| 2253 | |
| 2254 var_map_index.Bind(map_index); | |
| 2255 assembler->Goto(&allocate_array_iterator); | |
| 2256 } | |
| 2257 | |
| 2258 assembler->Bind(&call_to_object); | |
| 2259 { | |
| 2260 Callable callable = CodeFactory::ToObject(assembler->isolate()); | |
| 2261 Node* result = assembler->CallStub(callable, context, var_array.value()); | |
| 2262 var_map.Bind(assembler->LoadMap(result)); | |
| 2263 var_array.Bind(result); | |
| 2264 assembler->Goto(&if_isgeneric); | |
| 2265 } | |
| 2266 | |
| 2267 assembler->Bind(&if_isgeneric); | |
| 2268 { | |
| 2269 Node* map_index = assembler->IntPtrConstant( | |
| 2270 Context::GENERIC_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX); | |
| 2271 var_map_index.Bind(map_index); | |
| 2272 assembler->Goto(&allocate_array_iterator); | |
| 2273 } | |
| 2274 | |
| 2275 assembler->Bind(&allocate_array_iterator); | |
| 2276 { | |
| 2277 Node* iterator = assembler->Allocate(JSArrayIterator::kSize); | |
| 2278 Node* map = assembler->LoadFixedArrayElement( | |
| 2279 native_context, var_map_index.value(), 0, | |
| 2280 CodeStubAssembler::INTPTR_PARAMETERS); | |
| 2281 assembler->StoreMapNoWriteBarrier(iterator, map); | |
| 2282 assembler->StoreObjectFieldRoot(iterator, | |
| 2283 JSIteratorResult::kPropertiesOffset, | |
| 2284 Heap::kEmptyFixedArrayRootIndex); | |
| 2285 assembler->StoreObjectFieldRoot(iterator, JSIteratorResult::kElementsOffset, | |
| 2286 Heap::kEmptyFixedArrayRootIndex); | |
| 2287 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2288 iterator, JSArrayIterator::kIteratedObjectOffset, var_array.value()); | |
| 2289 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2290 iterator, JSArrayIterator::kNextIndexOffset, | |
| 2291 assembler->SmiConstant(Smi::FromInt(0))); | |
| 2292 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2293 iterator, JSArrayIterator::kIteratedObjectMapOffset, var_map.value()); | |
| 2294 assembler->Return(iterator); | |
| 2295 } | |
| 2296 | |
| 2297 assembler->Bind(&allocate_typed_array_iterator); | |
| 2298 { | |
| 2299 Node* map_index = assembler->IntPtrAdd( | |
| 2300 assembler->IntPtrConstant( | |
| 2301 Context::UINT8_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX), | |
| 2302 assembler->Int32Sub(assembler->LoadMapElementsKind(var_map.value()), | |
| 2303 assembler->Int32Constant(UINT8_ELEMENTS))); | |
| 2304 Node* map = assembler->LoadFixedArrayElement( | |
| 2305 native_context, map_index, 0, CodeStubAssembler::INTPTR_PARAMETERS); | |
| 2306 Node* iterator = assembler->Allocate(JSTypedArrayIterator::kSize); | |
| 2307 assembler->StoreMapNoWriteBarrier(iterator, map); | |
| 2308 assembler->StoreObjectFieldRoot(iterator, | |
| 2309 JSTypedArrayIterator::kPropertiesOffset, | |
| 2310 Heap::kEmptyFixedArrayRootIndex); | |
| 2311 assembler->StoreObjectFieldRoot(iterator, | |
| 2312 JSTypedArrayIterator::kElementsOffset, | |
| 2313 Heap::kEmptyFixedArrayRootIndex); | |
| 2314 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2315 iterator, JSTypedArrayIterator::kIteratedObjectOffset, | |
| 2316 var_array.value()); | |
| 2317 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2318 iterator, JSTypedArrayIterator::kNextIndexOffset, | |
| 2319 assembler->SmiConstant(Smi::FromInt(0))); | |
| 2320 assembler->Return(iterator); | |
| 2321 } | |
| 2322 } | |
| 2323 | |
| 2324 void Builtins::Generate_ArrayPrototypeKeys(CodeStubAssembler* assembler) { | |
| 2325 typedef compiler::Node Node; | |
| 2326 typedef CodeStubAssembler::Label Label; | |
| 2327 typedef CodeStubAssembler::Variable Variable; | |
| 2328 | |
| 2329 Variable var_array(assembler, MachineRepresentation::kTagged); | |
| 2330 Variable var_result(assembler, MachineRepresentation::kTagged); | |
| 2331 Variable var_map(assembler, MachineRepresentation::kTagged); | |
| 2332 | |
| 2333 Label call_to_object(assembler); | |
| 2334 Label check_instance_type(assembler); | |
| 2335 Label if_isfastarray(assembler); | |
| 2336 Label if_isgeneric(assembler); | |
| 2337 Label allocate_array_iterator(assembler); | |
| 2338 Label allocate_typed_array_iterator(assembler); | |
| 2339 | |
| 2340 Node* receiver = assembler->Parameter(0); | |
| 2341 Node* context = assembler->Parameter(3); | |
| 2342 Node* native_context = assembler->LoadNativeContext(context); | |
| 2343 | |
| 2344 var_array.Bind(receiver); | |
| 2345 var_result.Bind(assembler->UndefinedConstant()); | |
| 2346 var_map.Bind(assembler->UndefinedConstant()); | |
|
Benedikt Meurer
2016/10/13 05:07:19
You don't need to Bind var_result and var_map here
caitp
2016/10/13 22:32:43
They are, but as I mentioned, they still hit CHECK
| |
| 2347 | |
| 2348 assembler->Branch(assembler->TaggedIsSmi(var_array.value()), &call_to_object, | |
| 2349 &check_instance_type); | |
| 2350 assembler->Bind(&check_instance_type); | |
| 2351 { | |
| 2352 var_map.Bind(assembler->LoadMap(var_array.value())); | |
| 2353 Node* instance_type = assembler->LoadMapInstanceType(var_map.value()); | |
| 2354 assembler->GotoIf( | |
| 2355 assembler->Int32LessThan( | |
| 2356 instance_type, assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE)), | |
| 2357 &call_to_object); | |
| 2358 | |
| 2359 assembler->Branch( | |
| 2360 assembler->WordEqual(instance_type, | |
| 2361 assembler->Int32Constant(JS_ARRAY_TYPE)), | |
| 2362 &allocate_array_iterator, &allocate_typed_array_iterator); | |
|
Benedikt Meurer
2016/10/13 05:07:19
You need to handle the generic as well. Also non-f
caitp
2016/10/13 22:32:43
I'm not sure it's possible to skip the length chec
Benedikt Meurer
2016/10/14 03:46:50
What I'm saying is you need to do the map check de
| |
| 2363 } | |
| 2364 | |
| 2365 assembler->Bind(&call_to_object); | |
| 2366 { | |
| 2367 Callable callable = CodeFactory::ToObject(assembler->isolate()); | |
| 2368 Node* result = assembler->CallStub(callable, context, var_array.value()); | |
| 2369 var_array.Bind(result); | |
| 2370 assembler->Goto(&allocate_array_iterator); | |
| 2371 } | |
| 2372 | |
| 2373 assembler->Bind(&allocate_array_iterator); | |
| 2374 { | |
| 2375 Node* map_index = assembler->IntPtrConstant( | |
| 2376 Context::GENERIC_ARRAY_KEY_ITERATOR_MAP_INDEX); | |
| 2377 Node* map = assembler->LoadFixedArrayElement( | |
| 2378 native_context, map_index, 0, CodeStubAssembler::INTPTR_PARAMETERS); | |
| 2379 Node* iterator = assembler->Allocate(JSArrayIterator::kSize); | |
| 2380 assembler->StoreMapNoWriteBarrier(iterator, map); | |
| 2381 assembler->StoreObjectFieldRoot(iterator, | |
| 2382 JSIteratorResult::kPropertiesOffset, | |
| 2383 Heap::kEmptyFixedArrayRootIndex); | |
| 2384 assembler->StoreObjectFieldRoot(iterator, JSIteratorResult::kElementsOffset, | |
| 2385 Heap::kEmptyFixedArrayRootIndex); | |
| 2386 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2387 iterator, JSArrayIterator::kIteratedObjectOffset, var_array.value()); | |
| 2388 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2389 iterator, JSArrayIterator::kNextIndexOffset, | |
| 2390 assembler->SmiConstant(Smi::FromInt(0))); | |
| 2391 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2392 iterator, JSArrayIterator::kIteratedObjectMapOffset, var_map.value()); | |
| 2393 assembler->Return(iterator); | |
| 2394 } | |
| 2395 | |
| 2396 assembler->Bind(&allocate_typed_array_iterator); | |
| 2397 { | |
| 2398 Node* map_index = | |
| 2399 assembler->IntPtrConstant(Context::TYPED_ARRAY_KEY_ITERATOR_MAP_INDEX); | |
| 2400 Node* map = assembler->LoadFixedArrayElement( | |
| 2401 native_context, map_index, 0, CodeStubAssembler::INTPTR_PARAMETERS); | |
| 2402 Node* iterator = assembler->Allocate(JSTypedArrayIterator::kSize); | |
| 2403 assembler->StoreMapNoWriteBarrier(iterator, map); | |
| 2404 assembler->StoreObjectFieldRoot(iterator, | |
| 2405 JSTypedArrayIterator::kPropertiesOffset, | |
| 2406 Heap::kEmptyFixedArrayRootIndex); | |
| 2407 assembler->StoreObjectFieldRoot(iterator, | |
| 2408 JSTypedArrayIterator::kElementsOffset, | |
| 2409 Heap::kEmptyFixedArrayRootIndex); | |
| 2410 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2411 iterator, JSTypedArrayIterator::kIteratedObjectOffset, | |
| 2412 var_array.value()); | |
| 2413 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2414 iterator, JSTypedArrayIterator::kNextIndexOffset, | |
| 2415 assembler->SmiConstant(Smi::FromInt(0))); | |
| 2416 assembler->Return(iterator); | |
| 2417 } | |
| 2418 } | |
| 2419 | |
| 2420 void Builtins::Generate_ArrayIteratorPrototypeNext( | |
| 2421 CodeStubAssembler* assembler) { | |
| 2422 typedef compiler::Node Node; | |
| 2423 typedef CodeStubAssembler::Label Label; | |
| 2424 typedef CodeStubAssembler::Variable Variable; | |
| 2425 | |
| 2426 Variable var_value(assembler, MachineRepresentation::kTagged); | |
| 2427 Variable var_done(assembler, MachineRepresentation::kTagged); | |
| 2428 Variable var_result(assembler, MachineRepresentation::kTagged); | |
| 2429 | |
| 2430 Label set_done_and_return(assembler); | |
| 2431 Label did_set_done(assembler); | |
| 2432 Label allocate_entry_if_needed(assembler); | |
| 2433 Label allocate_iterator_result(assembler); | |
| 2434 Label throw_bad_receiver(assembler); | |
| 2435 | |
| 2436 Label if_isarray(assembler); | |
| 2437 Label if_istypedarray(assembler); | |
| 2438 Label if_slow(assembler); | |
| 2439 Label if_slownotkeyiterator(assembler); | |
| 2440 | |
| 2441 var_value.Bind(assembler->UndefinedConstant()); | |
| 2442 var_done.Bind(assembler->BooleanConstant(false)); | |
| 2443 var_result.Bind(assembler->UndefinedConstant()); | |
| 2444 | |
| 2445 Node* iterator = assembler->Parameter(0); | |
| 2446 Node* context = assembler->Parameter(3); | |
| 2447 | |
| 2448 // If O does not have all of the internal slots of an Array Iterator Instance | |
| 2449 // (22.1.5.3), throw a TypeError exception | |
| 2450 assembler->GotoIf(assembler->TaggedIsSmi(iterator), &throw_bad_receiver); | |
| 2451 Node* instance_type = assembler->LoadInstanceType(iterator); | |
| 2452 // FIXME: Use bitmasks instead of integer ranges | |
|
Benedikt Meurer
2016/10/13 05:07:19
You can subtract the base and then do a single uns
caitp
2016/10/13 22:32:43
Done, seems to be working nicely.
| |
| 2453 assembler->GotoIf( | |
| 2454 assembler->Int32LessThan( | |
| 2455 instance_type, assembler->Int32Constant(FIRST_ARRAY_ITERATOR_TYPE)), | |
| 2456 &throw_bad_receiver); | |
| 2457 assembler->GotoIf( | |
| 2458 assembler->Int32GreaterThan( | |
| 2459 instance_type, assembler->Int32Constant(LAST_ARRAY_ITERATOR_TYPE)), | |
| 2460 &throw_bad_receiver); | |
| 2461 | |
| 2462 Node* native_context = assembler->LoadNativeContext(context); | |
| 2463 | |
| 2464 // Let a be O.[[IteratedObject]]. | |
| 2465 STATIC_ASSERT(JSArrayIterator::kIteratedObjectOffset == | |
| 2466 JSTypedArrayIterator::kIteratedObjectOffset); | |
| 2467 Node* array = assembler->LoadObjectField( | |
| 2468 iterator, JSArrayIterator::kIteratedObjectOffset); | |
| 2469 | |
| 2470 Node* array_map = assembler->LoadMap(array); | |
| 2471 Node* array_type = assembler->LoadMapInstanceType(array_map); | |
| 2472 | |
| 2473 // If a is undefined, return CreateIterResultObject(undefined, true) | |
| 2474 assembler->GotoIf(assembler->WordEqual(array, assembler->UndefinedConstant()), | |
| 2475 &did_set_done); | |
| 2476 | |
| 2477 // Let index be O.[[ArrayIteratorNextIndex]]. | |
| 2478 STATIC_ASSERT(JSArrayIterator::kNextIndexOffset == | |
| 2479 JSTypedArrayIterator::kNextIndexOffset); | |
| 2480 Node* index = | |
| 2481 assembler->LoadObjectField(iterator, JSArrayIterator::kNextIndexOffset); | |
| 2482 | |
| 2483 assembler->GotoIf(assembler->Word32Equal( | |
|
Benedikt Meurer
2016/10/13 05:07:19
How about just having a single switch over all rel
caitp
2016/10/13 22:32:43
Done
| |
| 2484 array_type, assembler->Int32Constant(JS_ARRAY_TYPE)), | |
| 2485 &if_isarray); | |
| 2486 | |
| 2487 assembler->Branch( | |
| 2488 assembler->Word32Equal(array_type, | |
| 2489 assembler->Int32Constant(JS_TYPED_ARRAY_TYPE)), | |
| 2490 &if_istypedarray, &if_slow); | |
| 2491 | |
| 2492 assembler->Bind(&if_isarray); | |
| 2493 { // JSArray-specialized algorithm for fast JSArrays | |
|
Benedikt Meurer
2016/10/13 05:07:19
You can only take the fast JSArray case if the arr
caitp
2016/10/13 22:32:43
I'll add some new interesting tests to ensure all
| |
| 2494 assembler->Assert(assembler->TaggedIsSmi(index)); | |
| 2495 | |
| 2496 Node* length = assembler->LoadObjectField(array, JSArray::kLengthOffset); | |
| 2497 assembler->GotoIf(assembler->SmiAboveOrEqual(index, length), | |
| 2498 &set_done_and_return); | |
| 2499 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2500 iterator, JSStringIterator::kNextIndexOffset, | |
| 2501 assembler->SmiAdd(index, assembler->SmiConstant(Smi::FromInt(1)))); | |
| 2502 | |
| 2503 Label if_keyiterator(assembler), if_notkeyiterator(assembler); | |
| 2504 | |
| 2505 assembler->Branch( | |
| 2506 assembler->WordEqual( | |
| 2507 instance_type, | |
| 2508 assembler->Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), | |
| 2509 &if_keyiterator, &if_notkeyiterator); | |
| 2510 | |
| 2511 assembler->Bind(&if_keyiterator); | |
| 2512 { | |
| 2513 var_value.Bind(index); | |
| 2514 assembler->Goto(&allocate_iterator_result); | |
| 2515 } | |
| 2516 | |
| 2517 assembler->Bind(&if_notkeyiterator); | |
| 2518 { | |
| 2519 assembler->GotoIf( | |
| 2520 assembler->WordEqual(instance_type, | |
| 2521 assembler->Int32Constant( | |
| 2522 JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE)), | |
| 2523 &if_slow); | |
| 2524 assembler->GotoIf( | |
| 2525 assembler->WordEqual( | |
| 2526 instance_type, | |
| 2527 assembler->Int32Constant(JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE)), | |
| 2528 &if_slownotkeyiterator); | |
| 2529 Node* orig_map = assembler->LoadObjectField( | |
| 2530 iterator, JSArrayIterator::kIteratedObjectMapOffset); | |
| 2531 assembler->GotoIf(assembler->WordNotEqual(orig_map, array_map), | |
| 2532 &if_slownotkeyiterator); | |
| 2533 | |
| 2534 Node* elements = assembler->LoadElements(array); | |
| 2535 static int32_t kInstanceType[] = { | |
| 2536 JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
| 2537 JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
| 2538 JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
| 2539 JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
| 2540 JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
| 2541 JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
| 2542 | |
| 2543 JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE, | |
| 2544 JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE, | |
| 2545 JS_FAST_ARRAY_VALUE_ITERATOR_TYPE, | |
| 2546 JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE, | |
| 2547 JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE, | |
| 2548 JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE, | |
| 2549 }; | |
| 2550 | |
| 2551 Label if_smiorobjects(assembler), if_doubles(assembler); | |
| 2552 Label* instance_type_handlers[] = { | |
| 2553 &if_smiorobjects, &if_smiorobjects, &if_smiorobjects, | |
| 2554 &if_smiorobjects, &if_doubles, &if_doubles, | |
| 2555 &if_smiorobjects, &if_smiorobjects, &if_smiorobjects, | |
| 2556 &if_smiorobjects, &if_doubles, &if_doubles}; | |
| 2557 | |
| 2558 assembler->Switch(instance_type, &set_done_and_return, kInstanceType, | |
| 2559 instance_type_handlers, arraysize(kInstanceType)); | |
| 2560 | |
| 2561 assembler->Bind(&if_smiorobjects); | |
| 2562 { | |
| 2563 Node* value = assembler->LoadFixedArrayElement( | |
| 2564 elements, index, 0, CodeStubAssembler::SMI_PARAMETERS); | |
| 2565 var_value.Bind(assembler->UndefinedConstant()); | |
| 2566 assembler->GotoIf( | |
| 2567 assembler->WordEqual(value, assembler->TheHoleConstant()), | |
| 2568 &allocate_entry_if_needed); | |
| 2569 var_value.Bind(value); | |
| 2570 assembler->Goto(&allocate_entry_if_needed); | |
| 2571 } | |
| 2572 | |
| 2573 assembler->Bind(&if_doubles); | |
| 2574 { | |
| 2575 Node* value = assembler->LoadFixedDoubleArrayElement( | |
| 2576 elements, index, MachineType::Float64(), 0, | |
| 2577 CodeStubAssembler::SMI_PARAMETERS, &allocate_entry_if_needed); | |
| 2578 var_value.Bind(assembler->AllocateHeapNumberWithValue(value)); | |
| 2579 assembler->Goto(&allocate_entry_if_needed); | |
| 2580 } | |
| 2581 } | |
| 2582 } | |
| 2583 | |
| 2584 assembler->Bind(&if_istypedarray); | |
| 2585 { // Special-cased algorithm for JSTypedArrays | |
| 2586 assembler->Assert(assembler->TaggedIsSmi(index)); | |
| 2587 | |
| 2588 Node* length = assembler->LoadObjectField(array, JSArray::kLengthOffset); | |
| 2589 assembler->GotoIf(assembler->SmiAboveOrEqual(index, length), | |
| 2590 &set_done_and_return); | |
| 2591 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2592 iterator, JSStringIterator::kNextIndexOffset, | |
| 2593 assembler->SmiAdd(index, assembler->SmiConstant(Smi::FromInt(1)))); | |
| 2594 | |
| 2595 Label if_keyiterator(assembler), if_notkeyiterator(assembler); | |
| 2596 | |
| 2597 assembler->Branch(assembler->WordEqual( | |
| 2598 instance_type, assembler->Int32Constant( | |
| 2599 JS_TYPED_ARRAY_KEY_ITERATOR_TYPE)), | |
| 2600 &if_keyiterator, &if_notkeyiterator); | |
| 2601 | |
| 2602 assembler->Bind(&if_keyiterator); | |
| 2603 { | |
| 2604 var_value.Bind(index); | |
| 2605 assembler->Goto(&allocate_iterator_result); | |
| 2606 } | |
| 2607 | |
| 2608 assembler->Bind(&if_notkeyiterator); | |
| 2609 { | |
| 2610 Node* elements = assembler->LoadElements(array); | |
| 2611 Node* base_pointer = assembler->LoadObjectField( | |
| 2612 elements, FixedTypedArrayBase::kBasePointerOffset); | |
| 2613 Node* external_pointer = assembler->LoadObjectField( | |
| 2614 elements, FixedTypedArrayBase::kExternalPointerOffset); | |
| 2615 Node* data_pointer = assembler->IntPtrAdd(base_pointer, external_pointer); | |
| 2616 | |
| 2617 static int32_t kInstanceType[] = { | |
| 2618 JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
| 2619 JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
| 2620 JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
| 2621 JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
| 2622 JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
| 2623 JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
| 2624 JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
| 2625 JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
| 2626 JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
| 2627 | |
| 2628 JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE, | |
| 2629 JS_INT8_ARRAY_VALUE_ITERATOR_TYPE, | |
| 2630 JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE, | |
| 2631 JS_INT16_ARRAY_VALUE_ITERATOR_TYPE, | |
| 2632 JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE, | |
| 2633 JS_INT32_ARRAY_VALUE_ITERATOR_TYPE, | |
| 2634 JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE, | |
| 2635 JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE, | |
| 2636 JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE, | |
| 2637 }; | |
| 2638 | |
| 2639 Label if_uint8(assembler), if_int8(assembler), if_uint16(assembler), | |
| 2640 if_int16(assembler), if_uint32(assembler), if_int32(assembler), | |
| 2641 if_float32(assembler), if_float64(assembler); | |
| 2642 Label* instance_type_handlers[] = { | |
| 2643 &if_uint8, &if_int8, &if_uint16, &if_int16, &if_uint32, | |
| 2644 &if_int32, &if_float32, &if_float64, &if_uint8, &if_uint8, | |
| 2645 &if_int8, &if_uint16, &if_int16, &if_uint32, &if_int32, | |
| 2646 &if_float32, &if_float64, &if_uint8}; | |
| 2647 | |
| 2648 assembler->Switch(instance_type, &set_done_and_return, kInstanceType, | |
| 2649 instance_type_handlers, arraysize(kInstanceType)); | |
| 2650 | |
| 2651 assembler->Bind(&if_uint8); | |
| 2652 { | |
| 2653 Node* value_uint8 = assembler->LoadFixedTypedArrayElement( | |
| 2654 data_pointer, index, UINT8_ELEMENTS, | |
| 2655 CodeStubAssembler::SMI_PARAMETERS); | |
| 2656 var_value.Bind(assembler->SmiFromWord(value_uint8)); | |
| 2657 assembler->Goto(&allocate_entry_if_needed); | |
| 2658 } | |
| 2659 assembler->Bind(&if_int8); | |
| 2660 { | |
| 2661 Node* value_int8 = assembler->LoadFixedTypedArrayElement( | |
| 2662 data_pointer, index, INT8_ELEMENTS, | |
| 2663 CodeStubAssembler::SMI_PARAMETERS); | |
| 2664 var_value.Bind(assembler->SmiFromWord(value_int8)); | |
| 2665 assembler->Goto(&allocate_entry_if_needed); | |
| 2666 } | |
| 2667 assembler->Bind(&if_uint16); | |
| 2668 { | |
| 2669 Node* value_uint16 = assembler->LoadFixedTypedArrayElement( | |
| 2670 data_pointer, index, UINT16_ELEMENTS, | |
| 2671 CodeStubAssembler::SMI_PARAMETERS); | |
| 2672 var_value.Bind(assembler->SmiFromWord(value_uint16)); | |
| 2673 assembler->Goto(&allocate_entry_if_needed); | |
| 2674 } | |
| 2675 assembler->Bind(&if_int16); | |
| 2676 { | |
| 2677 Node* value_int16 = assembler->LoadFixedTypedArrayElement( | |
| 2678 data_pointer, index, INT16_ELEMENTS, | |
| 2679 CodeStubAssembler::SMI_PARAMETERS); | |
| 2680 var_value.Bind(assembler->SmiFromWord(value_int16)); | |
| 2681 assembler->Goto(&allocate_entry_if_needed); | |
| 2682 } | |
| 2683 assembler->Bind(&if_uint32); | |
| 2684 { | |
| 2685 Node* value_uint32 = assembler->LoadFixedTypedArrayElement( | |
| 2686 data_pointer, index, UINT32_ELEMENTS, | |
| 2687 CodeStubAssembler::SMI_PARAMETERS); | |
| 2688 var_value.Bind(assembler->ChangeUint32ToTagged(value_uint32)); | |
| 2689 assembler->Goto(&allocate_entry_if_needed); | |
| 2690 } | |
| 2691 assembler->Bind(&if_int32); | |
| 2692 { | |
| 2693 Node* value_int32 = assembler->LoadFixedTypedArrayElement( | |
| 2694 data_pointer, index, INT32_ELEMENTS, | |
| 2695 CodeStubAssembler::SMI_PARAMETERS); | |
| 2696 var_value.Bind(assembler->ChangeInt32ToTagged(value_int32)); | |
| 2697 assembler->Goto(&allocate_entry_if_needed); | |
| 2698 } | |
| 2699 assembler->Bind(&if_float32); | |
| 2700 { | |
| 2701 Node* value_float32 = assembler->LoadFixedTypedArrayElement( | |
| 2702 data_pointer, index, FLOAT32_ELEMENTS, | |
| 2703 CodeStubAssembler::SMI_PARAMETERS); | |
| 2704 var_value.Bind(assembler->AllocateHeapNumberWithValue( | |
| 2705 assembler->ChangeFloat32ToFloat64(value_float32))); | |
| 2706 assembler->Goto(&allocate_entry_if_needed); | |
| 2707 } | |
| 2708 assembler->Bind(&if_float64); | |
| 2709 { | |
| 2710 Node* value_float64 = assembler->LoadFixedTypedArrayElement( | |
| 2711 data_pointer, index, FLOAT64_ELEMENTS, | |
| 2712 CodeStubAssembler::SMI_PARAMETERS); | |
| 2713 var_value.Bind(assembler->AllocateHeapNumberWithValue(value_float64)); | |
| 2714 assembler->Goto(&allocate_entry_if_needed); | |
| 2715 } | |
| 2716 } | |
| 2717 } | |
| 2718 | |
| 2719 assembler->Bind(&if_slow); | |
| 2720 { // Generic objects | |
| 2721 Label if_slowkeyiterator(assembler); | |
| 2722 // Let len be ? ToLength(? Get(a, "length")). | |
| 2723 Node* length; | |
| 2724 { | |
| 2725 Callable get_property = CodeFactory::GetProperty(assembler->isolate()); | |
| 2726 length = assembler->CallStub( | |
| 2727 get_property, context, array, | |
| 2728 assembler->HeapConstant( | |
| 2729 assembler->isolate()->factory()->length_string())); | |
| 2730 Callable to_length = CodeFactory::ToLength(assembler->isolate()); | |
| 2731 length = assembler->CallStub(to_length, context, length); | |
| 2732 } | |
| 2733 | |
| 2734 // If index ≥ len, then <goto set_done_and_return> | |
| 2735 { | |
| 2736 Label if_notdone(assembler), if_smi(assembler), if_heapnum(assembler); | |
| 2737 | |
| 2738 assembler->Branch(assembler->TaggedIsSmi(length), &if_smi, &if_heapnum); | |
| 2739 | |
| 2740 assembler->Bind(&if_smi); | |
| 2741 { | |
| 2742 // Are these shortcuts valid? | |
| 2743 assembler->GotoUnless(assembler->TaggedIsSmi(index), | |
| 2744 &set_done_and_return); | |
| 2745 assembler->Branch(assembler->SmiBelow(index, length), &if_notdone, | |
| 2746 &set_done_and_return); | |
| 2747 } | |
| 2748 | |
| 2749 assembler->Bind(&if_heapnum); | |
| 2750 { | |
| 2751 // Are these shortcuts valid? | |
| 2752 assembler->GotoIf(assembler->TaggedIsSmi(index), &if_notdone); | |
| 2753 assembler->Branch( | |
| 2754 assembler->Float64LessThan(assembler->LoadHeapNumberValue(index), | |
| 2755 assembler->LoadHeapNumberValue(length)), | |
| 2756 &if_notdone, &set_done_and_return); | |
| 2757 } | |
| 2758 | |
| 2759 assembler->Bind(&if_notdone); | |
| 2760 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2761 iterator, JSStringIterator::kNextIndexOffset, | |
| 2762 assembler->NumberInc(index)); | |
| 2763 | |
| 2764 assembler->Branch( | |
| 2765 assembler->WordEqual( | |
| 2766 instance_type, | |
| 2767 assembler->Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), | |
| 2768 &if_slowkeyiterator, &if_slownotkeyiterator); | |
| 2769 } | |
| 2770 | |
| 2771 assembler->Bind(&if_slowkeyiterator); | |
| 2772 { | |
| 2773 var_value.Bind(index); | |
| 2774 assembler->Goto(&allocate_iterator_result); | |
| 2775 } | |
| 2776 | |
| 2777 assembler->Bind(&if_slownotkeyiterator); | |
| 2778 { | |
| 2779 Callable callable = CodeFactory::GetProperty(assembler->isolate()); | |
| 2780 var_value.Bind(assembler->CallStub(callable, context, array, index)); | |
| 2781 assembler->Goto(&allocate_entry_if_needed); | |
| 2782 } | |
| 2783 } | |
| 2784 | |
| 2785 assembler->Bind(&set_done_and_return); | |
| 2786 { | |
| 2787 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2788 iterator, JSTypedArrayIterator::kIteratedObjectOffset, | |
| 2789 assembler->UndefinedConstant()); | |
| 2790 assembler->Goto(&did_set_done); | |
| 2791 assembler->Bind(&did_set_done); | |
| 2792 { | |
| 2793 var_value.Bind(assembler->UndefinedConstant()); | |
| 2794 var_done.Bind(assembler->TrueConstant()); | |
| 2795 assembler->Goto(&allocate_iterator_result); | |
| 2796 } | |
| 2797 } | |
| 2798 | |
| 2799 assembler->Bind(&allocate_entry_if_needed); | |
| 2800 { | |
| 2801 assembler->GotoIf( | |
| 2802 assembler->Int32GreaterThan( | |
| 2803 instance_type, | |
| 2804 assembler->Int32Constant(LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE)), | |
| 2805 &allocate_iterator_result); | |
| 2806 Node* elements = assembler->AllocateFixedArray(FAST_ELEMENTS, | |
| 2807 assembler->Int32Constant(2)); | |
| 2808 assembler->StoreFixedArrayElement(elements, assembler->Int32Constant(0), | |
| 2809 index, SKIP_WRITE_BARRIER); | |
| 2810 assembler->StoreFixedArrayElement(elements, assembler->Int32Constant(1), | |
| 2811 var_value.value(), SKIP_WRITE_BARRIER); | |
| 2812 | |
| 2813 Node* entry = assembler->Allocate(JSArray::kSize); | |
| 2814 Node* map = assembler->LoadFixedArrayElement( | |
| 2815 native_context, | |
| 2816 assembler->IntPtrConstant(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX), 0, | |
| 2817 CodeStubAssembler::INTPTR_PARAMETERS); | |
| 2818 | |
| 2819 assembler->StoreMapNoWriteBarrier(entry, map); | |
| 2820 assembler->StoreObjectFieldRoot(entry, JSArray::kPropertiesOffset, | |
| 2821 Heap::kEmptyFixedArrayRootIndex); | |
| 2822 assembler->StoreObjectFieldNoWriteBarrier(entry, JSArray::kElementsOffset, | |
| 2823 elements); | |
| 2824 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2825 entry, JSArray::kLengthOffset, assembler->SmiConstant(Smi::FromInt(2))); | |
| 2826 | |
| 2827 var_value.Bind(entry); | |
| 2828 assembler->Goto(&allocate_iterator_result); | |
| 2829 } | |
| 2830 | |
| 2831 assembler->Bind(&allocate_iterator_result); | |
| 2832 { | |
| 2833 Node* result = assembler->Allocate(JSIteratorResult::kSize); | |
| 2834 Node* map = assembler->LoadFixedArrayElement( | |
| 2835 native_context, | |
| 2836 assembler->IntPtrConstant(Context::ITERATOR_RESULT_MAP_INDEX), 0, | |
| 2837 CodeStubAssembler::INTPTR_PARAMETERS); | |
| 2838 assembler->StoreMapNoWriteBarrier(result, map); | |
| 2839 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset, | |
| 2840 Heap::kEmptyFixedArrayRootIndex); | |
| 2841 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset, | |
| 2842 Heap::kEmptyFixedArrayRootIndex); | |
| 2843 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2844 result, JSIteratorResult::kValueOffset, var_value.value()); | |
| 2845 assembler->StoreObjectFieldNoWriteBarrier( | |
| 2846 result, JSIteratorResult::kDoneOffset, var_done.value()); | |
| 2847 assembler->Return(result); | |
| 2848 } | |
| 2849 | |
| 2850 assembler->Bind(&throw_bad_receiver); | |
| 2851 { | |
| 2852 // The {receiver} is not a valid JSArrayIterator or JSTypedArrayIterator. | |
| 2853 Node* result = assembler->CallRuntime( | |
| 2854 Runtime::kThrowIncompatibleMethodReceiver, context, | |
| 2855 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked( | |
| 2856 "Array Iterator.prototype.next", TENURED)), | |
| 2857 iterator); | |
| 2858 assembler->Return(result); | |
| 2859 } | |
| 2860 } | |
| 2861 | |
| 2070 } // namespace internal | 2862 } // namespace internal |
| 2071 } // namespace v8 | 2863 } // namespace v8 |
| OLD | NEW |