// 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.

#include "vm/bootstrap_natives.h"

#include "include/dart_api.h"

#include "vm/exceptions.h"
#include "vm/native_entry.h"
#include "vm/object.h"

namespace dart {

// TypedData.

// Checks to see if offsetInBytes + num_bytes is in the range.
static void RangeCheck(intptr_t offset_in_bytes,
                       intptr_t access_size,
                       intptr_t length_in_bytes,
                       intptr_t element_size_in_bytes) {
  if (!Utils::RangeCheck(offset_in_bytes, access_size, length_in_bytes)) {
    const intptr_t index =
        (offset_in_bytes + access_size) / element_size_in_bytes;
    const intptr_t length = length_in_bytes / element_size_in_bytes;
    Exceptions::ThrowRangeError("index", Integer::Handle(Integer::New(index)),
                                0, length);
  }
}


// Checks to see if a length will not result in an OOM error.
static void LengthCheck(intptr_t len, intptr_t max) {
  if (len < 0 || len > max) {
    const String& error = String::Handle(String::NewFormatted(
        "Length (%" Pd ") of object must be in range [0..%" Pd "]", len, max));
    Exceptions::ThrowArgumentError(error);
  }
}


DEFINE_NATIVE_ENTRY(TypedData_length, 1) {
  GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0));
  if (instance.IsTypedData()) {
    const TypedData& array = TypedData::Cast(instance);
    return Smi::New(array.Length());
  }
  if (instance.IsExternalTypedData()) {
    const ExternalTypedData& array = ExternalTypedData::Cast(instance);
    return Smi::New(array.Length());
  }
  const String& error = String::Handle(String::NewFormatted(
      "Expected a TypedData object but found %s", instance.ToCString()));
  Exceptions::ThrowArgumentError(error);
  return Integer::null();
}


template <typename DstType, typename SrcType>
static RawBool* CopyData(const Instance& dst,
                         const Instance& src,
                         const Smi& dst_start,
                         const Smi& src_start,
                         const Smi& length,
                         bool clamped) {
  const DstType& dst_array = DstType::Cast(dst);
  const SrcType& src_array = SrcType::Cast(src);
  const intptr_t dst_offset_in_bytes = dst_start.Value();
  const intptr_t src_offset_in_bytes = src_start.Value();
  const intptr_t length_in_bytes = length.Value();
  ASSERT(Utils::RangeCheck(src_offset_in_bytes, length_in_bytes,
                           src_array.LengthInBytes()));
  ASSERT(Utils::RangeCheck(dst_offset_in_bytes, length_in_bytes,
                           dst_array.LengthInBytes()));
  if (clamped) {
    TypedData::ClampedCopy<DstType, SrcType>(dst_array, dst_offset_in_bytes,
                                             src_array, src_offset_in_bytes,
                                             length_in_bytes);
  } else {
    TypedData::Copy<DstType, SrcType>(dst_array, dst_offset_in_bytes, src_array,
                                      src_offset_in_bytes, length_in_bytes);
  }
  return Bool::True().raw();
}


static bool IsClamped(intptr_t cid) {
  switch (cid) {
    case kTypedDataUint8ClampedArrayCid:
    case kExternalTypedDataUint8ClampedArrayCid:
    case kTypedDataUint8ClampedArrayViewCid:
      return true;
    default:
      return false;
  }
}


static bool IsUint8(intptr_t cid) {
  switch (cid) {
    case kTypedDataUint8ClampedArrayCid:
    case kExternalTypedDataUint8ClampedArrayCid:
    case kTypedDataUint8ClampedArrayViewCid:
    case kTypedDataUint8ArrayCid:
    case kExternalTypedDataUint8ArrayCid:
    case kTypedDataUint8ArrayViewCid:
      return true;
    default:
      return false;
  }
}


DEFINE_NATIVE_ENTRY(TypedData_setRange, 7) {
  const Instance& dst = Instance::CheckedHandle(arguments->NativeArgAt(0));
  const Smi& dst_start = Smi::CheckedHandle(arguments->NativeArgAt(1));
  const Smi& length = Smi::CheckedHandle(arguments->NativeArgAt(2));
  const Instance& src = Instance::CheckedHandle(arguments->NativeArgAt(3));
  const Smi& src_start = Smi::CheckedHandle(arguments->NativeArgAt(4));
  const Smi& to_cid_smi = Smi::CheckedHandle(arguments->NativeArgAt(5));
  const Smi& from_cid_smi = Smi::CheckedHandle(arguments->NativeArgAt(6));

  if (length.Value() < 0) {
    const String& error = String::Handle(String::NewFormatted(
        "length (%" Pd ") must be non-negative", length.Value()));
    Exceptions::ThrowArgumentError(error);
  }
  const intptr_t to_cid = to_cid_smi.Value();
  const intptr_t from_cid = from_cid_smi.Value();

  const bool needs_clamping = IsClamped(to_cid) && !IsUint8(from_cid);
  if (dst.IsTypedData()) {
    if (src.IsTypedData()) {
      return CopyData<TypedData, TypedData>(dst, src, dst_start, src_start,
                                            length, needs_clamping);
    } else if (src.IsExternalTypedData()) {
      return CopyData<TypedData, ExternalTypedData>(
          dst, src, dst_start, src_start, length, needs_clamping);
    }
  } else if (dst.IsExternalTypedData()) {
    if (src.IsTypedData()) {
      return CopyData<ExternalTypedData, TypedData>(
          dst, src, dst_start, src_start, length, needs_clamping);
    } else if (src.IsExternalTypedData()) {
      return CopyData<ExternalTypedData, ExternalTypedData>(
          dst, src, dst_start, src_start, length, needs_clamping);
    }
  }
  UNREACHABLE();
  return Bool::False().raw();
}


