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 namespace { |
| 2072 |
| 2073 template <IterationKind kIterationKind> |
| 2074 void Generate_ArrayPrototypeIterationMethod(CodeStubAssembler* assembler) { |
| 2075 typedef compiler::Node Node; |
| 2076 typedef CodeStubAssembler::Label Label; |
| 2077 typedef CodeStubAssembler::Variable Variable; |
| 2078 |
| 2079 Node* receiver = assembler->Parameter(0); |
| 2080 Node* context = assembler->Parameter(3); |
| 2081 |
| 2082 Variable var_array(assembler, MachineRepresentation::kTagged); |
| 2083 Variable var_map(assembler, MachineRepresentation::kTagged); |
| 2084 Variable var_type(assembler, MachineRepresentation::kWord32); |
| 2085 |
| 2086 Label if_isnotobject(assembler, Label::kDeferred); |
| 2087 Label create_array_iterator(assembler); |
| 2088 |
| 2089 assembler->GotoIf(assembler->TaggedIsSmi(receiver), &if_isnotobject); |
| 2090 var_array.Bind(receiver); |
| 2091 var_map.Bind(assembler->LoadMap(receiver)); |
| 2092 var_type.Bind(assembler->LoadMapInstanceType(var_map.value())); |
| 2093 assembler->Branch( |
| 2094 assembler->Int32LessThan( |
| 2095 var_type.value(), assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE)), |
| 2096 &if_isnotobject, &create_array_iterator); |
| 2097 |
| 2098 assembler->Bind(&if_isnotobject); |
| 2099 { |
| 2100 Callable callable = CodeFactory::ToObject(assembler->isolate()); |
| 2101 Node* result = assembler->CallStub(callable, context, receiver); |
| 2102 var_array.Bind(result); |
| 2103 var_map.Bind(assembler->LoadMap(result)); |
| 2104 var_type.Bind(assembler->LoadMapInstanceType(var_map.value())); |
| 2105 assembler->Goto(&create_array_iterator); |
| 2106 } |
| 2107 |
| 2108 assembler->Bind(&create_array_iterator); |
| 2109 assembler->Return(assembler->CreateArrayIterator( |
| 2110 var_array.value(), var_map.value(), var_type.value(), context, |
| 2111 kIterationKind)); |
| 2112 } |
| 2113 } // namespace |
| 2114 |
| 2115 void Builtins::Generate_ArrayPrototypeValues(CodeStubAssembler* assembler) { |
| 2116 Generate_ArrayPrototypeIterationMethod<IterationKind::kValues>(assembler); |
| 2117 } |
| 2118 |
| 2119 void Builtins::Generate_ArrayPrototypeEntries(CodeStubAssembler* assembler) { |
| 2120 Generate_ArrayPrototypeIterationMethod<IterationKind::kEntries>(assembler); |
| 2121 } |
| 2122 |
| 2123 void Builtins::Generate_ArrayPrototypeKeys(CodeStubAssembler* assembler) { |
| 2124 Generate_ArrayPrototypeIterationMethod<IterationKind::kKeys>(assembler); |
| 2125 } |
| 2126 |
| 2127 void Builtins::Generate_ArrayIteratorPrototypeNext( |
| 2128 CodeStubAssembler* assembler) { |
| 2129 typedef compiler::Node Node; |
| 2130 typedef CodeStubAssembler::Label Label; |
| 2131 typedef CodeStubAssembler::Variable Variable; |
| 2132 |
| 2133 Variable var_value(assembler, MachineRepresentation::kTagged); |
| 2134 Variable var_done(assembler, MachineRepresentation::kTagged); |
| 2135 Variable var_result(assembler, MachineRepresentation::kTagged); |
| 2136 |
| 2137 Label set_done_and_return(assembler); |
| 2138 Label did_set_done(assembler); |
| 2139 Label allocate_entry_if_needed(assembler); |
| 2140 Label allocate_iterator_result(assembler); |
| 2141 Label throw_bad_receiver(assembler); |
| 2142 |
| 2143 Label if_isarray(assembler); |
| 2144 Label if_istypedarray(assembler); |
| 2145 Label if_slow(assembler); |
| 2146 Label if_slownotkeyiterator(assembler); |
| 2147 |
| 2148 var_value.Bind(assembler->UndefinedConstant()); |
| 2149 var_done.Bind(assembler->BooleanConstant(false)); |
| 2150 var_result.Bind(assembler->UndefinedConstant()); |
| 2151 |
| 2152 Node* iterator = assembler->Parameter(0); |
| 2153 Node* context = assembler->Parameter(3); |
| 2154 |
| 2155 // If O does not have all of the internal slots of an Array Iterator Instance |
| 2156 // (22.1.5.3), throw a TypeError exception |
| 2157 assembler->GotoIf(assembler->TaggedIsSmi(iterator), &throw_bad_receiver); |
| 2158 Node* instance_type = assembler->LoadInstanceType(iterator); |
| 2159 assembler->GotoIf( |
| 2160 assembler->Uint32LessThan( |
| 2161 assembler->Int32Constant(LAST_ARRAY_ITERATOR_TYPE - |
| 2162 FIRST_ARRAY_ITERATOR_TYPE), |
| 2163 assembler->Int32Sub(instance_type, assembler->Int32Constant( |
| 2164 FIRST_ARRAY_ITERATOR_TYPE))), |
| 2165 &throw_bad_receiver); |
| 2166 |
| 2167 // Let a be O.[[IteratedObject]]. |
| 2168 STATIC_ASSERT(JSArrayIterator::kIteratedObjectOffset == |
| 2169 JSTypedArrayIterator::kIteratedObjectOffset); |
| 2170 Node* array = assembler->LoadObjectField( |
| 2171 iterator, JSArrayIterator::kIteratedObjectOffset); |
| 2172 |
| 2173 // If a is undefined, return CreateIterResultObject(undefined, true) |
| 2174 assembler->GotoIf(assembler->WordEqual(array, assembler->UndefinedConstant()), |
| 2175 &did_set_done); |
| 2176 |
| 2177 // Let index be O.[[ArrayIteratorNextIndex]]. |
| 2178 STATIC_ASSERT(JSArrayIterator::kNextIndexOffset == |
| 2179 JSTypedArrayIterator::kNextIndexOffset); |
| 2180 Node* index = |
| 2181 assembler->LoadObjectField(iterator, JSArrayIterator::kNextIndexOffset); |
| 2182 |
| 2183 Node* array_map = assembler->LoadMap(array); |
| 2184 Node* array_type = assembler->LoadMapInstanceType(array_map); |
| 2185 |
| 2186 Variable var_length(assembler, MachineRepresentation::kTagged); |
| 2187 Variable var_orig_map(assembler, MachineRepresentation::kTagged); |
| 2188 Variable var_typed_elements(assembler, MachineType::PointerRepresentation()); |
| 2189 Variable var_elements(assembler, MachineRepresentation::kTagged); |
| 2190 var_orig_map.Bind(assembler->UndefinedConstant()); |
| 2191 var_typed_elements.Bind(assembler->IntPtrConstant(0)); |
| 2192 var_elements.Bind(assembler->LoadElements(array)); |
| 2193 { |
| 2194 Label load_array_length(assembler), load_typedarray_length(assembler), |
| 2195 load_length_slow(assembler), did_get_length(assembler), |
| 2196 did_increment_next_index(assembler); |
| 2197 assembler->GotoIf(assembler->Word32Equal( |
| 2198 array_type, assembler->Int32Constant(JS_ARRAY_TYPE)), |
| 2199 &load_array_length); |
| 2200 assembler->Branch( |
| 2201 assembler->Word32Equal(array_type, |
| 2202 assembler->Int32Constant(JS_TYPED_ARRAY_TYPE)), |
| 2203 &load_typedarray_length, &load_length_slow); |
| 2204 |
| 2205 assembler->Bind(&load_array_length); |
| 2206 { |
| 2207 var_orig_map.Bind(assembler->LoadObjectField( |
| 2208 iterator, JSArrayIterator::kIteratedObjectMapOffset)); |
| 2209 var_length.Bind( |
| 2210 assembler->LoadObjectField(array, JSArray::kLengthOffset)); |
| 2211 assembler->Goto(&did_get_length); |
| 2212 } |
| 2213 |
| 2214 assembler->Bind(&load_typedarray_length); |
| 2215 { |
| 2216 assembler->Assert(assembler->TaggedIsSmi(index)); |
| 2217 var_typed_elements.Bind(assembler->IntPtrAdd( |
| 2218 assembler->LoadObjectField(var_elements.value(), |
| 2219 FixedTypedArrayBase::kBasePointerOffset), |
| 2220 assembler->LoadObjectField( |
| 2221 var_elements.value(), |
| 2222 FixedTypedArrayBase::kExternalPointerOffset))); |
| 2223 var_length.Bind( |
| 2224 assembler->LoadObjectField(array, JSTypedArray::kLengthOffset)); |
| 2225 assembler->Goto(&did_get_length); |
| 2226 } |
| 2227 |
| 2228 assembler->Bind(&load_length_slow); |
| 2229 { |
| 2230 Node* length_string = assembler->HeapConstant( |
| 2231 assembler->isolate()->factory()->length_string()); |
| 2232 Callable get_length = CodeFactory::GetProperty(assembler->isolate()); |
| 2233 Node* length = |
| 2234 assembler->CallStub(get_length, context, array, length_string); |
| 2235 Callable to_length = CodeFactory::ToLength(assembler->isolate()); |
| 2236 var_length.Bind(assembler->CallStub(to_length, context, length)); |
| 2237 assembler->Goto(&did_get_length); |
| 2238 } |
| 2239 |
| 2240 assembler->Bind(&did_get_length); |
| 2241 { |
| 2242 Label if_notdone(assembler), if_smi(assembler), if_heapnum(assembler); |
| 2243 Node* length = var_length.value(); |
| 2244 assembler->Branch(assembler->TaggedIsSmi(length), &if_smi, &if_heapnum); |
| 2245 |
| 2246 assembler->Bind(&if_smi); |
| 2247 { |
| 2248 // Are these shortcuts valid? |
| 2249 assembler->GotoUnless(assembler->TaggedIsSmi(index), |
| 2250 &set_done_and_return); |
| 2251 assembler->Branch(assembler->SmiBelow(index, length), &if_notdone, |
| 2252 &set_done_and_return); |
| 2253 } |
| 2254 |
| 2255 assembler->Bind(&if_heapnum); |
| 2256 { |
| 2257 // Are these shortcuts valid? |
| 2258 assembler->GotoIf(assembler->TaggedIsSmi(index), &if_notdone); |
| 2259 assembler->Branch( |
| 2260 assembler->Float64LessThan(assembler->LoadHeapNumberValue(index), |
| 2261 assembler->LoadHeapNumberValue(length)), |
| 2262 &if_notdone, &set_done_and_return); |
| 2263 } |
| 2264 |
| 2265 assembler->Bind(&if_notdone); |
| 2266 assembler->StoreObjectFieldNoWriteBarrier( |
| 2267 iterator, JSStringIterator::kNextIndexOffset, |
| 2268 assembler->NumberInc(index)); |
| 2269 |
| 2270 assembler->Goto(&did_increment_next_index); |
| 2271 } |
| 2272 |
| 2273 assembler->Bind(&did_increment_next_index); |
| 2274 } |
| 2275 |
| 2276 static int32_t kInstanceType[] = { |
| 2277 JS_TYPED_ARRAY_KEY_ITERATOR_TYPE, |
| 2278 JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE, |
| 2279 |
| 2280 JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
| 2281 JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
| 2282 JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
| 2283 JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
| 2284 JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
| 2285 JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
| 2286 JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
| 2287 JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
| 2288 JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
| 2289 |
| 2290 JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
| 2291 JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
| 2292 JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
| 2293 JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
| 2294 JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
| 2295 JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
| 2296 JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
| 2297 |
| 2298 JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE, |
| 2299 JS_INT8_ARRAY_VALUE_ITERATOR_TYPE, |
| 2300 JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE, |
| 2301 JS_INT16_ARRAY_VALUE_ITERATOR_TYPE, |
| 2302 JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE, |
| 2303 JS_INT32_ARRAY_VALUE_ITERATOR_TYPE, |
| 2304 JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE, |
| 2305 JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE, |
| 2306 JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE, |
| 2307 |
| 2308 JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE, |
| 2309 JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE, |
| 2310 JS_FAST_ARRAY_VALUE_ITERATOR_TYPE, |
| 2311 JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE, |
| 2312 JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE, |
| 2313 JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE, |
| 2314 JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE}; |
| 2315 |
| 2316 Label keys(assembler, Label::kDeferred); |
| 2317 Label object_values(assembler, Label::kDeferred); |
| 2318 Label double_values(assembler, Label::kDeferred); |
| 2319 Label generic_values(assembler, Label::kDeferred); |
| 2320 Label uint8_values(assembler, Label::kDeferred); |
| 2321 Label int8_values(assembler, Label::kDeferred); |
| 2322 Label uint16_values(assembler, Label::kDeferred); |
| 2323 Label int16_values(assembler, Label::kDeferred); |
| 2324 Label uint32_values(assembler, Label::kDeferred); |
| 2325 Label int32_values(assembler, Label::kDeferred); |
| 2326 Label float32_values(assembler, Label::kDeferred); |
| 2327 Label float64_values(assembler, Label::kDeferred); |
| 2328 |
| 2329 Label* kInstanceTypeHandlers[] = { |
| 2330 &keys, &keys, &uint8_values, &int8_values, |
| 2331 &uint16_values, &int16_values, &uint32_values, &int32_values, |
| 2332 &float32_values, &float64_values, &uint8_values, &object_values, |
| 2333 &object_values, &object_values, &object_values, &double_values, |
| 2334 &double_values, &generic_values, &uint8_values, &int8_values, |
| 2335 &uint16_values, &int16_values, &uint32_values, &int32_values, |
| 2336 &float32_values, &float64_values, &uint8_values, &object_values, |
| 2337 &object_values, &object_values, &object_values, &double_values, |
| 2338 &double_values, &generic_values, |
| 2339 }; |
| 2340 |
| 2341 assembler->Switch(instance_type, &set_done_and_return, kInstanceType, |
| 2342 kInstanceTypeHandlers, arraysize(kInstanceType)); |
| 2343 |
| 2344 assembler->Bind(&keys); |
| 2345 { |
| 2346 var_value.Bind(index); |
| 2347 assembler->Goto(&allocate_iterator_result); |
| 2348 } |
| 2349 |
| 2350 assembler->Bind(&object_values); |
| 2351 { |
| 2352 assembler->GotoIf(assembler->WordNotEqual(var_orig_map.value(), array_map), |
| 2353 &generic_values); |
| 2354 |
| 2355 Label is_smi(assembler), is_heapnum(assembler), do_load(assembler); |
| 2356 Variable var_idx(assembler, MachineRepresentation::kWord32); |
| 2357 var_idx.Bind(assembler->Int32Constant(0)); |
| 2358 |
| 2359 assembler->Branch(assembler->TaggedIsSmi(index), &is_smi, &is_heapnum); |
| 2360 |
| 2361 assembler->Bind(&is_smi); |
| 2362 { |
| 2363 var_idx.Bind(assembler->SmiToWord32(index)); |
| 2364 assembler->Goto(&do_load); |
| 2365 } |
| 2366 |
| 2367 assembler->Bind(&is_heapnum); |
| 2368 { |
| 2369 var_idx.Bind(assembler->TruncateFloat64ToWord32( |
| 2370 assembler->LoadHeapNumberValue(index))); |
| 2371 assembler->Goto(&do_load); |
| 2372 } |
| 2373 |
| 2374 assembler->Bind(&do_load); |
| 2375 var_value.Bind(assembler->LoadFixedArrayElement(var_elements.value(), |
| 2376 var_idx.value(), 0)); |
| 2377 assembler->GotoUnless( |
| 2378 assembler->WordEqual(var_value.value(), assembler->TheHoleConstant()), |
| 2379 &allocate_entry_if_needed); |
| 2380 var_value.Bind(assembler->UndefinedConstant()); |
| 2381 assembler->Goto(&allocate_entry_if_needed); |
| 2382 } |
| 2383 |
| 2384 assembler->Bind(&double_values); |
| 2385 { |
| 2386 assembler->GotoIf(assembler->WordNotEqual(var_orig_map.value(), array_map), |
| 2387 &generic_values); |
| 2388 |
| 2389 Label is_smi(assembler), is_heapnum(assembler), do_load(assembler); |
| 2390 Variable var_idx(assembler, MachineRepresentation::kWord32); |
| 2391 var_idx.Bind(assembler->Int32Constant(0)); |
| 2392 |
| 2393 assembler->Branch(assembler->TaggedIsSmi(index), &is_smi, &is_heapnum); |
| 2394 |
| 2395 assembler->Bind(&is_smi); |
| 2396 { |
| 2397 var_idx.Bind(assembler->SmiToWord32(index)); |
| 2398 assembler->Goto(&do_load); |
| 2399 } |
| 2400 |
| 2401 assembler->Bind(&is_heapnum); |
| 2402 { |
| 2403 var_idx.Bind(assembler->TruncateFloat64ToWord32( |
| 2404 assembler->LoadHeapNumberValue(index))); |
| 2405 assembler->Goto(&do_load); |
| 2406 } |
| 2407 |
| 2408 assembler->Bind(&do_load); |
| 2409 var_value.Bind(assembler->UndefinedConstant()); |
| 2410 Node* value = assembler->LoadFixedDoubleArrayElement( |
| 2411 var_elements.value(), var_idx.value(), MachineType::Float64(), 0, |
| 2412 CodeStubAssembler::INTEGER_PARAMETERS, &allocate_entry_if_needed); |
| 2413 var_value.Bind(assembler->AllocateHeapNumberWithValue(value)); |
| 2414 assembler->Goto(&allocate_entry_if_needed); |
| 2415 } |
| 2416 |
| 2417 assembler->Bind(&generic_values); |
| 2418 { |
| 2419 Callable callable = CodeFactory::GetProperty(assembler->isolate()); |
| 2420 var_value.Bind(assembler->CallStub(callable, context, array, index)); |
| 2421 assembler->Goto(&allocate_entry_if_needed); |
| 2422 } |
| 2423 |
| 2424 assembler->Bind(&uint8_values); |
| 2425 { |
| 2426 Node* value_uint8 = assembler->LoadFixedTypedArrayElement( |
| 2427 var_typed_elements.value(), index, UINT8_ELEMENTS, |
| 2428 CodeStubAssembler::SMI_PARAMETERS); |
| 2429 var_value.Bind(assembler->SmiFromWord(value_uint8)); |
| 2430 assembler->Goto(&allocate_entry_if_needed); |
| 2431 } |
| 2432 |
| 2433 assembler->Bind(&int8_values); |
| 2434 { |
| 2435 Node* value_int8 = assembler->LoadFixedTypedArrayElement( |
| 2436 var_typed_elements.value(), index, INT8_ELEMENTS, |
| 2437 CodeStubAssembler::SMI_PARAMETERS); |
| 2438 var_value.Bind(assembler->SmiFromWord(value_int8)); |
| 2439 assembler->Goto(&allocate_entry_if_needed); |
| 2440 } |
| 2441 |
| 2442 assembler->Bind(&uint16_values); |
| 2443 { |
| 2444 Node* value_uint16 = assembler->LoadFixedTypedArrayElement( |
| 2445 var_typed_elements.value(), index, UINT16_ELEMENTS, |
| 2446 CodeStubAssembler::SMI_PARAMETERS); |
| 2447 var_value.Bind(assembler->SmiFromWord(value_uint16)); |
| 2448 assembler->Goto(&allocate_entry_if_needed); |
| 2449 } |
| 2450 |
| 2451 assembler->Bind(&int16_values); |
| 2452 { |
| 2453 Node* value_int16 = assembler->LoadFixedTypedArrayElement( |
| 2454 var_typed_elements.value(), index, INT16_ELEMENTS, |
| 2455 CodeStubAssembler::SMI_PARAMETERS); |
| 2456 var_value.Bind(assembler->SmiFromWord(value_int16)); |
| 2457 assembler->Goto(&allocate_entry_if_needed); |
| 2458 } |
| 2459 |
| 2460 assembler->Bind(&uint32_values); |
| 2461 { |
| 2462 Node* value_uint32 = assembler->LoadFixedTypedArrayElement( |
| 2463 var_typed_elements.value(), index, UINT32_ELEMENTS, |
| 2464 CodeStubAssembler::SMI_PARAMETERS); |
| 2465 var_value.Bind(assembler->ChangeUint32ToTagged(value_uint32)); |
| 2466 assembler->Goto(&allocate_entry_if_needed); |
| 2467 } |
| 2468 assembler->Bind(&int32_values); |
| 2469 { |
| 2470 Node* value_int32 = assembler->LoadFixedTypedArrayElement( |
| 2471 var_typed_elements.value(), index, INT32_ELEMENTS, |
| 2472 CodeStubAssembler::SMI_PARAMETERS); |
| 2473 var_value.Bind(assembler->ChangeInt32ToTagged(value_int32)); |
| 2474 assembler->Goto(&allocate_entry_if_needed); |
| 2475 } |
| 2476 assembler->Bind(&float32_values); |
| 2477 { |
| 2478 Node* value_float32 = assembler->LoadFixedTypedArrayElement( |
| 2479 var_typed_elements.value(), index, FLOAT32_ELEMENTS, |
| 2480 CodeStubAssembler::SMI_PARAMETERS); |
| 2481 var_value.Bind(assembler->AllocateHeapNumberWithValue( |
| 2482 assembler->ChangeFloat32ToFloat64(value_float32))); |
| 2483 assembler->Goto(&allocate_entry_if_needed); |
| 2484 } |
| 2485 assembler->Bind(&float64_values); |
| 2486 { |
| 2487 Node* value_float64 = assembler->LoadFixedTypedArrayElement( |
| 2488 var_typed_elements.value(), index, FLOAT64_ELEMENTS, |
| 2489 CodeStubAssembler::SMI_PARAMETERS); |
| 2490 var_value.Bind(assembler->AllocateHeapNumberWithValue(value_float64)); |
| 2491 assembler->Goto(&allocate_entry_if_needed); |
| 2492 } |
| 2493 |
| 2494 assembler->Bind(&set_done_and_return); |
| 2495 { |
| 2496 assembler->StoreObjectFieldNoWriteBarrier( |
| 2497 iterator, JSTypedArrayIterator::kIteratedObjectOffset, |
| 2498 assembler->UndefinedConstant()); |
| 2499 assembler->Goto(&did_set_done); |
| 2500 assembler->Bind(&did_set_done); |
| 2501 { |
| 2502 var_value.Bind(assembler->UndefinedConstant()); |
| 2503 var_done.Bind(assembler->TrueConstant()); |
| 2504 assembler->Goto(&allocate_iterator_result); |
| 2505 } |
| 2506 } |
| 2507 |
| 2508 assembler->Bind(&allocate_entry_if_needed); |
| 2509 { |
| 2510 assembler->GotoIf( |
| 2511 assembler->Int32GreaterThan( |
| 2512 instance_type, |
| 2513 assembler->Int32Constant(LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE)), |
| 2514 &allocate_iterator_result); |
| 2515 Node* elements = assembler->AllocateFixedArray(FAST_ELEMENTS, |
| 2516 assembler->Int32Constant(2)); |
| 2517 assembler->StoreFixedArrayElement(elements, assembler->Int32Constant(0), |
| 2518 index, SKIP_WRITE_BARRIER); |
| 2519 assembler->StoreFixedArrayElement(elements, assembler->Int32Constant(1), |
| 2520 var_value.value(), SKIP_WRITE_BARRIER); |
| 2521 |
| 2522 Node* entry = assembler->Allocate(JSArray::kSize); |
| 2523 Node* map = assembler->LoadFixedArrayElement( |
| 2524 assembler->LoadNativeContext(context), |
| 2525 assembler->IntPtrConstant(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX), 0, |
| 2526 CodeStubAssembler::INTPTR_PARAMETERS); |
| 2527 |
| 2528 assembler->StoreMapNoWriteBarrier(entry, map); |
| 2529 assembler->StoreObjectFieldRoot(entry, JSArray::kPropertiesOffset, |
| 2530 Heap::kEmptyFixedArrayRootIndex); |
| 2531 assembler->StoreObjectFieldNoWriteBarrier(entry, JSArray::kElementsOffset, |
| 2532 elements); |
| 2533 assembler->StoreObjectFieldNoWriteBarrier( |
| 2534 entry, JSArray::kLengthOffset, assembler->SmiConstant(Smi::FromInt(2))); |
| 2535 |
| 2536 var_value.Bind(entry); |
| 2537 assembler->Goto(&allocate_iterator_result); |
| 2538 } |
| 2539 |
| 2540 assembler->Bind(&allocate_iterator_result); |
| 2541 { |
| 2542 Node* result = assembler->Allocate(JSIteratorResult::kSize); |
| 2543 Node* map = assembler->LoadFixedArrayElement( |
| 2544 assembler->LoadNativeContext(context), |
| 2545 assembler->IntPtrConstant(Context::ITERATOR_RESULT_MAP_INDEX), 0, |
| 2546 CodeStubAssembler::INTPTR_PARAMETERS); |
| 2547 assembler->StoreMapNoWriteBarrier(result, map); |
| 2548 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset, |
| 2549 Heap::kEmptyFixedArrayRootIndex); |
| 2550 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset, |
| 2551 Heap::kEmptyFixedArrayRootIndex); |
| 2552 assembler->StoreObjectFieldNoWriteBarrier( |
| 2553 result, JSIteratorResult::kValueOffset, var_value.value()); |
| 2554 assembler->StoreObjectFieldNoWriteBarrier( |
| 2555 result, JSIteratorResult::kDoneOffset, var_done.value()); |
| 2556 assembler->Return(result); |
| 2557 } |
| 2558 |
| 2559 assembler->Bind(&throw_bad_receiver); |
| 2560 { |
| 2561 // The {receiver} is not a valid JSArrayIterator or JSTypedArrayIterator. |
| 2562 Node* result = assembler->CallRuntime( |
| 2563 Runtime::kThrowIncompatibleMethodReceiver, context, |
| 2564 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked( |
| 2565 "Array Iterator.prototype.next", TENURED)), |
| 2566 iterator); |
| 2567 assembler->Return(result); |
| 2568 } |
| 2569 } |
| 2570 |
2070 } // namespace internal | 2571 } // namespace internal |
2071 } // namespace v8 | 2572 } // namespace v8 |
OLD | NEW |