// Copyright 2019 The IREE Authors
//
// Licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef IREE_VM_MODULE_ABI_PACKING_H_
#define IREE_VM_MODULE_ABI_PACKING_H_

#include <memory>
#include <tuple>
#include <utility>
#include <vector>

#include "iree/base/api.h"
#include "iree/base/internal/span.h"
#include "iree/base/status_cc.h"
#include "iree/vm/builtin_types.h"
#include "iree/vm/module.h"
#include "iree/vm/ref.h"
#include "iree/vm/ref_cc.h"
#include "iree/vm/stack.h"

// std::string_view is available starting in C++17.
// Prior to that only IREE's C iree_string_view_t is available.
#if defined(__has_include)
#if __has_include(<string_view>) && __cplusplus >= 201703L
#define IREE_HAVE_STD_STRING_VIEW 1
#include <string_view>
#endif  // __has_include(<string_view>)
#endif  // __has_include

namespace iree {
namespace vm {
namespace packing {

namespace impl {

// Workaround required to ensure proper evaluation order of parameter packs.
// MSVC (and other compilers, like clang-cl in MSVC compat mode) may evaluate
// parameter pack function arguments in any order. This shim allows us to expand
// the parameter pack inside of an initializer list, which unlike function
// arguments must be evaluated by the compiler in the order the elements appear
// in the list.
//
// Example:
//  impl::order_sequence{(ExpandedAction(), 0)...};
//
// More information:
// https://stackoverflow.com/questions/29194858/order-of-function-calls-in-variadic-template-expansion
struct order_sequence {
  template <typename... T>
  order_sequence(T&&...) {}
};

// Coming in C++20, but not widely available yet.
template <class T>
struct remove_cvref {
  typedef std::remove_cv_t<std::remove_reference_t<T>> type;
};

}  // namespace impl

template <typename T>
using enable_if_primitive =
    typename std::enable_if<std::is_arithmetic<T>::value ||
                            std::is_enum<T>::value>::type;
template <typename T>
using enable_if_not_primitive = typename std::enable_if<!(
    std::is_arithmetic<T>::value || std::is_enum<T>::value)>::type;

//===----------------------------------------------------------------------===//
// Compile-time string literals
//===----------------------------------------------------------------------===//

// Compile-time constant string.
// This allows us to concat string literals and produce a single flattened
// char[] containing the results. Includes a \0 so the character storage is
// length N + 1 and can be accessed as a c_str.
//
// Use the `literal` helper function to define a const string literal without
// needing the size.
//
// Example:
//  // produces: const_string<2>("ab")
//  constexpr const auto str = literal("a") + literal("b");
template <size_t N>
class const_string {
 public:
  constexpr const_string(const char (&data)[N + 1])
      : const_string(data, std::make_index_sequence<N>()) {}
  template <size_t N1, typename std::enable_if<(N1 <= N), bool>::type = true>
  constexpr const_string(const const_string<N1>& lhs,
                         const const_string<N - N1>& rhs)
      : const_string{lhs, rhs, std::make_index_sequence<N1>{},
                     std::make_index_sequence<N - N1>{}} {}

  constexpr std::size_t size() const { return N; }
  constexpr const char* data() const { return data_; }
  constexpr const char* c_str() const { return data_; }
  constexpr operator const char*() const { return data_; }
  constexpr char operator[](size_t i) const { return data_[i]; }

 private:
  template <size_t... PACK>
  constexpr const_string(const char (&data)[N + 1],
                         std::index_sequence<PACK...>)
      : data_{data[PACK]..., '\0'} {}
  template <size_t N1, size_t... PACK1, size_t... PACK2>
  constexpr const_string(const const_string<N1>& lhs,
                         const const_string<N - N1>& rhs,
                         std::index_sequence<PACK1...>,
                         std::index_sequence<PACK2...>)
      : data_{lhs[PACK1]..., rhs[PACK2]..., '\0'} {}

