Browse Source

new opcode TAILCALL

Roberto Ierusalimschy 26 years ago
parent
commit
0870a2d1d8
3 changed files with 39 additions and 28 deletions
  1. 7 5
      lopcodes.h
  2. 13 10
      lparser.c
  3. 19 13
      lvm.c

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

+ 13 - 10
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, ';');
   }

+ 19 - 13
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;
 }