diff --git a/src/scripting/vm/jit_call.cpp b/src/scripting/vm/jit_call.cpp index ddd7810e00..94958fbc04 100644 --- a/src/scripting/vm/jit_call.cpp +++ b/src/scripting/vm/jit_call.cpp @@ -417,19 +417,7 @@ int JitCompiler::DoCall(VMFrameStack *stack, VMFunction *call, int b, int c, VMV else { VMCalls[0]++; - VMScriptFunction *script = static_cast(call); - VMFrame *newf = stack->AllocFrame(script); - VMFillParams(param, newf, b); - try - { - numret = VMExec(stack, script->Code, returns, c); - } - catch (...) - { - stack->PopFrame(); - throw; - } - stack->PopFrame(); + numret = VMExec(static_cast(call), param, b, returns, c); } return numret; diff --git a/src/scripting/vm/vmexec.cpp b/src/scripting/vm/vmexec.cpp index 0fc5e19088..bfe5b5d323 100644 --- a/src/scripting/vm/vmexec.cpp +++ b/src/scripting/vm/vmexec.cpp @@ -135,7 +135,7 @@ struct VMExec_Unchecked #undef assert #include -int (*VMExec)(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret) = +int (*VMExec)(VMScriptFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret) = #ifdef NDEBUG VMExec_Unchecked::Exec #else diff --git a/src/scripting/vm/vmexec.h b/src/scripting/vm/vmexec.h index d75c898a63..df5efb210d 100644 --- a/src/scripting/vm/vmexec.h +++ b/src/scripting/vm/vmexec.h @@ -37,7 +37,7 @@ #error vmexec.h must not be #included outside vmexec.cpp. Use vm.h instead. #endif -static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret) +static int ExecScriptFunc(VMFrameStack *stack, VMReturn *ret, int numret) { #if COMPGOTO static const void * const ops[256] = @@ -49,51 +49,14 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret) //const VMOP *exception_frames[MAX_TRY_DEPTH]; //int try_depth = 0; VMFrame *f = stack->TopFrame(); - VMScriptFunction *sfunc; - const int *konstd; - const double *konstf; - const FString *konsts; - const FVoidObj *konsta; + VMScriptFunction *sfunc = static_cast(f->Func); + const int *konstd = sfunc->KonstD; + const double *konstf = sfunc->KonstF; + const FString *konsts = sfunc->KonstS; + const FVoidObj *konsta = sfunc->KonstA; + const VMOP *pc = sfunc->Code; - if (f->Func != NULL && !(f->Func->VarFlags & VARF_Native)) - { - sfunc = static_cast(f->Func); - konstd = sfunc->KonstD; - konstf = sfunc->KonstF; - konsts = sfunc->KonstS; - konsta = sfunc->KonstA; - } - else - { - sfunc = NULL; - konstd = NULL; - konstf = NULL; - konsts = NULL; - konsta = NULL; - } - - if (sfunc && sfunc->Code == pc) - { - if (!sfunc->JitCompiled) - { - sfunc->JitFunc = JitCompile(sfunc); - sfunc->JitCompiled = true; - } - if (sfunc->JitFunc) - { - JitExceptionInfo exceptInfo; - exceptInfo.reason = -1; - int result = sfunc->JitFunc(stack, ret, numret, &exceptInfo); - if (exceptInfo.reason != -1) - { - if (exceptInfo.cppException) - std::rethrow_exception(exceptInfo.cppException); - else - ThrowAbortException(sfunc, exceptInfo.pcOnJitAbort, (EVMAbortException)exceptInfo.reason, nullptr); - } - return result; - } - } + assert(!(f->Func->VarFlags & VARF_Native) && "Only script functions should ever reach VMExec"); const VMRegisters reg(f); @@ -748,19 +711,7 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret) else { VMCalls[0]++; - VMScriptFunction *script = static_cast(call); - VMFrame *newf = stack->AllocFrame(script); - VMFillParams(reg.param + f->NumParam - b, newf, b); - try - { - numret = Exec(stack, script->Code, returns, C); - } - catch(...) - { - stack->PopFrame(); - throw; - } - stack->PopFrame(); + numret = Exec(static_cast(call), 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; @@ -802,20 +753,7 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret) else { // FIXME: Not a true tail call VMCalls[0]++; - VMScriptFunction *script = static_cast(call); - VMFrame *newf = stack->AllocFrame(script); - VMFillParams(reg.param + f->NumParam - B, newf, B); - try - { - numret = Exec(stack, script->Code, ret, numret); - } - catch(...) - { - stack->PopFrame(); - throw; - } - stack->PopFrame(); - return numret; + return Exec(static_cast(call), reg.param + f->NumParam - B, B, ret, numret); } } NEXTOP; @@ -2105,3 +2043,41 @@ static void SetReturn(const VMRegisters ®, VMFrame *frame, VMReturn *ret, VM_ break; } } + +static int Exec(VMScriptFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret) +{ + VMFrameStack *stack = &GlobalVMStack; + VMFrame *newf = stack->AllocFrame(func); + 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 (...) + { + stack->PopFrame(); + throw; + } + stack->PopFrame(); + return numret; +} diff --git a/src/scripting/vm/vmframe.cpp b/src/scripting/vm/vmframe.cpp index 9643713316..b9114c4890 100644 --- a/src/scripting/vm/vmframe.cpp +++ b/src/scripting/vm/vmframe.cpp @@ -437,8 +437,9 @@ VMFrame *VMFrameStack::PopFrame() int VMCall(VMFunction *func, VMValue *params, int numparams, VMReturn *results, int numresults/*, VMException **trap*/) { - bool allocated = false; +#if 0 try +#endif { if (func->VarFlags & VARF_Native) { @@ -463,12 +464,7 @@ int VMCall(VMFunction *func, VMValue *params, int numparams, VMReturn *results, { VMCycles[0].Clock(); VMCalls[0]++; - auto &stack = GlobalVMStack; - stack.AllocFrame(static_cast(func)); - allocated = true; - VMFillParams(params, stack.TopFrame(), numparams); - int numret = VMExec(&stack, code, results, numresults); - stack.PopFrame(); + int numret = VMExec(static_cast(func), params, numparams, results, numresults); VMCycles[0].Unclock(); return numret; } @@ -477,10 +473,6 @@ int VMCall(VMFunction *func, VMValue *params, int numparams, VMReturn *results, #if 0 catch (VMException *exception) { - if (allocated) - { - PopFrame(); - } if (trap != NULL) { *trap = exception; @@ -489,14 +481,6 @@ int VMCall(VMFunction *func, VMValue *params, int numparams, VMReturn *results, throw; } #endif - catch (...) - { - if (allocated) - { - GlobalVMStack.PopFrame(); - } - throw; - } } // Exception stuff for the VM is intentionally placed there, because having this in vmexec.cpp would subject it to inlining diff --git a/src/scripting/vm/vmintern.h b/src/scripting/vm/vmintern.h index 832372a9ea..8d1f01b557 100644 --- a/src/scripting/vm/vmintern.h +++ b/src/scripting/vm/vmintern.h @@ -428,7 +428,7 @@ enum EVMEngine }; void VMSelectEngine(EVMEngine engine); -extern int (*VMExec)(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret); +extern int (*VMExec)(VMScriptFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret); void VMFillParams(VMValue *params, VMFrame *callee, int numparam); void VMDumpConstants(FILE *out, const VMScriptFunction *func);