Commit 43da5036 authored by Sathya Gunasekaran's avatar Sathya Gunasekaran Committed by Commit Bot

[builtins] Move IterableToList to iterator-gen

... So that this can be re-used in the intl code. Also, add a helper
method that loads the iterator if it's not provided.

Bug: v8:5751
Change-Id: Ifc1142a486b2cdf1c33a813c5446b206ad9f81ef
Reviewed-on: https://chromium-review.googlesource.com/1156390
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54819}
parent 27cd5d03
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "src/builtins/builtins-iterator-gen.h"
#include "src/builtins/growable-fixed-array-gen.h"
#include "src/heap/factory-inl.h"
......@@ -11,8 +12,8 @@ namespace internal {
using compiler::Node;
Node* IteratorBuiltinsAssembler::GetIteratorMethod(Node* context,
Node* object) {
TNode<Object> IteratorBuiltinsAssembler::GetIteratorMethod(Node* context,
Node* object) {
return GetProperty(context, object, factory()->iterator_symbol());
}
......@@ -194,5 +195,68 @@ void IteratorBuiltinsAssembler::IteratorCloseOnException(
Unreachable();
}
TNode<JSArray> IteratorBuiltinsAssembler::IterableToList(
TNode<Context> context, TNode<Object> iterable, TNode<Object> iterator_fn) {
Label fast_path(this), slow_path(this), done(this);
TVARIABLE(JSArray, created_list);
// This is a fast-path for ignoring the iterator.
// TODO(petermarshall): Port IterableToListCanBeElided to CSA.
Node* elided =
CallRuntime(Runtime::kIterableToListCanBeElided, context, iterable);
CSA_ASSERT(this, IsBoolean(elided));
Branch(IsTrue(elided), &fast_path, &slow_path);
BIND(&fast_path);
{
TNode<JSArray> input_array = CAST(iterable);
created_list = CAST(CloneFastJSArray(context, input_array));
Goto(&done);
}
BIND(&slow_path);
{
// 1. Let iteratorRecord be ? GetIterator(items, method).
IteratorRecord iterator_record =
GetIterator(context, iterable, iterator_fn);
// 2. Let values be a new empty List.
GrowableFixedArray values(state());
Variable* vars[] = {values.var_array(), values.var_length(),
values.var_capacity()};
Label loop_start(this, 3, vars), loop_end(this);
Goto(&loop_start);
// 3. Let next be true.
// 4. Repeat, while next is not false
BIND(&loop_start);
{
// a. Set next to ? IteratorStep(iteratorRecord).
TNode<Object> next =
CAST(IteratorStep(context, iterator_record, &loop_end));
// b. If next is not false, then
// i. Let nextValue be ? IteratorValue(next).
TNode<Object> next_value = CAST(IteratorValue(context, next));
// ii. Append nextValue to the end of the List values.
values.Push(next_value);
Goto(&loop_start);
}
BIND(&loop_end);
created_list = values.ToJSArray(context);
Goto(&done);
}
BIND(&done);
return created_list.value();
}
TNode<JSArray> IteratorBuiltinsAssembler::IterableToList(
TNode<Context> context, TNode<Object> iterable) {
TNode<Object> method = GetIteratorMethod(context, iterable);
return IterableToList(context, iterable, method);
}
} // namespace internal
} // namespace v8
......@@ -18,7 +18,7 @@ class IteratorBuiltinsAssembler : public CodeStubAssembler {
: CodeStubAssembler(state) {}
// Returns object[Symbol.iterator].
Node* GetIteratorMethod(Node* context, Node* object);
TNode<Object> GetIteratorMethod(Node* context, Node* object);
// https://tc39.github.io/ecma262/#sec-getiterator --- never used for
// @@asyncIterator.
......@@ -53,6 +53,11 @@ class IteratorBuiltinsAssembler : public CodeStubAssembler {
Label* if_exception, Variable* exception);
void IteratorCloseOnException(Node* context, const IteratorRecord& iterator,
Variable* exception);
// /#sec-iterabletolist
TNode<JSArray> IterableToList(TNode<Context> context, TNode<Object> iterable,
TNode<Object> iterator_fn);
TNode<JSArray> IterableToList(TNode<Context> context, TNode<Object> iterable);
};
} // namespace internal
......
......@@ -1647,44 +1647,6 @@ TF_BUILTIN(TypedArrayOf, TypedArrayBuiltinsAssembler) {
"%TypedArray%.of");
}
void TypedArrayBuiltinsAssembler::IterableToListSlowPath(
TNode<Context> context, TNode<Object> iterable, TNode<Object> iterator_fn,
Variable* created_list) {
IteratorBuiltinsAssembler iterator_assembler(state());
// 1. Let iteratorRecord be ? GetIterator(items, method).
IteratorRecord iterator_record =
iterator_assembler.GetIterator(context, iterable, iterator_fn);
// 2. Let values be a new empty List.
GrowableFixedArray values(state());
Variable* vars[] = {values.var_array(), values.var_length(),
values.var_capacity()};
Label loop_start(this, 3, vars), loop_end(this);
Goto(&loop_start);
// 3. Let next be true.
// 4. Repeat, while next is not false
BIND(&loop_start);
{
// a. Set next to ? IteratorStep(iteratorRecord).
TNode<Object> next = CAST(
iterator_assembler.IteratorStep(context, iterator_record, &loop_end));
// b. If next is not false, then
// i. Let nextValue be ? IteratorValue(next).
TNode<Object> next_value =
CAST(iterator_assembler.IteratorValue(context, next));
// ii. Append nextValue to the end of the List values.
values.Push(next_value);
Goto(&loop_start);
}
BIND(&loop_end);
// 5. Return values.
TNode<JSArray> js_array_values = values.ToJSArray(context);
created_list->Bind(js_array_values);
}
// This builtin always returns a new JSArray and is thus safe to use even in the
// presence of code that may call back into user-JS.
TF_BUILTIN(IterableToList, TypedArrayBuiltinsAssembler) {
......@@ -1692,33 +1654,8 @@ TF_BUILTIN(IterableToList, TypedArrayBuiltinsAssembler) {
TNode<Object> iterable = CAST(Parameter(Descriptor::kIterable));
TNode<Object> iterator_fn = CAST(Parameter(Descriptor::kIteratorFn));
Label fast_path(this), slow_path(this), done(this);
TVARIABLE(JSArray, created_list);
// This is a fast-path for ignoring the iterator.
// TODO(petermarshall): Port IterableToListCanBeElided to CSA.
Node* elided =
CallRuntime(Runtime::kIterableToListCanBeElided, context, iterable);
CSA_ASSERT(this, IsBoolean(elided));
Branch(IsTrue(elided), &fast_path, &slow_path);
BIND(&fast_path);
{
TNode<JSArray> input_array = CAST(iterable);
TNode<JSArray> new_array = CAST(CloneFastJSArray(context, input_array));
created_list = new_array;
Goto(&done);
}
BIND(&slow_path);
{
IterableToListSlowPath(context, iterable, iterator_fn, &created_list);
Goto(&done);
}
BIND(&done);
Return(created_list.value());
IteratorBuiltinsAssembler iterator_assembler(state());
Return(iterator_assembler.IterableToList(context, iterable, iterator_fn));
}
// ES6 #sec-%typedarray%.from
......
......@@ -55,10 +55,6 @@ class TypedArrayBuiltinsAssembler : public BaseBuiltinsFromDSLAssembler {
TNode<Map> map, TNode<Smi> length,
TNode<Number> byte_offset);
void IterableToListSlowPath(TNode<Context> context, TNode<Object> iterable,
TNode<Object> iterator_fn,
Variable* created_list);
TNode<Map> LoadMapForType(TNode<JSTypedArray> array);
TNode<UintPtrT> CalculateExternalPointer(TNode<UintPtrT> backing_store,
TNode<Number> byte_offset);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment