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