// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/builtins/builtins-typedarray-gen.h"

#include "src/builtins/builtins-constructor-gen.h"
#include "src/builtins/builtins-iterator-gen.h"
#include "src/builtins/builtins-utils-gen.h"
#include "src/builtins/builtins.h"
#include "src/builtins/growable-fixed-array-gen.h"
#include "src/handles-inl.h"

namespace v8 {
namespace internal {

using compiler::Node;
template <class T>
using TNode = compiler::TNode<T>;

// This is needed for gc_mole which will compile this file without the full set
// of GN defined macros.
#ifndef V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP
#define V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP 64
#endif

// -----------------------------------------------------------------------------
// ES6 section 22.2 TypedArray Objects

TNode<Map> TypedArrayBuiltinsAssembler::LoadMapForType(
    TNode<JSTypedArray> array) {
  TVARIABLE(Map, var_typed_map);
  TNode<Map> array_map = LoadMap(array);
  TNode<Int32T> elements_kind = LoadMapElementsKind(array_map);

  DispatchTypedArrayByElementsKind(
      elements_kind,
      [&](ElementsKind kind, int size, int typed_array_fun_index) {
        ExternalArrayType type =
            isolate()->factory()->GetArrayTypeFromElementsKind(kind);
        Handle<Map> map(isolate()->heap()->MapForFixedTypedArray(type));
        var_typed_map = HeapConstant(map);
      });

  return var_typed_map;
}

// The byte_offset can be higher than Smi range, in which case to perform the
// pointer arithmetic necessary to calculate external_pointer, converting
// byte_offset to an intptr is more difficult. The max byte_offset is 8 * MaxSmi
// on the particular platform. 32 bit platforms are self-limiting, because we
// can't allocate an array bigger than our 32-bit arithmetic range anyway. 64
// bit platforms could theoretically have an offset up to 2^35 - 1, so we may
// need to convert the float heap number to an intptr.
TNode<UintPtrT> TypedArrayBuiltinsAssembler::CalculateExternalPointer(
    TNode<UintPtrT> backing_store, TNode<Number> byte_offset) {
  return Unsigned(
      IntPtrAdd(backing_store, ChangeNonnegativeNumberToUintPtr(byte_offset)));
}

// Setup the TypedArray which is under construction.
//  - Set the length.
//  - Set the byte_offset.
//  - Set the byte_length.
//  - Set EmbedderFields to 0.
void TypedArrayBuiltinsAssembler::SetupTypedArray(TNode<JSTypedArray> holder,
                                                  TNode<Smi> length,
                                                  TNode<Number> byte_offset,
                                                  TNode<Number> byte_length) {
  StoreObjectField(holder, JSTypedArray::kLengthOffset, length);
  StoreObjectField(holder, JSArrayBufferView::kByteOffsetOffset, byte_offset);
  StoreObjectField(holder, JSArrayBufferView::kByteLengthOffset, byte_length);
  for (int offset = JSTypedArray::kSize;
       offset < JSTypedArray::kSizeWithEmbedderFields; offset += kPointerSize) {
    StoreObjectField(holder, offset, SmiConstant(0));
  }
}

// Attach an off-heap buffer to a TypedArray.
void TypedArrayBuiltinsAssembler::AttachBuffer(TNode<JSTypedArray> holder,
                                               TNode<JSArrayBuffer> buffer,
                                               TNode<Map> map,
                                               TNode<Smi> length,
                                               TNode<Number> byte_offset) {
  StoreObjectField(holder, JSArrayBufferView::kBufferOffset, buffer);

  Node* elements = Allocate(FixedTypedArrayBase::kHeaderSize);
  StoreMapNoWriteBarrier(elements, map);
  StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset, length);
  StoreObjectFieldNoWriteBarrier(
      elements, FixedTypedArrayBase::kBasePointerOffset, SmiConstant(0));

  TNode<UintPtrT> backing_store =
      LoadObjectField<UintPtrT>(buffer, JSArrayBuffer::kBackingStoreOffset);

  TNode<UintPtrT> external_pointer =
      CalculateExternalPointer(backing_store, byte_offset);
  StoreObjectFieldNoWriteBarrier(
      elements, FixedTypedArrayBase::kExternalPointerOffset, external_pointer,
      MachineType::PointerRepresentation());

  StoreObjectField(holder, JSObject::kElementsOffset, elements);
}

TF_BUILTIN(TypedArrayInitializeWithBuffer, TypedArrayBuiltinsAssembler) {
  TNode<JSTypedArray> holder = CAST(Parameter(Descriptor::kHolder));
  TNode<Smi> length = CAST(Parameter(Descriptor::kLength));
  TNode<JSArrayBuffer> buffer = CAST(Parameter(Descriptor::kBuffer));
  TNode<Smi> element_size = CAST(Parameter(Descriptor::kElementSize));
  TNode<Number> byte_offset = CAST(Parameter(Descriptor::kByteOffset));

  TNode<Map> fixed_typed_map = LoadMapForType(holder);

  // SmiMul returns a heap number in case of Smi overflow.
  TNode<Number> byte_length = SmiMul(length, element_size);

  SetupTypedArray(holder, length, byte_offset, byte_length);
  AttachBuffer(holder, buffer, fixed_typed_map, length, byte_offset);
  Return(UndefinedConstant());
}

TF_BUILTIN(TypedArrayInitialize, TypedArrayBuiltinsAssembler) {
  TNode<JSTypedArray> holder = CAST(Parameter(Descriptor::kHolder));
  TNode<Smi> length = CAST(Parameter(Descriptor::kLength));
  TNode<Smi> element_size = CAST(Parameter(Descriptor::kElementSize));
  Node* initialize = Parameter(Descriptor::kInitialize);
  TNode<Context> context = CAST(Parameter(Descriptor::kContext));

  CSA_ASSERT(this, TaggedIsPositiveSmi(length));
  CSA_ASSERT(this, TaggedIsPositiveSmi(element_size));
  CSA_ASSERT(this, IsBoolean(initialize));

  TNode<Smi> byte_offset = SmiConstant(0);

  static const int32_t fta_base_data_offset =
      FixedTypedArrayBase::kDataOffset - kHeapObjectTag;

  Label setup_holder(this), allocate_on_heap(this), aligned(this),
      allocate_elements(this), allocate_off_heap(this),
      allocate_off_heap_no_init(this), attach_buffer(this), done(this);
  VARIABLE(var_total_size, MachineType::PointerRepresentation());

  // SmiMul returns a heap number in case of Smi overflow.
  TNode<Number> byte_length = SmiMul(length, element_size);

  SetupTypedArray(holder, length, byte_offset, byte_length);

  TNode<Map> fixed_typed_map = LoadMapForType(holder);
  GotoIf(TaggedIsNotSmi(byte_length), &allocate_off_heap);
  GotoIf(
      SmiGreaterThan(byte_length, SmiConstant(V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP)),
      &allocate_off_heap);
  TNode<IntPtrT> word_byte_length = SmiToWord(CAST(byte_length));
  Goto(&allocate_on_heap);

  BIND(&allocate_on_heap);
  {
    CSA_ASSERT(this, TaggedIsPositiveSmi(byte_length));
    // Allocate a new ArrayBuffer and initialize it with empty properties and
    // elements.
    Node* native_context = LoadNativeContext(context);
    Node* map =
        LoadContextElement(native_context, Context::ARRAY_BUFFER_MAP_INDEX);
    Node* empty_fixed_array = LoadRoot(Heap::kEmptyFixedArrayRootIndex);

    Node* buffer = Allocate(JSArrayBuffer::kSizeWithEmbedderFields);
    StoreMapNoWriteBarrier(buffer, map);
    StoreObjectFieldNoWriteBarrier(buffer, JSArray::kPropertiesOrHashOffset,
                                   empty_fixed_array);
    StoreObjectFieldNoWriteBarrier(buffer, JSArray::kElementsOffset,
                                   empty_fixed_array);
    // Setup the ArrayBuffer.
    //  - Set BitField to 0.
    //  - Set IsExternal and IsNeuterable bits of BitFieldSlot.
    //  - Set the byte_length field to byte_length.
    //  - Set backing_store to null/Smi(0).
    //  - Set all embedder fields to Smi(0).
    StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kBitFieldSlot,
                                   SmiConstant(0));
    int32_t bitfield_value = (1 << JSArrayBuffer::IsExternal::kShift) |
                             (1 << JSArrayBuffer::IsNeuterable::kShift);
    StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kBitFieldOffset,
                                   Int32Constant(bitfield_value),
                                   MachineRepresentation::kWord32);

    StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kByteLengthOffset,
                                   byte_length);
    StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kBackingStoreOffset,
                                   SmiConstant(0));
    for (int i = 0; i < v8::ArrayBuffer::kEmbedderFieldCount; i++) {
      int offset = JSArrayBuffer::kSize + i * kPointerSize;
      StoreObjectFieldNoWriteBarrier(buffer, offset, SmiConstant(0));
    }

    StoreObjectField(holder, JSArrayBufferView::kBufferOffset, buffer);

    // Check the alignment.
    GotoIf(SmiEqual(SmiMod(element_size, SmiConstant(kObjectAlignment)),
                    SmiConstant(0)),
           &aligned);

    // Fix alignment if needed.
    DCHECK_EQ(0, FixedTypedArrayBase::kHeaderSize & kObjectAlignmentMask);
    Node* aligned_header_size =
        IntPtrConstant(FixedTypedArrayBase::kHeaderSize + kObjectAlignmentMask);
    Node* size = IntPtrAdd(word_byte_length, aligned_header_size);
    var_total_size.Bind(WordAnd(size, IntPtrConstant(~kObjectAlignmentMask)));
    Goto(&allocate_elements);
  }

  BIND(&aligned);
  {
    Node* header_size = IntPtrConstant(FixedTypedArrayBase::kHeaderSize);
    var_total_size.Bind(IntPtrAdd(word_byte_length, header_size));
    Goto(&allocate_elements);
  }

  BIND(&allocate_elements);
  {
    // Allocate a FixedTypedArray and set the length, base pointer and external
    // pointer.
    CSA_ASSERT(this, IsRegularHeapObjectSize(var_total_size.value()));

    Node* elements;

    if (UnalignedLoadSupported(MachineRepresentation::kFloat64) &&
        UnalignedStoreSupported(MachineRepresentation::kFloat64)) {
      elements = AllocateInNewSpace(var_total_size.value());
    } else {
      elements = AllocateInNewSpace(var_total_size.value(), kDoubleAlignment);
    }

    StoreMapNoWriteBarrier(elements, fixed_typed_map);
    StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset, length);
    StoreObjectFieldNoWriteBarrier(
        elements, FixedTypedArrayBase::kBasePointerOffset, elements);
    StoreObjectFieldNoWriteBarrier(elements,
                                   FixedTypedArrayBase::kExternalPointerOffset,
                                   IntPtrConstant(fta_base_data_offset),
                                   MachineType::PointerRepresentation());

    StoreObjectField(holder, JSObject::kElementsOffset, elements);

    GotoIf(IsFalse(initialize), &done);
    // Initialize the backing store by filling it with 0s.
    Node* backing_store = IntPtrAdd(BitcastTaggedToWord(elements),
                                    IntPtrConstant(fta_base_data_offset));
    // Call out to memset to perform initialization.
    Node* memset =
        ExternalConstant(ExternalReference::libc_memset_function(isolate()));
    CallCFunction3(MachineType::AnyTagged(), MachineType::Pointer(),
                   MachineType::IntPtr(), MachineType::UintPtr(), memset,
                   backing_store, IntPtrConstant(0), word_byte_length);
    Goto(&done);
  }

  TVARIABLE(JSArrayBuffer, var_buffer);

  BIND(&allocate_off_heap);
  {
    GotoIf(IsFalse(initialize), &allocate_off_heap_no_init);

    Node* buffer_constructor = LoadContextElement(
        LoadNativeContext(context), Context::ARRAY_BUFFER_FUN_INDEX);
    var_buffer = CAST(ConstructJS(CodeFactory::Construct(isolate()), context,
                                  buffer_constructor, byte_length));
    Goto(&attach_buffer);
  }

  BIND(&allocate_off_heap_no_init);
  {
    Node* buffer_constructor_noinit = LoadContextElement(
        LoadNativeContext(context), Context::ARRAY_BUFFER_NOINIT_FUN_INDEX);
    var_buffer = CAST(CallJS(CodeFactory::Call(isolate()), context,
                             buffer_constructor_noinit, UndefinedConstant(),
                             byte_length));
    Goto(&attach_buffer);
  }

  BIND(&attach_buffer);
  {
    AttachBuffer(holder, var_buffer, fixed_typed_map, length, byte_offset);
    Goto(&done);
  }

  BIND(&done);
  Return(UndefinedConstant());
}

// ES6 #sec-typedarray-length
void TypedArrayBuiltinsAssembler::ConstructByLength(TNode<Context> context,
                                                    TNode<JSTypedArray> holder,
                                                    TNode<Object> length,
                                                    TNode<Smi> element_size) {
  CSA_ASSERT(this, TaggedIsPositiveSmi(element_size));

  Label invalid_length(this, Label::kDeferred), done(this);

  TNode<Number> converted_length =
      ToInteger_Inline(context, length, CodeStubAssembler::kTruncateMinusZero);

  // The maximum length of a TypedArray is MaxSmi().
  // Note: this is not per spec, but rather a constraint of our current
  // representation (which uses Smis).
  GotoIf(TaggedIsNotSmi(converted_length), &invalid_length);
  GotoIf(SmiLessThan(converted_length, SmiConstant(0)), &invalid_length);

  Node* initialize = TrueConstant();
  CallBuiltin(Builtins::kTypedArrayInitialize, context, holder,
              converted_length, element_size, initialize);
  Goto(&done);

  BIND(&invalid_length);
  {
    CallRuntime(Runtime::kThrowRangeError, context,
                SmiConstant(MessageTemplate::kInvalidTypedArrayLength),
                converted_length);
    Unreachable();
  }

  BIND(&done);
}

// ES6 #sec-typedarray-buffer-byteoffset-length
void TypedArrayBuiltinsAssembler::ConstructByArrayBuffer(
    TNode<Context> context, TNode<JSTypedArray> holder,
    TNode<JSArrayBuffer> buffer, TNode<Object> byte_offset,
    TNode<Object> length, TNode<Smi> element_size) {
  CSA_ASSERT(this, TaggedIsPositiveSmi(element_size));

  VARIABLE(new_byte_length, MachineRepresentation::kTagged, SmiConstant(0));
  VARIABLE(offset, MachineRepresentation::kTagged, SmiConstant(0));

  Label start_offset_error(this, Label::kDeferred),
      byte_length_error(this, Label::kDeferred),
      invalid_offset_error(this, Label::kDeferred);
  Label offset_is_smi(this), offset_not_smi(this, Label::kDeferred),
      check_length(this), call_init(this), invalid_length(this),
      length_undefined(this), length_defined(this), detached_error(this),
      done(this);

  GotoIf(IsUndefined(byte_offset), &check_length);

  offset.Bind(ToInteger_Inline(context, byte_offset,
                               CodeStubAssembler::kTruncateMinusZero));
  Branch(TaggedIsSmi(offset.value()), &offset_is_smi, &offset_not_smi);

  // Check that the offset is a multiple of the element size.
  BIND(&offset_is_smi);
  {
    GotoIf(SmiEqual(offset.value(), SmiConstant(0)), &check_length);
    GotoIf(SmiLessThan(offset.value(), SmiConstant(0)), &invalid_length);
    Node* remainder = SmiMod(offset.value(), element_size);
    Branch(SmiEqual(remainder, SmiConstant(0)), &check_length,
           &start_offset_error);
  }
  BIND(&offset_not_smi);
  {
    GotoIf(IsTrue(CallBuiltin(Builtins::kLessThan, context, offset.value(),
                              SmiConstant(0))),
           &invalid_length);
    Node* remainder =
        CallBuiltin(Builtins::kModulus, context, offset.value(), element_size);
    // Remainder can be a heap number.
    Branch(IsTrue(CallBuiltin(Builtins::kEqual, context, remainder,
                              SmiConstant(0))),
           &check_length, &start_offset_error);
  }

  BIND(&check_length);
  Branch(IsUndefined(length), &length_undefined, &length_defined);

  BIND(&length_undefined);
  {
    GotoIf(IsDetachedBuffer(buffer), &detached_error);
    Node* buffer_byte_length =
        LoadObjectField(buffer, JSArrayBuffer::kByteLengthOffset);

    Node* remainder = CallBuiltin(Builtins::kModulus, context,
                                  buffer_byte_length, element_size);
    // Remainder can be a heap number.
    GotoIf(IsFalse(CallBuiltin(Builtins::kEqual, context, remainder,
                               SmiConstant(0))),
           &byte_length_error);

    new_byte_length.Bind(CallBuiltin(Builtins::kSubtract, context,
                                     buffer_byte_length, offset.value()));

    Branch(IsTrue(CallBuiltin(Builtins::kLessThan, context,
                              new_byte_length.value(), SmiConstant(0))),
           &invalid_offset_error, &call_init);
  }

  BIND(&length_defined);
  {
    Node* new_length = ToSmiIndex(length, context, &invalid_length);
    GotoIf(IsDetachedBuffer(buffer), &detached_error);
    new_byte_length.Bind(SmiMul(new_length, element_size));
    // Reading the byte length must come after the ToIndex operation, which
    // could cause the buffer to become detached.
    Node* buffer_byte_length =
        LoadObjectField(buffer, JSArrayBuffer::kByteLengthOffset);

    Node* end = CallBuiltin(Builtins::kAdd, context, offset.value(),
                            new_byte_length.value());

    Branch(IsTrue(CallBuiltin(Builtins::kGreaterThan, context, end,
                              buffer_byte_length)),
           &invalid_length, &call_init);
  }

  BIND(&call_init);
  {
    Node* new_length = CallBuiltin(Builtins::kDivide, context,
                                   new_byte_length.value(), element_size);
    // Force the result into a Smi, or throw a range error if it doesn't fit.
    new_length = ToSmiIndex(new_length, context, &invalid_length);

    CallBuiltin(Builtins::kTypedArrayInitializeWithBuffer, context, holder,
                new_length, buffer, element_size, offset.value());
    Goto(&done);
  }

  BIND(&invalid_offset_error);
  {
    CallRuntime(Runtime::kThrowRangeError, context,
                SmiConstant(MessageTemplate::kInvalidOffset), byte_offset);
    Unreachable();
  }

  BIND(&start_offset_error);
  {
    Node* holder_map = LoadMap(holder);
    Node* problem_string = StringConstant("start offset");
    CallRuntime(Runtime::kThrowInvalidTypedArrayAlignment, context, holder_map,
                problem_string);

    Unreachable();
  }

  BIND(&byte_length_error);
  {
    Node* holder_map = LoadMap(holder);
    Node* problem_string = StringConstant("byte length");
    CallRuntime(Runtime::kThrowInvalidTypedArrayAlignment, context, holder_map,
                problem_string);

    Unreachable();
  }

  BIND(&invalid_length);
  {
    CallRuntime(Runtime::kThrowRangeError, context,
                SmiConstant(MessageTemplate::kInvalidTypedArrayLength), length);
    Unreachable();
  }

  BIND(&detached_error);
  { ThrowTypeError(context, MessageTemplate::kDetachedOperation, "Construct"); }

  BIND(&done);
}

