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); | |
caitp
2016/10/17 18:11:37
Would anyone object to my adding an optional "name
| |
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/17 04:02:42
Use CodeStubAssembler::IsJSReceiverInstanceType
caitp
2016/10/18 00:16:50
Done.
| |
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 } | |
Benedikt Meurer
2016/10/17 04:02:42
Nit: Add empty line between the }s
caitp
2016/10/18 00:16:50
Done.
| |
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 | |
Benedikt Meurer
2016/10/17 04:02:42
Nit: s/thse/these
caitp
2016/10/18 00:16:50
Oops, done.
| |
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 generic_values(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 // Let index be O.[[ArrayIteratorNextIndex]]. | |
2168 Node* index = | |
2169 assembler->LoadObjectField(iterator, JSArrayIterator::kNextIndexOffset); | |
2170 Node* orig_map = assembler->LoadObjectField( | |
2171 iterator, JSArrayIterator::kIteratedObjectMapOffset); | |
2172 Node* array_map = assembler->LoadMap(array); | |
2173 | |
2174 Label if_isfastarray(assembler), if_isnotfastarray(assembler); | |
2175 | |
2176 assembler->Branch(assembler->WordEqual(orig_map, array_map), &if_isfastarray, | |
2177 &if_isnotfastarray); | |
2178 | |
2179 assembler->Bind(&if_isfastarray); | |
2180 { | |
2181 assembler->Assert( | |
2182 assembler->Word32Equal(assembler->LoadMapInstanceType(array_map), | |
2183 assembler->Int32Constant(JS_ARRAY_TYPE))); | |
2184 | |
2185 Node* length = assembler->LoadObjectField(array, JSArray::kLengthOffset); | |
2186 | |
2187 assembler->Assert(assembler->TaggedIsSmi(length)); | |
2188 assembler->Assert(assembler->TaggedIsSmi(index)); | |
2189 | |
2190 assembler->GotoUnless(assembler->SmiBelow(index, length), &set_done); | |
2191 | |
2192 Node* one = assembler->SmiConstant(Smi::FromInt(1)); | |
2193 assembler->StoreObjectFieldNoWriteBarrier( | |
2194 iterator, JSArrayIterator::kNextIndexOffset, | |
2195 assembler->IntPtrAdd(assembler->BitcastTaggedToWord(index), | |
2196 assembler->BitcastTaggedToWord(one))); | |
2197 | |
2198 var_done.Bind(assembler->FalseConstant()); | |
2199 Node* elements = assembler->LoadElements(array); | |
2200 | |
2201 static int32_t kInstanceType[] = { | |
2202 JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE, | |
2203 JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2204 JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2205 JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2206 JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2207 JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2208 JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2209 JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE, | |
2210 JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE, | |
2211 JS_FAST_ARRAY_VALUE_ITERATOR_TYPE, | |
2212 JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE, | |
2213 JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE, | |
2214 JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE, | |
2215 }; | |
2216 | |
2217 Label packed_object_values(assembler), holey_object_values(assembler), | |
2218 packed_double_values(assembler), holey_double_values(assembler); | |
2219 Label* kInstanceTypeHandlers[] = { | |
2220 &allocate_key_result, &packed_object_values, &holey_object_values, | |
2221 &packed_object_values, &holey_object_values, &packed_double_values, | |
2222 &holey_double_values, &packed_object_values, &holey_object_values, | |
2223 &packed_object_values, &holey_object_values, &packed_double_values, | |
2224 &holey_double_values}; | |
2225 | |
2226 assembler->Switch(instance_type, &throw_bad_receiver, kInstanceType, | |
2227 kInstanceTypeHandlers, arraysize(kInstanceType)); | |
2228 | |
2229 assembler->Bind(&packed_object_values); | |
2230 { | |
2231 var_value.Bind(assembler->LoadFixedArrayElement( | |
2232 elements, index, 0, CodeStubAssembler::SMI_PARAMETERS)); | |
2233 assembler->Goto(&allocate_entry_if_needed); | |
2234 } | |
2235 | |
2236 assembler->Bind(&packed_double_values); | |
2237 { | |
2238 Node* value = assembler->LoadFixedDoubleArrayElement( | |
2239 elements, index, MachineType::Float64(), 0, | |
2240 CodeStubAssembler::SMI_PARAMETERS); | |
2241 var_value.Bind(assembler->AllocateHeapNumberWithValue(value)); | |
2242 assembler->Goto(&allocate_entry_if_needed); | |
2243 } | |
2244 | |
2245 assembler->Bind(&holey_object_values); | |
2246 { | |
2247 // Check the array_protector cell, and take the slow path if it's invalid. | |
2248 Node* invalid = | |
2249 assembler->SmiConstant(Smi::FromInt(Isolate::kArrayProtectorInvalid)); | |
2250 Node* cell = assembler->LoadRoot(Heap::kArrayProtectorRootIndex); | |
2251 Node* cell_value = | |
2252 assembler->LoadObjectField(cell, PropertyCell::kValueOffset); | |
2253 assembler->GotoIf(assembler->WordEqual(cell_value, invalid), | |
2254 &generic_values); | |
2255 | |
2256 var_value.Bind(assembler->UndefinedConstant()); | |
2257 Node* value = assembler->LoadFixedArrayElement( | |
2258 elements, index, 0, CodeStubAssembler::SMI_PARAMETERS); | |
2259 assembler->GotoIf( | |
2260 assembler->WordEqual(value, assembler->TheHoleConstant()), | |
2261 &allocate_entry_if_needed); | |
2262 var_value.Bind(value); | |
2263 assembler->Goto(&allocate_entry_if_needed); | |
2264 } | |
2265 | |
2266 assembler->Bind(&holey_double_values); | |
2267 { | |
2268 // Check the array_protector cell, and take the slow path if it's invalid. | |
2269 Node* invalid = | |
2270 assembler->SmiConstant(Smi::FromInt(Isolate::kArrayProtectorInvalid)); | |
2271 Node* cell = assembler->LoadRoot(Heap::kArrayProtectorRootIndex); | |
2272 Node* cell_value = | |
2273 assembler->LoadObjectField(cell, PropertyCell::kValueOffset); | |
2274 assembler->GotoIf(assembler->WordEqual(cell_value, invalid), | |
2275 &generic_values); | |
2276 | |
2277 var_value.Bind(assembler->UndefinedConstant()); | |
2278 Node* value = assembler->LoadFixedDoubleArrayElement( | |
2279 elements, index, MachineType::Float64(), 0, | |
2280 CodeStubAssembler::SMI_PARAMETERS, &allocate_entry_if_needed); | |
2281 var_value.Bind(assembler->AllocateHeapNumberWithValue(value)); | |
2282 assembler->Goto(&allocate_entry_if_needed); | |
2283 } | |
2284 } | |
2285 | |
2286 assembler->Bind(&if_isnotfastarray); | |
2287 { | |
2288 Label if_istypedarray(assembler), if_isgeneric(assembler); | |
2289 | |
2290 // If a is undefined, return CreateIterResultObject(undefined, true) | |
2291 assembler->GotoIf( | |
2292 assembler->WordEqual(array, assembler->UndefinedConstant()), | |
2293 &did_set_done); | |
2294 | |
2295 assembler->Branch( | |
2296 assembler->Word32Equal(assembler->LoadInstanceType(array), | |
2297 assembler->Int32Constant(JS_TYPED_ARRAY_TYPE)), | |
2298 &if_istypedarray, &if_isgeneric); | |
2299 | |
2300 assembler->Bind(&if_isgeneric); | |
2301 { | |
2302 Node* length_string = assembler->HeapConstant( | |
2303 assembler->isolate()->factory()->length_string()); | |
2304 Callable get_property = CodeFactory::GetProperty(assembler->isolate()); | |
2305 Node* length = | |
2306 assembler->CallStub(get_property, context, array, length_string); | |
2307 Callable to_length = CodeFactory::ToLength(assembler->isolate()); | |
2308 length = assembler->CallStub(to_length, context, length); | |
2309 | |
2310 assembler->GotoUnlessNumberLessThan(index, length, &set_done); | |
2311 | |
2312 assembler->StoreObjectFieldNoWriteBarrier( | |
Benedikt Meurer
2016/10/17 04:02:42
The NumberInc can produce a HeapNumber and the ite
caitp
2016/10/18 00:16:50
And now there is a write barrier.
| |
2313 iterator, JSArrayIterator::kNextIndexOffset, | |
2314 assembler->NumberInc(index)); | |
2315 var_done.Bind(assembler->FalseConstant()); | |
2316 | |
2317 assembler->Branch( | |
2318 assembler->Word32Equal( | |
2319 instance_type, | |
2320 assembler->Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), | |
2321 &allocate_key_result, &generic_values); | |
2322 | |
2323 assembler->Bind(&generic_values); | |
2324 { | |
2325 Callable get_property = CodeFactory::GetProperty(assembler->isolate()); | |
2326 var_value.Bind( | |
2327 assembler->CallStub(get_property, context, array, index)); | |
2328 assembler->Goto(&allocate_entry_if_needed); | |
2329 } | |
2330 } | |
2331 | |
2332 assembler->Bind(&if_istypedarray); | |
2333 { | |
2334 Node* length = | |
2335 assembler->LoadObjectField(array, JSTypedArray::kLengthOffset); | |
2336 | |
2337 assembler->Assert(assembler->TaggedIsSmi(length)); | |
2338 assembler->Assert(assembler->TaggedIsSmi(index)); | |
2339 | |
2340 assembler->GotoUnless(assembler->SmiBelow(index, length), &set_done); | |
2341 | |
2342 Node* one = assembler->SmiConstant(Smi::FromInt(1)); | |
2343 assembler->StoreObjectFieldNoWriteBarrier( | |
2344 iterator, JSArrayIterator::kNextIndexOffset, | |
2345 assembler->IntPtrAdd(assembler->BitcastTaggedToWord(index), | |
2346 assembler->BitcastTaggedToWord(one))); | |
2347 var_done.Bind(assembler->FalseConstant()); | |
2348 | |
2349 Node* elements = assembler->LoadElements(array); | |
Benedikt Meurer
2016/10/17 04:02:42
You need to test whether the buffer is neutered he
caitp
2016/10/17 13:18:11
I'm not sure about this. I think we should treat l
caitp
2016/10/18 00:16:50
the if_istypedarray path now treats length as 0 if
| |
2350 Node* base_ptr = assembler->LoadObjectField( | |
2351 elements, FixedTypedArrayBase::kBasePointerOffset); | |
2352 Node* external_ptr = assembler->LoadObjectField( | |
2353 elements, FixedTypedArrayBase::kExternalPointerOffset); | |
2354 Node* data_ptr = assembler->IntPtrAdd(base_ptr, external_ptr); | |
2355 | |
2356 static int32_t kInstanceType[] = { | |
2357 JS_TYPED_ARRAY_KEY_ITERATOR_TYPE, | |
2358 JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2359 JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2360 JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2361 JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2362 JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2363 JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2364 JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2365 JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2366 JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE, | |
2367 JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE, | |
2368 JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE, | |
2369 JS_INT8_ARRAY_VALUE_ITERATOR_TYPE, | |
2370 JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE, | |
2371 JS_INT16_ARRAY_VALUE_ITERATOR_TYPE, | |
2372 JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE, | |
2373 JS_INT32_ARRAY_VALUE_ITERATOR_TYPE, | |
2374 JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE, | |
2375 JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE, | |
2376 }; | |
2377 | |
2378 Label uint8_values(assembler), int8_values(assembler), | |
2379 uint16_values(assembler), int16_values(assembler), | |
2380 uint32_values(assembler), int32_values(assembler), | |
2381 float32_values(assembler), float64_values(assembler); | |
2382 Label* kInstanceTypeHandlers[] = { | |
2383 &allocate_key_result, &uint8_values, &uint8_values, | |
2384 &int8_values, &uint16_values, &int16_values, | |
2385 &uint32_values, &int32_values, &float32_values, | |
2386 &float64_values, &uint8_values, &uint8_values, | |
2387 &int8_values, &uint16_values, &int16_values, | |
2388 &uint32_values, &int32_values, &float32_values, | |
2389 &float64_values, | |
2390 }; | |
2391 | |
2392 var_done.Bind(assembler->FalseConstant()); | |
2393 assembler->Switch(instance_type, &throw_bad_receiver, kInstanceType, | |
2394 kInstanceTypeHandlers, arraysize(kInstanceType)); | |
2395 | |
2396 assembler->Bind(&uint8_values); | |
2397 { | |
2398 Node* value_uint8 = assembler->LoadFixedTypedArrayElement( | |
2399 data_ptr, index, UINT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); | |
2400 var_value.Bind(assembler->SmiFromWord(value_uint8)); | |
2401 assembler->Goto(&allocate_entry_if_needed); | |
2402 } | |
2403 | |
2404 assembler->Bind(&int8_values); | |
2405 { | |
2406 Node* value_int8 = assembler->LoadFixedTypedArrayElement( | |
2407 data_ptr, index, INT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); | |
2408 var_value.Bind(assembler->SmiFromWord(value_int8)); | |
2409 assembler->Goto(&allocate_entry_if_needed); | |
2410 } | |
2411 | |
2412 assembler->Bind(&uint16_values); | |
2413 { | |
2414 Node* value_uint16 = assembler->LoadFixedTypedArrayElement( | |
2415 data_ptr, index, UINT16_ELEMENTS, | |
2416 CodeStubAssembler::SMI_PARAMETERS); | |
2417 var_value.Bind(assembler->SmiFromWord(value_uint16)); | |
2418 assembler->Goto(&allocate_entry_if_needed); | |
2419 } | |
2420 | |
2421 assembler->Bind(&int16_values); | |
2422 { | |
2423 Node* value_int16 = assembler->LoadFixedTypedArrayElement( | |
2424 data_ptr, index, INT16_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); | |
2425 var_value.Bind(assembler->SmiFromWord(value_int16)); | |
2426 assembler->Goto(&allocate_entry_if_needed); | |
2427 } | |
2428 | |
2429 assembler->Bind(&uint32_values); | |
2430 { | |
2431 Node* value_uint32 = assembler->LoadFixedTypedArrayElement( | |
2432 data_ptr, index, UINT32_ELEMENTS, | |
2433 CodeStubAssembler::SMI_PARAMETERS); | |
2434 var_value.Bind(assembler->ChangeUint32ToTagged(value_uint32)); | |
2435 assembler->Goto(&allocate_entry_if_needed); | |
2436 } | |
2437 assembler->Bind(&int32_values); | |
2438 { | |
2439 Node* value_int32 = assembler->LoadFixedTypedArrayElement( | |
2440 data_ptr, index, INT32_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); | |
2441 var_value.Bind(assembler->ChangeInt32ToTagged(value_int32)); | |
2442 assembler->Goto(&allocate_entry_if_needed); | |
2443 } | |
2444 assembler->Bind(&float32_values); | |
2445 { | |
2446 Node* value_float32 = assembler->LoadFixedTypedArrayElement( | |
2447 data_ptr, index, FLOAT32_ELEMENTS, | |
2448 CodeStubAssembler::SMI_PARAMETERS); | |
2449 var_value.Bind(assembler->AllocateHeapNumberWithValue( | |
2450 assembler->ChangeFloat32ToFloat64(value_float32))); | |
2451 assembler->Goto(&allocate_entry_if_needed); | |
2452 } | |
2453 assembler->Bind(&float64_values); | |
2454 { | |
2455 Node* value_float64 = assembler->LoadFixedTypedArrayElement( | |
2456 data_ptr, index, FLOAT64_ELEMENTS, | |
2457 CodeStubAssembler::SMI_PARAMETERS); | |
2458 var_value.Bind(assembler->AllocateHeapNumberWithValue(value_float64)); | |
2459 assembler->Goto(&allocate_entry_if_needed); | |
2460 } | |
2461 } | |
2462 } | |
2463 | |
2464 assembler->Bind(&set_done); | |
2465 { | |
2466 assembler->StoreObjectFieldNoWriteBarrier( | |
2467 iterator, JSArrayIterator::kIteratedObjectOffset, | |
2468 assembler->UndefinedConstant()); | |
2469 assembler->Goto(&did_set_done); | |
2470 } | |
2471 assembler->Bind(&did_set_done); | |
Benedikt Meurer
2016/10/17 04:02:42
It seems you don't need this did_set_done Label, a
caitp
2016/10/18 00:16:50
It's gone
| |
2472 { | |
2473 var_value.Bind(assembler->UndefinedConstant()); | |
2474 var_done.Bind(assembler->TrueConstant()); | |
2475 assembler->Goto(&allocate_iterator_result); | |
2476 } | |
2477 | |
2478 assembler->Bind(&allocate_key_result); | |
2479 { | |
2480 var_value.Bind(index); | |
2481 var_done.Bind(assembler->FalseConstant()); | |
2482 assembler->Goto(&allocate_iterator_result); | |
2483 } | |
2484 | |
2485 assembler->Bind(&allocate_entry_if_needed); | |
2486 { | |
2487 assembler->GotoIf( | |
2488 assembler->Int32GreaterThan( | |
2489 instance_type, | |
2490 assembler->Int32Constant(LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE)), | |
2491 &allocate_iterator_result); | |
2492 | |
2493 Node* elements = assembler->AllocateFixedArray(FAST_ELEMENTS, | |
2494 assembler->Int32Constant(2)); | |
2495 assembler->StoreFixedArrayElement(elements, assembler->Int32Constant(0), | |
2496 index, SKIP_WRITE_BARRIER); | |
2497 assembler->StoreFixedArrayElement(elements, assembler->Int32Constant(1), | |
2498 var_value.value(), SKIP_WRITE_BARRIER); | |
2499 | |
2500 Node* entry = assembler->Allocate(JSArray::kSize); | |
2501 Node* map = assembler->LoadFixedArrayElement( | |
2502 assembler->LoadNativeContext(context), | |
2503 assembler->IntPtrConstant(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX), 0, | |
2504 CodeStubAssembler::INTPTR_PARAMETERS); | |
Camillo Bruni
2016/10/17 14:56:39
nit: You can use LoadContextElement() here
caitp
2016/10/18 00:16:50
Done, thanks for the tip
| |
2505 | |
2506 assembler->StoreMapNoWriteBarrier(entry, map); | |
2507 assembler->StoreObjectFieldRoot(entry, JSArray::kPropertiesOffset, | |
2508 Heap::kEmptyFixedArrayRootIndex); | |
2509 assembler->StoreObjectFieldNoWriteBarrier(entry, JSArray::kElementsOffset, | |
2510 elements); | |
2511 assembler->StoreObjectFieldNoWriteBarrier( | |
2512 entry, JSArray::kLengthOffset, assembler->SmiConstant(Smi::FromInt(2))); | |
2513 | |
2514 var_value.Bind(entry); | |
2515 assembler->Goto(&allocate_iterator_result); | |
2516 } | |
2517 | |
2518 assembler->Bind(&allocate_iterator_result); | |
2519 { | |
2520 Node* result = assembler->Allocate(JSIteratorResult::kSize); | |
2521 Node* map = assembler->LoadFixedArrayElement( | |
2522 assembler->LoadNativeContext(context), | |
2523 assembler->IntPtrConstant(Context::ITERATOR_RESULT_MAP_INDEX), 0, | |
2524 CodeStubAssembler::INTPTR_PARAMETERS); | |
Camillo Bruni
2016/10/17 14:56:39
nit: You can use LoadContextElement() here
| |
2525 assembler->StoreMapNoWriteBarrier(result, map); | |
2526 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset, | |
2527 Heap::kEmptyFixedArrayRootIndex); | |
2528 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset, | |
2529 Heap::kEmptyFixedArrayRootIndex); | |
2530 assembler->StoreObjectFieldNoWriteBarrier( | |
2531 result, JSIteratorResult::kValueOffset, var_value.value()); | |
2532 assembler->StoreObjectFieldNoWriteBarrier( | |
2533 result, JSIteratorResult::kDoneOffset, var_done.value()); | |
2534 assembler->Return(result); | |
2535 } | |
2536 | |
2537 assembler->Bind(&throw_bad_receiver); | |
2538 { | |
2539 // The {receiver} is not a valid JSArrayIterator. | |
2540 Node* result = assembler->CallRuntime( | |
2541 Runtime::kThrowIncompatibleMethodReceiver, context, | |
2542 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked( | |
2543 "Array Iterator.prototype.next", TENURED)), | |
2544 iterator); | |
2545 assembler->Return(result); | |
2546 } | |
2547 } | |
2548 | |
2070 } // namespace internal | 2549 } // namespace internal |
2071 } // namespace v8 | 2550 } // namespace v8 |
OLD | NEW |