- modify the VM calling convention so that the callee sets up its own VM frame

This commit is contained in:
Magnus Norddahl 2018-10-09 02:08:15 +02:00
parent 367b60d88c
commit 137ef034d1
5 changed files with 54 additions and 106 deletions

View file

@ -417,19 +417,7 @@ int JitCompiler::DoCall(VMFrameStack *stack, VMFunction *call, int b, int c, VMV
else
{
VMCalls[0]++;
VMScriptFunction *script = static_cast<VMScriptFunction *>(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<VMScriptFunction *>(call), param, b, returns, c);
}
return numret;

View file

@ -135,7 +135,7 @@ struct VMExec_Unchecked
#undef assert
#include <assert.h>
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

View file

@ -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<VMScriptFunction *>(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<VMScriptFunction *>(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<VMScriptFunction *>(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<VMScriptFunction *>(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<VMScriptFunction *>(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<VMScriptFunction *>(call), reg.param + f->NumParam - B, B, ret, numret);
}
}
NEXTOP;
@ -2105,3 +2043,41 @@ static void SetReturn(const VMRegisters &reg, 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;
}

View file

@ -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<VMScriptFunction *>(func));
allocated = true;
VMFillParams(params, stack.TopFrame(), numparams);
int numret = VMExec(&stack, code, results, numresults);
stack.PopFrame();
int numret = VMExec(static_cast<VMScriptFunction *>(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

View file

@ -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);