void TypedArrayBuiltinsAssembler::ConstructByTypedArray(
    TNode<Context> context, TNode<JSTypedArray> holder,
    TNode<JSTypedArray> typed_array, TNode<Smi> element_size) {
  CSA_ASSERT(this, TaggedIsPositiveSmi(element_size));

  TNode<JSFunction> const default_constructor = CAST(LoadContextElement(
      LoadNativeContext(context), Context::ARRAY_BUFFER_FUN_INDEX));

  Label construct(this), if_detached(this), if_notdetached(this),
      check_for_sab(this), if_buffernotshared(this), check_prototype(this),
      done(this);
  TVARIABLE(JSReceiver, buffer_constructor, default_constructor);

  TNode<JSArrayBuffer> source_buffer = LoadObjectField<JSArrayBuffer>(
      typed_array, JSArrayBufferView::kBufferOffset);
  Branch(IsDetachedBuffer(source_buffer), &if_detached, &if_notdetached);

  // TODO(petermarshall): Throw on detached typedArray.
  TVARIABLE(Smi, source_length);
  BIND(&if_detached);
  source_length = SmiConstant(0);
  Goto(&check_for_sab);

  BIND(&if_notdetached);
  source_length =
      CAST(LoadObjectField(typed_array, JSTypedArray::kLengthOffset));
  Goto(&check_for_sab);

  // The spec requires that constructing a typed array using a SAB-backed typed
  // array use the ArrayBuffer constructor, not the species constructor. See
  // https://tc39.github.io/ecma262/#sec-typedarray-typedarray.
  BIND(&check_for_sab);
  TNode<Uint32T> bitfield =
      LoadObjectField<Uint32T>(source_buffer, JSArrayBuffer::kBitFieldOffset);
  Branch(IsSetWord32<JSArrayBuffer::IsShared>(bitfield), &construct,
         &if_buffernotshared);

  BIND(&if_buffernotshared);
  {
    buffer_constructor =
        CAST(SpeciesConstructor(context, source_buffer, default_constructor));
    // TODO(petermarshall): Throw on detached typedArray.
    GotoIfNot(IsDetachedBuffer(source_buffer), &construct);
    source_length = SmiConstant(0);
    Goto(&construct);
  }

  BIND(&construct);
  {
    ConstructByArrayLike(context, holder, typed_array, source_length,
                         element_size);
    Node* proto =
        GetProperty(context, buffer_constructor, PrototypeStringConstant());
    // TODO(petermarshall): Correct for realm as per 9.1.14 step 4.
    TNode<JSArrayBuffer> buffer = LoadObjectField<JSArrayBuffer>(
        holder, JSArrayBufferView::kBufferOffset);
    CallRuntime(Runtime::kInternalSetPrototype, context, buffer, proto);

    Goto(&done);
  }

  BIND(&done);
}

Node* TypedArrayBuiltinsAssembler::LoadDataPtr(Node* typed_array) {
  CSA_ASSERT(this, IsJSTypedArray(typed_array));
  Node* elements = LoadElements(typed_array);
  CSA_ASSERT(this, IsFixedTypedArray(elements));
  Node* base_pointer = BitcastTaggedToWord(
      LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset));
  Node* external_pointer = BitcastTaggedToWord(
      LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset));
  return IntPtrAdd(base_pointer, external_pointer);
}

TNode<BoolT> TypedArrayBuiltinsAssembler::ByteLengthIsValid(
    TNode<Number> byte_length) {
  Label smi(this), done(this);
  TVARIABLE(BoolT, is_valid);
  GotoIf(TaggedIsSmi(byte_length), &smi);

  TNode<Float64T> float_value = LoadHeapNumberValue(CAST(byte_length));
  TNode<Float64T> max_byte_length_double =
      Float64Constant(FixedTypedArrayBase::kMaxByteLength);
  is_valid = Float64LessThanOrEqual(float_value, max_byte_length_double);
  Goto(&done);

  BIND(&smi);
  TNode<IntPtrT> max_byte_length =
      IntPtrConstant(FixedTypedArrayBase::kMaxByteLength);
  is_valid =
      UintPtrLessThanOrEqual(SmiUntag(CAST(byte_length)), max_byte_length);
  Goto(&done);

  BIND(&done);
  return is_valid;
}

void TypedArrayBuiltinsAssembler::ConstructByArrayLike(
    TNode<Context> context, TNode<JSTypedArray> holder,
    TNode<HeapObject> array_like, TNode<Object> initial_length,
    TNode<Smi> element_size) {
  Node* initialize = FalseConstant();

  Label invalid_length(this), fill(this), fast_copy(this), done(this);

  // The caller has looked up length on array_like, which is observable.
  Node* length = ToSmiLength(initial_length, context, &invalid_length);

  CallBuiltin(Builtins::kTypedArrayInitialize, context, holder, length,
              element_size, initialize);
  GotoIf(SmiNotEqual(length, SmiConstant(0)), &fill);
  Goto(&done);

  BIND(&fill);
  TNode<Int32T> holder_kind = LoadMapElementsKind(LoadMap(holder));
  TNode<Int32T> source_kind = LoadMapElementsKind(LoadMap(array_like));
  GotoIf(Word32Equal(holder_kind, source_kind), &fast_copy);

  // Copy using the elements accessor.
  CallRuntime(Runtime::kTypedArrayCopyElements, context, holder, array_like,
              length);
  Goto(&done);

  BIND(&fast_copy);
  {
    Node* holder_data_ptr = LoadDataPtr(holder);
    Node* source_data_ptr = LoadDataPtr(array_like);

    // Calculate the byte length. We shouldn't be trying to copy if the typed
    // array was neutered.
    CSA_ASSERT(this, SmiNotEqual(length, SmiConstant(0)));
    CSA_ASSERT(this, Word32Equal(IsDetachedBuffer(LoadObjectField(
                                     array_like, JSTypedArray::kBufferOffset)),
                                 Int32Constant(0)));

    TNode<Number> byte_length = SmiMul(length, element_size);
    CSA_ASSERT(this, ByteLengthIsValid(byte_length));
    TNode<UintPtrT> byte_length_intptr =
        ChangeNonnegativeNumberToUintPtr(byte_length);
    CSA_ASSERT(this, UintPtrLessThanOrEqual(
                         byte_length_intptr,
                         IntPtrConstant(FixedTypedArrayBase::kMaxByteLength)));

    Node* memcpy =
        ExternalConstant(ExternalReference::libc_memcpy_function(isolate()));
    CallCFunction3(MachineType::AnyTagged(), MachineType::Pointer(),
                   MachineType::Pointer(), MachineType::UintPtr(), memcpy,
                   holder_data_ptr, source_data_ptr, byte_length_intptr);
    Goto(&done);
  }

  BIND(&invalid_length);
  {
    CallRuntime(Runtime::kThrowRangeError, context,
                SmiConstant(MessageTemplate::kInvalidTypedArrayLength),
                initial_length);
    Unreachable();
  }

  BIND(&done);
}

