//===--- MetadataValues.h - Compiler/runtime ABI Metadata -------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This header is shared between the runtime and the compiler and
// includes target-independent information which can be usefully shared
// between them.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_ABI_METADATAVALUES_H
#define SWIFT_ABI_METADATAVALUES_H

#include "swift/AST/Ownership.h"
#include "swift/Runtime/Unreachable.h"

#include <stdlib.h>
#include <stdint.h>

namespace swift {

struct InProcess;
template <typename Runtime> struct TargetMetadata;
using Metadata = TargetMetadata<InProcess>;

/// Kinds of Swift metadata records.  Some of these are types, some
/// aren't.
enum class MetadataKind : uint32_t {
#define METADATAKIND(name, value) name = value,
#define ABSTRACTMETADATAKIND(name, start, end)                                 \
  name##_Start = start, name##_End = end,
#include "MetadataKind.def"
};

const unsigned LastEnumeratedMetadataKind = 2047;

/// Try to translate the 'isa' value of a type/heap metadata into a value
/// of the MetadataKind enum.
inline MetadataKind getEnumeratedMetadataKind(uint64_t kind) {
  if (kind > LastEnumeratedMetadataKind)
    return MetadataKind::Class;
  return MetadataKind(kind);
}

/// Kinds of Swift nominal type descriptor records.
enum class NominalTypeKind : uint32_t {
#define NOMINALTYPEMETADATAKIND(name, value) name = value,
#include "MetadataKind.def"
};

/// Flags for dynamic-cast operations.
enum class DynamicCastFlags : size_t {
  /// All flags clear.
  Default = 0x0,

  /// True if the cast is not permitted to fail.
  Unconditional = 0x1,

  /// True if the cast should 'take' the source value on success;
  /// false if the value should be copied.
  TakeOnSuccess = 0x2,

  /// True if the cast should destroy the source value on failure;
  /// false if the value should be left in place.
  DestroyOnFailure = 0x4,
};
inline bool operator&(DynamicCastFlags a, DynamicCastFlags b) {
  return (size_t(a) & size_t(b)) != 0;
}
inline DynamicCastFlags operator|(DynamicCastFlags a, DynamicCastFlags b) {
  return DynamicCastFlags(size_t(a) | size_t(b));
}
inline DynamicCastFlags operator-(DynamicCastFlags a, DynamicCastFlags b) {
  return DynamicCastFlags(size_t(a) & ~size_t(b));
}
inline DynamicCastFlags &operator|=(DynamicCastFlags &a, DynamicCastFlags b) {
  return a = (a | b);
}

/// Swift class flags.
enum class ClassFlags : uint32_t {
  /// Is this a Swift 1 class?
  IsSwift1 = 0x1,

  /// Does this class use Swift 1.0 refcounting?
  UsesSwift1Refcounting = 0x2,

  /// Has this class a custom name, specified with the @objc attribute?
  HasCustomObjCName = 0x4
};
inline bool operator&(ClassFlags a, ClassFlags b) {
  return (uint32_t(a) & uint32_t(b)) != 0;
}
inline ClassFlags operator|(ClassFlags a, ClassFlags b) {
  return ClassFlags(uint32_t(a) | uint32_t(b));
}
inline ClassFlags &operator|=(ClassFlags &a, ClassFlags b) {
  return a = (a | b);
}

/// Flags that go in a MethodDescriptor structure.
class MethodDescriptorFlags {
public:
  typedef uint32_t int_type;
  enum class Kind {
    Method,
    Init,
    Getter,
    Setter,
    MaterializeForSet,
  };

private:
  enum : int_type {
    KindMask = 0x0F,                // 16 kinds should be enough for anybody
    IsInstanceMask = 0x10,
    IsDynamicMask = 0x20,
  };

  int_type Value;

public:
  MethodDescriptorFlags(Kind kind) : Value(unsigned(kind)) {}

