mirror of
https://github.com/rehlds/metamod-r.git
synced 2024-12-26 14:45: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 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);
|
||||
|
||||
if (m_jitdata->has_varargs) {
|
||||
@ -115,7 +115,7 @@ void CForwardCallbackJIT::naked_main()
|
||||
mov(dword_ptr[globals + mg_esp_save], esp);
|
||||
|
||||
// setup retval pointers
|
||||
if (m_jitdata->has_ret) {
|
||||
if (m_jitdata->rettype != rt_void) {
|
||||
lea(eax, dword_ptr[esp + over_ret]);
|
||||
mov(dword_ptr[globals + mg_orig_ret], esp);
|
||||
mov(dword_ptr[globals + mg_over_ret], eax);
|
||||
@ -160,7 +160,13 @@ void CForwardCallbackJIT::naked_main()
|
||||
mov(dword_ptr[globals + mg_status], ecx);
|
||||
|
||||
// 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]);
|
||||
cmp(edx, MRES_OVERRIDE);
|
||||
cmovae(ecx, eax);
|
||||
@ -181,7 +187,7 @@ void CForwardCallbackJIT::naked_main()
|
||||
}
|
||||
|
||||
// store original return value
|
||||
if (m_jitdata->has_ret) {
|
||||
if (m_jitdata->rettype == rt_integer) {
|
||||
if (m_jitdata->pfn_original)
|
||||
mov(dword_ptr[esp + orig_ret], eax);
|
||||
else
|
||||
@ -189,10 +195,18 @@ void CForwardCallbackJIT::naked_main()
|
||||
|
||||
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");
|
||||
{
|
||||
if (m_jitdata->has_ret) {
|
||||
if (m_jitdata->rettype != rt_void) {
|
||||
// if supercede
|
||||
mov(eax, dword_ptr[esp + over_ret]);
|
||||
mov(dword_ptr[esp + orig_ret], eax);
|
||||
@ -241,7 +255,13 @@ void CForwardCallbackJIT::naked_main()
|
||||
mov(dword_ptr[globals + mg_status], ecx);
|
||||
|
||||
// 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);
|
||||
mov(ecx, dword_ptr[esp + over_ret]);
|
||||
cmovae(ecx, eax);
|
||||
@ -264,11 +284,17 @@ void CForwardCallbackJIT::naked_main()
|
||||
movq(qword_ptr[globals + xmmreg_size], xmm1);
|
||||
|
||||
// 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]);
|
||||
cmp(dword_ptr[globals + mg_status], MRES_OVERRIDE);
|
||||
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
|
||||
mov(esp, ebp);
|
||||
@ -280,7 +306,7 @@ void CForwardCallbackJIT::naked_main()
|
||||
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 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
|
||||
if (m_jitdata->has_varargs) {
|
||||
|
@ -1,13 +1,20 @@
|
||||
#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
|
||||
{
|
||||
size_t pfn_original;
|
||||
size_t pfn_offset; // from fn table
|
||||
uint8 args_count;
|
||||
bool has_ret;
|
||||
rettype_t rettype;
|
||||
bool has_varargs;
|
||||
uint8 mm_hook_time;
|
||||
size_t mm_hook;
|
||||
@ -26,7 +33,7 @@ struct compile_data_t
|
||||
const char* name;
|
||||
size_t offset;
|
||||
uint8 args_count;
|
||||
bool has_ret;
|
||||
rettype_t rettype;
|
||||
bool has_varargs;
|
||||
uint8 mm_hook_time;
|
||||
size_t mm_hook;
|
||||
@ -45,27 +52,39 @@ size_t getArgsCount(ret_t (*)(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>
|
||||
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>
|
||||
bool is_void(ret_t (*)(t_args..., ...))
|
||||
rettype_t getRetType(ret_t (*)(t_args...))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename ret_t, typename ...t_args>
|
||||
bool is_void(ret_t (*)(t_args...))
|
||||
{
|
||||
return false;
|
||||
return rt_integer;
|
||||
}
|
||||
|
||||
template<typename ret_t, typename ...t_args>
|
||||
|
@ -227,7 +227,7 @@ void compile_dllfunc_callbacks()
|
||||
for (auto& cd : g_dllfunc_cdata) {
|
||||
jitdata.pfn_original = *(size_t *)(size_t(g_GameDLL.funcs.dllapi_table) + cd.offset);
|
||||
jitdata.args_count = cd.args_count;
|
||||
jitdata.has_ret = cd.has_ret;
|
||||
jitdata.rettype = cd.rettype;
|
||||
jitdata.has_varargs = cd.has_varargs;
|
||||
jitdata.pfn_offset = cd.offset;
|
||||
jitdata.mm_hook_time = cd.mm_hook_time;
|
||||
@ -251,7 +251,7 @@ void compile_newdllfunc_callbacks()
|
||||
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.args_count = cd.args_count;
|
||||
jitdata.has_ret = cd.has_ret;
|
||||
jitdata.rettype = cd.rettype;
|
||||
jitdata.has_varargs = cd.has_varargs;
|
||||
jitdata.pfn_offset = cd.offset;
|
||||
jitdata.mm_hook_time = cd.mm_hook_time;
|
||||
|
@ -202,7 +202,7 @@ void compile_engfuncs_callbacks()
|
||||
for (auto& cd : g_engfuncs_cdata) {
|
||||
jitdata.pfn_original = *(size_t *)(size_t(&g_engfuncs) + cd.offset);
|
||||
jitdata.args_count = cd.args_count;
|
||||
jitdata.has_ret = cd.has_ret;
|
||||
jitdata.rettype = cd.rettype;
|
||||
jitdata.has_varargs = cd.has_varargs;
|
||||
jitdata.pfn_offset = cd.offset;
|
||||
jitdata.mm_hook_time = cd.mm_hook_time;
|
||||
|
Loading…
Reference in New Issue
Block a user