浏览代码

first implementation for tail call

Roberto Ierusalimschy 23 年之前
父节点
当前提交
e9ef7ed2d3
共有 3 个文件被更改,包括 11 次插入4 次删除
  1. 3 1
      lopcodes.c
  2. 3 2
      lopcodes.h
  3. 5 1
      lparser.c

+ 3 - 1
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 */

+ 3 - 2
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	*/

+ 5 - 1
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 */