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 --- lparser.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'lparser.c') 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, ';'); } -- cgit v1.2.3-55-g6feb