aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-05-13 10:04:33 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-05-13 10:04:33 -0300
commit5c8770f8969a73cf4ca503f54c2217f76de62e04 (patch)
treed5dac87490011d117277d94c81f6f2fd47b1b094
parent7647d5d13d016f114dac4be0b9da62d502eab400 (diff)
downloadlua-5c8770f8969a73cf4ca503f54c2217f76de62e04.tar.gz
lua-5c8770f8969a73cf4ca503f54c2217f76de62e04.tar.bz2
lua-5c8770f8969a73cf4ca503f54c2217f76de62e04.zip
back to old-style vararg system (with vararg table collecting extra
arguments)
-rw-r--r--ldebug.c21
-rw-r--r--ldo.c41
-rw-r--r--ldo.h10
-rw-r--r--lparser.c11
-rw-r--r--ltm.c40
-rw-r--r--ltm.h5
-rw-r--r--lvm.c18
7 files changed, 74 insertions, 72 deletions
diff --git a/ldebug.c b/ldebug.c
index ead16794..776b05eb 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 2.123 2017/04/28 20:57:45 roberto Exp roberto $ 2** $Id: ldebug.c,v 2.124 2017/04/29 15:28:38 roberto Exp roberto $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -131,28 +131,13 @@ static const char *upvalname (Proto *p, int uv) {
131} 131}
132 132
133 133
134static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
135 int nparams = clLvalue(ci->func)->p->numparams;
136 if (n >= cast_int(ci->u.l.base - ci->func) - nparams)
137 return NULL; /* no such vararg */
138 else {
139 *pos = ci->func + nparams + n;
140 return "(*vararg)"; /* generic name for any vararg */
141 }
142}
143
144
145static const char *findlocal (lua_State *L, CallInfo *ci, int n, 134static const char *findlocal (lua_State *L, CallInfo *ci, int n,
146 StkId *pos) { 135 StkId *pos) {
147 const char *name = NULL; 136 const char *name = NULL;
148 StkId base; 137 StkId base;
149 if (isLua(ci)) { 138 if (isLua(ci)) {
150 if (n < 0) /* access to vararg values? */ 139 base = ci->u.l.base;
151 return findvararg(ci, -n, pos); 140 name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
152 else {
153 base = ci->u.l.base;
154 name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
155 }
156 } 141 }
157 else 142 else
158 base = ci->func + 1; 143 base = ci->func + 1;
diff --git a/ldo.c b/ldo.c
index 13387516..14d1adc6 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.156 2016/09/20 16:37:45 roberto Exp roberto $ 2** $Id: ldo.c,v 2.157 2016/12/13 15:52:21 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -290,23 +290,6 @@ static void callhook (lua_State *L, CallInfo *ci) {
290} 290}
291 291
292 292
293static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
294 int i;
295 int nfixargs = p->numparams;
296 StkId base, fixed;
297 /* move fixed parameters to final position */
298 fixed = L->top - actual; /* first fixed argument */
299 base = L->top; /* final position of first argument */
300 for (i = 0; i < nfixargs && i < actual; i++) {
301 setobjs2s(L, L->top++, fixed + i);
302 setnilvalue(fixed + i); /* erase original copy (for GC) */
303 }
304 for (; i < nfixargs; i++)
305 setnilvalue(L->top++); /* complete missing arguments */
306 return base;
307}
308
309
310/* 293/*
311** Check whether __call metafield of 'func' is a function. If so, put 294** Check whether __call metafield of 'func' is a function. If so, put
312** it in stack below original 'func' so that 'luaD_precall' can call 295** 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) {
395#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) 378#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))
396 379
397 380
398/* macro to check stack size, preserving 'p' */
399#define checkstackp(L,n,p) \
400 luaD_checkstackaux(L, n, \
401 ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \
402 luaC_checkGC(L), /* stack grow uses memory */ \
403 p = restorestack(L, t__)) /* 'pos' part: restore 'p' */
404
405
406/* 381/*
407** Prepares a function call: checks the stack, creates a new CallInfo 382** Prepares a function call: checks the stack, creates a new CallInfo
408** entry, fills in the relevant information, calls hook if needed. 383** entry, fills in the relevant information, calls hook if needed.
@@ -438,23 +413,19 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
438 return 1; 413 return 1;
439 } 414 }
440 case LUA_TLCL: { /* Lua function: prepare its call */ 415 case LUA_TLCL: { /* Lua function: prepare its call */
441 StkId base;
442 Proto *p = clLvalue(func)->p; 416 Proto *p = clLvalue(func)->p;
443 int n = cast_int(L->top - func) - 1; /* number of real arguments */ 417 int n = cast_int(L->top - func) - 1; /* number of real arguments */
444 int fsize = p->maxstacksize; /* frame size */ 418 int fsize = p->maxstacksize; /* frame size */
445 checkstackp(L, fsize, func); 419 checkstackp(L, fsize, func);
420 for (; n < p->numparams - p->is_vararg; n++)
421 setnilvalue(L->top++); /* complete missing arguments */
446 if (p->is_vararg) 422 if (p->is_vararg)
447 base = adjust_varargs(L, p, n); 423 luaT_adjustvarargs(L, p, n);
448 else { /* non vararg function */
449 for (; n < p->numparams; n++)
450 setnilvalue(L->top++); /* complete missing arguments */
451 base = func + 1;
452 }
453 ci = next_ci(L); /* now 'enter' new function */ 424 ci = next_ci(L); /* now 'enter' new function */
454 ci->nresults = nresults; 425 ci->nresults = nresults;
455 ci->func = func; 426 ci->func = func;
456 ci->u.l.base = base; 427 ci->u.l.base = func + 1;
457 L->top = ci->top = base + fsize; 428 L->top = ci->top = func + 1 + fsize;
458 lua_assert(ci->top <= L->stack_last); 429 lua_assert(ci->top <= L->stack_last);
459 ci->u.l.savedpc = p->code; /* starting point */ 430 ci->u.l.savedpc = p->code; /* starting point */
460 ci->callstatus = CIST_LUA; 431 ci->callstatus = CIST_LUA;
diff --git a/ldo.h b/ldo.h
index b2065cfa..4717620f 100644
--- a/ldo.h
+++ b/ldo.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.h,v 2.28 2015/11/23 11:29:43 roberto Exp roberto $ 2** $Id: ldo.h,v 2.29 2015/12/21 13:02:14 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -33,6 +33,14 @@
33#define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) 33#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
34 34
35 35
36/* macro to check stack size, preserving 'p' */
37#define checkstackp(L,n,p) \
38 luaD_checkstackaux(L, n, \
39 ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \
40 luaC_checkGC(L), /* stack grow uses memory */ \
41 p = restorestack(L, t__)) /* 'pos' part: restore 'p' */
42
43
36/* type of protected functions, to be ran by 'runprotected' */ 44/* type of protected functions, to be ran by 'runprotected' */
37typedef void (*Pfunc) (lua_State *L, void *ud); 45typedef void (*Pfunc) (lua_State *L, void *ud);
38 46
diff --git a/lparser.c b/lparser.c
index af5891c2..37f84cce 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.157 2017/04/28 20:57:45 roberto Exp roberto $ 2** $Id: lparser.c,v 2.158 2017/04/29 18:09:17 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -766,7 +766,12 @@ static void parlist (LexState *ls) {
766 } 766 }
767 case TK_DOTS: { /* param -> '...' */ 767 case TK_DOTS: { /* param -> '...' */
768 luaX_next(ls); 768 luaX_next(ls);
769 if (testnext(ls, '='))
770 new_localvar(ls, str_checkname(ls));
771 else
772 new_localvarliteral(ls, "_ARG");
769 f->is_vararg = 1; /* declared vararg */ 773 f->is_vararg = 1; /* declared vararg */
774 nparams++;
770 break; 775 break;
771 } 776 }
772 default: luaX_syntaxerror(ls, "<name> or '...' expected"); 777 default: luaX_syntaxerror(ls, "<name> or '...' expected");
@@ -1622,6 +1627,10 @@ static void mainfunc (LexState *ls, FuncState *fs) {
1622 expdesc v; 1627 expdesc v;
1623 open_func(ls, fs, &bl); 1628 open_func(ls, fs, &bl);
1624 fs->f->is_vararg = 1; /* main function is always declared vararg */ 1629 fs->f->is_vararg = 1; /* main function is always declared vararg */
1630 fs->f->numparams = 1;
1631 new_localvarliteral(ls, "_ARG");
1632 adjustlocalvars(ls, 1);
1633 luaK_reserveregs(fs, 1); /* reserve register for vararg */
1625 init_exp(&v, VLOCAL, 0); /* create and... */ 1634 init_exp(&v, VLOCAL, 0); /* create and... */
1626 newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ 1635 newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */
1627 luaX_next(ls); /* read first token */ 1636 luaX_next(ls); /* read first token */
diff --git a/ltm.c b/ltm.c
index 0ef76313..9da191f6 100644
--- a/ltm.c
+++ b/ltm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.c,v 2.39 2017/04/11 18:41:09 roberto Exp roberto $ 2** $Id: ltm.c,v 2.40 2017/05/08 15:57:23 roberto Exp roberto $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -163,3 +163,41 @@ int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
163 return !l_isfalse(L->top); 163 return !l_isfalse(L->top);
164} 164}
165 165
166
167void luaT_adjustvarargs (lua_State *L, Proto *p, int actual) {
168 int i;
169 Table *vtab;
170 TValue nname;
171 int nfixparams = p->numparams - 1; /* number of fixed parameters */
172 actual -= nfixparams; /* number of extra arguments */
173 vtab = luaH_new(L); /* create vararg table */
174 sethvalue(L, L->top, vtab); /* anchor it for resizing */
175 L->top++; /* space ensured by caller */
176 luaH_resize(L, vtab, actual, 1);
177 for (i = 0; i < actual; i++) /* put extra arguments into vararg table */
178 setobj2n(L, &vtab->array[i], L->top - actual + i - 1);
179 setsvalue(L, &nname, luaS_newliteral(L, "n")); /* get field 'n' */
180 setivalue(luaH_set(L, vtab, &nname), actual); /* store counter there */
181 L->top -= actual; /* remove extra elements from the stack */
182 sethvalue(L, L->top - 1, vtab); /* move table to new top */
183}
184
185
186void luaT_getvarargs (lua_State *L, StkId t, StkId where, int wanted) {
187 if (!ttistable(t))
188 luaG_runerror(L, "'vararg' parameter is not a table");
189 else {
190 int i;
191 Table *h = hvalue(t);
192 if (wanted < 0) { /* get all? */
193 const TValue *ns = luaH_getstr(h, luaS_newliteral(L, "n"));
194 int n = (ttisinteger(ns)) ? ivalue(ns) : 0;
195 wanted = n;
196 checkstackp(L, n, where);
197 L->top = where + n;
198 }
199 for (i = 0; i < wanted; i++) /* get what is available */
200 setobj2s(L, where + i, luaH_getint(h, i + 1));
201 return;
202 }
203}
diff --git a/ltm.h b/ltm.h
index 535e1885..2dfb46c1 100644
--- a/ltm.h
+++ b/ltm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.h,v 2.22 2016/02/26 19:20:15 roberto Exp roberto $ 2** $Id: ltm.h,v 2.23 2017/05/08 15:57:23 roberto Exp roberto $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -69,6 +69,9 @@ LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
69LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, 69LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1,
70 const TValue *p2, TMS event); 70 const TValue *p2, TMS event);
71 71
72LUAI_FUNC void luaT_adjustvarargs (lua_State *L, Proto *p, int actual);
73LUAI_FUNC void luaT_getvarargs (lua_State *L, StkId t, StkId where,
74 int wanted);
72 75
73 76
74#endif 77#endif
diff --git a/lvm.c b/lvm.c
index 9a60bb5b..3053d929 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.279 2017/05/10 17:32:19 roberto Exp roberto $ 2** $Id: lvm.c,v 2.280 2017/05/11 18:57:46 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -1433,20 +1433,8 @@ void luaV_execute (lua_State *L) {
1433 } 1433 }
1434 vmcase(OP_VARARG) { 1434 vmcase(OP_VARARG) {
1435 int b = GETARG_B(i) - 1; /* required results */ 1435 int b = GETARG_B(i) - 1; /* required results */
1436 int j; 1436 StkId vtab = base + cl->p->numparams - 1; /* vararg table */
1437 int n = cast_int(base - ci->func) - cl->p->numparams - 1; 1437 Protect(luaT_getvarargs(L, vtab, ra, b));
1438 if (n < 0) /* less arguments than parameters? */
1439 n = 0; /* no vararg arguments */
1440 if (b < 0) { /* B == 0? */
1441 b = n; /* get all var. arguments */
1442 Protect(luaD_checkstack(L, n));
1443 ra = RA(i); /* previous call may change the stack */
1444 L->top = ra + n;
1445 }
1446 for (j = 0; j < b && j < n; j++)
1447 setobjs2s(L, ra + j, base - n + j);
1448 for (; j < b; j++) /* complete required results with nil */
1449 setnilvalue(ra + j);
1450 vmbreak; 1438 vmbreak;
1451 } 1439 }
1452 vmcase(OP_EXTRAARG) { 1440 vmcase(OP_EXTRAARG) {