// 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/bigint_operations.h"
#include "vm/exceptions.h"
#include "vm/native_entry.h"
#include "vm/object.h"

namespace dart {

// TypedData.

// Checks to see if offset_in_bytes is in the range.
static bool RangeCheck(intptr_t offset_in_bytes, intptr_t length_in_bytes) {
  return ((offset_in_bytes >= 0) &&
          (length_in_bytes > 0) &&
          (offset_in_bytes < length_in_bytes));
}


// Checks to see if offsetInBytes + num_bytes is in the range.
static void SetRangeCheck(intptr_t offset_in_bytes,
                          intptr_t num_bytes,
                          intptr_t length_in_bytes,
                          intptr_t element_size_in_bytes) {
  if (!Utils::RangeCheck(offset_in_bytes, num_bytes, length_in_bytes)) {
    const String& error = String::Handle(String::NewFormatted(
        "index (%" Pd ") must be in the range [0..%" Pd ")",
        (offset_in_bytes / element_size_in_bytes),
        (length_in_bytes / element_size_in_bytes)));
    const Array& args = Array::Handle(Array::New(1));
    args.SetAt(0, error);
    Exceptions::ThrowByType(Exceptions::kRange, args);
  }
}


// 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));
    const Array& args = Array::Handle(Array::New(1));
    args.SetAt(0, error);
    Exceptions::ThrowByType(Exceptions::kArgument, args);
  }
}


  static void PeerFinalizer(Dart_WeakPersistentHandle handle, void* peer) {
  Dart_DeleteWeakPersistentHandle(handle);
  OS::AlignedFree(peer);
}


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()));
  const Array& args = Array::Handle(Array::New(1));
  args.SetAt(0, error);
  Exceptions::ThrowByType(Exceptions::kArgument, args);
  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) {
  const DstType& dst_array = DstType::Cast(dst);
  const SrcType& src_array = SrcType::Cast(src);
  intptr_t element_size_in_bytes = dst_array.ElementSizeInBytes();
  intptr_t dst_offset_in_bytes = dst_start.Value() * element_size_in_bytes;
  intptr_t src_offset_in_bytes = src_start.Value() * element_size_in_bytes;
  intptr_t length_in_bytes = length.Value() * element_size_in_bytes;
  if (dst_array.ElementType() != src_array.ElementType()) {
    return Bool::False().raw();
  }
  SetRangeCheck(src_offset_in_bytes,
                length_in_bytes,
                src_array.LengthInBytes(),
                element_size_in_bytes);
  SetRangeCheck(dst_offset_in_bytes,
                length_in_bytes,
                dst_array.LengthInBytes(),
                element_size_in_bytes);
  TypedData::Copy<DstType, SrcType>(dst_array, dst_offset_in_bytes,
                                    src_array, src_offset_in_bytes,
                                    length_in_bytes);
  return Bool::True().raw();
}


DEFINE_NATIVE_ENTRY(TypedData_setRange, 5) {
  GET_NON_NULL_NATIVE_ARGUMENT(Instance, dst, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Smi, dst_start, arguments->NativeArgAt(1));
  GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(2));
  GET_NON_NULL_NATIVE_ARGUMENT(Instance, src, arguments->NativeArgAt(3));
  GET_NON_NULL_NATIVE_ARGUMENT(Smi, src_start, arguments->NativeArgAt(4));

  if (length.Value() < 0) {
    const String& error = String::Handle(String::NewFormatted(
        "length (%" Pd ") must be non-negative", length.Value()));
    const Array& args = Array::Handle(Array::New(1));
    args.SetAt(0, error);
    Exceptions::ThrowByType(Exceptions::kArgument, args);
  }
  if (dst.IsTypedData()) {
    if (src.IsTypedData()) {
      return CopyData<TypedData, TypedData>(
          dst, src, dst_start, src_start, length);
    } else if (src.IsExternalTypedData()) {
      return CopyData<TypedData, ExternalTypedData>(
          dst, src, dst_start, src_start, length);
    }
  } else if (dst.IsExternalTypedData()) {
    if (src.IsTypedData()) {
      return CopyData<ExternalTypedData, TypedData>(
          dst, src, dst_start, src_start, length);
    } else if (src.IsExternalTypedData()) {
      return CopyData<ExternalTypedData, ExternalTypedData>(
          dst, src, dst_start, src_start, length);
    }
  }
  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.
