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