Browse Source

back to old-style vararg system (with vararg table collecting extra

arguments)
pull/11/head
Roberto Ierusalimschy 8 years ago
parent
commit
5c8770f896
  1. 17
      ldebug.c
  2. 41
      ldo.c
  3. 10
      ldo.h
  4. 11
      lparser.c
  5. 40
      ltm.c
  6. 5
      ltm.h
  7. 18
      lvm.c

17
ldebug.c

@ -1,5 +1,5 @@
/*
** $Id: ldebug.c,v 2.123 2017/04/28 20:57:45 roberto Exp roberto $
** $Id: ldebug.c,v 2.124 2017/04/29 15:28:38 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
@ -131,29 +131,14 @@ static const char *upvalname (Proto *p, int uv) {
}
static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
int nparams = clLvalue(ci->func)->p->numparams;
if (n >= cast_int(ci->u.l.base - ci->func) - nparams)
return NULL; /* no such vararg */
else {
*pos = ci->func + nparams + n;
return "(*vararg)"; /* generic name for any vararg */
}
}
static const char *findlocal (lua_State *L, CallInfo *ci, int n,
StkId *pos) {
const char *name = NULL;
StkId base;
if (isLua(ci)) {
if (n < 0) /* access to vararg values? */
return findvararg(ci, -n, pos);
else {
base = ci->u.l.base;
name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
}
}
else
base = ci->func + 1;
if (name == NULL) { /* no 'standard' name? */

41
ldo.c

@ -1,5 +1,5 @@
/*
** $Id: ldo.c,v 2.156 2016/09/20 16:37:45 roberto Exp roberto $
** $Id: ldo.c,v 2.157 2016/12/13 15:52:21 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@ -290,23 +290,6 @@ static void callhook (lua_State *L, CallInfo *ci) {
}
static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
int i;
int nfixargs = p->numparams;
StkId base, fixed;
/* move fixed parameters to final position */
fixed = L->top - actual; /* first fixed argument */
base = L->top; /* final position of first argument */
for (i = 0; i < nfixargs && i < actual; i++) {
setobjs2s(L, L->top++, fixed + i);
setnilvalue(fixed + i); /* erase original copy (for GC) */
}
for (; i < nfixargs; i++)
setnilvalue(L->top++); /* complete missing arguments */
return base;
}
/*
** Check whether __call metafield of 'func' is a function. If so, put
** it in stack below original 'func' so that 'luaD_precall' can call
@ -395,14 +378,6 @@ int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) {
#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))
/* macro to check stack size, preserving 'p' */
#define checkstackp(L,n,p) \
luaD_checkstackaux(L, n, \
ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \
luaC_checkGC(L), /* stack grow uses memory */ \
p = restorestack(L, t__)) /* 'pos' part: restore 'p' */
/*
** Prepares a function call: checks the stack, creates a new CallInfo
** entry, fills in the relevant information, calls hook if needed.
@ -438,23 +413,19 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
return 1;
}
case LUA_TLCL: { /* Lua function: prepare its call */
StkId base;
Proto *p = clLvalue(func)->p;
int n = cast_int(L->top - func) - 1; /* number of real arguments */
int fsize = p->maxstacksize; /* frame size */
checkstackp(L, fsize, func);
if (p->is_vararg)
base = adjust_varargs(L, p, n);
else { /* non vararg function */
for (; n < p->numparams; n++)
for (; n < p->numparams - p->is_vararg; n++)
setnilvalue(L->top++); /* complete missing arguments */
base = func + 1;
}
if (p->is_vararg)
luaT_adjustvarargs(L, p, n);
ci = next_ci(L); /* now 'enter' new function */
ci->nresults = nresults;
ci->func = func;
ci->u.l.base = base;
L->top = ci->top = base + fsize;
ci->u.l.base = func + 1;
L->top = ci->top = func + 1 + fsize;
lua_assert(ci->top <= L->stack_last);
ci->u.l.savedpc = p->code; /* starting point */
ci->callstatus = CIST_LUA;

10
ldo.h

@ -1,5 +1,5 @@
/*
** $Id: ldo.h,v 2.28 2015/11/23 11:29:43 roberto Exp roberto $
** $Id: ldo.h,v 2.29 2015/12/21 13:02:14 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@ -33,6 +33,14 @@
#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
/* macro to check stack size, preserving 'p' */
#define checkstackp(L,n,p) \
luaD_checkstackaux(L, n, \
ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \
luaC_checkGC(L), /* stack grow uses memory */ \
p = restorestack(L, t__)) /* 'pos' part: restore 'p' */
/* type of protected functions, to be ran by 'runprotected' */
typedef void (*Pfunc) (lua_State *L, void *ud);

11
lparser.c

@ -1,5 +1,5 @@
/*
** $Id: lparser.c,v 2.157 2017/04/28 20:57:45 roberto Exp roberto $
** $Id: lparser.c,v 2.158 2017/04/29 18:09:17 roberto Exp roberto $
** Lua Parser
** See Copyright Notice in lua.h
*/
@ -766,7 +766,12 @@ 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");
f->is_vararg = 1; /* declared vararg */
nparams++;
break;
}
default: luaX_syntaxerror(ls, "<name> or '...' expected");
@ -1622,6 +1627,10 @@ static void mainfunc (LexState *ls, FuncState *fs) {
expdesc v;
open_func(ls, fs, &bl);
fs->f->is_vararg = 1; /* main function is always declared vararg */
fs->f->numparams = 1;
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 */

40
ltm.c

@ -1,5 +1,5 @@
/*
** $Id: ltm.c,v 2.39 2017/04/11 18:41:09 roberto Exp roberto $
** $Id: ltm.c,v 2.40 2017/05/08 15:57:23 roberto Exp roberto $
** Tag methods
** See Copyright Notice in lua.h
*/
@ -163,3 +163,41 @@ int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
return !l_isfalse(L->top);
}
void luaT_adjustvarargs (lua_State *L, Proto *p, int actual) {
int i;
Table *vtab;
TValue nname;
int nfixparams = p->numparams - 1; /* number of fixed parameters */
actual -= nfixparams; /* number of extra arguments */
vtab = luaH_new(L); /* create vararg table */
sethvalue(L, L->top, vtab); /* anchor it for resizing */
L->top++; /* space ensured by caller */
luaH_resize(L, vtab, actual, 1);
for (i = 0; i < actual; i++) /* put extra arguments into vararg table */
setobj2n(L, &vtab->array[i], L->top - actual + i - 1);
setsvalue(L, &nname, luaS_newliteral(L, "n")); /* get field 'n' */
setivalue(luaH_set(L, vtab, &nname), actual); /* store counter there */
L->top -= actual; /* remove extra elements from the stack */
sethvalue(L, L->top - 1, vtab); /* move table to new top */
}
void luaT_getvarargs (lua_State *L, StkId t, StkId where, int wanted) {
if (!ttistable(t))
luaG_runerror(L, "'vararg' parameter is not a table");
else {
int i;
Table *h = hvalue(t);
if (wanted < 0) { /* get all? */
const TValue *ns = luaH_getstr(h, luaS_newliteral(L, "n"));
int n = (ttisinteger(ns)) ? ivalue(ns) : 0;
wanted = n;
checkstackp(L, n, where);
L->top = where + n;
}
for (i = 0; i < wanted; i++) /* get what is available */
setobj2s(L, where + i, luaH_getint(h, i + 1));
return;
}
}