void TypedArrayBuiltinsAssembler::ConstructByIterable(
    TNode<Context> context, TNode<JSTypedArray> holder,
    TNode<JSReceiver> iterable, TNode<Object> iterator_fn,
    TNode<Smi> element_size) {
  CSA_ASSERT(this, IsCallable(iterator_fn));
  Label fast_path(this), slow_path(this), done(this);

  TVARIABLE(JSReceiver, array_like);
  TVARIABLE(Object, initial_length);

  // This is a fast-path for ignoring the iterator.
  // TODO(petermarshall): Port to CSA.
  Node* elided =
      CallRuntime(Runtime::kIterableToListCanBeElided, context, iterable);
  CSA_ASSERT(this, IsBoolean(elided));
  Branch(IsTrue(elided), &fast_path, &slow_path);

  BIND(&fast_path);
  {
    TNode<JSArray> js_array_iterable = CAST(iterable);
    // This .length access is unobservable, because it being observable would
    // mean that iteration has side effects, and we wouldn't reach this path.
    array_like = js_array_iterable;
    initial_length = LoadJSArrayLength(js_array_iterable);
    Goto(&done);
  }

  BIND(&slow_path);
  {
    IteratorBuiltinsAssembler iterator_assembler(state());

    // 1. Let iteratorRecord be ? GetIterator(items, method).
    IteratorRecord iterator_record =
        iterator_assembler.GetIterator(context, iterable, iterator_fn);

    // 2. Let values be a new empty List.
    GrowableFixedArray values(state());

    Variable* vars[] = {values.var_array(), values.var_length(),
                        values.var_capacity()};
    Label loop_start(this, 3, vars), loop_end(this);
    Goto(&loop_start);
    // 3. Let next be true.
    // 4. Repeat, while next is not false
    BIND(&loop_start);
    {
      //  a. Set next to ? IteratorStep(iteratorRecord).
      TNode<Object> next = CAST(
          iterator_assembler.IteratorStep(context, iterator_record, &loop_end));
      //  b. If next is not false, then
      //   i. Let nextValue be ? IteratorValue(next).
      TNode<Object> next_value =
          CAST(iterator_assembler.IteratorValue(context, next));
      //   ii. Append nextValue to the end of the List values.
      values.Push(next_value);
      Goto(&loop_start);
    }
    BIND(&loop_end);

    // 5. Return values.
    TNode<JSArray> js_array_values = values.ToJSArray(context);
    array_like = js_array_values;
    initial_length = LoadJSArrayLength(js_array_values);
    Goto(&done);
  }

  BIND(&done);
  ConstructByArrayLike(context, holder, array_like, initial_length,
                       element_size);
}

TF_BUILTIN(TypedArrayConstructor, TypedArrayBuiltinsAssembler) {
  TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));

  // If NewTarget is undefined, throw a TypeError exception.
  Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
                               MachineType::TaggedPointer());
  Node* shared = LoadObjectField(target, JSFunction::kSharedFunctionInfoOffset);
  Node* name = LoadObjectField(shared, SharedFunctionInfo::kNameOffset);
  ThrowTypeError(context, MessageTemplate::kConstructorNotFunction, name);
}

TF_BUILTIN(TypedArrayConstructor_ConstructStub, TypedArrayBuiltinsAssembler) {
  Label if_arg1isbuffer(this), if_arg1istypedarray(this),
      if_arg1isreceiver(this), if_arg1isnumber(this), done(this);

  TNode<Object> new_target = CAST(Parameter(BuiltinDescriptor::kNewTarget));
  CSA_ASSERT(this, IsNotUndefined(new_target));

  Node* argc =
      ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
  CodeStubArguments args(this, argc);
  TNode<Object> arg1 = CAST(args.GetOptionalArgumentValue(0));
  TNode<Object> arg2 = CAST(args.GetOptionalArgumentValue(1));
  TNode<Object> arg3 = CAST(args.GetOptionalArgumentValue(2));
  TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));

  Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
                               MachineType::TaggedPointer());
  ConstructorBuiltinsAssembler constructor_assembler(this->state());
  TNode<JSTypedArray> holder = CAST(
      constructor_assembler.EmitFastNewObject(context, target, new_target));

  TNode<Smi> element_size =
      SmiTag(GetTypedArrayElementSize(LoadElementsKind(holder)));

  GotoIf(TaggedIsSmi(arg1), &if_arg1isnumber);
  GotoIf(IsJSArrayBuffer(arg1), &if_arg1isbuffer);
  GotoIf(IsJSTypedArray(arg1), &if_arg1istypedarray);
  GotoIf(IsJSReceiver(arg1), &if_arg1isreceiver);
  Goto(&if_arg1isnumber);

  BIND(&if_arg1isbuffer);
  ConstructByArrayBuffer(context, holder, CAST(arg1), arg2, arg3, element_size);
  Goto(&done);

  BIND(&if_arg1istypedarray);
  TNode<JSTypedArray> typed_array = CAST(arg1);
  ConstructByTypedArray(context, holder, typed_array, element_size);
  Goto(&done);

  BIND(&if_arg1isreceiver);
  {
    Label if_iteratorundefined(this), if_iteratornotcallable(this);
    // Get iterator symbol
    TNode<Object> iteratorFn =
        CAST(GetMethod(context, arg1, isolate()->factory()->iterator_symbol(),
                       &if_iteratorundefined));
    GotoIf(TaggedIsSmi(iteratorFn), &if_iteratornotcallable);
    GotoIfNot(IsCallable(iteratorFn), &if_iteratornotcallable);

    ConstructByIterable(context, holder, CAST(arg1), iteratorFn, element_size);
    Goto(&done);

    BIND(&if_iteratorundefined);
    {
      TNode<HeapObject> array_like = CAST(arg1);
      TNode<Object> initial_length =
          CAST(GetProperty(context, arg1, LengthStringConstant()));

      ConstructByArrayLike(context, holder, array_like, initial_length,
                           element_size);
      Goto(&done);
    }

    BIND(&if_iteratornotcallable);
    { ThrowTypeError(context, MessageTemplate::kIteratorSymbolNonCallable); }
  }

  // First arg was a number or fell through and will be treated as a number.
  BIND(&if_arg1isnumber);
  ConstructByLength(context, holder, arg1, element_size);
  Goto(&done);

  BIND(&done);
  args.PopAndReturn(holder);
}

void TypedArrayBuiltinsAssembler::GenerateTypedArrayPrototypeGetter(
    Node* context, Node* receiver, const char* method_name, int object_offset) {
  // Check if the {receiver} is actually a JSTypedArray.
  Label receiver_is_incompatible(this, Label::kDeferred);
  GotoIf(TaggedIsSmi(receiver), &receiver_is_incompatible);
  GotoIfNot(HasInstanceType(receiver, JS_TYPED_ARRAY_TYPE),
            &receiver_is_incompatible);

  // Check if the {receiver}'s JSArrayBuffer was neutered.
  Node* receiver_buffer =
      LoadObjectField(receiver, JSTypedArray::kBufferOffset);
  Label if_receiverisneutered(this, Label::kDeferred);
  GotoIf(IsDetachedBuffer(receiver_buffer), &if_receiverisneutered);
  Return(LoadObjectField(receiver, object_offset));

  BIND(&if_receiverisneutered);
  {
    // The {receiver}s buffer was neutered, default to zero.
    Return(SmiConstant(0));
  }

  BIND(&receiver_is_incompatible);
  {
    // The {receiver} is not a valid JSTypedArray.
    CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context,
                StringConstant(method_name), receiver);
    Unreachable();
  }
}

// ES6 #sec-get-%typedarray%.prototype.bytelength
TF_BUILTIN(TypedArrayPrototypeByteLength, TypedArrayBuiltinsAssembler) {
  Node* context = Parameter(Descriptor::kContext);
  Node* receiver = Parameter(Descriptor::kReceiver);
  GenerateTypedArrayPrototypeGetter(context, receiver,
                                    "get TypedArray.prototype.byteLength",
                                    JSTypedArray::kByteLengthOffset);
}

// ES6 #sec-get-%typedarray%.prototype.byteoffset
TF_BUILTIN(TypedArrayPrototypeByteOffset, TypedArrayBuiltinsAssembler) {
  Node* context = Parameter(Descriptor::kContext);
  Node* receiver = Parameter(Descriptor::kReceiver);
  GenerateTypedArrayPrototypeGetter(context, receiver,
                                    "get TypedArray.prototype.byteOffset",
                                    JSTypedArray::kByteOffsetOffset);
}

// ES6 #sec-get-%typedarray%.prototype.length
TF_BUILTIN(TypedArrayPrototypeLength, TypedArrayBuiltinsAssembler) {
  Node* context = Parameter(Descriptor::kContext);
  Node* receiver = Parameter(Descriptor::kReceiver);
  GenerateTypedArrayPrototypeGetter(context, receiver,
                                    "get TypedArray.prototype.length",
                                    JSTypedArray::kLengthOffset);
}