#define TYPED_DATA_NEW(name)                                                   \
DEFINE_NATIVE_ENTRY(TypedData_##name##_new, 1) {                               \
  GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));        \
  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);                                             \
}                                                                              \


// 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.
#define EXT_TYPED_DATA_NEW(name)                                               \
DEFINE_NATIVE_ENTRY(ExternalTypedData_##name##_new, 1) {                       \
  const int kAlignment = 16;                                                   \
  GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));        \
  intptr_t cid = kExternalTypedData##name##Cid;                                \
  intptr_t len = length.Value();                                               \
  intptr_t max = ExternalTypedData::MaxElements(cid);                          \
  LengthCheck(len, max);                                                       \
  intptr_t len_bytes = len * ExternalTypedData::ElementSizeInBytes(cid);       \
  uint8_t* data = OS::AllocateAlignedArray<uint8_t>(len_bytes, kAlignment);    \
  const ExternalTypedData& obj =                                               \
      ExternalTypedData::Handle(ExternalTypedData::New(cid, data, len));       \
  obj.AddFinalizer(data, PeerFinalizer);                                       \
  return obj.raw();                                                            \
}                                                                              \


#define TYPED_DATA_NEW_NATIVE(name)                                            \
  TYPED_DATA_NEW(name)                                                         \
  EXT_TYPED_DATA_NEW(name)                                                     \


CLASS_LIST_TYPED_DATA(TYPED_DATA_NEW_NATIVE)

#define TYPED_DATA_GETTER(getter, object)                                      \
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);                        \
    ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes()));          \
    return object::New(array.getter(offsetInBytes.Value()));                   \
  }                                                                            \
  if (instance.IsExternalTypedData()) {                                        \
    const ExternalTypedData& array = ExternalTypedData::Cast(instance);        \
    ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes()));          \
    return object::New(array.getter(offsetInBytes.Value()));                   \
  }                                                                            \
  const String& error = String::Handle(String::NewFormatted(                   \
      "Expected a TypedData object but found %s", instance.ToCString()));      \
  const Array& args = Array::Handle(Array::New(1));                            \
  args.SetAt(0, error);                                                        \
  Exceptions::ThrowByType(Exceptions::kArgument, args);                        \
  return object::null();                                                       \
}                                                                              \


#define TYPED_DATA_SETTER(setter, object, get_object_value)                    \
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);                        \
    ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes()));          \
    array.setter(offsetInBytes.Value(), value.get_object_value());             \
  } else if (instance.IsExternalTypedData()) {                                 \
    const ExternalTypedData& array = ExternalTypedData::Cast(instance);        \
    ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes()));          \
    array.setter(offsetInBytes.Value(), value.get_object_value());             \
  } else {                                                                     \
    const String& error = String::Handle(String::NewFormatted(                 \
        "Expected a TypedData object but found %s", instance.ToCString()));    \
    const Array& args = Array::Handle(Array::New(1));                          \
    args.SetAt(0, error);                                                      \
    Exceptions::ThrowByType(Exceptions::kArgument, args);                      \
  }                                                                            \
  return Object::null();                                                       \
}


