// 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 == ElementsKind::UINT8_ELEMENTS) {
    return 'DataView.prototype.getUint8';
  } else if constexpr (kind == ElementsKind::INT8_ELEMENTS) {
    return 'DataView.prototype.getInt8';
  } else if constexpr (kind == ElementsKind::UINT16_ELEMENTS) {
    return 'DataView.prototype.getUint16';
  } else if constexpr (kind == ElementsKind::INT16_ELEMENTS) {
    return 'DataView.prototype.getInt16';
  } else if constexpr (kind == ElementsKind::UINT32_ELEMENTS) {
    return 'DataView.prototype.getUint32';
  } else if constexpr (kind == ElementsKind::INT32_ELEMENTS) {
    return 'DataView.prototype.getInt32';
  } else if constexpr (kind == ElementsKind::FLOAT32_ELEMENTS) {
    return 'DataView.prototype.getFloat32';
  } else if constexpr (kind == ElementsKind::FLOAT64_ELEMENTS) {
    return 'DataView.prototype.getFloat64';
  } else if constexpr (kind == ElementsKind::BIGINT64_ELEMENTS) {
    return 'DataView.prototype.getBigInt64';
  } else if constexpr (kind == ElementsKind::BIGUINT64_ELEMENTS) {
    return 'DataView.prototype.getBigUint64';
  } else {
    unreachable;
  }
}

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

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

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

// ES6 section 24.2.4.1 get DataView.prototype.buffer
javascript builtin DataViewPrototypeGetBuffer(
    js-implicit context: NativeContext,
    receiver: JSAny)(...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: NativeContext, receiver: JSAny)(...arguments): Number {
  const dataView: JSDataView =
      ValidateDataView(context, receiver, 'get DataView.prototype.byte_length');
  if (WasDetached(dataView)) {
    // TODO(bmeurer): According to the ES6 spec, we should throw a TypeError
    // here if the JSArrayBuffer of the {dataView} was detached.
    return 0;
  }
  return Convert<Number>(dataView.byte_length);
}

