11cb0ef41Sopenharmony_ci// Copyright 2017 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/builtins/builtins-array-gen.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/builtins/builtins-iterator-gen.h"
81cb0ef41Sopenharmony_ci#include "src/builtins/builtins-string-gen.h"
91cb0ef41Sopenharmony_ci#include "src/builtins/builtins-typed-array-gen.h"
101cb0ef41Sopenharmony_ci#include "src/builtins/builtins-utils-gen.h"
111cb0ef41Sopenharmony_ci#include "src/builtins/builtins.h"
121cb0ef41Sopenharmony_ci#include "src/codegen/code-stub-assembler.h"
131cb0ef41Sopenharmony_ci#include "src/codegen/interface-descriptors-inl.h"
141cb0ef41Sopenharmony_ci#include "src/execution/frame-constants.h"
151cb0ef41Sopenharmony_ci#include "src/heap/factory-inl.h"
161cb0ef41Sopenharmony_ci#include "src/objects/allocation-site-inl.h"
171cb0ef41Sopenharmony_ci#include "src/objects/arguments-inl.h"
181cb0ef41Sopenharmony_ci#include "src/objects/property-cell.h"
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_cinamespace v8 {
211cb0ef41Sopenharmony_cinamespace internal {
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ciArrayBuiltinsAssembler::ArrayBuiltinsAssembler(
241cb0ef41Sopenharmony_ci    compiler::CodeAssemblerState* state)
251cb0ef41Sopenharmony_ci    : CodeStubAssembler(state),
261cb0ef41Sopenharmony_ci      k_(this),
271cb0ef41Sopenharmony_ci      a_(this),
281cb0ef41Sopenharmony_ci      fully_spec_compliant_(this, {&k_, &a_}) {}
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_civoid ArrayBuiltinsAssembler::TypedArrayMapResultGenerator() {
311cb0ef41Sopenharmony_ci  // 6. Let A be ? TypedArraySpeciesCreate(O, len).
321cb0ef41Sopenharmony_ci  TNode<JSTypedArray> original_array = CAST(o());
331cb0ef41Sopenharmony_ci  const char* method_name = "%TypedArray%.prototype.map";
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci  TNode<JSTypedArray> a = TypedArraySpeciesCreateByLength(
361cb0ef41Sopenharmony_ci      context(), method_name, original_array, len());
371cb0ef41Sopenharmony_ci  // In the Spec and our current implementation, the length check is already
381cb0ef41Sopenharmony_ci  // performed in TypedArraySpeciesCreate.
391cb0ef41Sopenharmony_ci  CSA_DCHECK(this, UintPtrLessThanOrEqual(len(), LoadJSTypedArrayLength(a)));
401cb0ef41Sopenharmony_ci  fast_typed_array_target_ =
411cb0ef41Sopenharmony_ci      Word32Equal(LoadElementsKind(original_array), LoadElementsKind(a));
421cb0ef41Sopenharmony_ci  a_ = a;
431cb0ef41Sopenharmony_ci}
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci// See tc39.github.io/ecma262/#sec-%typedarray%.prototype.map.
461cb0ef41Sopenharmony_ciTNode<Object> ArrayBuiltinsAssembler::TypedArrayMapProcessor(
471cb0ef41Sopenharmony_ci    TNode<Object> k_value, TNode<UintPtrT> k) {
481cb0ef41Sopenharmony_ci  // 7c. Let mapped_value be ? Call(callbackfn, T, « kValue, k, O »).
491cb0ef41Sopenharmony_ci  TNode<Number> k_number = ChangeUintPtrToTagged(k);
501cb0ef41Sopenharmony_ci  TNode<Object> mapped_value =
511cb0ef41Sopenharmony_ci      Call(context(), callbackfn(), this_arg(), k_value, k_number, o());
521cb0ef41Sopenharmony_ci  Label fast(this), slow(this), done(this), detached(this, Label::kDeferred);
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci  // 7d. Perform ? Set(A, Pk, mapped_value, true).
551cb0ef41Sopenharmony_ci  // Since we know that A is a TypedArray, this always ends up in
561cb0ef41Sopenharmony_ci  // #sec-integer-indexed-exotic-objects-set-p-v-receiver and then
571cb0ef41Sopenharmony_ci  // tc39.github.io/ecma262/#sec-integerindexedelementset .
581cb0ef41Sopenharmony_ci  Branch(fast_typed_array_target_, &fast, &slow);
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci  BIND(&fast);
611cb0ef41Sopenharmony_ci  // #sec-integerindexedelementset
621cb0ef41Sopenharmony_ci  // 2. If arrayTypeName is "BigUint64Array" or "BigInt64Array", let
631cb0ef41Sopenharmony_ci  // numValue be ? ToBigInt(v).
641cb0ef41Sopenharmony_ci  // 3. Otherwise, let numValue be ? ToNumber(value).
651cb0ef41Sopenharmony_ci  TNode<Object> num_value;
661cb0ef41Sopenharmony_ci  if (source_elements_kind_ == BIGINT64_ELEMENTS ||
671cb0ef41Sopenharmony_ci      source_elements_kind_ == BIGUINT64_ELEMENTS) {
681cb0ef41Sopenharmony_ci    num_value = ToBigInt(context(), mapped_value);
691cb0ef41Sopenharmony_ci  } else {
701cb0ef41Sopenharmony_ci    num_value = ToNumber_Inline(context(), mapped_value);
711cb0ef41Sopenharmony_ci  }
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci  // The only way how this can bailout is because of a detached buffer.
741cb0ef41Sopenharmony_ci  // TODO(v8:4153): Consider checking IsDetachedBuffer() and calling
751cb0ef41Sopenharmony_ci  // TypedArrayBuiltinsAssembler::StoreJSTypedArrayElementFromNumeric() here
761cb0ef41Sopenharmony_ci  // instead to avoid converting k_number back to UintPtrT.
771cb0ef41Sopenharmony_ci  EmitElementStore(CAST(a()), k_number, num_value, source_elements_kind_,
781cb0ef41Sopenharmony_ci                   KeyedAccessStoreMode::STANDARD_STORE, &detached, context());
791cb0ef41Sopenharmony_ci  Goto(&done);
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci  BIND(&slow);
821cb0ef41Sopenharmony_ci  {
831cb0ef41Sopenharmony_ci    SetPropertyStrict(context(), a(), k_number, mapped_value);
841cb0ef41Sopenharmony_ci    Goto(&done);
851cb0ef41Sopenharmony_ci  }
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci  BIND(&detached);
881cb0ef41Sopenharmony_ci  // tc39.github.io/ecma262/#sec-integerindexedelementset
891cb0ef41Sopenharmony_ci  // 8. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
901cb0ef41Sopenharmony_ci  ThrowTypeError(context_, MessageTemplate::kDetachedOperation, name_);
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci  BIND(&done);
931cb0ef41Sopenharmony_ci  return a();
941cb0ef41Sopenharmony_ci}
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_civoid ArrayBuiltinsAssembler::ReturnFromBuiltin(TNode<Object> value) {
971cb0ef41Sopenharmony_ci  if (argc_ == nullptr) {
981cb0ef41Sopenharmony_ci    Return(value);
991cb0ef41Sopenharmony_ci  } else {
1001cb0ef41Sopenharmony_ci    CodeStubArguments args(this, argc());
1011cb0ef41Sopenharmony_ci    PopAndReturn(args.GetLengthWithReceiver(), value);
1021cb0ef41Sopenharmony_ci  }
1031cb0ef41Sopenharmony_ci}
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_civoid ArrayBuiltinsAssembler::InitIteratingArrayBuiltinBody(
1061cb0ef41Sopenharmony_ci    TNode<Context> context, TNode<Object> receiver, TNode<Object> callbackfn,
1071cb0ef41Sopenharmony_ci    TNode<Object> this_arg, TNode<IntPtrT> argc) {
1081cb0ef41Sopenharmony_ci  context_ = context;
1091cb0ef41Sopenharmony_ci  receiver_ = receiver;
1101cb0ef41Sopenharmony_ci  callbackfn_ = callbackfn;
1111cb0ef41Sopenharmony_ci  this_arg_ = this_arg;
1121cb0ef41Sopenharmony_ci  argc_ = argc;
1131cb0ef41Sopenharmony_ci}
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_civoid ArrayBuiltinsAssembler::GenerateIteratingTypedArrayBuiltinBody(
1161cb0ef41Sopenharmony_ci    const char* name, const BuiltinResultGenerator& generator,
1171cb0ef41Sopenharmony_ci    const CallResultProcessor& processor, ForEachDirection direction) {
1181cb0ef41Sopenharmony_ci  name_ = name;
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci  // ValidateTypedArray: tc39.github.io/ecma262/#sec-validatetypedarray
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci  Label throw_not_typed_array(this, Label::kDeferred);
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci  GotoIf(TaggedIsSmi(receiver_), &throw_not_typed_array);
1251cb0ef41Sopenharmony_ci  TNode<Map> typed_array_map = LoadMap(CAST(receiver_));
1261cb0ef41Sopenharmony_ci  GotoIfNot(IsJSTypedArrayMap(typed_array_map), &throw_not_typed_array);
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci  TNode<JSTypedArray> typed_array = CAST(receiver_);
1291cb0ef41Sopenharmony_ci  o_ = typed_array;
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ci  Label throw_detached(this, Label::kDeferred);
1321cb0ef41Sopenharmony_ci  len_ = LoadJSTypedArrayLengthAndCheckDetached(typed_array, &throw_detached);
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci  Label throw_not_callable(this, Label::kDeferred);
1351cb0ef41Sopenharmony_ci  Label distinguish_types(this);
1361cb0ef41Sopenharmony_ci  GotoIf(TaggedIsSmi(callbackfn_), &throw_not_callable);
1371cb0ef41Sopenharmony_ci  Branch(IsCallableMap(LoadMap(CAST(callbackfn_))), &distinguish_types,
1381cb0ef41Sopenharmony_ci         &throw_not_callable);
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci  BIND(&throw_not_typed_array);
1411cb0ef41Sopenharmony_ci  ThrowTypeError(context_, MessageTemplate::kNotTypedArray);
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci  BIND(&throw_not_callable);
1441cb0ef41Sopenharmony_ci  ThrowTypeError(context_, MessageTemplate::kCalledNonCallable, callbackfn_);
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ci  BIND(&throw_detached);
1471cb0ef41Sopenharmony_ci  ThrowTypeError(context_, MessageTemplate::kDetachedOperation, name_);
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci  Label unexpected_instance_type(this);
1501cb0ef41Sopenharmony_ci  BIND(&unexpected_instance_type);
1511cb0ef41Sopenharmony_ci  Unreachable();
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci  std::vector<int32_t> elements_kinds = {
1541cb0ef41Sopenharmony_ci#define ELEMENTS_KIND(Type, type, TYPE, ctype) TYPE##_ELEMENTS,
1551cb0ef41Sopenharmony_ci      TYPED_ARRAYS(ELEMENTS_KIND) RAB_GSAB_TYPED_ARRAYS(ELEMENTS_KIND)
1561cb0ef41Sopenharmony_ci#undef ELEMENTS_KIND
1571cb0ef41Sopenharmony_ci  };
1581cb0ef41Sopenharmony_ci  std::list<Label> labels;
1591cb0ef41Sopenharmony_ci  for (size_t i = 0; i < elements_kinds.size(); ++i) {
1601cb0ef41Sopenharmony_ci    labels.emplace_back(this);
1611cb0ef41Sopenharmony_ci  }
1621cb0ef41Sopenharmony_ci  std::vector<Label*> label_ptrs;
1631cb0ef41Sopenharmony_ci  for (Label& label : labels) {
1641cb0ef41Sopenharmony_ci    label_ptrs.push_back(&label);
1651cb0ef41Sopenharmony_ci  }
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ci  BIND(&distinguish_types);
1681cb0ef41Sopenharmony_ci
1691cb0ef41Sopenharmony_ci  generator(this);
1701cb0ef41Sopenharmony_ci
1711cb0ef41Sopenharmony_ci  TNode<JSArrayBuffer> array_buffer = LoadJSArrayBufferViewBuffer(typed_array);
1721cb0ef41Sopenharmony_ci  TNode<Int32T> elements_kind = LoadMapElementsKind(typed_array_map);
1731cb0ef41Sopenharmony_ci  Switch(elements_kind, &unexpected_instance_type, elements_kinds.data(),
1741cb0ef41Sopenharmony_ci         label_ptrs.data(), labels.size());
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ci  size_t i = 0;
1771cb0ef41Sopenharmony_ci  for (auto it = labels.begin(); it != labels.end(); ++i, ++it) {
1781cb0ef41Sopenharmony_ci    BIND(&*it);
1791cb0ef41Sopenharmony_ci    source_elements_kind_ = static_cast<ElementsKind>(elements_kinds[i]);
1801cb0ef41Sopenharmony_ci    // TODO(v8:11111): Only RAB-backed TAs need special handling here since the
1811cb0ef41Sopenharmony_ci    // backing store can shrink mid-iteration. This implementation has an
1821cb0ef41Sopenharmony_ci    // overzealous check for GSAB-backed length-tracking TAs. Then again, the
1831cb0ef41Sopenharmony_ci    // non-RAB/GSAB code also has an overzealous detached check for SABs.
1841cb0ef41Sopenharmony_ci    bool is_rab_gsab = IsRabGsabTypedArrayElementsKind(source_elements_kind_);
1851cb0ef41Sopenharmony_ci    if (is_rab_gsab) {
1861cb0ef41Sopenharmony_ci      source_elements_kind_ =
1871cb0ef41Sopenharmony_ci          GetCorrespondingNonRabGsabElementsKind(source_elements_kind_);
1881cb0ef41Sopenharmony_ci    }
1891cb0ef41Sopenharmony_ci    VisitAllTypedArrayElements(array_buffer, processor, direction, typed_array,
1901cb0ef41Sopenharmony_ci                               is_rab_gsab);
1911cb0ef41Sopenharmony_ci    ReturnFromBuiltin(a_.value());
1921cb0ef41Sopenharmony_ci  }
1931cb0ef41Sopenharmony_ci}
1941cb0ef41Sopenharmony_ci
1951cb0ef41Sopenharmony_civoid ArrayBuiltinsAssembler::VisitAllTypedArrayElements(
1961cb0ef41Sopenharmony_ci    TNode<JSArrayBuffer> array_buffer, const CallResultProcessor& processor,
1971cb0ef41Sopenharmony_ci    ForEachDirection direction, TNode<JSTypedArray> typed_array,
1981cb0ef41Sopenharmony_ci    bool can_shrink) {
1991cb0ef41Sopenharmony_ci  VariableList list({&a_, &k_}, zone());
2001cb0ef41Sopenharmony_ci
2011cb0ef41Sopenharmony_ci  TNode<UintPtrT> start = UintPtrConstant(0);
2021cb0ef41Sopenharmony_ci  TNode<UintPtrT> end = len_;
2031cb0ef41Sopenharmony_ci  IndexAdvanceMode advance_mode = IndexAdvanceMode::kPost;
2041cb0ef41Sopenharmony_ci  int incr = 1;
2051cb0ef41Sopenharmony_ci  if (direction == ForEachDirection::kReverse) {
2061cb0ef41Sopenharmony_ci    std::swap(start, end);
2071cb0ef41Sopenharmony_ci    advance_mode = IndexAdvanceMode::kPre;
2081cb0ef41Sopenharmony_ci    incr = -1;
2091cb0ef41Sopenharmony_ci  }
2101cb0ef41Sopenharmony_ci  k_ = start;
2111cb0ef41Sopenharmony_ci  BuildFastLoop<UintPtrT>(
2121cb0ef41Sopenharmony_ci      list, start, end,
2131cb0ef41Sopenharmony_ci      [&](TNode<UintPtrT> index) {
2141cb0ef41Sopenharmony_ci        TVARIABLE(Object, value);
2151cb0ef41Sopenharmony_ci        Label detached(this, Label::kDeferred);
2161cb0ef41Sopenharmony_ci        Label process(this);
2171cb0ef41Sopenharmony_ci        if (can_shrink) {
2181cb0ef41Sopenharmony_ci          // If `index` is out of bounds, Get returns undefined.
2191cb0ef41Sopenharmony_ci          CheckJSTypedArrayIndex(index, typed_array, &detached);
2201cb0ef41Sopenharmony_ci        } else {
2211cb0ef41Sopenharmony_ci          GotoIf(IsDetachedBuffer(array_buffer), &detached);
2221cb0ef41Sopenharmony_ci        }
2231cb0ef41Sopenharmony_ci        {
2241cb0ef41Sopenharmony_ci          TNode<RawPtrT> data_ptr = LoadJSTypedArrayDataPtr(typed_array);
2251cb0ef41Sopenharmony_ci          value = LoadFixedTypedArrayElementAsTagged(data_ptr, index,
2261cb0ef41Sopenharmony_ci                                                     source_elements_kind_);
2271cb0ef41Sopenharmony_ci          Goto(&process);
2281cb0ef41Sopenharmony_ci        }
2291cb0ef41Sopenharmony_ci
2301cb0ef41Sopenharmony_ci        BIND(&detached);
2311cb0ef41Sopenharmony_ci        {
2321cb0ef41Sopenharmony_ci          value = UndefinedConstant();
2331cb0ef41Sopenharmony_ci          Goto(&process);
2341cb0ef41Sopenharmony_ci        }
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ci        BIND(&process);
2371cb0ef41Sopenharmony_ci        {
2381cb0ef41Sopenharmony_ci          k_ = index;
2391cb0ef41Sopenharmony_ci          a_ = processor(this, value.value(), index);
2401cb0ef41Sopenharmony_ci        }
2411cb0ef41Sopenharmony_ci      },
2421cb0ef41Sopenharmony_ci      incr, advance_mode);
2431cb0ef41Sopenharmony_ci}
2441cb0ef41Sopenharmony_ci
2451cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayPrototypePop, CodeStubAssembler) {
2461cb0ef41Sopenharmony_ci  auto argc = UncheckedParameter<Int32T>(Descriptor::kJSActualArgumentsCount);
2471cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
2481cb0ef41Sopenharmony_ci  CSA_DCHECK(this, IsUndefined(Parameter<Object>(Descriptor::kJSNewTarget)));
2491cb0ef41Sopenharmony_ci
2501cb0ef41Sopenharmony_ci  CodeStubArguments args(this, argc);
2511cb0ef41Sopenharmony_ci  TNode<Object> receiver = args.GetReceiver();
2521cb0ef41Sopenharmony_ci
2531cb0ef41Sopenharmony_ci  Label runtime(this, Label::kDeferred);
2541cb0ef41Sopenharmony_ci  Label fast(this);
2551cb0ef41Sopenharmony_ci
2561cb0ef41Sopenharmony_ci  // Only pop in this stub if
2571cb0ef41Sopenharmony_ci  // 1) the array has fast elements
2581cb0ef41Sopenharmony_ci  // 2) the length is writable,
2591cb0ef41Sopenharmony_ci  // 3) the elements backing store isn't copy-on-write,
2601cb0ef41Sopenharmony_ci  // 4) we aren't supposed to shrink the backing store.
2611cb0ef41Sopenharmony_ci
2621cb0ef41Sopenharmony_ci  // 1) Check that the array has fast elements.
2631cb0ef41Sopenharmony_ci  BranchIfFastJSArray(receiver, context, &fast, &runtime);
2641cb0ef41Sopenharmony_ci
2651cb0ef41Sopenharmony_ci  BIND(&fast);
2661cb0ef41Sopenharmony_ci  {
2671cb0ef41Sopenharmony_ci    TNode<JSArray> array_receiver = CAST(receiver);
2681cb0ef41Sopenharmony_ci    CSA_DCHECK(this, TaggedIsPositiveSmi(LoadJSArrayLength(array_receiver)));
2691cb0ef41Sopenharmony_ci    TNode<IntPtrT> length =
2701cb0ef41Sopenharmony_ci        LoadAndUntagObjectField(array_receiver, JSArray::kLengthOffset);
2711cb0ef41Sopenharmony_ci    Label return_undefined(this), fast_elements(this);
2721cb0ef41Sopenharmony_ci
2731cb0ef41Sopenharmony_ci    // 2) Ensure that the length is writable.
2741cb0ef41Sopenharmony_ci    EnsureArrayLengthWritable(context, LoadMap(array_receiver), &runtime);
2751cb0ef41Sopenharmony_ci
2761cb0ef41Sopenharmony_ci    GotoIf(IntPtrEqual(length, IntPtrConstant(0)), &return_undefined);
2771cb0ef41Sopenharmony_ci
2781cb0ef41Sopenharmony_ci    // 3) Check that the elements backing store isn't copy-on-write.
2791cb0ef41Sopenharmony_ci    TNode<FixedArrayBase> elements = LoadElements(array_receiver);
2801cb0ef41Sopenharmony_ci    GotoIf(TaggedEqual(LoadMap(elements), FixedCOWArrayMapConstant()),
2811cb0ef41Sopenharmony_ci           &runtime);
2821cb0ef41Sopenharmony_ci
2831cb0ef41Sopenharmony_ci    TNode<IntPtrT> new_length = IntPtrSub(length, IntPtrConstant(1));
2841cb0ef41Sopenharmony_ci
2851cb0ef41Sopenharmony_ci    // 4) Check that we're not supposed to shrink the backing store, as
2861cb0ef41Sopenharmony_ci    //    implemented in elements.cc:ElementsAccessorBase::SetLengthImpl.
2871cb0ef41Sopenharmony_ci    TNode<IntPtrT> capacity = SmiUntag(LoadFixedArrayBaseLength(elements));
2881cb0ef41Sopenharmony_ci    GotoIf(IntPtrLessThan(
2891cb0ef41Sopenharmony_ci               IntPtrAdd(IntPtrAdd(new_length, new_length),
2901cb0ef41Sopenharmony_ci                         IntPtrConstant(JSObject::kMinAddedElementsCapacity)),
2911cb0ef41Sopenharmony_ci               capacity),
2921cb0ef41Sopenharmony_ci           &runtime);
2931cb0ef41Sopenharmony_ci
2941cb0ef41Sopenharmony_ci    StoreObjectFieldNoWriteBarrier(array_receiver, JSArray::kLengthOffset,
2951cb0ef41Sopenharmony_ci                                   SmiTag(new_length));
2961cb0ef41Sopenharmony_ci
2971cb0ef41Sopenharmony_ci    TNode<Int32T> elements_kind = LoadElementsKind(array_receiver);
2981cb0ef41Sopenharmony_ci    GotoIf(Int32LessThanOrEqual(elements_kind,
2991cb0ef41Sopenharmony_ci                                Int32Constant(TERMINAL_FAST_ELEMENTS_KIND)),
3001cb0ef41Sopenharmony_ci           &fast_elements);
3011cb0ef41Sopenharmony_ci
3021cb0ef41Sopenharmony_ci    {
3031cb0ef41Sopenharmony_ci      TNode<FixedDoubleArray> elements_known_double_array =
3041cb0ef41Sopenharmony_ci          ReinterpretCast<FixedDoubleArray>(elements);
3051cb0ef41Sopenharmony_ci      TNode<Float64T> value = LoadFixedDoubleArrayElement(
3061cb0ef41Sopenharmony_ci          elements_known_double_array, new_length, &return_undefined);
3071cb0ef41Sopenharmony_ci
3081cb0ef41Sopenharmony_ci      StoreFixedDoubleArrayHole(elements_known_double_array, new_length);
3091cb0ef41Sopenharmony_ci      args.PopAndReturn(AllocateHeapNumberWithValue(value));
3101cb0ef41Sopenharmony_ci    }
3111cb0ef41Sopenharmony_ci
3121cb0ef41Sopenharmony_ci    BIND(&fast_elements);
3131cb0ef41Sopenharmony_ci    {
3141cb0ef41Sopenharmony_ci      TNode<FixedArray> elements_known_fixed_array = CAST(elements);
3151cb0ef41Sopenharmony_ci      TNode<Object> value =
3161cb0ef41Sopenharmony_ci          LoadFixedArrayElement(elements_known_fixed_array, new_length);
3171cb0ef41Sopenharmony_ci      StoreFixedArrayElement(elements_known_fixed_array, new_length,
3181cb0ef41Sopenharmony_ci                             TheHoleConstant());
3191cb0ef41Sopenharmony_ci      GotoIf(TaggedEqual(value, TheHoleConstant()), &return_undefined);
3201cb0ef41Sopenharmony_ci      args.PopAndReturn(value);
3211cb0ef41Sopenharmony_ci    }
3221cb0ef41Sopenharmony_ci
3231cb0ef41Sopenharmony_ci    BIND(&return_undefined);
3241cb0ef41Sopenharmony_ci    { args.PopAndReturn(UndefinedConstant()); }
3251cb0ef41Sopenharmony_ci  }
3261cb0ef41Sopenharmony_ci
3271cb0ef41Sopenharmony_ci  BIND(&runtime);
3281cb0ef41Sopenharmony_ci  {
3291cb0ef41Sopenharmony_ci    // We are not using Parameter(Descriptor::kJSTarget) and loading the value
3301cb0ef41Sopenharmony_ci    // from the current frame here in order to reduce register pressure on the
3311cb0ef41Sopenharmony_ci    // fast path.
3321cb0ef41Sopenharmony_ci    TNode<JSFunction> target = LoadTargetFromFrame();
3331cb0ef41Sopenharmony_ci    TailCallBuiltin(Builtin::kArrayPop, context, target, UndefinedConstant(),
3341cb0ef41Sopenharmony_ci                    argc);
3351cb0ef41Sopenharmony_ci  }
3361cb0ef41Sopenharmony_ci}
3371cb0ef41Sopenharmony_ci
3381cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayPrototypePush, CodeStubAssembler) {
3391cb0ef41Sopenharmony_ci  TVARIABLE(IntPtrT, arg_index);
3401cb0ef41Sopenharmony_ci  Label default_label(this, &arg_index);
3411cb0ef41Sopenharmony_ci  Label smi_transition(this);
3421cb0ef41Sopenharmony_ci  Label object_push_pre(this);
3431cb0ef41Sopenharmony_ci  Label object_push(this, &arg_index);
3441cb0ef41Sopenharmony_ci  Label double_push(this, &arg_index);
3451cb0ef41Sopenharmony_ci  Label double_transition(this);
3461cb0ef41Sopenharmony_ci  Label runtime(this, Label::kDeferred);
3471cb0ef41Sopenharmony_ci
3481cb0ef41Sopenharmony_ci  auto argc = UncheckedParameter<Int32T>(Descriptor::kJSActualArgumentsCount);
3491cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
3501cb0ef41Sopenharmony_ci  CSA_DCHECK(this, IsUndefined(Parameter<Object>(Descriptor::kJSNewTarget)));
3511cb0ef41Sopenharmony_ci
3521cb0ef41Sopenharmony_ci  CodeStubArguments args(this, argc);
3531cb0ef41Sopenharmony_ci  TNode<Object> receiver = args.GetReceiver();
3541cb0ef41Sopenharmony_ci  TNode<JSArray> array_receiver;
3551cb0ef41Sopenharmony_ci  TNode<Int32T> kind;
3561cb0ef41Sopenharmony_ci
3571cb0ef41Sopenharmony_ci  Label fast(this);
3581cb0ef41Sopenharmony_ci  BranchIfFastJSArray(receiver, context, &fast, &runtime);
3591cb0ef41Sopenharmony_ci
3601cb0ef41Sopenharmony_ci  BIND(&fast);
3611cb0ef41Sopenharmony_ci  {
3621cb0ef41Sopenharmony_ci    array_receiver = CAST(receiver);
3631cb0ef41Sopenharmony_ci    arg_index = IntPtrConstant(0);
3641cb0ef41Sopenharmony_ci    kind = EnsureArrayPushable(context, LoadMap(array_receiver), &runtime);
3651cb0ef41Sopenharmony_ci    GotoIf(IsElementsKindGreaterThan(kind, HOLEY_SMI_ELEMENTS),
3661cb0ef41Sopenharmony_ci           &object_push_pre);
3671cb0ef41Sopenharmony_ci
3681cb0ef41Sopenharmony_ci    TNode<Smi> new_length =
3691cb0ef41Sopenharmony_ci        BuildAppendJSArray(PACKED_SMI_ELEMENTS, array_receiver, &args,
3701cb0ef41Sopenharmony_ci                           &arg_index, &smi_transition);
3711cb0ef41Sopenharmony_ci    args.PopAndReturn(new_length);
3721cb0ef41Sopenharmony_ci  }
3731cb0ef41Sopenharmony_ci
3741cb0ef41Sopenharmony_ci  // If the argument is not a smi, then use a heavyweight SetProperty to
3751cb0ef41Sopenharmony_ci  // transition the array for only the single next element. If the argument is
3761cb0ef41Sopenharmony_ci  // a smi, the failure is due to some other reason and we should fall back on
3771cb0ef41Sopenharmony_ci  // the most generic implementation for the rest of the array.
3781cb0ef41Sopenharmony_ci  BIND(&smi_transition);
3791cb0ef41Sopenharmony_ci  {
3801cb0ef41Sopenharmony_ci    TNode<Object> arg = args.AtIndex(arg_index.value());
3811cb0ef41Sopenharmony_ci    GotoIf(TaggedIsSmi(arg), &default_label);
3821cb0ef41Sopenharmony_ci    TNode<Number> length = LoadJSArrayLength(array_receiver);
3831cb0ef41Sopenharmony_ci    // TODO(danno): Use the KeyedStoreGeneric stub here when possible,
3841cb0ef41Sopenharmony_ci    // calling into the runtime to do the elements transition is overkill.
3851cb0ef41Sopenharmony_ci    SetPropertyStrict(context, array_receiver, length, arg);
3861cb0ef41Sopenharmony_ci    Increment(&arg_index);
3871cb0ef41Sopenharmony_ci    // The runtime SetProperty call could have converted the array to dictionary
3881cb0ef41Sopenharmony_ci    // mode, which must be detected to abort the fast-path.
3891cb0ef41Sopenharmony_ci    TNode<Int32T> elements_kind = LoadElementsKind(array_receiver);
3901cb0ef41Sopenharmony_ci    GotoIf(Word32Equal(elements_kind, Int32Constant(DICTIONARY_ELEMENTS)),
3911cb0ef41Sopenharmony_ci           &default_label);
3921cb0ef41Sopenharmony_ci
3931cb0ef41Sopenharmony_ci    GotoIfNotNumber(arg, &object_push);
3941cb0ef41Sopenharmony_ci    Goto(&double_push);
3951cb0ef41Sopenharmony_ci  }
3961cb0ef41Sopenharmony_ci
3971cb0ef41Sopenharmony_ci  BIND(&object_push_pre);
3981cb0ef41Sopenharmony_ci  {
3991cb0ef41Sopenharmony_ci    Branch(IsElementsKindGreaterThan(kind, HOLEY_ELEMENTS), &double_push,
4001cb0ef41Sopenharmony_ci           &object_push);
4011cb0ef41Sopenharmony_ci  }
4021cb0ef41Sopenharmony_ci
4031cb0ef41Sopenharmony_ci  BIND(&object_push);
4041cb0ef41Sopenharmony_ci  {
4051cb0ef41Sopenharmony_ci    TNode<Smi> new_length = BuildAppendJSArray(
4061cb0ef41Sopenharmony_ci        PACKED_ELEMENTS, array_receiver, &args, &arg_index, &default_label);
4071cb0ef41Sopenharmony_ci    args.PopAndReturn(new_length);
4081cb0ef41Sopenharmony_ci  }
4091cb0ef41Sopenharmony_ci
4101cb0ef41Sopenharmony_ci  BIND(&double_push);
4111cb0ef41Sopenharmony_ci  {
4121cb0ef41Sopenharmony_ci    TNode<Smi> new_length =
4131cb0ef41Sopenharmony_ci        BuildAppendJSArray(PACKED_DOUBLE_ELEMENTS, array_receiver, &args,
4141cb0ef41Sopenharmony_ci                           &arg_index, &double_transition);
4151cb0ef41Sopenharmony_ci    args.PopAndReturn(new_length);
4161cb0ef41Sopenharmony_ci  }
4171cb0ef41Sopenharmony_ci
4181cb0ef41Sopenharmony_ci  // If the argument is not a double, then use a heavyweight SetProperty to
4191cb0ef41Sopenharmony_ci  // transition the array for only the single next element. If the argument is
4201cb0ef41Sopenharmony_ci  // a double, the failure is due to some other reason and we should fall back
4211cb0ef41Sopenharmony_ci  // on the most generic implementation for the rest of the array.
4221cb0ef41Sopenharmony_ci  BIND(&double_transition);
4231cb0ef41Sopenharmony_ci  {
4241cb0ef41Sopenharmony_ci    TNode<Object> arg = args.AtIndex(arg_index.value());
4251cb0ef41Sopenharmony_ci    GotoIfNumber(arg, &default_label);
4261cb0ef41Sopenharmony_ci    TNode<Number> length = LoadJSArrayLength(array_receiver);
4271cb0ef41Sopenharmony_ci    // TODO(danno): Use the KeyedStoreGeneric stub here when possible,
4281cb0ef41Sopenharmony_ci    // calling into the runtime to do the elements transition is overkill.
4291cb0ef41Sopenharmony_ci    SetPropertyStrict(context, array_receiver, length, arg);
4301cb0ef41Sopenharmony_ci    Increment(&arg_index);
4311cb0ef41Sopenharmony_ci    // The runtime SetProperty call could have converted the array to dictionary
4321cb0ef41Sopenharmony_ci    // mode, which must be detected to abort the fast-path.
4331cb0ef41Sopenharmony_ci    TNode<Int32T> elements_kind = LoadElementsKind(array_receiver);
4341cb0ef41Sopenharmony_ci    GotoIf(Word32Equal(elements_kind, Int32Constant(DICTIONARY_ELEMENTS)),
4351cb0ef41Sopenharmony_ci           &default_label);
4361cb0ef41Sopenharmony_ci    Goto(&object_push);
4371cb0ef41Sopenharmony_ci  }
4381cb0ef41Sopenharmony_ci
4391cb0ef41Sopenharmony_ci  // Fallback that stores un-processed arguments using the full, heavyweight
4401cb0ef41Sopenharmony_ci  // SetProperty machinery.
4411cb0ef41Sopenharmony_ci  BIND(&default_label);
4421cb0ef41Sopenharmony_ci  {
4431cb0ef41Sopenharmony_ci    args.ForEach(
4441cb0ef41Sopenharmony_ci        [=](TNode<Object> arg) {
4451cb0ef41Sopenharmony_ci          TNode<Number> length = LoadJSArrayLength(array_receiver);
4461cb0ef41Sopenharmony_ci          SetPropertyStrict(context, array_receiver, length, arg);
4471cb0ef41Sopenharmony_ci        },
4481cb0ef41Sopenharmony_ci        arg_index.value());
4491cb0ef41Sopenharmony_ci    args.PopAndReturn(LoadJSArrayLength(array_receiver));
4501cb0ef41Sopenharmony_ci  }
4511cb0ef41Sopenharmony_ci
4521cb0ef41Sopenharmony_ci  BIND(&runtime);
4531cb0ef41Sopenharmony_ci  {
4541cb0ef41Sopenharmony_ci    // We are not using Parameter(Descriptor::kJSTarget) and loading the value
4551cb0ef41Sopenharmony_ci    // from the current frame here in order to reduce register pressure on the
4561cb0ef41Sopenharmony_ci    // fast path.
4571cb0ef41Sopenharmony_ci    TNode<JSFunction> target = LoadTargetFromFrame();
4581cb0ef41Sopenharmony_ci    TailCallBuiltin(Builtin::kArrayPush, context, target, UndefinedConstant(),
4591cb0ef41Sopenharmony_ci                    argc);
4601cb0ef41Sopenharmony_ci  }
4611cb0ef41Sopenharmony_ci}
4621cb0ef41Sopenharmony_ci
4631cb0ef41Sopenharmony_ciTF_BUILTIN(ExtractFastJSArray, ArrayBuiltinsAssembler) {
4641cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
4651cb0ef41Sopenharmony_ci  auto array = Parameter<JSArray>(Descriptor::kSource);
4661cb0ef41Sopenharmony_ci  TNode<BInt> begin = SmiToBInt(Parameter<Smi>(Descriptor::kBegin));
4671cb0ef41Sopenharmony_ci  TNode<BInt> count = SmiToBInt(Parameter<Smi>(Descriptor::kCount));
4681cb0ef41Sopenharmony_ci
4691cb0ef41Sopenharmony_ci  CSA_DCHECK(this, Word32BinaryNot(IsNoElementsProtectorCellInvalid()));
4701cb0ef41Sopenharmony_ci
4711cb0ef41Sopenharmony_ci  Return(ExtractFastJSArray(context, array, begin, count));
4721cb0ef41Sopenharmony_ci}
4731cb0ef41Sopenharmony_ci
4741cb0ef41Sopenharmony_ciTF_BUILTIN(CloneFastJSArray, ArrayBuiltinsAssembler) {
4751cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
4761cb0ef41Sopenharmony_ci  auto array = Parameter<JSArray>(Descriptor::kSource);
4771cb0ef41Sopenharmony_ci
4781cb0ef41Sopenharmony_ci  CSA_DCHECK(this,
4791cb0ef41Sopenharmony_ci             Word32Or(Word32BinaryNot(IsHoleyFastElementsKindForRead(
4801cb0ef41Sopenharmony_ci                          LoadElementsKind(array))),
4811cb0ef41Sopenharmony_ci                      Word32BinaryNot(IsNoElementsProtectorCellInvalid())));
4821cb0ef41Sopenharmony_ci
4831cb0ef41Sopenharmony_ci  Return(CloneFastJSArray(context, array));
4841cb0ef41Sopenharmony_ci}
4851cb0ef41Sopenharmony_ci
4861cb0ef41Sopenharmony_ci// This builtin copies the backing store of fast arrays, while converting any
4871cb0ef41Sopenharmony_ci// holes to undefined.
4881cb0ef41Sopenharmony_ci// - If there are no holes in the source, its ElementsKind will be preserved. In
4891cb0ef41Sopenharmony_ci// that case, this builtin should perform as fast as CloneFastJSArray. (In fact,
4901cb0ef41Sopenharmony_ci// for fast packed arrays, the behavior is equivalent to CloneFastJSArray.)
4911cb0ef41Sopenharmony_ci// - If there are holes in the source, the ElementsKind of the "copy" will be
4921cb0ef41Sopenharmony_ci// PACKED_ELEMENTS (such that undefined can be stored).
4931cb0ef41Sopenharmony_ciTF_BUILTIN(CloneFastJSArrayFillingHoles, ArrayBuiltinsAssembler) {
4941cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
4951cb0ef41Sopenharmony_ci  auto array = Parameter<JSArray>(Descriptor::kSource);
4961cb0ef41Sopenharmony_ci
4971cb0ef41Sopenharmony_ci  CSA_DCHECK(this,
4981cb0ef41Sopenharmony_ci             Word32Or(Word32BinaryNot(IsHoleyFastElementsKindForRead(
4991cb0ef41Sopenharmony_ci                          LoadElementsKind(array))),
5001cb0ef41Sopenharmony_ci                      Word32BinaryNot(IsNoElementsProtectorCellInvalid())));
5011cb0ef41Sopenharmony_ci
5021cb0ef41Sopenharmony_ci  Return(CloneFastJSArray(context, array, base::nullopt,
5031cb0ef41Sopenharmony_ci                          HoleConversionMode::kConvertToUndefined));
5041cb0ef41Sopenharmony_ci}
5051cb0ef41Sopenharmony_ci
5061cb0ef41Sopenharmony_ciclass ArrayPopulatorAssembler : public CodeStubAssembler {
5071cb0ef41Sopenharmony_ci public:
5081cb0ef41Sopenharmony_ci  explicit ArrayPopulatorAssembler(compiler::CodeAssemblerState* state)
5091cb0ef41Sopenharmony_ci      : CodeStubAssembler(state) {}
5101cb0ef41Sopenharmony_ci
5111cb0ef41Sopenharmony_ci  TNode<Object> ConstructArrayLike(TNode<Context> context,
5121cb0ef41Sopenharmony_ci                                   TNode<Object> receiver) {
5131cb0ef41Sopenharmony_ci    TVARIABLE(Object, array);
5141cb0ef41Sopenharmony_ci    Label is_constructor(this), is_not_constructor(this), done(this);
5151cb0ef41Sopenharmony_ci    GotoIf(TaggedIsSmi(receiver), &is_not_constructor);
5161cb0ef41Sopenharmony_ci    Branch(IsConstructor(CAST(receiver)), &is_constructor, &is_not_constructor);
5171cb0ef41Sopenharmony_ci
5181cb0ef41Sopenharmony_ci    BIND(&is_constructor);
5191cb0ef41Sopenharmony_ci    {
5201cb0ef41Sopenharmony_ci      array = Construct(context, CAST(receiver));
5211cb0ef41Sopenharmony_ci      Goto(&done);
5221cb0ef41Sopenharmony_ci    }
5231cb0ef41Sopenharmony_ci
5241cb0ef41Sopenharmony_ci    BIND(&is_not_constructor);
5251cb0ef41Sopenharmony_ci    {
5261cb0ef41Sopenharmony_ci      Label allocate_js_array(this);
5271cb0ef41Sopenharmony_ci
5281cb0ef41Sopenharmony_ci      TNode<Map> array_map = CAST(LoadContextElement(
5291cb0ef41Sopenharmony_ci          context, Context::JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX));
5301cb0ef41Sopenharmony_ci
5311cb0ef41Sopenharmony_ci      TNode<IntPtrT> capacity = IntPtrConstant(0);
5321cb0ef41Sopenharmony_ci      TNode<Smi> length = SmiConstant(0);
5331cb0ef41Sopenharmony_ci      array = AllocateJSArray(PACKED_SMI_ELEMENTS, array_map, capacity, length);
5341cb0ef41Sopenharmony_ci      Goto(&done);
5351cb0ef41Sopenharmony_ci    }
5361cb0ef41Sopenharmony_ci
5371cb0ef41Sopenharmony_ci    BIND(&done);
5381cb0ef41Sopenharmony_ci    return array.value();
5391cb0ef41Sopenharmony_ci  }
5401cb0ef41Sopenharmony_ci
5411cb0ef41Sopenharmony_ci  TNode<Object> ConstructArrayLike(TNode<Context> context,
5421cb0ef41Sopenharmony_ci                                   TNode<Object> receiver,
5431cb0ef41Sopenharmony_ci                                   TNode<Number> length) {
5441cb0ef41Sopenharmony_ci    TVARIABLE(Object, array);
5451cb0ef41Sopenharmony_ci    Label is_constructor(this), is_not_constructor(this), done(this);
5461cb0ef41Sopenharmony_ci    CSA_DCHECK(this, IsNumberNormalized(length));
5471cb0ef41Sopenharmony_ci    GotoIf(TaggedIsSmi(receiver), &is_not_constructor);
5481cb0ef41Sopenharmony_ci    Branch(IsConstructor(CAST(receiver)), &is_constructor, &is_not_constructor);
5491cb0ef41Sopenharmony_ci
5501cb0ef41Sopenharmony_ci    BIND(&is_constructor);
5511cb0ef41Sopenharmony_ci    {
5521cb0ef41Sopenharmony_ci      array = Construct(context, CAST(receiver), length);
5531cb0ef41Sopenharmony_ci      Goto(&done);
5541cb0ef41Sopenharmony_ci    }
5551cb0ef41Sopenharmony_ci
5561cb0ef41Sopenharmony_ci    BIND(&is_not_constructor);
5571cb0ef41Sopenharmony_ci    {
5581cb0ef41Sopenharmony_ci      array = ArrayCreate(context, length);
5591cb0ef41Sopenharmony_ci      Goto(&done);
5601cb0ef41Sopenharmony_ci    }
5611cb0ef41Sopenharmony_ci
5621cb0ef41Sopenharmony_ci    BIND(&done);
5631cb0ef41Sopenharmony_ci    return array.value();
5641cb0ef41Sopenharmony_ci  }
5651cb0ef41Sopenharmony_ci};
5661cb0ef41Sopenharmony_ci
5671cb0ef41Sopenharmony_ciTF_BUILTIN(TypedArrayPrototypeMap, ArrayBuiltinsAssembler) {
5681cb0ef41Sopenharmony_ci  TNode<IntPtrT> argc = ChangeInt32ToIntPtr(
5691cb0ef41Sopenharmony_ci      UncheckedParameter<Int32T>(Descriptor::kJSActualArgumentsCount));
5701cb0ef41Sopenharmony_ci  CodeStubArguments args(this, argc);
5711cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
5721cb0ef41Sopenharmony_ci  TNode<Object> receiver = args.GetReceiver();
5731cb0ef41Sopenharmony_ci  TNode<Object> callbackfn = args.GetOptionalArgumentValue(0);
5741cb0ef41Sopenharmony_ci  TNode<Object> this_arg = args.GetOptionalArgumentValue(1);
5751cb0ef41Sopenharmony_ci
5761cb0ef41Sopenharmony_ci  InitIteratingArrayBuiltinBody(context, receiver, callbackfn, this_arg, argc);
5771cb0ef41Sopenharmony_ci
5781cb0ef41Sopenharmony_ci  GenerateIteratingTypedArrayBuiltinBody(
5791cb0ef41Sopenharmony_ci      "%TypedArray%.prototype.map",
5801cb0ef41Sopenharmony_ci      &ArrayBuiltinsAssembler::TypedArrayMapResultGenerator,
5811cb0ef41Sopenharmony_ci      &ArrayBuiltinsAssembler::TypedArrayMapProcessor);
5821cb0ef41Sopenharmony_ci}
5831cb0ef41Sopenharmony_ci
5841cb0ef41Sopenharmony_ciclass ArrayIncludesIndexofAssembler : public CodeStubAssembler {
5851cb0ef41Sopenharmony_ci public:
5861cb0ef41Sopenharmony_ci  explicit ArrayIncludesIndexofAssembler(compiler::CodeAssemblerState* state)
5871cb0ef41Sopenharmony_ci      : CodeStubAssembler(state) {}
5881cb0ef41Sopenharmony_ci
5891cb0ef41Sopenharmony_ci  enum SearchVariant { kIncludes, kIndexOf };
5901cb0ef41Sopenharmony_ci
5911cb0ef41Sopenharmony_ci  void Generate(SearchVariant variant, TNode<IntPtrT> argc,
5921cb0ef41Sopenharmony_ci                TNode<Context> context);
5931cb0ef41Sopenharmony_ci  void GenerateSmiOrObject(SearchVariant variant, TNode<Context> context,
5941cb0ef41Sopenharmony_ci                           TNode<FixedArray> elements,
5951cb0ef41Sopenharmony_ci                           TNode<Object> search_element,
5961cb0ef41Sopenharmony_ci                           TNode<Smi> array_length, TNode<Smi> from_index);
5971cb0ef41Sopenharmony_ci  void GeneratePackedDoubles(SearchVariant variant,
5981cb0ef41Sopenharmony_ci                             TNode<FixedDoubleArray> elements,
5991cb0ef41Sopenharmony_ci                             TNode<Object> search_element,
6001cb0ef41Sopenharmony_ci                             TNode<Smi> array_length, TNode<Smi> from_index);
6011cb0ef41Sopenharmony_ci  void GenerateHoleyDoubles(SearchVariant variant,
6021cb0ef41Sopenharmony_ci                            TNode<FixedDoubleArray> elements,
6031cb0ef41Sopenharmony_ci                            TNode<Object> search_element,
6041cb0ef41Sopenharmony_ci                            TNode<Smi> array_length, TNode<Smi> from_index);
6051cb0ef41Sopenharmony_ci
6061cb0ef41Sopenharmony_ci  void ReturnIfEmpty(TNode<Smi> length, TNode<Object> value) {
6071cb0ef41Sopenharmony_ci    Label done(this);
6081cb0ef41Sopenharmony_ci    GotoIf(SmiGreaterThan(length, SmiConstant(0)), &done);
6091cb0ef41Sopenharmony_ci    Return(value);
6101cb0ef41Sopenharmony_ci    BIND(&done);
6111cb0ef41Sopenharmony_ci  }
6121cb0ef41Sopenharmony_ci};
6131cb0ef41Sopenharmony_ci
6141cb0ef41Sopenharmony_civoid ArrayIncludesIndexofAssembler::Generate(SearchVariant variant,
6151cb0ef41Sopenharmony_ci                                             TNode<IntPtrT> argc,
6161cb0ef41Sopenharmony_ci                                             TNode<Context> context) {
6171cb0ef41Sopenharmony_ci  const int kSearchElementArg = 0;
6181cb0ef41Sopenharmony_ci  const int kFromIndexArg = 1;
6191cb0ef41Sopenharmony_ci
6201cb0ef41Sopenharmony_ci  CodeStubArguments args(this, argc);
6211cb0ef41Sopenharmony_ci
6221cb0ef41Sopenharmony_ci  TNode<Object> receiver = args.GetReceiver();
6231cb0ef41Sopenharmony_ci  TNode<Object> search_element =
6241cb0ef41Sopenharmony_ci      args.GetOptionalArgumentValue(kSearchElementArg);
6251cb0ef41Sopenharmony_ci
6261cb0ef41Sopenharmony_ci  TNode<IntPtrT> intptr_zero = IntPtrConstant(0);
6271cb0ef41Sopenharmony_ci
6281cb0ef41Sopenharmony_ci  Label init_index(this), return_not_found(this), call_runtime(this);
6291cb0ef41Sopenharmony_ci
6301cb0ef41Sopenharmony_ci  // Take slow path if not a JSArray, if retrieving elements requires
6311cb0ef41Sopenharmony_ci  // traversing prototype, or if access checks are required.
6321cb0ef41Sopenharmony_ci  BranchIfFastJSArrayForRead(receiver, context, &init_index, &call_runtime);
6331cb0ef41Sopenharmony_ci
6341cb0ef41Sopenharmony_ci  BIND(&init_index);
6351cb0ef41Sopenharmony_ci  TVARIABLE(IntPtrT, index_var, intptr_zero);
6361cb0ef41Sopenharmony_ci  TNode<JSArray> array = CAST(receiver);
6371cb0ef41Sopenharmony_ci
6381cb0ef41Sopenharmony_ci  // JSArray length is always a positive Smi for fast arrays.
6391cb0ef41Sopenharmony_ci  CSA_DCHECK(this, TaggedIsPositiveSmi(LoadJSArrayLength(array)));
6401cb0ef41Sopenharmony_ci  TNode<Smi> array_length = LoadFastJSArrayLength(array);
6411cb0ef41Sopenharmony_ci  TNode<IntPtrT> array_length_untagged = SmiUntag(array_length);
6421cb0ef41Sopenharmony_ci
6431cb0ef41Sopenharmony_ci  {
6441cb0ef41Sopenharmony_ci    // Initialize fromIndex.
6451cb0ef41Sopenharmony_ci    Label is_smi(this), is_nonsmi(this), done(this);
6461cb0ef41Sopenharmony_ci
6471cb0ef41Sopenharmony_ci    // If no fromIndex was passed, default to 0.
6481cb0ef41Sopenharmony_ci    GotoIf(IntPtrLessThanOrEqual(args.GetLengthWithoutReceiver(),
6491cb0ef41Sopenharmony_ci                                 IntPtrConstant(kFromIndexArg)),
6501cb0ef41Sopenharmony_ci           &done);
6511cb0ef41Sopenharmony_ci
6521cb0ef41Sopenharmony_ci    TNode<Object> start_from = args.AtIndex(kFromIndexArg);
6531cb0ef41Sopenharmony_ci    // Handle Smis and undefined here and everything else in runtime.
6541cb0ef41Sopenharmony_ci    // We must be very careful with side effects from the ToInteger conversion,
6551cb0ef41Sopenharmony_ci    // as the side effects might render previously checked assumptions about
6561cb0ef41Sopenharmony_ci    // the receiver being a fast JSArray and its length invalid.
6571cb0ef41Sopenharmony_ci    Branch(TaggedIsSmi(start_from), &is_smi, &is_nonsmi);
6581cb0ef41Sopenharmony_ci
6591cb0ef41Sopenharmony_ci    BIND(&is_nonsmi);
6601cb0ef41Sopenharmony_ci    {
6611cb0ef41Sopenharmony_ci      GotoIfNot(IsUndefined(start_from), &call_runtime);
6621cb0ef41Sopenharmony_ci      Goto(&done);
6631cb0ef41Sopenharmony_ci    }
6641cb0ef41Sopenharmony_ci    BIND(&is_smi);
6651cb0ef41Sopenharmony_ci    {
6661cb0ef41Sopenharmony_ci      TNode<IntPtrT> intptr_start_from = SmiUntag(CAST(start_from));
6671cb0ef41Sopenharmony_ci      index_var = intptr_start_from;
6681cb0ef41Sopenharmony_ci
6691cb0ef41Sopenharmony_ci      GotoIf(IntPtrGreaterThanOrEqual(index_var.value(), intptr_zero), &done);
6701cb0ef41Sopenharmony_ci      // The fromIndex is negative: add it to the array's length.
6711cb0ef41Sopenharmony_ci      index_var = IntPtrAdd(array_length_untagged, index_var.value());
6721cb0ef41Sopenharmony_ci      // Clamp negative results at zero.
6731cb0ef41Sopenharmony_ci      GotoIf(IntPtrGreaterThanOrEqual(index_var.value(), intptr_zero), &done);
6741cb0ef41Sopenharmony_ci      index_var = intptr_zero;
6751cb0ef41Sopenharmony_ci      Goto(&done);
6761cb0ef41Sopenharmony_ci    }
6771cb0ef41Sopenharmony_ci    BIND(&done);
6781cb0ef41Sopenharmony_ci  }
6791cb0ef41Sopenharmony_ci
6801cb0ef41Sopenharmony_ci  // Fail early if startIndex >= array.length.
6811cb0ef41Sopenharmony_ci  GotoIf(IntPtrGreaterThanOrEqual(index_var.value(), array_length_untagged),
6821cb0ef41Sopenharmony_ci         &return_not_found);
6831cb0ef41Sopenharmony_ci
6841cb0ef41Sopenharmony_ci  Label if_smiorobjects(this), if_packed_doubles(this), if_holey_doubles(this);
6851cb0ef41Sopenharmony_ci
6861cb0ef41Sopenharmony_ci  TNode<Int32T> elements_kind = LoadElementsKind(array);
6871cb0ef41Sopenharmony_ci  TNode<FixedArrayBase> elements = LoadElements(array);
6881cb0ef41Sopenharmony_ci  STATIC_ASSERT(PACKED_SMI_ELEMENTS == 0);
6891cb0ef41Sopenharmony_ci  STATIC_ASSERT(HOLEY_SMI_ELEMENTS == 1);
6901cb0ef41Sopenharmony_ci  STATIC_ASSERT(PACKED_ELEMENTS == 2);
6911cb0ef41Sopenharmony_ci  STATIC_ASSERT(HOLEY_ELEMENTS == 3);
6921cb0ef41Sopenharmony_ci  GotoIf(IsElementsKindLessThanOrEqual(elements_kind, HOLEY_ELEMENTS),
6931cb0ef41Sopenharmony_ci         &if_smiorobjects);
6941cb0ef41Sopenharmony_ci  GotoIf(
6951cb0ef41Sopenharmony_ci      ElementsKindEqual(elements_kind, Int32Constant(PACKED_DOUBLE_ELEMENTS)),
6961cb0ef41Sopenharmony_ci      &if_packed_doubles);
6971cb0ef41Sopenharmony_ci  GotoIf(ElementsKindEqual(elements_kind, Int32Constant(HOLEY_DOUBLE_ELEMENTS)),
6981cb0ef41Sopenharmony_ci         &if_holey_doubles);
6991cb0ef41Sopenharmony_ci  GotoIf(IsElementsKindLessThanOrEqual(elements_kind,
7001cb0ef41Sopenharmony_ci                                       LAST_ANY_NONEXTENSIBLE_ELEMENTS_KIND),
7011cb0ef41Sopenharmony_ci         &if_smiorobjects);
7021cb0ef41Sopenharmony_ci  Goto(&return_not_found);
7031cb0ef41Sopenharmony_ci
7041cb0ef41Sopenharmony_ci  BIND(&if_smiorobjects);
7051cb0ef41Sopenharmony_ci  {
7061cb0ef41Sopenharmony_ci    Callable callable = (variant == kIncludes)
7071cb0ef41Sopenharmony_ci                            ? Builtins::CallableFor(
7081cb0ef41Sopenharmony_ci                                  isolate(), Builtin::kArrayIncludesSmiOrObject)
7091cb0ef41Sopenharmony_ci                            : Builtins::CallableFor(
7101cb0ef41Sopenharmony_ci                                  isolate(), Builtin::kArrayIndexOfSmiOrObject);
7111cb0ef41Sopenharmony_ci    TNode<Object> result = CallStub(callable, context, elements, search_element,
7121cb0ef41Sopenharmony_ci                                    array_length, SmiTag(index_var.value()));
7131cb0ef41Sopenharmony_ci    args.PopAndReturn(result);
7141cb0ef41Sopenharmony_ci  }
7151cb0ef41Sopenharmony_ci
7161cb0ef41Sopenharmony_ci  BIND(&if_packed_doubles);
7171cb0ef41Sopenharmony_ci  {
7181cb0ef41Sopenharmony_ci    Callable callable =
7191cb0ef41Sopenharmony_ci        (variant == kIncludes)
7201cb0ef41Sopenharmony_ci            ? Builtins::CallableFor(isolate(),
7211cb0ef41Sopenharmony_ci                                    Builtin::kArrayIncludesPackedDoubles)
7221cb0ef41Sopenharmony_ci            : Builtins::CallableFor(isolate(),
7231cb0ef41Sopenharmony_ci                                    Builtin::kArrayIndexOfPackedDoubles);
7241cb0ef41Sopenharmony_ci    TNode<Object> result = CallStub(callable, context, elements, search_element,
7251cb0ef41Sopenharmony_ci                                    array_length, SmiTag(index_var.value()));
7261cb0ef41Sopenharmony_ci    args.PopAndReturn(result);
7271cb0ef41Sopenharmony_ci  }
7281cb0ef41Sopenharmony_ci
7291cb0ef41Sopenharmony_ci  BIND(&if_holey_doubles);
7301cb0ef41Sopenharmony_ci  {
7311cb0ef41Sopenharmony_ci    Callable callable =
7321cb0ef41Sopenharmony_ci        (variant == kIncludes)
7331cb0ef41Sopenharmony_ci            ? Builtins::CallableFor(isolate(),
7341cb0ef41Sopenharmony_ci                                    Builtin::kArrayIncludesHoleyDoubles)
7351cb0ef41Sopenharmony_ci            : Builtins::CallableFor(isolate(),
7361cb0ef41Sopenharmony_ci                                    Builtin::kArrayIndexOfHoleyDoubles);
7371cb0ef41Sopenharmony_ci    TNode<Object> result = CallStub(callable, context, elements, search_element,
7381cb0ef41Sopenharmony_ci                                    array_length, SmiTag(index_var.value()));
7391cb0ef41Sopenharmony_ci    args.PopAndReturn(result);
7401cb0ef41Sopenharmony_ci  }
7411cb0ef41Sopenharmony_ci
7421cb0ef41Sopenharmony_ci  BIND(&return_not_found);
7431cb0ef41Sopenharmony_ci  if (variant == kIncludes) {
7441cb0ef41Sopenharmony_ci    args.PopAndReturn(FalseConstant());
7451cb0ef41Sopenharmony_ci  } else {
7461cb0ef41Sopenharmony_ci    args.PopAndReturn(NumberConstant(-1));
7471cb0ef41Sopenharmony_ci  }
7481cb0ef41Sopenharmony_ci
7491cb0ef41Sopenharmony_ci  BIND(&call_runtime);
7501cb0ef41Sopenharmony_ci  {
7511cb0ef41Sopenharmony_ci    TNode<Object> start_from = args.GetOptionalArgumentValue(kFromIndexArg);
7521cb0ef41Sopenharmony_ci    Runtime::FunctionId function = variant == kIncludes
7531cb0ef41Sopenharmony_ci                                       ? Runtime::kArrayIncludes_Slow
7541cb0ef41Sopenharmony_ci                                       : Runtime::kArrayIndexOf;
7551cb0ef41Sopenharmony_ci    args.PopAndReturn(
7561cb0ef41Sopenharmony_ci        CallRuntime(function, context, array, search_element, start_from));
7571cb0ef41Sopenharmony_ci  }
7581cb0ef41Sopenharmony_ci}
7591cb0ef41Sopenharmony_ci
7601cb0ef41Sopenharmony_civoid ArrayIncludesIndexofAssembler::GenerateSmiOrObject(
7611cb0ef41Sopenharmony_ci    SearchVariant variant, TNode<Context> context, TNode<FixedArray> elements,
7621cb0ef41Sopenharmony_ci    TNode<Object> search_element, TNode<Smi> array_length,
7631cb0ef41Sopenharmony_ci    TNode<Smi> from_index) {
7641cb0ef41Sopenharmony_ci  TVARIABLE(IntPtrT, index_var, SmiUntag(from_index));
7651cb0ef41Sopenharmony_ci  TVARIABLE(Float64T, search_num);
7661cb0ef41Sopenharmony_ci  TNode<IntPtrT> array_length_untagged = SmiUntag(array_length);
7671cb0ef41Sopenharmony_ci
7681cb0ef41Sopenharmony_ci  Label ident_loop(this, &index_var), heap_num_loop(this, &search_num),
7691cb0ef41Sopenharmony_ci      string_loop(this), bigint_loop(this, &index_var),
7701cb0ef41Sopenharmony_ci      undef_loop(this, &index_var), not_smi(this), not_heap_num(this),
7711cb0ef41Sopenharmony_ci      return_found(this), return_not_found(this);
7721cb0ef41Sopenharmony_ci
7731cb0ef41Sopenharmony_ci  GotoIfNot(TaggedIsSmi(search_element), &not_smi);
7741cb0ef41Sopenharmony_ci  search_num = SmiToFloat64(CAST(search_element));
7751cb0ef41Sopenharmony_ci  Goto(&heap_num_loop);
7761cb0ef41Sopenharmony_ci
7771cb0ef41Sopenharmony_ci  BIND(&not_smi);
7781cb0ef41Sopenharmony_ci  if (variant == kIncludes) {
7791cb0ef41Sopenharmony_ci    GotoIf(IsUndefined(search_element), &undef_loop);
7801cb0ef41Sopenharmony_ci  }
7811cb0ef41Sopenharmony_ci  TNode<Map> map = LoadMap(CAST(search_element));
7821cb0ef41Sopenharmony_ci  GotoIfNot(IsHeapNumberMap(map), &not_heap_num);
7831cb0ef41Sopenharmony_ci  search_num = LoadHeapNumberValue(CAST(search_element));
7841cb0ef41Sopenharmony_ci  Goto(&heap_num_loop);
7851cb0ef41Sopenharmony_ci
7861cb0ef41Sopenharmony_ci  BIND(&not_heap_num);
7871cb0ef41Sopenharmony_ci  TNode<Uint16T> search_type = LoadMapInstanceType(map);
7881cb0ef41Sopenharmony_ci  GotoIf(IsStringInstanceType(search_type), &string_loop);
7891cb0ef41Sopenharmony_ci  GotoIf(IsBigIntInstanceType(search_type), &bigint_loop);
7901cb0ef41Sopenharmony_ci  Goto(&ident_loop);
7911cb0ef41Sopenharmony_ci
7921cb0ef41Sopenharmony_ci  BIND(&ident_loop);
7931cb0ef41Sopenharmony_ci  {
7941cb0ef41Sopenharmony_ci    GotoIfNot(UintPtrLessThan(index_var.value(), array_length_untagged),
7951cb0ef41Sopenharmony_ci              &return_not_found);
7961cb0ef41Sopenharmony_ci    TNode<Object> element_k =
7971cb0ef41Sopenharmony_ci        UnsafeLoadFixedArrayElement(elements, index_var.value());
7981cb0ef41Sopenharmony_ci    GotoIf(TaggedEqual(element_k, search_element), &return_found);
7991cb0ef41Sopenharmony_ci
8001cb0ef41Sopenharmony_ci    Increment(&index_var);
8011cb0ef41Sopenharmony_ci    Goto(&ident_loop);
8021cb0ef41Sopenharmony_ci  }
8031cb0ef41Sopenharmony_ci
8041cb0ef41Sopenharmony_ci  if (variant == kIncludes) {
8051cb0ef41Sopenharmony_ci    BIND(&undef_loop);
8061cb0ef41Sopenharmony_ci
8071cb0ef41Sopenharmony_ci    GotoIfNot(UintPtrLessThan(index_var.value(), array_length_untagged),
8081cb0ef41Sopenharmony_ci              &return_not_found);
8091cb0ef41Sopenharmony_ci    TNode<Object> element_k =
8101cb0ef41Sopenharmony_ci        UnsafeLoadFixedArrayElement(elements, index_var.value());
8111cb0ef41Sopenharmony_ci    GotoIf(IsUndefined(element_k), &return_found);
8121cb0ef41Sopenharmony_ci    GotoIf(IsTheHole(element_k), &return_found);
8131cb0ef41Sopenharmony_ci
8141cb0ef41Sopenharmony_ci    Increment(&index_var);
8151cb0ef41Sopenharmony_ci    Goto(&undef_loop);
8161cb0ef41Sopenharmony_ci  }
8171cb0ef41Sopenharmony_ci
8181cb0ef41Sopenharmony_ci  BIND(&heap_num_loop);
8191cb0ef41Sopenharmony_ci  {
8201cb0ef41Sopenharmony_ci    Label nan_loop(this, &index_var), not_nan_loop(this, &index_var);
8211cb0ef41Sopenharmony_ci    Label* nan_handling = variant == kIncludes ? &nan_loop : &return_not_found;
8221cb0ef41Sopenharmony_ci    BranchIfFloat64IsNaN(search_num.value(), nan_handling, &not_nan_loop);
8231cb0ef41Sopenharmony_ci
8241cb0ef41Sopenharmony_ci    BIND(&not_nan_loop);
8251cb0ef41Sopenharmony_ci    {
8261cb0ef41Sopenharmony_ci      Label continue_loop(this), element_k_not_smi(this);
8271cb0ef41Sopenharmony_ci      GotoIfNot(UintPtrLessThan(index_var.value(), array_length_untagged),
8281cb0ef41Sopenharmony_ci                &return_not_found);
8291cb0ef41Sopenharmony_ci      TNode<Object> element_k =
8301cb0ef41Sopenharmony_ci          UnsafeLoadFixedArrayElement(elements, index_var.value());
8311cb0ef41Sopenharmony_ci      GotoIfNot(TaggedIsSmi(element_k), &element_k_not_smi);
8321cb0ef41Sopenharmony_ci      Branch(Float64Equal(search_num.value(), SmiToFloat64(CAST(element_k))),
8331cb0ef41Sopenharmony_ci             &return_found, &continue_loop);
8341cb0ef41Sopenharmony_ci
8351cb0ef41Sopenharmony_ci      BIND(&element_k_not_smi);
8361cb0ef41Sopenharmony_ci      GotoIfNot(IsHeapNumber(CAST(element_k)), &continue_loop);
8371cb0ef41Sopenharmony_ci      Branch(Float64Equal(search_num.value(),
8381cb0ef41Sopenharmony_ci                          LoadHeapNumberValue(CAST(element_k))),
8391cb0ef41Sopenharmony_ci             &return_found, &continue_loop);
8401cb0ef41Sopenharmony_ci
8411cb0ef41Sopenharmony_ci      BIND(&continue_loop);
8421cb0ef41Sopenharmony_ci      Increment(&index_var);
8431cb0ef41Sopenharmony_ci      Goto(&not_nan_loop);
8441cb0ef41Sopenharmony_ci    }
8451cb0ef41Sopenharmony_ci
8461cb0ef41Sopenharmony_ci    // Array.p.includes uses SameValueZero comparisons, where NaN == NaN.
8471cb0ef41Sopenharmony_ci    if (variant == kIncludes) {
8481cb0ef41Sopenharmony_ci      BIND(&nan_loop);
8491cb0ef41Sopenharmony_ci      Label continue_loop(this);
8501cb0ef41Sopenharmony_ci      GotoIfNot(UintPtrLessThan(index_var.value(), array_length_untagged),
8511cb0ef41Sopenharmony_ci                &return_not_found);
8521cb0ef41Sopenharmony_ci      TNode<Object> element_k =
8531cb0ef41Sopenharmony_ci          UnsafeLoadFixedArrayElement(elements, index_var.value());
8541cb0ef41Sopenharmony_ci      GotoIf(TaggedIsSmi(element_k), &continue_loop);
8551cb0ef41Sopenharmony_ci      GotoIfNot(IsHeapNumber(CAST(element_k)), &continue_loop);
8561cb0ef41Sopenharmony_ci      BranchIfFloat64IsNaN(LoadHeapNumberValue(CAST(element_k)), &return_found,
8571cb0ef41Sopenharmony_ci                           &continue_loop);
8581cb0ef41Sopenharmony_ci
8591cb0ef41Sopenharmony_ci      BIND(&continue_loop);
8601cb0ef41Sopenharmony_ci      Increment(&index_var);
8611cb0ef41Sopenharmony_ci      Goto(&nan_loop);
8621cb0ef41Sopenharmony_ci    }
8631cb0ef41Sopenharmony_ci  }
8641cb0ef41Sopenharmony_ci
8651cb0ef41Sopenharmony_ci  BIND(&string_loop);
8661cb0ef41Sopenharmony_ci  {
8671cb0ef41Sopenharmony_ci    TNode<String> search_element_string = CAST(search_element);
8681cb0ef41Sopenharmony_ci    Label continue_loop(this), next_iteration(this, &index_var),
8691cb0ef41Sopenharmony_ci        slow_compare(this), runtime(this, Label::kDeferred);
8701cb0ef41Sopenharmony_ci    TNode<IntPtrT> search_length =
8711cb0ef41Sopenharmony_ci        LoadStringLengthAsWord(search_element_string);
8721cb0ef41Sopenharmony_ci    Goto(&next_iteration);
8731cb0ef41Sopenharmony_ci    BIND(&next_iteration);
8741cb0ef41Sopenharmony_ci    GotoIfNot(UintPtrLessThan(index_var.value(), array_length_untagged),
8751cb0ef41Sopenharmony_ci              &return_not_found);
8761cb0ef41Sopenharmony_ci    TNode<Object> element_k =
8771cb0ef41Sopenharmony_ci        UnsafeLoadFixedArrayElement(elements, index_var.value());
8781cb0ef41Sopenharmony_ci    GotoIf(TaggedIsSmi(element_k), &continue_loop);
8791cb0ef41Sopenharmony_ci    GotoIf(TaggedEqual(search_element_string, element_k), &return_found);
8801cb0ef41Sopenharmony_ci    TNode<Uint16T> element_k_type = LoadInstanceType(CAST(element_k));
8811cb0ef41Sopenharmony_ci    GotoIfNot(IsStringInstanceType(element_k_type), &continue_loop);
8821cb0ef41Sopenharmony_ci    Branch(IntPtrEqual(search_length, LoadStringLengthAsWord(CAST(element_k))),
8831cb0ef41Sopenharmony_ci           &slow_compare, &continue_loop);
8841cb0ef41Sopenharmony_ci
8851cb0ef41Sopenharmony_ci    BIND(&slow_compare);
8861cb0ef41Sopenharmony_ci    StringBuiltinsAssembler string_asm(state());
8871cb0ef41Sopenharmony_ci    string_asm.StringEqual_Core(search_element_string, search_type,
8881cb0ef41Sopenharmony_ci                                CAST(element_k), element_k_type, search_length,
8891cb0ef41Sopenharmony_ci                                &return_found, &continue_loop, &runtime);
8901cb0ef41Sopenharmony_ci    BIND(&runtime);
8911cb0ef41Sopenharmony_ci    TNode<Object> result = CallRuntime(Runtime::kStringEqual, context,
8921cb0ef41Sopenharmony_ci                                       search_element_string, element_k);
8931cb0ef41Sopenharmony_ci    Branch(TaggedEqual(result, TrueConstant()), &return_found, &continue_loop);
8941cb0ef41Sopenharmony_ci
8951cb0ef41Sopenharmony_ci    BIND(&continue_loop);
8961cb0ef41Sopenharmony_ci    Increment(&index_var);
8971cb0ef41Sopenharmony_ci    Goto(&next_iteration);
8981cb0ef41Sopenharmony_ci  }
8991cb0ef41Sopenharmony_ci
9001cb0ef41Sopenharmony_ci  BIND(&bigint_loop);
9011cb0ef41Sopenharmony_ci  {
9021cb0ef41Sopenharmony_ci    GotoIfNot(UintPtrLessThan(index_var.value(), array_length_untagged),
9031cb0ef41Sopenharmony_ci              &return_not_found);
9041cb0ef41Sopenharmony_ci
9051cb0ef41Sopenharmony_ci    TNode<Object> element_k =
9061cb0ef41Sopenharmony_ci        UnsafeLoadFixedArrayElement(elements, index_var.value());
9071cb0ef41Sopenharmony_ci    Label continue_loop(this);
9081cb0ef41Sopenharmony_ci    GotoIf(TaggedIsSmi(element_k), &continue_loop);
9091cb0ef41Sopenharmony_ci    GotoIfNot(IsBigInt(CAST(element_k)), &continue_loop);
9101cb0ef41Sopenharmony_ci    TNode<Object> result = CallRuntime(Runtime::kBigIntEqualToBigInt, context,
9111cb0ef41Sopenharmony_ci                                       search_element, element_k);
9121cb0ef41Sopenharmony_ci    Branch(TaggedEqual(result, TrueConstant()), &return_found, &continue_loop);
9131cb0ef41Sopenharmony_ci
9141cb0ef41Sopenharmony_ci    BIND(&continue_loop);
9151cb0ef41Sopenharmony_ci    Increment(&index_var);
9161cb0ef41Sopenharmony_ci    Goto(&bigint_loop);
9171cb0ef41Sopenharmony_ci  }
9181cb0ef41Sopenharmony_ci  BIND(&return_found);
9191cb0ef41Sopenharmony_ci  if (variant == kIncludes) {
9201cb0ef41Sopenharmony_ci    Return(TrueConstant());
9211cb0ef41Sopenharmony_ci  } else {
9221cb0ef41Sopenharmony_ci    Return(SmiTag(index_var.value()));
9231cb0ef41Sopenharmony_ci  }
9241cb0ef41Sopenharmony_ci
9251cb0ef41Sopenharmony_ci  BIND(&return_not_found);
9261cb0ef41Sopenharmony_ci  if (variant == kIncludes) {
9271cb0ef41Sopenharmony_ci    Return(FalseConstant());
9281cb0ef41Sopenharmony_ci  } else {
9291cb0ef41Sopenharmony_ci    Return(NumberConstant(-1));
9301cb0ef41Sopenharmony_ci  }
9311cb0ef41Sopenharmony_ci}
9321cb0ef41Sopenharmony_ci
9331cb0ef41Sopenharmony_civoid ArrayIncludesIndexofAssembler::GeneratePackedDoubles(
9341cb0ef41Sopenharmony_ci    SearchVariant variant, TNode<FixedDoubleArray> elements,
9351cb0ef41Sopenharmony_ci    TNode<Object> search_element, TNode<Smi> array_length,
9361cb0ef41Sopenharmony_ci    TNode<Smi> from_index) {
9371cb0ef41Sopenharmony_ci  TVARIABLE(IntPtrT, index_var, SmiUntag(from_index));
9381cb0ef41Sopenharmony_ci  TNode<IntPtrT> array_length_untagged = SmiUntag(array_length);
9391cb0ef41Sopenharmony_ci
9401cb0ef41Sopenharmony_ci  Label nan_loop(this, &index_var), not_nan_loop(this, &index_var),
9411cb0ef41Sopenharmony_ci      hole_loop(this, &index_var), search_notnan(this), return_found(this),
9421cb0ef41Sopenharmony_ci      return_not_found(this);
9431cb0ef41Sopenharmony_ci  TVARIABLE(Float64T, search_num);
9441cb0ef41Sopenharmony_ci  search_num = Float64Constant(0);
9451cb0ef41Sopenharmony_ci
9461cb0ef41Sopenharmony_ci  GotoIfNot(TaggedIsSmi(search_element), &search_notnan);
9471cb0ef41Sopenharmony_ci  search_num = SmiToFloat64(CAST(search_element));
9481cb0ef41Sopenharmony_ci  Goto(&not_nan_loop);
9491cb0ef41Sopenharmony_ci
9501cb0ef41Sopenharmony_ci  BIND(&search_notnan);
9511cb0ef41Sopenharmony_ci  GotoIfNot(IsHeapNumber(CAST(search_element)), &return_not_found);
9521cb0ef41Sopenharmony_ci
9531cb0ef41Sopenharmony_ci  search_num = LoadHeapNumberValue(CAST(search_element));
9541cb0ef41Sopenharmony_ci
9551cb0ef41Sopenharmony_ci  Label* nan_handling = variant == kIncludes ? &nan_loop : &return_not_found;
9561cb0ef41Sopenharmony_ci  BranchIfFloat64IsNaN(search_num.value(), nan_handling, &not_nan_loop);
9571cb0ef41Sopenharmony_ci
9581cb0ef41Sopenharmony_ci  BIND(&not_nan_loop);
9591cb0ef41Sopenharmony_ci  {
9601cb0ef41Sopenharmony_ci    Label continue_loop(this);
9611cb0ef41Sopenharmony_ci    GotoIfNot(UintPtrLessThan(index_var.value(), array_length_untagged),
9621cb0ef41Sopenharmony_ci              &return_not_found);
9631cb0ef41Sopenharmony_ci    TNode<Float64T> element_k =
9641cb0ef41Sopenharmony_ci        LoadFixedDoubleArrayElement(elements, index_var.value());
9651cb0ef41Sopenharmony_ci    Branch(Float64Equal(element_k, search_num.value()), &return_found,
9661cb0ef41Sopenharmony_ci           &continue_loop);
9671cb0ef41Sopenharmony_ci    BIND(&continue_loop);
9681cb0ef41Sopenharmony_ci    Increment(&index_var);
9691cb0ef41Sopenharmony_ci    Goto(&not_nan_loop);
9701cb0ef41Sopenharmony_ci  }
9711cb0ef41Sopenharmony_ci
9721cb0ef41Sopenharmony_ci  // Array.p.includes uses SameValueZero comparisons, where NaN == NaN.
9731cb0ef41Sopenharmony_ci  if (variant == kIncludes) {
9741cb0ef41Sopenharmony_ci    BIND(&nan_loop);
9751cb0ef41Sopenharmony_ci    Label continue_loop(this);
9761cb0ef41Sopenharmony_ci    GotoIfNot(UintPtrLessThan(index_var.value(), array_length_untagged),
9771cb0ef41Sopenharmony_ci              &return_not_found);
9781cb0ef41Sopenharmony_ci    TNode<Float64T> element_k =
9791cb0ef41Sopenharmony_ci        LoadFixedDoubleArrayElement(elements, index_var.value());
9801cb0ef41Sopenharmony_ci    BranchIfFloat64IsNaN(element_k, &return_found, &continue_loop);
9811cb0ef41Sopenharmony_ci    BIND(&continue_loop);
9821cb0ef41Sopenharmony_ci    Increment(&index_var);
9831cb0ef41Sopenharmony_ci    Goto(&nan_loop);
9841cb0ef41Sopenharmony_ci  }
9851cb0ef41Sopenharmony_ci
9861cb0ef41Sopenharmony_ci  BIND(&return_found);
9871cb0ef41Sopenharmony_ci  if (variant == kIncludes) {
9881cb0ef41Sopenharmony_ci    Return(TrueConstant());
9891cb0ef41Sopenharmony_ci  } else {
9901cb0ef41Sopenharmony_ci    Return(SmiTag(index_var.value()));
9911cb0ef41Sopenharmony_ci  }
9921cb0ef41Sopenharmony_ci
9931cb0ef41Sopenharmony_ci  BIND(&return_not_found);
9941cb0ef41Sopenharmony_ci  if (variant == kIncludes) {
9951cb0ef41Sopenharmony_ci    Return(FalseConstant());
9961cb0ef41Sopenharmony_ci  } else {
9971cb0ef41Sopenharmony_ci    Return(NumberConstant(-1));
9981cb0ef41Sopenharmony_ci  }
9991cb0ef41Sopenharmony_ci}
10001cb0ef41Sopenharmony_ci
10011cb0ef41Sopenharmony_civoid ArrayIncludesIndexofAssembler::GenerateHoleyDoubles(
10021cb0ef41Sopenharmony_ci    SearchVariant variant, TNode<FixedDoubleArray> elements,
10031cb0ef41Sopenharmony_ci    TNode<Object> search_element, TNode<Smi> array_length,
10041cb0ef41Sopenharmony_ci    TNode<Smi> from_index) {
10051cb0ef41Sopenharmony_ci  TVARIABLE(IntPtrT, index_var, SmiUntag(from_index));
10061cb0ef41Sopenharmony_ci  TNode<IntPtrT> array_length_untagged = SmiUntag(array_length);
10071cb0ef41Sopenharmony_ci
10081cb0ef41Sopenharmony_ci  Label nan_loop(this, &index_var), not_nan_loop(this, &index_var),
10091cb0ef41Sopenharmony_ci      hole_loop(this, &index_var), search_notnan(this), return_found(this),
10101cb0ef41Sopenharmony_ci      return_not_found(this);
10111cb0ef41Sopenharmony_ci  TVARIABLE(Float64T, search_num);
10121cb0ef41Sopenharmony_ci  search_num = Float64Constant(0);
10131cb0ef41Sopenharmony_ci
10141cb0ef41Sopenharmony_ci  GotoIfNot(TaggedIsSmi(search_element), &search_notnan);
10151cb0ef41Sopenharmony_ci  search_num = SmiToFloat64(CAST(search_element));
10161cb0ef41Sopenharmony_ci  Goto(&not_nan_loop);
10171cb0ef41Sopenharmony_ci
10181cb0ef41Sopenharmony_ci  BIND(&search_notnan);
10191cb0ef41Sopenharmony_ci  if (variant == kIncludes) {
10201cb0ef41Sopenharmony_ci    GotoIf(IsUndefined(search_element), &hole_loop);
10211cb0ef41Sopenharmony_ci  }
10221cb0ef41Sopenharmony_ci  GotoIfNot(IsHeapNumber(CAST(search_element)), &return_not_found);
10231cb0ef41Sopenharmony_ci
10241cb0ef41Sopenharmony_ci  search_num = LoadHeapNumberValue(CAST(search_element));
10251cb0ef41Sopenharmony_ci
10261cb0ef41Sopenharmony_ci  Label* nan_handling = variant == kIncludes ? &nan_loop : &return_not_found;
10271cb0ef41Sopenharmony_ci  BranchIfFloat64IsNaN(search_num.value(), nan_handling, &not_nan_loop);
10281cb0ef41Sopenharmony_ci
10291cb0ef41Sopenharmony_ci  BIND(&not_nan_loop);
10301cb0ef41Sopenharmony_ci  {
10311cb0ef41Sopenharmony_ci    Label continue_loop(this);
10321cb0ef41Sopenharmony_ci    GotoIfNot(UintPtrLessThan(index_var.value(), array_length_untagged),
10331cb0ef41Sopenharmony_ci              &return_not_found);
10341cb0ef41Sopenharmony_ci
10351cb0ef41Sopenharmony_ci    // No need for hole checking here; the following Float64Equal will
10361cb0ef41Sopenharmony_ci    // return 'not equal' for holes anyway.
10371cb0ef41Sopenharmony_ci    TNode<Float64T> element_k =
10381cb0ef41Sopenharmony_ci        LoadFixedDoubleArrayElement(elements, index_var.value());
10391cb0ef41Sopenharmony_ci
10401cb0ef41Sopenharmony_ci    Branch(Float64Equal(element_k, search_num.value()), &return_found,
10411cb0ef41Sopenharmony_ci           &continue_loop);
10421cb0ef41Sopenharmony_ci    BIND(&continue_loop);
10431cb0ef41Sopenharmony_ci    Increment(&index_var);
10441cb0ef41Sopenharmony_ci    Goto(&not_nan_loop);
10451cb0ef41Sopenharmony_ci  }
10461cb0ef41Sopenharmony_ci
10471cb0ef41Sopenharmony_ci  // Array.p.includes uses SameValueZero comparisons, where NaN == NaN.
10481cb0ef41Sopenharmony_ci  if (variant == kIncludes) {
10491cb0ef41Sopenharmony_ci    BIND(&nan_loop);
10501cb0ef41Sopenharmony_ci    Label continue_loop(this);
10511cb0ef41Sopenharmony_ci    GotoIfNot(UintPtrLessThan(index_var.value(), array_length_untagged),
10521cb0ef41Sopenharmony_ci              &return_not_found);
10531cb0ef41Sopenharmony_ci
10541cb0ef41Sopenharmony_ci    // Load double value or continue if it's the hole NaN.
10551cb0ef41Sopenharmony_ci    TNode<Float64T> element_k = LoadFixedDoubleArrayElement(
10561cb0ef41Sopenharmony_ci        elements, index_var.value(), &continue_loop);
10571cb0ef41Sopenharmony_ci
10581cb0ef41Sopenharmony_ci    BranchIfFloat64IsNaN(element_k, &return_found, &continue_loop);
10591cb0ef41Sopenharmony_ci    BIND(&continue_loop);
10601cb0ef41Sopenharmony_ci    Increment(&index_var);
10611cb0ef41Sopenharmony_ci    Goto(&nan_loop);
10621cb0ef41Sopenharmony_ci  }
10631cb0ef41Sopenharmony_ci
10641cb0ef41Sopenharmony_ci  // Array.p.includes treats the hole as undefined.
10651cb0ef41Sopenharmony_ci  if (variant == kIncludes) {
10661cb0ef41Sopenharmony_ci    BIND(&hole_loop);
10671cb0ef41Sopenharmony_ci    GotoIfNot(UintPtrLessThan(index_var.value(), array_length_untagged),
10681cb0ef41Sopenharmony_ci              &return_not_found);
10691cb0ef41Sopenharmony_ci
10701cb0ef41Sopenharmony_ci    // Check if the element is a double hole, but don't load it.
10711cb0ef41Sopenharmony_ci    LoadFixedDoubleArrayElement(elements, index_var.value(), &return_found,
10721cb0ef41Sopenharmony_ci                                MachineType::None());
10731cb0ef41Sopenharmony_ci
10741cb0ef41Sopenharmony_ci    Increment(&index_var);
10751cb0ef41Sopenharmony_ci    Goto(&hole_loop);
10761cb0ef41Sopenharmony_ci  }
10771cb0ef41Sopenharmony_ci
10781cb0ef41Sopenharmony_ci  BIND(&return_found);
10791cb0ef41Sopenharmony_ci  if (variant == kIncludes) {
10801cb0ef41Sopenharmony_ci    Return(TrueConstant());
10811cb0ef41Sopenharmony_ci  } else {
10821cb0ef41Sopenharmony_ci    Return(SmiTag(index_var.value()));
10831cb0ef41Sopenharmony_ci  }
10841cb0ef41Sopenharmony_ci
10851cb0ef41Sopenharmony_ci  BIND(&return_not_found);
10861cb0ef41Sopenharmony_ci  if (variant == kIncludes) {
10871cb0ef41Sopenharmony_ci    Return(FalseConstant());
10881cb0ef41Sopenharmony_ci  } else {
10891cb0ef41Sopenharmony_ci    Return(NumberConstant(-1));
10901cb0ef41Sopenharmony_ci  }
10911cb0ef41Sopenharmony_ci}
10921cb0ef41Sopenharmony_ci
10931cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayIncludes, ArrayIncludesIndexofAssembler) {
10941cb0ef41Sopenharmony_ci  TNode<IntPtrT> argc = ChangeInt32ToIntPtr(
10951cb0ef41Sopenharmony_ci      UncheckedParameter<Int32T>(Descriptor::kJSActualArgumentsCount));
10961cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
10971cb0ef41Sopenharmony_ci
10981cb0ef41Sopenharmony_ci  Generate(kIncludes, argc, context);
10991cb0ef41Sopenharmony_ci}
11001cb0ef41Sopenharmony_ci
11011cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayIncludesSmiOrObject, ArrayIncludesIndexofAssembler) {
11021cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
11031cb0ef41Sopenharmony_ci  auto elements = Parameter<FixedArray>(Descriptor::kElements);
11041cb0ef41Sopenharmony_ci  auto search_element = Parameter<Object>(Descriptor::kSearchElement);
11051cb0ef41Sopenharmony_ci  auto array_length = Parameter<Smi>(Descriptor::kLength);
11061cb0ef41Sopenharmony_ci  auto from_index = Parameter<Smi>(Descriptor::kFromIndex);
11071cb0ef41Sopenharmony_ci
11081cb0ef41Sopenharmony_ci  GenerateSmiOrObject(kIncludes, context, elements, search_element,
11091cb0ef41Sopenharmony_ci                      array_length, from_index);
11101cb0ef41Sopenharmony_ci}
11111cb0ef41Sopenharmony_ci
11121cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayIncludesPackedDoubles, ArrayIncludesIndexofAssembler) {
11131cb0ef41Sopenharmony_ci  auto elements = Parameter<FixedArrayBase>(Descriptor::kElements);
11141cb0ef41Sopenharmony_ci  auto search_element = Parameter<Object>(Descriptor::kSearchElement);
11151cb0ef41Sopenharmony_ci  auto array_length = Parameter<Smi>(Descriptor::kLength);
11161cb0ef41Sopenharmony_ci  auto from_index = Parameter<Smi>(Descriptor::kFromIndex);
11171cb0ef41Sopenharmony_ci
11181cb0ef41Sopenharmony_ci  ReturnIfEmpty(array_length, FalseConstant());
11191cb0ef41Sopenharmony_ci  GeneratePackedDoubles(kIncludes, CAST(elements), search_element, array_length,
11201cb0ef41Sopenharmony_ci                        from_index);
11211cb0ef41Sopenharmony_ci}
11221cb0ef41Sopenharmony_ci
11231cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayIncludesHoleyDoubles, ArrayIncludesIndexofAssembler) {
11241cb0ef41Sopenharmony_ci  auto elements = Parameter<FixedArrayBase>(Descriptor::kElements);
11251cb0ef41Sopenharmony_ci  auto search_element = Parameter<Object>(Descriptor::kSearchElement);
11261cb0ef41Sopenharmony_ci  auto array_length = Parameter<Smi>(Descriptor::kLength);
11271cb0ef41Sopenharmony_ci  auto from_index = Parameter<Smi>(Descriptor::kFromIndex);
11281cb0ef41Sopenharmony_ci
11291cb0ef41Sopenharmony_ci  ReturnIfEmpty(array_length, FalseConstant());
11301cb0ef41Sopenharmony_ci  GenerateHoleyDoubles(kIncludes, CAST(elements), search_element, array_length,
11311cb0ef41Sopenharmony_ci                       from_index);
11321cb0ef41Sopenharmony_ci}
11331cb0ef41Sopenharmony_ci
11341cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayIndexOf, ArrayIncludesIndexofAssembler) {
11351cb0ef41Sopenharmony_ci  TNode<IntPtrT> argc = ChangeInt32ToIntPtr(
11361cb0ef41Sopenharmony_ci      UncheckedParameter<Int32T>(Descriptor::kJSActualArgumentsCount));
11371cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
11381cb0ef41Sopenharmony_ci
11391cb0ef41Sopenharmony_ci  Generate(kIndexOf, argc, context);
11401cb0ef41Sopenharmony_ci}
11411cb0ef41Sopenharmony_ci
11421cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayIndexOfSmiOrObject, ArrayIncludesIndexofAssembler) {
11431cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
11441cb0ef41Sopenharmony_ci  auto elements = Parameter<FixedArray>(Descriptor::kElements);
11451cb0ef41Sopenharmony_ci  auto search_element = Parameter<Object>(Descriptor::kSearchElement);
11461cb0ef41Sopenharmony_ci  auto array_length = Parameter<Smi>(Descriptor::kLength);
11471cb0ef41Sopenharmony_ci  auto from_index = Parameter<Smi>(Descriptor::kFromIndex);
11481cb0ef41Sopenharmony_ci
11491cb0ef41Sopenharmony_ci  GenerateSmiOrObject(kIndexOf, context, elements, search_element, array_length,
11501cb0ef41Sopenharmony_ci                      from_index);
11511cb0ef41Sopenharmony_ci}
11521cb0ef41Sopenharmony_ci
11531cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayIndexOfPackedDoubles, ArrayIncludesIndexofAssembler) {
11541cb0ef41Sopenharmony_ci  auto elements = Parameter<FixedArrayBase>(Descriptor::kElements);
11551cb0ef41Sopenharmony_ci  auto search_element = Parameter<Object>(Descriptor::kSearchElement);
11561cb0ef41Sopenharmony_ci  auto array_length = Parameter<Smi>(Descriptor::kLength);
11571cb0ef41Sopenharmony_ci  auto from_index = Parameter<Smi>(Descriptor::kFromIndex);
11581cb0ef41Sopenharmony_ci
11591cb0ef41Sopenharmony_ci  ReturnIfEmpty(array_length, NumberConstant(-1));
11601cb0ef41Sopenharmony_ci  GeneratePackedDoubles(kIndexOf, CAST(elements), search_element, array_length,
11611cb0ef41Sopenharmony_ci                        from_index);
11621cb0ef41Sopenharmony_ci}
11631cb0ef41Sopenharmony_ci
11641cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayIndexOfHoleyDoubles, ArrayIncludesIndexofAssembler) {
11651cb0ef41Sopenharmony_ci  auto elements = Parameter<FixedArrayBase>(Descriptor::kElements);
11661cb0ef41Sopenharmony_ci  auto search_element = Parameter<Object>(Descriptor::kSearchElement);
11671cb0ef41Sopenharmony_ci  auto array_length = Parameter<Smi>(Descriptor::kLength);
11681cb0ef41Sopenharmony_ci  auto from_index = Parameter<Smi>(Descriptor::kFromIndex);
11691cb0ef41Sopenharmony_ci
11701cb0ef41Sopenharmony_ci  ReturnIfEmpty(array_length, NumberConstant(-1));
11711cb0ef41Sopenharmony_ci  GenerateHoleyDoubles(kIndexOf, CAST(elements), search_element, array_length,
11721cb0ef41Sopenharmony_ci                       from_index);
11731cb0ef41Sopenharmony_ci}
11741cb0ef41Sopenharmony_ci
11751cb0ef41Sopenharmony_ci// ES #sec-array.prototype.values
11761cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayPrototypeValues, CodeStubAssembler) {
11771cb0ef41Sopenharmony_ci  auto context = Parameter<NativeContext>(Descriptor::kContext);
11781cb0ef41Sopenharmony_ci  auto receiver = Parameter<Object>(Descriptor::kReceiver);
11791cb0ef41Sopenharmony_ci  Return(CreateArrayIterator(context, ToObject_Inline(context, receiver),
11801cb0ef41Sopenharmony_ci                             IterationKind::kValues));
11811cb0ef41Sopenharmony_ci}
11821cb0ef41Sopenharmony_ci
11831cb0ef41Sopenharmony_ci// ES #sec-array.prototype.entries
11841cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayPrototypeEntries, CodeStubAssembler) {
11851cb0ef41Sopenharmony_ci  auto context = Parameter<NativeContext>(Descriptor::kContext);
11861cb0ef41Sopenharmony_ci  auto receiver = Parameter<Object>(Descriptor::kReceiver);
11871cb0ef41Sopenharmony_ci  Return(CreateArrayIterator(context, ToObject_Inline(context, receiver),
11881cb0ef41Sopenharmony_ci                             IterationKind::kEntries));
11891cb0ef41Sopenharmony_ci}
11901cb0ef41Sopenharmony_ci
11911cb0ef41Sopenharmony_ci// ES #sec-array.prototype.keys
11921cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayPrototypeKeys, CodeStubAssembler) {
11931cb0ef41Sopenharmony_ci  auto context = Parameter<NativeContext>(Descriptor::kContext);
11941cb0ef41Sopenharmony_ci  auto receiver = Parameter<Object>(Descriptor::kReceiver);
11951cb0ef41Sopenharmony_ci  Return(CreateArrayIterator(context, ToObject_Inline(context, receiver),
11961cb0ef41Sopenharmony_ci                             IterationKind::kKeys));
11971cb0ef41Sopenharmony_ci}
11981cb0ef41Sopenharmony_ci
11991cb0ef41Sopenharmony_ci// ES #sec-%arrayiteratorprototype%.next
12001cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) {
12011cb0ef41Sopenharmony_ci  const char* method_name = "Array Iterator.prototype.next";
12021cb0ef41Sopenharmony_ci
12031cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
12041cb0ef41Sopenharmony_ci  auto maybe_iterator = Parameter<Object>(Descriptor::kReceiver);
12051cb0ef41Sopenharmony_ci
12061cb0ef41Sopenharmony_ci  TVARIABLE(Oddball, var_done, TrueConstant());
12071cb0ef41Sopenharmony_ci  TVARIABLE(Object, var_value, UndefinedConstant());
12081cb0ef41Sopenharmony_ci
12091cb0ef41Sopenharmony_ci  Label allocate_entry_if_needed(this);
12101cb0ef41Sopenharmony_ci  Label allocate_iterator_result(this);
12111cb0ef41Sopenharmony_ci  Label if_typedarray(this), if_other(this, Label::kDeferred), if_array(this),
12121cb0ef41Sopenharmony_ci      if_generic(this, Label::kDeferred);
12131cb0ef41Sopenharmony_ci  Label set_done(this, Label::kDeferred);
12141cb0ef41Sopenharmony_ci
12151cb0ef41Sopenharmony_ci  // If O does not have all of the internal slots of an Array Iterator Instance
12161cb0ef41Sopenharmony_ci  // (22.1.5.3), throw a TypeError exception
12171cb0ef41Sopenharmony_ci  ThrowIfNotInstanceType(context, maybe_iterator, JS_ARRAY_ITERATOR_TYPE,
12181cb0ef41Sopenharmony_ci                         method_name);
12191cb0ef41Sopenharmony_ci
12201cb0ef41Sopenharmony_ci  TNode<JSArrayIterator> iterator = CAST(maybe_iterator);
12211cb0ef41Sopenharmony_ci
12221cb0ef41Sopenharmony_ci  // Let a be O.[[IteratedObject]].
12231cb0ef41Sopenharmony_ci  TNode<JSReceiver> array = LoadJSArrayIteratorIteratedObject(iterator);
12241cb0ef41Sopenharmony_ci
12251cb0ef41Sopenharmony_ci  // Let index be O.[[ArrayIteratorNextIndex]].
12261cb0ef41Sopenharmony_ci  TNode<Number> index = LoadJSArrayIteratorNextIndex(iterator);
12271cb0ef41Sopenharmony_ci  CSA_DCHECK(this, IsNumberNonNegativeSafeInteger(index));
12281cb0ef41Sopenharmony_ci
12291cb0ef41Sopenharmony_ci  // Dispatch based on the type of the {array}.
12301cb0ef41Sopenharmony_ci  TNode<Map> array_map = LoadMap(array);
12311cb0ef41Sopenharmony_ci  TNode<Uint16T> array_type = LoadMapInstanceType(array_map);
12321cb0ef41Sopenharmony_ci  GotoIf(InstanceTypeEqual(array_type, JS_ARRAY_TYPE), &if_array);
12331cb0ef41Sopenharmony_ci  Branch(InstanceTypeEqual(array_type, JS_TYPED_ARRAY_TYPE), &if_typedarray,
12341cb0ef41Sopenharmony_ci         &if_other);
12351cb0ef41Sopenharmony_ci
12361cb0ef41Sopenharmony_ci  BIND(&if_array);
12371cb0ef41Sopenharmony_ci  {
12381cb0ef41Sopenharmony_ci    // If {array} is a JSArray, then the {index} must be in Unsigned32 range.
12391cb0ef41Sopenharmony_ci    CSA_DCHECK(this, IsNumberArrayIndex(index));
12401cb0ef41Sopenharmony_ci
12411cb0ef41Sopenharmony_ci    // Check that the {index} is within range for the {array}. We handle all
12421cb0ef41Sopenharmony_ci    // kinds of JSArray's here, so we do the computation on Uint32.
12431cb0ef41Sopenharmony_ci    TNode<Uint32T> index32 = ChangeNumberToUint32(index);
12441cb0ef41Sopenharmony_ci    TNode<Uint32T> length32 =
12451cb0ef41Sopenharmony_ci        ChangeNumberToUint32(LoadJSArrayLength(CAST(array)));
12461cb0ef41Sopenharmony_ci    GotoIfNot(Uint32LessThan(index32, length32), &set_done);
12471cb0ef41Sopenharmony_ci    StoreJSArrayIteratorNextIndex(
12481cb0ef41Sopenharmony_ci        iterator, ChangeUint32ToTagged(Uint32Add(index32, Uint32Constant(1))));
12491cb0ef41Sopenharmony_ci
12501cb0ef41Sopenharmony_ci    var_done = FalseConstant();
12511cb0ef41Sopenharmony_ci    var_value = index;
12521cb0ef41Sopenharmony_ci
12531cb0ef41Sopenharmony_ci    GotoIf(Word32Equal(LoadAndUntagToWord32ObjectField(
12541cb0ef41Sopenharmony_ci                           iterator, JSArrayIterator::kKindOffset),
12551cb0ef41Sopenharmony_ci                       Int32Constant(static_cast<int>(IterationKind::kKeys))),
12561cb0ef41Sopenharmony_ci           &allocate_iterator_result);
12571cb0ef41Sopenharmony_ci
12581cb0ef41Sopenharmony_ci    Label if_hole(this, Label::kDeferred);
12591cb0ef41Sopenharmony_ci    TNode<Int32T> elements_kind = LoadMapElementsKind(array_map);
12601cb0ef41Sopenharmony_ci    TNode<FixedArrayBase> elements = LoadElements(CAST(array));
12611cb0ef41Sopenharmony_ci    GotoIfForceSlowPath(&if_generic);
12621cb0ef41Sopenharmony_ci    var_value = LoadFixedArrayBaseElementAsTagged(
12631cb0ef41Sopenharmony_ci        elements, Signed(ChangeUint32ToWord(index32)), elements_kind,
12641cb0ef41Sopenharmony_ci        &if_generic, &if_hole);
12651cb0ef41Sopenharmony_ci    Goto(&allocate_entry_if_needed);
12661cb0ef41Sopenharmony_ci
12671cb0ef41Sopenharmony_ci    BIND(&if_hole);
12681cb0ef41Sopenharmony_ci    {
12691cb0ef41Sopenharmony_ci      GotoIf(IsNoElementsProtectorCellInvalid(), &if_generic);
12701cb0ef41Sopenharmony_ci      GotoIfNot(IsPrototypeInitialArrayPrototype(context, array_map),
12711cb0ef41Sopenharmony_ci                &if_generic);
12721cb0ef41Sopenharmony_ci      var_value = UndefinedConstant();
12731cb0ef41Sopenharmony_ci      Goto(&allocate_entry_if_needed);
12741cb0ef41Sopenharmony_ci    }
12751cb0ef41Sopenharmony_ci  }
12761cb0ef41Sopenharmony_ci
12771cb0ef41Sopenharmony_ci  BIND(&if_other);
12781cb0ef41Sopenharmony_ci  {
12791cb0ef41Sopenharmony_ci    // We cannot enter here with either JSArray's or JSTypedArray's.
12801cb0ef41Sopenharmony_ci    CSA_DCHECK(this, Word32BinaryNot(IsJSArray(array)));
12811cb0ef41Sopenharmony_ci    CSA_DCHECK(this, Word32BinaryNot(IsJSTypedArray(array)));
12821cb0ef41Sopenharmony_ci
12831cb0ef41Sopenharmony_ci    // Check that the {index} is within the bounds of the {array}s "length".
12841cb0ef41Sopenharmony_ci    TNode<Number> length = CAST(
12851cb0ef41Sopenharmony_ci        CallBuiltin(Builtin::kToLength, context,
12861cb0ef41Sopenharmony_ci                    GetProperty(context, array, factory()->length_string())));
12871cb0ef41Sopenharmony_ci    GotoIfNumberGreaterThanOrEqual(index, length, &set_done);
12881cb0ef41Sopenharmony_ci    StoreJSArrayIteratorNextIndex(iterator, NumberInc(index));
12891cb0ef41Sopenharmony_ci
12901cb0ef41Sopenharmony_ci    var_done = FalseConstant();
12911cb0ef41Sopenharmony_ci    var_value = index;
12921cb0ef41Sopenharmony_ci
12931cb0ef41Sopenharmony_ci    Branch(Word32Equal(LoadAndUntagToWord32ObjectField(
12941cb0ef41Sopenharmony_ci                           iterator, JSArrayIterator::kKindOffset),
12951cb0ef41Sopenharmony_ci                       Int32Constant(static_cast<int>(IterationKind::kKeys))),
12961cb0ef41Sopenharmony_ci           &allocate_iterator_result, &if_generic);
12971cb0ef41Sopenharmony_ci  }
12981cb0ef41Sopenharmony_ci
12991cb0ef41Sopenharmony_ci  BIND(&set_done);
13001cb0ef41Sopenharmony_ci  {
13011cb0ef41Sopenharmony_ci    // Change the [[ArrayIteratorNextIndex]] such that the {iterator} will
13021cb0ef41Sopenharmony_ci    // never produce values anymore, because it will always fail the bounds
13031cb0ef41Sopenharmony_ci    // check. Note that this is different from what the specification does,
13041cb0ef41Sopenharmony_ci    // which is changing the [[IteratedObject]] to undefined, because leaving
13051cb0ef41Sopenharmony_ci    // [[IteratedObject]] alone helps TurboFan to generate better code with
13061cb0ef41Sopenharmony_ci    // the inlining in JSCallReducer::ReduceArrayIteratorPrototypeNext().
13071cb0ef41Sopenharmony_ci    //
13081cb0ef41Sopenharmony_ci    // The terminal value we chose here depends on the type of the {array},
13091cb0ef41Sopenharmony_ci    // for JSArray's we use kMaxUInt32 so that TurboFan can always use
13101cb0ef41Sopenharmony_ci    // Word32 representation for fast-path indices (and this is safe since
13111cb0ef41Sopenharmony_ci    // the "length" of JSArray's is limited to Unsigned32 range). For other
13121cb0ef41Sopenharmony_ci    // JSReceiver's we have to use kMaxSafeInteger, since the "length" can
13131cb0ef41Sopenharmony_ci    // be any arbitrary value in the safe integer range.
13141cb0ef41Sopenharmony_ci    //
13151cb0ef41Sopenharmony_ci    // Note specifically that JSTypedArray's will never take this path, so
13161cb0ef41Sopenharmony_ci    // we don't need to worry about their maximum value.
13171cb0ef41Sopenharmony_ci    CSA_DCHECK(this, Word32BinaryNot(IsJSTypedArray(array)));
13181cb0ef41Sopenharmony_ci    TNode<Number> max_length =
13191cb0ef41Sopenharmony_ci        SelectConstant(IsJSArray(array), NumberConstant(kMaxUInt32),
13201cb0ef41Sopenharmony_ci                       NumberConstant(kMaxSafeInteger));
13211cb0ef41Sopenharmony_ci    StoreJSArrayIteratorNextIndex(iterator, max_length);
13221cb0ef41Sopenharmony_ci    Goto(&allocate_iterator_result);
13231cb0ef41Sopenharmony_ci  }
13241cb0ef41Sopenharmony_ci
13251cb0ef41Sopenharmony_ci  BIND(&if_generic);
13261cb0ef41Sopenharmony_ci  {
13271cb0ef41Sopenharmony_ci    var_value = GetProperty(context, array, index);
13281cb0ef41Sopenharmony_ci    Goto(&allocate_entry_if_needed);
13291cb0ef41Sopenharmony_ci  }
13301cb0ef41Sopenharmony_ci
13311cb0ef41Sopenharmony_ci  BIND(&if_typedarray);
13321cb0ef41Sopenharmony_ci  {
13331cb0ef41Sopenharmony_ci    // Overflowing uintptr range also means end of iteration.
13341cb0ef41Sopenharmony_ci    TNode<UintPtrT> index_uintptr =
13351cb0ef41Sopenharmony_ci        ChangeSafeIntegerNumberToUintPtr(index, &allocate_iterator_result);
13361cb0ef41Sopenharmony_ci
13371cb0ef41Sopenharmony_ci    // If we go outside of the {length}, we don't need to update the
13381cb0ef41Sopenharmony_ci    // [[ArrayIteratorNextIndex]] anymore, since a JSTypedArray's
13391cb0ef41Sopenharmony_ci    // length cannot change anymore, so this {iterator} will never
13401cb0ef41Sopenharmony_ci    // produce values again anyways.
13411cb0ef41Sopenharmony_ci    Label detached(this);
13421cb0ef41Sopenharmony_ci    TNode<UintPtrT> length =
13431cb0ef41Sopenharmony_ci        LoadJSTypedArrayLengthAndCheckDetached(CAST(array), &detached);
13441cb0ef41Sopenharmony_ci    GotoIfNot(UintPtrLessThan(index_uintptr, length),
13451cb0ef41Sopenharmony_ci              &allocate_iterator_result);
13461cb0ef41Sopenharmony_ci    // TODO(v8:4153): Consider storing next index as uintptr. Update this and
13471cb0ef41Sopenharmony_ci    // the relevant TurboFan code.
13481cb0ef41Sopenharmony_ci    StoreJSArrayIteratorNextIndex(
13491cb0ef41Sopenharmony_ci        iterator,
13501cb0ef41Sopenharmony_ci        ChangeUintPtrToTagged(UintPtrAdd(index_uintptr, UintPtrConstant(1))));
13511cb0ef41Sopenharmony_ci
13521cb0ef41Sopenharmony_ci    var_done = FalseConstant();
13531cb0ef41Sopenharmony_ci    var_value = index;
13541cb0ef41Sopenharmony_ci
13551cb0ef41Sopenharmony_ci    GotoIf(Word32Equal(LoadAndUntagToWord32ObjectField(
13561cb0ef41Sopenharmony_ci                           iterator, JSArrayIterator::kKindOffset),
13571cb0ef41Sopenharmony_ci                       Int32Constant(static_cast<int>(IterationKind::kKeys))),
13581cb0ef41Sopenharmony_ci           &allocate_iterator_result);
13591cb0ef41Sopenharmony_ci
13601cb0ef41Sopenharmony_ci    TNode<Int32T> elements_kind = LoadMapElementsKind(array_map);
13611cb0ef41Sopenharmony_ci    TNode<RawPtrT> data_ptr = LoadJSTypedArrayDataPtr(CAST(array));
13621cb0ef41Sopenharmony_ci    var_value = LoadFixedTypedArrayElementAsTagged(data_ptr, index_uintptr,
13631cb0ef41Sopenharmony_ci                                                   elements_kind);
13641cb0ef41Sopenharmony_ci    Goto(&allocate_entry_if_needed);
13651cb0ef41Sopenharmony_ci
13661cb0ef41Sopenharmony_ci    BIND(&detached);
13671cb0ef41Sopenharmony_ci    ThrowTypeError(context, MessageTemplate::kDetachedOperation, method_name);
13681cb0ef41Sopenharmony_ci  }
13691cb0ef41Sopenharmony_ci
13701cb0ef41Sopenharmony_ci  BIND(&allocate_entry_if_needed);
13711cb0ef41Sopenharmony_ci  {
13721cb0ef41Sopenharmony_ci    GotoIf(Word32Equal(LoadAndUntagToWord32ObjectField(
13731cb0ef41Sopenharmony_ci                           iterator, JSArrayIterator::kKindOffset),
13741cb0ef41Sopenharmony_ci                       Int32Constant(static_cast<int>(IterationKind::kValues))),
13751cb0ef41Sopenharmony_ci           &allocate_iterator_result);
13761cb0ef41Sopenharmony_ci
13771cb0ef41Sopenharmony_ci    TNode<JSObject> result =
13781cb0ef41Sopenharmony_ci        AllocateJSIteratorResultForEntry(context, index, var_value.value());
13791cb0ef41Sopenharmony_ci    Return(result);
13801cb0ef41Sopenharmony_ci  }
13811cb0ef41Sopenharmony_ci
13821cb0ef41Sopenharmony_ci  BIND(&allocate_iterator_result);
13831cb0ef41Sopenharmony_ci  {
13841cb0ef41Sopenharmony_ci    TNode<JSObject> result =
13851cb0ef41Sopenharmony_ci        AllocateJSIteratorResult(context, var_value.value(), var_done.value());
13861cb0ef41Sopenharmony_ci    Return(result);
13871cb0ef41Sopenharmony_ci  }
13881cb0ef41Sopenharmony_ci}
13891cb0ef41Sopenharmony_ci
13901cb0ef41Sopenharmony_ciclass ArrayFlattenAssembler : public CodeStubAssembler {
13911cb0ef41Sopenharmony_ci public:
13921cb0ef41Sopenharmony_ci  explicit ArrayFlattenAssembler(compiler::CodeAssemblerState* state)
13931cb0ef41Sopenharmony_ci      : CodeStubAssembler(state) {}
13941cb0ef41Sopenharmony_ci
13951cb0ef41Sopenharmony_ci  // https://tc39.github.io/proposal-flatMap/#sec-FlattenIntoArray
13961cb0ef41Sopenharmony_ci  TNode<Number> FlattenIntoArray(
13971cb0ef41Sopenharmony_ci      TNode<Context> context, TNode<JSReceiver> target,
13981cb0ef41Sopenharmony_ci      TNode<JSReceiver> source, TNode<Number> source_length,
13991cb0ef41Sopenharmony_ci      TNode<Number> start, TNode<Number> depth,
14001cb0ef41Sopenharmony_ci      base::Optional<TNode<HeapObject>> mapper_function = base::nullopt,
14011cb0ef41Sopenharmony_ci      base::Optional<TNode<Object>> this_arg = base::nullopt) {
14021cb0ef41Sopenharmony_ci    CSA_DCHECK(this, IsNumberPositive(source_length));
14031cb0ef41Sopenharmony_ci    CSA_DCHECK(this, IsNumberPositive(start));
14041cb0ef41Sopenharmony_ci
14051cb0ef41Sopenharmony_ci    // 1. Let targetIndex be start.
14061cb0ef41Sopenharmony_ci    TVARIABLE(Number, var_target_index, start);
14071cb0ef41Sopenharmony_ci
14081cb0ef41Sopenharmony_ci    // 2. Let sourceIndex be 0.
14091cb0ef41Sopenharmony_ci    TVARIABLE(Number, var_source_index, SmiConstant(0));
14101cb0ef41Sopenharmony_ci
14111cb0ef41Sopenharmony_ci    // 3. Repeat...
14121cb0ef41Sopenharmony_ci    Label loop(this, {&var_target_index, &var_source_index}), done_loop(this);
14131cb0ef41Sopenharmony_ci    Goto(&loop);
14141cb0ef41Sopenharmony_ci    BIND(&loop);
14151cb0ef41Sopenharmony_ci    {
14161cb0ef41Sopenharmony_ci      TNode<Number> source_index = var_source_index.value();
14171cb0ef41Sopenharmony_ci      TNode<Number> target_index = var_target_index.value();
14181cb0ef41Sopenharmony_ci
14191cb0ef41Sopenharmony_ci      // ...while sourceIndex < sourceLen
14201cb0ef41Sopenharmony_ci      GotoIfNumberGreaterThanOrEqual(source_index, source_length, &done_loop);
14211cb0ef41Sopenharmony_ci
14221cb0ef41Sopenharmony_ci      // a. Let P be ! ToString(sourceIndex).
14231cb0ef41Sopenharmony_ci      // b. Let exists be ? HasProperty(source, P).
14241cb0ef41Sopenharmony_ci      CSA_DCHECK(this,
14251cb0ef41Sopenharmony_ci                 SmiGreaterThanOrEqual(CAST(source_index), SmiConstant(0)));
14261cb0ef41Sopenharmony_ci      const TNode<Oddball> exists =
14271cb0ef41Sopenharmony_ci          HasProperty(context, source, source_index, kHasProperty);
14281cb0ef41Sopenharmony_ci
14291cb0ef41Sopenharmony_ci      // c. If exists is true, then
14301cb0ef41Sopenharmony_ci      Label next(this);
14311cb0ef41Sopenharmony_ci      GotoIfNot(IsTrue(exists), &next);
14321cb0ef41Sopenharmony_ci      {
14331cb0ef41Sopenharmony_ci        // i. Let element be ? Get(source, P).
14341cb0ef41Sopenharmony_ci        TNode<Object> element_maybe_smi =
14351cb0ef41Sopenharmony_ci            GetProperty(context, source, source_index);
14361cb0ef41Sopenharmony_ci
14371cb0ef41Sopenharmony_ci        // ii. If mapperFunction is present, then
14381cb0ef41Sopenharmony_ci        if (mapper_function) {
14391cb0ef41Sopenharmony_ci          CSA_DCHECK(this, Word32Or(IsUndefined(mapper_function.value()),
14401cb0ef41Sopenharmony_ci                                    IsCallable(mapper_function.value())));
14411cb0ef41Sopenharmony_ci          DCHECK(this_arg.has_value());
14421cb0ef41Sopenharmony_ci
14431cb0ef41Sopenharmony_ci          // 1. Set element to ? Call(mapperFunction, thisArg , « element,
14441cb0ef41Sopenharmony_ci          //                          sourceIndex, source »).
14451cb0ef41Sopenharmony_ci          element_maybe_smi =
14461cb0ef41Sopenharmony_ci              Call(context, mapper_function.value(), this_arg.value(),
14471cb0ef41Sopenharmony_ci                   element_maybe_smi, source_index, source);
14481cb0ef41Sopenharmony_ci        }
14491cb0ef41Sopenharmony_ci
14501cb0ef41Sopenharmony_ci        // iii. Let shouldFlatten be false.
14511cb0ef41Sopenharmony_ci        Label if_flatten_array(this), if_flatten_proxy(this, Label::kDeferred),
14521cb0ef41Sopenharmony_ci            if_noflatten(this);
14531cb0ef41Sopenharmony_ci        // iv. If depth > 0, then
14541cb0ef41Sopenharmony_ci        GotoIfNumberGreaterThanOrEqual(SmiConstant(0), depth, &if_noflatten);
14551cb0ef41Sopenharmony_ci        // 1. Set shouldFlatten to ? IsArray(element).
14561cb0ef41Sopenharmony_ci        GotoIf(TaggedIsSmi(element_maybe_smi), &if_noflatten);
14571cb0ef41Sopenharmony_ci        TNode<HeapObject> element = CAST(element_maybe_smi);
14581cb0ef41Sopenharmony_ci        GotoIf(IsJSArray(element), &if_flatten_array);
14591cb0ef41Sopenharmony_ci        GotoIfNot(IsJSProxy(element), &if_noflatten);
14601cb0ef41Sopenharmony_ci        Branch(IsTrue(CallRuntime(Runtime::kArrayIsArray, context, element)),
14611cb0ef41Sopenharmony_ci               &if_flatten_proxy, &if_noflatten);
14621cb0ef41Sopenharmony_ci
14631cb0ef41Sopenharmony_ci        BIND(&if_flatten_array);
14641cb0ef41Sopenharmony_ci        {
14651cb0ef41Sopenharmony_ci          CSA_DCHECK(this, IsJSArray(element));
14661cb0ef41Sopenharmony_ci
14671cb0ef41Sopenharmony_ci          // 1. Let elementLen be ? ToLength(? Get(element, "length")).
14681cb0ef41Sopenharmony_ci          const TNode<Object> element_length =
14691cb0ef41Sopenharmony_ci              LoadObjectField(element, JSArray::kLengthOffset);
14701cb0ef41Sopenharmony_ci
14711cb0ef41Sopenharmony_ci          // 2. Set targetIndex to ? FlattenIntoArray(target, element,
14721cb0ef41Sopenharmony_ci          //                                          elementLen, targetIndex,
14731cb0ef41Sopenharmony_ci          //                                          depth - 1).
14741cb0ef41Sopenharmony_ci          var_target_index = CAST(
14751cb0ef41Sopenharmony_ci              CallBuiltin(Builtin::kFlattenIntoArray, context, target, element,
14761cb0ef41Sopenharmony_ci                          element_length, target_index, NumberDec(depth)));
14771cb0ef41Sopenharmony_ci          Goto(&next);
14781cb0ef41Sopenharmony_ci        }
14791cb0ef41Sopenharmony_ci
14801cb0ef41Sopenharmony_ci        BIND(&if_flatten_proxy);
14811cb0ef41Sopenharmony_ci        {
14821cb0ef41Sopenharmony_ci          CSA_DCHECK(this, IsJSProxy(element));
14831cb0ef41Sopenharmony_ci
14841cb0ef41Sopenharmony_ci          // 1. Let elementLen be ? ToLength(? Get(element, "length")).
14851cb0ef41Sopenharmony_ci          const TNode<Number> element_length = ToLength_Inline(
14861cb0ef41Sopenharmony_ci              context, GetProperty(context, element, LengthStringConstant()));
14871cb0ef41Sopenharmony_ci
14881cb0ef41Sopenharmony_ci          // 2. Set targetIndex to ? FlattenIntoArray(target, element,
14891cb0ef41Sopenharmony_ci          //                                          elementLen, targetIndex,
14901cb0ef41Sopenharmony_ci          //                                          depth - 1).
14911cb0ef41Sopenharmony_ci          var_target_index = CAST(
14921cb0ef41Sopenharmony_ci              CallBuiltin(Builtin::kFlattenIntoArray, context, target, element,
14931cb0ef41Sopenharmony_ci                          element_length, target_index, NumberDec(depth)));
14941cb0ef41Sopenharmony_ci          Goto(&next);
14951cb0ef41Sopenharmony_ci        }
14961cb0ef41Sopenharmony_ci
14971cb0ef41Sopenharmony_ci        BIND(&if_noflatten);
14981cb0ef41Sopenharmony_ci        {
14991cb0ef41Sopenharmony_ci          // 1. If targetIndex >= 2^53-1, throw a TypeError exception.
15001cb0ef41Sopenharmony_ci          Label throw_error(this, Label::kDeferred);
15011cb0ef41Sopenharmony_ci          GotoIfNumberGreaterThanOrEqual(
15021cb0ef41Sopenharmony_ci              target_index, NumberConstant(kMaxSafeInteger), &throw_error);
15031cb0ef41Sopenharmony_ci
15041cb0ef41Sopenharmony_ci          // 2. Perform ? CreateDataPropertyOrThrow(target,
15051cb0ef41Sopenharmony_ci          //                                        ! ToString(targetIndex),
15061cb0ef41Sopenharmony_ci          //                                        element).
15071cb0ef41Sopenharmony_ci          CallRuntime(Runtime::kCreateDataProperty, context, target,
15081cb0ef41Sopenharmony_ci                      target_index, element);
15091cb0ef41Sopenharmony_ci
15101cb0ef41Sopenharmony_ci          // 3. Increase targetIndex by 1.
15111cb0ef41Sopenharmony_ci          var_target_index = NumberInc(target_index);
15121cb0ef41Sopenharmony_ci          Goto(&next);
15131cb0ef41Sopenharmony_ci
15141cb0ef41Sopenharmony_ci          BIND(&throw_error);
15151cb0ef41Sopenharmony_ci          ThrowTypeError(context, MessageTemplate::kFlattenPastSafeLength,
15161cb0ef41Sopenharmony_ci                         source_length, target_index);
15171cb0ef41Sopenharmony_ci        }
15181cb0ef41Sopenharmony_ci      }
15191cb0ef41Sopenharmony_ci      BIND(&next);
15201cb0ef41Sopenharmony_ci
15211cb0ef41Sopenharmony_ci      // d. Increase sourceIndex by 1.
15221cb0ef41Sopenharmony_ci      var_source_index = NumberInc(source_index);
15231cb0ef41Sopenharmony_ci      Goto(&loop);
15241cb0ef41Sopenharmony_ci    }
15251cb0ef41Sopenharmony_ci
15261cb0ef41Sopenharmony_ci    BIND(&done_loop);
15271cb0ef41Sopenharmony_ci    return var_target_index.value();
15281cb0ef41Sopenharmony_ci  }
15291cb0ef41Sopenharmony_ci};
15301cb0ef41Sopenharmony_ci
15311cb0ef41Sopenharmony_ci// https://tc39.github.io/proposal-flatMap/#sec-FlattenIntoArray
15321cb0ef41Sopenharmony_ciTF_BUILTIN(FlattenIntoArray, ArrayFlattenAssembler) {
15331cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
15341cb0ef41Sopenharmony_ci  auto target = Parameter<JSReceiver>(Descriptor::kTarget);
15351cb0ef41Sopenharmony_ci  auto source = Parameter<JSReceiver>(Descriptor::kSource);
15361cb0ef41Sopenharmony_ci  auto source_length = Parameter<Number>(Descriptor::kSourceLength);
15371cb0ef41Sopenharmony_ci  auto start = Parameter<Number>(Descriptor::kStart);
15381cb0ef41Sopenharmony_ci  auto depth = Parameter<Number>(Descriptor::kDepth);
15391cb0ef41Sopenharmony_ci
15401cb0ef41Sopenharmony_ci  // FlattenIntoArray might get called recursively, check stack for overflow
15411cb0ef41Sopenharmony_ci  // manually as it has stub linkage.
15421cb0ef41Sopenharmony_ci  PerformStackCheck(context);
15431cb0ef41Sopenharmony_ci
15441cb0ef41Sopenharmony_ci  Return(
15451cb0ef41Sopenharmony_ci      FlattenIntoArray(context, target, source, source_length, start, depth));
15461cb0ef41Sopenharmony_ci}
15471cb0ef41Sopenharmony_ci
15481cb0ef41Sopenharmony_ci// https://tc39.github.io/proposal-flatMap/#sec-FlattenIntoArray
15491cb0ef41Sopenharmony_ciTF_BUILTIN(FlatMapIntoArray, ArrayFlattenAssembler) {
15501cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
15511cb0ef41Sopenharmony_ci  auto target = Parameter<JSReceiver>(Descriptor::kTarget);
15521cb0ef41Sopenharmony_ci  auto source = Parameter<JSReceiver>(Descriptor::kSource);
15531cb0ef41Sopenharmony_ci  auto source_length = Parameter<Number>(Descriptor::kSourceLength);
15541cb0ef41Sopenharmony_ci  auto start = Parameter<Number>(Descriptor::kStart);
15551cb0ef41Sopenharmony_ci  auto depth = Parameter<Number>(Descriptor::kDepth);
15561cb0ef41Sopenharmony_ci  auto mapper_function = Parameter<HeapObject>(Descriptor::kMapperFunction);
15571cb0ef41Sopenharmony_ci  auto this_arg = Parameter<Object>(Descriptor::kThisArg);
15581cb0ef41Sopenharmony_ci
15591cb0ef41Sopenharmony_ci  Return(FlattenIntoArray(context, target, source, source_length, start, depth,
15601cb0ef41Sopenharmony_ci                          mapper_function, this_arg));
15611cb0ef41Sopenharmony_ci}
15621cb0ef41Sopenharmony_ci
15631cb0ef41Sopenharmony_ci// https://tc39.github.io/proposal-flatMap/#sec-Array.prototype.flat
15641cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayPrototypeFlat, CodeStubAssembler) {
15651cb0ef41Sopenharmony_ci  const TNode<IntPtrT> argc = ChangeInt32ToIntPtr(
15661cb0ef41Sopenharmony_ci      UncheckedParameter<Int32T>(Descriptor::kJSActualArgumentsCount));
15671cb0ef41Sopenharmony_ci  CodeStubArguments args(this, argc);
15681cb0ef41Sopenharmony_ci  const auto context = Parameter<Context>(Descriptor::kContext);
15691cb0ef41Sopenharmony_ci  const TNode<Object> receiver = args.GetReceiver();
15701cb0ef41Sopenharmony_ci  const TNode<Object> depth = args.GetOptionalArgumentValue(0);
15711cb0ef41Sopenharmony_ci
15721cb0ef41Sopenharmony_ci  // 1. Let O be ? ToObject(this value).
15731cb0ef41Sopenharmony_ci  const TNode<JSReceiver> o = ToObject_Inline(context, receiver);
15741cb0ef41Sopenharmony_ci
15751cb0ef41Sopenharmony_ci  // 2. Let sourceLen be ? ToLength(? Get(O, "length")).
15761cb0ef41Sopenharmony_ci  const TNode<Number> source_length =
15771cb0ef41Sopenharmony_ci      ToLength_Inline(context, GetProperty(context, o, LengthStringConstant()));
15781cb0ef41Sopenharmony_ci
15791cb0ef41Sopenharmony_ci  // 3. Let depthNum be 1.
15801cb0ef41Sopenharmony_ci  TVARIABLE(Number, var_depth_num, SmiConstant(1));
15811cb0ef41Sopenharmony_ci
15821cb0ef41Sopenharmony_ci  // 4. If depth is not undefined, then
15831cb0ef41Sopenharmony_ci  Label done(this);
15841cb0ef41Sopenharmony_ci  GotoIf(IsUndefined(depth), &done);
15851cb0ef41Sopenharmony_ci  {
15861cb0ef41Sopenharmony_ci    // a. Set depthNum to ? ToInteger(depth).
15871cb0ef41Sopenharmony_ci    var_depth_num = ToInteger_Inline(context, depth);
15881cb0ef41Sopenharmony_ci    Goto(&done);
15891cb0ef41Sopenharmony_ci  }
15901cb0ef41Sopenharmony_ci  BIND(&done);
15911cb0ef41Sopenharmony_ci
15921cb0ef41Sopenharmony_ci  // 5. Let A be ? ArraySpeciesCreate(O, 0).
15931cb0ef41Sopenharmony_ci  const TNode<JSReceiver> constructor =
15941cb0ef41Sopenharmony_ci      CAST(CallRuntime(Runtime::kArraySpeciesConstructor, context, o));
15951cb0ef41Sopenharmony_ci  const TNode<JSReceiver> a = Construct(context, constructor, SmiConstant(0));
15961cb0ef41Sopenharmony_ci
15971cb0ef41Sopenharmony_ci  // 6. Perform ? FlattenIntoArray(A, O, sourceLen, 0, depthNum).
15981cb0ef41Sopenharmony_ci  CallBuiltin(Builtin::kFlattenIntoArray, context, a, o, source_length,
15991cb0ef41Sopenharmony_ci              SmiConstant(0), var_depth_num.value());
16001cb0ef41Sopenharmony_ci
16011cb0ef41Sopenharmony_ci  // 7. Return A.
16021cb0ef41Sopenharmony_ci  args.PopAndReturn(a);
16031cb0ef41Sopenharmony_ci}
16041cb0ef41Sopenharmony_ci
16051cb0ef41Sopenharmony_ci// https://tc39.github.io/proposal-flatMap/#sec-Array.prototype.flatMap
16061cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayPrototypeFlatMap, CodeStubAssembler) {
16071cb0ef41Sopenharmony_ci  const TNode<IntPtrT> argc = ChangeInt32ToIntPtr(
16081cb0ef41Sopenharmony_ci      UncheckedParameter<Int32T>(Descriptor::kJSActualArgumentsCount));
16091cb0ef41Sopenharmony_ci  CodeStubArguments args(this, argc);
16101cb0ef41Sopenharmony_ci  const auto context = Parameter<Context>(Descriptor::kContext);
16111cb0ef41Sopenharmony_ci  const TNode<Object> receiver = args.GetReceiver();
16121cb0ef41Sopenharmony_ci  const TNode<Object> mapper_function = args.GetOptionalArgumentValue(0);
16131cb0ef41Sopenharmony_ci
16141cb0ef41Sopenharmony_ci  // 1. Let O be ? ToObject(this value).
16151cb0ef41Sopenharmony_ci  const TNode<JSReceiver> o = ToObject_Inline(context, receiver);
16161cb0ef41Sopenharmony_ci
16171cb0ef41Sopenharmony_ci  // 2. Let sourceLen be ? ToLength(? Get(O, "length")).
16181cb0ef41Sopenharmony_ci  const TNode<Number> source_length =
16191cb0ef41Sopenharmony_ci      ToLength_Inline(context, GetProperty(context, o, LengthStringConstant()));
16201cb0ef41Sopenharmony_ci
16211cb0ef41Sopenharmony_ci  // 3. If IsCallable(mapperFunction) is false, throw a TypeError exception.
16221cb0ef41Sopenharmony_ci  Label if_not_callable(this, Label::kDeferred);
16231cb0ef41Sopenharmony_ci  GotoIf(TaggedIsSmi(mapper_function), &if_not_callable);
16241cb0ef41Sopenharmony_ci  GotoIfNot(IsCallable(CAST(mapper_function)), &if_not_callable);
16251cb0ef41Sopenharmony_ci
16261cb0ef41Sopenharmony_ci  // 4. If thisArg is present, let T be thisArg; else let T be undefined.
16271cb0ef41Sopenharmony_ci  const TNode<Object> t = args.GetOptionalArgumentValue(1);
16281cb0ef41Sopenharmony_ci
16291cb0ef41Sopenharmony_ci  // 5. Let A be ? ArraySpeciesCreate(O, 0).
16301cb0ef41Sopenharmony_ci  const TNode<JSReceiver> constructor =
16311cb0ef41Sopenharmony_ci      CAST(CallRuntime(Runtime::kArraySpeciesConstructor, context, o));
16321cb0ef41Sopenharmony_ci  const TNode<JSReceiver> a = Construct(context, constructor, SmiConstant(0));
16331cb0ef41Sopenharmony_ci
16341cb0ef41Sopenharmony_ci  // 6. Perform ? FlattenIntoArray(A, O, sourceLen, 0, 1, mapperFunction, T).
16351cb0ef41Sopenharmony_ci  CallBuiltin(Builtin::kFlatMapIntoArray, context, a, o, source_length,
16361cb0ef41Sopenharmony_ci              SmiConstant(0), SmiConstant(1), mapper_function, t);
16371cb0ef41Sopenharmony_ci
16381cb0ef41Sopenharmony_ci  // 7. Return A.
16391cb0ef41Sopenharmony_ci  args.PopAndReturn(a);
16401cb0ef41Sopenharmony_ci
16411cb0ef41Sopenharmony_ci  BIND(&if_not_callable);
16421cb0ef41Sopenharmony_ci  { ThrowTypeError(context, MessageTemplate::kMapperFunctionNonCallable); }
16431cb0ef41Sopenharmony_ci}
16441cb0ef41Sopenharmony_ci
16451cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayConstructor, ArrayBuiltinsAssembler) {
16461cb0ef41Sopenharmony_ci  // This is a trampoline to ArrayConstructorImpl which just adds
16471cb0ef41Sopenharmony_ci  // allocation_site parameter value and sets new_target if necessary.
16481cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
16491cb0ef41Sopenharmony_ci  auto function = Parameter<JSFunction>(Descriptor::kTarget);
16501cb0ef41Sopenharmony_ci  auto new_target = Parameter<Object>(Descriptor::kNewTarget);
16511cb0ef41Sopenharmony_ci  auto argc = UncheckedParameter<Int32T>(Descriptor::kActualArgumentsCount);
16521cb0ef41Sopenharmony_ci
16531cb0ef41Sopenharmony_ci  // If new_target is undefined, then this is the 'Call' case, so set new_target
16541cb0ef41Sopenharmony_ci  // to function.
16551cb0ef41Sopenharmony_ci  new_target =
16561cb0ef41Sopenharmony_ci      SelectConstant<Object>(IsUndefined(new_target), function, new_target);
16571cb0ef41Sopenharmony_ci
16581cb0ef41Sopenharmony_ci  // Run the native code for the Array function called as a normal function.
16591cb0ef41Sopenharmony_ci  TNode<Oddball> no_gc_site = UndefinedConstant();
16601cb0ef41Sopenharmony_ci  TailCallBuiltin(Builtin::kArrayConstructorImpl, context, function, new_target,
16611cb0ef41Sopenharmony_ci                  argc, no_gc_site);
16621cb0ef41Sopenharmony_ci}
16631cb0ef41Sopenharmony_ci
16641cb0ef41Sopenharmony_civoid ArrayBuiltinsAssembler::TailCallArrayConstructorStub(
16651cb0ef41Sopenharmony_ci    const Callable& callable, TNode<Context> context, TNode<JSFunction> target,
16661cb0ef41Sopenharmony_ci    TNode<HeapObject> allocation_site_or_undefined, TNode<Int32T> argc) {
16671cb0ef41Sopenharmony_ci  TNode<CodeT> code = HeapConstant(callable.code());
16681cb0ef41Sopenharmony_ci
16691cb0ef41Sopenharmony_ci  // We are going to call here ArrayNoArgumentsConstructor or
16701cb0ef41Sopenharmony_ci  // ArraySingleArgumentsConstructor which in addition to the register arguments
16711cb0ef41Sopenharmony_ci  // also expect some number of arguments on the expression stack.
16721cb0ef41Sopenharmony_ci  // Since
16731cb0ef41Sopenharmony_ci  // 1) incoming JS arguments are still on the stack,
16741cb0ef41Sopenharmony_ci  // 2) the ArrayNoArgumentsConstructor, ArraySingleArgumentsConstructor and
16751cb0ef41Sopenharmony_ci  //    ArrayNArgumentsConstructor are defined so that the register arguments
16761cb0ef41Sopenharmony_ci  //    are passed on the same registers,
16771cb0ef41Sopenharmony_ci  // in order to be able to generate a tail call to those builtins we do the
16781cb0ef41Sopenharmony_ci  // following trick here: we tail call to the constructor builtin using
16791cb0ef41Sopenharmony_ci  // ArrayNArgumentsConstructorDescriptor, so the tail call instruction
16801cb0ef41Sopenharmony_ci  // pops the current frame but leaves all the incoming JS arguments on the
16811cb0ef41Sopenharmony_ci  // expression stack so that the target builtin can still find them where it
16821cb0ef41Sopenharmony_ci  // expects.
16831cb0ef41Sopenharmony_ci  TailCallStub(ArrayNArgumentsConstructorDescriptor{}, code, context, target,
16841cb0ef41Sopenharmony_ci               allocation_site_or_undefined, argc);
16851cb0ef41Sopenharmony_ci}
16861cb0ef41Sopenharmony_ci
16871cb0ef41Sopenharmony_civoid ArrayBuiltinsAssembler::CreateArrayDispatchNoArgument(
16881cb0ef41Sopenharmony_ci    TNode<Context> context, TNode<JSFunction> target, TNode<Int32T> argc,
16891cb0ef41Sopenharmony_ci    AllocationSiteOverrideMode mode,
16901cb0ef41Sopenharmony_ci    base::Optional<TNode<AllocationSite>> allocation_site) {
16911cb0ef41Sopenharmony_ci  if (mode == DISABLE_ALLOCATION_SITES) {
16921cb0ef41Sopenharmony_ci    Callable callable = CodeFactory::ArrayNoArgumentConstructor(
16931cb0ef41Sopenharmony_ci        isolate(), GetInitialFastElementsKind(), mode);
16941cb0ef41Sopenharmony_ci
16951cb0ef41Sopenharmony_ci    TailCallArrayConstructorStub(callable, context, target, UndefinedConstant(),
16961cb0ef41Sopenharmony_ci                                 argc);
16971cb0ef41Sopenharmony_ci  } else {
16981cb0ef41Sopenharmony_ci    DCHECK_EQ(mode, DONT_OVERRIDE);
16991cb0ef41Sopenharmony_ci    DCHECK(allocation_site);
17001cb0ef41Sopenharmony_ci    TNode<Int32T> elements_kind = LoadElementsKind(*allocation_site);
17011cb0ef41Sopenharmony_ci
17021cb0ef41Sopenharmony_ci    // TODO(ishell): Compute the builtin index dynamically instead of
17031cb0ef41Sopenharmony_ci    // iterating over all expected elements kinds.
17041cb0ef41Sopenharmony_ci    int last_index =
17051cb0ef41Sopenharmony_ci        GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND);
17061cb0ef41Sopenharmony_ci    for (int i = 0; i <= last_index; ++i) {
17071cb0ef41Sopenharmony_ci      Label next(this);
17081cb0ef41Sopenharmony_ci      ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
17091cb0ef41Sopenharmony_ci      GotoIfNot(Word32Equal(elements_kind, Int32Constant(kind)), &next);
17101cb0ef41Sopenharmony_ci
17111cb0ef41Sopenharmony_ci      Callable callable =
17121cb0ef41Sopenharmony_ci          CodeFactory::ArrayNoArgumentConstructor(isolate(), kind, mode);
17131cb0ef41Sopenharmony_ci
17141cb0ef41Sopenharmony_ci      TailCallArrayConstructorStub(callable, context, target, *allocation_site,
17151cb0ef41Sopenharmony_ci                                   argc);
17161cb0ef41Sopenharmony_ci
17171cb0ef41Sopenharmony_ci      BIND(&next);
17181cb0ef41Sopenharmony_ci    }
17191cb0ef41Sopenharmony_ci
17201cb0ef41Sopenharmony_ci    // If we reached this point there is a problem.
17211cb0ef41Sopenharmony_ci    Abort(AbortReason::kUnexpectedElementsKindInArrayConstructor);
17221cb0ef41Sopenharmony_ci  }
17231cb0ef41Sopenharmony_ci}
17241cb0ef41Sopenharmony_ci
17251cb0ef41Sopenharmony_civoid ArrayBuiltinsAssembler::CreateArrayDispatchSingleArgument(
17261cb0ef41Sopenharmony_ci    TNode<Context> context, TNode<JSFunction> target, TNode<Int32T> argc,
17271cb0ef41Sopenharmony_ci    AllocationSiteOverrideMode mode,
17281cb0ef41Sopenharmony_ci    base::Optional<TNode<AllocationSite>> allocation_site) {
17291cb0ef41Sopenharmony_ci  if (mode == DISABLE_ALLOCATION_SITES) {
17301cb0ef41Sopenharmony_ci    ElementsKind initial = GetInitialFastElementsKind();
17311cb0ef41Sopenharmony_ci    ElementsKind holey_initial = GetHoleyElementsKind(initial);
17321cb0ef41Sopenharmony_ci    Callable callable = CodeFactory::ArraySingleArgumentConstructor(
17331cb0ef41Sopenharmony_ci        isolate(), holey_initial, mode);
17341cb0ef41Sopenharmony_ci
17351cb0ef41Sopenharmony_ci    TailCallArrayConstructorStub(callable, context, target, UndefinedConstant(),
17361cb0ef41Sopenharmony_ci                                 argc);
17371cb0ef41Sopenharmony_ci  } else {
17381cb0ef41Sopenharmony_ci    DCHECK_EQ(mode, DONT_OVERRIDE);
17391cb0ef41Sopenharmony_ci    DCHECK(allocation_site);
17401cb0ef41Sopenharmony_ci    TNode<Smi> transition_info = LoadTransitionInfo(*allocation_site);
17411cb0ef41Sopenharmony_ci
17421cb0ef41Sopenharmony_ci    // Least significant bit in fast array elements kind means holeyness.
17431cb0ef41Sopenharmony_ci    STATIC_ASSERT(PACKED_SMI_ELEMENTS == 0);
17441cb0ef41Sopenharmony_ci    STATIC_ASSERT(HOLEY_SMI_ELEMENTS == 1);
17451cb0ef41Sopenharmony_ci    STATIC_ASSERT(PACKED_ELEMENTS == 2);
17461cb0ef41Sopenharmony_ci    STATIC_ASSERT(HOLEY_ELEMENTS == 3);
17471cb0ef41Sopenharmony_ci    STATIC_ASSERT(PACKED_DOUBLE_ELEMENTS == 4);
17481cb0ef41Sopenharmony_ci    STATIC_ASSERT(HOLEY_DOUBLE_ELEMENTS == 5);
17491cb0ef41Sopenharmony_ci
17501cb0ef41Sopenharmony_ci    Label normal_sequence(this);
17511cb0ef41Sopenharmony_ci    TVARIABLE(Int32T, var_elements_kind,
17521cb0ef41Sopenharmony_ci              Signed(DecodeWord32<AllocationSite::ElementsKindBits>(
17531cb0ef41Sopenharmony_ci                  SmiToInt32(transition_info))));
17541cb0ef41Sopenharmony_ci    // Is the low bit set? If so, we are holey and that is good.
17551cb0ef41Sopenharmony_ci    int fast_elements_kind_holey_mask =
17561cb0ef41Sopenharmony_ci        AllocationSite::ElementsKindBits::encode(static_cast<ElementsKind>(1));
17571cb0ef41Sopenharmony_ci    GotoIf(IsSetSmi(transition_info, fast_elements_kind_holey_mask),
17581cb0ef41Sopenharmony_ci           &normal_sequence);
17591cb0ef41Sopenharmony_ci    {
17601cb0ef41Sopenharmony_ci      // Make elements kind holey and update elements kind in the type info.
17611cb0ef41Sopenharmony_ci      var_elements_kind = Word32Or(var_elements_kind.value(), Int32Constant(1));
17621cb0ef41Sopenharmony_ci      StoreObjectFieldNoWriteBarrier(
17631cb0ef41Sopenharmony_ci          *allocation_site, AllocationSite::kTransitionInfoOrBoilerplateOffset,
17641cb0ef41Sopenharmony_ci          SmiOr(transition_info, SmiConstant(fast_elements_kind_holey_mask)));
17651cb0ef41Sopenharmony_ci      Goto(&normal_sequence);
17661cb0ef41Sopenharmony_ci    }
17671cb0ef41Sopenharmony_ci    BIND(&normal_sequence);
17681cb0ef41Sopenharmony_ci
17691cb0ef41Sopenharmony_ci    // TODO(ishell): Compute the builtin index dynamically instead of
17701cb0ef41Sopenharmony_ci    // iterating over all expected elements kinds.
17711cb0ef41Sopenharmony_ci    // TODO(ishell): Given that the code above ensures that the elements kind
17721cb0ef41Sopenharmony_ci    // is holey we can skip checking with non-holey elements kinds.
17731cb0ef41Sopenharmony_ci    int last_index =
17741cb0ef41Sopenharmony_ci        GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND);
17751cb0ef41Sopenharmony_ci    for (int i = 0; i <= last_index; ++i) {
17761cb0ef41Sopenharmony_ci      Label next(this);
17771cb0ef41Sopenharmony_ci      ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
17781cb0ef41Sopenharmony_ci      GotoIfNot(Word32Equal(var_elements_kind.value(), Int32Constant(kind)),
17791cb0ef41Sopenharmony_ci                &next);
17801cb0ef41Sopenharmony_ci
17811cb0ef41Sopenharmony_ci      Callable callable =
17821cb0ef41Sopenharmony_ci          CodeFactory::ArraySingleArgumentConstructor(isolate(), kind, mode);
17831cb0ef41Sopenharmony_ci
17841cb0ef41Sopenharmony_ci      TailCallArrayConstructorStub(callable, context, target, *allocation_site,
17851cb0ef41Sopenharmony_ci                                   argc);
17861cb0ef41Sopenharmony_ci
17871cb0ef41Sopenharmony_ci      BIND(&next);
17881cb0ef41Sopenharmony_ci    }
17891cb0ef41Sopenharmony_ci
17901cb0ef41Sopenharmony_ci    // If we reached this point there is a problem.
17911cb0ef41Sopenharmony_ci    Abort(AbortReason::kUnexpectedElementsKindInArrayConstructor);
17921cb0ef41Sopenharmony_ci  }
17931cb0ef41Sopenharmony_ci}
17941cb0ef41Sopenharmony_ci
17951cb0ef41Sopenharmony_civoid ArrayBuiltinsAssembler::GenerateDispatchToArrayStub(
17961cb0ef41Sopenharmony_ci    TNode<Context> context, TNode<JSFunction> target, TNode<Int32T> argc,
17971cb0ef41Sopenharmony_ci    AllocationSiteOverrideMode mode,
17981cb0ef41Sopenharmony_ci    base::Optional<TNode<AllocationSite>> allocation_site) {
17991cb0ef41Sopenharmony_ci  CodeStubArguments args(this, argc);
18001cb0ef41Sopenharmony_ci  Label check_one_case(this), fallthrough(this);
18011cb0ef41Sopenharmony_ci  GotoIfNot(IntPtrEqual(args.GetLengthWithoutReceiver(), IntPtrConstant(0)),
18021cb0ef41Sopenharmony_ci            &check_one_case);
18031cb0ef41Sopenharmony_ci  CreateArrayDispatchNoArgument(context, target, argc, mode, allocation_site);
18041cb0ef41Sopenharmony_ci
18051cb0ef41Sopenharmony_ci  BIND(&check_one_case);
18061cb0ef41Sopenharmony_ci  GotoIfNot(IntPtrEqual(args.GetLengthWithoutReceiver(), IntPtrConstant(1)),
18071cb0ef41Sopenharmony_ci            &fallthrough);
18081cb0ef41Sopenharmony_ci  CreateArrayDispatchSingleArgument(context, target, argc, mode,
18091cb0ef41Sopenharmony_ci                                    allocation_site);
18101cb0ef41Sopenharmony_ci
18111cb0ef41Sopenharmony_ci  BIND(&fallthrough);
18121cb0ef41Sopenharmony_ci}
18131cb0ef41Sopenharmony_ci
18141cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayConstructorImpl, ArrayBuiltinsAssembler) {
18151cb0ef41Sopenharmony_ci  auto target = Parameter<JSFunction>(Descriptor::kTarget);
18161cb0ef41Sopenharmony_ci  auto new_target = Parameter<Object>(Descriptor::kNewTarget);
18171cb0ef41Sopenharmony_ci  auto argc = UncheckedParameter<Int32T>(Descriptor::kActualArgumentsCount);
18181cb0ef41Sopenharmony_ci  auto maybe_allocation_site =
18191cb0ef41Sopenharmony_ci      Parameter<HeapObject>(Descriptor::kAllocationSite);
18201cb0ef41Sopenharmony_ci
18211cb0ef41Sopenharmony_ci  // Initial map for the builtin Array functions should be Map.
18221cb0ef41Sopenharmony_ci  CSA_DCHECK(this, IsMap(CAST(LoadObjectField(
18231cb0ef41Sopenharmony_ci                       target, JSFunction::kPrototypeOrInitialMapOffset))));
18241cb0ef41Sopenharmony_ci
18251cb0ef41Sopenharmony_ci  // We should either have undefined or a valid AllocationSite
18261cb0ef41Sopenharmony_ci  CSA_DCHECK(this, Word32Or(IsUndefined(maybe_allocation_site),
18271cb0ef41Sopenharmony_ci                            IsAllocationSite(maybe_allocation_site)));
18281cb0ef41Sopenharmony_ci
18291cb0ef41Sopenharmony_ci  // "Enter" the context of the Array function.
18301cb0ef41Sopenharmony_ci  TNode<Context> context =
18311cb0ef41Sopenharmony_ci      CAST(LoadObjectField(target, JSFunction::kContextOffset));
18321cb0ef41Sopenharmony_ci
18331cb0ef41Sopenharmony_ci  Label runtime(this, Label::kDeferred);
18341cb0ef41Sopenharmony_ci  GotoIf(TaggedNotEqual(target, new_target), &runtime);
18351cb0ef41Sopenharmony_ci
18361cb0ef41Sopenharmony_ci  Label no_info(this);
18371cb0ef41Sopenharmony_ci  // If the feedback vector is the undefined value call an array constructor
18381cb0ef41Sopenharmony_ci  // that doesn't use AllocationSites.
18391cb0ef41Sopenharmony_ci  GotoIf(IsUndefined(maybe_allocation_site), &no_info);
18401cb0ef41Sopenharmony_ci
18411cb0ef41Sopenharmony_ci  GenerateDispatchToArrayStub(context, target, argc, DONT_OVERRIDE,
18421cb0ef41Sopenharmony_ci                              CAST(maybe_allocation_site));
18431cb0ef41Sopenharmony_ci  Goto(&runtime);
18441cb0ef41Sopenharmony_ci
18451cb0ef41Sopenharmony_ci  BIND(&no_info);
18461cb0ef41Sopenharmony_ci  GenerateDispatchToArrayStub(context, target, argc, DISABLE_ALLOCATION_SITES);
18471cb0ef41Sopenharmony_ci  Goto(&runtime);
18481cb0ef41Sopenharmony_ci
18491cb0ef41Sopenharmony_ci  BIND(&runtime);
18501cb0ef41Sopenharmony_ci  GenerateArrayNArgumentsConstructor(context, target, new_target, argc,
18511cb0ef41Sopenharmony_ci                                     maybe_allocation_site);
18521cb0ef41Sopenharmony_ci}
18531cb0ef41Sopenharmony_ci
18541cb0ef41Sopenharmony_civoid ArrayBuiltinsAssembler::GenerateConstructor(
18551cb0ef41Sopenharmony_ci    TNode<Context> context, TNode<HeapObject> array_function,
18561cb0ef41Sopenharmony_ci    TNode<Map> array_map, TNode<Object> array_size,
18571cb0ef41Sopenharmony_ci    TNode<HeapObject> allocation_site, ElementsKind elements_kind,
18581cb0ef41Sopenharmony_ci    AllocationSiteMode mode) {
18591cb0ef41Sopenharmony_ci  Label ok(this);
18601cb0ef41Sopenharmony_ci  Label smi_size(this);
18611cb0ef41Sopenharmony_ci  Label small_smi_size(this);
18621cb0ef41Sopenharmony_ci  Label call_runtime(this, Label::kDeferred);
18631cb0ef41Sopenharmony_ci
18641cb0ef41Sopenharmony_ci  Branch(TaggedIsSmi(array_size), &smi_size, &call_runtime);
18651cb0ef41Sopenharmony_ci
18661cb0ef41Sopenharmony_ci  BIND(&smi_size);
18671cb0ef41Sopenharmony_ci  {
18681cb0ef41Sopenharmony_ci    TNode<Smi> array_size_smi = CAST(array_size);
18691cb0ef41Sopenharmony_ci
18701cb0ef41Sopenharmony_ci    if (IsFastPackedElementsKind(elements_kind)) {
18711cb0ef41Sopenharmony_ci      Label abort(this, Label::kDeferred);
18721cb0ef41Sopenharmony_ci      Branch(SmiEqual(array_size_smi, SmiConstant(0)), &small_smi_size, &abort);
18731cb0ef41Sopenharmony_ci
18741cb0ef41Sopenharmony_ci      BIND(&abort);
18751cb0ef41Sopenharmony_ci      TNode<Smi> reason =
18761cb0ef41Sopenharmony_ci          SmiConstant(AbortReason::kAllocatingNonEmptyPackedArray);
18771cb0ef41Sopenharmony_ci      TailCallRuntime(Runtime::kAbort, context, reason);
18781cb0ef41Sopenharmony_ci    } else {
18791cb0ef41Sopenharmony_ci      Branch(SmiAboveOrEqual(array_size_smi,
18801cb0ef41Sopenharmony_ci                             SmiConstant(JSArray::kInitialMaxFastElementArray)),
18811cb0ef41Sopenharmony_ci             &call_runtime, &small_smi_size);
18821cb0ef41Sopenharmony_ci    }
18831cb0ef41Sopenharmony_ci
18841cb0ef41Sopenharmony_ci    BIND(&small_smi_size);
18851cb0ef41Sopenharmony_ci    {
18861cb0ef41Sopenharmony_ci      TNode<JSArray> array = AllocateJSArray(
18871cb0ef41Sopenharmony_ci          elements_kind, array_map, array_size_smi, array_size_smi,
18881cb0ef41Sopenharmony_ci          mode == DONT_TRACK_ALLOCATION_SITE
18891cb0ef41Sopenharmony_ci              ? base::Optional<TNode<AllocationSite>>(base::nullopt)
18901cb0ef41Sopenharmony_ci              : CAST(allocation_site));
18911cb0ef41Sopenharmony_ci      Return(array);
18921cb0ef41Sopenharmony_ci    }
18931cb0ef41Sopenharmony_ci  }
18941cb0ef41Sopenharmony_ci
18951cb0ef41Sopenharmony_ci  BIND(&call_runtime);
18961cb0ef41Sopenharmony_ci  {
18971cb0ef41Sopenharmony_ci    TailCallRuntimeNewArray(context, array_function, array_size, array_function,
18981cb0ef41Sopenharmony_ci                            allocation_site);
18991cb0ef41Sopenharmony_ci  }
19001cb0ef41Sopenharmony_ci}
19011cb0ef41Sopenharmony_ci
19021cb0ef41Sopenharmony_civoid ArrayBuiltinsAssembler::GenerateArrayNoArgumentConstructor(
19031cb0ef41Sopenharmony_ci    ElementsKind kind, AllocationSiteOverrideMode mode) {
19041cb0ef41Sopenharmony_ci  using Descriptor = ArrayNoArgumentConstructorDescriptor;
19051cb0ef41Sopenharmony_ci  TNode<NativeContext> native_context = LoadObjectField<NativeContext>(
19061cb0ef41Sopenharmony_ci      Parameter<HeapObject>(Descriptor::kFunction), JSFunction::kContextOffset);
19071cb0ef41Sopenharmony_ci  bool track_allocation_site =
19081cb0ef41Sopenharmony_ci      AllocationSite::ShouldTrack(kind) && mode != DISABLE_ALLOCATION_SITES;
19091cb0ef41Sopenharmony_ci  base::Optional<TNode<AllocationSite>> allocation_site =
19101cb0ef41Sopenharmony_ci      track_allocation_site
19111cb0ef41Sopenharmony_ci          ? Parameter<AllocationSite>(Descriptor::kAllocationSite)
19121cb0ef41Sopenharmony_ci          : base::Optional<TNode<AllocationSite>>(base::nullopt);
19131cb0ef41Sopenharmony_ci  TNode<Map> array_map = LoadJSArrayElementsMap(kind, native_context);
19141cb0ef41Sopenharmony_ci  TNode<JSArray> array = AllocateJSArray(
19151cb0ef41Sopenharmony_ci      kind, array_map, IntPtrConstant(JSArray::kPreallocatedArrayElements),
19161cb0ef41Sopenharmony_ci      SmiConstant(0), allocation_site);
19171cb0ef41Sopenharmony_ci  Return(array);
19181cb0ef41Sopenharmony_ci}
19191cb0ef41Sopenharmony_ci
19201cb0ef41Sopenharmony_civoid ArrayBuiltinsAssembler::GenerateArraySingleArgumentConstructor(
19211cb0ef41Sopenharmony_ci    ElementsKind kind, AllocationSiteOverrideMode mode) {
19221cb0ef41Sopenharmony_ci  using Descriptor = ArraySingleArgumentConstructorDescriptor;
19231cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
19241cb0ef41Sopenharmony_ci  auto function = Parameter<HeapObject>(Descriptor::kFunction);
19251cb0ef41Sopenharmony_ci  TNode<NativeContext> native_context =
19261cb0ef41Sopenharmony_ci      CAST(LoadObjectField(function, JSFunction::kContextOffset));
19271cb0ef41Sopenharmony_ci  TNode<Map> array_map = LoadJSArrayElementsMap(kind, native_context);
19281cb0ef41Sopenharmony_ci
19291cb0ef41Sopenharmony_ci  AllocationSiteMode allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
19301cb0ef41Sopenharmony_ci  if (mode == DONT_OVERRIDE) {
19311cb0ef41Sopenharmony_ci    allocation_site_mode = AllocationSite::ShouldTrack(kind)
19321cb0ef41Sopenharmony_ci                               ? TRACK_ALLOCATION_SITE
19331cb0ef41Sopenharmony_ci                               : DONT_TRACK_ALLOCATION_SITE;
19341cb0ef41Sopenharmony_ci  }
19351cb0ef41Sopenharmony_ci
19361cb0ef41Sopenharmony_ci  auto array_size = Parameter<Object>(Descriptor::kArraySizeSmiParameter);
19371cb0ef41Sopenharmony_ci  // allocation_site can be Undefined or an AllocationSite
19381cb0ef41Sopenharmony_ci  auto allocation_site = Parameter<HeapObject>(Descriptor::kAllocationSite);
19391cb0ef41Sopenharmony_ci
19401cb0ef41Sopenharmony_ci  GenerateConstructor(context, function, array_map, array_size, allocation_site,
19411cb0ef41Sopenharmony_ci                      kind, allocation_site_mode);
19421cb0ef41Sopenharmony_ci}
19431cb0ef41Sopenharmony_ci
19441cb0ef41Sopenharmony_civoid ArrayBuiltinsAssembler::GenerateArrayNArgumentsConstructor(
19451cb0ef41Sopenharmony_ci    TNode<Context> context, TNode<JSFunction> target, TNode<Object> new_target,
19461cb0ef41Sopenharmony_ci    TNode<Int32T> argc, TNode<HeapObject> maybe_allocation_site) {
19471cb0ef41Sopenharmony_ci  // Replace incoming JS receiver argument with the target.
19481cb0ef41Sopenharmony_ci  // TODO(ishell): Avoid replacing the target on the stack and just add it
19491cb0ef41Sopenharmony_ci  // as another additional parameter for Runtime::kNewArray.
19501cb0ef41Sopenharmony_ci  CodeStubArguments args(this, argc);
19511cb0ef41Sopenharmony_ci  args.SetReceiver(target);
19521cb0ef41Sopenharmony_ci
19531cb0ef41Sopenharmony_ci  // Adjust arguments count for the runtime call:
19541cb0ef41Sopenharmony_ci  // +2 for new_target and maybe_allocation_site.
19551cb0ef41Sopenharmony_ci  argc = Int32Add(TruncateIntPtrToInt32(args.GetLengthWithReceiver()),
19561cb0ef41Sopenharmony_ci                  Int32Constant(2));
19571cb0ef41Sopenharmony_ci  TailCallRuntime(Runtime::kNewArray, argc, context, new_target,
19581cb0ef41Sopenharmony_ci                  maybe_allocation_site);
19591cb0ef41Sopenharmony_ci}
19601cb0ef41Sopenharmony_ci
19611cb0ef41Sopenharmony_ciTF_BUILTIN(ArrayNArgumentsConstructor, ArrayBuiltinsAssembler) {
19621cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
19631cb0ef41Sopenharmony_ci  auto target = Parameter<JSFunction>(Descriptor::kFunction);
19641cb0ef41Sopenharmony_ci  auto argc = UncheckedParameter<Int32T>(Descriptor::kActualArgumentsCount);
19651cb0ef41Sopenharmony_ci  auto maybe_allocation_site =
19661cb0ef41Sopenharmony_ci      Parameter<HeapObject>(Descriptor::kAllocationSite);
19671cb0ef41Sopenharmony_ci
19681cb0ef41Sopenharmony_ci  GenerateArrayNArgumentsConstructor(context, target, target, argc,
19691cb0ef41Sopenharmony_ci                                     maybe_allocation_site);
19701cb0ef41Sopenharmony_ci}
19711cb0ef41Sopenharmony_ci
19721cb0ef41Sopenharmony_ci#define GENERATE_ARRAY_CTOR(name, kind_camel, kind_caps, mode_camel, \
19731cb0ef41Sopenharmony_ci                            mode_caps)                               \
19741cb0ef41Sopenharmony_ci  TF_BUILTIN(Array##name##Constructor_##kind_camel##_##mode_camel,   \
19751cb0ef41Sopenharmony_ci             ArrayBuiltinsAssembler) {                               \
19761cb0ef41Sopenharmony_ci    GenerateArray##name##Constructor(kind_caps, mode_caps);          \
19771cb0ef41Sopenharmony_ci  }
19781cb0ef41Sopenharmony_ci
19791cb0ef41Sopenharmony_ci// The ArrayNoArgumentConstructor builtin family.
19801cb0ef41Sopenharmony_ciGENERATE_ARRAY_CTOR(NoArgument, PackedSmi, PACKED_SMI_ELEMENTS, DontOverride,
19811cb0ef41Sopenharmony_ci                    DONT_OVERRIDE)
19821cb0ef41Sopenharmony_ciGENERATE_ARRAY_CTOR(NoArgument, HoleySmi, HOLEY_SMI_ELEMENTS, DontOverride,
19831cb0ef41Sopenharmony_ci                    DONT_OVERRIDE)
19841cb0ef41Sopenharmony_ciGENERATE_ARRAY_CTOR(NoArgument, PackedSmi, PACKED_SMI_ELEMENTS,
19851cb0ef41Sopenharmony_ci                    DisableAllocationSites, DISABLE_ALLOCATION_SITES)
19861cb0ef41Sopenharmony_ciGENERATE_ARRAY_CTOR(NoArgument, HoleySmi, HOLEY_SMI_ELEMENTS,
19871cb0ef41Sopenharmony_ci                    DisableAllocationSites, DISABLE_ALLOCATION_SITES)
19881cb0ef41Sopenharmony_ciGENERATE_ARRAY_CTOR(NoArgument, Packed, PACKED_ELEMENTS, DisableAllocationSites,
19891cb0ef41Sopenharmony_ci                    DISABLE_ALLOCATION_SITES)
19901cb0ef41Sopenharmony_ciGENERATE_ARRAY_CTOR(NoArgument, Holey, HOLEY_ELEMENTS, DisableAllocationSites,
19911cb0ef41Sopenharmony_ci                    DISABLE_ALLOCATION_SITES)
19921cb0ef41Sopenharmony_ciGENERATE_ARRAY_CTOR(NoArgument, PackedDouble, PACKED_DOUBLE_ELEMENTS,
19931cb0ef41Sopenharmony_ci                    DisableAllocationSites, DISABLE_ALLOCATION_SITES)
19941cb0ef41Sopenharmony_ciGENERATE_ARRAY_CTOR(NoArgument, HoleyDouble, HOLEY_DOUBLE_ELEMENTS,
19951cb0ef41Sopenharmony_ci                    DisableAllocationSites, DISABLE_ALLOCATION_SITES)
19961cb0ef41Sopenharmony_ci
19971cb0ef41Sopenharmony_ci// The ArraySingleArgumentConstructor builtin family.
19981cb0ef41Sopenharmony_ciGENERATE_ARRAY_CTOR(SingleArgument, PackedSmi, PACKED_SMI_ELEMENTS,
19991cb0ef41Sopenharmony_ci                    DontOverride, DONT_OVERRIDE)
20001cb0ef41Sopenharmony_ciGENERATE_ARRAY_CTOR(SingleArgument, HoleySmi, HOLEY_SMI_ELEMENTS, DontOverride,
20011cb0ef41Sopenharmony_ci                    DONT_OVERRIDE)
20021cb0ef41Sopenharmony_ciGENERATE_ARRAY_CTOR(SingleArgument, PackedSmi, PACKED_SMI_ELEMENTS,
20031cb0ef41Sopenharmony_ci                    DisableAllocationSites, DISABLE_ALLOCATION_SITES)
20041cb0ef41Sopenharmony_ciGENERATE_ARRAY_CTOR(SingleArgument, HoleySmi, HOLEY_SMI_ELEMENTS,
20051cb0ef41Sopenharmony_ci                    DisableAllocationSites, DISABLE_ALLOCATION_SITES)
20061cb0ef41Sopenharmony_ciGENERATE_ARRAY_CTOR(SingleArgument, Packed, PACKED_ELEMENTS,
20071cb0ef41Sopenharmony_ci                    DisableAllocationSites, DISABLE_ALLOCATION_SITES)
20081cb0ef41Sopenharmony_ciGENERATE_ARRAY_CTOR(SingleArgument, Holey, HOLEY_ELEMENTS,
20091cb0ef41Sopenharmony_ci                    DisableAllocationSites, DISABLE_ALLOCATION_SITES)
20101cb0ef41Sopenharmony_ciGENERATE_ARRAY_CTOR(SingleArgument, PackedDouble, PACKED_DOUBLE_ELEMENTS,
20111cb0ef41Sopenharmony_ci                    DisableAllocationSites, DISABLE_ALLOCATION_SITES)
20121cb0ef41Sopenharmony_ciGENERATE_ARRAY_CTOR(SingleArgument, HoleyDouble, HOLEY_DOUBLE_ELEMENTS,
20131cb0ef41Sopenharmony_ci                    DisableAllocationSites, DISABLE_ALLOCATION_SITES)
20141cb0ef41Sopenharmony_ci
20151cb0ef41Sopenharmony_ci#undef GENERATE_ARRAY_CTOR
20161cb0ef41Sopenharmony_ci
20171cb0ef41Sopenharmony_ci}  // namespace internal
20181cb0ef41Sopenharmony_ci}  // namespace v8
2019