  MethodDescriptorFlags withIsInstance(bool isInstance) const {
    auto copy = *this;
    if (isInstance) {
      copy.Value |= IsInstanceMask;
    } else {
      copy.Value &= ~IsInstanceMask;
    }
    return copy;
  }

  MethodDescriptorFlags withIsDynamic(bool isDynamic) const {
    auto copy = *this;
    if (isDynamic)
      copy.Value |= IsDynamicMask;
    else
      copy.Value &= ~IsDynamicMask;
    return copy;
  }

  Kind getKind() const { return Kind(Value & KindMask); }

  /// Is the method marked 'dynamic'?
  bool isDynamic() const { return Value & IsDynamicMask; }

  /// Is the method an instance member?
  ///
  /// Note that 'init' is not considered an instance member.
  bool isInstance() const { return Value & IsInstanceMask; }

  int_type getIntValue() const { return Value; }
};

enum : unsigned {
  /// Number of words reserved in generic metadata patterns.
  NumGenericMetadataPrivateDataWords = 16,
};
  
/// Kinds of type metadata/protocol conformance records.
enum class TypeMetadataRecordKind : unsigned {
  /// The conformance is universal and might apply to any type.
  /// getDirectType() is nil.
  Universal,

  /// The conformance is for a nongeneric native struct or enum type.
  /// getDirectType() points to the canonical metadata for the type.
  UniqueDirectType,
  
  /// The conformance is for a nongeneric foreign struct or enum type.
  /// getDirectType() points to a nonunique metadata record for the type, which
  /// needs to be uniqued by the runtime.
  NonuniqueDirectType,
  
  /// The conformance is for a nongeneric class type.
  /// getIndirectClass() points to a variable that contains the pointer to the
  /// class object, which may be ObjC and thus require a runtime call to get
  /// metadata.
  ///
  /// On platforms without ObjC interop, this indirection isn't necessary,
  /// and classes could be emitted as UniqueDirectType.
  UniqueIndirectClass,
  
  /// The conformance is for a generic or resilient type.
  /// getNominalTypeDescriptor() points to the nominal type descriptor shared
  /// by all metadata instantiations of this type.
  UniqueNominalTypeDescriptor,
  
  /// The conformance is for a nongeneric class type.
  /// getDirectType() points to the unique class object.
  ///
  /// FIXME: This shouldn't exist. On ObjC interop platforms, class references
  /// must be indirected (using UniqueIndirectClass). On non-ObjC interop
  /// platforms, the class object always is the type metadata.
  UniqueDirectClass = 0xF,
};

/// Kinds of reference to protocol conformance.
enum class ProtocolConformanceReferenceKind : unsigned {
  /// A direct reference to a protocol witness table.
  WitnessTable,
  /// A function pointer that can be called to access the protocol witness
  /// table.
  WitnessTableAccessor,
};

// Type metadata record discriminant
struct TypeMetadataRecordFlags {
protected:
  using int_type = unsigned;
  int_type Data;
  
  enum : int_type {
    TypeKindMask = 0x0000000FU,
    TypeKindShift = 0,
  };
  
public:
  constexpr TypeMetadataRecordFlags() : Data(0) {}
  constexpr TypeMetadataRecordFlags(int_type Data) : Data(Data) {}
  
  constexpr TypeMetadataRecordKind getTypeKind() const {
    return TypeMetadataRecordKind((Data & TypeKindMask) >> TypeKindShift);
  }
  constexpr TypeMetadataRecordFlags withTypeKind(
                                        TypeMetadataRecordKind ptk) const {
    return TypeMetadataRecordFlags(
                     (Data & ~TypeKindMask) | (int_type(ptk) << TypeKindShift));
  }
  
  int_type getValue() const { return Data; }
};

// Protocol conformance discriminant
struct ProtocolConformanceFlags : public TypeMetadataRecordFlags {
private:
  enum : int_type {
    ConformanceKindMask = 0x00000010U,
    ConformanceKindShift = 4,
  };

public:
  constexpr ProtocolConformanceFlags() : TypeMetadataRecordFlags(0) {}
  constexpr ProtocolConformanceFlags(int_type Data) : TypeMetadataRecordFlags(Data) {}

