// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Specialized integers and floating point numbers,
 * with SIMD support and efficient lists.
 */
library dart.typed_data.implementation;

import 'dart:collection';
import 'dart:_internal';
import 'dart:_interceptors' show JSIndexable;
import 'dart:_js_helper'
    show
        Creates,
        JavaScriptIndexingBehavior,
        JSName,
        Native,
        Null,
        Returns,
        diagnoseIndexError,
        diagnoseRangeError;
import 'dart:_foreign_helper' show JS;
import 'dart:math' as Math;

import 'dart:typed_data';

@Native("ArrayBuffer")
class NativeByteBuffer implements ByteBuffer {
  @JSName('byteLength')
  external int get lengthInBytes;

  Type get runtimeType => ByteBuffer;

  Uint8List asUint8List([int offsetInBytes = 0, int length]) {
    return NativeUint8List.view(this, offsetInBytes, length);
  }

  Int8List asInt8List([int offsetInBytes = 0, int length]) {
    return NativeInt8List.view(this, offsetInBytes, length);
  }

  Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int length]) {
    return NativeUint8ClampedList.view(this, offsetInBytes, length);
  }

  Uint16List asUint16List([int offsetInBytes = 0, int length]) {
    return NativeUint16List.view(this, offsetInBytes, length);
  }

  Int16List asInt16List([int offsetInBytes = 0, int length]) {
    return NativeInt16List.view(this, offsetInBytes, length);
  }

  Uint32List asUint32List([int offsetInBytes = 0, int length]) {
    return NativeUint32List.view(this, offsetInBytes, length);
  }

  Int32List asInt32List([int offsetInBytes = 0, int length]) {
    return NativeInt32List.view(this, offsetInBytes, length);
  }

  Uint64List asUint64List([int offsetInBytes = 0, int length]) {
    throw UnsupportedError("Uint64List not supported by dart2js.");
  }

  Int64List asInt64List([int offsetInBytes = 0, int length]) {
    throw UnsupportedError("Int64List not supported by dart2js.");
  }

  Int32x4List asInt32x4List([int offsetInBytes = 0, int length]) {
    NativeInt32List storage =
        this.asInt32List(offsetInBytes, length != null ? length * 4 : null);
    return NativeInt32x4List._externalStorage(storage);
  }

  Float32List asFloat32List([int offsetInBytes = 0, int length]) {
    return NativeFloat32List.view(this, offsetInBytes, length);
  }

  Float64List asFloat64List([int offsetInBytes = 0, int length]) {
    return NativeFloat64List.view(this, offsetInBytes, length);
  }

  Float32x4List asFloat32x4List([int offsetInBytes = 0, int length]) {
    NativeFloat32List storage =
        this.asFloat32List(offsetInBytes, length != null ? length * 4 : null);
    return NativeFloat32x4List._externalStorage(storage);
  }

  Float64x2List asFloat64x2List([int offsetInBytes = 0, int length]) {
    NativeFloat64List storage =
        this.asFloat64List(offsetInBytes, length != null ? length * 2 : null);
    return NativeFloat64x2List._externalStorage(storage);
  }

  ByteData asByteData([int offsetInBytes = 0, int length]) {
    return NativeByteData.view(this, offsetInBytes, length);
  }
}

/**
 * A fixed-length list of Float32x4 numbers that is viewable as a
 * [TypedData]. For long lists, this implementation will be considerably more
 * space- and time-efficient than the default [List] implementation.
 */
class NativeFloat32x4List extends Object
    with ListMixin<Float32x4>, FixedLengthListMixin<Float32x4>
    implements Float32x4List {
  final NativeFloat32List _storage;

  /**
   * Creates a [Float32x4List] of the specified length (in elements),
   * all of whose elements are initially zero.
   */
  NativeFloat32x4List(int length) : _storage = NativeFloat32List(length * 4);

  NativeFloat32x4List._externalStorage(this._storage);

  NativeFloat32x4List._slowFromList(List<Float32x4> list)
      : _storage = NativeFloat32List(list.length * 4) {
    for (int i = 0; i < list.length; i++) {
      var e = list[i];
      _storage[(i * 4) + 0] = e.x;
      _storage[(i * 4) + 1] = e.y;
      _storage[(i * 4) + 2] = e.z;
      _storage[(i * 4) + 3] = e.w;
    }
  }

  Type get runtimeType => Float32x4List;

  /**
   * Creates a [Float32x4List] with the same size as the [elements] list
   * and copies over the elements.
   */
  factory NativeFloat32x4List.fromList(List<Float32x4> list) {
    if (list is NativeFloat32x4List) {
      return NativeFloat32x4List._externalStorage(
          NativeFloat32List.fromList(list._storage));
    } else {
      return NativeFloat32x4List._slowFromList(list);
    }
  }

  ByteBuffer get buffer => _storage.buffer;

  int get lengthInBytes => _storage.lengthInBytes;

  int get offsetInBytes => _storage.offsetInBytes;

  int get elementSizeInBytes => Float32x4List.bytesPerElement;

  int get length => _storage.length ~/ 4;

  Float32x4 operator [](int index) {
    _checkValidIndex(index, this, this.length);
    double _x = _storage[(index * 4) + 0];
    double _y = _storage[(index * 4) + 1];
    double _z = _storage[(index * 4) + 2];
    double _w = _storage[(index * 4) + 3];
    return NativeFloat32x4._truncated(_x, _y, _z, _w);
  }

  void operator []=(int index, Float32x4 value) {
    _checkValidIndex(index, this, this.length);
    _storage[(index * 4) + 0] = value.x;
    _storage[(index * 4) + 1] = value.y;
    _storage[(index * 4) + 2] = value.z;
    _storage[(index * 4) + 3] = value.w;
  }

  Float32x4List sublist(int start, [int end]) {
    end = _checkValidRange(start, end, this.length);
    return NativeFloat32x4List._externalStorage(
        _storage.sublist(start * 4, end * 4));
  }
}

/**
 * A fixed-length list of Int32x4 numbers that is viewable as a
 * [TypedData]. For long lists, this implementation will be considerably more
 * space- and time-efficient than the default [List] implementation.
 */
class NativeInt32x4List extends Object
    with ListMixin<Int32x4>, FixedLengthListMixin<Int32x4>
    implements Int32x4List {
  final Int32List _storage;

  /**
   * Creates a [Int32x4List] of the specified length (in elements),
   * all of whose elements are initially zero.
   */
  NativeInt32x4List(int length) : _storage = NativeInt32List(length * 4);

  NativeInt32x4List._externalStorage(Int32List storage) : _storage = storage;

  NativeInt32x4List._slowFromList(List<Int32x4> list)
      : _storage = NativeInt32List(list.length * 4) {
    for (int i = 0; i < list.length; i++) {
      var e = list[i];
      _storage[(i * 4) + 0] = e.x;
      _storage[(i * 4) + 1] = e.y;
      _storage[(i * 4) + 2] = e.z;
      _storage[(i * 4) + 3] = e.w;
    }
  }

  Type get runtimeType => Int32x4List;

  /**
   * Creates a [Int32x4List] with the same size as the [elements] list
   * and copies over the elements.
   */
  factory NativeInt32x4List.fromList(List<Int32x4> list) {
    if (list is NativeInt32x4List) {
      return NativeInt32x4List._externalStorage(
          NativeInt32List.fromList(list._storage));
    } else {
      return NativeInt32x4List._slowFromList(list);
    }
  }

  ByteBuffer get buffer => _storage.buffer;

  int get lengthInBytes => _storage.lengthInBytes;

  int get offsetInBytes => _storage.offsetInBytes;

  int get elementSizeInBytes => Int32x4List.bytesPerElement;

  int get length => _storage.length ~/ 4;

  Int32x4 operator [](int index) {
    _checkValidIndex(index, this, this.length);
    int _x = _storage[(index * 4) + 0];
    int _y = _storage[(index * 4) + 1];
    int _z = _storage[(index * 4) + 2];
    int _w = _storage[(index * 4) + 3];
    return NativeInt32x4._truncated(_x, _y, _z, _w);
  }

  void operator []=(int index, Int32x4 value) {
    _checkValidIndex(index, this, this.length);
    _storage[(index * 4) + 0] = value.x;
    _storage[(index * 4) + 1] = value.y;
    _storage[(index * 4) + 2] = value.z;
    _storage[(index * 4) + 3] = value.w;
  }

  Int32x4List sublist(int start, [int end]) {
    end = _checkValidRange(start, end, this.length);
    return NativeInt32x4List._externalStorage(
        _storage.sublist(start * 4, end * 4));
  }
}

