From 0870a2d1d8a1434eecae1923886ba219c4e699c7 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 5 Mar 1999 18:16:07 -0300 Subject: new opcode TAILCALL --- lopcodes.h | 12 +++++++----- lparser.c | 23 +++++++++++++---------- lvm.c | 32 +++++++++++++++++++------------- 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/lopcodes.h b/lopcodes.h index 728ea0da..5361b876 100644 --- a/lopcodes.h +++ b/lopcodes.h @@ -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 */ diff --git a/lparser.c b/lparser.c index a30c3777..eb1e0236 100644 --- a/lparser.c +++ b/lparser.c @@ -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, ';'); } diff --git a/lvm.c b/lvm.c index 3c26b220..8a80aebf 100644 --- a/lvm.c +++ b/lvm.c @@ -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; } -- cgit v1.2.3-55-g6feb