current commit
260424.4 · deps: update V8 to 14.6.202.33
// 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.

namespace typed_array {
// ES %TypedArray%.prototype.subarray
transitioning javascript builtin TypedArrayPrototypeSubArray(
    js-implicit context: NativeContext, receiver: JSAny)(
    ...arguments): JSTypedArray {
  const methodName: constexpr string = '%TypedArray%.prototype.subarray';

  // 1. Let O be the this value.
  // 2. Perform ? RequireInternalSlot(O, [[TypedArrayName]]).
  const source = Cast<JSTypedArray>(receiver)
      otherwise ThrowTypeError(
      MessageTemplate::kIncompatibleMethodReceiver, methodName, receiver);

  // 3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  // 4. Let buffer be O.[[ViewedArrayBuffer]].
  const buffer = typed_array::GetTypedArrayBuffer(source);

  // 5. Let getSrcBufferByteLength be
  //    MakeIdempotentArrayBufferByteLengthGetter(SeqCst).
  // 6. Let srcLength be IntegerIndexedObjectLength(O, getSrcBufferByteLength).
  let srcLength: uintptr;
  try {
    srcLength =
        LoadJSTypedArrayLengthAndValidate(source, TypedArrayAccessMode::kRead)
        otherwise Fail;
  } label Fail {
    srcLength = 0;
  }

  // 8. Let relativeBegin be ? ToIntegerOrInfinity(begin).
  // 9. If relativeBegin is -∞, let beginIndex be 0.
  // 10. Else if relativeBegin < 0, let beginIndex be max(srcLength +
  //     relativeBegin, 0).
  // 11. Else, let beginIndex be min(relativeBegin, srcLength).
  const arg0 = arguments[0];
  const begin: uintptr =
      arg0 != Undefined ? ConvertAndClampRelativeIndex(arg0, srcLength) : 0;

  // 12. If O.[[ArrayLength]] is auto and end is undefined, then
  const arg1 = arguments[1];
  const endIsDefined = arg1 != Undefined;

  let newLength: NumberOrUndefined;
  if (IsLengthTrackingJSArrayBufferView(source) && !endIsDefined) {
    // a. Let newLength be undefined.
    newLength = Undefined;
  } else {
    // 13. Else,
    //   a. If end is undefined, let relativeEnd be srcLength; else let
    //      relativeEnd be ? ToIntegerOrInfinity(end).
    //   b. If relativeEnd is -∞, let endIndex be 0.
    //   c. Else if relativeEnd < 0, let endIndex be max(srcLength +
    //      relativeEnd, 0).
    //   d. Else, let endIndex be min(relativeEnd, srcLength).
    const end: uintptr = endIsDefined ?
        ConvertAndClampRelativeIndex(arg1, srcLength) :
        srcLength;

    //   e. Let newLength be max(endIndex - beginIndex, 0).
    newLength = Convert<Number>(Unsigned(IntPtrMax(Signed(end - begin), 0)));
  }

  // 14. Let constructorName be the String value of O.[[TypedArrayName]].
  // 15. Let elementSize be the Number value of the Element Size value
  // specified in Table 52 for constructorName.
  const elementsInfo = typed_array::GetTypedArrayElementsInfo(source);

  // 16. Let srcByteOffset be O.[[ByteOffset]].
  const srcByteOffset: uintptr = source.byte_offset;

  // 17. Let beginByteOffset be srcByteOffset + beginIndex × elementSize.
  // The subarray can only be too big if the API limits the size of typed
  // arrays, but doesn't put a similar limit on the size of wasm byte arrays.
  const beginByteOffset =
      srcByteOffset + elementsInfo.CalculateByteLength(begin)
      otherwise ThrowRangeError(MessageTemplate::kInvalidArrayBufferLength);

  // 18. If newLength is undefined, then
  //   a. Let argumentsList be « buffer, 𝔽(beginByteOffset) ».
  // 19. Else,
  //   a. Let argumentsList be « buffer, 𝔽(beginByteOffset), 𝔽(newLength) ».
  // 20. Return ? TypedArraySpeciesCreate(O, argumentsList).
  return TypedArraySpeciesCreateByBuffer(
      methodName, source, buffer, beginByteOffset, newLength,
      TypedArrayAccessMode::kRead);
}
}