/**
 * A fixed-length list of Float64x2 numbers that is viewable as a
 * [TypedData]. For long lists, this implementation will be considerably more
 * space- and time-efficient than the default [List] implementation.
 */
class NativeFloat64x2List extends Object
    with ListMixin<Float64x2>, FixedLengthListMixin<Float64x2>
    implements Float64x2List {
  final NativeFloat64List _storage;

  /**
   * Creates a [Float64x2List] of the specified length (in elements),
   * all of whose elements are initially zero.
   */
  NativeFloat64x2List(int length) : _storage = NativeFloat64List(length * 2);

  NativeFloat64x2List._externalStorage(this._storage);

  NativeFloat64x2List._slowFromList(List<Float64x2> list)
      : _storage = NativeFloat64List(list.length * 2) {
    for (int i = 0; i < list.length; i++) {
      var e = list[i];
      _storage[(i * 2) + 0] = e.x;
      _storage[(i * 2) + 1] = e.y;
    }
  }

  /**
   * Creates a [Float64x2List] with the same size as the [elements] list
   * and copies over the elements.
   */
  factory NativeFloat64x2List.fromList(List<Float64x2> list) {
    if (list is NativeFloat64x2List) {
      return NativeFloat64x2List._externalStorage(
          NativeFloat64List.fromList(list._storage));
    } else {
      return NativeFloat64x2List._slowFromList(list);
    }
  }

  Type get runtimeType => Float64x2List;

  ByteBuffer get buffer => _storage.buffer;

  int get lengthInBytes => _storage.lengthInBytes;

  int get offsetInBytes => _storage.offsetInBytes;

  int get elementSizeInBytes => Float64x2List.bytesPerElement;

  int get length => _storage.length ~/ 2;

  Float64x2 operator [](int index) {
    _checkValidIndex(index, this, this.length);
    double _x = _storage[(index * 2) + 0];
    double _y = _storage[(index * 2) + 1];
    return Float64x2(_x, _y);
  }

  void operator []=(int index, Float64x2 value) {
    _checkValidIndex(index, this, this.length);
    _storage[(index * 2) + 0] = value.x;
    _storage[(index * 2) + 1] = value.y;
  }

  Float64x2List sublist(int start, [int end]) {
    end = _checkValidRange(start, end, this.length);
    return NativeFloat64x2List._externalStorage(
        _storage.sublist(start * 2, end * 2));
  }
}

@Native("ArrayBufferView")
class NativeTypedData implements TypedData {
  /**
   * Returns the byte buffer associated with this object.
   */
  @Creates('NativeByteBuffer')
  // May be Null for IE's CanvasPixelArray.
  @Returns('NativeByteBuffer|Null')
  external ByteBuffer get buffer;

  /**
   * Returns the length of this view, in bytes.
   */
  @JSName('byteLength')
  external int get lengthInBytes;

  /**
   * Returns the offset in bytes into the underlying byte buffer of this view.
   */
  @JSName('byteOffset')
  external int get offsetInBytes;

  /**
   * Returns the number of bytes in the representation of each element in this
   * list.
   */
  @JSName('BYTES_PER_ELEMENT')
  external int get elementSizeInBytes;

  void _invalidPosition(int position, int length, String name) {
    if (position is! int) {
      throw ArgumentError.value(position, name, 'Invalid list position');
    } else {
      throw RangeError.range(position, 0, length, name);
    }
  }

  void _checkPosition(int position, int length, String name) {
    if (JS('bool', '(# >>> 0) !== #', position, position) ||
        JS('int', '#', position) > length) {
      // 'int' guaranteed by above test.
      _invalidPosition(position, length, name);
    }
  }
}

// Validates the unnamed constructor length argument.  Checking is necessary
// because passing unvalidated values to the native constructors can cause
// conversions or create views.
int _checkLength(length) {
  if (length is! int) throw ArgumentError('Invalid length $length');
  return length;
}

// Validates `.view` constructor arguments.  Checking is necessary because
// passing unvalidated values to the native constructors can cause conversions
// (e.g. String arguments) or create typed data objects that are not actually
// views of the input.
void _checkViewArguments(buffer, offsetInBytes, length) {
  if (buffer is! NativeByteBuffer) {
    throw ArgumentError('Invalid view buffer');
  }
  if (offsetInBytes is! int) {
    throw ArgumentError('Invalid view offsetInBytes $offsetInBytes');
  }
  if (length != null && length is! int) {
    throw ArgumentError('Invalid view length $length');
  }
}

// Ensures that [list] is a JavaScript Array or a typed array.  If necessary,
// returns a copy of the list.
List _ensureNativeList(List list) {
  if (list is JSIndexable) return list;
  List result = List(list.length);
  for (int i = 0; i < list.length; i++) {
    result[i] = list[i];
  }
  return result;
}

@Native("DataView")
class NativeByteData extends NativeTypedData implements ByteData {
  /**
   * Creates a [ByteData] of the specified length (in elements), all of
   * whose elements are initially zero.
   */
  factory NativeByteData(int length) => _create1(_checkLength(length));

  /**
   * Creates an [ByteData] _view_ of the specified region in the specified
   * byte buffer. Changes in the [ByteData] will be visible in the byte
   * buffer and vice versa. If the [offsetInBytes] index of the region is not
   * specified, it defaults to zero (the first byte in the byte buffer).
   * If the length is not specified, it defaults to null, which indicates
   * that the view extends to the end of the byte buffer.
   *
   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
   * the length of [buffer].
   */
  factory NativeByteData.view(
      ByteBuffer buffer, int offsetInBytes, int length) {
    _checkViewArguments(buffer, offsetInBytes, length);
    return length == null
        ? _create2(buffer, offsetInBytes)
        : _create3(buffer, offsetInBytes, length);
  }

  Type get runtimeType => ByteData;

  int get elementSizeInBytes => 1;

  /**
   * Returns the floating point number represented by the four bytes at
   * the specified [byteOffset] in this object, in IEEE 754
   * single-precision binary floating-point format (binary32).
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 4` is greater than the length of this object.
   */
  double getFloat32(int byteOffset, [Endian endian = Endian.big]) =>
      _getFloat32(byteOffset, Endian.little == endian);

  @JSName('getFloat32')
  @Returns('double')
  double _getFloat32(int byteOffset, [bool littleEndian]) native;

  /**
   * Returns the floating point number represented by the eight bytes at
   * the specified [byteOffset] in this object, in IEEE 754
   * double-precision binary floating-point format (binary64).
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 8` is greater than the length of this object.
   */
  double getFloat64(int byteOffset, [Endian endian = Endian.big]) =>
      _getFloat64(byteOffset, Endian.little == endian);

  @JSName('getFloat64')
  @Returns('double')
  double _getFloat64(int byteOffset, [bool littleEndian]) native;

  /**
   * Returns the (possibly negative) integer represented by the two bytes at
   * the specified [byteOffset] in this object, in two's complement binary
   * form.
   * The return value will be between 2<sup>15</sup> and 2<sup>15</sup> - 1,
   * inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 2` is greater than the length of this object.
   */
  int getInt16(int byteOffset, [Endian endian = Endian.big]) =>
      _getInt16(byteOffset, Endian.little == endian);

  @JSName('getInt16')
  @Returns('int')
  int _getInt16(int byteOffset, [bool littleEndian]) native;

  /**
   * Returns the (possibly negative) integer represented by the four bytes at
   * the specified [byteOffset] in this object, in two's complement binary
   * form.
   * The return value will be between 2<sup>31</sup> and 2<sup>31</sup> - 1,
   * inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 4` is greater than the length of this object.
   */
  int getInt32(int byteOffset, [Endian endian = Endian.big]) =>
      _getInt32(byteOffset, Endian.little == endian);

  @JSName('getInt32')
  @Returns('int')
  int _getInt32(int byteOffset, [bool littleEndian]) native;