  constexpr ProtocolConformanceFlags withTypeKind(
                                        TypeMetadataRecordKind ptk) const {
    return ProtocolConformanceFlags(
                     (Data & ~TypeKindMask) | (int_type(ptk) << TypeKindShift));
  }
  constexpr ProtocolConformanceReferenceKind getConformanceKind() const {
    return ProtocolConformanceReferenceKind((Data & ConformanceKindMask)
                                     >> ConformanceKindShift);
  }
  constexpr ProtocolConformanceFlags withConformanceKind(
                                  ProtocolConformanceReferenceKind pck) const {
    return ProtocolConformanceFlags(
       (Data & ~ConformanceKindMask) | (int_type(pck) << ConformanceKindShift));
  }
};

/// Flag that indicates whether an existential type is class-constrained or not.
enum class ProtocolClassConstraint : bool {
  /// The protocol is class-constrained, so only class types can conform to it.
  ///
  /// This must be 0 for ABI compatibility with Objective-C protocol_t records.
  Class = false,
  /// Any type can conform to the protocol.
  Any = true,
};

/// Identifiers for protocols with special meaning to the Swift runtime.
enum class SpecialProtocol: uint8_t {
  /// Not a special protocol.
  ///
  /// This must be 0 for ABI compatibility with Objective-C protocol_t records.
  None = 0,
  /// The Error protocol.
  Error = 1,
};

/// Identifiers for protocol method dispatch strategies.
enum class ProtocolDispatchStrategy: uint8_t {
  /// Uses ObjC method dispatch.
  ///
  /// This must be 0 for ABI compatibility with Objective-C protocol_t records.
  ObjC = 0,
  
  /// Uses Swift protocol witness table dispatch.
  ///
  /// To invoke methods of this protocol, a pointer to a protocol witness table
  /// corresponding to the protocol conformance must be available.
  Swift = 1,
};

/// Flags in a generic nominal type descriptor.
class GenericParameterDescriptorFlags {
  typedef uint32_t int_type;
  enum : int_type {
    HasParent        = 0x01,
    HasGenericParent = 0x02,
    HasVTable        = 0x04,
  };
  int_type Data;
  
  constexpr GenericParameterDescriptorFlags(int_type data) : Data(data) {}
public:
  constexpr GenericParameterDescriptorFlags() : Data(0) {}

  constexpr GenericParameterDescriptorFlags withHasParent(bool b) const {
    return GenericParameterDescriptorFlags(b ? (Data | HasParent)
                                             : (Data & ~HasParent));
  }

  constexpr GenericParameterDescriptorFlags withHasGenericParent(bool b) const {
    return GenericParameterDescriptorFlags(b ? (Data | HasGenericParent)
                                             : (Data & ~HasGenericParent));
  }

  constexpr GenericParameterDescriptorFlags withHasVTable(bool b) const {
    return GenericParameterDescriptorFlags(b ? (Data | HasVTable)
                                             : (Data & ~HasVTable));
  }

  /// Does this type have a lexical parent type?
  ///
  /// For class metadata, if this is true, the storage for the parent type
  /// appears immediately prior to the first generic argument.  Other
  /// metadata always have a slot for their parent type.
  bool hasParent() const {
    return Data & HasParent;
  }

  /// Given that this type has a parent type, is that type generic?  If so,
  /// it forms part of the key distinguishing this metadata from other
  /// metadata, and the parent metadata will be the first argument to
  /// the generic metadata access function.
  bool hasGenericParent() const {
    return Data & HasGenericParent;
  }

  /// If this type is a class, does it have a vtable?  If so, the number
  /// of vtable entries immediately follows the generic requirement
  /// descriptor.
  bool hasVTable() const {
    return Data & HasVTable;
  }

  int_type getIntValue() const {
    return Data;
  }
  
  static GenericParameterDescriptorFlags fromIntValue(int_type Data) {
    return GenericParameterDescriptorFlags(Data);
  }
  
