// Copyright 2018 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-data-view-gen.h'

namespace data_view {

  macro MakeDataViewGetterNameString(kind: constexpr ElementsKind): String {
    if constexpr (kind == UINT8_ELEMENTS) {
      return 'DataView.prototype.getUint8';
    } else if constexpr (kind == INT8_ELEMENTS) {
      return 'DataView.prototype.getInt8';
    } else if constexpr (kind == UINT16_ELEMENTS) {
      return 'DataView.prototype.getUint16';
    } else if constexpr (kind == INT16_ELEMENTS) {
      return 'DataView.prototype.getInt16';
    } else if constexpr (kind == UINT32_ELEMENTS) {
      return 'DataView.prototype.getUint32';
    } else if constexpr (kind == INT32_ELEMENTS) {
      return 'DataView.prototype.getInt32';
    } else if constexpr (kind == FLOAT32_ELEMENTS) {
      return 'DataView.prototype.getFloat32';
    } else if constexpr (kind == FLOAT64_ELEMENTS) {
      return 'DataView.prototype.getFloat64';
    } else if constexpr (kind == BIGINT64_ELEMENTS) {
      return 'DataView.prototype.getBigInt64';
    } else if constexpr (kind == BIGUINT64_ELEMENTS) {
      return 'DataView.prototype.getBigUint64';
    } else {
      unreachable;
    }
  }

  macro MakeDataViewSetterNameString(kind: constexpr ElementsKind): String {
    if constexpr (kind == UINT8_ELEMENTS) {
      return 'DataView.prototype.setUint8';
    } else if constexpr (kind == INT8_ELEMENTS) {
      return 'DataView.prototype.setInt8';
    } else if constexpr (kind == UINT16_ELEMENTS) {
      return 'DataView.prototype.setUint16';
    } else if constexpr (kind == INT16_ELEMENTS) {
      return 'DataView.prototype.setInt16';
    } else if constexpr (kind == UINT32_ELEMENTS) {
      return 'DataView.prototype.setUint32';
    } else if constexpr (kind == INT32_ELEMENTS) {
      return 'DataView.prototype.setInt32';
    } else if constexpr (kind == FLOAT32_ELEMENTS) {
      return 'DataView.prototype.setFloat32';
    } else if constexpr (kind == FLOAT64_ELEMENTS) {
      return 'DataView.prototype.setFloat64';
    } else if constexpr (kind == BIGINT64_ELEMENTS) {
      return 'DataView.prototype.setBigInt64';
    } else if constexpr (kind == BIGUINT64_ELEMENTS) {
      return 'DataView.prototype.setBigUint64';
    } else {
      unreachable;
    }
  }

  macro WasNeutered(view: JSArrayBufferView): bool {
    return IsDetachedBuffer(view.buffer);
  }

  macro ValidateDataView(context: Context, o: Object, method: String):
      JSDataView {
    try {
      return Cast<JSDataView>(o) otherwise CastError;
    }
    label CastError {
      ThrowTypeError(kIncompatibleMethodReceiver, method);
    }
  }

  // ES6 section 24.2.4.1 get DataView.prototype.buffer
  javascript builtin DataViewPrototypeGetBuffer(
      js-implicit context: Context,
      receiver: Object)(...arguments): JSArrayBuffer {
    const dataView: JSDataView =
        ValidateDataView(context, receiver, 'get DataView.prototype.buffer');
    return dataView.buffer;
  }

  // ES6 section 24.2.4.2 get DataView.prototype.byteLength
  javascript builtin DataViewPrototypeGetByteLength(
      js-implicit context: Context, receiver: Object)(...arguments): Number {
    const dataView: JSDataView = ValidateDataView(
        context, receiver, 'get DataView.prototype.byte_length');
    if (WasNeutered(dataView)) {
      // TODO(bmeurer): According to the ES6 spec, we should throw a TypeError
      // here if the JSArrayBuffer of the {dataView} was neutered.
      return 0;
    }
    return Convert<Number>(dataView.byte_length);
  }

