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

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

Issue 2405253006: [builtins] implement Array.prototype[@@iterator] in TFJ builtins (Closed)
Patch Set: latest round 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
« no previous file with comments | « src/builtins/builtins.h ('k') | src/builtins/builtins-typedarray.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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(assembler->IsJSReceiverInstanceType(var_type.value()),
2094 &create_array_iterator, &if_isnotobject);
2095
2096 assembler->Bind(&if_isnotobject);
2097 {
2098 Callable callable = CodeFactory::ToObject(assembler->isolate());
2099 Node* result = assembler->CallStub(callable, context, receiver);
2100 var_array.Bind(result);
2101 var_map.Bind(assembler->LoadMap(result));
2102 var_type.Bind(assembler->LoadMapInstanceType(var_map.value()));
2103 assembler->Goto(&create_array_iterator);
2104 }
2105
2106 assembler->Bind(&create_array_iterator);
2107 assembler->Return(assembler->CreateArrayIterator(
2108 var_array.value(), var_map.value(), var_type.value(), context,
2109 kIterationKind));
2110 }
2111
2112 } // namespace
2113
2114 void Builtins::Generate_ArrayPrototypeValues(CodeStubAssembler* assembler) {
2115 Generate_ArrayPrototypeIterationMethod<IterationKind::kValues>(assembler);
2116 }
2117
2118 void Builtins::Generate_ArrayPrototypeEntries(CodeStubAssembler* assembler) {
2119 Generate_ArrayPrototypeIterationMethod<IterationKind::kEntries>(assembler);
2120 }
2121
2122 void Builtins::Generate_ArrayPrototypeKeys(CodeStubAssembler* assembler) {
2123 Generate_ArrayPrototypeIterationMethod<IterationKind::kKeys>(assembler);
2124 }
2125
2126 void Builtins::Generate_ArrayIteratorPrototypeNext(
2127 CodeStubAssembler* assembler) {
2128 typedef compiler::Node Node;
2129 typedef CodeStubAssembler::Label Label;
2130 typedef CodeStubAssembler::Variable Variable;
2131
2132 Node* iterator = assembler->Parameter(0);
2133 Node* context = assembler->Parameter(3);
2134
2135 Variable var_value(assembler, MachineRepresentation::kTagged);
2136 Variable var_done(assembler, MachineRepresentation::kTagged);
2137
2138 // Required, or else `throw_bad_receiver` fails a DCHECK due to these
2139 // variables not being bound along all paths, despite not being used.
2140 var_done.Bind(assembler->TrueConstant());
2141 var_value.Bind(assembler->UndefinedConstant());
2142
2143 Label throw_bad_receiver(assembler, Label::kDeferred);
2144 Label set_done(assembler);
2145 Label allocate_key_result(assembler);
2146 Label allocate_entry_if_needed(assembler);
2147 Label allocate_iterator_result(assembler);
2148 Label generic_values(assembler);
2149
2150 // If O does not have all of the internal slots of an Array Iterator Instance
2151 // (22.1.5.3), throw a TypeError exception
2152 assembler->GotoIf(assembler->TaggedIsSmi(iterator), &throw_bad_receiver);
2153 Node* instance_type = assembler->LoadInstanceType(iterator);
2154 assembler->GotoIf(
2155 assembler->Uint32LessThan(
2156 assembler->Int32Constant(LAST_ARRAY_ITERATOR_TYPE -
2157 FIRST_ARRAY_ITERATOR_TYPE),
2158 assembler->Int32Sub(instance_type, assembler->Int32Constant(
2159 FIRST_ARRAY_ITERATOR_TYPE))),
2160 &throw_bad_receiver);
2161
2162 // Let a be O.[[IteratedObject]].
2163 Node* array = assembler->LoadObjectField(
2164 iterator, JSArrayIterator::kIteratedObjectOffset);
2165
2166 // Let index be O.[[ArrayIteratorNextIndex]].
2167 Node* index =
2168 assembler->LoadObjectField(iterator, JSArrayIterator::kNextIndexOffset);
2169 Node* orig_map = assembler->LoadObjectField(
2170 iterator, JSArrayIterator::kIteratedObjectMapOffset);
2171 Node* array_map = assembler->LoadMap(array);
2172
2173 Label if_isfastarray(assembler), if_isnotfastarray(assembler);
2174
2175 assembler->Branch(assembler->WordEqual(orig_map, array_map), &if_isfastarray,
2176 &if_isnotfastarray);
2177
2178 assembler->Bind(&if_isfastarray);
2179 {
2180 assembler->Assert(
2181 assembler->Word32Equal(assembler->LoadMapInstanceType(array_map),
2182 assembler->Int32Constant(JS_ARRAY_TYPE)));
2183
2184 Node* length = assembler->LoadObjectField(array, JSArray::kLengthOffset);
2185
2186 assembler->Assert(assembler->TaggedIsSmi(length));
2187 assembler->Assert(assembler->TaggedIsSmi(index));
2188
2189 assembler->GotoUnless(assembler->SmiBelow(index, length), &set_done);
2190
2191 Node* one = assembler->SmiConstant(Smi::FromInt(1));
2192 assembler->StoreObjectFieldNoWriteBarrier(
2193 iterator, JSArrayIterator::kNextIndexOffset,
2194 assembler->IntPtrAdd(assembler->BitcastTaggedToWord(index),
2195 assembler->BitcastTaggedToWord(one)));
2196
2197 var_done.Bind(assembler->FalseConstant());
2198 Node* elements = assembler->LoadElements(array);
2199
2200 static int32_t kInstanceType[] = {
2201 JS_FAST_ARRAY_KEY_ITERATOR_TYPE,
2202 JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2203 JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2204 JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2205 JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2206 JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2207 JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2208 JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE,
2209 JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE,
2210 JS_FAST_ARRAY_VALUE_ITERATOR_TYPE,
2211 JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE,
2212 JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE,
2213 JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE,
2214 };
2215
2216 Label packed_object_values(assembler), holey_object_values(assembler),
2217 packed_double_values(assembler), holey_double_values(assembler);
2218 Label* kInstanceTypeHandlers[] = {
2219 &allocate_key_result, &packed_object_values, &holey_object_values,
2220 &packed_object_values, &holey_object_values, &packed_double_values,
2221 &holey_double_values, &packed_object_values, &holey_object_values,
2222 &packed_object_values, &holey_object_values, &packed_double_values,
2223 &holey_double_values};
2224
2225 assembler->Switch(instance_type, &throw_bad_receiver, kInstanceType,
2226 kInstanceTypeHandlers, arraysize(kInstanceType));
2227
2228 assembler->Bind(&packed_object_values);
2229 {
2230 var_value.Bind(assembler->LoadFixedArrayElement(
2231 elements, index, 0, CodeStubAssembler::SMI_PARAMETERS));
2232 assembler->Goto(&allocate_entry_if_needed);
2233 }
2234
2235 assembler->Bind(&packed_double_values);
2236 {
2237 Node* value = assembler->LoadFixedDoubleArrayElement(
2238 elements, index, MachineType::Float64(), 0,
2239 CodeStubAssembler::SMI_PARAMETERS);
2240 var_value.Bind(assembler->AllocateHeapNumberWithValue(value));
2241 assembler->Goto(&allocate_entry_if_needed);
2242 }
2243
2244 assembler->Bind(&holey_object_values);
2245 {
2246 // Check the array_protector cell, and take the slow path if it's invalid.
2247 Node* invalid =
2248 assembler->SmiConstant(Smi::FromInt(Isolate::kArrayProtectorInvalid));
2249 Node* cell = assembler->LoadRoot(Heap::kArrayProtectorRootIndex);
2250 Node* cell_value =
2251 assembler->LoadObjectField(cell, PropertyCell::kValueOffset);
2252 assembler->GotoIf(assembler->WordEqual(cell_value, invalid),
2253 &generic_values);
2254
2255 var_value.Bind(assembler->UndefinedConstant());
2256 Node* value = assembler->LoadFixedArrayElement(
2257 elements, index, 0, CodeStubAssembler::SMI_PARAMETERS);
2258 assembler->GotoIf(
2259 assembler->WordEqual(value, assembler->TheHoleConstant()),
2260 &allocate_entry_if_needed);
2261 var_value.Bind(value);
2262 assembler->Goto(&allocate_entry_if_needed);
2263 }
2264
2265 assembler->Bind(&holey_double_values);
2266 {
2267 // Check the array_protector cell, and take the slow path if it's invalid.
2268 Node* invalid =
2269 assembler->SmiConstant(Smi::FromInt(Isolate::kArrayProtectorInvalid));
2270 Node* cell = assembler->LoadRoot(Heap::kArrayProtectorRootIndex);
2271 Node* cell_value =
2272 assembler->LoadObjectField(cell, PropertyCell::kValueOffset);
2273 assembler->GotoIf(assembler->WordEqual(cell_value, invalid),
2274 &generic_values);
2275
2276 var_value.Bind(assembler->UndefinedConstant());
2277 Node* value = assembler->LoadFixedDoubleArrayElement(
2278 elements, index, MachineType::Float64(), 0,
2279 CodeStubAssembler::SMI_PARAMETERS, &allocate_entry_if_needed);
2280 var_value.Bind(assembler->AllocateHeapNumberWithValue(value));
2281 assembler->Goto(&allocate_entry_if_needed);
2282 }
2283 }
2284
2285 assembler->Bind(&if_isnotfastarray);
2286 {
2287 Label if_istypedarray(assembler), if_isgeneric(assembler);
2288
2289 // If a is undefined, return CreateIterResultObject(undefined, true)
2290 assembler->GotoIf(
2291 assembler->WordEqual(array, assembler->UndefinedConstant()),
2292 &allocate_iterator_result);
2293
2294 Node* array_type = assembler->LoadInstanceType(array);
2295 assembler->Branch(
2296 assembler->Word32Equal(array_type,
2297 assembler->Int32Constant(JS_TYPED_ARRAY_TYPE)),
2298 &if_istypedarray, &if_isgeneric);
2299
2300 assembler->Bind(&if_isgeneric);
2301 {
2302 Node* length = nullptr;
2303 {
2304 Variable var_length(assembler, MachineRepresentation::kTagged);
2305 Label if_isarray(assembler), if_isnotarray(assembler), done(assembler);
2306 assembler->Branch(
2307 assembler->Word32Equal(array_type,
2308 assembler->Int32Constant(JS_ARRAY_TYPE)),
2309 &if_isarray, &if_isnotarray);
2310
2311 assembler->Bind(&if_isarray);
2312 {
2313 var_length.Bind(
2314 assembler->LoadObjectField(array, JSArray::kLengthOffset));
2315 assembler->Goto(&done);
2316 }
2317
2318 assembler->Bind(&if_isnotarray);
2319 {
2320 Node* length_string = assembler->HeapConstant(
2321 assembler->isolate()->factory()->length_string());
2322 Callable get_property =
2323 CodeFactory::GetProperty(assembler->isolate());
2324 Node* length =
2325 assembler->CallStub(get_property, context, array, length_string);
2326 Callable to_length = CodeFactory::ToLength(assembler->isolate());
2327 var_length.Bind(assembler->CallStub(to_length, context, length));
2328 assembler->Goto(&done);
2329 }
2330
2331 assembler->Bind(&done);
2332 length = var_length.value();
2333 }
2334
2335 assembler->GotoUnlessNumberLessThan(index, length, &set_done);
2336
2337 assembler->StoreObjectField(iterator, JSArrayIterator::kNextIndexOffset,
2338 assembler->NumberInc(index));
2339 var_done.Bind(assembler->FalseConstant());
2340
2341 assembler->Branch(
2342 assembler->Uint32LessThanOrEqual(
2343 instance_type,
2344 assembler->Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)),
2345 &allocate_key_result, &generic_values);
2346
2347 assembler->Bind(&generic_values);
2348 {
2349 Callable get_property = CodeFactory::GetProperty(assembler->isolate());
2350 var_value.Bind(
2351 assembler->CallStub(get_property, context, array, index));
2352 assembler->Goto(&allocate_entry_if_needed);
2353 }
2354 }
2355
2356 assembler->Bind(&if_istypedarray);
2357 {
2358 Node* length = nullptr;
2359 {
2360 Variable var_length(assembler, MachineRepresentation::kTagged);
2361 Label if_isdetached(assembler, Label::kDeferred),
2362 if_isnotdetached(assembler), done(assembler);
2363
2364 Node* buffer =
2365 assembler->LoadObjectField(array, JSTypedArray::kBufferOffset);
2366 assembler->Branch(assembler->IsDetachedBuffer(buffer), &if_isdetached,
2367 &if_isnotdetached);
2368
2369 assembler->Bind(&if_isnotdetached);
2370 {
2371 var_length.Bind(
2372 assembler->LoadObjectField(array, JSTypedArray::kLengthOffset));
2373 assembler->Goto(&done);
2374 }
2375
2376 assembler->Bind(&if_isdetached);
2377 {
2378 var_length.Bind(assembler->SmiConstant(Smi::kZero));
2379 assembler->Goto(&done);
2380 }
2381
2382 assembler->Bind(&done);
2383 length = var_length.value();
2384 }
2385 assembler->Assert(assembler->TaggedIsSmi(length));
2386 assembler->Assert(assembler->TaggedIsSmi(index));
2387
2388 assembler->GotoUnless(assembler->SmiBelow(index, length), &set_done);
2389
2390 Node* one = assembler->SmiConstant(Smi::FromInt(1));
2391 assembler->StoreObjectFieldNoWriteBarrier(
2392 iterator, JSArrayIterator::kNextIndexOffset,
2393 assembler->IntPtrAdd(assembler->BitcastTaggedToWord(index),
2394 assembler->BitcastTaggedToWord(one)));
2395 var_done.Bind(assembler->FalseConstant());
2396
2397 Node* elements = assembler->LoadElements(array);
2398 Node* base_ptr = assembler->LoadObjectField(
2399 elements, FixedTypedArrayBase::kBasePointerOffset);
2400 Node* external_ptr = assembler->LoadObjectField(
2401 elements, FixedTypedArrayBase::kExternalPointerOffset);
2402 Node* data_ptr = assembler->IntPtrAdd(base_ptr, external_ptr);
2403
2404 static int32_t kInstanceType[] = {
2405 JS_TYPED_ARRAY_KEY_ITERATOR_TYPE,
2406 JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2407 JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2408 JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2409 JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2410 JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2411 JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2412 JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2413 JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2414 JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE,
2415 JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE,
2416 JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE,
2417 JS_INT8_ARRAY_VALUE_ITERATOR_TYPE,
2418 JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE,
2419 JS_INT16_ARRAY_VALUE_ITERATOR_TYPE,
2420 JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE,
2421 JS_INT32_ARRAY_VALUE_ITERATOR_TYPE,
2422 JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE,
2423 JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE,
2424 };
2425
2426 Label uint8_values(assembler), int8_values(assembler),
2427 uint16_values(assembler), int16_values(assembler),
2428 uint32_values(assembler), int32_values(assembler),
2429 float32_values(assembler), float64_values(assembler);
2430 Label* kInstanceTypeHandlers[] = {
2431 &allocate_key_result, &uint8_values, &uint8_values,
2432 &int8_values, &uint16_values, &int16_values,
2433 &uint32_values, &int32_values, &float32_values,
2434 &float64_values, &uint8_values, &uint8_values,
2435 &int8_values, &uint16_values, &int16_values,
2436 &uint32_values, &int32_values, &float32_values,
2437 &float64_values,
2438 };
2439
2440 var_done.Bind(assembler->FalseConstant());
2441 assembler->Switch(instance_type, &throw_bad_receiver, kInstanceType,
2442 kInstanceTypeHandlers, arraysize(kInstanceType));
2443
2444 assembler->Bind(&uint8_values);
2445 {
2446 Node* value_uint8 = assembler->LoadFixedTypedArrayElement(
2447 data_ptr, index, UINT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS);
2448 var_value.Bind(assembler->SmiFromWord(value_uint8));
2449 assembler->Goto(&allocate_entry_if_needed);
2450 }
2451
2452 assembler->Bind(&int8_values);
2453 {
2454 Node* value_int8 = assembler->LoadFixedTypedArrayElement(
2455 data_ptr, index, INT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS);
2456 var_value.Bind(assembler->SmiFromWord(value_int8));
2457 assembler->Goto(&allocate_entry_if_needed);
2458 }
2459
2460 assembler->Bind(&uint16_values);
2461 {
2462 Node* value_uint16 = assembler->LoadFixedTypedArrayElement(
2463 data_ptr, index, UINT16_ELEMENTS,
2464 CodeStubAssembler::SMI_PARAMETERS);
2465 var_value.Bind(assembler->SmiFromWord(value_uint16));
2466 assembler->Goto(&allocate_entry_if_needed);
2467 }
2468
2469 assembler->Bind(&int16_values);
2470 {
2471 Node* value_int16 = assembler->LoadFixedTypedArrayElement(
2472 data_ptr, index, INT16_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS);
2473 var_value.Bind(assembler->SmiFromWord(value_int16));
2474 assembler->Goto(&allocate_entry_if_needed);
2475 }
2476
2477 assembler->Bind(&uint32_values);
2478 {
2479 Node* value_uint32 = assembler->LoadFixedTypedArrayElement(
2480 data_ptr, index, UINT32_ELEMENTS,
2481 CodeStubAssembler::SMI_PARAMETERS);
2482 var_value.Bind(assembler->ChangeUint32ToTagged(value_uint32));
2483 assembler->Goto(&allocate_entry_if_needed);
2484 }
2485 assembler->Bind(&int32_values);
2486 {
2487 Node* value_int32 = assembler->LoadFixedTypedArrayElement(
2488 data_ptr, index, INT32_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS);
2489 var_value.Bind(assembler->ChangeInt32ToTagged(value_int32));
2490 assembler->Goto(&allocate_entry_if_needed);
2491 }
2492 assembler->Bind(&float32_values);
2493 {
2494 Node* value_float32 = assembler->LoadFixedTypedArrayElement(
2495 data_ptr, index, FLOAT32_ELEMENTS,
2496 CodeStubAssembler::SMI_PARAMETERS);
2497 var_value.Bind(assembler->AllocateHeapNumberWithValue(
2498 assembler->ChangeFloat32ToFloat64(value_float32)));
2499 assembler->Goto(&allocate_entry_if_needed);
2500 }
2501 assembler->Bind(&float64_values);
2502 {
2503 Node* value_float64 = assembler->LoadFixedTypedArrayElement(
2504 data_ptr, index, FLOAT64_ELEMENTS,
2505 CodeStubAssembler::SMI_PARAMETERS);
2506 var_value.Bind(assembler->AllocateHeapNumberWithValue(value_float64));
2507 assembler->Goto(&allocate_entry_if_needed);
2508 }
2509 }
2510 }
2511
2512 assembler->Bind(&set_done);
2513 {
2514 assembler->StoreObjectFieldNoWriteBarrier(
2515 iterator, JSArrayIterator::kIteratedObjectOffset,
2516 assembler->UndefinedConstant());
2517 assembler->Goto(&allocate_iterator_result);
2518 }
2519
2520 assembler->Bind(&allocate_key_result);
2521 {
2522 var_value.Bind(index);
2523 var_done.Bind(assembler->FalseConstant());
2524 assembler->Goto(&allocate_iterator_result);
2525 }
2526
2527 assembler->Bind(&allocate_entry_if_needed);
2528 {
2529 assembler->GotoIf(
2530 assembler->Int32GreaterThan(
2531 instance_type,
2532 assembler->Int32Constant(LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE)),
2533 &allocate_iterator_result);
2534
2535 Node* elements = assembler->AllocateFixedArray(FAST_ELEMENTS,
2536 assembler->Int32Constant(2));
2537 assembler->StoreFixedArrayElement(elements, assembler->Int32Constant(0),
2538 index, SKIP_WRITE_BARRIER);
2539 assembler->StoreFixedArrayElement(elements, assembler->Int32Constant(1),
2540 var_value.value(), SKIP_WRITE_BARRIER);
2541
2542 Node* entry = assembler->Allocate(JSArray::kSize);
2543 Node* map = assembler->LoadContextElement(
2544 assembler->LoadNativeContext(context),
2545 Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX);
2546
2547 assembler->StoreMapNoWriteBarrier(entry, map);
2548 assembler->StoreObjectFieldRoot(entry, JSArray::kPropertiesOffset,
2549 Heap::kEmptyFixedArrayRootIndex);
2550 assembler->StoreObjectFieldNoWriteBarrier(entry, JSArray::kElementsOffset,
2551 elements);
2552 assembler->StoreObjectFieldNoWriteBarrier(
2553 entry, JSArray::kLengthOffset, assembler->SmiConstant(Smi::FromInt(2)));
2554
2555 var_value.Bind(entry);
2556 assembler->Goto(&allocate_iterator_result);
2557 }
2558
2559 assembler->Bind(&allocate_iterator_result);
2560 {
2561 Node* result = assembler->Allocate(JSIteratorResult::kSize);
2562 Node* map =
2563 assembler->LoadContextElement(assembler->LoadNativeContext(context),
2564 Context::ITERATOR_RESULT_MAP_INDEX);
2565 assembler->StoreMapNoWriteBarrier(result, map);
2566 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset,
2567 Heap::kEmptyFixedArrayRootIndex);
2568 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset,
2569 Heap::kEmptyFixedArrayRootIndex);
2570 assembler->StoreObjectFieldNoWriteBarrier(
2571 result, JSIteratorResult::kValueOffset, var_value.value());
2572 assembler->StoreObjectFieldNoWriteBarrier(
2573 result, JSIteratorResult::kDoneOffset, var_done.value());
2574 assembler->Return(result);
2575 }
2576
2577 assembler->Bind(&throw_bad_receiver);
2578 {
2579 // The {receiver} is not a valid JSArrayIterator.
2580 Node* result = assembler->CallRuntime(
2581 Runtime::kThrowIncompatibleMethodReceiver, context,
2582 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked(
2583 "Array Iterator.prototype.next", TENURED)),
2584 iterator);
2585 assembler->Return(result);
2586 }
2587 }
2588
2070 } // namespace internal 2589 } // namespace internal
2071 } // namespace v8 2590 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins.h ('k') | src/builtins/builtins-typedarray.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698