diff --git a/src/scripting/vm/jit_call.cpp b/src/scripting/vm/jit_call.cpp index 94958fbc0..82c6d5ea3 100644 --- a/src/scripting/vm/jit_call.cpp +++ b/src/scripting/vm/jit_call.cpp @@ -417,7 +417,8 @@ int JitCompiler::DoCall(VMFrameStack *stack, VMFunction *call, int b, int c, VMV else { VMCalls[0]++; - numret = VMExec(static_cast(call), param, b, returns, c); + auto sfunc = static_cast(call); + numret = sfunc->ScriptCall(sfunc, param, b, returns, c); } return numret; diff --git a/src/scripting/vm/vmexec.cpp b/src/scripting/vm/vmexec.cpp index c7284d7f3..e40de0378 100644 --- a/src/scripting/vm/vmexec.cpp +++ b/src/scripting/vm/vmexec.cpp @@ -41,7 +41,6 @@ #include "math/cmath.h" #include "stats.h" #include "vmintern.h" -#include "jit.h" #include "types.h" extern cycle_t VMCycles[10]; diff --git a/src/scripting/vm/vmexec.h b/src/scripting/vm/vmexec.h index 3a93152a5..dafa2bed8 100644 --- a/src/scripting/vm/vmexec.h +++ b/src/scripting/vm/vmexec.h @@ -711,7 +711,8 @@ static int ExecScriptFunc(VMFrameStack *stack, VMReturn *ret, int numret) else { VMCalls[0]++; - numret = Exec(static_cast(call), reg.param + f->NumParam - b, b, returns, C); + auto sfunc = static_cast(call); + numret = sfunc->ScriptCall(sfunc, reg.param + f->NumParam - b, b, returns, C); } assert(numret == C && "Number of parameters returned differs from what was expected by the caller"); f->NumParam -= B; @@ -753,7 +754,8 @@ static int ExecScriptFunc(VMFrameStack *stack, VMReturn *ret, int numret) else { // FIXME: Not a true tail call VMCalls[0]++; - return Exec(static_cast(call), reg.param + f->NumParam - B, B, ret, numret); + auto sfunc = static_cast(call); + return sfunc->ScriptCall(sfunc, reg.param + f->NumParam - B, B, ret, numret); } } NEXTOP; @@ -2051,26 +2053,6 @@ static int Exec(VMScriptFunction *func, VMValue *params, int numparams, VMReturn VMFillParams(params, newf, numparams); try { - if (!func->JitCompiled) - { - func->JitFunc = JitCompile(func); - func->JitCompiled = true; - } - if (func->JitFunc) - { - JitExceptionInfo exceptInfo; - exceptInfo.reason = -1; - int result = func->JitFunc(stack, ret, numret, &exceptInfo); - if (exceptInfo.reason != -1) - { - if (exceptInfo.cppException) - std::rethrow_exception(exceptInfo.cppException); - else - ThrowAbortException(func, exceptInfo.pcOnJitAbort, (EVMAbortException)exceptInfo.reason, nullptr); - } - return result; - } - numret = ExecScriptFunc(stack, ret, numret); } catch (...) diff --git a/src/scripting/vm/vmframe.cpp b/src/scripting/vm/vmframe.cpp index 6045de5e7..e6c00209d 100644 --- a/src/scripting/vm/vmframe.cpp +++ b/src/scripting/vm/vmframe.cpp @@ -217,6 +217,45 @@ int VMScriptFunction::PCToLine(const VMOP *pc) return -1; } +int VMScriptFunction::FirstScriptCall(VMScriptFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret) +{ + func->JitFunc = JitCompile(func); + if (func->JitFunc) + func->ScriptCall = &VMScriptFunction::JitCall; + else + func->ScriptCall = VMExec; + + return func->ScriptCall(func, params, numparams, ret, numret); +} + +int VMScriptFunction::JitCall(VMScriptFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret) +{ + VMFrameStack *stack = &GlobalVMStack; + VMFrame *newf = stack->AllocFrame(func); + VMFillParams(params, newf, numparams); + try + { + JitExceptionInfo exceptInfo; + exceptInfo.reason = -1; + int result = func->JitFunc(stack, ret, numret, &exceptInfo); + if (exceptInfo.reason != -1) + { + if (exceptInfo.cppException) + std::rethrow_exception(exceptInfo.cppException); + else + ThrowAbortException(func, exceptInfo.pcOnJitAbort, (EVMAbortException)exceptInfo.reason, nullptr); + } + return result; + } + catch (...) + { + stack->PopFrame(); + throw; + } + stack->PopFrame(); + return numret; +} + //=========================================================================== // // VMFrame :: InitRegS @@ -475,7 +514,8 @@ int VMCall(VMFunction *func, VMValue *params, int numparams, VMReturn *results, { VMCycles[0].Clock(); VMCalls[0]++; - int numret = VMExec(static_cast(func), params, numparams, results, numresults); + auto sfunc = static_cast(func); + int numret = sfunc->ScriptCall(sfunc, params, numparams, results, numresults); VMCycles[0].Unclock(); return numret; } diff --git a/src/scripting/vm/vmintern.h b/src/scripting/vm/vmintern.h index 5662d74bc..38003f8dd 100644 --- a/src/scripting/vm/vmintern.h +++ b/src/scripting/vm/vmintern.h @@ -482,11 +482,15 @@ public: VM_UBYTE NumArgs; // Number of arguments this function takes TArray SpecialInits; // list of all contents on the extra stack which require construction and destruction - bool JitCompiled = false; - JitFuncPtr JitFunc = nullptr; + int(*ScriptCall)(VMScriptFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret) = &VMScriptFunction::FirstScriptCall; void InitExtra(void *addr); void DestroyExtra(void *addr); int AllocExtraStack(PType *type); int PCToLine(const VMOP *pc); + +private: + static int FirstScriptCall(VMScriptFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret); + static int JitCall(VMScriptFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret); + JitFuncPtr JitFunc = nullptr; };