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