#define TYPED_DATA_UINT64_GETTER(getter, object)                               \
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)); \
  uint64_t value = 0;                                                          \
  if (instance.IsTypedData()) {                                                \
    const TypedData& array = TypedData::Cast(instance);                        \
    ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes()));          \
    value = array.getter(offsetInBytes.Value());                               \
  } else if (instance.IsExternalTypedData()) {                                 \
    const ExternalTypedData& array = ExternalTypedData::Cast(instance);        \
    ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes()));          \
    value = array.getter(offsetInBytes.Value());                               \
  } else {                                                                     \
    const String& error = String::Handle(String::NewFormatted(                 \
        "Expected a TypedData object but found %s", instance.ToCString()));    \
    const Array& args = Array::Handle(Array::New(1));                          \
    args.SetAt(0, error);                                                      \
    Exceptions::ThrowByType(Exceptions::kArgument, args);                      \
  }                                                                            \
  return Integer::NewFromUint64(value);                                        \
}                                                                              \


// TODO(asiva): Consider truncating the bigint value if it does not fit into
// a uint64_t value (see ASSERT(BigintOperations::FitsIntoUint64(bigint))).
#define TYPED_DATA_UINT64_SETTER(setter, object)                               \
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));      \
  uint64_t object_value;                                                       \
  if (value.IsBigint()) {                                                      \
    const Bigint& bigint = Bigint::Cast(value);                                \
    ASSERT(BigintOperations::FitsIntoUint64(bigint));                          \
    object_value = BigintOperations::AbsToUint64(bigint);                      \
  } else {                                                                     \
    ASSERT(value.IsMint() || value.IsSmi());                                   \
    object_value = value.AsInt64Value();                                       \
  }                                                                            \
  if (instance.IsTypedData()) {                                                \
    const TypedData& array = TypedData::Cast(instance);                        \
    ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes()));          \
    array.setter(offsetInBytes.Value(), object_value);                         \
  } else if (instance.IsExternalTypedData()) {                                 \
    const ExternalTypedData& array = ExternalTypedData::Cast(instance);        \
    ASSERT(RangeCheck(offsetInBytes.Value(), array.LengthInBytes()));          \
    array.setter(offsetInBytes.Value(), object_value);                         \
  } else {                                                                     \
    const String& error = String::Handle(String::NewFormatted(                 \
        "Expected a TypedData object but found %s", instance.ToCString()));    \
    const Array& args = Array::Handle(Array::New(1));                          \
    args.SetAt(0, error);                                                      \
    Exceptions::ThrowByType(Exceptions::kArgument, args);                      \
  }                                                                            \
  return Object::null();                                                       \
}


#define TYPED_DATA_NATIVES(getter, setter, object, get_object_value)           \
  TYPED_DATA_GETTER(getter, object)                                            \
  TYPED_DATA_SETTER(setter, object, get_object_value)                          \


#define TYPED_DATA_UINT64_NATIVES(getter, setter, object)                      \
  TYPED_DATA_UINT64_GETTER(getter, object)                                     \
  TYPED_DATA_UINT64_SETTER(setter, object)                                     \


TYPED_DATA_NATIVES(GetInt8, SetInt8, Smi, Value)
TYPED_DATA_NATIVES(GetUint8, SetUint8, Smi, Value)
TYPED_DATA_NATIVES(GetInt16, SetInt16, Smi, Value)
TYPED_DATA_NATIVES(GetUint16, SetUint16, Smi, Value)
TYPED_DATA_NATIVES(GetInt32, SetInt32, Integer, AsInt64Value)
TYPED_DATA_NATIVES(GetUint32, SetUint32, Integer, AsInt64Value)
TYPED_DATA_NATIVES(GetInt64, SetInt64, Integer, AsInt64Value)
TYPED_DATA_UINT64_NATIVES(GetUint64, SetUint64, Integer)
TYPED_DATA_NATIVES(GetFloat32, SetFloat32, Double, value)
TYPED_DATA_NATIVES(GetFloat64, SetFloat64, Double, value)
TYPED_DATA_NATIVES(GetFloat32x4, SetFloat32x4, Float32x4, value)


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() <= kMaxInt32);
  int32_t value = 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 = 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(BigintOperations::FitsIntoUint64(bigint));
    value = BigintOperations::AbsToUint64(bigint);
  } 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