TNode<Word32T> TypedArrayBuiltinsAssembler::IsUint8ElementsKind(
    TNode<Word32T> kind) {
  return Word32Or(Word32Equal(kind, Int32Constant(UINT8_ELEMENTS)),
                  Word32Equal(kind, Int32Constant(UINT8_CLAMPED_ELEMENTS)));
}

TNode<Word32T> TypedArrayBuiltinsAssembler::LoadElementsKind(
    TNode<Object> typed_array) {
  CSA_ASSERT(this, IsJSTypedArray(typed_array));
  return LoadMapElementsKind(LoadMap(CAST(typed_array)));
}

TNode<IntPtrT> TypedArrayBuiltinsAssembler::GetTypedArrayElementSize(
    TNode<Word32T> elements_kind) {
  TVARIABLE(IntPtrT, element_size);

  DispatchTypedArrayByElementsKind(
      elements_kind,
      [&](ElementsKind el_kind, int size, int typed_array_fun_index) {
        element_size = IntPtrConstant(size);
      });

  return element_size;
}

TNode<Object> TypedArrayBuiltinsAssembler::GetDefaultConstructor(
    TNode<Context> context, TNode<JSTypedArray> exemplar) {
  TVARIABLE(IntPtrT, context_slot);
  TNode<Word32T> elements_kind = LoadElementsKind(exemplar);

  DispatchTypedArrayByElementsKind(
      elements_kind,
      [&](ElementsKind el_kind, int size, int typed_array_function_index) {
        context_slot = IntPtrConstant(typed_array_function_index);
      });

  return LoadContextElement(LoadNativeContext(context), context_slot);
}

TNode<Object> TypedArrayBuiltinsAssembler::TypedArraySpeciesConstructor(
    TNode<Context> context, TNode<JSTypedArray> exemplar) {
  TVARIABLE(Object, var_constructor);
  Label slow(this), done(this);

  // Let defaultConstructor be the intrinsic object listed in column one of
  // Table 52 for exemplar.[[TypedArrayName]].
  TNode<Object> default_constructor = GetDefaultConstructor(context, exemplar);

  var_constructor = default_constructor;
  Node* map = LoadMap(exemplar);
  GotoIfNot(IsPrototypeTypedArrayPrototype(context, map), &slow);
  Branch(IsSpeciesProtectorCellInvalid(), &slow, &done);

  BIND(&slow);
  var_constructor =
      CAST(SpeciesConstructor(context, exemplar, default_constructor));
  Goto(&done);

  BIND(&done);
  return var_constructor;
}

TNode<JSTypedArray> TypedArrayBuiltinsAssembler::SpeciesCreateByArrayBuffer(
    TNode<Context> context, TNode<JSTypedArray> exemplar,
    TNode<JSArrayBuffer> buffer, TNode<Number> byte_offset, TNode<Smi> len,
    const char* method_name) {
  // Let constructor be ? SpeciesConstructor(exemplar, defaultConstructor).
  TNode<Object> constructor = TypedArraySpeciesConstructor(context, exemplar);

  // Let newTypedArray be ? Construct(constructor, argumentList).
  TNode<Object> new_object =
      CAST(ConstructJS(CodeFactory::Construct(isolate()), context, constructor,
                       buffer, byte_offset, len));

  // Perform ? ValidateTypedArray(newTypedArray).
  return ValidateTypedArray(context, new_object, method_name);
}

TNode<JSTypedArray> TypedArrayBuiltinsAssembler::SpeciesCreateByLength(
    TNode<Context> context, TNode<JSTypedArray> exemplar, TNode<Smi> len,
    const char* method_name) {
  CSA_ASSERT(this, TaggedIsPositiveSmi(len));

  // Let constructor be ? SpeciesConstructor(exemplar, defaultConstructor).
  TNode<Object> constructor = TypedArraySpeciesConstructor(context, exemplar);
  CSA_ASSERT(this, IsJSFunction(constructor));

  return CreateByLength(context, constructor, len, method_name);
}

TNode<JSTypedArray> TypedArrayBuiltinsAssembler::CreateByLength(
    TNode<Context> context, TNode<Object> constructor, TNode<Smi> len,
    const char* method_name) {
  // Let newTypedArray be ? Construct(constructor, argumentList).
  TNode<Object> new_object = CAST(ConstructJS(CodeFactory::Construct(isolate()),
                                              context, constructor, len));

  // Perform ? ValidateTypedArray(newTypedArray).
  TNode<JSTypedArray> new_typed_array =
      ValidateTypedArray(context, new_object, method_name);

  // If newTypedArray.[[ArrayLength]] < argumentList[0], throw a TypeError
  // exception.
  Label if_length_is_not_short(this);
  TNode<Smi> new_length =
      LoadObjectField<Smi>(new_typed_array, JSTypedArray::kLengthOffset);
  GotoIfNot(SmiLessThan(new_length, len), &if_length_is_not_short);
  ThrowTypeError(context, MessageTemplate::kNotTypedArray);

  BIND(&if_length_is_not_short);
  return new_typed_array;
}

TNode<JSArrayBuffer> TypedArrayBuiltinsAssembler::GetBuffer(
    TNode<Context> context, TNode<JSTypedArray> array) {
  Label call_runtime(this), done(this);
  TVARIABLE(Object, var_result);

  TNode<Object> buffer = LoadObjectField(array, JSTypedArray::kBufferOffset);
  GotoIf(IsDetachedBuffer(buffer), &call_runtime);
  TNode<UintPtrT> backing_store = LoadObjectField<UintPtrT>(
      CAST(buffer), JSArrayBuffer::kBackingStoreOffset);
  GotoIf(WordEqual(backing_store, IntPtrConstant(0)), &call_runtime);
  var_result = buffer;
  Goto(&done);

  BIND(&call_runtime);
  {
    var_result = CallRuntime(Runtime::kTypedArrayGetBuffer, context, array);
    Goto(&done);
  }

  BIND(&done);
  return CAST(var_result);
}

TNode<JSTypedArray> TypedArrayBuiltinsAssembler::ValidateTypedArray(
    TNode<Context> context, TNode<Object> obj, const char* method_name) {
  Label validation_done(this);

  // If it is not a typed array, throw
  ThrowIfNotInstanceType(context, obj, JS_TYPED_ARRAY_TYPE, method_name);

  // If the typed array's buffer is detached, throw
  TNode<Object> buffer =
      LoadObjectField(CAST(obj), JSTypedArray::kBufferOffset);
  GotoIfNot(IsDetachedBuffer(buffer), &validation_done);
  ThrowTypeError(context, MessageTemplate::kDetachedOperation, method_name);

  BIND(&validation_done);
  return CAST(obj);
}

void TypedArrayBuiltinsAssembler::SetTypedArraySource(
    TNode<Context> context, TNode<JSTypedArray> source,
    TNode<JSTypedArray> target, TNode<IntPtrT> offset, Label* call_runtime,
    Label* if_source_too_large) {
  CSA_ASSERT(this, Word32BinaryNot(IsDetachedBuffer(
                       LoadObjectField(source, JSTypedArray::kBufferOffset))));
  CSA_ASSERT(this, Word32BinaryNot(IsDetachedBuffer(
                       LoadObjectField(target, JSTypedArray::kBufferOffset))));
  CSA_ASSERT(this, IntPtrGreaterThanOrEqual(offset, IntPtrConstant(0)));
  CSA_ASSERT(this,
             IntPtrLessThanOrEqual(offset, IntPtrConstant(Smi::kMaxValue)));

  // Check for possible range errors.

  TNode<IntPtrT> source_length =
      LoadAndUntagObjectField(source, JSTypedArray::kLengthOffset);
  TNode<IntPtrT> target_length =
      LoadAndUntagObjectField(target, JSTypedArray::kLengthOffset);
  TNode<IntPtrT> required_target_length = IntPtrAdd(source_length, offset);

  GotoIf(IntPtrGreaterThan(required_target_length, target_length),
         if_source_too_large);

  // Grab pointers and byte lengths we need later on.

  TNode<IntPtrT> target_data_ptr = UncheckedCast<IntPtrT>(LoadDataPtr(target));
  TNode<IntPtrT> source_data_ptr = UncheckedCast<IntPtrT>(LoadDataPtr(source));

  TNode<Word32T> source_el_kind = LoadElementsKind(source);
  TNode<Word32T> target_el_kind = LoadElementsKind(target);

  TNode<IntPtrT> source_el_size = GetTypedArrayElementSize(source_el_kind);
  TNode<IntPtrT> target_el_size = GetTypedArrayElementSize(target_el_kind);

  // A note on byte lengths: both source- and target byte lengths must be valid,
  // i.e. it must be possible to allocate an array of the given length. That
  // means we're safe from overflows in the following multiplication.
  TNode<IntPtrT> source_byte_length = IntPtrMul(source_length, source_el_size);
  CSA_ASSERT(this,
             UintPtrGreaterThanOrEqual(source_byte_length, IntPtrConstant(0)));

  Label call_memmove(this), fast_c_call(this), out(this);

  // A fast memmove call can be used when the source and target types are are
  // the same or either Uint8 or Uint8Clamped.
  GotoIf(Word32Equal(source_el_kind, target_el_kind), &call_memmove);
  GotoIfNot(IsUint8ElementsKind(source_el_kind), &fast_c_call);
  Branch(IsUint8ElementsKind(target_el_kind), &call_memmove, &fast_c_call);

  BIND(&call_memmove);
  {
    TNode<IntPtrT> target_start =
        IntPtrAdd(target_data_ptr, IntPtrMul(offset, target_el_size));
    CallCMemmove(target_start, source_data_ptr, source_byte_length);
    Goto(&out);
  }

  BIND(&fast_c_call);
  {
    CSA_ASSERT(
        this, UintPtrGreaterThanOrEqual(
                  IntPtrMul(target_length, target_el_size), IntPtrConstant(0)));

    TNode<IntPtrT> source_length =
        LoadAndUntagObjectField(source, JSTypedArray::kLengthOffset);
    CallCCopyTypedArrayElementsToTypedArray(source, target, source_length,
                                            offset);
    Goto(&out);
  }

  BIND(&out);
}

void TypedArrayBuiltinsAssembler::SetJSArraySource(
    TNode<Context> context, TNode<JSArray> source, TNode<JSTypedArray> target,
    TNode<IntPtrT> offset, Label* call_runtime, Label* if_source_too_large) {
  CSA_ASSERT(this, IsFastJSArray(source, context));
  CSA_ASSERT(this, IntPtrGreaterThanOrEqual(offset, IntPtrConstant(0)));
  CSA_ASSERT(this,
             IntPtrLessThanOrEqual(offset, IntPtrConstant(Smi::kMaxValue)));

  TNode<IntPtrT> source_length = SmiUntag(LoadFastJSArrayLength(source));
  TNode<IntPtrT> target_length =
      LoadAndUntagObjectField(target, JSTypedArray::kLengthOffset);

  // Maybe out of bounds?
  GotoIf(IntPtrGreaterThan(IntPtrAdd(source_length, offset), target_length),
         if_source_too_large);

  // Nothing to do if {source} is empty.
  Label out(this), fast_c_call(this);
  GotoIf(IntPtrEqual(source_length, IntPtrConstant(0)), &out);

  // Dispatch based on the source elements kind.
  {
    // These are the supported elements kinds in TryCopyElementsFastNumber.
    int32_t values[] = {
        PACKED_SMI_ELEMENTS, HOLEY_SMI_ELEMENTS, PACKED_DOUBLE_ELEMENTS,
        HOLEY_DOUBLE_ELEMENTS,
    };
    Label* labels[] = {
        &fast_c_call, &fast_c_call, &fast_c_call, &fast_c_call,
    };
    STATIC_ASSERT(arraysize(values) == arraysize(labels));

    TNode<Int32T> source_elements_kind = LoadMapElementsKind(LoadMap(source));
    Switch(source_elements_kind, call_runtime, values, labels,
           arraysize(values));
  }

  BIND(&fast_c_call);
  CallCCopyFastNumberJSArrayElementsToTypedArray(context, source, target,
                                                 source_length, offset);
  Goto(&out);
  BIND(&out);
}

void TypedArrayBuiltinsAssembler::CallCMemmove(TNode<IntPtrT> dest_ptr,
                                               TNode<IntPtrT> src_ptr,
                                               TNode<IntPtrT> byte_length) {
  TNode<ExternalReference> memmove =
      ExternalConstant(ExternalReference::libc_memmove_function(isolate()));
  CallCFunction3(MachineType::AnyTagged(), MachineType::Pointer(),
                 MachineType::Pointer(), MachineType::UintPtr(), memmove,
                 dest_ptr, src_ptr, byte_length);
}

void TypedArrayBuiltinsAssembler::
    CallCCopyFastNumberJSArrayElementsToTypedArray(TNode<Context> context,
                                                   TNode<JSArray> source,
                                                   TNode<JSTypedArray> dest,
                                                   TNode<IntPtrT> source_length,
                                                   TNode<IntPtrT> offset) {
  TNode<ExternalReference> f = ExternalConstant(
      ExternalReference::copy_fast_number_jsarray_elements_to_typed_array(
          isolate()));
  CallCFunction5(MachineType::AnyTagged(), MachineType::AnyTagged(),
                 MachineType::AnyTagged(), MachineType::AnyTagged(),
                 MachineType::UintPtr(), MachineType::UintPtr(), f, context,
                 source, dest, source_length, offset);
}

void TypedArrayBuiltinsAssembler::CallCCopyTypedArrayElementsToTypedArray(
    TNode<JSTypedArray> source, TNode<JSTypedArray> dest,
    TNode<IntPtrT> source_length, TNode<IntPtrT> offset) {
  TNode<ExternalReference> f = ExternalConstant(
      ExternalReference::copy_typed_array_elements_to_typed_array(isolate()));
  CallCFunction4(MachineType::AnyTagged(), MachineType::AnyTagged(),
                 MachineType::AnyTagged(), MachineType::UintPtr(),
                 MachineType::UintPtr(), f, source, dest, source_length,
                 offset);
}

void TypedArrayBuiltinsAssembler::DispatchTypedArrayByElementsKind(
    TNode<Word32T> elements_kind, const TypedArraySwitchCase& case_function) {
  Label next(this), if_unknown_type(this, Label::kDeferred);

  int32_t elements_kinds[] = {
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) TYPE##_ELEMENTS,
      TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
  };

#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
  Label if_##type##array(this);
  TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE

  Label* elements_kind_labels[] = {
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) &if_##type##array,
      TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
  };
  STATIC_ASSERT(arraysize(elements_kinds) == arraysize(elements_kind_labels));

  Switch(elements_kind, &if_unknown_type, elements_kinds, elements_kind_labels,
         arraysize(elements_kinds));

#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                    \
  BIND(&if_##type##array);                                                 \
  {                                                                        \
    case_function(TYPE##_ELEMENTS, size, Context::TYPE##_ARRAY_FUN_INDEX); \
    Goto(&next);                                                           \
  }
  TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE

  BIND(&if_unknown_type);
  Unreachable();

  BIND(&next);
}

// ES #sec-get-%typedarray%.prototype.set
TF_BUILTIN(TypedArrayPrototypeSet, TypedArrayBuiltinsAssembler) {
  TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
  CodeStubArguments args(
      this, ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount)));

  Label if_source_is_typed_array(this), if_source_is_fast_jsarray(this),
      if_offset_is_out_of_bounds(this, Label::kDeferred),
      if_source_too_large(this, Label::kDeferred),
      if_typed_array_is_neutered(this, Label::kDeferred),
      if_receiver_is_not_typedarray(this, Label::kDeferred);

  // Check the receiver is a typed array.
  TNode<Object> receiver = args.GetReceiver();
  GotoIf(TaggedIsSmi(receiver), &if_receiver_is_not_typedarray);
  GotoIfNot(IsJSTypedArray(receiver), &if_receiver_is_not_typedarray);

  // Normalize offset argument (using ToInteger) and handle heap number cases.
  TNode<Object> offset = args.GetOptionalArgumentValue(1, SmiConstant(0));
  TNode<Number> offset_num =
      ToInteger_Inline(context, offset, kTruncateMinusZero);

  // Since ToInteger always returns a Smi if the given value is within Smi
  // range, and the only corner case of -0.0 has already been truncated to 0.0,
  // we can simply throw unless the offset is a non-negative Smi.
  // TODO(jgruber): It's an observable spec violation to throw here if
  // {offset_num} is a positive number outside the Smi range. Per spec, we need
  // to check for detached buffers and call the observable ToObject/ToLength
  // operations first.
  GotoIfNot(TaggedIsPositiveSmi(offset_num), &if_offset_is_out_of_bounds);
  TNode<Smi> offset_smi = CAST(offset_num);

  // Check the receiver is not neutered.
  TNode<Object> receiver_buffer =
      LoadObjectField(CAST(receiver), JSTypedArray::kBufferOffset);
  GotoIf(IsDetachedBuffer(receiver_buffer), &if_typed_array_is_neutered);

  // Check the source argument is valid and whether a fast path can be taken.
  Label call_runtime(this);
  TNode<Object> source = args.GetOptionalArgumentValue(0);
  GotoIf(TaggedIsSmi(source), &call_runtime);
  GotoIf(IsJSTypedArray(source), &if_source_is_typed_array);
  BranchIfFastJSArray(source, context, &if_source_is_fast_jsarray,
                      &call_runtime);

  // Fast path for a typed array source argument.
  BIND(&if_source_is_typed_array);
  {
    // Check the source argument is not neutered.
    TNode<Object> source_buffer =
        LoadObjectField(CAST(source), JSTypedArray::kBufferOffset);
    GotoIf(IsDetachedBuffer(source_buffer), &if_typed_array_is_neutered);

    SetTypedArraySource(context, CAST(source), CAST(receiver),
                        SmiUntag(offset_smi), &call_runtime,
                        &if_source_too_large);
    args.PopAndReturn(UndefinedConstant());
  }

  // Fast path for a fast JSArray source argument.
  BIND(&if_source_is_fast_jsarray);
  {
    SetJSArraySource(context, CAST(source), CAST(receiver),
                     SmiUntag(offset_smi), &call_runtime, &if_source_too_large);
    args.PopAndReturn(UndefinedConstant());
  }

  BIND(&call_runtime);
  args.PopAndReturn(CallRuntime(Runtime::kTypedArraySet, context, receiver,
                                source, offset_smi));

  BIND(&if_offset_is_out_of_bounds);
  ThrowRangeError(context, MessageTemplate::kTypedArraySetOffsetOutOfBounds);

  BIND(&if_source_too_large);
  ThrowRangeError(context, MessageTemplate::kTypedArraySetSourceTooLarge);

  BIND(&if_typed_array_is_neutered);
  ThrowTypeError(context, MessageTemplate::kDetachedOperation,
                 "%TypedArray%.prototype.set");

  BIND(&if_receiver_is_not_typedarray);
  ThrowTypeError(context, MessageTemplate::kNotTypedArray);
}