  const char data_[N + 1];
};

template <size_t N1, size_t N2>
constexpr auto operator+(const const_string<N1>& lhs,
                         const const_string<N2>& rhs) {
  return const_string<N1 + N2>(lhs, rhs);
}

// Defines a compile-time constant string literal.
template <size_t N_PLUS_1>
constexpr auto literal(const char (&data)[N_PLUS_1]) {
  return const_string<N_PLUS_1 - 1>(data);
}

constexpr auto concat_impl() { return literal(""); }
template <typename T>
constexpr auto concat_impl(const T& lhs) {
  return lhs;
}
template <typename T, typename... Ts>
constexpr auto concat_impl(const T& lhs, const Ts&... s) {
  return lhs + concat_impl(s...);
}

// Concatenates one or more const_string values into a new const_string.
//
// Example:
//  constexpr const auto abc = concat_literals(literal("a"),
//                                             literal("b"),
//                                             literal("c"));
template <typename... Ts>
constexpr auto concat_literals(const Ts&... s) {
  return concat_impl(s...);
}

template <size_t C, typename T>
struct splat_impl {
  static constexpr auto apply(const T& v) {
    return concat_literals(v, splat_impl<C - 1, T>::apply(v));
  }
};
template <typename T>
struct splat_impl<1, T> {
  static constexpr auto apply(const T& v) { return v; }
};

// Splats a single const_string value C times.
//
// Example:
//  constexpr const auto aaa = splat_literal<3>(literal("a"));
template <size_t C, typename T>
constexpr auto splat_literal(const T& v) {
  return splat_impl<C, T>::apply(v);
}

//===----------------------------------------------------------------------===//
// Calling convention format generation
//===----------------------------------------------------------------------===//
// Prototyped here: https://godbolt.org/z/Tvhh7M

template <typename T>
struct cconv_map;

template <typename T>
struct cconv_map {
  static constexpr const auto conv_chars = literal("i");
};

template <>
struct cconv_map<int64_t> {
  static constexpr const auto conv_chars = literal("I");
};
template <>
struct cconv_map<uint64_t> {
  static constexpr const auto conv_chars = literal("I");
};

template <>
struct cconv_map<opaque_ref> {
  static constexpr const auto conv_chars = literal("r");
};
template <typename T>
struct cconv_map<ref<T>> {
  static constexpr const auto conv_chars = literal("r");
};
template <>
struct cconv_map<iree_string_view_t> {
  static constexpr const auto conv_chars = literal("r");
};
#if defined(IREE_HAVE_STD_STRING_VIEW)
template <>
struct cconv_map<std::string_view> {
  static constexpr const auto conv_chars = literal("r");
};
#endif  // IREE_HAVE_STD_STRING_VIEW

template <typename U, size_t S>
struct cconv_map<std::array<U, S>> {
  static constexpr const auto conv_chars = splat_literal<S>(
      cconv_map<typename impl::remove_cvref<U>::type>::conv_chars);
};

template <typename... Ts>
struct cconv_map<std::tuple<Ts...>> {
  static constexpr const auto conv_chars = concat_literals(
      cconv_map<typename impl::remove_cvref<Ts>::type>::conv_chars...);
};

template <typename U>
struct cconv_map<iree::span<U>> {
  static constexpr const auto conv_chars = concat_literals(
      literal("C"), cconv_map<typename impl::remove_cvref<U>::type>::conv_chars,
      literal("D"));
};

template <typename Result, size_t ParamsCount, typename... Params>
struct cconv_storage {
  static const iree_string_view_t value() {
    static constexpr const auto value = concat_literals(
        literal("0"),
        concat_literals(
            cconv_map<
                typename impl::remove_cvref<Params>::type>::conv_chars...),
        literal("_"),
        concat_literals(
            cconv_map<typename impl::remove_cvref<Result>::type>::conv_chars));
    static constexpr const auto str =
        iree_string_view_t{value.data(), value.size()};
    return str;
  }
};

template <typename Result>
struct cconv_storage<Result, 0> {
  static const iree_string_view_t value() {
    static constexpr const auto value = concat_literals(
        literal("0v_"),
        concat_literals(
            cconv_map<typename impl::remove_cvref<Result>::type>::conv_chars));
    static constexpr const auto str =
        iree_string_view_t{value.data(), value.size()};
    return str;
  }
};

template <size_t ParamsCount, typename... Params>
struct cconv_storage_void {
  static const iree_string_view_t value() {
    static constexpr const auto value = concat_literals(
        literal("0"),
        concat_literals(
            cconv_map<
                typename impl::remove_cvref<Params>::type>::conv_chars...),
        literal("_v"));
    static constexpr const auto str =
        iree_string_view_t{value.data(), value.size()};
    return str;
  }
};

template <>
struct cconv_storage_void<0> {
  static const iree_string_view_t value() {
    static constexpr const auto value = concat_literals(literal("0v_v"));
    static constexpr const auto str =
        iree_string_view_t{value.data(), value.size()};
    return str;
  }
};

//===----------------------------------------------------------------------===//
// Parameter unpacking
//===----------------------------------------------------------------------===//

// TODO(benvanik): see if we can't use `extern template` to share
// implementations of these and prevent code bloat across many modules.
// We can also try some non-templated base functions (like "UnpackI32") that the
// templated ones simply wrap with type casts.

namespace impl {

using params_ptr_t = uint8_t*;

template <typename T, typename EN = void>
struct ParamUnpack;
template <>
struct ParamUnpack<opaque_ref>;
template <typename T>
struct ParamUnpack<ref<T>>;
template <typename T>
struct ParamUnpack<const ref<T>>;
template <>
struct ParamUnpack<iree_string_view_t>;
#if defined(IREE_HAVE_STD_STRING_VIEW)
template <>
struct ParamUnpack<std::string_view>;
#endif  // IREE_HAVE_STD_STRING_VIEW
template <typename U, size_t S>
struct ParamUnpack<std::array<U, S>>;
template <typename... Ts>
struct ParamUnpack<std::tuple<Ts...>>;
template <typename U>
struct ParamUnpack<iree::span<U>, enable_if_not_primitive<U>>;
template <typename U>
struct ParamUnpack<iree::span<U>, enable_if_primitive<U>>;

struct Unpacker {
  template <typename... Ts>
  static StatusOr<std::tuple<typename impl::ParamUnpack<
      typename std::remove_reference<Ts>::type>::storage_type...>>
  LoadSequence(iree_byte_span_t storage) {
    auto params = std::make_tuple(
        typename impl::ParamUnpack<
            typename impl::remove_cvref<Ts>::type>::storage_type()...);
    Status status;
    params_ptr_t ptr = storage.data;
    ApplyLoad<Ts...>(status, ptr, params,
                     std::make_index_sequence<sizeof...(Ts)>());
    IREE_RETURN_IF_ERROR(std::move(status));
    params_ptr_t limit = storage.data + storage.data_length;
    if (IREE_UNLIKELY(ptr != limit)) {
      return iree_make_status(
          IREE_STATUS_INVALID_ARGUMENT,
          "argument buffer unpacking failure; consumed %zu of %zu bytes",
          (reinterpret_cast<intptr_t>(ptr) -
           reinterpret_cast<intptr_t>(storage.data)),
          storage.data_length);
    }
    return std::move(params);
  }