  /**
   * Returns the (possibly negative) integer represented by the eight bytes at
   * the specified [byteOffset] in this object, in two's complement binary
   * form.
   * The return value will be between 2<sup>63</sup> and 2<sup>63</sup> - 1,
   * inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 8` is greater than the length of this object.
   */
  int getInt64(int byteOffset, [Endian endian = Endian.big]) {
    throw UnsupportedError('Int64 accessor not supported by dart2js.');
  }

  /**
   * Returns the (possibly negative) integer represented by the byte at the
   * specified [byteOffset] in this object, in two's complement binary
   * representation. The return value will be between -128 and 127, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * greater than or equal to the length of this object.
   */
  int getInt8(int byteOffset) native;

  /**
   * Returns the positive integer represented by the two bytes starting
   * at the specified [byteOffset] in this object, in unsigned binary
   * form.
   * The return value will be between 0 and  2<sup>16</sup> - 1, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 2` is greater than the length of this object.
   */
  int getUint16(int byteOffset, [Endian endian = Endian.big]) =>
      _getUint16(byteOffset, Endian.little == endian);

  @JSName('getUint16')
  @Returns('int')
  int _getUint16(int byteOffset, [bool littleEndian]) native;

  /**
   * Returns the positive integer represented by the four bytes starting
   * at the specified [byteOffset] in this object, in unsigned binary
   * form.
   * The return value will be between 0 and  2<sup>32</sup> - 1, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 4` is greater than the length of this object.
   */
  int getUint32(int byteOffset, [Endian endian = Endian.big]) =>
      _getUint32(byteOffset, Endian.little == endian);

  @JSName('getUint32')
  @Returns('int')
  int _getUint32(int byteOffset, [bool littleEndian]) native;

  /**
   * Returns the positive integer represented by the eight bytes starting
   * at the specified [byteOffset] in this object, in unsigned binary
   * form.
   * The return value will be between 0 and  2<sup>64</sup> - 1, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 8` is greater than the length of this object.
   */
  int getUint64(int byteOffset, [Endian endian = Endian.big]) {
    throw UnsupportedError('Uint64 accessor not supported by dart2js.');
  }

  /**
   * Returns the positive integer represented by the byte at the specified
   * [byteOffset] in this object, in unsigned binary form. The
   * return value will be between 0 and 255, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * greater than or equal to the length of this object.
   */
  int getUint8(int byteOffset) native;

  /**
   * Sets the four bytes starting at the specified [byteOffset] in this
   * object to the IEEE 754 single-precision binary floating-point
   * (binary32) representation of the specified [value].
   *
   * **Note that this method can lose precision.** The input [value] is
   * a 64-bit floating point value, which will be converted to 32-bit
   * floating point value by IEEE 754 rounding rules before it is stored.
   * If [value] cannot be represented exactly as a binary32, it will be
   * converted to the nearest binary32 value.  If two binary32 values are
   * equally close, the one whose least significant bit is zero will be used.
   * Note that finite (but large) values can be converted to infinity, and
   * small non-zero values can be converted to zero.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 4` is greater than the length of this object.
   */
  void setFloat32(int byteOffset, num value, [Endian endian = Endian.big]) =>
      _setFloat32(byteOffset, value, Endian.little == endian);

  @JSName('setFloat32')
  void _setFloat32(int byteOffset, num value, [bool littleEndian]) native;

  /**
   * Sets the eight bytes starting at the specified [byteOffset] in this
   * object to the IEEE 754 double-precision binary floating-point
   * (binary64) representation of the specified [value].
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 8` is greater than the length of this object.
   */
  void setFloat64(int byteOffset, num value, [Endian endian = Endian.big]) =>
      _setFloat64(byteOffset, value, Endian.little == endian);

  @JSName('setFloat64')
  void _setFloat64(int byteOffset, num value, [bool littleEndian]) native;

  /**
   * Sets the two bytes starting at the specified [byteOffset] in this
   * object to the two's complement binary representation of the specified
   * [value], which must fit in two bytes. In other words, [value] must lie
   * between 2<sup>15</sup> and 2<sup>15</sup> - 1, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 2` is greater than the length of this object.
   */
  void setInt16(int byteOffset, int value, [Endian endian = Endian.big]) =>
      _setInt16(byteOffset, value, Endian.little == endian);

  @JSName('setInt16')
  void _setInt16(int byteOffset, int value, [bool littleEndian]) native;

  /**
   * Sets the four bytes starting at the specified [byteOffset] in this
   * object to the two's complement binary representation of the specified
   * [value], which must fit in four bytes. In other words, [value] must lie
   * between 2<sup>31</sup> and 2<sup>31</sup> - 1, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 4` is greater than the length of this object.
   */
  void setInt32(int byteOffset, int value, [Endian endian = Endian.big]) =>
      _setInt32(byteOffset, value, Endian.little == endian);

  @JSName('setInt32')
  void _setInt32(int byteOffset, int value, [bool littleEndian]) native;

  /**
   * Sets the eight bytes starting at the specified [byteOffset] in this
   * object to the two's complement binary representation of the specified
   * [value], which must fit in eight bytes. In other words, [value] must lie
   * between 2<sup>63</sup> and 2<sup>63</sup> - 1, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 8` is greater than the length of this object.
   */
  void setInt64(int byteOffset, int value, [Endian endian = Endian.big]) {
    throw UnsupportedError('Int64 accessor not supported by dart2js.');
  }

  /**
   * Sets the byte at the specified [byteOffset] in this object to the
   * two's complement binary representation of the specified [value], which
   * must fit in a single byte. In other words, [value] must be between
   * -128 and 127, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * greater than or equal to the length of this object.
   */
  void setInt8(int byteOffset, int value) native;

  /**
   * Sets the two bytes starting at the specified [byteOffset] in this object
   * to the unsigned binary representation of the specified [value],
   * which must fit in two bytes. in other words, [value] must be between
   * 0 and 2<sup>16</sup> - 1, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 2` is greater than the length of this object.
   */
  void setUint16(int byteOffset, int value, [Endian endian = Endian.big]) =>
      _setUint16(byteOffset, value, Endian.little == endian);

  @JSName('setUint16')
  void _setUint16(int byteOffset, int value, [bool littleEndian]) native;

  /**
   * Sets the four bytes starting at the specified [byteOffset] in this object
   * to the unsigned binary representation of the specified [value],
   * which must fit in four bytes. in other words, [value] must be between
   * 0 and 2<sup>32</sup> - 1, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 4` is greater than the length of this object.
   */
  void setUint32(int byteOffset, int value, [Endian endian = Endian.big]) =>
      _setUint32(byteOffset, value, Endian.little == endian);

  @JSName('setUint32')
  void _setUint32(int byteOffset, int value, [bool littleEndian]) native;

  /**
   * Sets the eight bytes starting at the specified [byteOffset] in this object
   * to the unsigned binary representation of the specified [value],
   * which must fit in eight bytes. in other words, [value] must be between
   * 0 and 2<sup>64</sup> - 1, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 8` is greater than the length of this object.
   */
  void setUint64(int byteOffset, int value, [Endian endian = Endian.big]) {
    throw UnsupportedError('Uint64 accessor not supported by dart2js.');
  }

  /**
   * Sets the byte at the specified [byteOffset] in this object to the
   * unsigned binary representation of the specified [value], which must fit
   * in a single byte. in other words, [value] must be between 0 and 255,
   * inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative,
   * or greater than or equal to the length of this object.
   */
  void setUint8(int byteOffset, int value) native;

  static NativeByteData _create1(arg) =>
      JS('NativeByteData', 'new DataView(new ArrayBuffer(#))', arg);

  static NativeByteData _create2(arg1, arg2) =>
      JS('NativeByteData', 'new DataView(#, #)', arg1, arg2);

  static NativeByteData _create3(arg1, arg2, arg3) =>
      JS('NativeByteData', 'new DataView(#, #, #)', arg1, arg2, arg3);
}

