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

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

Issue 2405253006: [builtins] implement Array.prototype[@@iterator] in TFJ builtins (Closed)
Patch Set: remove apparently redundant var bindings and fix other bugs 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);
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698