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: add array_iterator_protector, and check array_protector in holey fast arrays 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(
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
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