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( | |
Benedikt Meurer
2016/10/14 03:46:50
You can use CodeStubAssembler::IsJSReceiverInstanc
| |
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 Node* iterator = assembler->Parameter(0); | |
2149 Node* context = assembler->Parameter(3); | |
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 STATIC_ASSERT(JSArrayIterator::kIteratedObjectOffset == | |
2165 JSTypedArrayIterator::kIteratedObjectOffset); | |
2166 Node* array = assembler->LoadObjectField( | |
2167 iterator, JSArrayIterator::kIteratedObjectOffset); | |
2168 | |
2169 // If a is undefined, return CreateIterResultObject(undefined, true) | |
2170 assembler->GotoIf(assembler->WordEqual(array, assembler->UndefinedConstant()), | |
2171 &did_set_done); | |
2172 | |
2173 // Let index be O.[[ArrayIteratorNextIndex]]. | |
2174 STATIC_ASSERT(JSArrayIterator::kNextIndexOffset == | |
2175 JSTypedArrayIterator::kNextIndexOffset); | |
2176 Node* index = | |
2177 assembler->LoadObjectField(iterator, JSArrayIterator::kNextIndexOffset); | |
2178 | |
2179 Node* array_map = assembler->LoadMap(array); | |
2180 Node* array_type = assembler->LoadMapInstanceType(array_map); | |
2181 | |
2182 Variable var_length(assembler, MachineRepresentation::kTagged); | |
2183 Variable var_orig_map(assembler, MachineRepresentation::kTagged); | |
2184 Variable var_typed_elements(assembler, MachineType::PointerRepresentation()); | |
2185 Variable var_elements(assembler, MachineRepresentation::kTagged); | |
2186 var_orig_map.Bind(assembler->UndefinedConstant()); | |
2187 var_typed_elements.Bind(assembler->IntPtrConstant(0)); | |
2188 var_elements.Bind(assembler->LoadElements(array)); | |
2189 { | |
2190 Label load_array_length(assembler), load_typedarray_length(assembler), | |
2191 load_length_slow(assembler), did_get_length(assembler), | |
2192 did_increment_next_index(assembler); | |
2193 assembler->GotoIf(assembler->Word32Equal( | |
Benedikt Meurer
2016/10/14 03:46:50
What is the motivation to not do a big switch on t
caitp
2016/10/14 03:57:15
I suppose there's no reason not to do it, other th
Benedikt Meurer
2016/10/14 04:11:18
As said, I'm perfectly happy if you say the other
| |
2194 array_type, assembler->Int32Constant(JS_ARRAY_TYPE)), | |
2195 &load_array_length); | |
2196 assembler->Branch( | |
2197 assembler->Word32Equal(array_type, | |
2198 assembler->Int32Constant(JS_TYPED_ARRAY_TYPE)), | |
2199 &load_typedarray_length, &load_length_slow); | |
2200 | |
2201 assembler->Bind(&load_array_length); | |
2202 { | |
2203 var_orig_map.Bind(assembler->LoadObjectField( | |
2204 iterator, JSArrayIterator::kIteratedObjectMapOffset)); | |
2205 var_length.Bind( | |
2206 assembler->LoadObjectField(array, JSArray::kLengthOffset)); | |
Benedikt Meurer
2016/10/14 03:46:50
This is only valid if the array map didn't change
caitp
2016/10/14 03:57:15
I don't think it's possible to alter the way "leng
Benedikt Meurer
2016/10/14 04:11:18
Ah, indeed, you are right.
Ok, so this reduces to
| |
2207 assembler->Goto(&did_get_length); | |
2208 } | |
2209 | |
2210 assembler->Bind(&load_typedarray_length); | |
2211 { | |
2212 assembler->Assert(assembler->TaggedIsSmi(index)); | |
2213 var_typed_elements.Bind(assembler->IntPtrAdd( | |
2214 assembler->LoadObjectField(var_elements.value(), | |
2215 FixedTypedArrayBase::kBasePointerOffset), | |
2216 assembler->LoadObjectField( | |
2217 var_elements.value(), | |
2218 FixedTypedArrayBase::kExternalPointerOffset))); | |
2219 var_length.Bind( | |
2220 assembler->LoadObjectField(array, JSTypedArray::kLengthOffset)); | |
2221 assembler->Goto(&did_get_length); | |
2222 } | |
2223 | |
2224 assembler->Bind(&load_length_slow); | |
2225 { | |
2226 Node* length_string = assembler->HeapConstant( | |
2227 assembler->isolate()->factory()->length_string()); | |
2228 Callable get_length = CodeFactory::GetProperty(assembler->isolate()); | |
2229 Node* length = | |
2230 assembler->CallStub(get_length, context, array, length_string); | |
2231 Callable to_length = CodeFactory::ToLength(assembler->isolate()); | |
2232 var_length.Bind(assembler->CallStub(to_length, context, length)); | |
2233 assembler->Goto(&did_get_length); | |
2234 } | |
2235 | |
2236 assembler->Bind(&did_get_length); | |
2237 { | |
2238 Label if_notdone(assembler), if_smi(assembler), if_heapnum(assembler); | |
2239 Node* length = var_length.value(); | |
2240 assembler->Branch(assembler->TaggedIsSmi(length), &if_smi, &if_heapnum); | |
2241 | |
2242 assembler->Bind(&if_smi); | |
2243 { | |
2244 // Are these shortcuts valid? | |
2245 assembler->GotoUnless(assembler->TaggedIsSmi(index), | |
2246 &set_done_and_return); | |
2247 assembler->Branch(assembler->SmiBelow(index, length), &if_notdone, | |
2248 &set_done_and_return); | |
2249 } | |
2250 | |
2251 assembler->Bind(&if_heapnum); | |
2252 { | |
2253 // Are these shortcuts valid? | |
2254 assembler->GotoIf(assembler->TaggedIsSmi(index), &if_notdone); | |
2255 assembler->Branch( | |
2256 assembler->Float64LessThan(assembler->LoadHeapNumberValue(index), | |
2257 assembler->LoadHeapNumberValue(length)), | |
2258 &if_notdone, &set_done_and_return); | |
2259 } | |
2260 | |
2261 assembler->Bind(&if_notdone); | |
2262 assembler->StoreObjectFieldNoWriteBarrier( | |
2263 iterator, JSStringIterator::kNextIndexOffset, | |
2264 assembler->NumberInc(index)); | |
2265 | |
2266 assembler->Goto(&did_increment_next_index); | |
2267 } | |
2268 | |
2269 assembler->Bind(&did_increment_next_index); | |
2270 var_done.Bind(assembler->BooleanConstant(false)); | |
2271 } | |
2272 | |
2273 static int32_t kInstanceType[] = { | |
2274 JS_TYPED_ARRAY_KEY_ITERATOR_TYPE, | |
2275 JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE, | |
2276 | |
2277 JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2278 JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2279 JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2280 JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2281 JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2282 JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2283 JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2284 JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2285 JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2286 | |
2287 JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2288 JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2289 JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2290 JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2291 JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2292 JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2293 JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2294 | |
2295 JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE, | |
2296 JS_INT8_ARRAY_VALUE_ITERATOR_TYPE, | |
2297 JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE, | |
2298 JS_INT16_ARRAY_VALUE_ITERATOR_TYPE, | |
2299 JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE, | |
2300 JS_INT32_ARRAY_VALUE_ITERATOR_TYPE, | |
2301 JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE, | |
2302 JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE, | |
2303 JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE, | |
2304 | |
2305 JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE, | |
2306 JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE, | |
2307 JS_FAST_ARRAY_VALUE_ITERATOR_TYPE, | |
2308 JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE, | |
2309 JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE, | |
2310 JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE, | |
2311 JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE}; | |
2312 | |
2313 Label keys(assembler, Label::kDeferred); | |
2314 Label object_values(assembler, Label::kDeferred); | |
2315 Label double_values(assembler, Label::kDeferred); | |
2316 Label generic_values(assembler, Label::kDeferred); | |
2317 Label uint8_values(assembler, Label::kDeferred); | |
2318 Label int8_values(assembler, Label::kDeferred); | |
2319 Label uint16_values(assembler, Label::kDeferred); | |
2320 Label int16_values(assembler, Label::kDeferred); | |
2321 Label uint32_values(assembler, Label::kDeferred); | |
2322 Label int32_values(assembler, Label::kDeferred); | |
2323 Label float32_values(assembler, Label::kDeferred); | |
2324 Label float64_values(assembler, Label::kDeferred); | |
2325 | |
2326 Label* kInstanceTypeHandlers[] = { | |
2327 &keys, &keys, &uint8_values, &int8_values, | |
2328 &uint16_values, &int16_values, &uint32_values, &int32_values, | |
2329 &float32_values, &float64_values, &uint8_values, &object_values, | |
2330 &object_values, &object_values, &object_values, &double_values, | |
2331 &double_values, &generic_values, &uint8_values, &int8_values, | |
2332 &uint16_values, &int16_values, &uint32_values, &int32_values, | |
2333 &float32_values, &float64_values, &uint8_values, &object_values, | |
2334 &object_values, &object_values, &object_values, &double_values, | |
2335 &double_values, &generic_values, | |
2336 }; | |
2337 | |
2338 assembler->Switch(instance_type, &set_done_and_return, kInstanceType, | |
2339 kInstanceTypeHandlers, arraysize(kInstanceType)); | |
2340 | |
2341 assembler->Bind(&keys); | |
2342 { | |
2343 var_value.Bind(index); | |
2344 assembler->Goto(&allocate_iterator_result); | |
2345 } | |
2346 | |
2347 assembler->Bind(&object_values); | |
2348 { | |
2349 assembler->GotoIf(assembler->WordNotEqual(var_orig_map.value(), array_map), | |
2350 &generic_values); | |
2351 | |
2352 Label is_smi(assembler), is_heapnum(assembler), do_load(assembler); | |
2353 Variable var_idx(assembler, MachineRepresentation::kWord32); | |
2354 | |
2355 assembler->Branch(assembler->TaggedIsSmi(index), &is_smi, &is_heapnum); | |
2356 | |
2357 assembler->Bind(&is_smi); | |
2358 { | |
2359 var_idx.Bind(assembler->SmiToWord32(index)); | |
2360 assembler->Goto(&do_load); | |
2361 } | |
2362 | |
2363 assembler->Bind(&is_heapnum); | |
2364 { | |
2365 var_idx.Bind(assembler->TruncateFloat64ToWord32( | |
2366 assembler->LoadHeapNumberValue(index))); | |
2367 assembler->Goto(&do_load); | |
2368 } | |
2369 | |
2370 assembler->Bind(&do_load); | |
2371 var_value.Bind(assembler->LoadFixedArrayElement(var_elements.value(), | |
2372 var_idx.value(), 0)); | |
2373 assembler->GotoUnless( | |
2374 assembler->WordEqual(var_value.value(), assembler->TheHoleConstant()), | |
2375 &allocate_entry_if_needed); | |
2376 var_value.Bind(assembler->UndefinedConstant()); | |
2377 assembler->Goto(&allocate_entry_if_needed); | |
2378 } | |
2379 | |
2380 assembler->Bind(&double_values); | |
2381 { | |
2382 assembler->GotoIf(assembler->WordNotEqual(var_orig_map.value(), array_map), | |
2383 &generic_values); | |
2384 | |
2385 Label is_smi(assembler), is_heapnum(assembler), do_load(assembler); | |
2386 Variable var_idx(assembler, MachineRepresentation::kWord32); | |
2387 | |
2388 assembler->Branch(assembler->TaggedIsSmi(index), &is_smi, &is_heapnum); | |
2389 | |
2390 assembler->Bind(&is_smi); | |
2391 { | |
2392 var_idx.Bind(assembler->SmiToWord32(index)); | |
2393 assembler->Goto(&do_load); | |
2394 } | |
2395 | |
2396 assembler->Bind(&is_heapnum); | |
2397 { | |
2398 var_idx.Bind(assembler->TruncateFloat64ToWord32( | |
2399 assembler->LoadHeapNumberValue(index))); | |
2400 assembler->Goto(&do_load); | |
2401 } | |
2402 | |
2403 assembler->Bind(&do_load); | |
2404 var_value.Bind(assembler->UndefinedConstant()); | |
2405 Node* value = assembler->LoadFixedDoubleArrayElement( | |
2406 var_elements.value(), var_idx.value(), MachineType::Float64(), 0, | |
2407 CodeStubAssembler::INTEGER_PARAMETERS, &allocate_entry_if_needed); | |
2408 var_value.Bind(assembler->AllocateHeapNumberWithValue(value)); | |
2409 assembler->Goto(&allocate_entry_if_needed); | |
2410 } | |
2411 | |
2412 assembler->Bind(&generic_values); | |
2413 { | |
2414 Callable callable = CodeFactory::GetProperty(assembler->isolate()); | |
2415 var_value.Bind(assembler->CallStub(callable, context, array, index)); | |
2416 assembler->Goto(&allocate_entry_if_needed); | |
2417 } | |
2418 | |
2419 assembler->Bind(&uint8_values); | |
2420 { | |
2421 Node* value_uint8 = assembler->LoadFixedTypedArrayElement( | |
2422 var_typed_elements.value(), index, UINT8_ELEMENTS, | |
2423 CodeStubAssembler::SMI_PARAMETERS); | |
2424 var_value.Bind(assembler->SmiFromWord(value_uint8)); | |
2425 assembler->Goto(&allocate_entry_if_needed); | |
2426 } | |
2427 | |
2428 assembler->Bind(&int8_values); | |
2429 { | |
2430 Node* value_int8 = assembler->LoadFixedTypedArrayElement( | |
2431 var_typed_elements.value(), index, INT8_ELEMENTS, | |
2432 CodeStubAssembler::SMI_PARAMETERS); | |
2433 var_value.Bind(assembler->SmiFromWord(value_int8)); | |
2434 assembler->Goto(&allocate_entry_if_needed); | |
2435 } | |
2436 | |
2437 assembler->Bind(&uint16_values); | |
2438 { | |
2439 Node* value_uint16 = assembler->LoadFixedTypedArrayElement( | |
2440 var_typed_elements.value(), index, UINT16_ELEMENTS, | |
2441 CodeStubAssembler::SMI_PARAMETERS); | |
2442 var_value.Bind(assembler->SmiFromWord(value_uint16)); | |
2443 assembler->Goto(&allocate_entry_if_needed); | |
2444 } | |
2445 | |
2446 assembler->Bind(&int16_values); | |
2447 { | |
2448 Node* value_int16 = assembler->LoadFixedTypedArrayElement( | |
2449 var_typed_elements.value(), index, INT16_ELEMENTS, | |
2450 CodeStubAssembler::SMI_PARAMETERS); | |
2451 var_value.Bind(assembler->SmiFromWord(value_int16)); | |
2452 assembler->Goto(&allocate_entry_if_needed); | |
2453 } | |
2454 | |
2455 assembler->Bind(&uint32_values); | |
2456 { | |
2457 Node* value_uint32 = assembler->LoadFixedTypedArrayElement( | |
2458 var_typed_elements.value(), index, UINT32_ELEMENTS, | |
2459 CodeStubAssembler::SMI_PARAMETERS); | |
2460 var_value.Bind(assembler->ChangeUint32ToTagged(value_uint32)); | |
2461 assembler->Goto(&allocate_entry_if_needed); | |
2462 } | |
2463 assembler->Bind(&int32_values); | |
2464 { | |
2465 Node* value_int32 = assembler->LoadFixedTypedArrayElement( | |
2466 var_typed_elements.value(), index, INT32_ELEMENTS, | |
2467 CodeStubAssembler::SMI_PARAMETERS); | |
2468 var_value.Bind(assembler->ChangeInt32ToTagged(value_int32)); | |
2469 assembler->Goto(&allocate_entry_if_needed); | |
2470 } | |
2471 assembler->Bind(&float32_values); | |
2472 { | |
2473 Node* value_float32 = assembler->LoadFixedTypedArrayElement( | |
2474 var_typed_elements.value(), index, FLOAT32_ELEMENTS, | |
2475 CodeStubAssembler::SMI_PARAMETERS); | |
2476 var_value.Bind(assembler->AllocateHeapNumberWithValue( | |
2477 assembler->ChangeFloat32ToFloat64(value_float32))); | |
2478 assembler->Goto(&allocate_entry_if_needed); | |
2479 } | |
2480 assembler->Bind(&float64_values); | |
2481 { | |
2482 Node* value_float64 = assembler->LoadFixedTypedArrayElement( | |
2483 var_typed_elements.value(), index, FLOAT64_ELEMENTS, | |
2484 CodeStubAssembler::SMI_PARAMETERS); | |
2485 var_value.Bind(assembler->AllocateHeapNumberWithValue(value_float64)); | |
2486 assembler->Goto(&allocate_entry_if_needed); | |
2487 } | |
2488 | |
2489 assembler->Bind(&set_done_and_return); | |
2490 { | |
2491 assembler->StoreObjectFieldNoWriteBarrier( | |
2492 iterator, JSTypedArrayIterator::kIteratedObjectOffset, | |
2493 assembler->UndefinedConstant()); | |
2494 assembler->Goto(&did_set_done); | |
2495 assembler->Bind(&did_set_done); | |
2496 { | |
2497 var_value.Bind(assembler->UndefinedConstant()); | |
2498 var_done.Bind(assembler->TrueConstant()); | |
2499 assembler->Goto(&allocate_iterator_result); | |
2500 } | |
2501 } | |
2502 | |
2503 assembler->Bind(&allocate_entry_if_needed); | |
2504 { | |
2505 assembler->GotoIf( | |
2506 assembler->Int32GreaterThan( | |
2507 instance_type, | |
2508 assembler->Int32Constant(LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE)), | |
2509 &allocate_iterator_result); | |
2510 Node* elements = assembler->AllocateFixedArray(FAST_ELEMENTS, | |
2511 assembler->Int32Constant(2)); | |
2512 assembler->StoreFixedArrayElement(elements, assembler->Int32Constant(0), | |
2513 index, SKIP_WRITE_BARRIER); | |
2514 assembler->StoreFixedArrayElement(elements, assembler->Int32Constant(1), | |
2515 var_value.value(), SKIP_WRITE_BARRIER); | |
2516 | |
2517 Node* entry = assembler->Allocate(JSArray::kSize); | |
2518 Node* map = assembler->LoadFixedArrayElement( | |
2519 assembler->LoadNativeContext(context), | |
2520 assembler->IntPtrConstant(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX), 0, | |
2521 CodeStubAssembler::INTPTR_PARAMETERS); | |
2522 | |
2523 assembler->StoreMapNoWriteBarrier(entry, map); | |
2524 assembler->StoreObjectFieldRoot(entry, JSArray::kPropertiesOffset, | |
2525 Heap::kEmptyFixedArrayRootIndex); | |
2526 assembler->StoreObjectFieldNoWriteBarrier(entry, JSArray::kElementsOffset, | |
2527 elements); | |
2528 assembler->StoreObjectFieldNoWriteBarrier( | |
2529 entry, JSArray::kLengthOffset, assembler->SmiConstant(Smi::FromInt(2))); | |
2530 | |
2531 var_value.Bind(entry); | |
2532 assembler->Goto(&allocate_iterator_result); | |
2533 } | |
2534 | |
2535 assembler->Bind(&allocate_iterator_result); | |
2536 { | |
2537 Node* result = assembler->Allocate(JSIteratorResult::kSize); | |
2538 Node* map = assembler->LoadFixedArrayElement( | |
2539 assembler->LoadNativeContext(context), | |
2540 assembler->IntPtrConstant(Context::ITERATOR_RESULT_MAP_INDEX), 0, | |
2541 CodeStubAssembler::INTPTR_PARAMETERS); | |
2542 assembler->StoreMapNoWriteBarrier(result, map); | |
2543 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset, | |
2544 Heap::kEmptyFixedArrayRootIndex); | |
2545 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset, | |
2546 Heap::kEmptyFixedArrayRootIndex); | |
2547 assembler->StoreObjectFieldNoWriteBarrier( | |
2548 result, JSIteratorResult::kValueOffset, var_value.value()); | |
2549 assembler->StoreObjectFieldNoWriteBarrier( | |
2550 result, JSIteratorResult::kDoneOffset, var_done.value()); | |
2551 assembler->Return(result); | |
2552 } | |
2553 | |
2554 assembler->Bind(&throw_bad_receiver); | |
2555 { | |
2556 // The {receiver} is not a valid JSArrayIterator or JSTypedArrayIterator. | |
2557 Node* result = assembler->CallRuntime( | |
2558 Runtime::kThrowIncompatibleMethodReceiver, context, | |
2559 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked( | |
2560 "Array Iterator.prototype.next", TENURED)), | |
2561 iterator); | |
2562 assembler->Return(result); | |
2563 } | |
2564 } | |
2565 | |
2070 } // namespace internal | 2566 } // namespace internal |
2071 } // namespace v8 | 2567 } // namespace v8 |
OLD | NEW |