// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILER_C_SIGNATURE_H_
#define V8_COMPILER_C_SIGNATURE_H_

#include "src/codegen/machine-type.h"

namespace v8 {
namespace internal {
namespace compiler {

#define FOREACH_CTYPE_MACHINE_TYPE_MAPPING(V) \
  V(void, MachineType::None())                \
  V(bool, MachineType::Uint8())               \
  V(int8_t, MachineType::Int8())              \
  V(uint8_t, MachineType::Uint8())            \
  V(int16_t, MachineType::Int16())            \
  V(uint16_t, MachineType::Uint16())          \
  V(int32_t, MachineType::Int32())            \
  V(uint32_t, MachineType::Uint32())          \
  V(int64_t, MachineType::Int64())            \
  V(uint64_t, MachineType::Uint64())          \
  V(float, MachineType::Float32())            \
  V(double, MachineType::Float64())           \
  V(void*, MachineType::Pointer())            \
  V(int*, MachineType::Pointer())

template <typename T>
inline constexpr MachineType MachineTypeForC() {
  static_assert(std::is_convertible<T, Object>::value,
                "all non-specialized types must be convertible to Object");
  return MachineType::AnyTagged();
}

#define DECLARE_TEMPLATE_SPECIALIZATION(ctype, mtype)     \
  template <>                                             \
  inline MachineType constexpr MachineTypeForC<ctype>() { \
    return mtype;                                         \
  }
FOREACH_CTYPE_MACHINE_TYPE_MAPPING(DECLARE_TEMPLATE_SPECIALIZATION)
#undef DECLARE_TEMPLATE_SPECIALIZATION

// Helper for building machine signatures from C types.
class CSignature : public MachineSignature {
 protected:
  CSignature(size_t return_count, size_t parameter_count, MachineType* reps)
      : MachineSignature(return_count, parameter_count, reps) {}

 public:
  friend Zone;

  template <typename... Params>
  static void VerifyParams(MachineSignature* sig) {
    // Verifies the C signature against the machine types.
    std::array<MachineType, sizeof...(Params)> params{
        {MachineTypeForC<Params>()...}};
    for (size_t p = 0; p < params.size(); ++p) {
      CHECK_EQ(sig->GetParam(p), params[p]);
    }
  }

  static CSignature* FromMachine(Zone* zone, MachineSignature* msig) {
    return reinterpret_cast<CSignature*>(msig);
  }

  template <typename... ParamMachineTypes>
  static CSignature* New(Zone* zone, MachineType ret,
                         ParamMachineTypes... params) {
    constexpr size_t param_count = sizeof...(params);
    std::array<MachineType, param_count> param_arr{{params...}};
    const size_t buffer_size =
        param_count + (ret == MachineType::None() ? 0 : 1);
    MachineType* buffer = zone->NewArray<MachineType>(buffer_size);
    size_t pos = 0;
    size_t return_count = 0;
    if (ret != MachineType::None()) {
      buffer[pos++] = ret;
      return_count++;
    }
    for (MachineType p : param_arr) {
      // Check that there are no MachineType::None()'s in the parameters.
      CHECK_NE(MachineType::None(), p);
      buffer[pos++] = p;
    }
    DCHECK_EQ(buffer_size, pos);
    return zone->New<CSignature>(return_count, param_count, buffer);
  }
};

// Helper classes for instantiating Signature objects to be callable from C.
template <typename Ret, typename... Params>
class CSignatureOf : public CSignature {
 public:
  CSignatureOf() : CSignature(kReturnCount, kParamCount, storage_) {
    constexpr std::array<MachineType, kParamCount> param_types{
        MachineTypeForC<Params>()...};
    if (kReturnCount == 1) storage_[0] = MachineTypeForC<Ret>();
    static_assert(
        std::is_same<decltype(*reps_), decltype(*param_types.data())>::value,
        "type mismatch, cannot memcpy");
    memcpy(storage_ + kReturnCount, param_types.data(),
           sizeof(*storage_) * kParamCount);
  }

 private:
  static constexpr size_t kReturnCount =
      MachineTypeForC<Ret>() == MachineType::None() ? 0 : 1;
  static constexpr size_t kParamCount = sizeof...(Params);

  MachineType storage_[kReturnCount + kParamCount];
};

using CSignature_i_ii = CSignatureOf<int32_t, int32_t, int32_t>;
using CSignature_u_uu = CSignatureOf<uint32_t, uint32_t, uint32_t>;
using CSignature_f_ff = CSignatureOf<float, float, float>;
using CSignature_d_dd = CSignatureOf<double, double, double>;
using CSignature_o_oo = CSignatureOf<Object, Object, Object>;

}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_COMPILER_C_SIGNATURE_H_
