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

#ifndef RUNTIME_VM_COMPILER_FFI_NATIVE_TYPE_H_
#define RUNTIME_VM_COMPILER_FFI_NATIVE_TYPE_H_

#include "platform/assert.h"
#include "platform/globals.h"
#include "vm/allocation.h"
#include "vm/growable_array.h"

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

namespace dart {

class BaseTextBuffer;

namespace compiler {

namespace ffi {

class NativePrimitiveType;
class NativeArrayType;
class NativeCompoundType;
class NativeStructType;

// NativeTypes are the types used in calling convention specifications:
// integers, floats, and compounds.
//
// NativeTypes exclude C types which are not discussed in calling conventions:
// pointer types (they are lowered to integers).
//
// The NativeTypes are a partially overlapping with unboxed Representations.
// NativeTypes do not have Dart representations such as the following:
// * tagged
// * untagged
//
// Instead, NativeTypes support representations not supported in Dart's unboxed
// Representations, such as:
// * Primitive types (https://en.cppreference.com/w/cpp/language/types):
//   * int8_t
//   * int16_t
//   * uint8_t
//   * uint16t
//   * void
// * Compound types (https://en.cppreference.com/w/cpp/language/type):
//   * Struct
//   * Union
class NativeType : public ZoneAllocated {
 public:
#if !defined(FFI_UNIT_TESTS)
  static const NativeType* FromAbstractType(Zone* zone,
                                            const AbstractType& type,
                                            const char** error);
#endif
  static const NativeType& FromTypedDataClassId(Zone* zone, classid_t class_id);

#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
  static NativePrimitiveType& FromUnboxedRepresentation(Zone* zone,
                                                        Representation rep);
#endif  // !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)

  virtual bool IsPrimitive() const { return false; }
  const NativePrimitiveType& AsPrimitive() const;
  virtual bool IsArray() const { return false; }
  const NativeArrayType& AsArray() const;
  virtual bool IsCompound() const { return false; }
  const NativeCompoundType& AsCompound() const;
  virtual bool IsStruct() const { return false; }
  const NativeStructType& AsStruct() const;

  virtual bool IsInt() const { return false; }
  virtual bool IsFloat() const { return false; }
  virtual bool IsVoid() const { return false; }

  virtual bool IsSigned() const { return false; }

  // The size in bytes of this representation.
  //
  // Does not take into account padding required if repeating.
  virtual intptr_t SizeInBytes() const = 0;

  // The alignment in bytes of this represntation on the stack.
  virtual intptr_t AlignmentInBytesStack() const = 0;

  // The alignment in bytes of this representation as member of a composite.
  virtual intptr_t AlignmentInBytesField() const = 0;

#if !defined(DART_PRECOMPILED_RUNTIME)
  // Returns true iff a range within this type contains only floats.
  //
  // Useful for determining whether struct is passed in FP registers on x64.
  virtual bool ContainsOnlyFloats(Range range) const = 0;
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

  // True iff any members are misaligned recursively due to packing.
  virtual bool ContainsUnalignedMembers(intptr_t offset = 0) const = 0;

#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
  // NativeTypes which are available as unboxed Representations.
  virtual bool IsExpressibleAsRepresentation() const { return false; }

  // Unboxed Representation if it exists.
  virtual Representation AsRepresentation() const { UNREACHABLE(); }

  // Unboxed Representation, over approximates if needed.
  Representation AsRepresentationOverApprox(Zone* zone_) const {
    const auto& widened = WidenTo4Bytes(zone_);
    return widened.AsRepresentation();
  }
#endif  // !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)

  virtual bool Equals(const NativeType& other) const { UNREACHABLE(); }

  // Split representation in two.
  virtual NativeType& Split(Zone* zone, intptr_t index) const { UNREACHABLE(); }

  // If this is a 8 or 16 bit int, returns a 32 bit container.
  // Otherwise, return original representation.
  const NativeType& WidenTo4Bytes(Zone* zone) const;

  virtual void PrintTo(BaseTextBuffer* f,
                       bool multi_line = false,
                       bool verbose = true) const;
  const char* ToCString(Zone* zone,
                        bool multi_line = false,
                        bool verbose = true) const;
#if !defined(FFI_UNIT_TESTS)
  const char* ToCString() const;
#endif

  virtual intptr_t NumPrimitiveMembersRecursive() const = 0;
  virtual const NativePrimitiveType& FirstPrimitiveMember() const = 0;

  // Returns the number of primitive members when this aggregrate is flattened
  // out, and sets the out-parameters to the first two such primitive members.
  virtual intptr_t PrimitivePairMembers(
      const NativePrimitiveType** first,
      const NativePrimitiveType** second,
      intptr_t offset_in_members = 0) const = 0;

