Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/builtins/builtins.h" | 5 #include "src/builtins/builtins.h" |
| 6 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
| 7 | 7 |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/contexts.h" | |
| 9 #include "src/elements.h" | 10 #include "src/elements.h" |
| 10 | 11 |
| 11 namespace v8 { | 12 namespace v8 { |
| 12 namespace internal { | 13 namespace internal { |
| 13 | 14 |
| 14 namespace { | 15 namespace { |
| 15 | 16 |
| 16 inline bool ClampedToInteger(Isolate* isolate, Object* object, int* out) { | 17 inline bool ClampedToInteger(Isolate* isolate, Object* object, int* out) { |
| 17 // This is an extended version of ECMA-262 7.1.11 handling signed values | 18 // This is an extended version of ECMA-262 7.1.11 handling signed values |
| 18 // Try to convert object to a number and clamp values to [kMinInt, kMaxInt] | 19 // Try to convert object to a number and clamp values to [kMinInt, kMaxInt] |
| (...skipping 2041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2060 assembler->Return(assembler->ChangeInt32ToTagged(index_var.value())); | 2061 assembler->Return(assembler->ChangeInt32ToTagged(index_var.value())); |
| 2061 | 2062 |
| 2062 assembler->Bind(&return_not_found); | 2063 assembler->Bind(&return_not_found); |
| 2063 assembler->Return(assembler->NumberConstant(-1)); | 2064 assembler->Return(assembler->NumberConstant(-1)); |
| 2064 | 2065 |
| 2065 assembler->Bind(&call_runtime); | 2066 assembler->Bind(&call_runtime); |
| 2066 assembler->Return(assembler->CallRuntime(Runtime::kArrayIndexOf, context, | 2067 assembler->Return(assembler->CallRuntime(Runtime::kArrayIndexOf, context, |
| 2067 array, search_element, start_from)); | 2068 array, search_element, start_from)); |
| 2068 } | 2069 } |
| 2069 | 2070 |
| 2071 namespace { | |
| 2072 | |
| 2073 template <IterationKind kIterationKind> | |
| 2074 void Generate_ArrayPrototypeIterationMethod(CodeStubAssembler* assembler) { | |
| 2075 typedef compiler::Node Node; | |
| 2076 typedef CodeStubAssembler::Label Label; | |
| 2077 typedef CodeStubAssembler::Variable Variable; | |
| 2078 | |
| 2079 Node* receiver = assembler->Parameter(0); | |
| 2080 Node* context = assembler->Parameter(3); | |
| 2081 | |
| 2082 Variable var_array(assembler, MachineRepresentation::kTagged); | |
| 2083 Variable var_map(assembler, MachineRepresentation::kTagged); | |
| 2084 Variable var_type(assembler, MachineRepresentation::kWord32); | |
| 2085 | |
| 2086 Label if_isnotobject(assembler, Label::kDeferred); | |
| 2087 Label create_array_iterator(assembler); | |
| 2088 | |
| 2089 assembler->GotoIf(assembler->TaggedIsSmi(receiver), &if_isnotobject); | |
| 2090 var_array.Bind(receiver); | |
| 2091 var_map.Bind(assembler->LoadMap(receiver)); | |
| 2092 var_type.Bind(assembler->LoadMapInstanceType(var_map.value())); | |
| 2093 assembler->Branch( | |
|
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 |
| OLD | NEW |