 private:
  template <typename... Ts, typename T, size_t... I>
  static void ApplyLoad(Status& status, params_ptr_t& ptr, T&& params,
                        std::index_sequence<I...>) {
    impl::order_sequence{
        (impl::ParamUnpack<typename impl::remove_cvref<
             typename std::tuple_element<I, std::tuple<Ts...>>::type>::type>::
             Load(status, ptr, std::get<I>(params)),
         0)...};
  }
};

// Common primitive types (`i32`, `i64`, `f32`, enums, etc).
template <typename T>
struct ParamUnpack<T, enable_if_primitive<T>> {
  using storage_type = T;
  static void Load(Status& status, params_ptr_t& ptr, storage_type& out_param) {
    out_param = *reinterpret_cast<const T*>(ptr);
    ptr += sizeof(T);
  }
};

// An opaque ref type (`vm.ref<?>`), possibly null.
template <>
struct ParamUnpack<opaque_ref> {
  using storage_type = opaque_ref;
  static void Load(Status& status, params_ptr_t& ptr, storage_type& out_param) {
    iree_vm_ref_retain(reinterpret_cast<iree_vm_ref_t*>(ptr), &out_param);
    ptr += sizeof(iree_vm_ref_t);
  }
};

// A `vm.ref<T>` type, possibly null.
// Ownership is transferred to the parameter.
template <typename T>
struct ParamUnpack<ref<T>> {
  using storage_type = ref<T>;
  static void Load(Status& status, params_ptr_t& ptr, storage_type& out_param) {
    auto* reg_ptr = reinterpret_cast<iree_vm_ref_t*>(ptr);
    ptr += sizeof(iree_vm_ref_t);
    if (reg_ptr->type == ref_type_descriptor<T>::get()->type) {
      out_param = vm::retain_ref(reinterpret_cast<T*>(reg_ptr->ptr));
      memset(reg_ptr, 0, sizeof(*reg_ptr));
    } else if (IREE_UNLIKELY(reg_ptr->type != IREE_VM_REF_TYPE_NULL)) {
      status =
          iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
                           "parameter contains a reference to the wrong type; "
                           "have %.*s but expected %.*s",
                           (int)iree_vm_ref_type_name(reg_ptr->type).size,
                           iree_vm_ref_type_name(reg_ptr->type).data,
                           (int)ref_type_descriptor<T>::get()->type_name.size,
                           ref_type_descriptor<T>::get()->type_name.data);
    } else {
      out_param = {};
    }
  }
};

// TODO(benvanik): merge with above somehow?
template <typename T>
struct ParamUnpack<const ref<T>> {
  using storage_type = ref<T>;
  static void Load(Status& status, params_ptr_t& ptr, storage_type& out_param) {
    auto* reg_ptr = reinterpret_cast<iree_vm_ref_t*>(ptr);
    ptr += sizeof(iree_vm_ref_t);
    if (reg_ptr->type == ref_type_descriptor<T>::get()->type) {
      out_param = vm::retain_ref(reinterpret_cast<T*>(reg_ptr->ptr));
      memset(reg_ptr, 0, sizeof(*reg_ptr));
    } else if (IREE_UNLIKELY(reg_ptr->type != IREE_VM_REF_TYPE_NULL)) {
      status =
          iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
                           "parameter contains a reference to the wrong type; "
                           "have %.*s but expected %.*s",
                           (int)iree_vm_ref_type_name(reg_ptr->type).size,
                           iree_vm_ref_type_name(reg_ptr->type).data,
                           (int)ref_type_descriptor<T>::get()->type_name.size,
                           ref_type_descriptor<T>::get()->type_name.data);
    } else {
      out_param = {};
    }
  }
};

// An `util.byte_buffer` containing a string.
// The string view is aliased directly into the underlying byte buffer.
template <>
struct ParamUnpack<iree_string_view_t> {
  using storage_type = iree_string_view_t;
  static void Load(Status& status, params_ptr_t& ptr, storage_type& out_param) {
    auto* reg_ptr = reinterpret_cast<iree_vm_ref_t*>(ptr);
    ptr += sizeof(iree_vm_ref_t);
    if (reg_ptr->type == ref_type_descriptor<iree_vm_buffer_t>::get()->type) {
      auto byte_span = reinterpret_cast<iree_vm_buffer_t*>(reg_ptr->ptr)->data;
      out_param = iree_make_string_view(
          reinterpret_cast<const char*>(byte_span.data), byte_span.data_length);
    } else if (IREE_UNLIKELY(reg_ptr->type != IREE_VM_REF_TYPE_NULL)) {
      status = iree_make_status(
          IREE_STATUS_INVALID_ARGUMENT,
          "parameter contains a reference to the wrong type; "
          "have %.*s but expected %.*s",
          (int)iree_vm_ref_type_name(reg_ptr->type).size,
          iree_vm_ref_type_name(reg_ptr->type).data,
          (int)ref_type_descriptor<iree_vm_buffer_t>::get()->type_name.size,
          ref_type_descriptor<iree_vm_buffer_t>::get()->type_name.data);
    } else {
      // NOTE: empty string is allowed here!
      out_param = iree_string_view_empty();
    }
  }
};
#if defined(IREE_HAVE_STD_STRING_VIEW)
template <>
struct ParamUnpack<std::string_view> {
  using storage_type = std::string_view;
  static void Load(Status& status, params_ptr_t& ptr, storage_type& out_param) {
    auto* reg_ptr = reinterpret_cast<iree_vm_ref_t*>(ptr);
    ptr += sizeof(iree_vm_ref_t);
    if (reg_ptr->type == ref_type_descriptor<iree_vm_buffer_t>::get()->type) {
      auto byte_span = reinterpret_cast<iree_vm_buffer_t*>(reg_ptr->ptr)->data;
      out_param = std::string_view{
          reinterpret_cast<const char*>(byte_span.data), byte_span.data_length};
    } else if (IREE_UNLIKELY(reg_ptr->type != IREE_VM_REF_TYPE_NULL)) {
      status = iree_make_status(
          IREE_STATUS_INVALID_ARGUMENT,
          "parameter contains a reference to the wrong type; "
          "have %.*s but expected %.*s",
          (int)iree_vm_ref_type_name(reg_ptr->type).size,
          iree_vm_ref_type_name(reg_ptr->type).data,
          (int)ref_type_descriptor<iree_vm_buffer_t>::get()->type_name.size,
          ref_type_descriptor<iree_vm_buffer_t>::get()->type_name.data);
    } else {
      // NOTE: empty string is allowed here!
      out_param = {};
    }
  }
};
#endif  // IREE_HAVE_STD_STRING_VIEW

// Arrays are C++ ABI only representing a fixed repeated field (`i32, i32`).
template <typename U, size_t S>
struct ParamUnpack<std::array<U, S>> {
  using element_type = typename impl::remove_cvref<U>::type;
  using storage_type = std::array<element_type, S>;
  static void Load(Status& status, params_ptr_t& ptr, storage_type& out_param) {
    for (size_t i = 0; i < S; ++i) {
      ParamUnpack::Load(status, ptr, out_param[i]);
    }
  }
};

// Tuples (`tuple<i32, i64>`) expand to just their flattened contents.
template <typename... Ts>
struct ParamUnpack<std::tuple<Ts...>> {
  using storage_type = std::tuple<typename impl::remove_cvref<Ts>::type...>;
  static void Load(Status& status, params_ptr_t& ptr, storage_type& out_param) {
    UnpackTuple(status, ptr, out_param,
                std::make_index_sequence<sizeof...(Ts)>());
  }
  template <size_t... I>
  static void UnpackTuple(Status& status, params_ptr_t& ptr,
                          storage_type& params, std::index_sequence<I...>) {
    impl::order_sequence{
        (ParamUnpack<typename std::tuple_element<I, std::tuple<Ts...>>::type>::
             Load(status, ptr, std::get<I>(params)),
         0)...};
  }
};

// Complex variadic span (like `tuple<i32, tuple<ref<...>, i64>>...`).
// We need to allocate storage here so that we can marshal the element type out.
// In the future we could check that all subelements are primitives and alias if
// the host machine endianness is the same.
template <typename U>
struct ParamUnpack<iree::span<U>, enable_if_not_primitive<U>> {
  using element_type = typename impl::remove_cvref<U>::type;
  using storage_type = std::vector<element_type>;
  static void Load(Status& status, params_ptr_t& ptr, storage_type& out_param) {
    iree_host_size_t count = *reinterpret_cast<const int32_t*>(ptr);
    ptr += sizeof(int32_t);
    out_param.resize(count);
    for (iree_host_size_t i = 0; i < count; ++i) {
      ParamUnpack<element_type>::Load(status, ptr, out_param[i]);
    }
  }
};

// Simple primitive variadic span (like `i32...`). We can alias directly into
// the argument buffer so long as endianness matches.
template <typename U>
struct ParamUnpack<iree::span<U>, enable_if_primitive<U>> {
  using element_type = U;
  using storage_type = iree::span<const element_type>;
  static void Load(Status& status, params_ptr_t& ptr, storage_type& out_param) {
    iree_host_size_t count = *reinterpret_cast<const int32_t*>(ptr);
    ptr += sizeof(int32_t);
    out_param =
        iree::span<U>(reinterpret_cast<const element_type*>(ptr), count);
    ptr += sizeof(element_type) * count;
  }
};

}  // namespace impl

//===----------------------------------------------------------------------===//
// Result packing
//===----------------------------------------------------------------------===//

namespace impl {

using result_ptr_t = uint8_t*;

template <typename T>
struct ResultPack {
  static void Store(result_ptr_t& ptr, T value) {
    *reinterpret_cast<T*>(ptr) = value;
    ptr += sizeof(T);
  }
};

template <>
struct ResultPack<opaque_ref> {
  static void Store(result_ptr_t& ptr, opaque_ref value) {
    iree_vm_ref_move(value.get(), reinterpret_cast<iree_vm_ref_t*>(ptr));
    ptr += sizeof(iree_vm_ref_t);
  }
};

template <typename T>
struct ResultPack<ref<T>> {
  static void Store(result_ptr_t& ptr, ref<T> value) {
    iree_vm_ref_wrap_assign(value.release(), value.type(),
                            reinterpret_cast<iree_vm_ref_t*>(ptr));
    ptr += sizeof(iree_vm_ref_t);
  }
};

template <typename U, size_t S>
struct ResultPack<std::array<U, S>>;
template <typename... Ts>
struct ResultPack<std::tuple<Ts...>>;

template <typename U, size_t S>
struct ResultPack<std::array<U, S>> {
  static void Store(result_ptr_t& ptr, std::array<U, S> value) {
    for (size_t i = 0; i < S; ++i) {
      ResultPack<U>::Store(ptr, std::move(value[i]));
    }
  }
};

template <typename... Ts>
struct ResultPack<std::tuple<Ts...>> {
  static void Store(result_ptr_t& ptr, std::tuple<Ts...> results) {
    PackTuple(ptr, results, std::make_index_sequence<sizeof...(Ts)>());
  }
  template <typename... T, size_t... I>
  static inline void PackTuple(result_ptr_t& ptr, std::tuple<T...>& value,
                               std::index_sequence<I...>) {
    impl::order_sequence{
        (ResultPack<typename std::tuple_element<I, std::tuple<T...>>::type>::
             Store(ptr, std::move(std::get<I>(value))),
         0)...};
  }
};

}  // namespace impl

//===----------------------------------------------------------------------===//
// Function wrapping
//===----------------------------------------------------------------------===//

template <typename Owner, typename Results, typename... Params>
struct DispatchFunctor {
  using FnPtr = StatusOr<Results> (Owner::*)(Params...);

