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:
parent
4c7d81715e
commit
83c51e6cfa
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
||||
|
@ -92,6 +92,11 @@ namespace SourceHook
|
||||
return m_RetPassInfo;
|
||||
}
|
||||
|
||||
IntPassInfo & GetRet()
|
||||
{
|
||||
return m_RetPassInfo;
|
||||
}
|
||||
|
||||
int GetConvention() const
|
||||
{
|
||||
return m_Convention;
|
||||
|
@ -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
pushd ..\..\generate
shworker.exe iter sourcehook.hxx sourcehook.h 20
copy sourcehook.h ..\sourcehook.h
popd
"
|
||||
CommandLine="echo on
pushd ..\..\generate
shworker.exe iter sourcehook.hxx sourcehook.h 16
copy sourcehook.h ..\sourcehook.h
popd
"
|
||||
Outputs="..\..\sourcehook.h"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
|
@ -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
|
||||
|
@ -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)); \
|
||||
}; \
|
||||
}; \
|
||||
}; \
|
||||
|
@ -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)); \
|
||||
}; \
|
||||
}; \
|
||||
}; \
|
||||
|
Loading…
x
Reference in New Issue
Block a user