Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Side by Side Diff: src/builtins/builtins-array.cc

Issue 2405253006: [builtins] implement Array.prototype[@@iterator] in TFJ builtins (Closed)
Patch Set: fix JSArrayIteratorVerify() Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698