5
ltm.h

@ -1,5 +1,5 @@
/*
** $Id: ltm.h,v 2.22 2016/02/26 19:20:15 roberto Exp roberto $
** $Id: ltm.h,v 2.23 2017/05/08 15:57:23 roberto Exp roberto $
** Tag methods
** See Copyright Notice in lua.h
*/
@ -69,6 +69,9 @@ LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1,
const TValue *p2, TMS event);
LUAI_FUNC void luaT_adjustvarargs (lua_State *L, Proto *p, int actual);
LUAI_FUNC void luaT_getvarargs (lua_State *L, StkId t, StkId where,
int wanted);
#endif

18
lvm.c

@ -1,5 +1,5 @@
/*
** $Id: lvm.c,v 2.279 2017/05/10 17:32:19 roberto Exp roberto $
** $Id: lvm.c,v 2.280 2017/05/11 18:57:46 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@ -1433,20 +1433,8 @@ void luaV_execute (lua_State *L) {
}
vmcase(OP_VARARG) {
int b = GETARG_B(i) - 1; /* required results */
int j;
int n = cast_int(base - ci->func) - cl->p->numparams - 1;
if (n < 0) /* less arguments than parameters? */
n = 0; /* no vararg arguments */
if (b < 0) { /* B == 0? */
b = n; /* get all var. arguments */
Protect(luaD_checkstack(L, n));
ra = RA(i); /* previous call may change the stack */
L->top = ra + n;
}
for (j = 0; j < b && j < n; j++)
setobjs2s(L, ra + j, base - n + j);
for (; j < b; j++) /* complete required results with nil */
setnilvalue(ra + j);
StkId vtab = base + cl->p->numparams - 1; /* vararg table */
Protect(luaT_getvarargs(L, vtab, ra, b));
vmbreak;
}
vmcase(OP_EXTRAARG) {

Loading…
Cancel
Save