mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 23:12:24 +00:00
- remove the need to do any VARF_Native runtime checks by making native functions use the same calling convention as the script version
This commit is contained in:
parent
b6bc06e568
commit
0120ea190c
8 changed files with 68 additions and 157 deletions
|
@ -250,6 +250,14 @@ void JitCompiler::Setup()
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
labels[i] = cc.newLabel();
|
labels[i] = cc.newLabel();
|
||||||
|
|
||||||
|
// VMCalls[0]++
|
||||||
|
auto vmcallsptr = newTempIntPtr();
|
||||||
|
auto vmcalls = newTempInt32();
|
||||||
|
cc.mov(vmcallsptr, imm_ptr(VMCalls));
|
||||||
|
cc.mov(vmcalls, x86::dword_ptr(vmcallsptr));
|
||||||
|
cc.add(vmcalls, (int)1);
|
||||||
|
cc.mov(x86::dword_ptr(vmcallsptr), vmcalls);
|
||||||
|
|
||||||
frameD = cc.newIntPtr();
|
frameD = cc.newIntPtr();
|
||||||
frameF = cc.newIntPtr();
|
frameF = cc.newIntPtr();
|
||||||
frameS = cc.newIntPtr();
|
frameS = cc.newIntPtr();
|
||||||
|
|
|
@ -106,7 +106,6 @@ void JitCompiler::EmitPARAM()
|
||||||
I_FatalError("Unknown REGT value passed to EmitPARAM\n");
|
I_FatalError("Unknown REGT value passed to EmitPARAM\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::EmitPARAMI()
|
void JitCompiler::EmitPARAMI()
|
||||||
|
@ -126,33 +125,29 @@ void JitCompiler::EmitRESULT()
|
||||||
|
|
||||||
void JitCompiler::EmitCALL()
|
void JitCompiler::EmitCALL()
|
||||||
{
|
{
|
||||||
EmitDoCall(regA[A], CallType::Unknown);
|
EmitDoCall(regA[A]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::EmitCALL_K()
|
void JitCompiler::EmitCALL_K()
|
||||||
{
|
{
|
||||||
VMFunction *func = (VMFunction*)konsta[A].o;
|
|
||||||
|
|
||||||
auto ptr = newTempIntPtr();
|
auto ptr = newTempIntPtr();
|
||||||
cc.mov(ptr, asmjit::imm_ptr(func));
|
cc.mov(ptr, asmjit::imm_ptr(konsta[A].o));
|
||||||
EmitDoCall(ptr, (func->VarFlags & VARF_Native) ? CallType::Native : CallType::Script);
|
EmitDoCall(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::EmitTAIL()
|
void JitCompiler::EmitTAIL()
|
||||||
{
|
{
|
||||||
EmitDoTail(regA[A], CallType::Unknown);
|
EmitDoTail(regA[A]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::EmitTAIL_K()
|
void JitCompiler::EmitTAIL_K()
|
||||||
{
|
{
|
||||||
VMFunction *func = (VMFunction*)konsta[A].o;
|
|
||||||
|
|
||||||
auto ptr = newTempIntPtr();
|
auto ptr = newTempIntPtr();
|
||||||
cc.mov(ptr, asmjit::imm_ptr(func));
|
cc.mov(ptr, asmjit::imm_ptr(konsta[A].o));
|
||||||
EmitDoTail(ptr, (func->VarFlags & VARF_Native) ? CallType::Native : CallType::Script);
|
EmitDoTail(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::EmitDoCall(asmjit::X86Gp vmfunc, CallType calltype)
|
void JitCompiler::EmitDoCall(asmjit::X86Gp vmfunc)
|
||||||
{
|
{
|
||||||
using namespace asmjit;
|
using namespace asmjit;
|
||||||
|
|
||||||
|
@ -173,28 +168,7 @@ void JitCompiler::EmitDoCall(asmjit::X86Gp vmfunc, CallType calltype)
|
||||||
paramsptr = params;
|
paramsptr = params;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (calltype == CallType::Script)
|
EmitScriptCall(vmfunc, paramsptr);
|
||||||
{
|
|
||||||
EmitScriptCall(vmfunc, paramsptr);
|
|
||||||
}
|
|
||||||
else if (calltype == CallType::Native)
|
|
||||||
{
|
|
||||||
EmitNativeCall(vmfunc, paramsptr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto nativecall = cc.newLabel();
|
|
||||||
auto endcall = cc.newLabel();
|
|
||||||
auto varflags = newTempInt32();
|
|
||||||
cc.mov(varflags, x86::dword_ptr(vmfunc, offsetof(VMFunction, VarFlags)));
|
|
||||||
cc.test(varflags, (int)VARF_Native);
|
|
||||||
cc.jnz(nativecall);
|
|
||||||
EmitScriptCall(vmfunc, paramsptr);
|
|
||||||
cc.jmp(endcall);
|
|
||||||
cc.bind(nativecall);
|
|
||||||
EmitNativeCall(vmfunc, paramsptr);
|
|
||||||
cc.bind(endcall);
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadInOuts(B);
|
LoadInOuts(B);
|
||||||
LoadReturns(pc + 1, C);
|
LoadReturns(pc + 1, C);
|
||||||
|
@ -207,14 +181,6 @@ void JitCompiler::EmitScriptCall(asmjit::X86Gp vmfunc, asmjit::X86Gp paramsptr)
|
||||||
{
|
{
|
||||||
using namespace asmjit;
|
using namespace asmjit;
|
||||||
|
|
||||||
// VMCalls[0]++
|
|
||||||
auto vmcallsptr = newTempIntPtr();
|
|
||||||
auto vmcalls = newTempInt32();
|
|
||||||
cc.mov(vmcallsptr, imm_ptr(VMCalls));
|
|
||||||
cc.mov(vmcalls, x86::dword_ptr(vmcallsptr));
|
|
||||||
cc.add(vmcalls, (int)1);
|
|
||||||
cc.mov(x86::dword_ptr(vmcallsptr), vmcalls);
|
|
||||||
|
|
||||||
auto scriptcall = newTempIntPtr();
|
auto scriptcall = newTempIntPtr();
|
||||||
cc.mov(scriptcall, x86::ptr(vmfunc, offsetof(VMScriptFunction, ScriptCall)));
|
cc.mov(scriptcall, x86::ptr(vmfunc, offsetof(VMScriptFunction, ScriptCall)));
|
||||||
|
|
||||||
|
@ -228,20 +194,7 @@ void JitCompiler::EmitScriptCall(asmjit::X86Gp vmfunc, asmjit::X86Gp paramsptr)
|
||||||
call->setArg(4, Imm(C));
|
call->setArg(4, Imm(C));
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::EmitNativeCall(asmjit::X86Gp vmfunc, asmjit::X86Gp paramsptr)
|
void JitCompiler::EmitDoTail(asmjit::X86Gp vmfunc)
|
||||||
{
|
|
||||||
using namespace asmjit;
|
|
||||||
auto result = newResultInt32();
|
|
||||||
auto call = CreateCall<int, VMFunction*, int, int, VMValue*, VMReturn*>(&JitCompiler::DoNativeCall);
|
|
||||||
call->setRet(0, result);
|
|
||||||
call->setArg(0, vmfunc);
|
|
||||||
call->setArg(1, Imm(B));
|
|
||||||
call->setArg(2, Imm(C));
|
|
||||||
call->setArg(3, paramsptr);
|
|
||||||
call->setArg(4, callReturns);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JitCompiler::EmitDoTail(asmjit::X86Gp vmfunc, CallType calltype)
|
|
||||||
{
|
{
|
||||||
// Whereas the CALL instruction uses its third operand to specify how many return values
|
// Whereas the CALL instruction uses its third operand to specify how many return values
|
||||||
// it expects, TAIL ignores its third operand and uses whatever was passed to this Exec call.
|
// it expects, TAIL ignores its third operand and uses whatever was passed to this Exec call.
|
||||||
|
@ -268,28 +221,7 @@ void JitCompiler::EmitDoTail(asmjit::X86Gp vmfunc, CallType calltype)
|
||||||
|
|
||||||
auto result = newResultInt32();
|
auto result = newResultInt32();
|
||||||
|
|
||||||
if (calltype == CallType::Script)
|
EmitScriptTailCall(vmfunc, result, paramsptr);
|
||||||
{
|
|
||||||
EmitScriptTailCall(vmfunc, result, paramsptr);
|
|
||||||
}
|
|
||||||
else if (calltype == CallType::Native)
|
|
||||||
{
|
|
||||||
EmitNativeTailCall(vmfunc, result, paramsptr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto nativecall = cc.newLabel();
|
|
||||||
auto endcall = cc.newLabel();
|
|
||||||
auto varflags = newTempInt32();
|
|
||||||
cc.mov(varflags, x86::dword_ptr(vmfunc, offsetof(VMFunction, VarFlags)));
|
|
||||||
cc.test(varflags, (int)VARF_Native);
|
|
||||||
cc.jnz(nativecall);
|
|
||||||
EmitScriptTailCall(vmfunc, result, paramsptr);
|
|
||||||
cc.jmp(endcall);
|
|
||||||
cc.bind(nativecall);
|
|
||||||
EmitNativeTailCall(vmfunc, result, paramsptr);
|
|
||||||
cc.bind(endcall);
|
|
||||||
}
|
|
||||||
|
|
||||||
EmitPopFrame();
|
EmitPopFrame();
|
||||||
cc.ret(result);
|
cc.ret(result);
|
||||||
|
@ -302,14 +234,6 @@ void JitCompiler::EmitScriptTailCall(asmjit::X86Gp vmfunc, asmjit::X86Gp result,
|
||||||
{
|
{
|
||||||
using namespace asmjit;
|
using namespace asmjit;
|
||||||
|
|
||||||
// VMCalls[0]++
|
|
||||||
auto vmcallsptr = newTempIntPtr();
|
|
||||||
auto vmcalls = newTempInt32();
|
|
||||||
cc.mov(vmcallsptr, imm_ptr(VMCalls));
|
|
||||||
cc.mov(vmcalls, x86::dword_ptr(vmcallsptr));
|
|
||||||
cc.add(vmcalls, (int)1);
|
|
||||||
cc.mov(x86::dword_ptr(vmcallsptr), vmcalls);
|
|
||||||
|
|
||||||
auto scriptcall = newTempIntPtr();
|
auto scriptcall = newTempIntPtr();
|
||||||
cc.mov(scriptcall, x86::ptr(vmfunc, offsetof(VMScriptFunction, ScriptCall)));
|
cc.mov(scriptcall, x86::ptr(vmfunc, offsetof(VMScriptFunction, ScriptCall)));
|
||||||
|
|
||||||
|
@ -322,19 +246,6 @@ void JitCompiler::EmitScriptTailCall(asmjit::X86Gp vmfunc, asmjit::X86Gp result,
|
||||||
call->setArg(4, numret);
|
call->setArg(4, numret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::EmitNativeTailCall(asmjit::X86Gp vmfunc, asmjit::X86Gp result, asmjit::X86Gp paramsptr)
|
|
||||||
{
|
|
||||||
using namespace asmjit;
|
|
||||||
|
|
||||||
auto call = CreateCall<int, VMFunction*, int, int, VMValue*, VMReturn*>(&JitCompiler::DoNativeCall);
|
|
||||||
call->setRet(0, result);
|
|
||||||
call->setArg(0, vmfunc);
|
|
||||||
call->setArg(1, Imm(B));
|
|
||||||
call->setArg(2, numret);
|
|
||||||
call->setArg(3, paramsptr);
|
|
||||||
call->setArg(4, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JitCompiler::StoreInOuts(int b)
|
void JitCompiler::StoreInOuts(int b)
|
||||||
{
|
{
|
||||||
using namespace asmjit;
|
using namespace asmjit;
|
||||||
|
@ -497,29 +408,3 @@ void JitCompiler::FillReturns(const VMOP *retval, int numret)
|
||||||
cc.mov(x86::byte_ptr(callReturns, i * sizeof(VMReturn) + offsetof(VMReturn, RegType)), type);
|
cc.mov(x86::byte_ptr(callReturns, i * sizeof(VMReturn) + offsetof(VMReturn, RegType)), type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int JitCompiler::DoNativeCall(VMFunction *call, int b, int c, VMValue *param, VMReturn *returns)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
assert((call->VarFlags & VARF_Native) && "DoNativeCall must only be called for native functions");
|
|
||||||
|
|
||||||
VMCycles[0].Unclock();
|
|
||||||
int numret = static_cast<VMNativeFunction *>(call)->NativeCall(param, call->DefaultArgs, b, returns, c);
|
|
||||||
VMCycles[0].Clock();
|
|
||||||
|
|
||||||
return numret;
|
|
||||||
}
|
|
||||||
catch (CVMAbortException &err)
|
|
||||||
{
|
|
||||||
err.MaybePrintMessage();
|
|
||||||
err.stacktrace.AppendFormat("Called from %s\n", call->PrintableName.GetChars());
|
|
||||||
VMThrowException(std::current_exception());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
VMThrowException(std::current_exception());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -42,20 +42,11 @@ private:
|
||||||
void EmitOpcode();
|
void EmitOpcode();
|
||||||
void EmitPopFrame();
|
void EmitPopFrame();
|
||||||
|
|
||||||
enum class CallType
|
void EmitDoCall(asmjit::X86Gp ptr);
|
||||||
{
|
|
||||||
Unknown,
|
|
||||||
Script,
|
|
||||||
Native
|
|
||||||
};
|
|
||||||
|
|
||||||
void EmitDoCall(asmjit::X86Gp ptr, CallType calltype);
|
|
||||||
void EmitScriptCall(asmjit::X86Gp vmfunc, asmjit::X86Gp paramsptr);
|
void EmitScriptCall(asmjit::X86Gp vmfunc, asmjit::X86Gp paramsptr);
|
||||||
void EmitNativeCall(asmjit::X86Gp vmfunc, asmjit::X86Gp paramsptr);
|
|
||||||
|
|
||||||
void EmitDoTail(asmjit::X86Gp ptr, CallType calltype);
|
void EmitDoTail(asmjit::X86Gp ptr);
|
||||||
void EmitScriptTailCall(asmjit::X86Gp vmfunc, asmjit::X86Gp result, asmjit::X86Gp paramsptr);
|
void EmitScriptTailCall(asmjit::X86Gp vmfunc, asmjit::X86Gp result, asmjit::X86Gp paramsptr);
|
||||||
void EmitNativeTailCall(asmjit::X86Gp vmfunc, asmjit::X86Gp result, asmjit::X86Gp paramsptr);
|
|
||||||
|
|
||||||
void StoreInOuts(int b);
|
void StoreInOuts(int b);
|
||||||
void LoadInOuts(int b);
|
void LoadInOuts(int b);
|
||||||
|
@ -63,8 +54,6 @@ private:
|
||||||
void FillReturns(const VMOP *retval, int numret);
|
void FillReturns(const VMOP *retval, int numret);
|
||||||
void LoadCallResult(const VMOP &opdata, bool addrof);
|
void LoadCallResult(const VMOP &opdata, bool addrof);
|
||||||
|
|
||||||
static int DoNativeCall(VMFunction *call, int b, int c, VMValue *param, VMReturn *returns);
|
|
||||||
|
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
void EmitComparisonOpcode(Func jmpFunc)
|
void EmitComparisonOpcode(Func jmpFunc)
|
||||||
{
|
{
|
||||||
|
|
|
@ -330,6 +330,8 @@ public:
|
||||||
|
|
||||||
class PPrototype *Proto;
|
class PPrototype *Proto;
|
||||||
|
|
||||||
|
int(*ScriptCall)(VMFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret) = nullptr;
|
||||||
|
|
||||||
VMFunction(FName name = NAME_None) : ImplicitArgs(0), Name(name), Proto(NULL)
|
VMFunction(FName name = NAME_None) : ImplicitArgs(0), Name(name), Proto(NULL)
|
||||||
{
|
{
|
||||||
AllFunctions.Push(this);
|
AllFunctions.Push(this);
|
||||||
|
@ -361,12 +363,15 @@ public:
|
||||||
typedef int (*NativeCallType)(VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret);
|
typedef int (*NativeCallType)(VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret);
|
||||||
|
|
||||||
// 8 is VARF_Native. I can't write VARF_Native because of circular references between this and dobject/dobjtype.
|
// 8 is VARF_Native. I can't write VARF_Native because of circular references between this and dobject/dobjtype.
|
||||||
VMNativeFunction() : NativeCall(NULL) { VarFlags = 8; }
|
VMNativeFunction() : NativeCall(NULL) { VarFlags = 8; ScriptCall = &VMNativeFunction::NativeScriptCall; }
|
||||||
VMNativeFunction(NativeCallType call) : NativeCall(call) { VarFlags = 8; }
|
VMNativeFunction(NativeCallType call) : NativeCall(call) { VarFlags = 8; ScriptCall = &VMNativeFunction::NativeScriptCall; }
|
||||||
VMNativeFunction(NativeCallType call, FName name) : VMFunction(name), NativeCall(call) { VarFlags = 8; }
|
VMNativeFunction(NativeCallType call, FName name) : VMFunction(name), NativeCall(call) { VarFlags = 8; ScriptCall = &VMNativeFunction::NativeScriptCall; }
|
||||||
|
|
||||||
// Return value is the number of results.
|
// Return value is the number of results.
|
||||||
NativeCallType NativeCall;
|
NativeCallType NativeCall;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static int NativeScriptCall(VMFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret);
|
||||||
};
|
};
|
||||||
|
|
||||||
int VMCall(VMFunction *func, VMValue *params, int numparams, VMReturn *results, int numresults/*, VMException **trap = NULL*/);
|
int VMCall(VMFunction *func, VMValue *params, int numparams, VMReturn *results, int numresults/*, VMException **trap = NULL*/);
|
||||||
|
|
|
@ -134,7 +134,7 @@ struct VMExec_Unchecked
|
||||||
#undef assert
|
#undef assert
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
int (*VMExec)(VMScriptFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret) =
|
int (*VMExec)(VMFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret) =
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
VMExec_Unchecked::Exec
|
VMExec_Unchecked::Exec
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -710,7 +710,6 @@ static int ExecScriptFunc(VMFrameStack *stack, VMReturn *ret, int numret)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VMCalls[0]++;
|
|
||||||
auto sfunc = static_cast<VMScriptFunction *>(call);
|
auto sfunc = static_cast<VMScriptFunction *>(call);
|
||||||
numret = sfunc->ScriptCall(sfunc, reg.param + f->NumParam - b, b, returns, C);
|
numret = sfunc->ScriptCall(sfunc, reg.param + f->NumParam - b, b, returns, C);
|
||||||
}
|
}
|
||||||
|
@ -753,7 +752,6 @@ static int ExecScriptFunc(VMFrameStack *stack, VMReturn *ret, int numret)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // FIXME: Not a true tail call
|
{ // FIXME: Not a true tail call
|
||||||
VMCalls[0]++;
|
|
||||||
auto sfunc = static_cast<VMScriptFunction *>(call);
|
auto sfunc = static_cast<VMScriptFunction *>(call);
|
||||||
return sfunc->ScriptCall(sfunc, reg.param + f->NumParam - B, B, ret, numret);
|
return sfunc->ScriptCall(sfunc, reg.param + f->NumParam - B, B, ret, numret);
|
||||||
}
|
}
|
||||||
|
@ -2046,10 +2044,11 @@ static void SetReturn(const VMRegisters ®, VMFrame *frame, VMReturn *ret, VM_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Exec(VMScriptFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret)
|
static int Exec(VMFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret)
|
||||||
{
|
{
|
||||||
|
VMCalls[0]++;
|
||||||
VMFrameStack *stack = &GlobalVMStack;
|
VMFrameStack *stack = &GlobalVMStack;
|
||||||
VMFrame *newf = stack->AllocFrame(func);
|
VMFrame *newf = stack->AllocFrame(static_cast<VMScriptFunction*>(func));
|
||||||
VMFillParams(params, newf, numparams);
|
VMFillParams(params, newf, numparams);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -74,6 +74,7 @@ VMScriptFunction::VMScriptFunction(FName name)
|
||||||
NumKonstA = 0;
|
NumKonstA = 0;
|
||||||
MaxParam = 0;
|
MaxParam = 0;
|
||||||
NumArgs = 0;
|
NumArgs = 0;
|
||||||
|
ScriptCall = &VMScriptFunction::FirstScriptCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
VMScriptFunction::~VMScriptFunction()
|
VMScriptFunction::~VMScriptFunction()
|
||||||
|
@ -213,17 +214,44 @@ int VMScriptFunction::PCToLine(const VMOP *pc)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VMScriptFunction::FirstScriptCall(VMScriptFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret)
|
int VMScriptFunction::FirstScriptCall(VMFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret)
|
||||||
{
|
{
|
||||||
func->ScriptCall = JitCompile(func);
|
VMScriptFunction *sfunc = static_cast<VMScriptFunction*>(func);
|
||||||
if (!func->ScriptCall)
|
sfunc->ScriptCall = JitCompile(sfunc);
|
||||||
func->ScriptCall = VMExec;
|
if (!sfunc->ScriptCall)
|
||||||
|
sfunc->ScriptCall = VMExec;
|
||||||
else
|
else
|
||||||
func->FunctionJitted = true;
|
sfunc->FunctionJitted = true;
|
||||||
|
|
||||||
return func->ScriptCall(func, params, numparams, ret, numret);
|
return func->ScriptCall(func, params, numparams, ret, numret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int VMNativeFunction::NativeScriptCall(VMFunction *func, VMValue *params, int numparams, VMReturn *returns, int numret)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
assert((call->VarFlags & VARF_Native) && "DoNativeCall must only be called for native functions");
|
||||||
|
|
||||||
|
VMCycles[0].Unclock();
|
||||||
|
numret = static_cast<VMNativeFunction *>(func)->NativeCall(params, func->DefaultArgs, numparams, returns, numret);
|
||||||
|
VMCycles[0].Clock();
|
||||||
|
|
||||||
|
return numret;
|
||||||
|
}
|
||||||
|
catch (CVMAbortException &err)
|
||||||
|
{
|
||||||
|
err.MaybePrintMessage();
|
||||||
|
err.stacktrace.AppendFormat("Called from %s\n", func->PrintableName.GetChars());
|
||||||
|
VMThrowException(std::current_exception());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
VMThrowException(std::current_exception());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// VMFrame :: InitRegS
|
// VMFrame :: InitRegS
|
||||||
|
@ -500,7 +528,6 @@ int VMCall(VMFunction *func, VMValue *params, int numparams, VMReturn *results,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VMCycles[0].Clock();
|
VMCycles[0].Clock();
|
||||||
VMCalls[0]++;
|
|
||||||
|
|
||||||
JitExceptionInfo *prevExceptInfo = CurrentJitExceptInfo;
|
JitExceptionInfo *prevExceptInfo = CurrentJitExceptInfo;
|
||||||
JitExceptionInfo newExceptInfo;
|
JitExceptionInfo newExceptInfo;
|
||||||
|
|
|
@ -429,7 +429,7 @@ enum EVMEngine
|
||||||
};
|
};
|
||||||
|
|
||||||
void VMSelectEngine(EVMEngine engine);
|
void VMSelectEngine(EVMEngine engine);
|
||||||
extern int (*VMExec)(VMScriptFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret);
|
extern int (*VMExec)(VMFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret);
|
||||||
void VMFillParams(VMValue *params, VMFrame *callee, int numparam);
|
void VMFillParams(VMValue *params, VMFrame *callee, int numparam);
|
||||||
|
|
||||||
void VMDumpConstants(FILE *out, const VMScriptFunction *func);
|
void VMDumpConstants(FILE *out, const VMScriptFunction *func);
|
||||||
|
@ -450,7 +450,7 @@ extern thread_local JitExceptionInfo *CurrentJitExceptInfo;
|
||||||
|
|
||||||
void VMThrowException(std::exception_ptr cppException);
|
void VMThrowException(std::exception_ptr cppException);
|
||||||
|
|
||||||
typedef int(*JitFuncPtr)(VMScriptFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret);
|
typedef int(*JitFuncPtr)(VMFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret);
|
||||||
|
|
||||||
class VMScriptFunction : public VMFunction
|
class VMScriptFunction : public VMFunction
|
||||||
{
|
{
|
||||||
|
@ -482,15 +482,13 @@ public:
|
||||||
VM_UBYTE NumArgs; // Number of arguments this function takes
|
VM_UBYTE NumArgs; // Number of arguments this function takes
|
||||||
TArray<FTypeAndOffset> SpecialInits; // list of all contents on the extra stack which require construction and destruction
|
TArray<FTypeAndOffset> SpecialInits; // list of all contents on the extra stack which require construction and destruction
|
||||||
|
|
||||||
int(*ScriptCall)(VMScriptFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret) = &VMScriptFunction::FirstScriptCall;
|
|
||||||
|
|
||||||
void InitExtra(void *addr);
|
void InitExtra(void *addr);
|
||||||
void DestroyExtra(void *addr);
|
void DestroyExtra(void *addr);
|
||||||
int AllocExtraStack(PType *type);
|
int AllocExtraStack(PType *type);
|
||||||
int PCToLine(const VMOP *pc);
|
int PCToLine(const VMOP *pc);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int FirstScriptCall(VMScriptFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret);
|
static int FirstScriptCall(VMFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret);
|
||||||
|
|
||||||
bool FunctionJitted = false;
|
bool FunctionJitted = false;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue