mirror of
https://github.com/lua/lua
synced 2025-04-17 10:22:47 +03:00
new opcode TAILCALL
This commit is contained in:
parent
78edc241e9
commit
0870a2d1d8
12
lopcodes.h
12
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
|
** Opcodes for Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -17,8 +17,12 @@
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
/* name parm before after side effect
|
/* name parm before after side effect
|
||||||
-----------------------------------------------------------------------------*/
|
-----------------------------------------------------------------------------*/
|
||||||
ENDCODE,/* - - - */
|
ENDCODE,/* - - (return) */
|
||||||
RETCODE,/* b - - */
|
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 */
|
PUSHNIL,/* b - nil_0...nil_b */
|
||||||
POP,/* b a_b...a_1 - */
|
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) */
|
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) */
|
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 */
|
SETLINEW,/* w - - LINE=w */
|
||||||
SETLINE,/* b - - LINE=b */
|
SETLINE,/* b - - LINE=b */
|
||||||
|
|
||||||
|
17
lparser.c
17
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
|
** LL(1) Parser and code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -387,15 +387,13 @@ static void adjuststack (LexState *ls, int n) {
|
|||||||
|
|
||||||
|
|
||||||
static void close_exp (LexState *ls, int pc, int nresults) {
|
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;
|
Byte *code = ls->fs->f->code;
|
||||||
code[pc-1] = (Byte)nresults; /* set nresults */
|
code[pc-1] = (Byte)nresults; /* set nresults */
|
||||||
if (nresults != MULT_RET)
|
/* push results, pop params (at code[pc]) and function */
|
||||||
deltastack(ls, nresults); /* push results */
|
deltastack(ls, nresults-(code[pc]+1));
|
||||||
deltastack(ls, -(code[pc]+1)); /* pop params (at code[pc]) and function */
|
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (nresults != MULT_RET)
|
|
||||||
code_oparg(ls, CHECKSTACK, ls->fs->stacksize, 0);
|
code_oparg(ls, CHECKSTACK, ls->fs->stacksize, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -879,7 +877,12 @@ static void ret (LexState *ls) {
|
|||||||
if (optional(ls, RETURN)) {
|
if (optional(ls, RETURN)) {
|
||||||
listdesc e;
|
listdesc e;
|
||||||
explist(ls, &e);
|
explist(ls, &e);
|
||||||
close_exp(ls, e.pc, MULT_RET);
|
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);
|
code_oparg(ls, RETCODE, ls->fs->nlocalvar, 0);
|
||||||
ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */
|
ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */
|
||||||
optional(ls, ';');
|
optional(ls, ';');
|
||||||
|
32
lvm.c
32
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
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -329,13 +329,22 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
|
|||||||
switchentry:
|
switchentry:
|
||||||
switch ((OpCode)*pc++) {
|
switch ((OpCode)*pc++) {
|
||||||
|
|
||||||
case ENDCODE: aux = 1;
|
case ENDCODE:
|
||||||
S->top = S->stack + base;
|
S->top = S->stack + base;
|
||||||
/* goes through */
|
goto ret;
|
||||||
|
|
||||||
case RETCODE:
|
case RETCODE:
|
||||||
if (L->callhook)
|
base += *pc++;
|
||||||
luaD_callHook(base, NULL, 1);
|
goto ret;
|
||||||
return base + (aux ? 0 : *pc);
|
|
||||||
|
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++;
|
case PUSHNIL: aux = *pc++;
|
||||||
do {
|
do {
|
||||||
@ -619,12 +628,6 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
|
|||||||
luaC_checkGC();
|
luaC_checkGC();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CALL: aux = *pc++; {
|
|
||||||
StkId newBase = (S->top-S->stack)-(*pc++);
|
|
||||||
luaD_call(newBase, aux);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SETLINEW: aux += highbyte(*pc++);
|
case SETLINEW: aux += highbyte(*pc++);
|
||||||
case SETLINE: aux += *pc++;
|
case SETLINE: aux += *pc++;
|
||||||
if ((S->stack+base-1)->ttype != LUA_T_LINE) {
|
if ((S->stack+base-1)->ttype != LUA_T_LINE) {
|
||||||
@ -648,6 +651,9 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
} ret:
|
||||||
|
if (L->callhook)
|
||||||
|
luaD_callHook(0, NULL, 1);
|
||||||
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user