  virtual ~NativeType() {}

 protected:
  NativeType() {}
};

enum PrimitiveType {
  kInt8,
  kUint8,
  kInt16,
  kUint16,
  kInt32,
  kUint32,
  kInt64,
  kUint64,
  kFloat,
  kDouble,
  kHalfDouble,  // When doubles are split over two 32 bit locations.
  kVoid,
  // TODO(37470): Add packed data structures.
};

PrimitiveType PrimitiveTypeFromSizeInBytes(intptr_t size);

// Represents a primitive native type.
//
// These are called object types in the C standard (ISO/IEC 9899:2011) and
// fundamental types in C++ (https://en.cppreference.com/w/cpp/language/types)
// but more commonly these are called primitive types
// (https://en.wikipedia.org/wiki/Primitive_data_type).
class NativePrimitiveType : public NativeType {
 public:
  explicit NativePrimitiveType(PrimitiveType rep) : representation_(rep) {}

  PrimitiveType representation() const { return representation_; }

  virtual bool IsPrimitive() const { return true; }

  virtual bool IsInt() const;
  virtual bool IsFloat() const;
  virtual bool IsVoid() const;

  virtual bool IsSigned() const;

  virtual intptr_t SizeInBytes() const;
  virtual intptr_t AlignmentInBytesStack() const;
  virtual intptr_t AlignmentInBytesField() const;

#if !defined(DART_PRECOMPILED_RUNTIME)
  virtual bool ContainsOnlyFloats(Range range) const;
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

  virtual bool ContainsUnalignedMembers(intptr_t offset = 0) const;

#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
  virtual bool IsExpressibleAsRepresentation() const;
  virtual Representation AsRepresentation() const;
#endif  // !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)

  virtual bool Equals(const NativeType& other) const;
  virtual NativePrimitiveType& Split(Zone* zone, intptr_t part) const;

  virtual void PrintTo(BaseTextBuffer* f,
                       bool multi_line = false,
                       bool verbose = true) const;

  virtual intptr_t NumPrimitiveMembersRecursive() const;
  virtual const NativePrimitiveType& FirstPrimitiveMember() const;
  virtual intptr_t PrimitivePairMembers(const NativePrimitiveType** first,
                                        const NativePrimitiveType** second,
                                        intptr_t offset_in_members = 0) const;

  virtual ~NativePrimitiveType() {}

 private:
  const PrimitiveType representation_;
};

// Fixed-length arrays.
class NativeArrayType : public NativeType {
 public:
  NativeArrayType(const NativeType& element_type, intptr_t length)
      : element_type_(element_type), length_(length) {
    ASSERT(!element_type.IsArray());
    ASSERT(length > 0);
  }

  const NativeType& element_type() const { return element_type_; }
  intptr_t length() const { return length_; }

  virtual bool IsArray() const { return true; }

  virtual intptr_t SizeInBytes() const {
    return element_type_.SizeInBytes() * length_;
  }
  virtual intptr_t AlignmentInBytesField() const {
    return element_type_.AlignmentInBytesField();
  }
  virtual intptr_t AlignmentInBytesStack() const {
    return element_type_.AlignmentInBytesStack();
  }

#if !defined(DART_PRECOMPILED_RUNTIME)
  virtual bool ContainsOnlyFloats(Range range) const;
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

  virtual bool ContainsUnalignedMembers(intptr_t offset = 0) const;

  virtual bool Equals(const NativeType& other) const;

  virtual void PrintTo(BaseTextBuffer* f,
                       bool multi_line = false,
                       bool verbose = true) const;

  virtual intptr_t NumPrimitiveMembersRecursive() const;
  virtual const NativePrimitiveType& FirstPrimitiveMember() const;
  virtual intptr_t PrimitivePairMembers(const NativePrimitiveType** first,
                                        const NativePrimitiveType** second,
                                        intptr_t offset_in_members = 0) const;

 private:
  const NativeType& element_type_;
  const intptr_t length_;
};

using NativeTypes = ZoneGrowableArray<const NativeType*>;

// Compound native types: native arrays and native structs.
class NativeCompoundType : public NativeType {
 public:
  const NativeTypes& members() const { return members_; }

  virtual bool IsCompound() const { return true; }

  virtual intptr_t SizeInBytes() const { return size_; }
  virtual intptr_t AlignmentInBytesField() const { return alignment_field_; }
  virtual intptr_t AlignmentInBytesStack() const { return alignment_stack_; }

  virtual bool Equals(const NativeType& other) const;

  virtual void PrintTo(BaseTextBuffer* f,
                       bool multi_line = false,
                       bool verbose = true) const;

#if !defined(DART_PRECOMPILED_RUNTIME)
  virtual bool ContainsOnlyFloats(Range range) const = 0;