  static Status Call(void (Owner::*ptr)(), Owner* self, iree_vm_stack_t* stack,
                     const iree_vm_function_call_t* call,
                     iree_vm_execution_result_t* out_result) {
    // Marshal arguments into types/locals we can forward to the function.
    IREE_ASSIGN_OR_RETURN(
        auto params, impl::Unpacker::LoadSequence<Params...>(call->arguments));

    // Call the target function with the params.
    IREE_ASSIGN_OR_RETURN(
        auto results,
        ApplyFn(reinterpret_cast<FnPtr>(ptr), self, std::move(params),
                std::make_index_sequence<sizeof...(Params)>()));

    // Marshal call results back into the ABI results buffer.
    impl::result_ptr_t result_ptr = call->results.data;
    impl::ResultPack<Results>::Store(result_ptr, std::move(results));

    return OkStatus();
  }

  template <typename T, size_t... I>
  static StatusOr<Results> ApplyFn(FnPtr ptr, Owner* self, T&& params,
                                   std::index_sequence<I...>) {
    return (self->*ptr)(std::move(std::get<I>(params))...);
  }
};

// A DispatchFunctor specialization for methods with no return values.
template <typename Owner, typename... Params>
struct DispatchFunctorVoid {
  using FnPtr = Status (Owner::*)(Params...);

