mirror of
https://github.com/alliedmodders/metamod-source.git
synced 2025-03-01 22:29:15 +01:00
First support attempt for reference returns
--HG-- branch : hookman_autogen extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40538
This commit is contained in:
parent
ebf7cf8fee
commit
2c8203f263
@ -380,13 +380,22 @@ namespace SourceHook
|
|||||||
|
|
||||||
void GenContext::SaveRetVal(int v_where, int v_place_for_memret)
|
void GenContext::SaveRetVal(int v_where, int v_place_for_memret)
|
||||||
{
|
{
|
||||||
size_t size = m_Proto.GetRet().size;
|
size_t size = GetRealSize(m_Proto.GetRet());
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
// No return value -> nothing
|
// No return value -> nothing
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_Proto.GetRet().flags & PassInfo::PassFlag_ByRef)
|
||||||
|
{
|
||||||
|
// mov [ebp + v_plugin_ret], eax
|
||||||
|
IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_where);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// else: ByVal
|
||||||
|
|
||||||
|
|
||||||
// Memory return:
|
// Memory return:
|
||||||
if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem)
|
if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem)
|
||||||
{
|
{
|
||||||
@ -557,36 +566,46 @@ namespace SourceHook
|
|||||||
|
|
||||||
|
|
||||||
// *eax = plugin_ret
|
// *eax = plugin_ret
|
||||||
if (m_Proto.GetRet().pAssignOperator)
|
if (m_Proto.GetRet().flags & PassInfo::PassFlag_ByRef)
|
||||||
{
|
{
|
||||||
// lea edx, [ebp + v_plugin_ret]
|
// mov ecx, [ebp+v_plugin_ret]
|
||||||
// msvc: ecx = eax <-- dest addr
|
// mov [eax], ecx
|
||||||
// gcc: push eax <-- dest addr
|
IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_plugin_ret);
|
||||||
// push edx <-- src addr
|
IA32_Mov_Rm_Reg(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG);
|
||||||
// call it
|
|
||||||
|
|
||||||
IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_plugin_ret);
|
|
||||||
#if SH_COMP == SH_COMP_MSVC
|
|
||||||
IA32_Mov_Reg_Rm(&m_HookFunc, REG_ECX, REG_EAX, MOD_REG);
|
|
||||||
#elif SH_COMP == SH_COMP_GCC
|
|
||||||
IA32_Push_Reg(&m_HookFunc, REG_EAX);
|
|
||||||
#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
|
else
|
||||||
{
|
{
|
||||||
// bitwise copy
|
if (m_Proto.GetRet().pAssignOperator)
|
||||||
BitwiseCopy_Setup();
|
{
|
||||||
|
// lea edx, [ebp + v_plugin_ret]
|
||||||
|
// msvc: ecx = eax <-- dest addr
|
||||||
|
// gcc: push eax <-- dest addr
|
||||||
|
// push edx <-- src addr
|
||||||
|
// call it
|
||||||
|
|
||||||
//mov edi, eax <-- destination
|
IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EDX, REG_EBP, v_plugin_ret);
|
||||||
//lea esi, [ebp+v_plugin_ret] <-- src
|
#if SH_COMP == SH_COMP_MSVC
|
||||||
IA32_Mov_Reg_Rm(&m_HookFunc, REG_EDI, REG_EAX, MOD_REG);
|
IA32_Mov_Reg_Rm(&m_HookFunc, REG_ECX, REG_EAX, MOD_REG);
|
||||||
IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ESI, REG_EBP, v_plugin_ret);
|
#elif SH_COMP == SH_COMP_GCC
|
||||||
|
IA32_Push_Reg(&m_HookFunc, REG_EAX);
|
||||||
|
#endif
|
||||||
|
IA32_Push_Reg(&m_HookFunc, REG_EDX);
|
||||||
|
|
||||||
BitwiseCopy_Do(m_Proto.GetRet().size);
|
IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(m_Proto.GetRet().pAssignOperator));
|
||||||
|
IA32_Call_Reg(&m_HookFunc, REG_EAX);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// bitwise copy
|
||||||
|
BitwiseCopy_Setup();
|
||||||
|
|
||||||
|
//mov edi, eax <-- destination
|
||||||
|
//lea esi, [ebp+v_plugin_ret] <-- src
|
||||||
|
IA32_Mov_Reg_Rm(&m_HookFunc, REG_EDI, REG_EAX, MOD_REG);
|
||||||
|
IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ESI, REG_EBP, v_plugin_ret);
|
||||||
|
|
||||||
|
BitwiseCopy_Do(m_Proto.GetRet().size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_HookFunc.end_count(counter);
|
m_HookFunc.end_count(counter);
|
||||||
@ -649,12 +668,18 @@ namespace SourceHook
|
|||||||
if (!size)
|
if (!size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// :TODO: memory return support
|
|
||||||
|
|
||||||
// Get real ret pointer into ecx
|
// Get real ret pointer into ecx
|
||||||
// mov ecx, [ebp + v_ret_ptr]
|
// mov ecx, [ebp + v_ret_ptr]
|
||||||
IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_retptr);
|
IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_retptr);
|
||||||
|
|
||||||
|
if (m_Proto.GetRet().flags & PassInfo::PassFlag_ByRef)
|
||||||
|
{
|
||||||
|
// mov eax, [ecx]
|
||||||
|
IA32_Mov_Reg_Rm(&m_HookFunc, REG_EAX, REG_ECX, MOD_MEM_REG);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// else: byval
|
||||||
|
|
||||||
if (m_Proto.GetRet().type == PassInfo::PassType_Float)
|
if (m_Proto.GetRet().type == PassInfo::PassType_Float)
|
||||||
{
|
{
|
||||||
if (size == 4)
|
if (size == 4)
|
||||||
@ -1441,6 +1466,12 @@ namespace SourceHook
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// byref: make sure that the flag is _not_ set
|
||||||
|
pi.flags &= ~PassInfo::PassFlag_RetMem;
|
||||||
|
pi.flags |= PassInfo::PassFlag_RetReg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HookManagerPubFunc GenContext::Generate()
|
HookManagerPubFunc GenContext::Generate()
|
||||||
|
@ -371,7 +371,6 @@ namespace
|
|||||||
THGM_SETUP_RI(110, ObjRet13, SourceHook::PassInfo::PassType_Object,
|
THGM_SETUP_RI(110, ObjRet13, SourceHook::PassInfo::PassType_Object,
|
||||||
SourceHook::PassInfo::PassFlag_ByVal | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor |
|
SourceHook::PassInfo::PassFlag_ByVal | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor |
|
||||||
SourceHook::PassInfo::PassFlag_CCtor | SourceHook::PassInfo::PassFlag_AssignOp);
|
SourceHook::PassInfo::PassFlag_CCtor | SourceHook::PassInfo::PassFlag_AssignOp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TestHookManGen(std::string &error)
|
bool TestHookManGen(std::string &error)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user