// ES %TypedArray%.prototype.slice
TF_BUILTIN(TypedArrayPrototypeSlice, TypedArrayBuiltinsAssembler) {
  const char* method_name = "%TypedArray%.prototype.slice";
  Label call_runtime(this), call_memmove(this), if_count_is_not_zero(this),
      if_typed_array_is_neutered(this, Label::kDeferred);

  TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
  CodeStubArguments args(
      this, ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount)));

  TNode<Object> receiver = args.GetReceiver();
  TNode<JSTypedArray> source =
      ValidateTypedArray(context, receiver, method_name);

  TNode<Smi> source_length =
      LoadObjectField<Smi>(source, JSTypedArray::kLengthOffset);

  // Convert start offset argument to integer, and calculate relative offset.
  TNode<Object> start = args.GetOptionalArgumentValue(0, SmiConstant(0));
  TNode<Smi> start_index =
      ConvertToRelativeIndex(context, start, source_length);

  // Convert end offset argument to integer, and calculate relative offset.
  // If end offset is not given or undefined is given, set source_length to
  // "end_index".
  TNode<Object> end = args.GetOptionalArgumentValue(1, UndefinedConstant());
  TNode<Smi> end_index = Select<Smi>(
      IsUndefined(end), [=] { return source_length; },
      [=] { return ConvertToRelativeIndex(context, end, source_length); },
      MachineRepresentation::kTagged);

  // Create a result array by invoking TypedArraySpeciesCreate.
  TNode<Smi> count = SmiMax(SmiSub(end_index, start_index), SmiConstant(0));
  TNode<JSTypedArray> result_array =
      SpeciesCreateByLength(context, source, count, method_name);

  // If count is zero, return early.
  GotoIf(SmiGreaterThan(count, SmiConstant(0)), &if_count_is_not_zero);
  args.PopAndReturn(result_array);

  BIND(&if_count_is_not_zero);
  // Check the source array is neutered or not. We don't need to check if the
  // result array is neutered or not since TypedArraySpeciesCreate checked it.
  CSA_ASSERT(this, Word32BinaryNot(IsDetachedBuffer(LoadObjectField(
                       result_array, JSTypedArray::kBufferOffset))));
  TNode<Object> receiver_buffer =
      LoadObjectField(CAST(receiver), JSTypedArray::kBufferOffset);
  GotoIf(IsDetachedBuffer(receiver_buffer), &if_typed_array_is_neutered);

  // result_array could be a different type from source or share the same
  // buffer with the source because of custom species constructor.
  // If the types of source and result array are the same and they are not
  // sharing the same buffer, use memmove.
  TNode<Word32T> source_el_kind = LoadElementsKind(source);
  TNode<Word32T> target_el_kind = LoadElementsKind(result_array);
  GotoIfNot(Word32Equal(source_el_kind, target_el_kind), &call_runtime);

  TNode<Object> target_buffer =
      LoadObjectField(result_array, JSTypedArray::kBufferOffset);
  Branch(WordEqual(receiver_buffer, target_buffer), &call_runtime,
         &call_memmove);

  BIND(&call_memmove);
  {
    GotoIfForceSlowPath(&call_runtime);

    TNode<IntPtrT> target_data_ptr =
        UncheckedCast<IntPtrT>(LoadDataPtr(result_array));
    TNode<IntPtrT> source_data_ptr =
        UncheckedCast<IntPtrT>(LoadDataPtr(source));

    TNode<IntPtrT> source_el_size = GetTypedArrayElementSize(source_el_kind);
    TNode<IntPtrT> source_start_bytes =
        IntPtrMul(SmiToWord(start_index), source_el_size);
    TNode<IntPtrT> source_start =
        IntPtrAdd(source_data_ptr, source_start_bytes);

    TNode<IntPtrT> count_bytes = IntPtrMul(SmiToWord(count), source_el_size);

#ifdef DEBUG
    TNode<IntPtrT> target_byte_length =
        LoadAndUntagObjectField(result_array, JSTypedArray::kByteLengthOffset);
    CSA_ASSERT(this, IntPtrLessThanOrEqual(count_bytes, target_byte_length));

    TNode<IntPtrT> source_byte_length =
        LoadAndUntagObjectField(source, JSTypedArray::kByteLengthOffset);
    TNode<IntPtrT> source_size_in_bytes =
        IntPtrSub(source_byte_length, source_start_bytes);
    CSA_ASSERT(this, IntPtrLessThanOrEqual(count_bytes, source_size_in_bytes));
#endif  // DEBUG

    CallCMemmove(target_data_ptr, source_start, count_bytes);
    args.PopAndReturn(result_array);
  }

  BIND(&call_runtime);
  args.PopAndReturn(CallRuntime(Runtime::kTypedArraySlice, context, source,
                                start_index, end_index, result_array));

  BIND(&if_typed_array_is_neutered);
  ThrowTypeError(context, MessageTemplate::kDetachedOperation, method_name);
}

// ES %TypedArray%.prototype.subarray
TF_BUILTIN(TypedArrayPrototypeSubArray, TypedArrayBuiltinsAssembler) {
  const char* method_name = "%TypedArray%.prototype.subarray";
  Label offset_done(this);

  TVARIABLE(Smi, var_begin);
  TVARIABLE(Smi, var_end);

  TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
  CodeStubArguments args(
      this, ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount)));

  // 1. Let O be the this value.
  // 3. If O does not have a [[TypedArrayName]] internal slot, throw a TypeError
  // exception.
  TNode<Object> receiver = args.GetReceiver();
  ThrowIfNotInstanceType(context, receiver, JS_TYPED_ARRAY_TYPE, method_name);

  TNode<JSTypedArray> source = CAST(receiver);

  // 5. Let buffer be O.[[ViewedArrayBuffer]].
  TNode<JSArrayBuffer> buffer = GetBuffer(context, source);
  // 6. Let srcLength be O.[[ArrayLength]].
  TNode<Smi> source_length =
      LoadObjectField<Smi>(source, JSTypedArray::kLengthOffset);

  // 7. Let relativeBegin be ? ToInteger(begin).
  // 8. If relativeBegin < 0, let beginIndex be max((srcLength + relativeBegin),
  // 0); else let beginIndex be min(relativeBegin, srcLength).
  TNode<Object> begin = args.GetOptionalArgumentValue(0, SmiConstant(0));
  var_begin = ConvertToRelativeIndex(context, begin, source_length);

  TNode<Object> end = args.GetOptionalArgumentValue(1, UndefinedConstant());
  // 9. If end is undefined, let relativeEnd be srcLength;
  var_end = source_length;
  GotoIf(IsUndefined(end), &offset_done);

  // else, let relativeEnd be ? ToInteger(end).
  // 10. If relativeEnd < 0, let endIndex be max((srcLength + relativeEnd), 0);
  // else let endIndex be min(relativeEnd, srcLength).
  var_end = ConvertToRelativeIndex(context, end, source_length);
  Goto(&offset_done);

  BIND(&offset_done);

  // 11. Let newLength be max(endIndex - beginIndex, 0).
  TNode<Smi> new_length = SmiMax(SmiSub(var_end, var_begin), SmiConstant(0));

  // 12. Let constructorName be the String value of O.[[TypedArrayName]].
  // 13. Let elementSize be the Number value of the Element Size value specified
  // in Table 52 for constructorName.
  TNode<Word32T> element_kind = LoadElementsKind(source);
  TNode<IntPtrT> element_size = GetTypedArrayElementSize(element_kind);

  // 14. Let srcByteOffset be O.[[ByteOffset]].
  TNode<Number> source_byte_offset =
      LoadObjectField<Number>(source, JSTypedArray::kByteOffsetOffset);

  // 15. Let beginByteOffset be srcByteOffset + beginIndex × elementSize.
  TNode<Number> offset = SmiMul(var_begin, SmiFromWord(element_size));
  TNode<Number> begin_byte_offset = CAST(NumberAdd(source_byte_offset, offset));

  // 16. Let argumentsList be « buffer, beginByteOffset, newLength ».
  // 17. Return ? TypedArraySpeciesCreate(O, argumentsList).
  args.PopAndReturn(SpeciesCreateByArrayBuffer(
      context, source, buffer, begin_byte_offset, new_length, method_name));
}

