Chromium Code Reviews| Index: src/runtime/runtime-array.cc |
| diff --git a/src/runtime/runtime-array.cc b/src/runtime/runtime-array.cc |
| index 8958d7786433765faaaadf4e2ff97311f283912a..b75de611553235bd5521fbe82ba6abd7b3225002 100644 |
| --- a/src/runtime/runtime-array.cc |
| +++ b/src/runtime/runtime-array.cc |
| @@ -636,5 +636,49 @@ RUNTIME_FUNCTION(Runtime_ArrayIndexOf) { |
| return Smi::FromInt(-1); |
| } |
| +RUNTIME_FUNCTION(Runtime_SpreadIterablePrepare) { |
| + HandleScope scope(isolate); |
| + DCHECK_EQ(1, args.length()); |
| + CONVERT_ARG_HANDLE_CHECKED(Object, spread, 0); |
| + |
| + if (spread->IsJSArray()) { |
| + // Check that the spread arg has fast elements |
| + Handle<JSArray> spread_array = Handle<JSArray>::cast(spread); |
| + ElementsKind array_kind = spread_array->GetElementsKind(); |
| + |
| + // And that it has the orignal ArrayPrototype |
| + JSObject* array_proto = JSObject::cast(spread_array->map()->prototype()); |
| + Map* iterator_map = isolate->initial_array_iterator_prototype()->map(); |
| + |
| + // Check that the iterator acts as expected. |
| + // If IsArrayIteratorLookupChainIntact(), then we know that the initial |
| + // ArrayIterator is being used. If the map of the prototype has changed, |
| + // then take the slow path. |
| + |
| + if (isolate->is_initial_array_prototype(array_proto) && |
| + isolate->IsArrayIteratorLookupChainIntact() && |
| + isolate->is_initial_array_iterator_prototype_map(iterator_map)) { |
| + if (array_kind == FAST_SMI_ELEMENTS || array_kind == FAST_ELEMENTS) { |
|
Yang
2016/11/15 13:12:02
Can we also allow FAST_DOUBLE_ELEMENTS? (test case
Benedikt Meurer
2016/11/15 13:13:46
Yes, please.
petermarshall
2016/11/15 14:24:49
OK, done
|
| + return *spread; |
| + } |
| + if ((array_kind == FAST_HOLEY_SMI_ELEMENTS || |
| + array_kind == FAST_HOLEY_ELEMENTS) && |
|
Yang
2016/11/15 13:12:02
Same here.
|
| + isolate->IsFastArrayConstructorPrototypeChainIntact()) { |
| + return *spread; |
| + } |
| + } |
| + } |
| + |
| + Handle<JSFunction> spread_iterable_function = isolate->spread_iterable(); |
| + |
| + Handle<Object> spreaded; |
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| + isolate, spreaded, |
| + Execution::Call(isolate, spread_iterable_function, |
| + isolate->factory()->undefined_value(), 1, &spread)); |
| + |
| + return *spreaded; |
| +} |
| + |
| } // namespace internal |
| } // namespace v8 |