// 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-utils-gen.h"
#include "src/builtins/builtins.h"
#include "src/code-stub-assembler.h"
#include "src/handles-inl.h"

namespace v8 {
namespace internal {

// 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

class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
 public:
  explicit TypedArrayBuiltinsAssembler(compiler::CodeAssemblerState* state)
      : CodeStubAssembler(state) {}

 protected:
  void GenerateTypedArrayPrototypeGetter(Node* context, Node* receiver,
                                         const char* method_name,
                                         int object_offset);
  void GenerateTypedArrayPrototypeIterationMethod(Node* context, Node* receiver,
                                                  const char* method_name,
                                                  IterationKind iteration_kind);

  void SetupTypedArray(Node* holder, Node* length, Node* byte_offset,
                       Node* byte_length);
  void AttachBuffer(Node* holder, Node* buffer, Node* map, Node* length,
                    Node* byte_offset);

  Node* LoadMapForType(Node* array);
  Node* CalculateExternalPointer(Node* backing_store, Node* byte_offset);
  Node* LoadDataPtr(Node* typed_array);
  Node* ByteLengthIsValid(Node* byte_length);
};

compiler::Node* TypedArrayBuiltinsAssembler::LoadMapForType(Node* array) {
  CSA_ASSERT(this, IsJSTypedArray(array));

  Label unreachable(this), done(this);
  Label uint8_elements(this), uint8_clamped_elements(this), int8_elements(this),
      uint16_elements(this), int16_elements(this), uint32_elements(this),
      int32_elements(this), float32_elements(this), float64_elements(this);
  Label* elements_kind_labels[] = {
      &uint8_elements,  &uint8_clamped_elements, &int8_elements,
      &uint16_elements, &int16_elements,         &uint32_elements,
      &int32_elements,  &float32_elements,       &float64_elements};
  int32_t elements_kinds[] = {
      UINT8_ELEMENTS,  UINT8_CLAMPED_ELEMENTS, INT8_ELEMENTS,
      UINT16_ELEMENTS, INT16_ELEMENTS,         UINT32_ELEMENTS,
      INT32_ELEMENTS,  FLOAT32_ELEMENTS,       FLOAT64_ELEMENTS};
  const size_t kTypedElementsKindCount = LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND -
                                         FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND +
                                         1;
  DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kinds));
  DCHECK_EQ(kTypedElementsKindCount, arraysize(elements_kind_labels));

  VARIABLE(var_typed_map, MachineRepresentation::kTagged);

  Node* array_map = LoadMap(array);
  Node* elements_kind = LoadMapElementsKind(array_map);
  Switch(elements_kind, &unreachable, elements_kinds, elements_kind_labels,
         kTypedElementsKindCount);

  for (int i = 0; i < static_cast<int>(kTypedElementsKindCount); i++) {
    BIND(elements_kind_labels[i]);
    {
      ElementsKind kind = static_cast<ElementsKind>(elements_kinds[i]);
      ExternalArrayType type =
          isolate()->factory()->GetArrayTypeFromElementsKind(kind);
      Handle<Map> map(isolate()->heap()->MapForFixedTypedArray(type));
      var_typed_map.Bind(HeapConstant(map));
      Goto(&done);
    }
  }

  BIND(&unreachable);
  { Unreachable(); }
  BIND(&done);
  return var_typed_map.value();
}

