1
0
mirror of https://github.com/alliedmodders/metamod-source.git synced 2025-02-20 13:54:14 +01:00

Implemented memory returns on MSVC for POD types.

--HG--
branch : hookman_autogen
extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40536
This commit is contained in:
Pavol Marko 2007-11-01 17:29:39 +00:00
parent 4c7d81715e
commit 83c51e6cfa
11 changed files with 447 additions and 150 deletions

View File

@ -173,7 +173,13 @@ namespace SourceHook
PassFlag_ODtor = (1<<2), /**< Object has a destructor */
PassFlag_OCtor = (1<<3), /**< Object has a normal non-trivial constructor */
PassFlag_AssignOp = (1<<4), /**< Object has a non-trivial assignment operator */
PassFlag_CCtor = (1<<5) /**< Object has a copy constructor (which takes const Object& as only parameter) */
PassFlag_CCtor = (1<<5), /**< Object has a copy constructor (which takes const Object& as only parameter) */
// The following two flags are only relevant for byval return types.
// SH tries to auto-detect these
// If you want to override SH's auto-detection, pass them in yourself
PassFlag_RetMem = (1<<6), /**< Object is returned in memory (through hidden first param */
PassFlag_RetReg = (1<<7) /**< Object is returned in EAX(:EDX) */
};
size_t size; //!< Size of the data being passed

View File

@ -173,7 +173,13 @@ namespace SourceHook
PassFlag_ODtor = (1<<2), /**< Object has a destructor */
PassFlag_OCtor = (1<<3), /**< Object has a normal non-trivial constructor */
PassFlag_AssignOp = (1<<4), /**< Object has a non-trivial assignment operator */
PassFlag_CCtor = (1<<5) /**< Object has a copy constructor (which takes const Object& as only parameter) */
PassFlag_CCtor = (1<<5), /**< Object has a copy constructor (which takes const Object& as only parameter) */
// The following two flags are only relevant for byval return types.
// SH tries to auto-detect these
// If you want to override SH's auto-detection, pass them in yourself
PassFlag_RetMem = (1<<6), /**< Object is returned in memory (through hidden first param */
PassFlag_RetReg = (1<<7) /**< Object is returned in EAX(:EDX) */
};
size_t size; //!< Size of the data being passed

View File

@ -173,7 +173,13 @@ namespace SourceHook
PassFlag_ODtor = (1<<2), /**< Object has a destructor */
PassFlag_OCtor = (1<<3), /**< Object has a normal non-trivial constructor */
PassFlag_AssignOp = (1<<4), /**< Object has a non-trivial assignment operator */
PassFlag_CCtor = (1<<5) /**< Object has a copy constructor (which takes const Object& as only parameter) */
PassFlag_CCtor = (1<<5), /**< Object has a copy constructor (which takes const Object& as only parameter) */
// The following two flags are only relevant for byval return types.
// SH tries to auto-detect these
// If you want to override SH's auto-detection, pass them in yourself
PassFlag_RetMem = (1<<6), /**< Object is returned in memory (through hidden first param */
PassFlag_RetReg = (1<<7) /**< Object is returned in EAX(:EDX) */
};
size_t size; //!< Size of the data being passed

View File

