aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-03-05 18:16:07 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-03-05 18:16:07 -0300
commit0870a2d1d8a1434eecae1923886ba219c4e699c7 (patch)
tree3ca86564265ec369f3108ac286c61445ad50db14
parent78edc241e95d467e2b6c9a26b5311a62c7b04459 (diff)
downloadlua-0870a2d1d8a1434eecae1923886ba219c4e699c7.tar.gz
lua-0870a2d1d8a1434eecae1923886ba219c4e699c7.tar.bz2
lua-0870a2d1d8a1434eecae1923886ba219c4e699c7.zip
new opcode TAILCALL
-rw-r--r--lopcodes.h12
-rw-r--r--lparser.c23
-rw-r--r--lvm.c32
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 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.29 1999/02/26 15:19:54 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.30 1999/03/04 21:15:50 roberto Exp roberto $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -17,8 +17,12 @@
17typedef enum { 17typedef enum {
18/* name parm before after side effect 18/* name parm before after side effect
19-----------------------------------------------------------------------------*/ 19-----------------------------------------------------------------------------*/
20ENDCODE,/* - - - */ 20ENDCODE,/* - - (return) */
21RETCODE,/* b - - */ 21RETCODE,/* b - (return) */
22
23CALL,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */
24
25TAILCALL,/* b c v_c...v_1 f (return) f(v1,...,v_c) */
22 26
23PUSHNIL,/* b - nil_0...nil_b */ 27PUSHNIL,/* b - nil_0...nil_b */
24POP,/* b a_b...a_1 - */ 28POP,/* b a_b...a_1 - */
@@ -101,8 +105,6 @@ IFFUPJMP,/* b x - (x==nil)? PC-=b */
101CLOSUREW,/* w c v_c...v_1 closure(CNST[w], v_c...v_1) */ 105CLOSUREW,/* w c v_c...v_1 closure(CNST[w], v_c...v_1) */
102CLOSURE,/* b c v_c...v_1 closure(CNST[b], v_c...v_1) */ 106CLOSURE,/* b c v_c...v_1 closure(CNST[b], v_c...v_1) */
103 107
104CALL,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */
105
106SETLINEW,/* w - - LINE=w */ 108SETLINEW,/* w - - LINE=w */
107SETLINE,/* b - - LINE=b */ 109SETLINE,/* b - - LINE=b */
108 110
diff --git a/lparser.c b/lparser.c
index a30c3777..eb1e0236 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.25 1999/02/26 15:48:55 roberto Exp roberto $ 2** $Id: lparser.c,v 1.26 1999/03/04 21:17:26 roberto Exp roberto $
3** LL(1) Parser and code generator for Lua 3** LL(1) Parser and code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -387,16 +387,14 @@ static void adjuststack (LexState *ls, int n) {
387 387
388 388
389static void close_exp (LexState *ls, int pc, int nresults) { 389static void close_exp (LexState *ls, int pc, int nresults) {
390 if (pc > 0) { /* expression is an open function call */ 390 if (pc > 0) { /* expression is an open function call? */
391 Byte *code = ls->fs->f->code; 391 Byte *code = ls->fs->f->code;
392 code[pc-1] = (Byte)nresults; /* set nresults */ 392 code[pc-1] = (Byte)nresults; /* set nresults */
393 if (nresults != MULT_RET) 393 /* push results, pop params (at code[pc]) and function */
394 deltastack(ls, nresults); /* push results */ 394 deltastack(ls, nresults-(code[pc]+1));
395 deltastack(ls, -(code[pc]+1)); /* pop params (at code[pc]) and function */
396 } 395 }
397#ifdef DEBUG 396#ifdef DEBUG
398 if (nresults != MULT_RET) 397 code_oparg(ls, CHECKSTACK, ls->fs->stacksize, 0);
399 code_oparg(ls, CHECKSTACK, ls->fs->stacksize, 0);
400#endif 398#endif
401} 399}
402 400
@@ -878,9 +876,14 @@ static void ret (LexState *ls) {
878 check_debugline(ls); 876 check_debugline(ls);
879 if (optional(ls, RETURN)) { 877 if (optional(ls, RETURN)) {
880 listdesc e; 878 listdesc e;
881 explist(ls, &e); 879 explist(ls, &e);
882 close_exp(ls, e.pc, MULT_RET); 880 if (e.pc > 0) { /* expression is an open function call? */
883 code_oparg(ls, RETCODE, ls->fs->nlocalvar, 0); 881 Byte *code = ls->fs->f->code;
882 code[e.pc-2] = TAILCALL; /* instead of a conventional CALL */
883 code[e.pc-1] = (Byte)ls->fs->nlocalvar;
884 }
885 else
886 code_oparg(ls, RETCODE, ls->fs->nlocalvar, 0);
884 ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ 887 ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */
885 optional(ls, ';'); 888 optional(ls, ';');
886 } 889 }
diff --git a/lvm.c b/lvm.c
index 3c26b220..8a80aebf 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.51 1999/02/24 17:55:51 roberto Exp roberto $ 2** $Id: lvm.c,v 1.52 1999/03/04 21:15:50 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -329,13 +329,22 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
329 switchentry: 329 switchentry:
330 switch ((OpCode)*pc++) { 330 switch ((OpCode)*pc++) {
331 331
332 case ENDCODE: aux = 1; 332 case ENDCODE:
333 S->top = S->stack + base; 333 S->top = S->stack + base;
334 /* goes through */ 334 goto ret;
335
335 case RETCODE: 336 case RETCODE:
336 if (L->callhook) 337 base += *pc++;
337 luaD_callHook(base, NULL, 1); 338 goto ret;
338 return base + (aux ? 0 : *pc); 339
340 case CALL: aux = *pc++;
341 luaD_call((S->top-S->stack)-(*pc++), aux);
342 break;
343
344 case TAILCALL: aux = *pc++;
345 luaD_call((S->top-S->stack)-(*pc++), MULT_RET);
346 base += aux;
347 goto ret;
339 348
340 case PUSHNIL: aux = *pc++; 349 case PUSHNIL: aux = *pc++;
341 do { 350 do {
@@ -619,12 +628,6 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
619 luaC_checkGC(); 628 luaC_checkGC();
620 break; 629 break;
621 630
622 case CALL: aux = *pc++; {
623 StkId newBase = (S->top-S->stack)-(*pc++);
624 luaD_call(newBase, aux);
625 break;
626 }
627
628 case SETLINEW: aux += highbyte(*pc++); 631 case SETLINEW: aux += highbyte(*pc++);
629 case SETLINE: aux += *pc++; 632 case SETLINE: aux += *pc++;
630 if ((S->stack+base-1)->ttype != LUA_T_LINE) { 633 if ((S->stack+base-1)->ttype != LUA_T_LINE) {
@@ -648,6 +651,9 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
648 break; 651 break;
649 652
650 } 653 }
651 } 654 } ret:
655 if (L->callhook)
656 luaD_callHook(0, NULL, 1);
657 return base;
652} 658}
653 659