// We check the length parameter against a possible maximum length for the
// array based on available physical addressable memory on the system. The
// maximum possible length is a scaled value of kSmiMax which is set up based
// on whether the underlying architecture is 32-bit or 64-bit.
// Argument 0 is type arguments and is ignored.
#define TYPED_DATA_NEW(name)                                                   \
  DEFINE_NATIVE_ENTRY(TypedData_##name##_new, 2) {                             \
    GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(1));      \
    intptr_t cid = kTypedData##name##Cid;                                      \
    intptr_t len = length.Value();                                             \
    intptr_t max = TypedData::MaxElements(cid);                                \
    LengthCheck(len, max);                                                     \
    return TypedData::New(cid, len);                                           \
  }


#define TYPED_DATA_NEW_NATIVE(name) TYPED_DATA_NEW(name)


CLASS_LIST_TYPED_DATA(TYPED_DATA_NEW_NATIVE)

#define TYPED_DATA_GETTER(getter, object, ctor, access_size)                   \
  DEFINE_NATIVE_ENTRY(TypedData_##getter, 2) {                                 \
    GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance,                           \
                                 arguments->NativeArgAt(0));                   \
    GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes,                           \
                                 arguments->NativeArgAt(1));                   \
    if (instance.IsTypedData()) {                                              \
      const TypedData& array = TypedData::Cast(instance);                      \
      RangeCheck(offsetInBytes.Value(), access_size, array.LengthInBytes(),    \
                 access_size);                                                 \
      return object::ctor(array.getter(offsetInBytes.Value()));                \
    }                                                                          \
    if (instance.IsExternalTypedData()) {                                      \
      const ExternalTypedData& array = ExternalTypedData::Cast(instance);      \
      RangeCheck(offsetInBytes.Value(), access_size, array.LengthInBytes(),    \
                 access_size);                                                 \
      return object::ctor(array.getter(offsetInBytes.Value()));                \
    }                                                                          \
    const String& error = String::Handle(String::NewFormatted(                 \
        "Expected a TypedData object but found %s", instance.ToCString()));    \
    Exceptions::ThrowArgumentError(error);                                     \
    return object::null();                                                     \
  }


#define TYPED_DATA_SETTER(setter, object, get_object_value, access_size,       \
                          access_type)                                         \
  DEFINE_NATIVE_ENTRY(TypedData_##setter, 3) {                                 \
    GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance,                           \
                                 arguments->NativeArgAt(0));                   \
    GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes,                           \
                                 arguments->NativeArgAt(1));                   \
    GET_NON_NULL_NATIVE_ARGUMENT(object, value, arguments->NativeArgAt(2));    \
    if (instance.IsTypedData()) {                                              \
      const TypedData& array = TypedData::Cast(instance);                      \
      RangeCheck(offsetInBytes.Value(), access_size, array.LengthInBytes(),    \
                 access_size);                                                 \
      array.setter(offsetInBytes.Value(),                                      \
                   static_cast<access_type>(value.get_object_value()));        \
    } else if (instance.IsExternalTypedData()) {                               \
      const ExternalTypedData& array = ExternalTypedData::Cast(instance);      \
      RangeCheck(offsetInBytes.Value(), access_size, array.LengthInBytes(),    \
                 access_size);                                                 \
      array.setter(offsetInBytes.Value(),                                      \
                   static_cast<access_type>(value.get_object_value()));        \
    } else {                                                                   \
      const String& error = String::Handle(String::NewFormatted(               \
          "Expected a TypedData object but found %s", instance.ToCString()));  \
      Exceptions::ThrowArgumentError(error);                                   \
    }                                                                          \
    return Object::null();                                                     \
  }