@ -306,7 +306,7 @@ namespace SourceHook
}
// May not touch eax!
jit_int32_t GenContext::PushParams(jit_int32_t param_base_offset)
jit_int32_t GenContext::PushParams(jit_int32_t param_base_offset, jit_int32_t save_ret_to)
{
jit_int32_t added_to_stack = 0;
jit_int32_t ret = 0;
@ -348,14 +348,23 @@ namespace SourceHook
}
added_to_stack += ret;
}
// Memory return support
if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem)
{
// push address where to save it!
int reg = NextRegEBX_ECX_EDX();
IA32_Lea_DispRegImmAuto(&m_HookFunc, reg, REG_EBP, save_ret_to);
IA32_Push_Reg(&m_HookFunc, reg);
added_to_stack += SIZE_PTR;
}
return added_to_stack;
}
void GenContext::SaveRetVal(int v_where)
{
// :TODO: assign op support
// :TODO: memory return support
size_t size = m_Proto.GetRet().size;
if (size == 0)
{
@ -363,6 +372,11 @@ namespace SourceHook
return;
}
// Memory return:
// PushParams already did everything that was neccessary
if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem)
return;
if (m_Proto.GetRet().type == PassInfo::PassType_Float)
{
if (size == 4)
@ -391,14 +405,35 @@ namespace SourceHook
IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_where);
IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EDX, v_where + 4);
}
else
}
else if (m_Proto.GetRet().type == PassInfo::PassType_Object)
{
if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetReg)
{
// size >8: return in memory
// :TODO:
// add flag: MSVC_RetInMemory?
if (size <= 4)
{
// size <= 4: return in EAX
// We align <4 sizes up to 4
// mov [ebp + v_plugin_ret], eax
IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_where);
}
else if (size <= 8)
{
// size <= 4: return in EAX:EDX
// We align 4<x<8 sizes up to 8
// mov [ebp + v_plugin_ret], eax
// mov [ebp + v_plugin_ret + 4], edx
IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_where);
IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EDX, v_where + 4);
}
else
{
SH_ASSERT(0, ("RetReg and size > 8 !"));
}
}
}
// :TODO: object
}
void GenContext::ProcessPluginRetVal(int v_cur_res, int v_pContext, int v_plugin_ret)
@ -559,7 +594,7 @@ namespace SourceHook
IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_retptr);
}
void GenContext::DoReturn(int v_retptr)
void GenContext::DoReturn(int v_retptr, int v_memret_outaddr)
{
size_t size = m_Proto.GetRet().size;
if (!size)
@ -579,14 +614,14 @@ namespace SourceHook
else if (size == 8)
IA32_Fld_Mem64(&m_HookFunc, REG_ECX);
}
else if (m_Proto.GetRet().type == PassInfo::PassType_Basic)
else if (m_Proto.GetRet().type == PassInfo::PassType_Basic ||
((m_Proto.GetRet().type == PassInfo::PassType_Object) && (m_Proto.GetRet().flags & PassInfo::PassFlag_RetReg)) )
{
if (size <= 4)
{
// size <= 4: return in EAX
// We align <4 sizes up to 4
// mov eax, [ecx]
IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG);
}
@ -603,11 +638,79 @@ namespace SourceHook
else
{
// size >8: return in memory
// :TODO:
// add flag: MSVC_RetInMemory?
// handled later
}
}
// :TODO: object
if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem)
{
// *memret_outaddr = plugin_ret
if (m_Proto.GetRet().pAssignOperator)
{
// mov edx, ecx <-- src ( we set ecx to [ebp+v_retptr] before )
// msvc: ecx = [ebp + v_memret_outaddr] <-- dest addr
// gcc: push [ebp + v_memret_outaddr] <-- dest addr
// push edx <-- src addr
// call it
IA32_Mov_Reg_Rm(&m_HookFunc, REG_EDX, REG_ECX, MOD_REG);
#if SH_COMP == SH_COMP_MSVC
IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_memret_outaddr);
#elif SH_COMP == SH_COMP_GCC
IA32_Push_Rm_DispAuto(&m_HookFunc, REG_EBP, v_memret_outaddr);
#endif
IA32_Push_Reg(&m_HookFunc, REG_EDX);
IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator));
IA32_Call_Reg(&m_HookFunc, REG_EAX);
}
else
{
jit_uint32_t dwords = DownCastSize(m_Proto.GetRet().size) / 4;
jit_uint32_t bytes = DownCastSize(m_Proto.GetRet().size) % 4;
// bitwise copy
//cld
//push edi
//push esi
//mov edi, [ebp+v_memret_outaddr] <-- destination
//mov esi, ecx <-- src ( we set ecx to [ebp+v_retptr] before )
//if dwords
// mov ecx, <dwords>
// rep movsd
//if bytes
// mov ecx, <bytes>
// rep movsb
//pop esi
//pop edi
IA32_Cld(&m_HookFunc);
IA32_Push_Reg(&m_HookFunc, REG_EDI);
IA32_Push_Reg(&m_HookFunc, REG_ESI);
IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EDI, REG_EBP, v_memret_outaddr);
IA32_Mov_Reg_Rm(&m_HookFunc, REG_ESI, REG_ECX, MOD_REG);
if (dwords)
{
IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, dwords);
IA32_Rep(&m_HookFunc);
IA32_Movsd(&m_HookFunc);
}
if (bytes)
{
IA32_Mov_Reg_Imm32(&m_HookFunc, REG_ECX, bytes);
IA32_Rep(&m_HookFunc);
IA32_Movsb(&m_HookFunc);
}
IA32_Pop_Reg(&m_HookFunc, REG_ESI);
IA32_Pop_Reg(&m_HookFunc, REG_EDI);
}
// In both cases: return the pointer in EAX
// mov eax, [ebp + v_memret_outaddr]
IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_EAX, REG_EBP, v_memret_outaddr);
}
}
void GenContext::GenerateCallHooks(int v_status, int v_prev_res, int v_cur_res, int v_iter,
@ -656,7 +759,7 @@ namespace SourceHook
// eax = [ecx]
// eax = [eax+2*SIZE_PTR]
// call eax
jit_int32_t gcc_clean_bytes = PushParams(base_param_offset);
jit_int32_t gcc_clean_bytes = PushParams(base_param_offset, v_plugin_ret);
IA32_Mov_Reg_Rm(&m_HookFunc, REG_ECX, REG_EAX, MOD_REG);
#if SH_COMP == SH_COMP_GCC
@ -718,6 +821,13 @@ namespace SourceHook
{
acc += GetStackSize(m_Proto.GetParam(i));
}
// Memory return: address is first param
if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem)
acc += SIZE_PTR;
// :TODO: cdecl: THIS POINTER AS FIRST PARAM!!!
return acc;
}
@ -775,7 +885,7 @@ namespace SourceHook
m_HookFunc.start_count(counter2);
// push params
jit_int32_t gcc_clean_bytes = PushParams(param_base_offs);
jit_int32_t gcc_clean_bytes = PushParams(param_base_offs, v_orig_ret);
// thisptr
IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_this);
@ -1032,11 +1142,19 @@ namespace SourceHook
const jit_int8_t v_pContext = -24 + addstackoffset;
#if SH_COMP == SH_COMP_GCC
const jit_int32_t param_base_offs = 16;
jit_int32_t param_base_offs = 16;
#elif SH_COMP == SH_COMP_MSVC
const jit_int32_t param_base_offs = 12;
jit_int32_t param_base_offs = 12;
#endif
// Memory return: first param is the address
jit_int32_t v_memret_addr = 0;
if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem)
{
v_memret_addr = param_base_offs;
param_base_offs += SIZE_PTR;
}
jit_int32_t v_ret_ptr = -28 + addstackoffset;
jit_int32_t v_orig_ret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 1;
jit_int32_t v_override_ret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 2;
@ -1111,7 +1229,7 @@ namespace SourceHook
cur_param_pos += GetStackSize(pi);
}
DoReturn(v_ret_ptr);
DoReturn(v_ret_ptr, v_memret_addr);
// !! :TODO: Call destructors of orig_ret/ ...
@ -1254,6 +1372,49 @@ namespace SourceHook
return true;
}
void GenContext::AutoDetectRetType()
{
IntPassInfo &pi = m_Proto.GetRet();
// Only relevant for byval types
if (pi.flags & PassInfo::PassFlag_ByVal)
{
// Basic + float:
if (pi.type == PassInfo::PassType_Basic ||
pi.type == PassInfo::PassType_Float)
{
// <= 8 bytes:
// _always_ in registers, no matter what the user says
if (pi.size <= 8)
{
pi.flags &= ~PassInfo::PassFlag_RetMem;
pi.flags |= PassInfo::PassFlag_RetReg;
}
else
{
// Does this even exist? No idea, if it does: in memory!
pi.flags &= ~PassInfo::PassFlag_RetReg;
pi.flags |= PassInfo::PassFlag_RetMem;
}
}
// Object:
else if (pi.type == PassInfo::PassType_Object)
{
// If the user says nothing, auto-detect
if ((pi.flags & (PassInfo::PassFlag_RetMem | PassInfo::PassFlag_RetReg)) == 0)
{
#if SH_COMP == SH_COMP_MSVC
// MSVC seems to return _all_ structs, classes, unions in memory
pi.flags |= PassInfo::PassFlag_RetMem;
#elif SH_COMP == SH_COMP_GCC
// Same goes for GCC :)
pi.flags |= PassInfo::PassFlag_RetMem;
#endif
}
}
}
}
HookManagerPubFunc GenContext::Generate()
{
Clear();
@ -1270,6 +1431,8 @@ namespace SourceHook
return NULL;
}
AutoDetectRetType();
if (m_Proto.GetConvention() != ProtoInfo::CallConv_Cdecl &&
m_Proto.GetConvention() != ProtoInfo::CallConv_ThisCall)
{

View File

@ -87,6 +87,7 @@ namespace SourceHook
SH_ASSERT(0, ("bad_alloc: couldn't allocate 0x%08X bytes of memory\n", m_AllocatedSize));
return;
}
memset((void*)newBuf, 0xCC, m_AllocatedSize); // :TODO: remove this !
memcpy((void*)newBuf, (const void*)m_pData, m_Size);
if (m_pData)
ms_Allocator.Free(reinterpret_cast<void*>(m_pData));
@ -183,7 +184,7 @@ namespace SourceHook
// Param push
jit_int32_t PushParams(jit_int32_t param_base_offset);
jit_int32_t PushParams(jit_int32_t param_base_offset, jit_int32_t save_ret_to); // save_ret_to only used for memory returns
jit_int32_t PushRef(jit_int32_t param_offset, const IntPassInfo &pi);
jit_int32_t PushBasic(jit_int32_t param_offset, const IntPassInfo &pi);
jit_int32_t PushFloat(jit_int32_t param_offset, const IntPassInfo &pi);
@ -194,7 +195,7 @@ namespace SourceHook
void ProcessPluginRetVal(int v_cur_res, int v_pContext, int v_plugin_ret);
void PrepareReturn(int v_status, int v_pContext, int v_retptr);
void DoReturn(int v_retptr);
void DoReturn(int v_retptr, int v_memret_outaddr);
// Call hooks
void GenerateCallHooks(int v_status, int v_prev_res, int v_cur_res, int v_iter,
@ -212,6 +213,7 @@ namespace SourceHook
void CallEndContext(int v_pContext);
// Level 2 -> called from Generate()
void AutoDetectRetType();
bool PassInfoSupported(const IntPassInfo &pi, bool is_ret);
void Clear();
void BuildProtoInfo();

View File

@ -13,6 +13,7 @@
#include "sh_list.h"
#include "sourcehook_impl_cproto.h"
#include "sourcehook_hookmangen.h"
namespace SourceHook
{
@ -72,7 +73,7 @@ namespace SourceHook
}
// *** IHookManagerInfo interface ***
void SetInfo(int hookman_version, int vtbloffs, int vtblidx,
void SetInfo(int hookman_version, int vtbloffs, int vtblidx,
ProtoInfo *proto, void *hookfunc_vfnptr);
};
@ -194,5 +195,5 @@ namespace SourceHook
}
}
#endif
#endif

