[ORC-RT] Add MethodWrapperHandler utility for WrapperFunction.
This is an ORC runtime counterpart to a01f772d19, which introduced the same
functionality into LLVM.
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include "c_api.h"
|
||||
#include "common.h"
|
||||
#include "error.h"
|
||||
#include "executor_address.h"
|
||||
#include "simple_packed_serialization.h"
|
||||
#include <type_traits>
|
||||
|
||||
@@ -321,8 +322,8 @@ public:
|
||||
static WrapperFunctionResult handle(const char *ArgData, size_t ArgSize,
|
||||
HandlerT &&Handler) {
|
||||
using WFHH =
|
||||
detail::WrapperFunctionHandlerHelper<HandlerT, ResultSerializer,
|
||||
SPSTagTs...>;
|
||||
detail::WrapperFunctionHandlerHelper<std::remove_reference_t<HandlerT>,
|
||||
ResultSerializer, SPSTagTs...>;
|
||||
return WFHH::apply(std::forward<HandlerT>(Handler), ArgData, ArgSize);
|
||||
}
|
||||
|
||||
@@ -354,6 +355,48 @@ public:
|
||||
using WrapperFunction<SPSEmpty(SPSTagTs...)>::handle;
|
||||
};
|
||||
|
||||
/// A function object that takes an ExecutorAddr as its first argument,
|
||||
/// casts that address to a ClassT*, then calls the given method on that
|
||||
/// pointer passing in the remaining function arguments. This utility
|
||||
/// removes some of the boilerplate from writing wrappers for method calls.
|
||||
///
|
||||
/// @code{.cpp}
|
||||
/// class MyClass {
|
||||
/// public:
|
||||
/// void myMethod(uint32_t, bool) { ... }
|
||||
/// };
|
||||
///
|
||||
/// // SPS Method signature -- note MyClass object address as first argument.
|
||||
/// using SPSMyMethodWrapperSignature =
|
||||
/// SPSTuple<SPSExecutorAddr, uint32_t, bool>;
|
||||
///
|
||||
/// WrapperFunctionResult
|
||||
/// myMethodCallWrapper(const char *ArgData, size_t ArgSize) {
|
||||
/// return WrapperFunction<SPSMyMethodWrapperSignature>::handle(
|
||||
/// ArgData, ArgSize, makeMethodWrapperHandler(&MyClass::myMethod));
|
||||
/// }
|
||||
/// @endcode
|
||||
///
|
||||
template <typename RetT, typename ClassT, typename... ArgTs>
|
||||
class MethodWrapperHandler {
|
||||
public:
|
||||
using MethodT = RetT (ClassT::*)(ArgTs...);
|
||||
MethodWrapperHandler(MethodT M) : M(M) {}
|
||||
RetT operator()(ExecutorAddr ObjAddr, ArgTs &...Args) {
|
||||
return (ObjAddr.toPtr<ClassT *>()->*M)(std::forward<ArgTs>(Args)...);
|
||||
}
|
||||
|
||||
private:
|
||||
MethodT M;
|
||||
};
|
||||
|
||||
/// Create a MethodWrapperHandler object from the given method pointer.
|
||||
template <typename RetT, typename ClassT, typename... ArgTs>
|
||||
MethodWrapperHandler<RetT, ClassT, ArgTs...>
|
||||
makeMethodWrapperHandler(RetT (ClassT::*Method)(ArgTs...)) {
|
||||
return MethodWrapperHandler<RetT, ClassT, ArgTs...>(Method);
|
||||
}
|
||||
|
||||
} // end namespace __orc_rt
|
||||
|
||||
#endif // ORC_RT_WRAPPER_FUNCTION_UTILS_H
|
||||
|
||||
Reference in New Issue
Block a user