#define TYPED_DATA_NATIVES(type_name, object, ctor, get_object_value,          \
                           access_size, access_type)                           \
  TYPED_DATA_GETTER(Get##type_name, object, ctor, access_size)                 \
  TYPED_DATA_SETTER(Set##type_name, object, get_object_value, access_size,     \
                    access_type)

TYPED_DATA_NATIVES(Int8, Integer, New, AsTruncatedUint32Value, 1, int8_t)
TYPED_DATA_NATIVES(Uint8, Integer, New, AsTruncatedUint32Value, 1, uint8_t)
TYPED_DATA_NATIVES(Int16, Integer, New, AsTruncatedUint32Value, 2, int16_t)
TYPED_DATA_NATIVES(Uint16, Integer, New, AsTruncatedUint32Value, 2, uint16_t)
TYPED_DATA_NATIVES(Int32, Integer, New, AsTruncatedUint32Value, 4, int32_t)
TYPED_DATA_NATIVES(Uint32, Integer, New, AsTruncatedUint32Value, 4, uint32_t)
TYPED_DATA_NATIVES(Int64, Integer, New, AsTruncatedInt64Value, 8, int64_t)
TYPED_DATA_NATIVES(Uint64,
                   Integer,
                   NewFromUint64,
                   AsTruncatedInt64Value,
                   8,
                   uint64_t)
TYPED_DATA_NATIVES(Float32, Double, New, value, 4, float)
TYPED_DATA_NATIVES(Float64, Double, New, value, 8, double)
TYPED_DATA_NATIVES(Float32x4, Float32x4, New, value, 16, simd128_value_t)
TYPED_DATA_NATIVES(Int32x4, Int32x4, New, value, 16, simd128_value_t)
TYPED_DATA_NATIVES(Float64x2, Float64x2, New, value, 16, simd128_value_t)


DEFINE_NATIVE_ENTRY(ByteData_ToEndianInt16, 2) {
  GET_NON_NULL_NATIVE_ARGUMENT(Smi, host_value, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1));
  int16_t value = host_value.Value();
  if (little_endian.value()) {
    value = Utils::HostToLittleEndian16(value);
  } else {
    value = Utils::HostToBigEndian16(value);
  }
  return Smi::New(value);
}


DEFINE_NATIVE_ENTRY(ByteData_ToEndianUint16, 2) {
  GET_NON_NULL_NATIVE_ARGUMENT(Smi, host_value, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1));
  uint16_t value = host_value.Value();
  if (little_endian.value()) {
    return Smi::New(Utils::HostToLittleEndian16(value));
  }
  return Smi::New(Utils::HostToBigEndian16(value));
}


DEFINE_NATIVE_ENTRY(ByteData_ToEndianInt32, 2) {
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1));
  ASSERT((host_value.AsInt64Value() >= kMinInt32) ||
         (host_value.AsInt64Value() <= kMaxInt32));
  int32_t value = static_cast<int32_t>(host_value.AsInt64Value());
  if (little_endian.value()) {
    value = Utils::HostToLittleEndian32(value);
  } else {
    value = Utils::HostToBigEndian32(value);
  }
  return Integer::New(value);
}


DEFINE_NATIVE_ENTRY(ByteData_ToEndianUint32, 2) {
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1));
  ASSERT(host_value.AsInt64Value() <= kMaxUint32);
  uint32_t value = static_cast<uint32_t>(host_value.AsInt64Value());
  if (little_endian.value()) {
    value = Utils::HostToLittleEndian32(value);
  } else {
    value = Utils::HostToBigEndian32(value);
  }
  return Integer::New(value);
}


DEFINE_NATIVE_ENTRY(ByteData_ToEndianInt64, 2) {
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1));
  int64_t value = host_value.AsInt64Value();
  if (little_endian.value()) {
    value = Utils::HostToLittleEndian64(value);
  } else {
    value = Utils::HostToBigEndian64(value);
  }
  return Integer::New(value);
}


DEFINE_NATIVE_ENTRY(ByteData_ToEndianUint64, 2) {
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1));
  uint64_t value;
  if (host_value.IsBigint()) {
    const Bigint& bigint = Bigint::Cast(host_value);
    ASSERT(bigint.FitsIntoUint64());
    value = bigint.AsUint64Value();
  } else {
    ASSERT(host_value.IsMint() || host_value.IsSmi());
    value = host_value.AsInt64Value();
  }
  if (little_endian.value()) {
    value = Utils::HostToLittleEndian64(value);
  } else {
    value = Utils::HostToBigEndian64(value);
  }
  return Integer::NewFromUint64(value);
}


DEFINE_NATIVE_ENTRY(ByteData_ToEndianFloat32, 2) {
  GET_NON_NULL_NATIVE_ARGUMENT(Double, host_value, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1));
  float value = host_value.value();
  if (little_endian.value()) {
    value =
        bit_cast<float>(Utils::HostToLittleEndian32(bit_cast<uint32_t>(value)));
  } else {
    value =
        bit_cast<float>(Utils::HostToBigEndian32(bit_cast<uint32_t>(value)));
  }
  return Double::New(value);
}


DEFINE_NATIVE_ENTRY(ByteData_ToEndianFloat64, 2) {
  GET_NON_NULL_NATIVE_ARGUMENT(Double, host_value, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1));
  double value = host_value.value();
  if (little_endian.value()) {
    value = bit_cast<double>(
        Utils::HostToLittleEndian64(bit_cast<uint64_t>(value)));
  } else {
    value =
        bit_cast<double>(Utils::HostToBigEndian64(bit_cast<uint64_t>(value)));
  }
  return Double::New(value);
}

}  // namespace dart
