22 #include "../config.h"
24 #include <type_traits>
26 #include <BlackBone/Process/Process.h>
27 #include <BlackBone/Process/RPC/RemoteFunction.hpp>
28 #include "RMonoAPIBase_Def.h"
29 #include "RMonoAPIFunctionTypeAdapters.h"
30 #include "RMonoAPIFunctionSimple_Def.h"
31 #include "RMonoAPIFunctionCommon_Def.h"
32 #include "abi/RMonoABITypeTraits.h"
75 template <
class CommonT,
typename ABI,
typename RetT,
typename... ArgsT>
79 typedef RetT WrapRetType;
80 typedef std::tuple<ArgsT...> WrapArgsTuple;
88 void linkWrap(blackbone::ptr_t wrapFuncAddr)
90 this->wrapFunc.rebuild(getRemoteMonoAPI()->getProcess(), wrapFuncAddr, getRemoteMonoAPI()->getWorkerThread());
93 RetT invokeWrap(ArgsT... args) {
return wrapFunc(args...); }
95 blackbone::ptr_t getWrapFuncAddress()
const {
return wrapFunc.getAddress(); }
98 ABI* getABI() {
return static_cast<CommonT*
>(
this)->getABI(); }
99 RMonoAPIBase* getRemoteMonoAPI() {
return static_cast<CommonT*
>(
this)->getRemoteMonoAPI(); }
119 template <
typename CommonT,
typename ABI,
typename RetT,
typename... ArgsT>
123 typename RMonoAPIReturnTypeAdapter<ABI, RetT>::WrapType,
124 typename RMonoAPIParamTypeAdapter<ABI, ArgsT>::WrapType...
128 template <
typename Enable,
typename CommonT,
typename ABI,
typename RetT,
typename... ArgsT>
132 template <
typename CommonT,
typename ABI,
typename RetT,
typename... ArgsT>
134 std::enable_if_t<std::is_base_of_v<RMonoVariant, typename RetT::Type>>,
135 CommonT, ABI, RetT, ArgsT...
137 tags::ReturnNull<typename RMonoABITypeTraits<ABI>::irmono_voidp>, tags::ParamOut<RMonoVariant>, ArgsT...> {};
140 template <
typename CommonT,
typename ABI,
typename RetT,
typename... ArgsT>
143 std::is_base_of_v<std::string, typename RetT::Type>
144 || std::is_base_of_v<std::u16string, typename RetT::Type>
145 || std::is_base_of_v<std::u32string, typename RetT::Type>
147 CommonT, ABI, RetT, ArgsT...
150 template <
typename CommonT,
typename ABI,
typename RetT,
typename... ArgsT>
153 !std::is_base_of_v<RMonoVariant, typename RetT::Type>
154 && !std::is_base_of_v<std::string, typename RetT::Type>
155 && !std::is_base_of_v<std::u16string, typename RetT::Type>
156 && !std::is_base_of_v<std::u32string, typename RetT::Type>
158 CommonT, ABI, RetT, ArgsT...
162 template <
typename Enable,
typename CommonT,
typename ABI,
typename RetT,
typename... ArgsT>
182 template <
typename CommonT,
typename ABI,
typename RetT,
typename... ArgsT>
186 typedef RMonoABITypeTraits<ABI> ABITypeTraits;
188 REMOTEMONO_ABI_TYPETRAITS_TYPEDEFS(ABITypeTraits)
193 typedef typename RMonoAPIFunctionCommon<ABI>::variantflags_t variantflags_t;
198 struct AsmBuildContext
200 blackbone::IAsmHelper* a;
204 blackbone::ptr_t gchandleGetTargetAddr;
205 blackbone::ptr_t gchandleNewAddr;
206 blackbone::ptr_t objectGetClassAddr;
207 blackbone::ptr_t classIsValuetypeAddr;
208 blackbone::ptr_t objectUnboxAddr;
211 int32_t rawArgStackSize;
214 int32_t stackOffsArgBase;
215 int32_t stackOffsRetval;
219 template <
size_t idx = 0>
220 constexpr
static std::enable_if_t<idx < std::tuple_size_v<DefArgsTuple>,
bool> needsWrapFuncArg()
222 typedef std::tuple_element_t<idx, DefArgsTuple> ArgType;
228 std::is_base_of_v<Variant, typename ArgType::Type>
229 || std::is_base_of_v<VariantArray, typename ArgType::Type>
230 || std::is_base_of_v<std::string_view, typename ArgType::Type>
231 || std::is_base_of_v<std::u16string_view, typename ArgType::Type>
232 || std::is_base_of_v<std::u32string_view, typename ArgType::Type>
233 || std::is_base_of_v<RMonoObjectHandleTag, typename ArgType::Type>
234 || tags::has_param_tag_v<ArgType, tags::ParamOutTag>
238 return needsWrapFuncArg<idx+1>();
242 template <
size_t idx = 0>
243 constexpr
static std::enable_if_t<idx == std::tuple_size_v<DefArgsTuple>,
bool> needsWrapFuncArg() {
return false; }
248 constexpr
static bool needsWrapFunc()
251 std::is_base_of_v<Variant, typename DefRetType::Type>
252 || std::is_base_of_v<VariantArray, typename DefRetType::Type>
253 || std::is_base_of_v<std::string, typename DefRetType::Type>
254 || std::is_base_of_v<std::u16string, typename DefRetType::Type>
255 || std::is_base_of_v<std::u32string, typename DefRetType::Type>
256 || std::is_base_of_v<RMonoObjectHandleTag, typename DefRetType::Type>
260 return needsWrapFuncArg<0>();
265 asmjit::Label compileWrap(blackbone::IAsmHelper& a);
274 void generateWrapperAsm(AsmBuildContext& ctx);
277 template <
size_t wrapArgIdx>
278 void genWrapperSpillArgsToStackX64(AsmBuildContext& ctx);
281 void genWrapperReserveStack(AsmBuildContext& ctx);
283 template <
size_t wrapArgIdx,
typename ArgT,
typename... RestT>
285 template <
size_t wrapArgIdx>
286 void genWrapperReserveArgStack(AsmBuildContext& ctx) {}
288 template <
size_t rawArgIdx>
289 void genWrapperCalculateRawArgStackSize(AsmBuildContext& ctx);
292 void genWrapperBuildRawArgs(AsmBuildContext& ctx);
294 template <
size_t wrapArgIdx,
size_t rawArgIdx,
typename ArgT,
typename... RestT>
296 template <
size_t wrapArgIdx,
size_t rawArgIdx>
297 void genWrapperBuildRawArg(AsmBuildContext& ctx) {}
300 template <
size_t rawArgIdx>
301 void genWrapperMoveStackArgsToRegsX64(AsmBuildContext& ctx);
304 void genWrapperHandleRetAndOutParams(AsmBuildContext& ctx);
306 template <
size_t wrapArgIdx,
size_t rawArgIdx,
typename ArgT,
typename... RestT>
308 template <
size_t wrapArgIdx,
size_t rawArgIdx>
309 void genWrapperHandleOutParams(AsmBuildContext& ctx) {}
312 void genGchandleGetTargetChecked(AsmBuildContext& ctx);
313 void genGchandleNewChecked(AsmBuildContext& ctx);
314 void genIsValueTypeInstance(AsmBuildContext& ctx);
315 void genObjectUnbox(AsmBuildContext& ctx);
317 template <
size_t argIdx,
typename ArgsTupleT>
318 constexpr
size_t calcStackArgOffset()
320 if constexpr(argIdx == 0) {
323 return static_align(
sizeof(std::tuple_element_t<argIdx-1, ArgsTupleT>),
sizeof(irmono_voidp))
324 + calcStackArgOffset<argIdx-1, ArgsTupleT>();
328 template <
size_t argIdx>
329 asmjit::X86Mem ptrWrapFuncArg(AsmBuildContext& ctx,
size_t partIdx = 0, uint32_t size = 0)
331 return asmjit::host::ptr (
336 + partIdx*
sizeof(irmono_voidp)
342 template <
size_t argIdx>
343 asmjit::X86Mem ptrRawFuncArg(AsmBuildContext& ctx,
size_t partIdx = 0, uint32_t size = 0)
345 return asmjit::host::ptr (
349 + partIdx*
sizeof(irmono_voidp)
356 ABI* getABI() {
return static_cast<CommonT*
>(
this)->getABI(); }
357 RMonoAPIBase* getRemoteMonoAPI() {
return static_cast<CommonT*
>(
this)->getRemoteMonoAPI(); }