new opcode TAILCALL

This commit is contained in:
Roberto Ierusalimschy 1999-03-05 18:16:07 -03:00
parent 78edc241e9
commit 0870a2d1d8
3 changed files with 39 additions and 28 deletions

View File

@ -1,5 +1,5 @@
/*
** $Id: lopcodes.h,v 1.29 1999/02/26 15:19:54 roberto Exp roberto $
** $Id: lopcodes.h,v 1.30 1999/03/04 21:15:50 roberto Exp roberto $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@ -17,8 +17,12 @@
typedef enum {
/* name parm before after side effect
-----------------------------------------------------------------------------*/
ENDCODE,/* - - - */
RETCODE,/* b - - */
ENDCODE,/* - - (return) */
RETCODE,/* b - (return) */
CALL,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */
TAILCALL,/* b c v_c...v_1 f (return) f(v1,...,v_c) */
PUSHNIL,/* b - nil_0...nil_b */
POP,/* b a_b...a_1 - */
@ -101,8 +105,6 @@ IFFUPJMP,/* b x - (x==nil)? PC-=b */
CLOSUREW,/* w c v_c...v_1 closure(CNST[w], v_c...v_1) */
CLOSURE,/* b c v_c...v_1 closure(CNST[b], v_c...v_1) */
CALL,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */
SETLINEW,/* w - - LINE=w */
SETLINE,/* b - - LINE=b */

View File

@ -1,5 +1,5 @@
/*
** $Id: lparser.c,v 1.25 1999/02/26 15:48:55 roberto Exp roberto $
** $Id: lparser.c,v 1.26 1999/03/04 21:17:26 roberto Exp roberto $
** LL(1) Parser and code generator for Lua
** See Copyright Notice in lua.h
*/
@ -387,16 +387,14 @@ static void adjuststack (LexState *ls, int n) {
static void close_exp (LexState *ls, int pc, int nresults) {
if (pc > 0) { /* expression is an open function call */
if (pc > 0) { /* expression is an open function call? */
Byte *code = ls->fs->f->code;
code[pc-1] = (Byte)nresults; /* set nresults */
if (nresults != MULT_RET)
deltastack(ls, nresults); /* push results */
deltastack(ls, -(code[pc]+1)); /* pop params (at code[pc]) and function */
/* push results, pop params (at code[pc]) and function */
deltastack(ls, nresults-(code[pc]+1));
}
#ifdef DEBUG
if (nresults != MULT_RET)
code_oparg(ls, CHECKSTACK, ls->fs->stacksize, 0);
code_oparg(ls, CHECKSTACK, ls->fs->stacksize, 0);
#endif
}
@ -878,9 +876,14 @@ static void ret (LexState *ls) {
check_debugline(ls);
if (optional(ls, RETURN)) {
listdesc e;
explist(ls, &e);
close_exp(ls, e.pc, MULT_RET);
code_oparg(ls, RETCODE, ls->fs->nlocalvar, 0);
explist(ls, &e);
if (e.pc > 0) { /* expression is an open function call? */
Byte *code = ls->fs->f->code;
code[e.pc-2] = TAILCALL; /* instead of a conventional CALL */
code[e.pc-1] = (Byte)ls->fs->nlocalvar;
}
else
code_oparg(ls, RETCODE, ls->fs->nlocalvar, 0);
ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */
optional(ls, ';');
}

32
lvm.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lvm.c,v 1.51 1999/02/24 17:55:51 roberto Exp roberto $
** $Id: lvm.c,v 1.52 1999/03/04 21:15:50 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@ -329,13 +329,22 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
switchentry:
switch ((OpCode)*pc++) {
case ENDCODE: aux = 1;
case ENDCODE:
S->top = S->stack + base;
/* goes through */
goto ret;
case RETCODE:
if (L->callhook)
luaD_callHook(base, NULL, 1);
return base + (aux ? 0 : *pc);
base += *pc++;
goto ret;
case CALL: aux = *pc++;
luaD_call((S->top-S->stack)-(*pc++), aux);
break;
case TAILCALL: aux = *pc++;
luaD_call((S->top-S->stack)-(*pc++), MULT_RET);
base += aux;
goto ret;
case PUSHNIL: aux = *pc++;
do {
@ -619,12 +628,6 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
luaC_checkGC();
break;
case CALL: aux = *pc++; {
StkId newBase = (S->top-S->stack)-(*pc++);
luaD_call(newBase, aux);
break;
}
case SETLINEW: aux += highbyte(*pc++);
case SETLINE: aux += *pc++;
if ((S->stack+base-1)->ttype != LUA_T_LINE) {
@ -648,6 +651,9 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
break;
}
}
} ret:
if (L->callhook)
luaD_callHook(0, NULL, 1);
return base;
}