lua

A copy of the Lua development repository
Log | Files | Refs | README

commit e9ef7ed2d3015ff6083ae51995b153b88837b64d
parent 2626708b72f987b62747801443f22953655a2bfc
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date:   Thu, 21 Mar 2002 17:32:00 -0300

first implementation for tail call

Diffstat:
Mlopcodes.c | 4+++-
Mlopcodes.h | 5+++--
Mlparser.c | 6+++++-
3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/lopcodes.c b/lopcodes.c @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.c,v 1.11 2002/02/05 22:39:12 roberto Exp roberto $ +** $Id: lopcodes.c,v 1.12 2002/03/08 19:10:32 roberto Exp roberto $ ** extracted automatically from lopcodes.h by mkprint.lua ** DO NOT EDIT ** See Copyright Notice in lua.h @@ -45,6 +45,7 @@ const char *const luaP_opnames[] = { "TESTT", "TESTF", "CALL", + "TAILCALL", "RETURN", "FORLOOP", "TFORLOOP", @@ -93,6 +94,7 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = { ,opmode(1,0,1,0, 1,0,iABC) /* OP_TESTT */ ,opmode(1,0,1,0, 1,0,iABC) /* OP_TESTF */ ,opmode(0,0,0,0, 0,0,iABC) /* OP_CALL */ + ,opmode(0,0,0,0, 0,0,iABC) /* OP_TAILCALL */ ,opmode(0,0,0,0, 0,0,iABC) /* OP_RETURN */ ,opmode(0,1,0,0, 0,0,iAsBc) /* OP_FORLOOP */ ,opmode(0,0,0,0, 0,0,iABC) /* OP_TFORLOOP */ diff --git a/lopcodes.h b/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.90 2002/03/08 19:10:32 roberto Exp roberto $ +** $Id: lopcodes.h,v 1.91 2002/03/18 14:49:46 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -77,7 +77,7 @@ enum OpMode {iABC, iABc, iAsBc}; /* basic instruction format */ */ #define GET_OPCODE(i) (cast(OpCode, (i)&MASK1(SIZE_OP,0))) -#define SET_OPCODE(i,o) (((i)&MASK0(SIZE_OP,0)) | cast(Instruction, o)) +#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,0)) | cast(Instruction, o))) #define GETARG_A(i) (cast(int, (i)>>POS_A)) #define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ @@ -168,6 +168,7 @@ OP_TESTT,/* A B if (R(B)) then R(A) := R(B) else pc++ */ OP_TESTF,/* A B if not (R(B)) then R(A) := R(B) else pc++ */ OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_TAILCALL,/* A B return R(A)(R(A+1), ... ,R(A+B-1)) */ OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see (3)) */ OP_FORLOOP,/* A sBc R(A)+=R(A+2); if R(A) <?= R(A+1) then PC+= sBc */ diff --git a/lparser.c b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.170 2002/03/14 18:32:37 roberto Exp roberto $ +** $Id: lparser.c,v 1.171 2002/03/18 14:49:46 roberto Exp roberto $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -1209,6 +1209,10 @@ static void retstat (LexState *ls) { else { nret = explist1(ls, &e); /* optional return values */ if (e.k == VCALL) { + if (nret == 1) { /* tail call? */ + SET_OPCODE(getcode(fs,&e), OP_TAILCALL); + return; + } luaK_setcallreturns(fs, &e, LUA_MULTRET); first = fs->nactloc; nret = LUA_MULTRET; /* return all values */