  // ES6 section 24.2.4.3 get DataView.prototype.byteOffset
  javascript builtin DataViewPrototypeGetByteOffset(
      js-implicit context: Context, receiver: Object)(...arguments): Number {
    const dataView: JSDataView = ValidateDataView(
        context, receiver, 'get DataView.prototype.byte_offset');
    if (WasNeutered(dataView)) {
      // TODO(bmeurer): According to the ES6 spec, we should throw a TypeError
      // here if the JSArrayBuffer of the {dataView} was neutered.
      return 0;
    }
    return Convert<Number>(dataView.byte_offset);
  }

  extern macro BitcastInt32ToFloat32(uint32): float32;
  extern macro BitcastFloat32ToInt32(float32): uint32;
  extern macro Float64ExtractLowWord32(float64): uint32;
  extern macro Float64ExtractHighWord32(float64): uint32;
  extern macro Float64InsertLowWord32(float64, uint32): float64;
  extern macro Float64InsertHighWord32(float64, uint32): float64;

  extern macro DataViewBuiltinsAssembler::LoadUint8(RawPtr, uintptr): uint32;
  extern macro DataViewBuiltinsAssembler::LoadInt8(RawPtr, uintptr): int32;

  macro LoadDataView8(
      buffer: JSArrayBuffer, offset: uintptr, signed: constexpr bool): Smi {
    if constexpr (signed) {
      return Convert<Smi>(LoadInt8(buffer.backing_store, offset));
    } else {
      return Convert<Smi>(LoadUint8(buffer.backing_store, offset));
    }
  }

  macro LoadDataView16(
      buffer: JSArrayBuffer, offset: uintptr, requestedLittleEndian: bool,
      signed: constexpr bool): Number {
    const dataPointer: RawPtr = buffer.backing_store;

    let b0: int32;
    let b1: int32;
    let result: int32;

    // Sign-extend the most significant byte by loading it as an Int8.
    if (requestedLittleEndian) {
      b0 = Signed(LoadUint8(dataPointer, offset));
      b1 = LoadInt8(dataPointer, offset + 1);
      result = (b1 << 8) + b0;
    } else {
      b0 = LoadInt8(dataPointer, offset);
      b1 = Signed(LoadUint8(dataPointer, offset + 1));
      result = (b0 << 8) + b1;
    }
    if constexpr (signed) {
      return Convert<Smi>(result);
    } else {
      // Bit-mask the higher bits to prevent sign extension if we're unsigned.
      return Convert<Smi>(result & 0xFFFF);
    }
  }

