mirror of
https://github.com/rehlds/metamod-r.git
synced 2024-12-27 07:05:34 +03:00
Add float return type support (lol :D)
This commit is contained in:
parent
76f64ff95d
commit
80555d35b8
@ -69,7 +69,7 @@ void CForwardCallbackJIT::naked_main()
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto globals = ebx;
|
auto globals = ebx;
|
||||||
auto locals_size = m_jitdata->has_ret ? sizeof(int) * 2 /* orig + over */ : 0;
|
auto locals_size = m_jitdata->rettype != rt_void ? sizeof(int) * 2 /* orig + over */ : 0;
|
||||||
auto framesize = align(locals_size + sizeof(meta_globals_t) + /* for align */m_jitdata->args_count * sizeof(int), xmmreg_size) - m_jitdata->args_count * sizeof(int);
|
auto framesize = align(locals_size + sizeof(meta_globals_t) + /* for align */m_jitdata->args_count * sizeof(int), xmmreg_size) - m_jitdata->args_count * sizeof(int);
|
||||||
|
|
||||||
if (m_jitdata->has_varargs) {
|
if (m_jitdata->has_varargs) {
|
||||||
@ -115,7 +115,7 @@ void CForwardCallbackJIT::naked_main()
|
|||||||
mov(dword_ptr[globals + mg_esp_save], esp);
|
mov(dword_ptr[globals + mg_esp_save], esp);
|
||||||
|
|
||||||
// setup retval pointers
|
// setup retval pointers
|
||||||
if (m_jitdata->has_ret) {
|
if (m_jitdata->rettype != rt_void) {
|
||||||
lea(eax, dword_ptr[esp + over_ret]);
|
lea(eax, dword_ptr[esp + over_ret]);
|
||||||
mov(dword_ptr[globals + mg_orig_ret], esp);
|
mov(dword_ptr[globals + mg_orig_ret], esp);
|
||||||
mov(dword_ptr[globals + mg_over_ret], eax);
|
mov(dword_ptr[globals + mg_over_ret], eax);
|
||||||
@ -160,7 +160,13 @@ void CForwardCallbackJIT::naked_main()
|
|||||||
mov(dword_ptr[globals + mg_status], ecx);
|
mov(dword_ptr[globals + mg_status], ecx);
|
||||||
|
|
||||||
// save return value if override or supercede
|
// save return value if override or supercede
|
||||||
if (m_jitdata->has_ret) {
|
if (m_jitdata->rettype != rt_void) {
|
||||||
|
if (m_jitdata->rettype == rt_float) {
|
||||||
|
sub(esp, sizeof(int));
|
||||||
|
fstp(dword_ptr[esp]);
|
||||||
|
pop(eax);
|
||||||
|
}
|
||||||
|
|
||||||
mov(ecx, dword_ptr[esp + over_ret]);
|
mov(ecx, dword_ptr[esp + over_ret]);
|
||||||
cmp(edx, MRES_OVERRIDE);
|
cmp(edx, MRES_OVERRIDE);
|
||||||
cmovae(ecx, eax);
|
cmovae(ecx, eax);
|
||||||
@ -181,7 +187,7 @@ void CForwardCallbackJIT::naked_main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// store original return value
|
// store original return value
|
||||||
if (m_jitdata->has_ret) {
|
if (m_jitdata->rettype == rt_integer) {
|
||||||
if (m_jitdata->pfn_original)
|
if (m_jitdata->pfn_original)
|
||||||
mov(dword_ptr[esp + orig_ret], eax);
|
mov(dword_ptr[esp + orig_ret], eax);
|
||||||
else
|
else
|
||||||
@ -189,10 +195,18 @@ void CForwardCallbackJIT::naked_main()
|
|||||||
|
|
||||||
jmp("skip_supercede");
|
jmp("skip_supercede");
|
||||||
}
|
}
|
||||||
|
else if (m_jitdata->rettype == rt_float) {
|
||||||
|
if (m_jitdata->pfn_original)
|
||||||
|
fstp(dword_ptr[esp + orig_ret]);
|
||||||
|
else
|
||||||
|
mov(dword_ptr[esp + orig_ret], 0);
|
||||||
|
|
||||||
|
jmp("skip_supercede");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
L("skip_original");
|
L("skip_original");
|
||||||
{
|
{
|
||||||
if (m_jitdata->has_ret) {
|
if (m_jitdata->rettype != rt_void) {
|
||||||
// if supercede
|
// if supercede
|
||||||
mov(eax, dword_ptr[esp + over_ret]);
|
mov(eax, dword_ptr[esp + over_ret]);
|
||||||
mov(dword_ptr[esp + orig_ret], eax);
|
mov(dword_ptr[esp + orig_ret], eax);
|
||||||
@ -241,7 +255,13 @@ void CForwardCallbackJIT::naked_main()
|
|||||||
mov(dword_ptr[globals + mg_status], ecx);
|
mov(dword_ptr[globals + mg_status], ecx);
|
||||||
|
|
||||||
// save return value if override or supercede
|
// save return value if override or supercede
|
||||||
if (m_jitdata->has_ret) {
|
if (m_jitdata->rettype != rt_void) {
|
||||||
|
if (m_jitdata->rettype == rt_float) {
|
||||||
|
sub(esp, sizeof(int));
|
||||||
|
fstp(dword_ptr[esp]);
|
||||||
|
pop(eax);
|
||||||
|
}
|
||||||
|
|
||||||
cmp(edx, MRES_OVERRIDE);
|
cmp(edx, MRES_OVERRIDE);
|
||||||
mov(ecx, dword_ptr[esp + over_ret]);
|
mov(ecx, dword_ptr[esp + over_ret]);
|
||||||
cmovae(ecx, eax);
|
cmovae(ecx, eax);
|
||||||
@ -264,11 +284,17 @@ void CForwardCallbackJIT::naked_main()
|
|||||||
movq(qword_ptr[globals + xmmreg_size], xmm1);
|
movq(qword_ptr[globals + xmmreg_size], xmm1);
|
||||||
|
|
||||||
// setup return value and override it if needed
|
// setup return value and override it if needed
|
||||||
if (m_jitdata->has_ret) {
|
if (m_jitdata->rettype == rt_integer) {
|
||||||
mov(eax, dword_ptr[esp + orig_ret]);
|
mov(eax, dword_ptr[esp + orig_ret]);
|
||||||
cmp(dword_ptr[globals + mg_status], MRES_OVERRIDE);
|
cmp(dword_ptr[globals + mg_status], MRES_OVERRIDE);
|
||||||
cmovae(eax, dword_ptr[esp + over_ret]);
|
cmovae(eax, dword_ptr[esp + over_ret]);
|
||||||
}
|
}
|
||||||
|
else if (m_jitdata->rettype == rt_float) {
|
||||||
|
lea(eax, dword_ptr[esp + over_ret]);
|
||||||
|
cmp(dword_ptr[globals + mg_status], MRES_OVERRIDE);
|
||||||
|
cmovb(eax, esp); // orig_ret
|
||||||
|
fld(dword_ptr[eax]);
|
||||||
|
}
|
||||||
|
|
||||||
// epilogue
|
// epilogue
|
||||||
mov(esp, ebp);
|
mov(esp, ebp);
|
||||||
@ -280,7 +306,7 @@ void CForwardCallbackJIT::naked_main()
|
|||||||
void CForwardCallbackJIT::call_func(Reg32 addr)
|
void CForwardCallbackJIT::call_func(Reg32 addr)
|
||||||
{
|
{
|
||||||
const size_t fixed_args_count = m_jitdata->args_count - (m_jitdata->has_varargs ? 1u /* excluding format string */ : 0u);
|
const size_t fixed_args_count = m_jitdata->args_count - (m_jitdata->has_varargs ? 1u /* excluding format string */ : 0u);
|
||||||
const size_t strbuf_offset = m_jitdata->has_ret ? sizeof(int) * 2u /* orig + over */ : 0u;
|
const size_t strbuf_offset = m_jitdata->rettype != rt_void ? sizeof(int) * 2u /* orig + over */ : 0u;
|
||||||
|
|
||||||
// push formatted buf instead of format string
|
// push formatted buf instead of format string
|
||||||
if (m_jitdata->has_varargs) {
|
if (m_jitdata->has_varargs) {
|
||||||
|
@ -1,13 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define CDATA_ENTRY(s, x, p, h) {#x, offsetof(s, x), (uint8)getArgsCount(decltype(s##::##x)()), !is_void(decltype(s##::##x)()), is_varargs(decltype(s##::##x)()), p, h}
|
#define CDATA_ENTRY(s, x, p, h) {#x, offsetof(s, x), (uint8)getArgsCount(decltype(s##::##x)()), getRetType(decltype(s##::##x)()), is_varargs(decltype(s##::##x)()), p, h}
|
||||||
|
|
||||||
|
enum rettype_t : uint8_t
|
||||||
|
{
|
||||||
|
rt_void,
|
||||||
|
rt_integer,
|
||||||
|
rt_float
|
||||||
|
};
|
||||||
|
|
||||||
struct jitdata_t
|
struct jitdata_t
|
||||||
{
|
{
|
||||||
size_t pfn_original;
|
size_t pfn_original;
|
||||||
size_t pfn_offset; // from fn table
|
size_t pfn_offset; // from fn table
|
||||||
uint8 args_count;
|
uint8 args_count;
|
||||||
bool has_ret;
|
rettype_t rettype;
|
||||||
bool has_varargs;
|
bool has_varargs;
|
||||||
uint8 mm_hook_time;
|
uint8 mm_hook_time;
|
||||||
size_t mm_hook;
|
size_t mm_hook;
|
||||||
@ -26,7 +33,7 @@ struct compile_data_t
|
|||||||
const char* name;
|
const char* name;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
uint8 args_count;
|
uint8 args_count;
|
||||||
bool has_ret;
|
rettype_t rettype;
|
||||||
bool has_varargs;
|
bool has_varargs;
|
||||||
uint8 mm_hook_time;
|
uint8 mm_hook_time;
|
||||||
size_t mm_hook;
|
size_t mm_hook;
|
||||||
@ -45,27 +52,39 @@ size_t getArgsCount(ret_t (*)(t_args..., ...))
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename ...t_args>
|
template<typename ...t_args>
|
||||||
bool is_void(void (*)(t_args...))
|
rettype_t getRetType(void (*)(t_args..., ...))
|
||||||
{
|
{
|
||||||
return true;
|
return rt_void;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ...t_args>
|
template<typename ...t_args>
|
||||||
bool is_void(void (*)(t_args..., ...))
|
rettype_t getRetType(void(*)(t_args...))
|
||||||
{
|
{
|
||||||
return true;
|
return rt_void;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ...t_args>
|
||||||
|
rettype_t getRetType(float (*)(t_args...))
|
||||||
|
{
|
||||||
|
return rt_float;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ...t_args>
|
||||||
|
rettype_t getRetType(double (*)(t_args...))
|
||||||
|
{
|
||||||
|
return rt_float;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ...t_args>
|
||||||
|
rettype_t getRetType(long double (*)(t_args...))
|
||||||
|
{
|
||||||
|
return rt_float;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ret_t, typename ...t_args>
|
template<typename ret_t, typename ...t_args>
|
||||||
bool is_void(ret_t (*)(t_args..., ...))
|
rettype_t getRetType(ret_t (*)(t_args...))
|
||||||
{
|
{
|
||||||
return false;
|
return rt_integer;
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ret_t, typename ...t_args>
|
|
||||||
bool is_void(ret_t (*)(t_args...))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ret_t, typename ...t_args>
|
template<typename ret_t, typename ...t_args>
|
||||||
|
@ -227,7 +227,7 @@ void compile_dllfunc_callbacks()
|
|||||||
for (auto& cd : g_dllfunc_cdata) {
|
for (auto& cd : g_dllfunc_cdata) {
|
||||||
jitdata.pfn_original = *(size_t *)(size_t(g_GameDLL.funcs.dllapi_table) + cd.offset);
|
jitdata.pfn_original = *(size_t *)(size_t(g_GameDLL.funcs.dllapi_table) + cd.offset);
|
||||||
jitdata.args_count = cd.args_count;
|
jitdata.args_count = cd.args_count;
|
||||||
jitdata.has_ret = cd.has_ret;
|
jitdata.rettype = cd.rettype;
|
||||||
jitdata.has_varargs = cd.has_varargs;
|
jitdata.has_varargs = cd.has_varargs;
|
||||||
jitdata.pfn_offset = cd.offset;
|
jitdata.pfn_offset = cd.offset;
|
||||||
jitdata.mm_hook_time = cd.mm_hook_time;
|
jitdata.mm_hook_time = cd.mm_hook_time;
|
||||||
@ -251,7 +251,7 @@ void compile_newdllfunc_callbacks()
|
|||||||
for (auto& cd : g_newdllfunc_cdata) {
|
for (auto& cd : g_newdllfunc_cdata) {
|
||||||
jitdata.pfn_original = g_GameDLL.funcs.newapi_table ? *(size_t *)(size_t(g_GameDLL.funcs.newapi_table) + cd.offset) : 0;
|
jitdata.pfn_original = g_GameDLL.funcs.newapi_table ? *(size_t *)(size_t(g_GameDLL.funcs.newapi_table) + cd.offset) : 0;
|
||||||
jitdata.args_count = cd.args_count;
|
jitdata.args_count = cd.args_count;
|
||||||
jitdata.has_ret = cd.has_ret;
|
jitdata.rettype = cd.rettype;
|
||||||
jitdata.has_varargs = cd.has_varargs;
|
jitdata.has_varargs = cd.has_varargs;
|
||||||
jitdata.pfn_offset = cd.offset;
|
jitdata.pfn_offset = cd.offset;
|
||||||
jitdata.mm_hook_time = cd.mm_hook_time;
|
jitdata.mm_hook_time = cd.mm_hook_time;
|
||||||
|
@ -202,7 +202,7 @@ void compile_engfuncs_callbacks()
|
|||||||
for (auto& cd : g_engfuncs_cdata) {
|
for (auto& cd : g_engfuncs_cdata) {
|
||||||
jitdata.pfn_original = *(size_t *)(size_t(&g_engfuncs) + cd.offset);
|
jitdata.pfn_original = *(size_t *)(size_t(&g_engfuncs) + cd.offset);
|
||||||
jitdata.args_count = cd.args_count;
|
jitdata.args_count = cd.args_count;
|
||||||
jitdata.has_ret = cd.has_ret;
|
jitdata.rettype = cd.rettype;
|
||||||
jitdata.has_varargs = cd.has_varargs;
|
jitdata.has_varargs = cd.has_varargs;
|
||||||
jitdata.pfn_offset = cd.offset;
|
jitdata.pfn_offset = cd.offset;
|
||||||
jitdata.mm_hook_time = cd.mm_hook_time;
|
jitdata.mm_hook_time = cd.mm_hook_time;
|
||||||
|
Loading…
Reference in New Issue
Block a user