@@ -1145,6 +1145,31 @@ struct PackedFuncValueConverter {
11451145 } \
11461146 }
11471147
1148+ #define TVM_MODULE_VTABLE_BEGIN (TypeKey ) \
1149+ const char * type_key () const final { return TypeKey; } \
1150+ PackedFunc GetFunction (const String& _name, const ObjectPtr<Object>& _self) final { \
1151+ using SelfPtr = std::remove_cv_t <decltype (this )>;
1152+ #define TVM_MODULE_VTABLE_END () \
1153+ return PackedFunc (nullptr ); \
1154+ }
1155+ #define TVM_MODULE_VTABLE_ENTRY (Name, MemFunc ) \
1156+ if (_name == Name) { \
1157+ return PackedFunc ([_self](TVMArgs args, TVMRetValue* rv) -> void { \
1158+ using Helper = ::tvm::runtime::detail::ModuleVTableEntryHelper<decltype (MemFunc)>; \
1159+ SelfPtr self = static_cast <SelfPtr>(_self.get ()); \
1160+ CHECK_EQ (args.size (), Helper::LenArgs) \
1161+ << " Function `" << self->type_key () << " ::" << Name << " ` requires " << Helper::LenArgs \
1162+ << " arguments, but got " << args.size (); \
1163+ Helper::Call (rv, self, MemFunc, args, Helper::IndexSeq{}); \
1164+ }); \
1165+ }
1166+ #define TVM_MODULE_VTABLE_ENTRY_PACKED (Name, Func ) \
1167+ if (_name == Name) { \
1168+ auto f = (Func); \
1169+ using FType = ::tvm::runtime::detail::function_signature<decltype (f)>::FType; \
1170+ return TypedPackedFunc<FType>(std::move (f)).packed (); \
1171+ }
1172+
11481173/* !
11491174 * \brief Export typed function as a PackedFunc
11501175 * that can be loaded by LibraryModule.
@@ -1330,6 +1355,61 @@ inline void for_each(const F& f, Args&&... args) { // NOLINT(*)
13301355 for_each_dispatcher<sizeof ...(Args) == 0 , 0 , F>::run (f, std::forward<Args>(args)...);
13311356}
13321357
1358+ template <typename T>
1359+ struct ModuleVTableEntryHelper {};
1360+
1361+ template <typename T, typename R, typename ... Args>
1362+ struct ModuleVTableEntryHelper <R (T::*)(Args...) const > {
1363+ using MemFnType = R (T::*)(Args...) const ;
1364+ using IndexSeq = std::index_sequence_for<Args...>;
1365+ static constexpr const std::size_t LenArgs = sizeof ...(Args);
1366+
1367+ template <std::size_t ... Is>
1368+ static TVM_ALWAYS_INLINE void Call (TVMRetValue* rv, T* self, MemFnType f, TVMArgs args,
1369+ std::index_sequence<Is...>) {
1370+ *rv = (self->*f)(args[Is]...);
1371+ }
1372+ };
1373+
1374+ template <typename T, typename R, typename ... Args>
1375+ struct ModuleVTableEntryHelper <R (T::*)(Args...)> {
1376+ using MemFnType = R (T::*)(Args...);
1377+ using IndexSeq = std::index_sequence_for<Args...>;
1378+ static constexpr const std::size_t LenArgs = sizeof ...(Args);
1379+
1380+ template <std::size_t ... Is>
1381+ static TVM_ALWAYS_INLINE void Call (TVMRetValue* rv, T* self, MemFnType f, TVMArgs args,
1382+ std::index_sequence<Is...>) {
1383+ *rv = (self->*f)(args[Is]...);
1384+ }
1385+ };
1386+
1387+ template <typename T, typename ... Args>
1388+ struct ModuleVTableEntryHelper <void (T::*)(Args...) const > {
1389+ using MemFnType = void (T::*)(Args...) const ;
1390+ using IndexSeq = std::index_sequence_for<Args...>;
1391+ static constexpr const std::size_t LenArgs = sizeof ...(Args);
1392+
1393+ template <std::size_t ... Is>
1394+ static TVM_ALWAYS_INLINE void Call (TVMRetValue* rv, T* self, MemFnType f, TVMArgs args,
1395+ std::index_sequence<Is...>) {
1396+ (self->*f)(args[Is]...);
1397+ }
1398+ };
1399+
1400+ template <typename T, typename ... Args>
1401+ struct ModuleVTableEntryHelper <void (T::*)(Args...)> {
1402+ using MemFnType = void (T::*)(Args...);
1403+ using IndexSeq = std::index_sequence_for<Args...>;
1404+ static constexpr const std::size_t LenArgs = sizeof ...(Args);
1405+
1406+ template <std::size_t ... Is>
1407+ static TVM_ALWAYS_INLINE void Call (TVMRetValue* rv, T* self, MemFnType f, TVMArgs args,
1408+ std::index_sequence<Is...>) {
1409+ (self->*f)(args[Is]...);
1410+ }
1411+ };
1412+
13331413namespace parameter_pack {
13341414
13351415template <typename ... EnumArgs>
0 commit comments