• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/builtins/builtins-iterator-gen.h"
6 #include "src/builtins/builtins-utils-gen.h"
7 #include "src/builtins/growable-fixed-array-gen.h"
8 #include "src/codegen/code-stub-assembler.h"
9 #include "src/objects/js-temporal-objects-inl.h"
10 #include "src/objects/objects-inl.h"
11 #include "src/objects/objects.h"
12 
13 namespace v8 {
14 namespace internal {
15 
16 class TemporalBuiltinsAssembler : public IteratorBuiltinsAssembler {
17  public:
TemporalBuiltinsAssembler(compiler::CodeAssemblerState * state)18   explicit TemporalBuiltinsAssembler(compiler::CodeAssemblerState* state)
19       : IteratorBuiltinsAssembler(state) {}
20 
21   // For the use inside Temporal GetPossibleInstantFor
22   TNode<FixedArray> TemporalInstantFixedArrayFromIterable(
23       TNode<Context> context, TNode<Object> iterable);
24 };
25 
26 // #sec-iterabletolistoftype
27 TNode<FixedArray>
TemporalInstantFixedArrayFromIterable(TNode<Context> context,TNode<Object> iterable)28 TemporalBuiltinsAssembler::TemporalInstantFixedArrayFromIterable(
29     TNode<Context> context, TNode<Object> iterable) {
30   GrowableFixedArray list(state());
31   Label done(this);
32   // 1. If iterable is undefined, then
33   //   a. Return a new empty List.
34   GotoIf(IsUndefined(iterable), &done);
35 
36   // 2. Let iteratorRecord be ? GetIterator(items).
37   IteratorRecord iterator_record = GetIterator(context, iterable);
38 
39   // 3. Let list be a new empty List.
40 
41   Label loop_start(this,
42                    {list.var_array(), list.var_length(), list.var_capacity()});
43   Goto(&loop_start);
44   // 4. Let next be true.
45   // 5. Repeat, while next is not false
46   Label if_isnottemporalinstant(this, Label::kDeferred),
47       if_exception(this, Label::kDeferred);
48   BIND(&loop_start);
49   {
50     //  a. Set next to ? IteratorStep(iteratorRecord).
51     TNode<JSReceiver> next = IteratorStep(context, iterator_record, &done);
52     //  b. If next is not false, then
53     //   i. Let nextValue be ? IteratorValue(next).
54     TNode<Object> next_value = IteratorValue(context, next);
55     //   ii. If Type(nextValue) is not Object or nextValue does not have an
56     //   [[InitializedTemporalInstant]] internal slot
57     GotoIf(TaggedIsSmi(next_value), &if_isnottemporalinstant);
58     TNode<Uint16T> next_value_type = LoadInstanceType(CAST(next_value));
59     GotoIfNot(IsTemporalInstantInstanceType(next_value_type),
60               &if_isnottemporalinstant);
61     //   iii. Append nextValue to the end of the List list.
62     list.Push(next_value);
63     Goto(&loop_start);
64     // 5.b.ii
65     BIND(&if_isnottemporalinstant);
66     {
67       // 1. Let error be ThrowCompletion(a newly created TypeError object).
68       TVARIABLE(Object, var_exception);
69       {
70         compiler::ScopedExceptionHandler handler(this, &if_exception,
71                                                  &var_exception);
72         CallRuntime(Runtime::kThrowTypeError, context,
73                     SmiConstant(MessageTemplate::kIterableYieldedNonString),
74                     next_value);
75       }
76       Unreachable();
77 
78       // 2. Return ? IteratorClose(iteratorRecord, error).
79       BIND(&if_exception);
80       IteratorCloseOnException(context, iterator_record);
81       CallRuntime(Runtime::kReThrow, context, var_exception.value());
82       Unreachable();
83     }
84   }
85 
86   BIND(&done);
87   return list.ToFixedArray();
88 }
89 
TF_BUILTIN(TemporalInstantFixedArrayFromIterable,TemporalBuiltinsAssembler)90 TF_BUILTIN(TemporalInstantFixedArrayFromIterable, TemporalBuiltinsAssembler) {
91   auto context = Parameter<Context>(Descriptor::kContext);
92   auto iterable = Parameter<Object>(Descriptor::kIterable);
93 
94   Return(TemporalInstantFixedArrayFromIterable(context, iterable));
95 }
96 
97 }  // namespace internal
98 }  // namespace v8
99