// ES #sec-get-%typedarray%.prototype-@@tostringtag
TF_BUILTIN(TypedArrayPrototypeToStringTag, TypedArrayBuiltinsAssembler) {
  Node* receiver = Parameter(Descriptor::kReceiver);
  Label if_receiverisheapobject(this), return_undefined(this);
  Branch(TaggedIsSmi(receiver), &return_undefined, &if_receiverisheapobject);

  // Dispatch on the elements kind, offset by
  // FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND.
  size_t const kTypedElementsKindCount = LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND -
                                         FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND +
                                         1;
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
  Label return_##type##array(this);                     \
  BIND(&return_##type##array);                          \
  Return(StringConstant(#Type "Array"));
  TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
  Label* elements_kind_labels[kTypedElementsKindCount] = {
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) &return_##type##array,
      TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
  };
  int32_t elements_kinds[kTypedElementsKindCount] = {
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
  TYPE##_ELEMENTS - FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND,
      TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
  };

  // We offset the dispatch by FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND, so
  // that this can be turned into a non-sparse table switch for ideal
  // performance.
  BIND(&if_receiverisheapobject);
  Node* elements_kind =
      Int32Sub(LoadMapElementsKind(LoadMap(receiver)),
               Int32Constant(FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND));
  Switch(elements_kind, &return_undefined, elements_kinds, elements_kind_labels,
         kTypedElementsKindCount);

  BIND(&return_undefined);
  Return(UndefinedConstant());
}

void TypedArrayBuiltinsAssembler::GenerateTypedArrayPrototypeIterationMethod(
    Node* context, Node* receiver, const char* method_name,
    IterationKind iteration_kind) {
  Label throw_bad_receiver(this, Label::kDeferred);
  Label throw_typeerror(this, Label::kDeferred);

  GotoIf(TaggedIsSmi(receiver), &throw_bad_receiver);

  Node* map = LoadMap(receiver);
  Node* instance_type = LoadMapInstanceType(map);
  GotoIfNot(InstanceTypeEqual(instance_type, JS_TYPED_ARRAY_TYPE),
            &throw_bad_receiver);

  // Check if the {receiver}'s JSArrayBuffer was neutered.
  Node* receiver_buffer =
      LoadObjectField(receiver, JSTypedArray::kBufferOffset);
  Label if_receiverisneutered(this, Label::kDeferred);
  GotoIf(IsDetachedBuffer(receiver_buffer), &if_receiverisneutered);

  Return(CreateArrayIterator(receiver, map, instance_type, context,
                             iteration_kind));

  VARIABLE(var_message, MachineRepresentation::kTagged);
  BIND(&throw_bad_receiver);
  var_message.Bind(SmiConstant(MessageTemplate::kNotTypedArray));
  Goto(&throw_typeerror);

  BIND(&if_receiverisneutered);
  var_message.Bind(SmiConstant(MessageTemplate::kDetachedOperation));
  Goto(&throw_typeerror);

  BIND(&throw_typeerror);
  {
    Node* method_arg = StringConstant(method_name);
    Node* result = CallRuntime(Runtime::kThrowTypeError, context,
                               var_message.value(), method_arg);
    Return(result);
  }
}

// ES6 #sec-%typedarray%.prototype.values
TF_BUILTIN(TypedArrayPrototypeValues, TypedArrayBuiltinsAssembler) {
  Node* context = Parameter(Descriptor::kContext);
  Node* receiver = Parameter(Descriptor::kReceiver);
  GenerateTypedArrayPrototypeIterationMethod(context, receiver,
                                             "%TypedArray%.prototype.values()",
                                             IterationKind::kValues);
}

// ES6 #sec-%typedarray%.prototype.entries
TF_BUILTIN(TypedArrayPrototypeEntries, TypedArrayBuiltinsAssembler) {
  Node* context = Parameter(Descriptor::kContext);
  Node* receiver = Parameter(Descriptor::kReceiver);
  GenerateTypedArrayPrototypeIterationMethod(context, receiver,
                                             "%TypedArray%.prototype.entries()",
                                             IterationKind::kEntries);
}

// ES6 #sec-%typedarray%.prototype.keys
TF_BUILTIN(TypedArrayPrototypeKeys, TypedArrayBuiltinsAssembler) {
  Node* context = Parameter(Descriptor::kContext);
  Node* receiver = Parameter(Descriptor::kReceiver);
  GenerateTypedArrayPrototypeIterationMethod(
      context, receiver, "%TypedArray%.prototype.keys()", IterationKind::kKeys);
}

void TypedArrayBuiltinsAssembler::DebugSanityCheckTypedArrayIndex(
    TNode<JSTypedArray> array, SloppyTNode<Smi> index) {
#ifdef DEBUG
  TNode<JSArrayBuffer> buffer =
      LoadObjectField<JSArrayBuffer>(array, JSArrayBufferView::kBufferOffset);
  CSA_ASSERT(this, Word32BinaryNot(IsDetachedBuffer(buffer)));
  TNode<Smi> array_length =
      LoadObjectField<Smi>(array, JSTypedArray::kLengthOffset);
  CSA_ASSERT(this, SmiLessThan(index, array_length));
#endif
}

// ES6 #sec-%typedarray%.of
TF_BUILTIN(TypedArrayOf, TypedArrayBuiltinsAssembler) {
  TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));

  // 1. Let len be the actual number of arguments passed to this function.
  TNode<Int32T> argc =
      UncheckedCast<Int32T>(Parameter(BuiltinDescriptor::kArgumentsCount));
  TNode<Smi> length = SmiFromWord32(argc);
  // 2. Let items be the List of arguments passed to this function.
  CodeStubArguments args(this, length, nullptr, ParameterMode::SMI_PARAMETERS,
                         CodeStubArguments::ReceiverMode::kHasReceiver);

  Label if_not_constructor(this, Label::kDeferred),
      unreachable(this, Label::kDeferred);

  // 3. Let C be the this value.
  // 4. If IsConstructor(C) is false, throw a TypeError exception.
  TNode<Object> receiver = args.GetReceiver();
  GotoIf(TaggedIsSmi(receiver), &if_not_constructor);
  GotoIfNot(IsConstructor(receiver), &if_not_constructor);

  // 5. Let newObj be ? TypedArrayCreate(C, len).
  TNode<JSTypedArray> new_typed_array =
      CreateByLength(context, receiver, length, "%TypedArray%.of");

  TNode<Word32T> elements_kind = LoadElementsKind(new_typed_array);

  // 6. Let k be 0.
  // 7. Repeat, while k < len
  //  a. Let kValue be items[k].
  //  b. Let Pk be ! ToString(k).
  //  c. Perform ? Set(newObj, Pk, kValue, true).
  //  d. Increase k by 1.
  DispatchTypedArrayByElementsKind(
      elements_kind,
      [&](ElementsKind kind, int size, int typed_array_fun_index) {
        BuildFastLoop(
            SmiConstant(0), length,
            [&](Node* index) {
              TNode<Object> item =
                  args.AtIndex(index, ParameterMode::SMI_PARAMETERS);
              TNode<Number> number = ToNumber_Inline(context, item);

              // ToNumber may execute JavaScript code, but it cannot access
              // arguments array and new typed array.
              DebugSanityCheckTypedArrayIndex(new_typed_array, index);

              // Since we can guarantee that "number" is Number type,
              // PrepareValueForWriteToTypedArray cannot bail out.
              Node* value =
                  PrepareValueForWriteToTypedArray(number, kind, &unreachable);

              // GC may move backing store in ToNumber, thus load backing store
              // everytime in this loop.
              TNode<IntPtrT> backing_store =
                  UncheckedCast<IntPtrT>(LoadDataPtr(new_typed_array));
              StoreElement(backing_store, kind, index, value, SMI_PARAMETERS);
            },
            1, ParameterMode::SMI_PARAMETERS, IndexAdvanceMode::kPost);
      });

  // 8. Return newObj.
  args.PopAndReturn(new_typed_array);

  BIND(&unreachable);
  Unreachable();

  BIND(&if_not_constructor);
  ThrowTypeError(context, MessageTemplate::kNotConstructor, receiver);
}

#undef V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP

}  // namespace internal
}  // namespace v8