// ES6 section 24.2.4.3 get DataView.prototype.byteOffset
javascript builtin DataViewPrototypeGetByteOffset(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): Number {
  const dataView: JSDataView =
      ValidateDataView(context, receiver, 'get DataView.prototype.byte_offset');
  if (WasDetached(dataView)) {
    // TODO(bmeurer): According to the ES6 spec, we should throw a TypeError
    // here if the JSArrayBuffer of the {dataView} was detached.
    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_ptr, offset));
  } else {
    return Convert<Smi>(LoadUint8(buffer.backing_store_ptr, offset));
  }
}

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

  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_ptr;

  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 == ElementsKind::INT32_ELEMENTS) {
    return Convert<Number>(Signed(result));
  } else if constexpr (kind == ElementsKind::UINT32_ELEMENTS) {
    return Convert<Number>(result);
  } else if constexpr (kind == ElementsKind::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_ptr;

  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_ptr;

  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 DataViewBuiltinsAssembler::DataViewElementSize(
    constexpr ElementsKind): constexpr int31;

// GetViewValue ( view, requestIndex, isLittleEndian, type )
// https://tc39.es/ecma262/#sec-getviewvalue
transitioning macro DataViewGet(
    context: Context, receiver: JSAny, requestIndex: JSAny,
    requestedLittleEndian: JSAny, kind: constexpr ElementsKind): Numeric {
  // 1. Perform ? RequireInternalSlot(view, [[DataView]]).
  // 2. Assert: view has a [[ViewedArrayBuffer]] internal slot.
  const dataView: JSDataView =
      ValidateDataView(context, receiver, MakeDataViewGetterNameString(kind));

  try {
    // 3. Let getIndex be ? ToIndex(requestIndex).
    const getIndex: uintptr = ToIndex(requestIndex) otherwise RangeError;

    // 4. Set isLittleEndian to ! ToBoolean(isLittleEndian).
    const littleEndian: bool = ToBoolean(requestedLittleEndian);

    // 5. Let buffer be view.[[ViewedArrayBuffer]].
    const buffer: JSArrayBuffer = dataView.buffer;

    // 6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
    if (IsDetachedBuffer(buffer)) {
      ThrowTypeError(
          MessageTemplate::kDetachedOperation,
          MakeDataViewGetterNameString(kind));
    }

    // 7. Let viewOffset be view.[[ByteOffset]].
    const viewOffset: uintptr = dataView.byte_offset;

    // 8. Let viewSize be view.[[ByteLength]].
    const viewSize: uintptr = dataView.byte_length;

    // 9. Let elementSize be the Element Size value specified in Table 62
    // for Element Type type.
    const elementSize: uintptr = DataViewElementSize(kind);

    // 10. If getIndex + elementSize > viewSize, throw a RangeError exception.
    CheckIntegerIndexAdditionOverflow(getIndex, elementSize, viewSize)
        otherwise RangeError;

    // 11. Let bufferIndex be getIndex + viewOffset.
    const bufferIndex: uintptr = getIndex + viewOffset;

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

transitioning javascript builtin DataViewPrototypeGetUint8(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  return DataViewGet(
      context, receiver, offset, Undefined, ElementsKind::UINT8_ELEMENTS);
}

transitioning javascript builtin DataViewPrototypeGetInt8(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  return DataViewGet(
      context, receiver, offset, Undefined, ElementsKind::INT8_ELEMENTS);
}

transitioning javascript builtin DataViewPrototypeGetUint16(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  const isLittleEndian: JSAny = arguments[1];
  return DataViewGet(
      context, receiver, offset, isLittleEndian, ElementsKind::UINT16_ELEMENTS);
}

transitioning javascript builtin DataViewPrototypeGetInt16(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  const isLittleEndian: JSAny = arguments[1];
  return DataViewGet(
      context, receiver, offset, isLittleEndian, ElementsKind::INT16_ELEMENTS);
}

transitioning javascript builtin DataViewPrototypeGetUint32(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  const isLittleEndian: JSAny = arguments[1];
  return DataViewGet(
      context, receiver, offset, isLittleEndian, ElementsKind::UINT32_ELEMENTS);
}

transitioning javascript builtin DataViewPrototypeGetInt32(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  const isLittleEndian: JSAny = arguments[1];
  return DataViewGet(
      context, receiver, offset, isLittleEndian, ElementsKind::INT32_ELEMENTS);
}

transitioning javascript builtin DataViewPrototypeGetFloat32(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  const isLittleEndian: JSAny = arguments[1];
  return DataViewGet(
      context, receiver, offset, isLittleEndian,
      ElementsKind::FLOAT32_ELEMENTS);
}

transitioning javascript builtin DataViewPrototypeGetFloat64(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  const isLittleEndian: JSAny = arguments[1];
  return DataViewGet(
      context, receiver, offset, isLittleEndian,
      ElementsKind::FLOAT64_ELEMENTS);
}

transitioning javascript builtin DataViewPrototypeGetBigUint64(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  const isLittleEndian: JSAny = arguments[1];
  return DataViewGet(
      context, receiver, offset, isLittleEndian,
      ElementsKind::BIGUINT64_ELEMENTS);
}

transitioning javascript builtin DataViewPrototypeGetBigInt64(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  const isLittleEndian: JSAny = arguments[1];
  return DataViewGet(
      context, receiver, offset, isLittleEndian,
      ElementsKind::BIGINT64_ELEMENTS);
}

extern macro ToNumber(Context, JSAny): Number;
extern macro ToBigInt(Context, JSAny): 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_ptr, offset, value & 0xFF);
}

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

  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_ptr;

  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_ptr;

  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);
}

