Skip to content

Commit

Permalink
vararg back to '...' (but with another implementation)
Browse files Browse the repository at this point in the history
new implementation should have zero overhead for non-vararg functions
  • Loading branch information
roberto-ieru committed Feb 9, 2018
1 parent 4e0de3a commit b137993
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 110 deletions.
26 changes: 13 additions & 13 deletions lcode.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lcode.c,v 2.151 2018/01/27 16:56:33 roberto Exp roberto $
** $Id: lcode.c,v 2.152 2018/01/28 15:13:26 roberto Exp roberto $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -31,7 +31,7 @@


/* Maximum number of registers in a Lua function (must fit in 8 bits) */
#define MAXREGS 255
#define MAXREGS 254


#define hasjumps(e) ((e)->t != (e)->f)
Expand Down Expand Up @@ -157,17 +157,17 @@ int luaK_jump (FuncState *fs) {
** Code a 'return' instruction
*/
void luaK_ret (FuncState *fs, int first, int nret) {
switch (nret) {
case 0:
luaK_codeABC(fs, OP_RETURN0, 0, 0, 0);
break;
case 1:
luaK_codeABC(fs, OP_RETURN1, first, 0, 0);
break;
default:
luaK_codeABC(fs, OP_RETURN, first, nret + 1, 0);
break;
OpCode op;
if (fs->f->is_vararg)
op = OP_RETVARARG;
else {
switch (nret) {
case 0: op = OP_RETURN0; break;
case 1: op = OP_RETURN1; break;
default: op = OP_RETURN; break;
}
}
luaK_codeABC(fs, op, first, nret + 1, fs->f->numparams);
}


Expand Down Expand Up @@ -1647,7 +1647,7 @@ void luaK_finish (FuncState *fs) {
lua_assert(i == 0 || isOT(*(pc - 1)) == isIT(*pc));
switch (GET_OPCODE(*pc)) {
case OP_RETURN: case OP_RETURN0: case OP_RETURN1:
case OP_TAILCALL: {
case OP_RETVARARG: case OP_TAILCALL: {
if (p->sizep > 0)
SETARG_k(*pc, 1); /* signal that they must close upvalues */
break;
Expand Down
26 changes: 21 additions & 5 deletions ldebug.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: ldebug.c,v 2.152 2018/01/10 12:02:35 roberto Exp roberto $
** $Id: ldebug.c,v 2.153 2018/02/06 19:16:56 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -187,12 +187,28 @@ static const char *upvalname (Proto *p, int uv) {
}


static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
if (clLvalue(s2v(ci->func))->p->is_vararg) {
int nextra = ci->u.l.nextraargs;
if (n <= nextra) {
*pos = ci->func - nextra + (n - 1);
return "(*vararg)"; /* generic name for any vararg */
}
}
return NULL; /* no such vararg */
}


static const char *findlocal (lua_State *L, CallInfo *ci, int n,
StkId *pos) {
StkId base = ci->func + 1;
const char *name = (isLua(ci))
? luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci))
: NULL;
const char *name = NULL;
if (isLua(ci)) {
if (n < 0) /* access to vararg values? */
return findvararg(ci, -n, pos);
else
name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
}
if (name == NULL) { /* no 'standard' name? */
StkId limit = (ci == L->ci) ? L->top : ci->next->func;
if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */
Expand Down Expand Up @@ -324,7 +340,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
}
else {
ar->isvararg = f->l.p->is_vararg;
ar->nparams = f->l.p->numparams + f->l.p->is_vararg;
ar->nparams = f->l.p->numparams;
}
break;
}
Expand Down
37 changes: 17 additions & 20 deletions ldo.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: ldo.c,v 2.191 2018/02/07 15:18:04 roberto Exp roberto $
** $Id: ldo.c,v 2.192 2018/02/07 15:55:18 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -310,7 +310,7 @@ void luaD_hookcall (lua_State *L, CallInfo *ci) {
}


static void rethook (lua_State *L, CallInfo *ci) {
void luaD_rethook (lua_State *L, CallInfo *ci) {
if (isLuacode(ci))
L->top = ci->top; /* prepare top */
if (L->hookmask & LUA_MASKRET) /* is return hook on? */
Expand Down Expand Up @@ -343,8 +343,8 @@ void luaD_tryfuncTM (lua_State *L, StkId func) {
** expressions, multiple results for tail calls/single parameters)
** separated.
*/
static void moveresults (lua_State *L, StkId firstResult, StkId res,
int nres, int wanted) {
void luaD_moveresults (lua_State *L, StkId firstResult, StkId res,
int nres, int wanted) {
switch (wanted) { /* handle typical cases separately */
case 0: break; /* nothing to move */
case 1: { /* one result needed */
Expand Down Expand Up @@ -382,27 +382,22 @@ static void moveresults (lua_State *L, StkId firstResult, StkId res,

/*
** Finishes a function call: calls hook if necessary, removes CallInfo,
** moves current number of results to proper place; returns 0 iff call
** wanted multiple (variable number of) results.
** moves current number of results to proper place.
*/
void luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) {
if (L->hookmask) {
ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */
rethook(L, ci);
luaD_rethook(L, ci);
firstResult = restorestack(L, fr);
}
L->ci = ci->previous; /* back to caller */
/* move results to proper place */
moveresults(L, firstResult, ci->func, nres, ci->nresults);
luaD_moveresults(L, firstResult, ci->func, nres, ci->nresults);
}



#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L))


#define checkstackGC(L,fsize) \
luaD_checkstackaux(L, (fsize), (void)0, luaC_checkGC(L))
#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))


/*
Expand Down Expand Up @@ -438,8 +433,6 @@ void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) {
void luaD_call (lua_State *L, StkId func, int nresults) {
lua_CFunction f;
TValue *funcv = s2v(func);
CallInfo *ci = next_ci(L);
ci->nresults = nresults;
switch (ttype(funcv)) {
case LUA_TCCL: /* C closure */
f = clCvalue(funcv)->f;
Expand All @@ -448,12 +441,14 @@ void luaD_call (lua_State *L, StkId func, int nresults) {
f = fvalue(funcv);
Cfunc: {
int n; /* number of returns */
CallInfo *ci;
checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
ci = next_ci(L);
ci->nresults = nresults;
ci->callstatus = CIST_C;
ci->top = L->top + LUA_MINSTACK;
ci->func = func;
lua_assert(ci->top <= L->stack_last);
L->ci = ci; /* now 'enter' new function */
if (L->hookmask & LUA_MASKCALL)
luaD_hook(L, LUA_HOOKCALL, -1);
lua_unlock(L);
Expand All @@ -464,18 +459,20 @@ void luaD_call (lua_State *L, StkId func, int nresults) {
break;
}
case LUA_TLCL: { /* Lua function */
CallInfo *ci;
Proto *p = clLvalue(funcv)->p;
int narg = cast_int(L->top - func) - 1; /* number of real arguments */
int nfixparams = p->numparams;
int fsize = p->maxstacksize; /* frame size */
ci->u.l.savedpc = p->code; /* starting point */
checkstackp(L, fsize, func);
for (; narg < nfixparams; narg++)
setnilvalue(s2v(L->top++)); /* complete missing arguments */
ci = next_ci(L);
ci->nresults = nresults;
ci->u.l.savedpc = p->code; /* starting point */
ci->callstatus = 0;
ci->top = func + 1 + fsize;
ci->func = func;
L->ci = ci; /* now 'enter' new function */
for (; narg < nfixparams; narg++)
setnilvalue(s2v(L->top++)); /* complete missing arguments */
lua_assert(ci->top <= L->stack_last);
luaV_execute(L, ci); /* run the function */
break;
Expand Down
10 changes: 9 additions & 1 deletion ldo.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: ldo.h,v 2.39 2018/01/10 19:19:27 roberto Exp roberto $
** $Id: ldo.h,v 2.40 2018/02/06 19:16:56 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -42,6 +42,11 @@
p = restorestack(L, t__)) /* 'pos' part: restore 'p' */


/* macro to check stack size and GC */
#define checkstackGC(L,fsize) \
luaD_checkstackaux(L, (fsize), (void)0, luaC_checkGC(L))


/* type of protected functions, to be ran by 'runprotected' */
typedef void (*Pfunc) (lua_State *L, void *ud);

Expand All @@ -57,7 +62,10 @@ LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
ptrdiff_t oldtop, ptrdiff_t ef);
LUAI_FUNC void luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult,
int nres);
LUAI_FUNC void luaD_rethook (lua_State *L, CallInfo *ci);
LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror);
LUAI_FUNC void luaD_moveresults (lua_State *L, StkId firstResult, StkId res,
int nres, int wanted);
LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror);
LUAI_FUNC void luaD_shrinkstack (lua_State *L);
LUAI_FUNC void luaD_inctop (lua_State *L);
Expand Down
4 changes: 3 additions & 1 deletion lopcodes.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lopcodes.c,v 1.75 2017/12/22 14:16:46 roberto Exp roberto $
** $Id: lopcodes.c,v 1.76 2018/02/07 15:18:04 roberto Exp roberto $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -80,6 +80,7 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
"CALL",
"TAILCALL",
"RETURN",
"RETVARARG",
"RETURN0",
"RETURN1",
"FORLOOP1",
Expand Down Expand Up @@ -161,6 +162,7 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
,opmode(1, 1, 0, 1, iABC) /* OP_CALL */
,opmode(1, 1, 0, 1, iABC) /* OP_TAILCALL */
,opmode(0, 1, 0, 0, iABC) /* OP_RETURN */
,opmode(0, 1, 0, 0, iABC) /* OP_RETVARARG */
,opmode(0, 0, 0, 0, iABC) /* OP_RETURN0 */
,opmode(0, 0, 0, 0, iABC) /* OP_RETURN1 */
,opmode(0, 0, 0, 1, iABx) /* OP_FORLOOP1 */
Expand Down
10 changes: 6 additions & 4 deletions lopcodes.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lopcodes.h,v 1.184 2018/01/28 15:13:26 roberto Exp roberto $
** $Id: lopcodes.h,v 1.186 2018/02/07 15:18:04 roberto Exp roberto $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -268,6 +268,7 @@ OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */

OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
OP_RETVARARG,/* A B return R(A), ... ,R(A+B-2) (see note) */
OP_RETURN0,/* return */
OP_RETURN1,/* A return R(A) */

Expand All @@ -286,7 +287,7 @@ OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */

OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */

OP_VARARG,/* A B C R(A), R(A+1), ..., R(A+C-2) = vararg(B) */
OP_VARARG,/* A B C R(A), R(A+1), ..., R(A+C-2) = vararg */

OP_PREPVARARG,/*A (adjust vararg parameters) */

Expand All @@ -305,9 +306,10 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
OP_SETLIST) may use 'top'.
(*) In OP_VARARG, if (C == 0) then use actual number of varargs and
set top (like in OP_CALL with C == 0). B is the vararg parameter.
set top (like in OP_CALL with C == 0).
(*) In OP_RETURN, if (B == 0) then return up to 'top'.
(*) In OP_RETURN/OP_RETVARARG, if (B == 0) then return up to 'top'.
(OP_RETVARARG is the return instruction for vararg functions.)
(*) In OP_SETLIST, if (B == 0) then real B = 'top'; if (C == 0) then
next 'instruction' is EXTRAARG(real C).
Expand Down
22 changes: 6 additions & 16 deletions lparser.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lparser.c,v 2.175 2017/12/22 14:16:46 roberto Exp roberto $
** $Id: lparser.c,v 2.176 2018/02/07 15:18:04 roberto Exp roberto $
** Lua Parser
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -568,6 +568,7 @@ static void close_func (LexState *ls) {
Proto *f = fs->f;
luaK_ret(fs, 0, 0); /* final return */
leaveblock(fs);
lua_assert(fs->bl == NULL);
luaK_finish(fs);
luaM_shrinkvector(L, f->code, f->sizecode, fs->pc, Instruction);
luaM_shrinkvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte);
Expand All @@ -577,7 +578,8 @@ static void close_func (LexState *ls) {
luaM_shrinkvector(L, f->p, f->sizep, fs->np, Proto *);
luaM_shrinkvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
luaM_shrinkvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc);
lua_assert(fs->bl == NULL);
if (f->is_vararg)
f->maxstacksize++; /* ensure space to copy the function */
ls->fs = fs->prev;
luaC_checkGC(L);
}
Expand Down Expand Up @@ -781,11 +783,6 @@ static void parlist (LexState *ls) {
}
case TK_DOTS: { /* param -> '...' */
luaX_next(ls);
if (testnext(ls, '='))
new_localvar(ls, str_checkname(ls));
else
new_localvarliteral(ls, "_ARG");
nparams++;
isvararg = 1;
break;
}
Expand All @@ -795,10 +792,8 @@ static void parlist (LexState *ls) {
}
adjustlocalvars(ls, nparams);
f->numparams = cast_byte(fs->nactvar);
if (isvararg) {
f->numparams--; /* exclude vararg parameter */
if (isvararg)
setvararg(fs, f->numparams); /* declared vararg */
}
luaK_reserveregs(fs, fs->nactvar); /* reserve registers for parameters */
}

Expand Down Expand Up @@ -984,10 +979,9 @@ static void simpleexp (LexState *ls, expdesc *v) {
}
case TK_DOTS: { /* vararg */
FuncState *fs = ls->fs;
int lastparam = fs->f->numparams;
check_condition(ls, fs->f->is_vararg,
"cannot use '...' outside a vararg function");
init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, lastparam, 1));
init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 0, 1));
break;
}
case '{': { /* constructor */
Expand Down Expand Up @@ -1703,10 +1697,6 @@ static void mainfunc (LexState *ls, FuncState *fs) {
expdesc v;
open_func(ls, fs, &bl);
setvararg(fs, 0); /* main function is always declared vararg */
fs->f->numparams = 0;
new_localvarliteral(ls, "_ARG");
adjustlocalvars(ls, 1);
luaK_reserveregs(fs, 1); /* reserve register for vararg */
init_exp(&v, VLOCAL, 0); /* create and... */
newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */
luaX_next(ls); /* read first token */
Expand Down
3 changes: 2 additions & 1 deletion lstate.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lstate.h,v 2.152 2017/11/23 16:35:54 roberto Exp roberto $
** $Id: lstate.h,v 2.153 2017/12/19 16:40:17 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -92,6 +92,7 @@ typedef struct CallInfo {
struct { /* only for Lua functions */
const Instruction *savedpc;
l_signalT trap;
int nextraargs; /* # of extra arguments in vararg functions */
} l;
struct { /* only for C functions */
lua_KFunction k; /* continuation in case of yields */
Expand Down
Loading

0 comments on commit b137993

Please sign in to comment.