  bool operator==(GenericParameterDescriptorFlags other) const {
    return Data == other.Data;
  }
  bool operator!=(GenericParameterDescriptorFlags other) const {
    return Data != other.Data;
  }
};


/// Flags for protocol descriptors.
class ProtocolDescriptorFlags {
  typedef uint32_t int_type;
  enum : int_type {
    IsSwift           =   1U <<  0U,
    ClassConstraint   =   1U <<  1U,

    DispatchStrategyMask  = 0xFU << 2U,
    DispatchStrategyShift = 2,

    SpecialProtocolMask  = 0x000003C0U,
    SpecialProtocolShift = 6,

    IsResilient       =   1U <<  10U,

    /// Reserved by the ObjC runtime.
    _ObjCReserved        = 0xFFFF0000U,
  };

  int_type Data;
  
  constexpr ProtocolDescriptorFlags(int_type Data) : Data(Data) {}
public:
  constexpr ProtocolDescriptorFlags() : Data(0) {}
  constexpr ProtocolDescriptorFlags withSwift(bool s) const {
    return ProtocolDescriptorFlags((Data & ~IsSwift) | (s ? IsSwift : 0));
  }
  constexpr ProtocolDescriptorFlags withClassConstraint(
                                              ProtocolClassConstraint c) const {
    return ProtocolDescriptorFlags((Data & ~ClassConstraint)
                                     | (bool(c) ? ClassConstraint : 0));
  }
  constexpr ProtocolDescriptorFlags withDispatchStrategy(
                                             ProtocolDispatchStrategy s) const {
    return ProtocolDescriptorFlags((Data & ~DispatchStrategyMask)
                                     | (int_type(s) << DispatchStrategyShift));
  }
  constexpr ProtocolDescriptorFlags
  withSpecialProtocol(SpecialProtocol sp) const {
    return ProtocolDescriptorFlags((Data & ~SpecialProtocolMask)
                                     | (int_type(sp) << SpecialProtocolShift));
  }
  constexpr ProtocolDescriptorFlags withResilient(bool s) const {
    return ProtocolDescriptorFlags((Data & ~IsResilient) | (s ? IsResilient : 0));
  }
  
  /// Was the protocol defined in Swift 1 or 2?
  bool isSwift() const { return Data & IsSwift; }

  /// Is the protocol class-constrained?
  ProtocolClassConstraint getClassConstraint() const {
    return ProtocolClassConstraint(bool(Data & ClassConstraint));
  }
  
  /// What dispatch strategy does this protocol use?
  ProtocolDispatchStrategy getDispatchStrategy() const {
    return ProtocolDispatchStrategy((Data & DispatchStrategyMask)
                                      >> DispatchStrategyShift);
  }
  
  /// Does the protocol require a witness table for method dispatch?
  bool needsWitnessTable() const {
    return needsWitnessTable(getDispatchStrategy());
  }
  
  static bool needsWitnessTable(ProtocolDispatchStrategy strategy) {
    switch (strategy) {
    case ProtocolDispatchStrategy::ObjC:
      return false;
    case ProtocolDispatchStrategy::Swift:
      return true;
    }

    swift_runtime_unreachable("Unhandled ProtocolDispatchStrategy in switch.");
  }
  
  /// Return the identifier if this is a special runtime-known protocol.
  SpecialProtocol getSpecialProtocol() const {
    return SpecialProtocol(uint8_t((Data & SpecialProtocolMask)
                                 >> SpecialProtocolShift));
  }
  
  /// Can new requirements with default witnesses be added resiliently?
  bool isResilient() const { return Data & IsResilient; }

  int_type getIntValue() const {
    return Data;
  }
};

/// Flags that go in a ProtocolRequirement structure.
class ProtocolRequirementFlags {
public:
  typedef uint32_t int_type;
  enum class Kind {
    BaseProtocol,
    Method,
    Init,
    Getter,
    Setter,
    MaterializeForSet,
    AssociatedTypeAccessFunction,
    AssociatedConformanceAccessFunction,
  };

private:
  enum : int_type {
    KindMask = 0x0F,                // 16 kinds should be enough for anybody
    IsInstanceMask = 0x10,
  };

