1// Copyright 2019 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5namespace typed_array {
6  // ES %TypedArray%.prototype.subarray
7  transitioning javascript builtin TypedArrayPrototypeSubArray(
8      js-implicit context: NativeContext,
9      receiver: JSAny)(...arguments): JSTypedArray {
10    const methodName: constexpr string = '%TypedArray%.prototype.subarray';
11
12    // 1. Let O be the this value.
13    // 3. If O does not have a [[TypedArrayName]] internal slot, throw a
14    // TypeError exception.
15    const source = Cast<JSTypedArray>(receiver)
16        otherwise ThrowTypeError(
17        MessageTemplate::kIncompatibleMethodReceiver, methodName);
18
19    // 5. Let buffer be O.[[ViewedArrayBuffer]].
20    const buffer = typed_array::GetBuffer(source);
21
22    // 6. Let srcLength be O.[[ArrayLength]].
23    const srcLength: uintptr = source.length;
24
25    // 7. Let relativeBegin be ? ToInteger(begin).
26    // 8. If relativeBegin < 0, let beginIndex be max((srcLength +
27    // relativeBegin), 0); else let beginIndex be min(relativeBegin,
28    // srcLength).
29    const arg0 = arguments[0];
30    const begin: uintptr =
31        arg0 != Undefined ? ConvertToRelativeIndex(arg0, srcLength) : 0;
32
33    // 9. If end is undefined, let relativeEnd be srcLength;
34    //      else, let relativeEnd be ? ToInteger(end).
35    // 10. If relativeEnd < 0, let endIndex be max((srcLength + relativeEnd),
36    // 0); else let endIndex be min(relativeEnd, srcLength).
37    const arg1 = arguments[1];
38    const end: uintptr =
39        arg1 != Undefined ? ConvertToRelativeIndex(arg1, srcLength) : srcLength;
40
41    // 11. Let newLength be max(endIndex - beginIndex, 0).
42    const newLength: uintptr = Unsigned(IntPtrMax(Signed(end - begin), 0));
43
44    // 12. Let constructorName be the String value of O.[[TypedArrayName]].
45    // 13. Let elementSize be the Number value of the Element Size value
46    // specified in Table 52 for constructorName.
47    const elementsInfo = typed_array::GetTypedArrayElementsInfo(source);
48
49    // 14. Let srcByteOffset be O.[[ByteOffset]].
50    const srcByteOffset: uintptr = source.byte_offset;
51
52    // 15. Let beginByteOffset be srcByteOffset + beginIndex × elementSize.
53    const beginByteOffset =
54        srcByteOffset + elementsInfo.CalculateByteLength(begin)
55        otherwise ThrowRangeError(MessageTemplate::kInvalidArrayBufferLength);
56
57    // 16. Let argumentsList be « buffer, beginByteOffset, newLength ».
58    // 17. Return ? TypedArraySpeciesCreate(O, argumentsList).
59    return TypedArraySpeciesCreateByBuffer(
60        methodName, source, buffer, beginByteOffset, newLength);
61  }
62}
63