summaryrefslogtreecommitdiff
path: root/deps/v8/src/builtins/typed-array-subarray.tq
blob: 4f98123f823a197f9749fe01a183eec12eea3f62 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// 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_subarray {
  // ES %TypedArray%.prototype.subarray
  transitioning javascript builtin TypedArrayPrototypeSubArray(
      js-implicit context: Context,
      receiver: Object)(...arguments): JSTypedArray {
    const methodName: constexpr string = '%TypedArray%.prototype.subarray';

    // 1. Let O be the this value.
    // 3. If O does not have a [[TypedArrayName]] internal slot, throw a
    // TypeError exception.
    const source = Cast<JSTypedArray>(receiver)
        otherwise ThrowTypeError(kIncompatibleMethodReceiver, methodName);

    // 5. Let buffer be O.[[ViewedArrayBuffer]].
    const buffer = typed_array::GetBuffer(source);

    // 6. Let srcLength be O.[[ArrayLength]].
    const srcLength = Convert<intptr>(source.length);

    // 7. Let relativeBegin be ? ToInteger(begin).
    // 8. If relativeBegin < 0, let beginIndex be max((srcLength +
    // relativeBegin), 0); else let beginIndex be min(relativeBegin,
    // srcLength).
    const arg0 = arguments[0];
    const begin: intptr =
        arg0 != Undefined ? ConvertToRelativeIndex(arg0, srcLength) : 0;

    // 9. If end is undefined, let relativeEnd be srcLength;
    //      else, let relativeEnd be ? ToInteger(end).
    // 10. If relativeEnd < 0, let endIndex be max((srcLength + relativeEnd),
    // 0); else let endIndex be min(relativeEnd, srcLength).
    const arg1 = arguments[1];
    const end: intptr =
        arg1 != Undefined ? ConvertToRelativeIndex(arg1, srcLength) : srcLength;

    // 11. Let newLength be max(endIndex - beginIndex, 0).
    const newLength = Convert<PositiveSmi>(IntPtrMax(end - begin, 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.
    const elementsInfo = typed_array::GetTypedArrayElementsInfo(source);

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

    // 15. Let beginByteOffset be srcByteOffset + beginIndex × elementSize.
    const beginByteOffset = srcByteOffset +
        elementsInfo.CalculateByteLength(Convert<PositiveSmi>(begin))
        otherwise ThrowRangeError(kInvalidArrayBufferLength);

    // 16. Let argumentsList be « buffer, beginByteOffset, newLength ».
    const beginByteOffsetNum = Convert<Number>(beginByteOffset);

    // 17. Return ? TypedArraySpeciesCreate(O, argumentsList).
    const numArgs: constexpr int31 = 3;
    return typed_array_createtypedarray::TypedArraySpeciesCreate(
        methodName, numArgs, source, buffer, beginByteOffsetNum, newLength);
  }
}