  int_type Value;

public:
  ProtocolRequirementFlags(Kind kind) : Value(unsigned(kind)) {}

  ProtocolRequirementFlags withIsInstance(bool isInstance) const {
    auto copy = *this;
    if (isInstance) {
      copy.Value |= IsInstanceMask;
    } else {
      copy.Value &= ~IsInstanceMask;
    }
    return copy;
  }

  Kind getKind() const { return Kind(Value & KindMask); }

  /// Is the method an instance member?
  ///
  /// Note that 'init' is not considered an instance member.
  bool isInstance() const { return Value & IsInstanceMask; }

  int_type getIntValue() const { return Value; }
};

/// Flags in an existential type metadata record.
class ExistentialTypeFlags {
  typedef size_t int_type;
  enum : int_type {
    NumWitnessTablesMask  = 0x00FFFFFFU,
    ClassConstraintMask   = 0x80000000U,
    HasSuperclassMask     = 0x40000000U,
    SpecialProtocolMask   = 0x3F000000U,
    SpecialProtocolShift  = 24U,
  };
  int_type Data;

public:
  constexpr ExistentialTypeFlags(int_type Data) : Data(Data) {}
  constexpr ExistentialTypeFlags() : Data(0) {}
  constexpr ExistentialTypeFlags withNumWitnessTables(unsigned numTables) const {
    return ExistentialTypeFlags((Data & ~NumWitnessTablesMask) | numTables);
  }
  constexpr ExistentialTypeFlags
  withClassConstraint(ProtocolClassConstraint c) const {
    return ExistentialTypeFlags((Data & ~ClassConstraintMask)
                                  | (bool(c) ? ClassConstraintMask : 0));
  }
  constexpr ExistentialTypeFlags
  withHasSuperclass(bool hasSuperclass) const {
    return ExistentialTypeFlags((Data & ~HasSuperclassMask)
                                  | (hasSuperclass ? HasSuperclassMask : 0));
  }
  constexpr ExistentialTypeFlags
  withSpecialProtocol(SpecialProtocol sp) const {
    return ExistentialTypeFlags((Data & ~SpecialProtocolMask)
                                  | (int_type(sp) << SpecialProtocolShift));
  }
  
  unsigned getNumWitnessTables() const {
    return Data & NumWitnessTablesMask;
  }
  
  ProtocolClassConstraint getClassConstraint() const {
    return ProtocolClassConstraint(bool(Data & ClassConstraintMask));
  }

  bool hasSuperclassConstraint() const {
    return bool(Data & HasSuperclassMask);
  }

  /// Return whether this existential type represents an uncomposed special
  /// protocol.
  SpecialProtocol getSpecialProtocol() const {
    return SpecialProtocol(uint8_t((Data & SpecialProtocolMask)
                                     >> SpecialProtocolShift));
  }
  
  int_type getIntValue() const {
    return Data;
  }
};

/// Convention values for function type metadata.
enum class FunctionMetadataConvention: uint8_t {
  Swift = 0,
  Block = 1,
  Thin = 2,
  CFunctionPointer = 3,
};

/// Flags in a function type metadata record.
template <typename int_type>
class TargetFunctionTypeFlags {
  enum : int_type {
    NumArgumentsMask = 0x00FFFFFFU,
    ConventionMask   = 0x0F000000U,
    ConventionShift  = 24U,
    ThrowsMask       = 0x10000000U,
  };
  int_type Data;
  
  constexpr TargetFunctionTypeFlags(int_type Data) : Data(Data) {}
public:
  constexpr TargetFunctionTypeFlags() : Data(0) {}

  constexpr TargetFunctionTypeFlags withNumArguments(unsigned numArguments) const {
    return TargetFunctionTypeFlags((Data & ~NumArgumentsMask) | numArguments);
  }
  
