Chromium Code Reviews| 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 |