1
0
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:
Pavol Marko 2007-11-02 11:59:57 +00:00
parent ebf7cf8fee
commit 2c8203f263
2 changed files with 58 additions and 28 deletions

View File

@ -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()

View File

@ -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)