  constexpr TargetFunctionTypeFlags<int_type>
  withConvention(FunctionMetadataConvention c) const {
    return TargetFunctionTypeFlags((Data & ~ConventionMask)
                             | (int_type(c) << ConventionShift));
  }
  
  constexpr TargetFunctionTypeFlags<int_type>
  withThrows(bool throws) const {
    return TargetFunctionTypeFlags<int_type>((Data & ~ThrowsMask) |
                                             (throws ? ThrowsMask : 0));
  }
  
  unsigned getNumArguments() const {
    return Data & NumArgumentsMask;
  }
  
  FunctionMetadataConvention getConvention() const {
    return FunctionMetadataConvention((Data&ConventionMask) >> ConventionShift);
  }
  
  bool throws() const {
    return bool(Data & ThrowsMask);
  }
  
  int_type getIntValue() const {
    return Data;
  }
  
  static TargetFunctionTypeFlags<int_type> fromIntValue(int_type Data) {
    return TargetFunctionTypeFlags(Data);
  }
  
  bool operator==(TargetFunctionTypeFlags<int_type> other) const {
    return Data == other.Data;
  }
  bool operator!=(TargetFunctionTypeFlags<int_type> other) const {
    return Data != other.Data;
  }
};
using FunctionTypeFlags = TargetFunctionTypeFlags<size_t>;

/// Field types and flags as represented in a nominal type's field/case type
/// vector.
class FieldType {
  typedef uintptr_t int_type;
  // Type metadata is always at least pointer-aligned, so we get at least two
  // low bits to stash flags. We could use three low bits on 64-bit, and maybe
  // some high bits as well.
  enum : int_type {
    Indirect = 1,
    Weak = 2,

    TypeMask = ((uintptr_t)-1) & ~(alignof(void*) - 1),
  };
  int_type Data;

  constexpr FieldType(int_type Data) : Data(Data) {}
public:
  constexpr FieldType() : Data(0) {}
  FieldType withType(const Metadata *T) const {
    return FieldType((Data & ~TypeMask) | (uintptr_t)T);
  }

  constexpr FieldType withIndirect(bool indirect) const {
    return FieldType((Data & ~Indirect)
                     | (indirect ? Indirect : 0));
  }

  constexpr FieldType withWeak(bool weak) const {
    return FieldType((Data & ~Weak)
                     | (weak ? Weak : 0));
  }

  bool isIndirect() const {
    return bool(Data & Indirect);
  }

  bool isWeak() const {
    return bool(Data & Weak);
  }

  const Metadata *getType() const {
    return (const Metadata *)(Data & TypeMask);
  }

  int_type getIntValue() const {
    return Data;
  }
};

/// Flags for exclusivity-checking operations.
enum class ExclusivityFlags : uintptr_t {
  Read             = 0x0,
  Modify           = 0x1,
  // Leave space for other actions.
  // Don't rely on ActionMask in stable ABI.
  ActionMask       = 0x1,

  // Downgrade exclusivity failures to a warning.
  WarningOnly      = 0x10
};
static inline ExclusivityFlags operator|(ExclusivityFlags lhs,
                                         ExclusivityFlags rhs) {
  return ExclusivityFlags(uintptr_t(lhs) | uintptr_t(rhs));
}
static inline ExclusivityFlags &operator|=(ExclusivityFlags &lhs,
                                           ExclusivityFlags rhs) {
  return (lhs = (lhs | rhs));
}
static inline ExclusivityFlags getAccessAction(ExclusivityFlags flags) {
  return ExclusivityFlags(uintptr_t(flags)
                        & uintptr_t(ExclusivityFlags::ActionMask));
}
static inline bool isWarningOnly(ExclusivityFlags flags) {
  return uintptr_t(flags) & uintptr_t(ExclusivityFlags::WarningOnly);
}

} // end namespace swift

#endif /* SWIFT_ABI_METADATAVALUES_H */