abstract class NativeTypedArray extends NativeTypedData
    implements JavaScriptIndexingBehavior {
  int get length;

  void _setRangeFast(
      int start, int end, NativeTypedArray source, int skipCount) {
    int targetLength = this.length;
    _checkPosition(start, targetLength, "start");
    _checkPosition(end, targetLength, "end");
    if (start > end) throw RangeError.range(start, 0, end);
    int count = end - start;

    if (skipCount < 0) throw ArgumentError(skipCount);

    int sourceLength = source.length;
    if (sourceLength - skipCount < count) {
      throw StateError('Not enough elements');
    }

    if (skipCount != 0 || sourceLength != count) {
      // Create a view of the exact subrange that is copied from the source.
      source = JS('', '#.subarray(#, #)', source, skipCount, skipCount + count);
    }
    JS('void', '#.set(#, #)', this, source, start);
  }
}

abstract class NativeTypedArrayOfDouble extends NativeTypedArray
    with ListMixin<double>, FixedLengthListMixin<double> {
  int get length => JS('int', '#.length', this);

  double operator [](int index) {
    _checkValidIndex(index, this, this.length);
    return JS('double', '#[#]', this, index);
  }

  void operator []=(int index, num value) {
    _checkValidIndex(index, this, this.length);
    JS('void', '#[#] = #', this, index, value);
  }

  void setRange(int start, int end, Iterable<double> iterable,
      [int skipCount = 0]) {
    if (iterable is NativeTypedArrayOfDouble) {
      _setRangeFast(start, end, iterable, skipCount);
      return;
    }
    super.setRange(start, end, iterable, skipCount);
  }
}

abstract class NativeTypedArrayOfInt extends NativeTypedArray
    with ListMixin<int>, FixedLengthListMixin<int>
    implements List<int> {
  int get length => JS('int', '#.length', this);

  // operator[]() is not here since different versions have different return
  // types

  void operator []=(int index, int value) {
    _checkValidIndex(index, this, this.length);
    JS('void', '#[#] = #', this, index, value);
  }

  void setRange(int start, int end, Iterable<int> iterable,
      [int skipCount = 0]) {
    if (iterable is NativeTypedArrayOfInt) {
      _setRangeFast(start, end, iterable, skipCount);
      return;
    }
    super.setRange(start, end, iterable, skipCount);
  }
}

@Native("Float32Array")
class NativeFloat32List extends NativeTypedArrayOfDouble
    implements Float32List {
  factory NativeFloat32List(int length) => _create1(_checkLength(length));

  factory NativeFloat32List.fromList(List<double> elements) =>
      _create1(_ensureNativeList(elements));

  factory NativeFloat32List.view(
      ByteBuffer buffer, int offsetInBytes, int length) {
    _checkViewArguments(buffer, offsetInBytes, length);
    return length == null
        ? _create2(buffer, offsetInBytes)
        : _create3(buffer, offsetInBytes, length);
  }

  Type get runtimeType => Float32List;

  Float32List sublist(int start, [int end]) {
    end = _checkValidRange(start, end, this.length);
    var source = JS('NativeFloat32List', '#.subarray(#, #)', this, start, end);
    return _create1(source);
  }

  static NativeFloat32List _create1(arg) =>
      JS('NativeFloat32List', 'new Float32Array(#)', arg);

  static NativeFloat32List _create2(arg1, arg2) =>
      JS('NativeFloat32List', 'new Float32Array(#, #)', arg1, arg2);

  static NativeFloat32List _create3(arg1, arg2, arg3) =>
      JS('NativeFloat32List', 'new Float32Array(#, #, #)', arg1, arg2, arg3);
}

@Native("Float64Array")
class NativeFloat64List extends NativeTypedArrayOfDouble
    implements Float64List {
  factory NativeFloat64List(int length) => _create1(_checkLength(length));

  factory NativeFloat64List.fromList(List<double> elements) =>
      _create1(_ensureNativeList(elements));

  factory NativeFloat64List.view(
      ByteBuffer buffer, int offsetInBytes, int length) {
    _checkViewArguments(buffer, offsetInBytes, length);
    return length == null
        ? _create2(buffer, offsetInBytes)
        : _create3(buffer, offsetInBytes, length);
  }

  Type get runtimeType => Float64List;

  Float64List sublist(int start, [int end]) {
    end = _checkValidRange(start, end, this.length);
    var source = JS('NativeFloat64List', '#.subarray(#, #)', this, start, end);
    return _create1(source);
  }

  static NativeFloat64List _create1(arg) =>
      JS('NativeFloat64List', 'new Float64Array(#)', arg);

  static NativeFloat64List _create2(arg1, arg2) =>
      JS('NativeFloat64List', 'new Float64Array(#, #)', arg1, arg2);

  static NativeFloat64List _create3(arg1, arg2, arg3) =>
      JS('NativeFloat64List', 'new Float64Array(#, #, #)', arg1, arg2, arg3);
}

@Native("Int16Array")
class NativeInt16List extends NativeTypedArrayOfInt implements Int16List {
  factory NativeInt16List(int length) => _create1(_checkLength(length));

  factory NativeInt16List.fromList(List<int> elements) =>
      _create1(_ensureNativeList(elements));

  factory NativeInt16List.view(
      NativeByteBuffer buffer, int offsetInBytes, int length) {
    _checkViewArguments(buffer, offsetInBytes, length);
    return length == null
        ? _create2(buffer, offsetInBytes)
        : _create3(buffer, offsetInBytes, length);
  }

  Type get runtimeType => Int16List;

  int operator [](int index) {
    _checkValidIndex(index, this, this.length);
    return JS('int', '#[#]', this, index);
  }

  Int16List sublist(int start, [int end]) {
    end = _checkValidRange(start, end, this.length);
    var source = JS('NativeInt16List', '#.subarray(#, #)', this, start, end);
    return _create1(source);
  }

  static NativeInt16List _create1(arg) =>
      JS('NativeInt16List', 'new Int16Array(#)', arg);

  static NativeInt16List _create2(arg1, arg2) =>
      JS('NativeInt16List', 'new Int16Array(#, #)', arg1, arg2);

  static NativeInt16List _create3(arg1, arg2, arg3) =>
      JS('NativeInt16List', 'new Int16Array(#, #, #)', arg1, arg2, arg3);
}

@Native("Int32Array")
class NativeInt32List extends NativeTypedArrayOfInt implements Int32List {
  factory NativeInt32List(int length) => _create1(_checkLength(length));

  factory NativeInt32List.fromList(List<int> elements) =>
      _create1(_ensureNativeList(elements));

  factory NativeInt32List.view(
      ByteBuffer buffer, int offsetInBytes, int length) {
    _checkViewArguments(buffer, offsetInBytes, length);
    return length == null
        ? _create2(buffer, offsetInBytes)
        : _create3(buffer, offsetInBytes, length);
  }

  Type get runtimeType => Int32List;

  int operator [](int index) {
    _checkValidIndex(index, this, this.length);
    return JS('int', '#[#]', this, index);
  }

  Int32List sublist(int start, [int end]) {
    end = _checkValidRange(start, end, this.length);
    var source = JS('NativeInt32List', '#.subarray(#, #)', this, start, end);
    return _create1(source);
  }

  static NativeInt32List _create1(arg) =>
      JS('NativeInt32List', 'new Int32Array(#)', arg);

  static NativeInt32List _create2(arg1, arg2) =>
      JS('NativeInt32List', 'new Int32Array(#, #)', arg1, arg2);

  static NativeInt32List _create3(arg1, arg2, arg3) =>
      JS('NativeInt32List', 'new Int32Array(#, #, #)', arg1, arg2, arg3);
}

@Native("Int8Array")
class NativeInt8List extends NativeTypedArrayOfInt implements Int8List {
  factory NativeInt8List(int length) => _create1(_checkLength(length));

  factory NativeInt8List.fromList(List<int> elements) =>
      _create1(_ensureNativeList(elements));

  factory NativeInt8List.view(
      ByteBuffer buffer, int offsetInBytes, int length) {
    _checkViewArguments(buffer, offsetInBytes, length);
    return length == null
        ? _create2(buffer, offsetInBytes)
        : _create3(buffer, offsetInBytes, length);
  }

  Type get runtimeType => Int8List;

  int operator [](int index) {
    _checkValidIndex(index, this, this.length);
    return JS('int', '#[#]', this, index);
  }