// SetViewValue ( view, requestIndex, isLittleEndian, type, value )
// https://tc39.es/ecma262/#sec-setviewvalue
transitioning macro DataViewSet(
    context: Context, receiver: JSAny, requestIndex: JSAny, value: JSAny,
    requestedLittleEndian: JSAny, kind: constexpr ElementsKind): JSAny {
  // 1. Perform ? RequireInternalSlot(view, [[DataView]]).
  // 2. Assert: view has a [[ViewedArrayBuffer]] internal slot.
  const dataView: JSDataView =
      ValidateDataView(context, receiver, MakeDataViewSetterNameString(kind));

  try {
    // 3. Let getIndex be ? ToIndex(requestIndex).
    const getIndex: uintptr = ToIndex(requestIndex) otherwise RangeError;

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

    let numberValue: Numeric;
    if constexpr (
        kind == ElementsKind::BIGUINT64_ELEMENTS ||
        kind == ElementsKind::BIGINT64_ELEMENTS) {
      // 4. If ! IsBigIntElementType(type) is true, let numberValue be
      // ? ToBigInt(value).
      numberValue = ToBigInt(context, value);
    } else {
      // 5. Otherwise, let numberValue be ? ToNumber(value).
      numberValue = ToNumber(context, value);
    }

    // 6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
    if (IsDetachedBuffer(buffer)) {
      ThrowTypeError(
          MessageTemplate::kDetachedOperation,
          MakeDataViewSetterNameString(kind));
    }

    // 9. Let viewOffset be view.[[ByteOffset]].
    const viewOffset: uintptr = dataView.byte_offset;

    // 10. Let viewSize be view.[[ByteLength]].
    const viewSize: uintptr = dataView.byte_length;

    // 11. Let elementSize be the Element Size value specified in Table 62
    // for Element Type type.
    const elementSize: uintptr = DataViewElementSize(kind);

    // 12. If getIndex + elementSize > viewSize, throw a RangeError exception.
    CheckIntegerIndexAdditionOverflow(getIndex, elementSize, viewSize)
        otherwise RangeError;

    // 13. Let bufferIndex be getIndex + viewOffset.
    const bufferIndex: uintptr = getIndex + viewOffset;

    if constexpr (
        kind == ElementsKind::BIGUINT64_ELEMENTS ||
        kind == ElementsKind::BIGINT64_ELEMENTS) {
      // For these elements kinds numberValue is BigInt.
      const bigIntValue: BigInt = %RawDownCast<BigInt>(numberValue);
      StoreDataViewBigInt(buffer, bufferIndex, bigIntValue, littleEndian);
    } else {
      // For these elements kinds numberValue is Number.
      const numValue: Number = %RawDownCast<Number>(numberValue);
      const doubleValue: float64 = ChangeNumberToFloat64(numValue);

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

transitioning javascript builtin DataViewPrototypeSetUint8(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  const value: JSAny = arguments[1];
  return DataViewSet(
      context, receiver, offset, value, Undefined,
      ElementsKind::UINT8_ELEMENTS);
}

transitioning javascript builtin DataViewPrototypeSetInt8(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  const value: JSAny = arguments[1];
  return DataViewSet(
      context, receiver, offset, value, Undefined, ElementsKind::INT8_ELEMENTS);
}

transitioning javascript builtin DataViewPrototypeSetUint16(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  const value: JSAny = arguments[1];
  const isLittleEndian: JSAny = arguments[2];
  return DataViewSet(
      context, receiver, offset, value, isLittleEndian,
      ElementsKind::UINT16_ELEMENTS);
}

transitioning javascript builtin DataViewPrototypeSetInt16(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  const value: JSAny = arguments[1];
  const isLittleEndian: JSAny = arguments[2];
  return DataViewSet(
      context, receiver, offset, value, isLittleEndian,
      ElementsKind::INT16_ELEMENTS);
}

transitioning javascript builtin DataViewPrototypeSetUint32(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  const value: JSAny = arguments[1];
  const isLittleEndian: JSAny = arguments[2];
  return DataViewSet(
      context, receiver, offset, value, isLittleEndian,
      ElementsKind::UINT32_ELEMENTS);
}

transitioning javascript builtin DataViewPrototypeSetInt32(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  const value: JSAny = arguments[1];
  const isLittleEndian: JSAny = arguments[2];
  return DataViewSet(
      context, receiver, offset, value, isLittleEndian,
      ElementsKind::INT32_ELEMENTS);
}

transitioning javascript builtin DataViewPrototypeSetFloat32(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  const value: JSAny = arguments[1];
  const isLittleEndian: JSAny = arguments[2];
  return DataViewSet(
      context, receiver, offset, value, isLittleEndian,
      ElementsKind::FLOAT32_ELEMENTS);
}

transitioning javascript builtin DataViewPrototypeSetFloat64(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  const value: JSAny = arguments[1];
  const isLittleEndian: JSAny = arguments[2];
  return DataViewSet(
      context, receiver, offset, value, isLittleEndian,
      ElementsKind::FLOAT64_ELEMENTS);
}

transitioning javascript builtin DataViewPrototypeSetBigUint64(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  const value: JSAny = arguments[1];
  const isLittleEndian: JSAny = arguments[2];
  return DataViewSet(
      context, receiver, offset, value, isLittleEndian,
      ElementsKind::BIGUINT64_ELEMENTS);
}

transitioning javascript builtin DataViewPrototypeSetBigInt64(
    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
  const offset: JSAny = arguments[0];
  const value: JSAny = arguments[1];
  const isLittleEndian: JSAny = arguments[2];
  return DataViewSet(
      context, receiver, offset, value, isLittleEndian,
      ElementsKind::BIGINT64_ELEMENTS);
}
}