View File

@ -92,6 +92,11 @@ namespace SourceHook
return m_RetPassInfo;
}
IntPassInfo & GetRet()
{
return m_RetPassInfo;
}
int GetConvention() const
{
return m_Convention;

View File

@ -303,6 +303,7 @@
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
StringPooling="true"
MinimalRebuild="true"
ExceptionHandling="1"
BasicRuntimeChecks="3"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
@ -488,6 +489,30 @@
RelativePath="..\..\sourcehook_impl.h"
>
</File>
<File
RelativePath="..\..\sourcehook_impl_chook.h"
>
</File>
<File
RelativePath="..\..\sourcehook_impl_chookidman.h"
>
</File>
<File
RelativePath="..\..\sourcehook_impl_chookmaninfo.h"
>
</File>
<File
RelativePath="..\..\sourcehook_impl_ciface.h"
>
</File>
<File
RelativePath="..\..\sourcehook_impl_cproto.h"
>
</File>
<File
RelativePath="..\..\sourcehook_impl_cvfnptr.h"
>
</File>
<File
RelativePath="..\sourcehook_test.h"
>
@ -519,7 +544,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="echo on&#x0D;&#x0A;pushd ..\..\generate&#x0D;&#x0A;shworker.exe iter sourcehook.hxx sourcehook.h 20&#x0D;&#x0A;copy sourcehook.h ..\sourcehook.h&#x0D;&#x0A;popd&#x0D;&#x0A;"
CommandLine="echo on&#x0D;&#x0A;pushd ..\..\generate&#x0D;&#x0A;shworker.exe iter sourcehook.hxx sourcehook.h 16&#x0D;&#x0A;copy sourcehook.h ..\sourcehook.h&#x0D;&#x0A;popd&#x0D;&#x0A;"
Outputs="..\..\sourcehook.h"
/>
</FileConfiguration>

View File

@ -18,53 +18,6 @@
namespace
{
#include "testhookmangen.h"
StateList g_States;
SourceHook::ISourceHook *g_SHPtr;
SourceHook::Plugin g_PLID;
// PtrBuf(ptr) gives ptrs unique numbers
// in the order they appear
SourceHook::List<const void*> g_PtrHash;
bool g_Inside_LeafFunc = false; // inside a hook or a func
template <class T>
int PtrBuf(T ptr)
{
int a = 0;
const void *vptr = reinterpret_cast<const void*>(ptr);
for (SourceHook::List<const void*>::iterator iter = g_PtrHash.begin(); iter != g_PtrHash.end(); ++iter)
{
if (*iter == vptr)
return a;
else
++a;
}
g_PtrHash.push_back(vptr);
return static_cast<int>(g_PtrHash.size()) - 1;
}
template <class T>
T PtrBufPtr(T ptr)
{
PtrBuf(ptr);
return ptr;
}
void PtrBuf_Clear(int leave_in = 0)
{
for (SourceHook::List<const void*>::iterator iter = g_PtrHash.begin(); iter != g_PtrHash.end();)
{
if (--leave_in < 0)
iter = g_PtrHash.erase(iter);
else
++iter;
}
}
// POD / Object types
template <int MYSIZE>
struct POD
@ -75,6 +28,16 @@ namespace
{
return memcmp(reinterpret_cast<void*>(x), reinterpret_cast<const void*>(other.x), MYSIZE) == 0;
}
bool operator==(char other)
{
for (int i = 0; i < MYSIZE; ++i)
{
if (x[i] != other)
return false;
}
return true;
}
};
template <int MYSIZE>
@ -132,6 +95,53 @@ namespace
return os;
}
#include "testhookmangen.h"
StateList g_States;
SourceHook::ISourceHook *g_SHPtr;
SourceHook::Plugin g_PLID;
// PtrBuf(ptr) gives ptrs unique numbers
// in the order they appear
SourceHook::List<const void*> g_PtrHash;
bool g_Inside_LeafFunc = false; // inside a hook or a func
template <class T>
int PtrBuf(T ptr)
{
int a = 0;
const void *vptr = reinterpret_cast<const void*>(ptr);
for (SourceHook::List<const void*>::iterator iter = g_PtrHash.begin(); iter != g_PtrHash.end(); ++iter)
{
if (*iter == vptr)
return a;
else
++a;
}
g_PtrHash.push_back(vptr);
return static_cast<int>(g_PtrHash.size()) - 1;
}
template <class T>
T PtrBufPtr(T ptr)
{
PtrBuf(ptr);
return ptr;
}
void PtrBuf_Clear(int leave_in = 0)
{
for (SourceHook::List<const void*>::iterator iter = g_PtrHash.begin(); iter != g_PtrHash.end();)
{
if (--leave_in < 0)
iter = g_PtrHash.erase(iter);
else
++iter;
}
}
// "Increment" something: (reproducible change for recall tests)
// integer: ++
@ -267,6 +277,31 @@ namespace
THGM_MAKE_TEST0(105, double);
THGM_SETUP_PI0(105);
THGM_SETUP_RI(105, double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal);
// pod 1-13
THGM_MAKE_TEST1(106, POD<1>, int);
THGM_SETUP_PI1(106,
int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal
);
THGM_SETUP_RI(106, POD<1>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST1(107, POD<4>, int);
THGM_SETUP_PI1(107,
int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal
);
THGM_SETUP_RI(107, POD<4>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST1(108, POD<8>, int);
THGM_SETUP_PI1(108,
int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal
);
THGM_SETUP_RI(108, POD<8>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST1(109, POD<13>, int);
THGM_SETUP_PI1(109,
int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal
);
THGM_SETUP_RI(109, POD<13>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal);
}
bool TestHookManGen(std::string &error)
@ -292,10 +327,10 @@ bool TestHookManGen(std::string &error)
double b = 233.33;
THGM_DO_TEST_void(7, (a, b));
POD<7> pod7 = {78};
POD<7> pod7 = MakeRet< POD<7> >::Do(78);
THGM_DO_TEST_void(8, (pod7));
POD<600> pod600 = {34};
POD<600> pod600 = MakeRet< POD<600> >::Do(34);
THGM_DO_TEST_void(9, (pod600));
THGM_DO_TEST_void(10, (pod600));
@ -461,6 +496,12 @@ bool TestHookManGen(std::string &error)
THGM_DO_TEST(105, ());
// pod returns
THGM_DO_TEST(106, (5));
THGM_DO_TEST(107, (5));
THGM_DO_TEST(108, (5));
THGM_DO_TEST(109, (5));
// Shutdown now!
// If we don't SH will auto-shutdown _after_ genc's destructor is called
// -> crash

View File

@ -84,6 +84,27 @@ template <class T> struct MyRefCarrier<T&>
};
};
// Return value maker
template <class T>
struct MakeRet
{
static T Do(int a)
{
return static_cast<T>(a);
}
};
template <int SIZE>
struct MakeRet< POD<SIZE> >
{
static POD<SIZE> Do(int a)
{
POD<SIZE> x;
memset(reinterpret_cast<void*>(x.x), a, SIZE);
return x;
}
};
// Stores parameter status
@ -509,7 +530,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
ADD_STATE(State_Func##id(this, ParamState_m##id())); \
g_Inside_LeafFunc = false; \
\
return 0; \
return MakeRet<ret_type>::Do(0); \
} \
\
struct Delegate1 : public MyDelegate \
@ -522,10 +543,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
\
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, ()); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet<ret_type>::Do(1), &TestClass##id::Func, ()); \
} \
else \
RETURN_META_VALUE(MRES_IGNORED, 1); \
RETURN_META_VALUE(MRES_IGNORED, MakeRet<ret_type>::Do(1)); \
} \
}; \
struct Delegate2 : public MyDelegate \
@ -538,10 +559,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
\
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, ()); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet<ret_type>::Do(2), &TestClass##id::Func, ()); \
} \
else \
RETURN_META_VALUE(MRES_SUPERCEDE, 2); \
RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet<ret_type>::Do(2)); \
} \
}; \
struct Delegate3 : public MyDelegate \
@ -554,10 +575,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
\
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, ()); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet<ret_type>::Do(3), &TestClass##id::Func, ()); \
} \
else \
RETURN_META_VALUE(MRES_IGNORED, 3); \
RETURN_META_VALUE(MRES_IGNORED, MakeRet<ret_type>::Do(3)); \
} \
}; \
struct Delegate4 : public MyDelegate \
@ -570,10 +591,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
\
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, ()); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet<ret_type>::Do(4), &TestClass##id::Func, ()); \
} \
else \
RETURN_META_VALUE(MRES_SUPERCEDE, 4); \
RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet<ret_type>::Do(4)); \
}; \
}; \
}; \
@ -718,7 +739,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
ADD_STATE(State_Func##id(this, ParamState_m##id(p1))); \
g_Inside_LeafFunc = false; \
\
return 0; \
return MakeRet<ret_type>::Do(0); \
} \
\
struct Delegate1 : public MyDelegate \
@ -731,10 +752,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (p1)); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet<ret_type>::Do(1), &TestClass##id::Func, (p1)); \
} \
else \
RETURN_META_VALUE(MRES_IGNORED, 1); \
RETURN_META_VALUE(MRES_IGNORED, MakeRet<ret_type>::Do(1)); \
} \
}; \
struct Delegate2 : public MyDelegate \
@ -747,10 +768,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (p1)); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet<ret_type>::Do(2), &TestClass##id::Func, (p1)); \
} \
else \
RETURN_META_VALUE(MRES_SUPERCEDE, 2); \
RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet<ret_type>::Do(2)); \
} \
}; \
struct Delegate3 : public MyDelegate \
@ -763,10 +784,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (p1)); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet<ret_type>::Do(3), &TestClass##id::Func, (p1)); \
} \
else \
RETURN_META_VALUE(MRES_IGNORED, 3); \
RETURN_META_VALUE(MRES_IGNORED, MakeRet<ret_type>::Do(3)); \
} \
}; \
struct Delegate4 : public MyDelegate \
@ -779,10 +800,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (p1)); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet<ret_type>::Do(4), &TestClass##id::Func, (p1)); \
} \
else \
RETURN_META_VALUE(MRES_SUPERCEDE, 4); \
RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet<ret_type>::Do(4)); \
}; \
}; \
}; \
@ -927,7 +948,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2))); \
g_Inside_LeafFunc = false; \
\
return 0; \
return MakeRet<ret_type>::Do(0); \
} \
\
struct Delegate1 : public MyDelegate \
@ -940,10 +961,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (p1, p2)); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet<ret_type>::Do(1), &TestClass##id::Func, (p1, p2)); \
} \
else \
RETURN_META_VALUE(MRES_IGNORED, 1); \
RETURN_META_VALUE(MRES_IGNORED, MakeRet<ret_type>::Do(1)); \
} \
}; \
struct Delegate2 : public MyDelegate \
@ -956,10 +977,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (p1, p2)); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet<ret_type>::Do(2), &TestClass##id::Func, (p1, p2)); \
} \
else \
RETURN_META_VALUE(MRES_SUPERCEDE, 2); \
RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet<ret_type>::Do(2)); \
} \
}; \
struct Delegate3 : public MyDelegate \
@ -972,10 +993,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (p1, p2)); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet<ret_type>::Do(3), &TestClass##id::Func, (p1, p2)); \
} \
else \
RETURN_META_VALUE(MRES_IGNORED, 3); \
RETURN_META_VALUE(MRES_IGNORED, MakeRet<ret_type>::Do(3)); \
} \
}; \
struct Delegate4 : public MyDelegate \
@ -988,10 +1009,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (p1, p2)); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet<ret_type>::Do(4), &TestClass##id::Func, (p1, p2)); \
} \
else \
RETURN_META_VALUE(MRES_SUPERCEDE, 4); \
RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet<ret_type>::Do(4)); \
}; \
}; \
}; \
@ -1136,7 +1157,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3))); \
g_Inside_LeafFunc = false; \
\
return 0; \
return MakeRet<ret_type>::Do(0); \
} \
\
struct Delegate1 : public MyDelegate \
@ -1149,10 +1170,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2);Increment<StripRef< param3 >::type>::Incr(p3); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (p1, p2, p3)); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet<ret_type>::Do(1), &TestClass##id::Func, (p1, p2, p3)); \
} \
else \
RETURN_META_VALUE(MRES_IGNORED, 1); \
RETURN_META_VALUE(MRES_IGNORED, MakeRet<ret_type>::Do(1)); \
} \
}; \
struct Delegate2 : public MyDelegate \
@ -1165,10 +1186,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2);Increment<StripRef< param3 >::type>::Incr(p3); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (p1, p2, p3)); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet<ret_type>::Do(2), &TestClass##id::Func, (p1, p2, p3)); \
} \
else \
RETURN_META_VALUE(MRES_SUPERCEDE, 2); \
RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet<ret_type>::Do(2)); \
} \
}; \
struct Delegate3 : public MyDelegate \
@ -1181,10 +1202,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2);Increment<StripRef< param3 >::type>::Incr(p3); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (p1, p2, p3)); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet<ret_type>::Do(3), &TestClass##id::Func, (p1, p2, p3)); \
} \
else \
RETURN_META_VALUE(MRES_IGNORED, 3); \
RETURN_META_VALUE(MRES_IGNORED, MakeRet<ret_type>::Do(3)); \
} \
}; \
struct Delegate4 : public MyDelegate \
@ -1197,10 +1218,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2);Increment<StripRef< param3 >::type>::Incr(p3); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (p1, p2, p3)); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet<ret_type>::Do(4), &TestClass##id::Func, (p1, p2, p3)); \
} \
else \
RETURN_META_VALUE(MRES_SUPERCEDE, 4); \
RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet<ret_type>::Do(4)); \
}; \
}; \
}; \
@ -1345,7 +1366,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4))); \
g_Inside_LeafFunc = false; \
\
return 0; \
return MakeRet<ret_type>::Do(0); \
} \
\
struct Delegate1 : public MyDelegate \
@ -1358,10 +1379,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2);Increment<StripRef< param3 >::type>::Incr(p3);Increment<StripRef< param4 >::type>::Incr(p4); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (p1, p2, p3, p4)); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet<ret_type>::Do(1), &TestClass##id::Func, (p1, p2, p3, p4)); \
} \
else \
RETURN_META_VALUE(MRES_IGNORED, 1); \
RETURN_META_VALUE(MRES_IGNORED, MakeRet<ret_type>::Do(1)); \
} \
}; \
struct Delegate2 : public MyDelegate \
@ -1374,10 +1395,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2);Increment<StripRef< param3 >::type>::Incr(p3);Increment<StripRef< param4 >::type>::Incr(p4); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (p1, p2, p3, p4)); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet<ret_type>::Do(2), &TestClass##id::Func, (p1, p2, p3, p4)); \
} \
else \
RETURN_META_VALUE(MRES_SUPERCEDE, 2); \
RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet<ret_type>::Do(2)); \
} \
}; \
struct Delegate3 : public MyDelegate \
@ -1390,10 +1411,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2);Increment<StripRef< param3 >::type>::Incr(p3);Increment<StripRef< param4 >::type>::Incr(p4); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (p1, p2, p3, p4)); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet<ret_type>::Do(3), &TestClass##id::Func, (p1, p2, p3, p4)); \
} \
else \
RETURN_META_VALUE(MRES_IGNORED, 3); \
RETURN_META_VALUE(MRES_IGNORED, MakeRet<ret_type>::Do(3)); \
} \
}; \
struct Delegate4 : public MyDelegate \
@ -1406,10 +1427,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2);Increment<StripRef< param3 >::type>::Incr(p3);Increment<StripRef< param4 >::type>::Incr(p4); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (p1, p2, p3, p4)); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet<ret_type>::Do(4), &TestClass##id::Func, (p1, p2, p3, p4)); \
} \
else \
RETURN_META_VALUE(MRES_SUPERCEDE, 4); \
RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet<ret_type>::Do(4)); \
}; \
}; \
}; \
@ -1554,7 +1575,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5))); \
g_Inside_LeafFunc = false; \
\
return 0; \
return MakeRet<ret_type>::Do(0); \
} \
\
struct Delegate1 : public MyDelegate \
@ -1567,10 +1588,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2);Increment<StripRef< param3 >::type>::Incr(p3);Increment<StripRef< param4 >::type>::Incr(p4);Increment<StripRef< param5 >::type>::Incr(p5); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet<ret_type>::Do(1), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \
} \
else \
RETURN_META_VALUE(MRES_IGNORED, 1); \
RETURN_META_VALUE(MRES_IGNORED, MakeRet<ret_type>::Do(1)); \
} \
}; \
struct Delegate2 : public MyDelegate \
@ -1583,10 +1604,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2);Increment<StripRef< param3 >::type>::Incr(p3);Increment<StripRef< param4 >::type>::Incr(p4);Increment<StripRef< param5 >::type>::Incr(p5); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet<ret_type>::Do(2), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \
} \
else \
RETURN_META_VALUE(MRES_SUPERCEDE, 2); \
RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet<ret_type>::Do(2)); \
} \
}; \
struct Delegate3 : public MyDelegate \
@ -1599,10 +1620,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2);Increment<StripRef< param3 >::type>::Incr(p3);Increment<StripRef< param4 >::type>::Incr(p4);Increment<StripRef< param5 >::type>::Incr(p5); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet<ret_type>::Do(3), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \
} \
else \
RETURN_META_VALUE(MRES_IGNORED, 3); \
RETURN_META_VALUE(MRES_IGNORED, MakeRet<ret_type>::Do(3)); \
} \
}; \
struct Delegate4 : public MyDelegate \
@ -1615,10 +1636,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2);Increment<StripRef< param3 >::type>::Incr(p3);Increment<StripRef< param4 >::type>::Incr(p4);Increment<StripRef< param5 >::type>::Incr(p5); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (p1, p2, p3, p4, p5)); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet<ret_type>::Do(4), &TestClass##id::Func, (p1, p2, p3, p4, p5)); \
} \
else \
RETURN_META_VALUE(MRES_SUPERCEDE, 4); \
RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet<ret_type>::Do(4)); \
}; \
}; \
}; \
@ -1763,7 +1784,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
ADD_STATE(State_Func##id(this, ParamState_m##id(p1, p2, p3, p4, p5, p6))); \
g_Inside_LeafFunc = false; \
\
return 0; \
return MakeRet<ret_type>::Do(0); \
} \
\
struct Delegate1 : public MyDelegate \
@ -1776,10 +1797,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2);Increment<StripRef< param3 >::type>::Incr(p3);Increment<StripRef< param4 >::type>::Incr(p4);Increment<StripRef< param5 >::type>::Incr(p5);Increment<StripRef< param6 >::type>::Incr(p6); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet<ret_type>::Do(1), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \
} \
else \
RETURN_META_VALUE(MRES_IGNORED, 1); \
RETURN_META_VALUE(MRES_IGNORED, MakeRet<ret_type>::Do(1)); \
} \
}; \
struct Delegate2 : public MyDelegate \
@ -1792,10 +1813,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2);Increment<StripRef< param3 >::type>::Incr(p3);Increment<StripRef< param4 >::type>::Incr(p4);Increment<StripRef< param5 >::type>::Incr(p5);Increment<StripRef< param6 >::type>::Incr(p6); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet<ret_type>::Do(2), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \
} \
else \
RETURN_META_VALUE(MRES_SUPERCEDE, 2); \
RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet<ret_type>::Do(2)); \
} \
}; \
struct Delegate3 : public MyDelegate \
@ -1808,10 +1829,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2);Increment<StripRef< param3 >::type>::Incr(p3);Increment<StripRef< param4 >::type>::Incr(p4);Increment<StripRef< param5 >::type>::Incr(p5);Increment<StripRef< param6 >::type>::Incr(p6); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet<ret_type>::Do(3), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \
} \
else \
RETURN_META_VALUE(MRES_IGNORED, 3); \
RETURN_META_VALUE(MRES_IGNORED, MakeRet<ret_type>::Do(3)); \
} \
}; \
struct Delegate4 : public MyDelegate \
@ -1824,10 +1845,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState6<0, p1, p2, p3, p4,
if (ms_DoRecall) \
{ \
Increment<StripRef< param1 >::type>::Incr(p1);Increment<StripRef< param2 >::type>::Incr(p2);Increment<StripRef< param3 >::type>::Incr(p3);Increment<StripRef< param4 >::type>::Incr(p4);Increment<StripRef< param5 >::type>::Incr(p5);Increment<StripRef< param6 >::type>::Incr(p6); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet<ret_type>::Do(4), &TestClass##id::Func, (p1, p2, p3, p4, p5, p6)); \
} \
else \
RETURN_META_VALUE(MRES_SUPERCEDE, 4); \
RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet<ret_type>::Do(4)); \
}; \
}; \
}; \