  // Returns how many word-sized chuncks _only_ contain floats.
  //
  // Useful for determining whether struct is passed in FP registers on x64.
  intptr_t NumberOfWordSizeChunksOnlyFloat() const;

  // Returns how many word-sized chunks do not _only_ contain floats.
  //
  // Useful for determining whether struct is passed in FP registers on x64.
  intptr_t NumberOfWordSizeChunksNotOnlyFloat() const;
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

  virtual bool ContainsUnalignedMembers(intptr_t offset = 0) const = 0;

  // Whether this type has only same-size floating point members.
  //
  // Useful for determining whether struct is passed in FP registers in hardfp
  // and arm64.
  bool ContainsHomogenuousFloats() const;

  virtual intptr_t NumPrimitiveMembersRecursive() const = 0;
  virtual const NativePrimitiveType& FirstPrimitiveMember() const;
  virtual intptr_t PrimitivePairMembers(const NativePrimitiveType** first,
                                        const NativePrimitiveType** second,
                                        intptr_t offset_in_members = 0) const;

 protected:
  NativeCompoundType(const NativeTypes& members,
                     intptr_t size,
                     intptr_t alignment_field,
                     intptr_t alignment_stack)
      : members_(members),
        size_(size),
        alignment_field_(alignment_field),
        alignment_stack_(alignment_stack) {}

  const NativeTypes& members_;
  const intptr_t size_;
  const intptr_t alignment_field_;
  const intptr_t alignment_stack_;

  virtual void PrintCompoundType(BaseTextBuffer* f) const = 0;
  virtual void PrintMemberOffset(BaseTextBuffer* f,
                                 intptr_t member_index) const {}
};

// Native structs.
class NativeStructType : public NativeCompoundType {
 public:
  static NativeStructType& FromNativeTypes(Zone* zone,
                                           const NativeTypes& members,
                                           intptr_t member_packing = kMaxInt32);

  const ZoneGrowableArray<intptr_t>& member_offsets() const {
    return member_offsets_;
  }

  virtual bool IsStruct() const { return true; }

#if !defined(DART_PRECOMPILED_RUNTIME)
  virtual bool ContainsOnlyFloats(Range range) const;
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

  virtual bool ContainsUnalignedMembers(intptr_t offset = 0) const;

  virtual intptr_t NumPrimitiveMembersRecursive() const;

 protected:
  virtual void PrintCompoundType(BaseTextBuffer* f) const;
  virtual void PrintMemberOffset(BaseTextBuffer* f,
                                 intptr_t member_index) const;

 private:
  NativeStructType(const NativeTypes& members,
                   const ZoneGrowableArray<intptr_t>& member_offsets,
                   intptr_t size,
                   intptr_t alignment_field,
                   intptr_t alignment_stack)
      : NativeCompoundType(members, size, alignment_field, alignment_stack),
        member_offsets_(member_offsets) {}

  const ZoneGrowableArray<intptr_t>& member_offsets_;
};

// Native unions.
class NativeUnionType : public NativeCompoundType {
 public:
  static NativeUnionType& FromNativeTypes(Zone* zone,
                                          const NativeTypes& members);

#if !defined(DART_PRECOMPILED_RUNTIME)
  virtual bool ContainsOnlyFloats(Range range) const;
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

  virtual bool ContainsUnalignedMembers(intptr_t offset = 0) const;

  virtual intptr_t NumPrimitiveMembersRecursive() const;

 protected:
  virtual void PrintCompoundType(BaseTextBuffer* f) const;

 private:
  NativeUnionType(const NativeTypes& members,
                  intptr_t size,
                  intptr_t alignment_field,
                  intptr_t alignment_stack)
      : NativeCompoundType(members, size, alignment_field, alignment_stack) {}
};

class NativeFunctionType : public ZoneAllocated {
 public:
  NativeFunctionType(const NativeTypes& argument_types,
                     const NativeType& return_type)
      : argument_types_(argument_types), return_type_(return_type) {}

#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(FFI_UNIT_TESTS)
  static const NativeFunctionType* FromUnboxedRepresentation(
      Zone* zone,
      intptr_t num_arguments,
      Representation representation);
#endif

  const NativeTypes& argument_types() const { return argument_types_; }
  const NativeType& return_type() const { return return_type_; }

  void PrintTo(BaseTextBuffer* f) const;
  const char* ToCString(Zone* zone) const;
#if !defined(FFI_UNIT_TESTS)
  const char* ToCString() const;
#endif

 private:
  const NativeTypes& argument_types_;
  const NativeType& return_type_;
};

}  // namespace ffi

}  // namespace compiler

}  // namespace dart

#endif  // RUNTIME_VM_COMPILER_FFI_NATIVE_TYPE_H_