  Int8List sublist(int start, [int end]) {
    end = _checkValidRange(start, end, this.length);
    var source = JS('NativeInt8List', '#.subarray(#, #)', this, start, end);
    return _create1(source);
  }

  static NativeInt8List _create1(arg) =>
      JS('NativeInt8List', 'new Int8Array(#)', arg);

  static NativeInt8List _create2(arg1, arg2) =>
      JS('NativeInt8List', 'new Int8Array(#, #)', arg1, arg2);

  static Int8List _create3(arg1, arg2, arg3) =>
      JS('NativeInt8List', 'new Int8Array(#, #, #)', arg1, arg2, arg3);
}

@Native("Uint16Array")
class NativeUint16List extends NativeTypedArrayOfInt implements Uint16List {
  factory NativeUint16List(int length) => _create1(_checkLength(length));

  factory NativeUint16List.fromList(List<int> list) =>
      _create1(_ensureNativeList(list));

  factory NativeUint16List.view(
      ByteBuffer buffer, int offsetInBytes, int length) {
    _checkViewArguments(buffer, offsetInBytes, length);
    return length == null
        ? _create2(buffer, offsetInBytes)
        : _create3(buffer, offsetInBytes, length);
  }

  Type get runtimeType => Uint16List;

  int operator [](int index) {
    _checkValidIndex(index, this, this.length);
    return JS('int', '#[#]', this, index);
  }

  Uint16List sublist(int start, [int end]) {
    end = _checkValidRange(start, end, this.length);
    var source = JS('NativeUint16List', '#.subarray(#, #)', this, start, end);
    return _create1(source);
  }

  static NativeUint16List _create1(arg) =>
      JS('NativeUint16List', 'new Uint16Array(#)', arg);

  static NativeUint16List _create2(arg1, arg2) =>
      JS('NativeUint16List', 'new Uint16Array(#, #)', arg1, arg2);

  static NativeUint16List _create3(arg1, arg2, arg3) =>
      JS('NativeUint16List', 'new Uint16Array(#, #, #)', arg1, arg2, arg3);
}

@Native("Uint32Array")
class NativeUint32List extends NativeTypedArrayOfInt implements Uint32List {
  factory NativeUint32List(int length) => _create1(_checkLength(length));

  factory NativeUint32List.fromList(List<int> elements) =>
      _create1(_ensureNativeList(elements));

  factory NativeUint32List.view(
      ByteBuffer buffer, int offsetInBytes, int length) {
    _checkViewArguments(buffer, offsetInBytes, length);
    return length == null
        ? _create2(buffer, offsetInBytes)
        : _create3(buffer, offsetInBytes, length);
  }

  Type get runtimeType => Uint32List;

  int operator [](int index) {
    _checkValidIndex(index, this, this.length);
    return JS('int', '#[#]', this, index);
  }

  Uint32List sublist(int start, [int end]) {
    end = _checkValidRange(start, end, this.length);
    var source = JS('NativeUint32List', '#.subarray(#, #)', this, start, end);
    return _create1(source);
  }

  static NativeUint32List _create1(arg) =>
      JS('NativeUint32List', 'new Uint32Array(#)', arg);

  static NativeUint32List _create2(arg1, arg2) =>
      JS('NativeUint32List', 'new Uint32Array(#, #)', arg1, arg2);

  static NativeUint32List _create3(arg1, arg2, arg3) =>
      JS('NativeUint32List', 'new Uint32Array(#, #, #)', arg1, arg2, arg3);
}

@Native("Uint8ClampedArray,CanvasPixelArray")
class NativeUint8ClampedList extends NativeTypedArrayOfInt
    implements Uint8ClampedList {
  factory NativeUint8ClampedList(int length) => _create1(_checkLength(length));

  factory NativeUint8ClampedList.fromList(List<int> elements) =>
      _create1(_ensureNativeList(elements));

  factory NativeUint8ClampedList.view(
      ByteBuffer buffer, int offsetInBytes, int length) {
    _checkViewArguments(buffer, offsetInBytes, length);
    return length == null
        ? _create2(buffer, offsetInBytes)
        : _create3(buffer, offsetInBytes, length);
  }

  Type get runtimeType => Uint8ClampedList;

  int get length => JS('int', '#.length', this);

  int operator [](int index) {
    _checkValidIndex(index, this, this.length);
    return JS('int', '#[#]', this, index);
  }

  Uint8ClampedList sublist(int start, [int end]) {
    end = _checkValidRange(start, end, this.length);
    var source =
        JS('NativeUint8ClampedList', '#.subarray(#, #)', this, start, end);
    return _create1(source);
  }

  static NativeUint8ClampedList _create1(arg) =>
      JS('NativeUint8ClampedList', 'new Uint8ClampedArray(#)', arg);

  static NativeUint8ClampedList _create2(arg1, arg2) =>
      JS('NativeUint8ClampedList', 'new Uint8ClampedArray(#, #)', arg1, arg2);

  static NativeUint8ClampedList _create3(arg1, arg2, arg3) => JS(
      'NativeUint8ClampedList',
      'new Uint8ClampedArray(#, #, #)',
      arg1,
      arg2,
      arg3);
}

// On some browsers Uint8ClampedArray is a subtype of Uint8Array.  Marking
// Uint8List as !nonleaf ensures that the native dispatch correctly handles
// the potential for Uint8ClampedArray to 'accidentally' pick up the
// dispatch record for Uint8List.
@Native("Uint8Array,!nonleaf")
class NativeUint8List extends NativeTypedArrayOfInt implements Uint8List {
  factory NativeUint8List(int length) => _create1(_checkLength(length));

  factory NativeUint8List.fromList(List<int> elements) =>
      _create1(_ensureNativeList(elements));

  factory NativeUint8List.view(
      ByteBuffer buffer, int offsetInBytes, int length) {
    _checkViewArguments(buffer, offsetInBytes, length);
    return length == null
        ? _create2(buffer, offsetInBytes)
        : _create3(buffer, offsetInBytes, length);
  }

  Type get runtimeType => Uint8List;

  int get length => JS('int', '#.length', this);

  int operator [](int index) {
    _checkValidIndex(index, this, this.length);
    return JS('int', '#[#]', this, index);
  }

  Uint8List sublist(int start, [int end]) {
    end = _checkValidRange(start, end, this.length);
    var source = JS('NativeUint8List', '#.subarray(#, #)', this, start, end);
    return _create1(source);
  }

  static NativeUint8List _create1(arg) =>
      JS('NativeUint8List', 'new Uint8Array(#)', arg);

  static NativeUint8List _create2(arg1, arg2) =>
      JS('NativeUint8List', 'new Uint8Array(#, #)', arg1, arg2);

  static NativeUint8List _create3(arg1, arg2, arg3) =>
      JS('NativeUint8List', 'new Uint8Array(#, #, #)', arg1, arg2, arg3);
}

/**
 * Implementation of Dart Float32x4 immutable value type and operations.
 * Float32x4 stores 4 32-bit floating point values in "lanes".
 * The lanes are "x", "y", "z", and "w" respectively.
 */
class NativeFloat32x4 implements Float32x4 {
  final double x;
  final double y;
  final double z;
  final double w;

  static final NativeFloat32List _list = NativeFloat32List(4);
  static final Uint32List _uint32view = _list.buffer.asUint32List();

  static _truncate(x) {
    _list[0] = x;
    return _list[0];
  }

  NativeFloat32x4(double x, double y, double z, double w)
      : this.x = _truncate(x),
        this.y = _truncate(y),
        this.z = _truncate(z),
        this.w = _truncate(w) {
    // We would prefer to check for `double` but in dart2js we can't see the
    // difference anyway.
    if (x is! num) throw ArgumentError(x);
    if (y is! num) throw ArgumentError(y);
    if (z is! num) throw ArgumentError(z);
    if (w is! num) throw ArgumentError(w);
  }

  NativeFloat32x4.splat(double v) : this(v, v, v, v);
  NativeFloat32x4.zero() : this._truncated(0.0, 0.0, 0.0, 0.0);

  /// Returns a bit-wise copy of [i] as a Float32x4.
  factory NativeFloat32x4.fromInt32x4Bits(Int32x4 i) {
    _uint32view[0] = i.x;
    _uint32view[1] = i.y;
    _uint32view[2] = i.z;
    _uint32view[3] = i.w;
    return NativeFloat32x4._truncated(_list[0], _list[1], _list[2], _list[3]);
  }