  static Status Call(void (Owner::*ptr)(), Owner* self, iree_vm_stack_t* stack,
                     const iree_vm_function_call_t* call,
                     iree_vm_execution_result_t* out_result) {
    IREE_ASSIGN_OR_RETURN(
        auto params, impl::Unpacker::LoadSequence<Params...>(call->arguments));
    return ApplyFn(reinterpret_cast<FnPtr>(ptr), self, std::move(params),
                   std::make_index_sequence<sizeof...(Params)>());
  }

  template <typename T, size_t... I>
  static Status ApplyFn(FnPtr ptr, Owner* self, T&& params,
                        std::index_sequence<I...>) {
    return (self->*ptr)(std::move(std::get<I>(params))...);
  }
};

}  // namespace packing

template <typename Owner>
struct NativeFunction {
  iree_string_view_t name;
  iree_string_view_t cconv;
  void (Owner::*const ptr)();
  Status (*const call)(void (Owner::*ptr)(), Owner* self,
                       iree_vm_stack_t* stack,
                       const iree_vm_function_call_t* call,
                       iree_vm_execution_result_t* out_result);
};

template <typename Owner, typename Result, typename... Params>
constexpr NativeFunction<Owner> MakeNativeFunction(
    const char* name, StatusOr<Result> (Owner::*fn)(Params...)) {
  using dispatch_functor_t = packing::DispatchFunctor<Owner, Result, Params...>;
  return {iree_make_cstring_view(name),
          packing::cconv_storage<Result, sizeof...(Params), Params...>::value(),
          (void (Owner::*)())fn, &dispatch_functor_t::Call};
}

template <typename Owner, typename... Params>
constexpr NativeFunction<Owner> MakeNativeFunction(
    const char* name, Status (Owner::*fn)(Params...)) {
  using dispatch_functor_t = packing::DispatchFunctorVoid<Owner, Params...>;
  return {iree_make_cstring_view(name),
          packing::cconv_storage_void<sizeof...(Params), Params...>::value(),
          (void (Owner::*)())fn, &dispatch_functor_t::Call};
}

}  // namespace vm
}  // namespace iree

#endif  // IREE_VM_MODULE_ABI_PACKING_H_
