diff options
Diffstat (limited to 'deps/v8/src/builtins/builtins-iterator-gen.cc')
-rw-r--r-- | deps/v8/src/builtins/builtins-iterator-gen.cc | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/deps/v8/src/builtins/builtins-iterator-gen.cc b/deps/v8/src/builtins/builtins-iterator-gen.cc index 7bd5acfdcd..2f8761902b 100644 --- a/deps/v8/src/builtins/builtins-iterator-gen.cc +++ b/deps/v8/src/builtins/builtins-iterator-gen.cc @@ -241,6 +241,104 @@ TF_BUILTIN(IterableToList, IteratorBuiltinsAssembler) { Return(IterableToList(context, iterable, iterator_fn)); } +TF_BUILTIN(IterableToFixedArrayForWasm, IteratorBuiltinsAssembler) { + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> iterable = CAST(Parameter(Descriptor::kIterable)); + TNode<Smi> expected_length = CAST(Parameter(Descriptor::kExpectedLength)); + + TNode<Object> iterator_fn = GetIteratorMethod(context, iterable); + + IteratorRecord iterator_record = GetIterator(context, iterable, iterator_fn); + + GrowableFixedArray values(state()); + + Variable* vars[] = {values.var_array(), values.var_length(), + values.var_capacity()}; + Label loop_start(this, 3, vars), compare_length(this), done(this); + Goto(&loop_start); + BIND(&loop_start); + { + TNode<JSReceiver> next = + IteratorStep(context, iterator_record, &compare_length); + TNode<Object> next_value = IteratorValue(context, next); + values.Push(next_value); + Goto(&loop_start); + } + + BIND(&compare_length); + GotoIf(WordEqual(SmiUntag(expected_length), values.var_length()->value()), + &done); + Return(CallRuntime( + Runtime::kThrowTypeError, context, + SmiConstant(MessageTemplate::kWasmTrapMultiReturnLengthMismatch))); + + BIND(&done); + Return(values.var_array()->value()); +} + +TNode<JSArray> IteratorBuiltinsAssembler::StringListFromIterable( + TNode<Context> context, TNode<Object> iterable) { + Label done(this); + GrowableFixedArray list(state()); + // 1. If iterable is undefined, then + // a. Return a new empty List. + GotoIf(IsUndefined(iterable), &done); + + // 2. Let iteratorRecord be ? GetIterator(items). + IteratorRecord iterator_record = GetIterator(context, iterable); + + // 3. Let list be a new empty List. + + Variable* vars[] = {list.var_array(), list.var_length(), list.var_capacity()}; + Label loop_start(this, 3, vars); + Goto(&loop_start); + // 4. Let next be true. + // 5. Repeat, while next is not false + Label if_isnotstringtype(this, Label::kDeferred), + if_exception(this, Label::kDeferred); + BIND(&loop_start); + { + // a. Set next to ? IteratorStep(iteratorRecord). + TNode<JSReceiver> next = IteratorStep(context, iterator_record, &done); + // b. If next is not false, then + // i. Let nextValue be ? IteratorValue(next). + TNode<Object> next_value = IteratorValue(context, next); + // ii. If Type(nextValue) is not String, then + GotoIf(TaggedIsSmi(next_value), &if_isnotstringtype); + TNode<Uint16T> next_value_type = LoadInstanceType(CAST(next_value)); + GotoIfNot(IsStringInstanceType(next_value_type), &if_isnotstringtype); + // iii. Append nextValue to the end of the List list. + list.Push(next_value); + Goto(&loop_start); + // 5.b.ii + BIND(&if_isnotstringtype); + { + // 1. Let error be ThrowCompletion(a newly created TypeError object). + TVARIABLE(Object, var_exception); + TNode<Object> ret = CallRuntime( + Runtime::kThrowTypeError, context, + SmiConstant(MessageTemplate::kIterableYieldedNonString), next_value); + GotoIfException(ret, &if_exception, &var_exception); + Unreachable(); + + // 2. Return ? IteratorClose(iteratorRecord, error). + BIND(&if_exception); + IteratorCloseOnException(context, iterator_record, var_exception.value()); + } + } + + BIND(&done); + // 6. Return list. + return list.ToJSArray(context); +} + +TF_BUILTIN(StringListFromIterable, IteratorBuiltinsAssembler) { + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> iterable = CAST(Parameter(Descriptor::kIterable)); + + Return(StringListFromIterable(context, iterable)); +} + // 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. This builtin will take the // fast path if the iterable is a fast array and the Array prototype and the @@ -354,5 +452,19 @@ TF_BUILTIN(IterableToListWithSymbolLookup, IteratorBuiltinsAssembler) { } } +TF_BUILTIN(GetIteratorWithFeedbackLazyDeoptContinuation, + IteratorBuiltinsAssembler) { + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + TNode<Smi> callSlot = CAST(Parameter(Descriptor::kCallSlot)); + TNode<FeedbackVector> feedback = CAST(Parameter(Descriptor::kFeedback)); + TNode<Object> iteratorMethod = CAST(Parameter(Descriptor::kResult)); + + TNode<Object> result = + CallBuiltin(Builtins::kCallIteratorWithFeedback, context, receiver, + iteratorMethod, callSlot, feedback); + Return(result); +} + } // namespace internal } // namespace v8 |