View File

@ -84,6 +84,27 @@ template <class T> struct MyRefCarrier<T&>
};
};
// Return value maker
template <class T>
struct MakeRet
{
static T Do(int a)
{
return a;
}
};
template <int SIZE>
struct MakeRet< POD<SIZE> >
{
static POD<SIZE> Do(int a)
{
POD x;
memset(reinterpret_cast<void*>(x.x), a, SIZE);
return x;
}
};
// Stores parameter status
@[$1,0,$a:
@ -251,7 +272,7 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@]
ADD_STATE(State_Func##id(this, ParamState_m##id(@[$2,1,$1|, :p$2@]))); \
g_Inside_LeafFunc = false; \
\
return 0; \
return MakeRet<ret_type>::Do(0); \
} \
\
struct Delegate1 : public MyDelegate \
@ -264,10 +285,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@]
if (ms_DoRecall) \
{ \
@[$2,1,$1:Increment<StripRef< param$2 >::type>::Incr(p$2);@] \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 1, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet<ret_type>::Do(1), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \
} \
else \
RETURN_META_VALUE(MRES_IGNORED, 1); \
RETURN_META_VALUE(MRES_IGNORED, MakeRet<ret_type>::Do(1)); \
} \
}; \
struct Delegate2 : public MyDelegate \
@ -280,10 +301,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@]
if (ms_DoRecall) \
{ \
@[$2,1,$1:Increment<StripRef< param$2 >::type>::Incr(p$2);@] \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 2, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet<ret_type>::Do(2), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \
} \
else \
RETURN_META_VALUE(MRES_SUPERCEDE, 2); \
RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet<ret_type>::Do(2)); \
} \
}; \
struct Delegate3 : public MyDelegate \
@ -296,10 +317,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@]
if (ms_DoRecall) \
{ \
@[$2,1,$1:Increment<StripRef< param$2 >::type>::Incr(p$2);@] \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, 3, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, MakeRet<ret_type>::Do(3), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \
} \
else \
RETURN_META_VALUE(MRES_IGNORED, 3); \
RETURN_META_VALUE(MRES_IGNORED, MakeRet<ret_type>::Do(3)); \
} \
}; \
struct Delegate4 : public MyDelegate \
@ -312,10 +333,10 @@ std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@]
if (ms_DoRecall) \
{ \
@[$2,1,$1:Increment<StripRef< param$2 >::type>::Incr(p$2);@] \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, 4, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \
RETURN_META_VALUE_NEWPARAMS(MRES_SUPERCEDE, MakeRet<ret_type>::Do(4), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \
} \
else \
RETURN_META_VALUE(MRES_SUPERCEDE, 4); \
RETURN_META_VALUE(MRES_SUPERCEDE, MakeRet<ret_type>::Do(4)); \
}; \
}; \
}; \