// Copyright (c) 2020, 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/compiler/ffi/native_type.h"

#include "platform/assert.h"
#include "platform/globals.h"
#include "vm/class_id.h"
#include "vm/constants.h"
#include "vm/zone_text_buffer.h"

#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
#include "vm/compiler/backend/locations.h"
#endif  // !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)

#if !defined(FFI_UNIT_TESTS)
#include "vm/symbols.h"
#endif

namespace dart {

namespace compiler {

namespace ffi {

PrimitiveType PrimitiveTypeFromSizeInBytes(intptr_t size) {
  ASSERT(size <= 8);
  ASSERT(size > 0);
  switch (size) {
    case 1:
      return kUint8;
    case 2:
      return kUint16;
    case 4:
      return kUint32;
    case 8:
      // Dart unboxed Representation for unsigned and signed is equal.
      return kInt64;
  }
  UNREACHABLE();
}

const NativePrimitiveType& NativeType::AsPrimitive() const {
  ASSERT(IsPrimitive());
  return static_cast<const NativePrimitiveType&>(*this);
}

const NativeArrayType& NativeType::AsArray() const {
  ASSERT(IsArray());
  return static_cast<const NativeArrayType&>(*this);
}

const NativeCompoundType& NativeType::AsCompound() const {
  ASSERT(IsCompound());
  return static_cast<const NativeCompoundType&>(*this);
}

bool NativePrimitiveType::IsInt() const {
  switch (representation_) {
    case kInt8:
    case kUint8:
    case kInt16:
    case kUint16:
    case kInt32:
    case kUint32:
    case kInt64:
    case kUint64:
      return true;
    default:
      return false;
  }
}

bool NativePrimitiveType::IsFloat() const {
  return representation_ == kFloat || representation_ == kDouble ||
         representation_ == kHalfDouble;
}

bool NativePrimitiveType::IsVoid() const {
  return representation_ == kVoid;
}

bool NativePrimitiveType::IsSigned() const {
  ASSERT(IsInt() || IsFloat());
  switch (representation_) {
    case kInt8:
    case kInt16:
    case kInt32:
    case kInt64:
    case kFloat:
    case kDouble:
    case kHalfDouble:
      return true;
    case kUint8:
    case kUint16:
    case kUint32:
    case kUint64:
    default:
      return false;
  }
}

static const intptr_t fundamental_size_in_bytes[kVoid + 1] = {
    1,  // kInt8,
    1,  // kUint8,
    2,  // kInt16,
    2,  // kUint16,
    4,  // kInt32,
    4,  // kUint32,
    8,  // kInt64,
    8,  // kUint64,
    4,  // kFloat,
    8,  // kDouble,
    4,  // kHalfDouble
    0,  // kVoid,
};

intptr_t NativePrimitiveType::SizeInBytes() const {
  return fundamental_size_in_bytes[representation_];
}

intptr_t NativePrimitiveType::AlignmentInBytesStack() const {
  switch (CallingConventions::kArgumentStackAlignment) {
    case kAlignedToWordSize:
      // The default is to align stack arguments to word size.
      return compiler::target::kWordSize;
    case kAlignedToWordSizeBut8AlignedTo8: {
      // However, arm32 deviates slightly.
      if (SizeInBytes() == 8) {
        return 8;
      }
      return compiler::target::kWordSize;
    }
    case kAlignedToValueSize:
      // iOS on arm64 only aligns to size.
      return SizeInBytes();
    default:
      UNREACHABLE();
  }
}

intptr_t NativePrimitiveType::AlignmentInBytesField() const {
  switch (CallingConventions::kFieldAlignment) {
    case kAlignedToValueSize:
      // The default is to align fields to their own size.
      return SizeInBytes();
    case kAlignedToValueSizeBut8AlignedTo4: {
      // However, on some 32-bit architectures, 8-byte fields are only aligned
      // to 4 bytes.
      if (SizeInBytes() == 8) {
        return 4;
      }
      return SizeInBytes();
    }
    default:
      UNREACHABLE();
  }
}

static bool ContainsHomogenuousFloatsInternal(const NativeTypes& types);

// Keep consistent with
// pkg/vm/lib/transformations/ffi_definitions.dart:StructLayout:_calculateLayout.
NativeCompoundType& NativeCompoundType::FromNativeTypes(
    Zone* zone,
    const NativeTypes& members,
    intptr_t member_packing) {
  intptr_t offset = 0;

  const intptr_t kAtLeast1ByteAligned = 1;
  // If this struct is nested in another struct, it should be aligned to the
  // largest alignment of its members.
  intptr_t alignment_field = kAtLeast1ByteAligned;
  // If this struct is passed on the stack, it should be aligned to the largest
  // alignment of its members when passing those members on the stack.
  intptr_t alignment_stack = kAtLeast1ByteAligned;
#if defined(TARGET_OS_MACOS_IOS) && defined(TARGET_ARCH_ARM64)
  // On iOS64 stack values can be less aligned than wordSize, which deviates
  // from the arm64 ABI.
  ASSERT(CallingConventions::kArgumentStackAlignment == kAlignedToValueSize);
  // Because the arm64 ABI aligns primitives to word size on the stack, every
  // struct will be automatically aligned to word size. iOS64 does not align
  // the primitives to word size, so we set structs to align to word size for
  // iOS64.
  // However, homogenous structs are treated differently. They are aligned to
  // their member alignment. (Which is 4 in case of a homogenous float).
  // Source: manual testing.
  if (!ContainsHomogenuousFloatsInternal(members)) {
    alignment_stack = compiler::target::kWordSize;
  }
#endif

  auto& member_offsets =
      *new (zone) ZoneGrowableArray<intptr_t>(zone, members.length());
  for (intptr_t i = 0; i < members.length(); i++) {
    const NativeType& member = *members[i];
    const intptr_t member_size = member.SizeInBytes();
    const intptr_t member_align_field =
        Utils::Minimum(member.AlignmentInBytesField(), member_packing);
    intptr_t member_align_stack = member.AlignmentInBytesStack();
    if (member_align_stack > member_packing &&
        member_packing < compiler::target::kWordSize) {
      member_align_stack = compiler::target::kWordSize;
    }
    offset = Utils::RoundUp(offset, member_align_field);
    member_offsets.Add(offset);
    offset += member_size;
    alignment_field = Utils::Maximum(alignment_field, member_align_field);
    alignment_stack = Utils::Maximum(alignment_stack, member_align_stack);
  }
  const intptr_t size = Utils::RoundUp(offset, alignment_field);

  return *new (zone) NativeCompoundType(members, member_offsets, size,
                                        alignment_field, alignment_stack);
}

#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
bool NativePrimitiveType::IsExpressibleAsRepresentation() const {
  switch (representation_) {
    case kInt8:
    case kUint8:
    case kInt16:
    case kUint16:
    case kHalfDouble:
      return false;
    case kInt32:
    case kUint32:
    case kInt64:
    case kUint64:  // We don't actually have a kUnboxedUint64.
    case kFloat:
    case kDouble:
      return true;
    case kVoid:
      return true;
    default:
      UNREACHABLE();  // Make MSVC happy.
  }
}

Representation NativePrimitiveType::AsRepresentation() const {
  ASSERT(IsExpressibleAsRepresentation());
  switch (representation_) {
    case kInt32:
      return kUnboxedInt32;
    case kUint32:
      return kUnboxedUint32;
    case kInt64:
    case kUint64:
      return kUnboxedInt64;
    case kFloat:
      return kUnboxedFloat;
    case kDouble:
      return kUnboxedDouble;
    case kVoid:
      return kUnboxedFfiIntPtr;
    default:
      UNREACHABLE();
  }
}
#endif  // !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)

bool NativePrimitiveType::Equals(const NativeType& other) const {
  if (!other.IsPrimitive()) {
    return false;
  }
  return other.AsPrimitive().representation_ == representation_;
}

bool NativeArrayType::Equals(const NativeType& other) const {
  if (!other.IsArray()) {
    return false;
  }
  return other.AsArray().length_ == length_ &&
         other.AsArray().element_type_.Equals(element_type_);
}

bool NativeCompoundType::Equals(const NativeType& other) const {
  if (!other.IsCompound()) {
    return false;
  }
  const auto& other_compound = other.AsCompound();
  const auto& other_members = other_compound.members_;
  if (other_members.length() != members_.length()) {
    return false;
  }
  for (intptr_t i = 0; i < members_.length(); i++) {
    if (!members_[i]->Equals(*other_members[i])) {
      return false;
    }
  }
  return true;
}

static PrimitiveType split_fundamental(PrimitiveType in) {
  switch (in) {
    case kInt16:
      return kInt8;
    case kInt32:
      return kInt16;
    case kInt64:
      return kInt32;
    case kUint16:
      return kUint8;
    case kUint32:
      return kUint16;
    case kUint64:
      return kUint32;
    case kDouble:
      return kHalfDouble;
    default:
      UNREACHABLE();
  }
}

NativePrimitiveType& NativePrimitiveType::Split(Zone* zone,
                                                intptr_t index) const {
  ASSERT(index == 0 || index == 1);
  auto new_rep = split_fundamental(representation());
  return *new (zone) NativePrimitiveType(new_rep);
}

static PrimitiveType TypeRepresentation(classid_t class_id) {
  switch (class_id) {
    case kFfiInt8Cid:
      return kInt8;
    case kFfiInt16Cid:
      return kInt16;
    case kFfiInt32Cid:
      return kInt32;
    case kFfiUint8Cid:
      return kUint8;
    case kFfiUint16Cid:
      return kUint16;
    case kFfiUint32Cid:
      return kUint32;
    case kFfiInt64Cid:
    case kFfiUint64Cid:
      return kInt64;
    case kFfiIntPtrCid:
      return compiler::target::kWordSize == 4 ? kInt32 : kInt64;
    case kFfiFloatCid:
      return kFloat;
    case kFfiDoubleCid:
      return kDouble;
    case kFfiPointerCid:
      return compiler::target::kWordSize == 4 ? kUint32 : kInt64;
    case kFfiVoidCid:
      return kVoid;
    case kFfiHandleCid:
      // We never expose this pointer as a Dart int, so no need to make it
      // unsigned on 32 bit architectures.
      return compiler::target::kWordSize == 4 ? kInt32 : kInt64;
    default:
      UNREACHABLE();
  }
}

NativeType& NativeType::FromTypedDataClassId(Zone* zone, classid_t class_id) {
  ASSERT(IsFfiPredefinedClassId(class_id));
  const auto fundamental_rep = TypeRepresentation(class_id);
  return *new (zone) NativePrimitiveType(fundamental_rep);
}

#if !defined(FFI_UNIT_TESTS)
NativeType& NativeType::FromAbstractType(Zone* zone, const AbstractType& type) {
  const classid_t class_id = type.type_class_id();
  if (IsFfiPredefinedClassId(class_id)) {
    return NativeType::FromTypedDataClassId(zone, class_id);
  }

  // User-defined structs.
  const auto& cls = Class::Handle(zone, type.type_class());

  auto& pragmas = Object::Handle(zone);
  Library::FindPragma(dart::Thread::Current(), /*only_core=*/false, cls,
                      Symbols::vm_ffi_struct_fields(), /*multiple=*/true,
                      &pragmas);
  ASSERT(!pragmas.IsNull());
  ASSERT(pragmas.IsGrowableObjectArray());
  const auto& pragmas_array = GrowableObjectArray::Cast(pragmas);
  auto& pragma = Instance::Handle(zone);
  auto& clazz = Class::Handle(zone);
  auto& library = Library::Handle(zone);
  for (intptr_t i = 0; i < pragmas_array.Length(); i++) {
    pragma ^= pragmas_array.At(i);
    clazz ^= pragma.clazz();
    library ^= clazz.library();
    if (String::Handle(zone, clazz.UserVisibleName())
            .Equals(Symbols::FfiStructLayout()) &&
        String::Handle(zone, library.url()).Equals(Symbols::DartFfi())) {
      break;
    }
  }

  const auto& struct_layout = pragma;
  const auto& struct_layout_class = clazz;
  ASSERT(String::Handle(zone, struct_layout_class.UserVisibleName())
             .Equals(Symbols::FfiStructLayout()));
  ASSERT(String::Handle(zone, library.url()).Equals(Symbols::DartFfi()));
  const auto& struct_layout_fields = Array::Handle(zone, clazz.fields());
  ASSERT(struct_layout_fields.Length() == 1);
  const auto& field =
      Field::Handle(zone, Field::RawCast(struct_layout_fields.At(0)));
  ASSERT(String::Handle(zone, field.name()).Equals(Symbols::FfiFieldTypes()));
  const auto& field_types =
      Array::Handle(zone, Array::RawCast(struct_layout.GetField(field)));

  auto& field_instance = Instance::Handle(zone);
  auto& field_type = AbstractType::Handle(zone);
  auto& field_native_types = *new (zone) ZoneGrowableArray<const NativeType*>(
      zone, field_types.Length());
  for (intptr_t i = 0; i < field_types.Length(); i++) {
    field_instance ^= field_types.At(i);
    if (field_instance.IsAbstractType()) {
      // Subtype of NativeType: Struct, native integer or native float.
      field_type ^= field_types.At(i);
      const auto& field_native_type =
          NativeType::FromAbstractType(zone, field_type);
      field_native_types.Add(&field_native_type);
    } else {
      // Inline array.
      const auto& struct_layout_array_class =
          Class::Handle(zone, field_instance.clazz());
      ASSERT(String::Handle(zone, struct_layout_array_class.UserVisibleName())
                 .Equals(Symbols::FfiStructLayoutArray()));
      const auto& struct_layout_array_fields =
          Array::Handle(zone, struct_layout_array_class.fields());
      ASSERT(struct_layout_array_fields.Length() == 2);
      const auto& element_type_field =
          Field::Handle(zone, Field::RawCast(struct_layout_array_fields.At(0)));
      ASSERT(String::Handle(zone, element_type_field.UserVisibleName())
                 .Equals(Symbols::FfiElementType()));
      field_type ^= field_instance.GetField(element_type_field);
      const auto& length_field =
          Field::Handle(zone, Field::RawCast(struct_layout_array_fields.At(1)));
      ASSERT(String::Handle(zone, length_field.UserVisibleName())
                 .Equals(Symbols::Length()));
      const auto& length = Smi::Handle(
          zone, Smi::RawCast(field_instance.GetField(length_field)));
      const auto& element_type = NativeType::FromAbstractType(zone, field_type);
      const auto& field_native_type =
          *new (zone) NativeArrayType(element_type, length.AsInt64Value());
      field_native_types.Add(&field_native_type);
    }
  }

  return NativeCompoundType::FromNativeTypes(zone, field_native_types);
}
#endif

#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
static PrimitiveType fundamental_rep(Representation rep) {
  switch (rep) {
    case kUnboxedDouble:
      return kDouble;
    case kUnboxedFloat:
      return kFloat;
    case kUnboxedInt32:
      return kInt32;
    case kUnboxedUint32:
      return kUint32;
    case kUnboxedInt64:
      return kInt64;
    default:
      break;
  }
  UNREACHABLE();
}

NativePrimitiveType& NativeType::FromUnboxedRepresentation(Zone* zone,
                                                           Representation rep) {
  return *new (zone) NativePrimitiveType(fundamental_rep(rep));
}
#endif  // !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)

const char* NativeType::ToCString(Zone* zone,
                                  bool multi_line,
                                  bool verbose) const {
  ZoneTextBuffer textBuffer(zone);
  PrintTo(&textBuffer, multi_line, verbose);
  return textBuffer.buffer();
}

#if !defined(FFI_UNIT_TESTS)
const char* NativeType::ToCString() const {
  return ToCString(Thread::Current()->zone());
}
#endif

static const char* PrimitiveTypeToCString(PrimitiveType rep) {
  switch (rep) {
    case kInt8:
      return "int8";
    case kUint8:
      return "uint8";
    case kInt16:
      return "int16";
    case kUint16:
      return "uint16";
    case kInt32:
      return "int32";
    case kUint32:
      return "uint32";
    case kInt64:
      return "int64";
    case kUint64:
      return "uint64";
    case kFloat:
      return "float";
    case kDouble:
      return "double";
    case kHalfDouble:
      return "half-double";
    case kVoid:
      return "void";
    default:
      UNREACHABLE();
  }
}

void NativeType::PrintTo(BaseTextBuffer* f,
                         bool multi_line,
                         bool verbose) const {
  f->AddString("I");
}

void NativePrimitiveType::PrintTo(BaseTextBuffer* f,
                                  bool multi_line,
                                  bool verbose) const {
  f->Printf("%s", PrimitiveTypeToCString(representation_));
}

const char* NativeFunctionType::ToCString(Zone* zone) const {
  ZoneTextBuffer textBuffer(zone);
  PrintTo(&textBuffer);
  return textBuffer.buffer();
}

void NativeArrayType::PrintTo(BaseTextBuffer* f,
                              bool multi_line,
                              bool verbose) const {
  f->AddString("Array(");
  f->Printf("element type: ");
  element_type_.PrintTo(f, /*multi_line*/ false, verbose);
  f->Printf(", length: %" Pd "", length_);
  f->AddString(")");
}

void NativeCompoundType::PrintTo(BaseTextBuffer* f,
                                 bool multi_line,
                                 bool verbose) const {
  f->AddString("Compound(");
  f->Printf("size: %" Pd "", SizeInBytes());
  if (verbose) {
    f->Printf(", field alignment: %" Pd ", ", AlignmentInBytesField());
    f->Printf("stack alignment: %" Pd ", ", AlignmentInBytesStack());
    f->AddString("members: {");
    if (multi_line) {
      f->AddString("\n  ");
    }
    for (intptr_t i = 0; i < members_.length(); i++) {
      if (i > 0) {
        if (multi_line) {
          f->AddString(",\n  ");
        } else {
          f->AddString(", ");
        }
      }
      f->Printf("%" Pd ": ", member_offsets_[i]);
      members_[i]->PrintTo(f);
    }
    if (multi_line) {
      f->AddString("\n");
    }
    f->AddString("}");
  }
  f->AddString(")");
  if (multi_line) {
    f->AddString("\n");
  }
}

#if !defined(FFI_UNIT_TESTS)
const char* NativeFunctionType::ToCString() const {
  return ToCString(Thread::Current()->zone());
}
#endif

void NativeFunctionType::PrintTo(BaseTextBuffer* f) const {
  f->AddString("(");
  for (intptr_t i = 0; i < argument_types_.length(); i++) {
    if (i > 0) {
      f->AddString(", ");
    }
    argument_types_[i]->PrintTo(f);
  }
  f->AddString(") => ");
  return_type_.PrintTo(f);
}

intptr_t NativePrimitiveType::NumPrimitiveMembersRecursive() const {
  return 1;
}

intptr_t NativeArrayType::NumPrimitiveMembersRecursive() const {
  return element_type_.NumPrimitiveMembersRecursive() * length_;
}

intptr_t NativeCompoundType::NumPrimitiveMembersRecursive() const {
  intptr_t count = 0;
  for (intptr_t i = 0; i < members_.length(); i++) {
    count += members_[i]->NumPrimitiveMembersRecursive();
  }
  return count;
}

const NativePrimitiveType& NativePrimitiveType::FirstPrimitiveMember() const {
  return *this;
}

const NativePrimitiveType& NativeArrayType::FirstPrimitiveMember() const {
  return element_type_.FirstPrimitiveMember();
}

const NativePrimitiveType& NativeCompoundType::FirstPrimitiveMember() const {
  ASSERT(NumPrimitiveMembersRecursive() >= 1);
  for (intptr_t i = 0; i < members().length(); i++) {
    if (members_[i]->NumPrimitiveMembersRecursive() >= 1) {
      return members_[i]->FirstPrimitiveMember();
    }
  }
  UNREACHABLE();
}

#if !defined(DART_PRECOMPILED_RUNTIME)
bool NativePrimitiveType::ContainsOnlyFloats(Range range) const {
  const auto this_range = Range::StartAndEnd(0, SizeInBytes());
  ASSERT(this_range.Contains(range));

  return IsFloat();
}

bool NativeArrayType::ContainsOnlyFloats(Range range) const {
  const auto this_range = Range::StartAndEnd(0, SizeInBytes());
  ASSERT(this_range.Contains(range));

  const intptr_t element_size_in_bytes = element_type_.SizeInBytes();

  // Assess how many elements are (partially) covered by the range.
  const intptr_t first_element_start = range.start() / element_size_in_bytes;
  const intptr_t last_element_index =
      range.end_inclusive() / element_size_in_bytes;
  const intptr_t num_elements = last_element_index - first_element_start + 1;
  ASSERT(num_elements >= 1);

  if (num_elements > 2) {
    // At least one full element covered.
    return element_type_.ContainsOnlyFloats(
        Range::StartAndLength(0, element_size_in_bytes));
  }

  // Check first element, which falls (partially) in range.
  const intptr_t first_start = first_element_start * element_size_in_bytes;
  const auto first_range =
      Range::StartAndLength(first_start, element_size_in_bytes);
  const auto first_range_clipped = range.Intersect(first_range);
  const auto range_in_first = first_range_clipped.Translate(-first_start);
  if (!element_type_.ContainsOnlyFloats(range_in_first)) {
    // First element contains not only floats in specified range.
    return false;
  }

  if (num_elements == 2) {
    // Check the second (and last) element, which falls (partially) in range.
    const intptr_t second_element_index = first_element_start + 1;
    const intptr_t second_start = second_element_index * element_size_in_bytes;
    const auto second_range =
        Range::StartAndLength(second_start, element_size_in_bytes);
    const auto second_range_clipped = range.Intersect(second_range);
    const auto range_in_second = second_range_clipped.Translate(-second_start);
    return element_type_.ContainsOnlyFloats(range_in_second);
  }

  return true;
}

bool NativeCompoundType::ContainsOnlyFloats(Range range) const {
  const auto this_range = Range::StartAndEnd(0, SizeInBytes());
  ASSERT(this_range.Contains(range));

  for (intptr_t i = 0; i < members_.length(); i++) {
    const auto& member = *members_[i];
    const intptr_t member_offset = member_offsets_[i];
    const intptr_t member_size = member.SizeInBytes();
    const auto member_range = Range::StartAndLength(member_offset, member_size);
    if (range.Overlaps(member_range)) {
      const auto member_range_clipped = member_range.Intersect(range);
      const auto range_in_member =
          member_range_clipped.Translate(-member_offset);
      if (!member.ContainsOnlyFloats(range_in_member)) {
        // Member contains not only floats in specified range.
        return false;
      }
    }
    if (member_range.After(range)) {
      // None of the remaining members fits the range.
      break;
    }
  }
  return true;
}

intptr_t NativeCompoundType::NumberOfWordSizeChunksOnlyFloat() const {
  // O(n^2) implementation, but only invoked for small structs.
  ASSERT(SizeInBytes() <= 16);
  const auto this_range = Range::StartAndEnd(0, SizeInBytes());
  const intptr_t size = SizeInBytes();
  intptr_t float_only_chunks = 0;
  for (intptr_t offset = 0; offset < size;
       offset += compiler::target::kWordSize) {
    const auto chunk_range =
        Range::StartAndLength(offset, compiler::target::kWordSize);
    if (ContainsOnlyFloats(chunk_range.Intersect(this_range))) {
      float_only_chunks++;
    }
  }
  return float_only_chunks;
}

intptr_t NativeCompoundType::NumberOfWordSizeChunksNotOnlyFloat() const {
  const intptr_t total_chunks =
      Utils::RoundUp(SizeInBytes(), compiler::target::kWordSize) /
      compiler::target::kWordSize;
  return total_chunks - NumberOfWordSizeChunksOnlyFloat();
}
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

bool NativePrimitiveType::ContainsUnalignedMembers() const {
  return false;
}

bool NativeArrayType::ContainsUnalignedMembers() const {
  return element_type_.ContainsUnalignedMembers();
}

bool NativeCompoundType::ContainsUnalignedMembers() const {
  for (intptr_t i = 0; i < members_.length(); i++) {
    const auto& member = *members_.At(i);
    const intptr_t member_offset = member_offsets_.At(i);
    const intptr_t member_alignment = member.AlignmentInBytesField();
    if (member_offset % member_alignment != 0) {
      return true;
    }
    if (member.ContainsUnalignedMembers()) {
      return true;
    }
  }
  return false;
}

static void ContainsHomogenuousFloatsRecursive(const NativeTypes& types,
                                               bool* only_float,
                                               bool* only_double) {
  for (intptr_t i = 0; i < types.length(); i++) {
    const auto& type = *types.At(i);
    const auto& member_type =
        type.IsArray() ? type.AsArray().element_type() : type;
    if (member_type.IsPrimitive()) {
      PrimitiveType type = member_type.AsPrimitive().representation();
      *only_float = *only_float && (type == kFloat);
      *only_double = *only_double && (type == kDouble);
    }
    if (member_type.IsCompound()) {
      ContainsHomogenuousFloatsRecursive(member_type.AsCompound().members(),
                                         only_float, only_double);
    }
  }
}

static bool ContainsHomogenuousFloatsInternal(const NativeTypes& types) {
  bool only_float = true;
  bool only_double = true;
  ContainsHomogenuousFloatsRecursive(types, &only_float, &only_double);
  return (only_double || only_float) && types.length() > 0;
}

bool NativeCompoundType::ContainsHomogenuousFloats() const {
  return ContainsHomogenuousFloatsInternal(this->members());
}

const NativeType& NativeType::WidenTo4Bytes(Zone* zone) const {
  if (IsInt() && SizeInBytes() <= 2) {
    if (IsSigned()) {
      return *new (zone) NativePrimitiveType(kInt32);
    } else {
      return *new (zone) NativePrimitiveType(kUint32);
    }
  }
  return *this;
}

}  // namespace ffi

}  // namespace compiler

}  // namespace dart