  macro LoadDataView32(
      buffer: JSArrayBuffer, offset: uintptr, requestedLittleEndian: bool,
      kind: constexpr ElementsKind): Number {
    const dataPointer: RawPtr = buffer.backing_store;

    const b0: uint32 = LoadUint8(dataPointer, offset);
    const b1: uint32 = LoadUint8(dataPointer, offset + 1);
    const b2: uint32 = LoadUint8(dataPointer, offset + 2);
    const b3: uint32 = LoadUint8(dataPointer, offset + 3);
    let result: uint32;

    if (requestedLittleEndian) {
      result = (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
    } else {
      result = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
    }

    if constexpr (kind == INT32_ELEMENTS) {
      return Convert<Number>(Signed(result));
    } else if constexpr (kind == UINT32_ELEMENTS) {
      return Convert<Number>(result);
    } else if constexpr (kind == FLOAT32_ELEMENTS) {
      const floatRes: float64 = Convert<float64>(BitcastInt32ToFloat32(result));
      return Convert<Number>(floatRes);
    } else {
      unreachable;
    }
  }

  macro LoadDataViewFloat64(
      buffer: JSArrayBuffer, offset: uintptr,
      requestedLittleEndian: bool): Number {
    const dataPointer: RawPtr = buffer.backing_store;

    const b0: uint32 = LoadUint8(dataPointer, offset);
    const b1: uint32 = LoadUint8(dataPointer, offset + 1);
    const b2: uint32 = LoadUint8(dataPointer, offset + 2);
    const b3: uint32 = LoadUint8(dataPointer, offset + 3);
    const b4: uint32 = LoadUint8(dataPointer, offset + 4);
    const b5: uint32 = LoadUint8(dataPointer, offset + 5);
    const b6: uint32 = LoadUint8(dataPointer, offset + 6);
    const b7: uint32 = LoadUint8(dataPointer, offset + 7);
    let lowWord: uint32;
    let highWord: uint32;

    if (requestedLittleEndian) {
      lowWord = (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
      highWord = (b7 << 24) | (b6 << 16) | (b5 << 8) | b4;
    } else {
      highWord = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
      lowWord = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
    }

    let result: float64 = 0;
    result = Float64InsertLowWord32(result, lowWord);
    result = Float64InsertHighWord32(result, highWord);

    return Convert<Number>(result);
  }

  const kZeroDigitBigInt: constexpr int31 = 0;
  const kOneDigitBigInt: constexpr int31 = 1;
  const kTwoDigitBigInt: constexpr int31 = 2;

  // Create a BigInt on a 64-bit architecture from two 32-bit values.
  macro MakeBigIntOn64Bit(implicit context: Context)(
      lowWord: uint32, highWord: uint32, signed: constexpr bool): BigInt {
    // 0n is represented by a zero-length BigInt.
    if (lowWord == 0 && highWord == 0) {
      return Convert<BigInt>(bigint::AllocateBigInt(kZeroDigitBigInt));
    }

    let sign: uint32 = bigint::kPositiveSign;
    const highPart: intptr = Signed(Convert<uintptr>(highWord));
    const lowPart: intptr = Signed(Convert<uintptr>(lowWord));
    let rawValue: intptr = (highPart << 32) + lowPart;

    if constexpr (signed) {
      if (rawValue < 0) {
        sign = bigint::kNegativeSign;
        // We have to store the absolute value of rawValue in the digit.
        rawValue = 0 - rawValue;
      }
    }

    // Allocate the BigInt and store the absolute value.
    const result: MutableBigInt =
        bigint::AllocateEmptyBigInt(sign, kOneDigitBigInt);
    bigint::StoreBigIntDigit(result, 0, Unsigned(rawValue));
    return Convert<BigInt>(result);
  }

  // Create a BigInt on a 32-bit architecture from two 32-bit values.
  macro MakeBigIntOn32Bit(implicit context: Context)(
      lowWord: uint32, highWord: uint32, signed: constexpr bool): BigInt {
    // 0n is represented by a zero-length BigInt.
    if (lowWord == 0 && highWord == 0) {
      return Convert<BigInt>(bigint::AllocateBigInt(kZeroDigitBigInt));
    }

    // On a 32-bit platform, we might need 1 or 2 digits to store the number.
    let needTwoDigits: bool = false;
    let sign: uint32 = bigint::kPositiveSign;

    // We need to do some math on lowWord and highWord,
    // so Convert them to int32.
    let lowPart: int32 = Signed(lowWord);
    let highPart: int32 = Signed(highWord);

    // If highWord == 0, the number is positive, and we only need 1 digit,
    // so we don't have anything to do.
    // Otherwise, all cases are possible.
    if (highWord != 0) {
      if constexpr (signed) {
        // If highPart < 0, the number is always negative.
        if (highPart < 0) {
          sign = bigint::kNegativeSign;

          // We have to compute the absolute value by hand.
          // There will be a negative carry from the low word
          // to the high word iff low != 0.
          highPart = 0 - highPart;
          if (lowPart != 0) {
            highPart = highPart - 1;
          }
          lowPart = 0 - lowPart;

          // Here, highPart could be 0 again so we might have 1 or 2 digits.
          if (highPart != 0) {
            needTwoDigits = true;
          }

        } else {
          // In this case, the number is positive, and we need 2 digits.
          needTwoDigits = true;
        }

      } else {
        // In this case, the number is positive (unsigned),
        // and we need 2 digits.
        needTwoDigits = true;
      }
    }

    // Allocate the BigInt with the right sign and length.
    let result: MutableBigInt;
    if (needTwoDigits) {
      result = bigint::AllocateEmptyBigInt(sign, kTwoDigitBigInt);
    } else {
      result = bigint::AllocateEmptyBigInt(sign, kOneDigitBigInt);
    }

    // Finally, write the digit(s) to the BigInt.
    bigint::StoreBigIntDigit(result, 0, Unsigned(Convert<intptr>(lowPart)));
    if (needTwoDigits) {
      bigint::StoreBigIntDigit(result, 1, Unsigned(Convert<intptr>(highPart)));
    }
    return Convert<BigInt>(result);
  }

  macro MakeBigInt(implicit context: Context)(
      lowWord: uint32, highWord: uint32, signed: constexpr bool): BigInt {
    // A BigInt digit has the platform word size, so we only need one digit
    // on 64-bit platforms but may need two on 32-bit.
    if constexpr (Is64()) {
      return MakeBigIntOn64Bit(lowWord, highWord, signed);
    } else {
      return MakeBigIntOn32Bit(lowWord, highWord, signed);
    }
  }

  macro LoadDataViewBigInt(implicit context: Context)(
      buffer: JSArrayBuffer, offset: uintptr, requestedLittleEndian: bool,
      signed: constexpr bool): BigInt {
    const dataPointer: RawPtr = buffer.backing_store;

    const b0: uint32 = LoadUint8(dataPointer, offset);
    const b1: uint32 = LoadUint8(dataPointer, offset + 1);
    const b2: uint32 = LoadUint8(dataPointer, offset + 2);
    const b3: uint32 = LoadUint8(dataPointer, offset + 3);
    const b4: uint32 = LoadUint8(dataPointer, offset + 4);
    const b5: uint32 = LoadUint8(dataPointer, offset + 5);
    const b6: uint32 = LoadUint8(dataPointer, offset + 6);
    const b7: uint32 = LoadUint8(dataPointer, offset + 7);
    let lowWord: uint32;
    let highWord: uint32;

    if (requestedLittleEndian) {
      lowWord = (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
      highWord = (b7 << 24) | (b6 << 16) | (b5 << 8) | b4;
    } else {
      highWord = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
      lowWord = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
    }

    return MakeBigInt(lowWord, highWord, signed);
  }

  extern macro ToSmiIndex(Object, Context): Smi
      labels RangeError;
  extern macro DataViewBuiltinsAssembler::DataViewElementSize(
      constexpr ElementsKind): constexpr int31;

  transitioning macro DataViewGet(
      context: Context, receiver: Object, offset: Object,
      requestedLittleEndian: Object, kind: constexpr ElementsKind): Numeric {
    const dataView: JSDataView =
        ValidateDataView(context, receiver, MakeDataViewGetterNameString(kind));

    let getIndex: Number;
    try {
      getIndex = ToIndex(offset, context) otherwise RangeError;
    }
    label RangeError {
      ThrowRangeError(kInvalidDataViewAccessorOffset);
    }

    const littleEndian: bool = ToBoolean(requestedLittleEndian);
    const buffer: JSArrayBuffer = dataView.buffer;

    if (IsDetachedBuffer(buffer)) {
      ThrowTypeError(kDetachedOperation, MakeDataViewGetterNameString(kind));
    }

    const getIndexFloat: float64 = Convert<float64>(getIndex);
    const getIndexWord: uintptr = Convert<uintptr>(getIndexFloat);

    const viewOffsetWord: uintptr = dataView.byte_offset;
    const viewSizeFloat: float64 = Convert<float64>(dataView.byte_length);
    const elementSizeFloat: float64 = DataViewElementSize(kind);

    if (getIndexFloat + elementSizeFloat > viewSizeFloat) {
      ThrowRangeError(kInvalidDataViewAccessorOffset);
    }

    const bufferIndex: uintptr = getIndexWord + viewOffsetWord;

    if constexpr (kind == UINT8_ELEMENTS) {
      return LoadDataView8(buffer, bufferIndex, false);
    } else if constexpr (kind == INT8_ELEMENTS) {
      return LoadDataView8(buffer, bufferIndex, true);
    } else if constexpr (kind == UINT16_ELEMENTS) {
      return LoadDataView16(buffer, bufferIndex, littleEndian, false);
    } else if constexpr (kind == INT16_ELEMENTS) {
      return LoadDataView16(buffer, bufferIndex, littleEndian, true);
    } else if constexpr (kind == UINT32_ELEMENTS) {
      return LoadDataView32(buffer, bufferIndex, littleEndian, kind);
    } else if constexpr (kind == INT32_ELEMENTS) {
      return LoadDataView32(buffer, bufferIndex, littleEndian, kind);
    } else if constexpr (kind == FLOAT32_ELEMENTS) {
      return LoadDataView32(buffer, bufferIndex, littleEndian, kind);
    } else if constexpr (kind == FLOAT64_ELEMENTS) {
      return LoadDataViewFloat64(buffer, bufferIndex, littleEndian);
    } else if constexpr (kind == BIGUINT64_ELEMENTS) {
      return LoadDataViewBigInt(buffer, bufferIndex, littleEndian, false);
    } else if constexpr (kind == BIGINT64_ELEMENTS) {
      return LoadDataViewBigInt(buffer, bufferIndex, littleEndian, true);
    } else {
      unreachable;
    }
  }

  transitioning javascript builtin DataViewPrototypeGetUint8(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    return DataViewGet(context, receiver, offset, Undefined, UINT8_ELEMENTS);
  }

  transitioning javascript builtin DataViewPrototypeGetInt8(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    return DataViewGet(context, receiver, offset, Undefined, INT8_ELEMENTS);
  }

  transitioning javascript builtin DataViewPrototypeGetUint16(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    const isLittleEndian: Object =
        arguments.length > 1 ? arguments[1] : Undefined;
    return DataViewGet(
        context, receiver, offset, isLittleEndian, UINT16_ELEMENTS);
  }

  transitioning javascript builtin DataViewPrototypeGetInt16(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    const isLittleEndian: Object =
        arguments.length > 1 ? arguments[1] : Undefined;
    return DataViewGet(
        context, receiver, offset, isLittleEndian, INT16_ELEMENTS);
  }

  transitioning javascript builtin DataViewPrototypeGetUint32(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    const isLittleEndian: Object =
        arguments.length > 1 ? arguments[1] : Undefined;
    return DataViewGet(
        context, receiver, offset, isLittleEndian, UINT32_ELEMENTS);
  }

  transitioning javascript builtin DataViewPrototypeGetInt32(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    const isLittleEndian: Object =
        arguments.length > 1 ? arguments[1] : Undefined;
    return DataViewGet(
        context, receiver, offset, isLittleEndian, INT32_ELEMENTS);
  }

  transitioning javascript builtin DataViewPrototypeGetFloat32(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    const isLittleEndian: Object =
        arguments.length > 1 ? arguments[1] : Undefined;
    return DataViewGet(
        context, receiver, offset, isLittleEndian, FLOAT32_ELEMENTS);
  }

  transitioning javascript builtin DataViewPrototypeGetFloat64(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    const isLittleEndian: Object =
        arguments.length > 1 ? arguments[1] : Undefined;
    return DataViewGet(
        context, receiver, offset, isLittleEndian, FLOAT64_ELEMENTS);
  }

  transitioning javascript builtin DataViewPrototypeGetBigUint64(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    const isLittleEndian: Object =
        arguments.length > 1 ? arguments[1] : Undefined;
    return DataViewGet(
        context, receiver, offset, isLittleEndian, BIGUINT64_ELEMENTS);
  }

  transitioning javascript builtin DataViewPrototypeGetBigInt64(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    const isLittleEndian: Object =
        arguments.length > 1 ? arguments[1] : Undefined;
    return DataViewGet(
        context, receiver, offset, isLittleEndian, BIGINT64_ELEMENTS);
  }

  extern macro ToNumber(Context, Object): Number;
  extern macro ToBigInt(Context, Object): BigInt;
  extern macro TruncateFloat64ToWord32(float64): uint32;

  extern macro DataViewBuiltinsAssembler::StoreWord8(RawPtr, uintptr, uint32):
      void;

  macro StoreDataView8(buffer: JSArrayBuffer, offset: uintptr, value: uint32) {
    StoreWord8(buffer.backing_store, offset, value & 0xFF);
  }

  macro StoreDataView16(
      buffer: JSArrayBuffer, offset: uintptr, value: uint32,
      requestedLittleEndian: bool) {
    const dataPointer: RawPtr = buffer.backing_store;

    const b0: uint32 = value & 0xFF;
    const b1: uint32 = (value >>> 8) & 0xFF;

    if (requestedLittleEndian) {
      StoreWord8(dataPointer, offset, b0);
      StoreWord8(dataPointer, offset + 1, b1);
    } else {
      StoreWord8(dataPointer, offset, b1);
      StoreWord8(dataPointer, offset + 1, b0);
    }
  }

  macro StoreDataView32(
      buffer: JSArrayBuffer, offset: uintptr, value: uint32,
      requestedLittleEndian: bool) {
    const dataPointer: RawPtr = buffer.backing_store;

    const b0: uint32 = value & 0xFF;
    const b1: uint32 = (value >>> 8) & 0xFF;
    const b2: uint32 = (value >>> 16) & 0xFF;
    const b3: uint32 = value >>> 24;  // We don't need to mask here.

    if (requestedLittleEndian) {
      StoreWord8(dataPointer, offset, b0);
      StoreWord8(dataPointer, offset + 1, b1);
      StoreWord8(dataPointer, offset + 2, b2);
      StoreWord8(dataPointer, offset + 3, b3);
    } else {
      StoreWord8(dataPointer, offset, b3);
      StoreWord8(dataPointer, offset + 1, b2);
      StoreWord8(dataPointer, offset + 2, b1);
      StoreWord8(dataPointer, offset + 3, b0);
    }
  }

  macro StoreDataView64(
      buffer: JSArrayBuffer, offset: uintptr, lowWord: uint32, highWord: uint32,
      requestedLittleEndian: bool) {
    const dataPointer: RawPtr = buffer.backing_store;

    const b0: uint32 = lowWord & 0xFF;
    const b1: uint32 = (lowWord >>> 8) & 0xFF;
    const b2: uint32 = (lowWord >>> 16) & 0xFF;
    const b3: uint32 = lowWord >>> 24;

    const b4: uint32 = highWord & 0xFF;
    const b5: uint32 = (highWord >>> 8) & 0xFF;
    const b6: uint32 = (highWord >>> 16) & 0xFF;
    const b7: uint32 = highWord >>> 24;

    if (requestedLittleEndian) {
      StoreWord8(dataPointer, offset, b0);
      StoreWord8(dataPointer, offset + 1, b1);
      StoreWord8(dataPointer, offset + 2, b2);
      StoreWord8(dataPointer, offset + 3, b3);
      StoreWord8(dataPointer, offset + 4, b4);
      StoreWord8(dataPointer, offset + 5, b5);
      StoreWord8(dataPointer, offset + 6, b6);
      StoreWord8(dataPointer, offset + 7, b7);
    } else {
      StoreWord8(dataPointer, offset, b7);
      StoreWord8(dataPointer, offset + 1, b6);
      StoreWord8(dataPointer, offset + 2, b5);
      StoreWord8(dataPointer, offset + 3, b4);
      StoreWord8(dataPointer, offset + 4, b3);
      StoreWord8(dataPointer, offset + 5, b2);
      StoreWord8(dataPointer, offset + 6, b1);
      StoreWord8(dataPointer, offset + 7, b0);
    }
  }

  extern macro DataViewBuiltinsAssembler::DataViewDecodeBigIntLength(
      BigIntBase): uint32;
  extern macro DataViewBuiltinsAssembler::DataViewDecodeBigIntSign(BigIntBase):
      uint32;

  // We might get here a BigInt that is bigger than 64 bits, but we're only
  // interested in the 64 lowest ones. This means the lowest BigInt digit
  // on 64-bit platforms, and the 2 lowest BigInt digits on 32-bit ones.
  macro StoreDataViewBigInt(
      buffer: JSArrayBuffer, offset: uintptr, bigIntValue: BigInt,
      requestedLittleEndian: bool) {
    const length: uint32 = DataViewDecodeBigIntLength(bigIntValue);
    const sign: uint32 = DataViewDecodeBigIntSign(bigIntValue);

    // The 32-bit words that will hold the BigInt's value in
    // two's complement representation.
    let lowWord: uint32 = 0;
    let highWord: uint32 = 0;

    // The length is nonzero if and only if the BigInt's value is nonzero.
    if (length != 0) {
      if constexpr (Is64()) {
        // There is always exactly 1 BigInt digit to load in this case.
        const value: uintptr = bigint::LoadBigIntDigit(bigIntValue, 0);
        lowWord = Convert<uint32>(value);  // Truncates value to 32 bits.
        highWord = Convert<uint32>(value >>> 32);
      } else {  // There might be either 1 or 2 BigInt digits we need to load.
        lowWord = Convert<uint32>(bigint::LoadBigIntDigit(bigIntValue, 0));
        if (length >= 2) {  // Only load the second digit if there is one.
          highWord = Convert<uint32>(bigint::LoadBigIntDigit(bigIntValue, 1));
        }
      }
    }

    if (sign != 0) {  // The number is negative, Convert it.
      highWord = Unsigned(0 - Signed(highWord));
      if (lowWord != 0) {
        highWord = Unsigned(Signed(highWord) - 1);
      }
      lowWord = Unsigned(0 - Signed(lowWord));
    }

    StoreDataView64(buffer, offset, lowWord, highWord, requestedLittleEndian);
  }

  transitioning macro DataViewSet(
      context: Context, receiver: Object, offset: Object, value: Object,
      requestedLittleEndian: Object, kind: constexpr ElementsKind): Object {
    const dataView: JSDataView =
        ValidateDataView(context, receiver, MakeDataViewSetterNameString(kind));

    let getIndex: Number;
    try {
      getIndex = ToIndex(offset, context) otherwise RangeError;
    }
    label RangeError {
      ThrowRangeError(kInvalidDataViewAccessorOffset);
    }

    const littleEndian: bool = ToBoolean(requestedLittleEndian);
    const buffer: JSArrayBuffer = dataView.buffer;

    // According to ES6 section 24.2.1.2 SetViewValue, we must perform
    // the conversion before doing the bounds check.
    if constexpr (kind == BIGUINT64_ELEMENTS || kind == BIGINT64_ELEMENTS) {
      const bigIntValue: BigInt = ToBigInt(context, value);

      if (IsDetachedBuffer(buffer)) {
        ThrowTypeError(kDetachedOperation, MakeDataViewSetterNameString(kind));
      }

      const getIndexFloat: float64 = Convert<float64>(getIndex);
      const getIndexWord: uintptr = Convert<uintptr>(getIndexFloat);

      const viewOffsetWord: uintptr = dataView.byte_offset;
      const viewSizeFloat: float64 = Convert<float64>(dataView.byte_length);
      const elementSizeFloat: float64 = DataViewElementSize(kind);

      if (getIndexFloat + elementSizeFloat > viewSizeFloat) {
        ThrowRangeError(kInvalidDataViewAccessorOffset);
      }

      const bufferIndex: uintptr = getIndexWord + viewOffsetWord;
      StoreDataViewBigInt(buffer, bufferIndex, bigIntValue, littleEndian);
    } else {
      const numValue: Number = ToNumber(context, value);

      if (IsDetachedBuffer(buffer)) {
        ThrowTypeError(kDetachedOperation, MakeDataViewSetterNameString(kind));
      }

      const getIndexFloat: float64 = Convert<float64>(getIndex);
      const getIndexWord: uintptr = Convert<uintptr>(getIndexFloat);

      const viewOffsetWord: uintptr = dataView.byte_offset;
      const viewSizeFloat: float64 = Convert<float64>(dataView.byte_length);
      const elementSizeFloat: float64 = DataViewElementSize(kind);

      if (getIndexFloat + elementSizeFloat > viewSizeFloat) {
        ThrowRangeError(kInvalidDataViewAccessorOffset);
      }

      const bufferIndex: uintptr = getIndexWord + viewOffsetWord;

      const doubleValue: float64 = ChangeNumberToFloat64(numValue);

      if constexpr (kind == UINT8_ELEMENTS || kind == INT8_ELEMENTS) {
        StoreDataView8(
            buffer, bufferIndex, TruncateFloat64ToWord32(doubleValue));
      } else if constexpr (kind == UINT16_ELEMENTS || kind == INT16_ELEMENTS) {
        StoreDataView16(
            buffer, bufferIndex, TruncateFloat64ToWord32(doubleValue),
            littleEndian);
      } else if constexpr (kind == UINT32_ELEMENTS || kind == INT32_ELEMENTS) {
        StoreDataView32(
            buffer, bufferIndex, TruncateFloat64ToWord32(doubleValue),
            littleEndian);
      } else if constexpr (kind == FLOAT32_ELEMENTS) {
        const floatValue: float32 = TruncateFloat64ToFloat32(doubleValue);
        StoreDataView32(
            buffer, bufferIndex, BitcastFloat32ToInt32(floatValue),
            littleEndian);
      } else if constexpr (kind == FLOAT64_ELEMENTS) {
        const lowWord: uint32 = Float64ExtractLowWord32(doubleValue);
        const highWord: uint32 = Float64ExtractHighWord32(doubleValue);
        StoreDataView64(buffer, bufferIndex, lowWord, highWord, littleEndian);
      }
    }
    return Undefined;
  }

  transitioning javascript builtin DataViewPrototypeSetUint8(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    const value: Object = arguments.length > 1 ? arguments[1] : Undefined;
    return DataViewSet(
        context, receiver, offset, value, Undefined, UINT8_ELEMENTS);
  }

  transitioning javascript builtin DataViewPrototypeSetInt8(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    const value: Object = arguments.length > 1 ? arguments[1] : Undefined;
    return DataViewSet(
        context, receiver, offset, value, Undefined, INT8_ELEMENTS);
  }

  transitioning javascript builtin DataViewPrototypeSetUint16(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    const value: Object = arguments.length > 1 ? arguments[1] : Undefined;
    const isLittleEndian: Object =
        arguments.length > 2 ? arguments[2] : Undefined;
    return DataViewSet(
        context, receiver, offset, value, isLittleEndian, UINT16_ELEMENTS);
  }

  transitioning javascript builtin DataViewPrototypeSetInt16(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    const value: Object = arguments.length > 1 ? arguments[1] : Undefined;
    const isLittleEndian: Object =
        arguments.length > 2 ? arguments[2] : Undefined;
    return DataViewSet(
        context, receiver, offset, value, isLittleEndian, INT16_ELEMENTS);
  }

  transitioning javascript builtin DataViewPrototypeSetUint32(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    const value: Object = arguments.length > 1 ? arguments[1] : Undefined;
    const isLittleEndian: Object =
        arguments.length > 2 ? arguments[2] : Undefined;
    return DataViewSet(
        context, receiver, offset, value, isLittleEndian, UINT32_ELEMENTS);
  }

  transitioning javascript builtin DataViewPrototypeSetInt32(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    const value: Object = arguments.length > 1 ? arguments[1] : Undefined;
    const isLittleEndian: Object =
        arguments.length > 2 ? arguments[2] : Undefined;
    return DataViewSet(
        context, receiver, offset, value, isLittleEndian, INT32_ELEMENTS);
  }

  transitioning javascript builtin DataViewPrototypeSetFloat32(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    const value: Object = arguments.length > 1 ? arguments[1] : Undefined;
    const isLittleEndian: Object =
        arguments.length > 2 ? arguments[2] : Undefined;
    return DataViewSet(
        context, receiver, offset, value, isLittleEndian, FLOAT32_ELEMENTS);
  }

  transitioning javascript builtin DataViewPrototypeSetFloat64(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    const value: Object = arguments.length > 1 ? arguments[1] : Undefined;
    const isLittleEndian: Object =
        arguments.length > 2 ? arguments[2] : Undefined;
    return DataViewSet(
        context, receiver, offset, value, isLittleEndian, FLOAT64_ELEMENTS);
  }

  transitioning javascript builtin DataViewPrototypeSetBigUint64(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    const value: Object = arguments.length > 1 ? arguments[1] : Undefined;
    const isLittleEndian: Object =
        arguments.length > 2 ? arguments[2] : Undefined;
    return DataViewSet(
        context, receiver, offset, value, isLittleEndian, BIGUINT64_ELEMENTS);
  }

  transitioning javascript builtin DataViewPrototypeSetBigInt64(
      js-implicit context: Context, receiver: Object)(...arguments): Object {
    const offset: Object = arguments.length > 0 ? arguments[0] : Undefined;
    const value: Object = arguments.length > 1 ? arguments[1] : Undefined;
    const isLittleEndian: Object =
        arguments.length > 2 ? arguments[2] : Undefined;
    return DataViewSet(
        context, receiver, offset, value, isLittleEndian, BIGINT64_ELEMENTS);
  }
}