  NativeFloat32x4.fromFloat64x2(Float64x2 v)
      : this._truncated(_truncate(v.x), _truncate(v.y), 0.0, 0.0);

  /// Creates a new NativeFloat32x4.
  ///
  /// Does not verify if the given arguments are non-null.
  NativeFloat32x4._doubles(double x, double y, double z, double w)
      : this.x = _truncate(x),
        this.y = _truncate(y),
        this.z = _truncate(z),
        this.w = _truncate(w);

  /// Creates a new NativeFloat32x4.
  ///
  /// The constructor does not truncate the arguments. They must already be in
  /// the correct range. It does not verify the type of the given arguments,
  /// either.
  NativeFloat32x4._truncated(this.x, this.y, this.z, this.w);

  String toString() {
    return '[$x, $y, $z, $w]';
  }

  /// Addition operator.
  Float32x4 operator +(Float32x4 other) {
    double _x = x + other.x;
    double _y = y + other.y;
    double _z = z + other.z;
    double _w = w + other.w;
    return NativeFloat32x4._doubles(_x, _y, _z, _w);
  }

  /// Negate operator.
  Float32x4 operator -() {
    return NativeFloat32x4._truncated(-x, -y, -z, -w);
  }

  /// Subtraction operator.
  Float32x4 operator -(Float32x4 other) {
    double _x = x - other.x;
    double _y = y - other.y;
    double _z = z - other.z;
    double _w = w - other.w;
    return NativeFloat32x4._doubles(_x, _y, _z, _w);
  }

  /// Multiplication operator.
  Float32x4 operator *(Float32x4 other) {
    double _x = x * other.x;
    double _y = y * other.y;
    double _z = z * other.z;
    double _w = w * other.w;
    return NativeFloat32x4._doubles(_x, _y, _z, _w);
  }

  /// Division operator.
  Float32x4 operator /(Float32x4 other) {
    double _x = x / other.x;
    double _y = y / other.y;
    double _z = z / other.z;
    double _w = w / other.w;
    return NativeFloat32x4._doubles(_x, _y, _z, _w);
  }

