// Copyright 2019 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-constructor-gen.h'

namespace typed_array {
extern builtin IterableToListMayPreserveHoles(
    Context, Object, Callable): JSArray;

extern macro TypedArrayBuiltinsAssembler::AllocateEmptyOnHeapBuffer(
    implicit context: Context)(uintptr): JSArrayBuffer;
extern macro CodeStubAssembler::AllocateByteArray(uintptr): ByteArray;
extern macro TypedArrayBuiltinsAssembler::GetDefaultConstructor(
    implicit context: Context)(JSTypedArray): JSFunction;
extern macro TypedArrayBuiltinsAssembler::SetupTypedArrayEmbedderFields(
    JSTypedArray): void;

extern runtime ThrowInvalidTypedArrayAlignment(implicit context: Context)(
    Map, String): never;

transitioning macro AllocateTypedArray(implicit context: Context)(
    isOnHeap: constexpr bool, map: Map, buffer: JSArrayBuffer,
    byteOffset: uintptr, byteLength: uintptr, length: uintptr): JSTypedArray {
  let elements: ByteArray;
  if constexpr (isOnHeap) {
    elements = AllocateByteArray(byteLength);
  } else {
    elements = kEmptyByteArray;

    // The max byteOffset 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.
    const backingStore: uintptr = Convert<uintptr>(buffer.backing_store_ptr);

    // Assert no overflow has occurred. Only assert if the mock array buffer
    // allocator is NOT used. When the mock array buffer is used, impossibly
    // large allocations are allowed that would erroneously cause an overflow
    // and this assertion to fail.
    assert(
        IsMockArrayBufferAllocatorFlag() ||
        (backingStore + byteOffset) >= backingStore);
  }

  // We can't just build the new object with "new JSTypedArray" here because
  // Torque doesn't know its full size including embedder fields, so use CSA
  // for the allocation step.
  const typedArray =
      UnsafeCast<JSTypedArray>(AllocateFastOrSlowJSObjectFromMap(map));
  typedArray.elements = elements;
  typedArray.buffer = buffer;
  typedArray.byte_offset = byteOffset;
  typedArray.byte_length = byteLength;
  typedArray.length = length;
  typed_array::AllocateJSTypedArrayExternalPointerEntry(typedArray);
  if constexpr (isOnHeap) {
    typed_array::SetJSTypedArrayOnHeapDataPtr(typedArray, elements, byteOffset);
  } else {
    typed_array::SetJSTypedArrayOffHeapDataPtr(
        typedArray, buffer.backing_store_ptr, byteOffset);
    assert(
        typedArray.data_ptr ==
        (buffer.backing_store_ptr + Convert<intptr>(byteOffset)));
  }
  SetupTypedArrayEmbedderFields(typedArray);
  return typedArray;
}

transitioning macro TypedArrayInitialize(implicit context: Context)(
    initialize: constexpr bool, map: Map, length: uintptr,
    elementsInfo: typed_array::TypedArrayElementsInfo,
    bufferConstructor: JSReceiver): JSTypedArray labels IfRangeError {
  const byteLength = elementsInfo.CalculateByteLength(length)
      otherwise IfRangeError;
  const byteLengthNum = Convert<Number>(byteLength);
  const defaultConstructor = GetArrayBufferFunction();
  const byteOffset: uintptr = 0;

  try {
    if (bufferConstructor != defaultConstructor) {
      goto AttachOffHeapBuffer(ConstructWithTarget(
          defaultConstructor, bufferConstructor, byteLengthNum));
    }

    if (byteLength > kMaxTypedArrayInHeap) goto AllocateOffHeap;

    const buffer = AllocateEmptyOnHeapBuffer(byteLength);

    const isOnHeap: constexpr bool = true;
    const typedArray = AllocateTypedArray(
        isOnHeap, map, buffer, byteOffset, byteLength, length);

    if constexpr (initialize) {
      const backingStore = typedArray.data_ptr;
      typed_array::CallCMemset(backingStore, 0, byteLength);
    }

    return typedArray;
  } label AllocateOffHeap {
    if constexpr (initialize) {
      goto AttachOffHeapBuffer(Construct(defaultConstructor, byteLengthNum));
    } else {
      goto AttachOffHeapBuffer(Call(
          context, GetArrayBufferNoInitFunction(), Undefined, byteLengthNum));
    }
  } label AttachOffHeapBuffer(bufferObj: Object) {
    const buffer = Cast<JSArrayBuffer>(bufferObj) otherwise unreachable;
    const isOnHeap: constexpr bool = false;
    return AllocateTypedArray(
        isOnHeap, map, buffer, byteOffset, byteLength, length);
  }
}

// 22.2.4.2 TypedArray ( length )
// ES #sec-typedarray-length
transitioning macro ConstructByLength(implicit context: Context)(
    map: Map, lengthObj: JSAny,
    elementsInfo: typed_array::TypedArrayElementsInfo): JSTypedArray {
  try {
    const length: uintptr = ToIndex(lengthObj) otherwise RangeError;
    const defaultConstructor: Constructor = GetArrayBufferFunction();
    const initialize: constexpr bool = true;
    return TypedArrayInitialize(
        initialize, map, length, elementsInfo, defaultConstructor)
        otherwise RangeError;
  } label RangeError deferred {
    ThrowRangeError(MessageTemplate::kInvalidTypedArrayLength, lengthObj);
  }
}

// 22.2.4.4 TypedArray ( object )
// ES #sec-typedarray-object
transitioning macro ConstructByArrayLike(implicit context: Context)(
    map: Map, arrayLike: HeapObject, length: uintptr,
    elementsInfo: typed_array::TypedArrayElementsInfo,
    bufferConstructor: JSReceiver): JSTypedArray {
  try {
    const initialize: constexpr bool = false;
    const typedArray = TypedArrayInitialize(
        initialize, map, length, elementsInfo, bufferConstructor)
        otherwise RangeError;

    try {
      const src: JSTypedArray = Cast<JSTypedArray>(arrayLike) otherwise IfSlow;

      if (IsDetachedBuffer(src.buffer)) {
        ThrowTypeError(MessageTemplate::kDetachedOperation, 'Construct');

      } else if (src.elements_kind != elementsInfo.kind) {
        goto IfSlow;

      } else if (length > 0) {
        const byteLength = typedArray.byte_length;
        assert(byteLength <= kArrayBufferMaxByteLength);
        typed_array::CallCMemcpy(typedArray.data_ptr, src.data_ptr, byteLength);
      }
    } label IfSlow deferred {
      if (length > 0) {
        TypedArrayCopyElements(
            context, typedArray, arrayLike, Convert<Number>(length));
      }
    }
    return typedArray;
  } label RangeError deferred {
    ThrowRangeError(
        MessageTemplate::kInvalidTypedArrayLength, Convert<Number>(length));
  }
}

// 22.2.4.4 TypedArray ( object )
// ES #sec-typedarray-object
transitioning macro ConstructByIterable(implicit context: Context)(
    iterable: JSReceiver, iteratorFn: Callable): never
    labels IfConstructByArrayLike(JSArray, uintptr, JSReceiver) {
  const array: JSArray =
      IterableToListMayPreserveHoles(context, iterable, iteratorFn);
  // Max JSArray length is a valid JSTypedArray length so we just use it.
  goto IfConstructByArrayLike(
      array, array.length_uintptr, GetArrayBufferFunction());
}

// 22.2.4.3 TypedArray ( typedArray )
// ES #sec-typedarray-typedarray
transitioning macro ConstructByTypedArray(implicit context: Context)(
    srcTypedArray: JSTypedArray): never
    labels IfConstructByArrayLike(JSTypedArray, uintptr, JSReceiver) {
  let bufferConstructor: JSReceiver = GetArrayBufferFunction();
  const srcBuffer: JSArrayBuffer = srcTypedArray.buffer;
  // TODO(petermarshall): Throw on detached typedArray.
  let length: uintptr = IsDetachedBuffer(srcBuffer) ? 0 : srcTypedArray.length;

  // 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.
  if (!IsSharedArrayBuffer(srcBuffer)) {
    bufferConstructor = SpeciesConstructor(srcBuffer, bufferConstructor);
    // TODO(petermarshall): Throw on detached typedArray.
    if (IsDetachedBuffer(srcBuffer)) length = 0;
  }
  goto IfConstructByArrayLike(srcTypedArray, length, bufferConstructor);
}

// 22.2.4.5 TypedArray ( buffer, byteOffset, length )
// ES #sec-typedarray-buffer-byteoffset-length
transitioning macro ConstructByArrayBuffer(implicit context: Context)(
    map: Map, buffer: JSArrayBuffer, byteOffset: JSAny, length: JSAny,
    elementsInfo: typed_array::TypedArrayElementsInfo): JSTypedArray {
  try {
    // 6. Let offset be ? ToIndex(byteOffset).
    const offset: uintptr = ToIndex(byteOffset) otherwise IfInvalidOffset;

    // 7. If offset modulo elementSize ≠ 0, throw a RangeError exception.
    if (elementsInfo.IsUnaligned(offset)) {
      goto IfInvalidAlignment('start offset');
    }

    // 8. If length is present and length is not undefined, then
    // a. Let newLength be ? ToIndex(length).
    let newLength: uintptr = ToIndex(length) otherwise IfInvalidLength;
    let newByteLength: uintptr;

    // 9. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
    if (IsDetachedBuffer(buffer)) {
      ThrowTypeError(MessageTemplate::kDetachedOperation, 'Construct');
    }

    // 10. Let bufferByteLength be buffer.[[ArrayBufferByteLength]].
    const bufferByteLength: uintptr = buffer.byte_length;

    // 11. If length is either not present or undefined, then
    if (length == Undefined) {
      // a. If bufferByteLength modulo elementSize ≠ 0, throw a RangeError
      // exception.
      if (elementsInfo.IsUnaligned(bufferByteLength)) {
        goto IfInvalidAlignment('byte length');
      }

      // b. Let newByteLength be bufferByteLength - offset.
      // c. If newByteLength < 0, throw a RangeError exception.
      if (bufferByteLength < offset) goto IfInvalidOffset;

      // Spec step 16 length calculated here to avoid recalculating the length
      // in the step 12 branch.
      newByteLength = bufferByteLength - offset;
      newLength = elementsInfo.CalculateLength(newByteLength)
          otherwise IfInvalidOffset;

      // 12. Else,
    } else {
      // a. Let newByteLength be newLength × elementSize.
      newByteLength = elementsInfo.CalculateByteLength(newLength)
          otherwise IfInvalidLength;

      // b. If offset + newByteLength > bufferByteLength, throw a RangeError
      // exception.
      if ((bufferByteLength < newByteLength) ||
          (offset > bufferByteLength - newByteLength))
        goto IfInvalidLength;
    }

    const isOnHeap: constexpr bool = false;
    return AllocateTypedArray(
        isOnHeap, map, buffer, offset, newByteLength, newLength);
  } label IfInvalidAlignment(problemString: String) deferred {
    ThrowInvalidTypedArrayAlignment(map, problemString);
  } label IfInvalidLength deferred {
    ThrowRangeError(MessageTemplate::kInvalidTypedArrayLength, length);
  } label IfInvalidOffset deferred {
    ThrowRangeError(MessageTemplate::kInvalidOffset, byteOffset);
  }
}

// 22.2.4.6 TypedArrayCreate ( constructor, argumentList )
// ES #typedarray-create
@export
transitioning macro TypedArrayCreateByLength(implicit context: Context)(
    constructor: Constructor, length: Number, methodName: constexpr string):
    JSTypedArray {
  assert(IsSafeInteger(length));

  // 1. Let newTypedArray be ? Construct(constructor, argumentList).
  const newTypedArrayObj = Construct(constructor, length);

  // 2. Perform ? ValidateTypedArray(newTypedArray).
  //    ValidateTypedArray currently returns the array, not the ViewBuffer.
  const newTypedArray: JSTypedArray =
      ValidateTypedArray(context, newTypedArrayObj, methodName);

  if (IsDetachedBuffer(newTypedArray.buffer)) deferred {
      ThrowTypeError(MessageTemplate::kDetachedOperation, methodName);
    }

  // 3. If argumentList is a List of a single Number, then
  //   a. If newTypedArray.[[ArrayLength]] < argumentList[0], throw a
  //      TypeError exception.
  if (newTypedArray.length < Convert<uintptr>(length)) deferred {
      ThrowTypeError(MessageTemplate::kTypedArrayTooShort);
    }

  // 4. Return newTypedArray.
  return newTypedArray;
}

transitioning macro ConstructByJSReceiver(implicit context: Context)(
    obj: JSReceiver): never
    labels IfConstructByArrayLike(JSReceiver, uintptr, JSReceiver) {
  try {
    // TODO(v8:8906): Use iterator::GetIteratorMethod() once it supports
    // labels.
    const iteratorMethod = GetMethod(obj, IteratorSymbolConstant())
        otherwise IfIteratorUndefined, IfIteratorNotCallable;
    ConstructByIterable(obj, iteratorMethod)
        otherwise IfConstructByArrayLike;
  } label IfIteratorUndefined {
    const lengthObj: JSAny = GetProperty(obj, kLengthString);
    const lengthNumber: Number = ToLength_Inline(lengthObj);
    // Throw RangeError here if the length does not fit in uintptr because
    // such a length will not pass bounds checks in ConstructByArrayLike()
    // anyway.
    const length: uintptr = ChangeSafeIntegerNumberToUintPtr(lengthNumber)
        otherwise goto IfInvalidLength(lengthNumber);
    goto IfConstructByArrayLike(obj, length, GetArrayBufferFunction());
  } label IfInvalidLength(length: Number) {
    ThrowRangeError(MessageTemplate::kInvalidTypedArrayLength, length);
  } label IfIteratorNotCallable(_value: JSAny) deferred {
    ThrowTypeError(MessageTemplate::kIteratorSymbolNonCallable);
  }
}

// 22.2.4 The TypedArray Constructors
// ES #sec-typedarray-constructors
transitioning builtin CreateTypedArray(
    context: Context, target: JSFunction, newTarget: JSReceiver, arg1: JSAny,
    arg2: JSAny, arg3: JSAny): JSTypedArray {
  assert(IsConstructor(target));
  // 4. Let O be ? AllocateTypedArray(constructorName, NewTarget,
  // "%TypedArrayPrototype%").
  const map = GetDerivedMap(target, newTarget);

  // 5. Let elementSize be the Number value of the Element Size value in Table
  // 56 for constructorName.
  const elementsInfo = GetTypedArrayElementsInfo(map);

  try {
    typeswitch (arg1) {
      case (length: Smi): {
        goto IfConstructByLength(length);
      }
      case (buffer: JSArrayBuffer): {
        return ConstructByArrayBuffer(map, buffer, arg2, arg3, elementsInfo);
      }
      case (typedArray: JSTypedArray): {
        ConstructByTypedArray(typedArray) otherwise IfConstructByArrayLike;
      }
      case (obj: JSReceiver): {
        ConstructByJSReceiver(obj) otherwise IfConstructByArrayLike;
      }
      // The first argument was a number or fell through and is treated as
      // a number. https://tc39.github.io/ecma262/#sec-typedarray-length
      case (lengthObj: JSAny): {
        goto IfConstructByLength(lengthObj);
      }
    }
  } label IfConstructByLength(length: JSAny) {
    return ConstructByLength(map, length, elementsInfo);
  } label IfConstructByArrayLike(
      arrayLike: JSReceiver, length: uintptr, bufferConstructor: JSReceiver) {
    return ConstructByArrayLike(
        map, arrayLike, length, elementsInfo, bufferConstructor);
  }
}

transitioning macro TypedArraySpeciesCreate(implicit context: Context)(
    methodName: constexpr string, numArgs: constexpr int31,
    exemplar: JSTypedArray, arg0: JSAny, arg1: JSAny,
    arg2: JSAny): JSTypedArray {
  const defaultConstructor = GetDefaultConstructor(exemplar);

  try {
    if (!IsPrototypeTypedArrayPrototype(exemplar.map)) goto IfSlow;
    if (IsTypedArraySpeciesProtectorCellInvalid()) goto IfSlow;

    const typedArray = CreateTypedArray(
        context, defaultConstructor, defaultConstructor, arg0, arg1, arg2);

    // It is assumed that the CreateTypedArray builtin does not produce a
    // typed array that fails ValidateTypedArray
    assert(!IsDetachedBuffer(typedArray.buffer));

    return typedArray;
  } label IfSlow deferred {
    const constructor =
        Cast<Constructor>(SpeciesConstructor(exemplar, defaultConstructor))
        otherwise unreachable;

    // TODO(pwong): Simplify and remove numArgs when varargs are supported in
    // macros.
    let newObj: JSAny = Undefined;
    if constexpr (numArgs == 1) {
      newObj = Construct(constructor, arg0);
    } else {
      assert(numArgs == 3);
      newObj = Construct(constructor, arg0, arg1, arg2);
    }

    return ValidateTypedArray(context, newObj, methodName);
  }
}

@export
transitioning macro TypedArraySpeciesCreateByLength(implicit context: Context)(
    methodName: constexpr string, exemplar: JSTypedArray, length: uintptr):
    JSTypedArray {
  const numArgs: constexpr int31 = 1;
  // TODO(v8:4153): pass length further as uintptr.
  const typedArray: JSTypedArray = TypedArraySpeciesCreate(
      methodName, numArgs, exemplar, Convert<Number>(length), Undefined,
      Undefined);
  if (typedArray.length < length) deferred {
      ThrowTypeError(MessageTemplate::kTypedArrayTooShort);
    }
  return typedArray;
}

transitioning macro TypedArraySpeciesCreateByBuffer(implicit context: Context)(
    methodName: constexpr string, exemplar: JSTypedArray, buffer: JSArrayBuffer,
    beginByteOffset: uintptr, newLength: uintptr): JSTypedArray {
  const numArgs: constexpr int31 = 3;
  // TODO(v8:4153): pass length further as uintptr.
  const typedArray: JSTypedArray = TypedArraySpeciesCreate(
      methodName, numArgs, exemplar, buffer, Convert<Number>(beginByteOffset),
      Convert<Number>(newLength));
  return typedArray;
}
}