// 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.
compiler::Node* TypedArrayBuiltinsAssembler::CalculateExternalPointer(
    Node* backing_store, Node* byte_offset) {
  return IntPtrAdd(backing_store, ChangeNumberToIntPtr(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(Node* holder, Node* length,
                                                  Node* byte_offset,
                                                  Node* byte_length) {
  CSA_ASSERT(this, IsJSTypedArray(holder));
  CSA_ASSERT(this, TaggedIsSmi(length));
  CSA_ASSERT(this, IsNumber(byte_offset));
  CSA_ASSERT(this, IsNumber(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(Node* holder, Node* buffer,
                                               Node* map, Node* length,
                                               Node* byte_offset) {
  CSA_ASSERT(this, IsJSTypedArray(holder));
  CSA_ASSERT(this, IsJSArrayBuffer(buffer));
  CSA_ASSERT(this, IsMap(map));
  CSA_ASSERT(this, TaggedIsSmi(length));
  CSA_ASSERT(this, IsNumber(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));

  Node* backing_store = LoadObjectField(
      buffer, JSArrayBuffer::kBackingStoreOffset, MachineType::Pointer());

  Node* external_pointer = CalculateExternalPointer(backing_store, byte_offset);
  StoreObjectFieldNoWriteBarrier(
      elements, FixedTypedArrayBase::kExternalPointerOffset, external_pointer,
      MachineType::PointerRepresentation());

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

TF_BUILTIN(TypedArrayInitializeWithBuffer, TypedArrayBuiltinsAssembler) {
  Node* holder = Parameter(Descriptor::kHolder);
  Node* length = Parameter(Descriptor::kLength);
  Node* buffer = Parameter(Descriptor::kBuffer);
  Node* element_size = Parameter(Descriptor::kElementSize);
  Node* byte_offset = Parameter(Descriptor::kByteOffset);

  CSA_ASSERT(this, IsJSTypedArray(holder));
  CSA_ASSERT(this, TaggedIsSmi(length));
  CSA_ASSERT(this, IsJSArrayBuffer(buffer));
  CSA_ASSERT(this, TaggedIsSmi(element_size));
  CSA_ASSERT(this, IsNumber(byte_offset));

  Node* fixed_typed_map = LoadMapForType(holder);

  // SmiMul returns a heap number in case of Smi overflow.
  Node* byte_length = SmiMul(length, element_size);
  CSA_ASSERT(this, IsNumber(byte_length));

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

TF_BUILTIN(TypedArrayInitialize, TypedArrayBuiltinsAssembler) {
  Node* holder = Parameter(Descriptor::kHolder);
  Node* length = Parameter(Descriptor::kLength);
  Node* element_size = Parameter(Descriptor::kElementSize);
  Node* initialize = Parameter(Descriptor::kInitialize);
  Node* context = Parameter(Descriptor::kContext);

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

  Node* 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.
  Node* byte_length = SmiMul(length, element_size);
  CSA_ASSERT(this, IsNumber(byte_length));

  SetupTypedArray(holder, length, byte_offset, byte_length);

  Node* 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);
  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(SmiToWord(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(SmiToWord(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), SmiToWord(byte_length));
    Goto(&done);
  }

  VARIABLE(var_buffer, MachineRepresentation::kTagged);

  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.Bind(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.Bind(CallJS(CodeFactory::Call(isolate()), context,
                           buffer_constructor_noinit, UndefinedConstant(),
                           byte_length));
    Goto(&attach_buffer);
  }

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

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

// ES6 #sec-typedarray-length
TF_BUILTIN(TypedArrayConstructByLength, TypedArrayBuiltinsAssembler) {
  Node* holder = Parameter(Descriptor::kHolder);
  Node* length = Parameter(Descriptor::kLength);
  Node* element_size = Parameter(Descriptor::kElementSize);
  Node* context = Parameter(Descriptor::kContext);

  CSA_ASSERT(this, IsJSTypedArray(holder));
  CSA_ASSERT(this, TaggedIsPositiveSmi(element_size));

  Node* initialize = BooleanConstant(true);

  Label invalid_length(this);

  length = ToInteger(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 smi's).
  GotoIf(TaggedIsNotSmi(length), &invalid_length);
  GotoIf(SmiLessThan(length, SmiConstant(0)), &invalid_length);

  CallBuiltin(Builtins::kTypedArrayInitialize, context, holder, length,
              element_size, initialize);
  Return(UndefinedConstant());

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

// ES6 #sec-typedarray-buffer-byteoffset-length
TF_BUILTIN(TypedArrayConstructByArrayBuffer, TypedArrayBuiltinsAssembler) {
  Node* holder = Parameter(Descriptor::kHolder);
  Node* buffer = Parameter(Descriptor::kBuffer);
  Node* byte_offset = Parameter(Descriptor::kByteOffset);
  Node* length = Parameter(Descriptor::kLength);
  Node* element_size = Parameter(Descriptor::kElementSize);
  Node* context = Parameter(Descriptor::kContext);

  CSA_ASSERT(this, IsJSTypedArray(holder));
  CSA_ASSERT(this, IsJSArrayBuffer(buffer));
  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);

  GotoIf(IsUndefined(byte_offset), &check_length);

  offset.Bind(
      ToInteger(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);
  // TODO(petermarshall): Throw on detached typedArray.
  Branch(IsUndefined(length), &length_undefined, &length_defined);

  BIND(&length_undefined);
  {
    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);
    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());
    Return(UndefinedConstant());
  }

  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();
  }
}

compiler::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);
}

compiler::Node* TypedArrayBuiltinsAssembler::ByteLengthIsValid(
    Node* byte_length) {
  Label smi(this), done(this);
  VARIABLE(is_valid, MachineRepresentation::kWord32);
  GotoIf(TaggedIsSmi(byte_length), &smi);

  CSA_ASSERT(this, IsHeapNumber(byte_length));
  Node* float_value = LoadHeapNumberValue(byte_length);
  Node* max_byte_length_double =
      Float64Constant(FixedTypedArrayBase::kMaxByteLength);
  is_valid.Bind(Float64LessThanOrEqual(float_value, max_byte_length_double));
  Goto(&done);

  BIND(&smi);
  Node* max_byte_length = IntPtrConstant(FixedTypedArrayBase::kMaxByteLength);
  is_valid.Bind(UintPtrLessThanOrEqual(SmiUntag(byte_length), max_byte_length));
  Goto(&done);

  BIND(&done);
  return is_valid.value();
}

TF_BUILTIN(TypedArrayConstructByArrayLike, TypedArrayBuiltinsAssembler) {
  Node* holder = Parameter(Descriptor::kHolder);
  Node* array_like = Parameter(Descriptor::kArrayLike);
  Node* initial_length = Parameter(Descriptor::kLength);
  Node* element_size = Parameter(Descriptor::kElementSize);
  CSA_ASSERT(this, TaggedIsSmi(element_size));
  Node* context = Parameter(Descriptor::kContext);

  Node* initialize = BooleanConstant(false);

  Label invalid_length(this), fill(this), fast_copy(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);
  Return(UndefinedConstant());

  BIND(&fill);
  Node* holder_kind = LoadMapElementsKind(LoadMap(holder));
  Node* 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);
  Return(UndefinedConstant());

  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)));

    Node* byte_length = SmiMul(length, element_size);
    CSA_ASSERT(this, ByteLengthIsValid(byte_length));
    Node* byte_length_intptr = ChangeNumberToIntPtr(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);
    Return(UndefinedConstant());
  }

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

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);
}

// 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);
  GotoIf(Word32NotEqual(instance_type, Int32Constant(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);
}

#undef V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP

}  // namespace internal
}  // namespace v8