  /// Relational less than.
  Int32x4 lessThan(Float32x4 other) {
    bool _cx = x < other.x;
    bool _cy = y < other.y;
    bool _cz = z < other.z;
    bool _cw = w < other.w;
    return NativeInt32x4._truncated(
        _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
  }

  /// Relational less than or equal.
  Int32x4 lessThanOrEqual(Float32x4 other) {
    bool _cx = x <= other.x;
    bool _cy = y <= other.y;
    bool _cz = z <= other.z;
    bool _cw = w <= other.w;
    return NativeInt32x4._truncated(
        _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
  }

  /// Relational greater than.
  Int32x4 greaterThan(Float32x4 other) {
    bool _cx = x > other.x;
    bool _cy = y > other.y;
    bool _cz = z > other.z;
    bool _cw = w > other.w;
    return NativeInt32x4._truncated(
        _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
  }

  /// Relational greater than or equal.
  Int32x4 greaterThanOrEqual(Float32x4 other) {
    bool _cx = x >= other.x;
    bool _cy = y >= other.y;
    bool _cz = z >= other.z;
    bool _cw = w >= other.w;
    return NativeInt32x4._truncated(
        _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
  }

  /// Relational equal.
  Int32x4 equal(Float32x4 other) {
    bool _cx = x == other.x;
    bool _cy = y == other.y;
    bool _cz = z == other.z;
    bool _cw = w == other.w;
    return NativeInt32x4._truncated(
        _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
  }

  /// Relational not-equal.
  Int32x4 notEqual(Float32x4 other) {
    bool _cx = x != other.x;
    bool _cy = y != other.y;
    bool _cz = z != other.z;
    bool _cw = w != other.w;
    return NativeInt32x4._truncated(
        _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
  }

  /// Returns a copy of [this] each lane being scaled by [s].
  Float32x4 scale(double s) {
    double _x = s * x;
    double _y = s * y;
    double _z = s * z;
    double _w = s * w;
    return NativeFloat32x4._doubles(_x, _y, _z, _w);
  }

  /// Returns the absolute value of this [Float32x4].
  Float32x4 abs() {
    double _x = x.abs();
    double _y = y.abs();
    double _z = z.abs();
    double _w = w.abs();
    return NativeFloat32x4._truncated(_x, _y, _z, _w);
  }

  /// Clamps [this] to be in the range [lowerLimit]-[upperLimit].
  Float32x4 clamp(Float32x4 lowerLimit, Float32x4 upperLimit) {
    double _lx = lowerLimit.x;
    double _ly = lowerLimit.y;
    double _lz = lowerLimit.z;
    double _lw = lowerLimit.w;
    double _ux = upperLimit.x;
    double _uy = upperLimit.y;
    double _uz = upperLimit.z;
    double _uw = upperLimit.w;
    double _x = x;
    double _y = y;
    double _z = z;
    double _w = w;
    // MAX(MIN(self, upper), lower).
    _x = _x > _ux ? _ux : _x;
    _y = _y > _uy ? _uy : _y;
    _z = _z > _uz ? _uz : _z;
    _w = _w > _uw ? _uw : _w;
    _x = _x < _lx ? _lx : _x;
    _y = _y < _ly ? _ly : _y;
    _z = _z < _lz ? _lz : _z;
    _w = _w < _lw ? _lw : _w;
    return NativeFloat32x4._truncated(_x, _y, _z, _w);
  }

  /// Extract the sign bit from each lane return them in the first 4 bits.
  int get signMask {
    var view = _uint32view;
    var mx, my, mz, mw;
    _list[0] = x;
    _list[1] = y;
    _list[2] = z;
    _list[3] = w;
    // This is correct because dart2js uses the unsigned right shift.
    mx = (view[0] & 0x80000000) >> 31;
    my = (view[1] & 0x80000000) >> 30;
    mz = (view[2] & 0x80000000) >> 29;
    mw = (view[3] & 0x80000000) >> 28;
    return mx | my | mz | mw;
  }

  /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
  Float32x4 shuffle(int mask) {
    if ((mask < 0) || (mask > 255)) {
      throw RangeError.range(mask, 0, 255, "mask");
    }
    _list[0] = x;
    _list[1] = y;
    _list[2] = z;
    _list[3] = w;

    double _x = _list[mask & 0x3];
    double _y = _list[(mask >> 2) & 0x3];
    double _z = _list[(mask >> 4) & 0x3];
    double _w = _list[(mask >> 6) & 0x3];
    return NativeFloat32x4._truncated(_x, _y, _z, _w);
  }

  /// Shuffle the lane values in [this] and [other]. The returned
  /// Float32x4 will have XY lanes from [this] and ZW lanes from [other].
  /// Uses the same [mask] as [shuffle].
  Float32x4 shuffleMix(Float32x4 other, int mask) {
    if ((mask < 0) || (mask > 255)) {
      throw RangeError.range(mask, 0, 255, "mask");
    }
    _list[0] = x;
    _list[1] = y;
    _list[2] = z;
    _list[3] = w;
    double _x = _list[mask & 0x3];
    double _y = _list[(mask >> 2) & 0x3];

    _list[0] = other.x;
    _list[1] = other.y;
    _list[2] = other.z;
    _list[3] = other.w;
    double _z = _list[(mask >> 4) & 0x3];
    double _w = _list[(mask >> 6) & 0x3];
    return NativeFloat32x4._truncated(_x, _y, _z, _w);
  }

  /// Copy [this] and replace the [x] lane.
  Float32x4 withX(double newX) {
    return NativeFloat32x4._truncated(_truncate(newX), y, z, w);
  }

  /// Copy [this] and replace the [y] lane.
  Float32x4 withY(double newY) {
    return NativeFloat32x4._truncated(x, _truncate(newY), z, w);
  }

  /// Copy [this] and replace the [z] lane.
  Float32x4 withZ(double newZ) {
    return NativeFloat32x4._truncated(x, y, _truncate(newZ), w);
  }

  /// Copy [this] and replace the [w] lane.
  Float32x4 withW(double newW) {
    return NativeFloat32x4._truncated(x, y, z, _truncate(newW));
  }

  /// Returns the lane-wise minimum value in [this] or [other].
  Float32x4 min(Float32x4 other) {
    double _x = x < other.x ? x : other.x;
    double _y = y < other.y ? y : other.y;
    double _z = z < other.z ? z : other.z;
    double _w = w < other.w ? w : other.w;
    return NativeFloat32x4._truncated(_x, _y, _z, _w);
  }

  /// Returns the lane-wise maximum value in [this] or [other].
  Float32x4 max(Float32x4 other) {
    double _x = x > other.x ? x : other.x;
    double _y = y > other.y ? y : other.y;
    double _z = z > other.z ? z : other.z;
    double _w = w > other.w ? w : other.w;
    return NativeFloat32x4._truncated(_x, _y, _z, _w);
  }

  /// Returns the square root of [this].
  Float32x4 sqrt() {
    double _x = Math.sqrt(x);
    double _y = Math.sqrt(y);
    double _z = Math.sqrt(z);
    double _w = Math.sqrt(w);
    return NativeFloat32x4._doubles(_x, _y, _z, _w);
  }

  /// Returns the reciprocal of [this].
  Float32x4 reciprocal() {
    double _x = 1.0 / x;
    double _y = 1.0 / y;
    double _z = 1.0 / z;
    double _w = 1.0 / w;
    return NativeFloat32x4._doubles(_x, _y, _z, _w);
  }

  /// Returns the square root of the reciprocal of [this].
  Float32x4 reciprocalSqrt() {
    double _x = Math.sqrt(1.0 / x);
    double _y = Math.sqrt(1.0 / y);
    double _z = Math.sqrt(1.0 / z);
    double _w = Math.sqrt(1.0 / w);
    return NativeFloat32x4._doubles(_x, _y, _z, _w);
  }
}

/**
 * Interface of Dart Int32x4 and operations.
 * Int32x4 stores 4 32-bit bit-masks in "lanes".
 * The lanes are "x", "y", "z", and "w" respectively.
 */
class NativeInt32x4 implements Int32x4 {
  final int x;
  final int y;
  final int z;
  final int w;

  static final _list = NativeInt32List(4);

  static _truncate(x) {
    _list[0] = x;
    return _list[0];
  }

  NativeInt32x4(int x, int y, int z, int w)
      : this.x = _truncate(x),
        this.y = _truncate(y),
        this.z = _truncate(z),
        this.w = _truncate(w) {
    if (x != this.x && x is! int) throw ArgumentError(x);
    if (y != this.y && y is! int) throw ArgumentError(y);
    if (z != this.z && z is! int) throw ArgumentError(z);
    if (w != this.w && w is! int) throw ArgumentError(w);
  }

  NativeInt32x4.bool(bool x, bool y, bool z, bool w)
      : this.x = x ? -1 : 0,
        this.y = y ? -1 : 0,
        this.z = z ? -1 : 0,
        this.w = w ? -1 : 0;

  /// Returns a bit-wise copy of [f] as a Int32x4.
  factory NativeInt32x4.fromFloat32x4Bits(Float32x4 f) {
    NativeFloat32List floatList = NativeFloat32x4._list;
    floatList[0] = f.x;
    floatList[1] = f.y;
    floatList[2] = f.z;
    floatList[3] = f.w;
    NativeInt32List view = floatList.buffer.asInt32List();
    return NativeInt32x4._truncated(view[0], view[1], view[2], view[3]);
  }

  NativeInt32x4._truncated(this.x, this.y, this.z, this.w);

  String toString() => '[$x, $y, $z, $w]';

  /// The bit-wise or operator.
  Int32x4 operator |(Int32x4 other) {
    // Dart2js uses unsigned results for bit-operations.
    // We use "JS" to fall back to the signed versions.
    return NativeInt32x4._truncated(
        JS("int", "# | #", x, other.x),
        JS("int", "# | #", y, other.y),
        JS("int", "# | #", z, other.z),
        JS("int", "# | #", w, other.w));
  }

  /// The bit-wise and operator.
  Int32x4 operator &(Int32x4 other) {
    // Dart2js uses unsigned results for bit-operations.
    // We use "JS" to fall back to the signed versions.
    return NativeInt32x4._truncated(
        JS("int", "# & #", x, other.x),
        JS("int", "# & #", y, other.y),
        JS("int", "# & #", z, other.z),
        JS("int", "# & #", w, other.w));
  }

  /// The bit-wise xor operator.
  Int32x4 operator ^(Int32x4 other) {
    // Dart2js uses unsigned results for bit-operations.
    // We use "JS" to fall back to the signed versions.
    return NativeInt32x4._truncated(
        JS("int", "# ^ #", x, other.x),
        JS("int", "# ^ #", y, other.y),
        JS("int", "# ^ #", z, other.z),
        JS("int", "# ^ #", w, other.w));
  }

  Int32x4 operator +(Int32x4 other) {
    // Avoid going through the typed array by "| 0" the result.
    return NativeInt32x4._truncated(
        JS("int", "(# + #) | 0", x, other.x),
        JS("int", "(# + #) | 0", y, other.y),
        JS("int", "(# + #) | 0", z, other.z),
        JS("int", "(# + #) | 0", w, other.w));
  }

  Int32x4 operator -(Int32x4 other) {
    // Avoid going through the typed array by "| 0" the result.
    return NativeInt32x4._truncated(
        JS("int", "(# - #) | 0", x, other.x),
        JS("int", "(# - #) | 0", y, other.y),
        JS("int", "(# - #) | 0", z, other.z),
        JS("int", "(# - #) | 0", w, other.w));
  }

  Int32x4 operator -() {
    // Avoid going through the typed array by "| 0" the result.
    return NativeInt32x4._truncated(
        JS("int", "(-#) | 0", x),
        JS("int", "(-#) | 0", y),
        JS("int", "(-#) | 0", z),
        JS("int", "(-#) | 0", w));
  }

  /// Extract the top bit from each lane return them in the first 4 bits.
  int get signMask {
    int mx = (x & 0x80000000) >> 31;
    int my = (y & 0x80000000) >> 31;
    int mz = (z & 0x80000000) >> 31;
    int mw = (w & 0x80000000) >> 31;
    return mx | my << 1 | mz << 2 | mw << 3;
  }

  /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
  Int32x4 shuffle(int mask) {
    if ((mask < 0) || (mask > 255)) {
      throw RangeError.range(mask, 0, 255, "mask");
    }
    _list[0] = x;
    _list[1] = y;
    _list[2] = z;
    _list[3] = w;
    int _x = _list[mask & 0x3];
    int _y = _list[(mask >> 2) & 0x3];
    int _z = _list[(mask >> 4) & 0x3];
    int _w = _list[(mask >> 6) & 0x3];
    return NativeInt32x4._truncated(_x, _y, _z, _w);
  }

  /// Shuffle the lane values in [this] and [other]. The returned
  /// Int32x4 will have XY lanes from [this] and ZW lanes from [other].
  /// Uses the same [mask] as [shuffle].
  Int32x4 shuffleMix(Int32x4 other, int mask) {
    if ((mask < 0) || (mask > 255)) {
      throw RangeError.range(mask, 0, 255, "mask");
    }
    _list[0] = x;
    _list[1] = y;
    _list[2] = z;
    _list[3] = w;
    int _x = _list[mask & 0x3];
    int _y = _list[(mask >> 2) & 0x3];

    _list[0] = other.x;
    _list[1] = other.y;
    _list[2] = other.z;
    _list[3] = other.w;
    int _z = _list[(mask >> 4) & 0x3];
    int _w = _list[(mask >> 6) & 0x3];
    return NativeInt32x4._truncated(_x, _y, _z, _w);
  }

  /// Returns a new [Int32x4] copied from [this] with a new x value.
  Int32x4 withX(int x) {
    int _x = _truncate(x);
    return NativeInt32x4._truncated(_x, y, z, w);
  }

  /// Returns a new [Int32x4] copied from [this] with a new y value.
  Int32x4 withY(int y) {
    int _y = _truncate(y);
    return NativeInt32x4._truncated(x, _y, z, w);
  }

  /// Returns a new [Int32x4] copied from [this] with a new z value.
  Int32x4 withZ(int z) {
    int _z = _truncate(z);
    return NativeInt32x4._truncated(x, y, _z, w);
  }

  /// Returns a new [Int32x4] copied from [this] with a new w value.
  Int32x4 withW(int w) {
    int _w = _truncate(w);
    return NativeInt32x4._truncated(x, y, z, _w);
  }

  /// Extracted x value. Returns `false` for 0, `true` for any other value.
  bool get flagX => x != 0;

  /// Extracted y value. Returns `false` for 0, `true` for any other value.
  bool get flagY => y != 0;

  /// Extracted z value. Returns `false` for 0, `true` for any other value.
  bool get flagZ => z != 0;

  /// Extracted w value. Returns `false` for 0, `true` for any other value.
  bool get flagW => w != 0;

  /// Returns a new [Int32x4] copied from [this] with a new x value.
  Int32x4 withFlagX(bool flagX) {
    int _x = flagX ? -1 : 0;
    return NativeInt32x4._truncated(_x, y, z, w);
  }

  /// Returns a new [Int32x4] copied from [this] with a new y value.
  Int32x4 withFlagY(bool flagY) {
    int _y = flagY ? -1 : 0;
    return NativeInt32x4._truncated(x, _y, z, w);
  }

  /// Returns a new [Int32x4] copied from [this] with a new z value.
  Int32x4 withFlagZ(bool flagZ) {
    int _z = flagZ ? -1 : 0;
    return NativeInt32x4._truncated(x, y, _z, w);
  }

  /// Returns a new [Int32x4] copied from [this] with a new w value.
  Int32x4 withFlagW(bool flagW) {
    int _w = flagW ? -1 : 0;
    return NativeInt32x4._truncated(x, y, z, _w);
  }

  /// Merge [trueValue] and [falseValue] based on [this]' bit mask:
  /// Select bit from [trueValue] when bit in [this] is on.
  /// Select bit from [falseValue] when bit in [this] is off.
  Float32x4 select(Float32x4 trueValue, Float32x4 falseValue) {
    var floatList = NativeFloat32x4._list;
    var intView = NativeFloat32x4._uint32view;

    floatList[0] = trueValue.x;
    floatList[1] = trueValue.y;
    floatList[2] = trueValue.z;
    floatList[3] = trueValue.w;
    int stx = intView[0];
    int sty = intView[1];
    int stz = intView[2];
    int stw = intView[3];

    floatList[0] = falseValue.x;
    floatList[1] = falseValue.y;
    floatList[2] = falseValue.z;
    floatList[3] = falseValue.w;
    int sfx = intView[0];
    int sfy = intView[1];
    int sfz = intView[2];
    int sfw = intView[3];
    int _x = (x & stx) | (~x & sfx);
    int _y = (y & sty) | (~y & sfy);
    int _z = (z & stz) | (~z & sfz);
    int _w = (w & stw) | (~w & sfw);
    intView[0] = _x;
    intView[1] = _y;
    intView[2] = _z;
    intView[3] = _w;
    return NativeFloat32x4._truncated(
        floatList[0], floatList[1], floatList[2], floatList[3]);
  }
}

class NativeFloat64x2 implements Float64x2 {
  final double x;
  final double y;

  static NativeFloat64List _list = NativeFloat64List(2);
  static NativeUint32List _uint32View = _list.buffer.asUint32List();

  NativeFloat64x2(this.x, this.y) {
    if (x is! num) throw ArgumentError(x);
    if (y is! num) throw ArgumentError(y);
  }

  NativeFloat64x2.splat(double v) : this(v, v);

  NativeFloat64x2.zero() : this.splat(0.0);

  NativeFloat64x2.fromFloat32x4(Float32x4 v) : this(v.x, v.y);

  /// Arguments [x] and [y] must be doubles.
  NativeFloat64x2._doubles(this.x, this.y);

  String toString() => '[$x, $y]';

  /// Addition operator.
  Float64x2 operator +(Float64x2 other) {
    return NativeFloat64x2._doubles(x + other.x, y + other.y);
  }

  /// Negate operator.
  Float64x2 operator -() {
    return NativeFloat64x2._doubles(-x, -y);
  }

  /// Subtraction operator.
  Float64x2 operator -(Float64x2 other) {
    return NativeFloat64x2._doubles(x - other.x, y - other.y);
  }

  /// Multiplication operator.
  Float64x2 operator *(Float64x2 other) {
    return NativeFloat64x2._doubles(x * other.x, y * other.y);
  }

  /// Division operator.
  Float64x2 operator /(Float64x2 other) {
    return NativeFloat64x2._doubles(x / other.x, y / other.y);
  }

  /// Returns a copy of [this] each lane being scaled by [s].
  Float64x2 scale(double s) {
    return NativeFloat64x2._doubles(x * s, y * s);
  }

  /// Returns the absolute value of this [Float64x2].
  Float64x2 abs() {
    return NativeFloat64x2._doubles(x.abs(), y.abs());
  }

  /// Clamps [this] to be in the range [lowerLimit]-[upperLimit].
  Float64x2 clamp(Float64x2 lowerLimit, Float64x2 upperLimit) {
    double _lx = lowerLimit.x;
    double _ly = lowerLimit.y;
    double _ux = upperLimit.x;
    double _uy = upperLimit.y;
    double _x = x;
    double _y = y;
    // MAX(MIN(self, upper), lower).
    _x = _x > _ux ? _ux : _x;
    _y = _y > _uy ? _uy : _y;
    _x = _x < _lx ? _lx : _x;
    _y = _y < _ly ? _ly : _y;
    return NativeFloat64x2._doubles(_x, _y);
  }

  /// Extract the sign bits from each lane return them in the first 2 bits.
  int get signMask {
    var view = _uint32View;
    _list[0] = x;
    _list[1] = y;
    var mx = (view[1] & 0x80000000) >> 31;
    var my = (view[3] & 0x80000000) >> 31;
    return mx | my << 1;
  }

  /// Returns a new [Float64x2] copied from [this] with a new x value.
  Float64x2 withX(double x) {
    if (x is! num) throw ArgumentError(x);
    return NativeFloat64x2._doubles(x, y);
  }

  /// Returns a new [Float64x2] copied from [this] with a new y value.
  Float64x2 withY(double y) {
    if (y is! num) throw ArgumentError(y);
    return NativeFloat64x2._doubles(x, y);
  }

  /// Returns the lane-wise minimum value in [this] or [other].
  Float64x2 min(Float64x2 other) {
    return NativeFloat64x2._doubles(
        x < other.x ? x : other.x, y < other.y ? y : other.y);
  }

  /// Returns the lane-wise maximum value in [this] or [other].
  Float64x2 max(Float64x2 other) {
    return NativeFloat64x2._doubles(
        x > other.x ? x : other.x, y > other.y ? y : other.y);
  }

  /// Returns the lane-wise square root of [this].
  Float64x2 sqrt() {
    return NativeFloat64x2._doubles(Math.sqrt(x), Math.sqrt(y));
  }
}

/// Checks that the value is a Uint32. If not, it's not valid as an array
/// index or offset. Also ensures that the value is non-negative.
bool _isInvalidArrayIndex(int index) {
  return (JS('bool', '(# >>> 0 !== #)', index, index));
}

/// Checks that [index] is a valid index into [list] which has length [length].
///
/// That is, [index] is an integer in the range `0..length - 1`.
void _checkValidIndex(int index, List list, int length) {
  if (_isInvalidArrayIndex(index) || JS('int', '#', index) >= length) {
    throw diagnoseIndexError(list, index);
  }
}

/// Checks that [start] and [end] form a range of a list of length [length].
///
/// That is: `start` and `end` are integers with `0 <= start <= end <= length`.
/// If `end` is `null` in which case it is considered to be `length`
///
/// Returns the actual value of `end`, which is `length` if `end` is `null`, and
/// the original value of `end` otherwise.
int _checkValidRange(int start, int end, int length) {
  if (_isInvalidArrayIndex(start) || // Ensures start is non-negative int.
      ((end == null)
          ? start > length
          : (_isInvalidArrayIndex(end) || start > end || end > length))) {
    throw diagnoseRangeError(start, end, length);
  }
  if (end == null) return length;
  return end;
}
