- Added the TAIL instruction to perform a CALL and a RET in the same instruction. The called

function will pass its results directly to this function's caller. Eventually, this should
  be changed to do a proper tail call for scripted functions.

SVN r3769 (scripting)
This commit is contained in:
Randy Heit 2012-07-17 04:06:28 +00:00
commit e1a2f3b546
5 changed files with 58 additions and 9 deletions

View file

@ -539,6 +539,43 @@ begin:
pc += C; // Skip RESULTs
}
NEXTOP;
OP(TAIL_K):
ASSERTKA(a);
assert(konstatag[a] == ATAG_OBJECT);
ptr = konsta[a].o;
goto Do_TAILCALL;
OP(TAIL):
ASSERTA(a);
ptr = reg.a[a];
Do_TAILCALL:
assert(B <= f->NumParam);
assert(C <= MAX_RETURNS);
{
VMFunction *call = (VMFunction *)ptr;
if (call->Native)
{
return static_cast<VMNativeFunction *>(call)->NativeCall(stack, reg.param + f->NumParam - B, B, ret, numret);
}
else
{ // FIXME: Not a true tail call
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;
}
}
NEXTOP;
OP(RET):
if (B == REGT_NIL)
{ // No return values