From edba8096bf2b2b251cb8f6813eb45c6005de4b9e Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Thu, 27 Feb 2014 22:50:25 +0100 Subject: [PATCH] x64Emitter: Add functions to call a C++ std::function from JITed code --- Source/Core/Common/x64Emitter.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Source/Core/Common/x64Emitter.h b/Source/Core/Common/x64Emitter.h index 5b30833b21..b35fff3319 100644 --- a/Source/Core/Common/x64Emitter.h +++ b/Source/Core/Common/x64Emitter.h @@ -8,6 +8,7 @@ #include #include +#include #include "Common/Common.h" #include "Common/MemoryUtil.h" @@ -739,6 +740,26 @@ public: #define DECLARE_IMPORT(x) extern "C" void *__imp_##x #endif + + // Utility to generate a call to a std::function object. + // + // Unfortunately, calling operator() directly is undefined behavior in C++ + // (this method might be a thunk in the case of multi-inheritance) so we + // have to go through a trampoline function. + template + static void CallLambdaTrampoline(const std::function* f, + Args... args) + { + (*f)(args...); + } + + template + void ABI_CallLambdaC(const std::function* f, u32 p1) + { + // Double casting is required by VC++ for some reason. + auto trampoline = (void(*)())&XEmitter::CallLambdaTrampoline; + ABI_CallFunctionPC((void*)trampoline, const_cast((const void*)f), p1); + } }; // class XEmitter