mirror of https://github.com/rusefi/lua.git
back to old-style vararg system (with vararg table collecting extra
arguments)
This commit is contained in:
parent
7647d5d13d
commit
5c8770f896
21
ldebug.c
21
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,28 +131,13 @@ 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));
|
||||
}
|
||||
base = ci->u.l.base;
|
||||
name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
|
||||
}
|
||||
else
|
||||
base = ci->func + 1;
|
||||
|
|
41
ldo.c
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);
|
||||
for (; n < p->numparams - p->is_vararg; n++)
|
||||
setnilvalue(L->top++); /* complete missing arguments */
|
||||
if (p->is_vararg)
|
||||
base = adjust_varargs(L, p, n);
|
||||
else { /* non vararg function */
|
||||
for (; n < p->numparams; n++)
|
||||
setnilvalue(L->top++); /* complete missing arguments */
|
||||
base = func + 1;
|
||||
}
|
||||
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
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
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
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
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
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…
Reference in New Issue