aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-11-02 12:06:01 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-11-02 12:06:01 -0200
commitc5363a1b58573162ef13ba4a345bd48ad3c355d9 (patch)
tree7c4ee5559a42ce93d770aa0253f0695439a7d2e3
parent332a06bbd1a8835c810e52bbf68014d6956b50b8 (diff)
downloadlua-c5363a1b58573162ef13ba4a345bd48ad3c355d9.tar.gz
lua-c5363a1b58573162ef13ba4a345bd48ad3c355d9.tar.bz2
lua-c5363a1b58573162ef13ba4a345bd48ad3c355d9.zip
in 'luaD_precall', in vararg functions, complete missing parameters
only after moving them to final place (avoids checking the stack again)
-rw-r--r--ldo.c28
-rw-r--r--lvm.c18
2 files changed, 21 insertions, 25 deletions
diff --git a/ldo.c b/ldo.c
index 528f19e9..524c1e57 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.144 2015/10/28 17:28:40 roberto Exp roberto $ 2** $Id: ldo.c,v 2.145 2015/11/02 11:48:59 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*/
@@ -273,15 +273,15 @@ static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
273 int i; 273 int i;
274 int nfixargs = p->numparams; 274 int nfixargs = p->numparams;
275 StkId base, fixed; 275 StkId base, fixed;
276 lua_assert(actual >= nfixargs);
277 /* move fixed parameters to final position */ 276 /* move fixed parameters to final position */
278 luaD_checkstack(L, p->maxstacksize); /* check again for new 'base' */
279 fixed = L->top - actual; /* first fixed argument */ 277 fixed = L->top - actual; /* first fixed argument */
280 base = L->top; /* final position of first argument */ 278 base = L->top; /* final position of first argument */
281 for (i=0; i<nfixargs; i++) { 279 for (i = 0; i < nfixargs && i < actual; i++) {
282 setobjs2s(L, L->top++, fixed + i); 280 setobjs2s(L, L->top++, fixed + i);
283 setnilvalue(fixed + i); 281 setnilvalue(fixed + i); /* erase original copy (for GC) */
284 } 282 }
283 for (; i < nfixargs; i++)
284 setnilvalue(L->top++); /* complete missing arguments */
285 return base; 285 return base;
286} 286}
287 287
@@ -354,25 +354,23 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
354 StkId base; 354 StkId base;
355 Proto *p = clLvalue(func)->p; 355 Proto *p = clLvalue(func)->p;
356 int n = cast_int(L->top - func) - 1; /* number of real arguments */ 356 int n = cast_int(L->top - func) - 1; /* number of real arguments */
357 checkstackp(L, p->maxstacksize, func); 357 int fsize = p->maxstacksize; /* frame size */
358 for (; n < p->numparams; n++) 358 checkstackp(L, fsize, func);
359 setnilvalue(L->top++); /* complete missing arguments */ 359 if (p->is_vararg != 1) { /* do not use vararg? */
360 if (p->is_vararg != 1) /* do not use vararg? */ 360 for (; n < p->numparams; n++)
361 setnilvalue(L->top++); /* complete missing arguments */
361 base = func + 1; 362 base = func + 1;
362 else {
363 ptrdiff_t funcr = savestack(L, func);
364 base = adjust_varargs(L, p, n);
365 func = restorestack(L, funcr); /* previous call can change stack */
366 } 363 }
364 else
365 base = adjust_varargs(L, p, n);
367 ci = next_ci(L); /* now 'enter' new function */ 366 ci = next_ci(L); /* now 'enter' new function */
368 ci->nresults = nresults; 367 ci->nresults = nresults;
369 ci->func = func; 368 ci->func = func;
370 ci->u.l.base = base; 369 ci->u.l.base = base;
371 ci->top = base + p->maxstacksize; 370 L->top = ci->top = base + fsize;
372 lua_assert(ci->top <= L->stack_last); 371 lua_assert(ci->top <= L->stack_last);
373 ci->u.l.savedpc = p->code; /* starting point */ 372 ci->u.l.savedpc = p->code; /* starting point */
374 ci->callstatus = CIST_LUA; 373 ci->callstatus = CIST_LUA;
375 L->top = ci->top;
376 if (L->hookmask & LUA_MASKCALL) 374 if (L->hookmask & LUA_MASKCALL)
377 callhook(L, ci); 375 callhook(L, ci);
378 return 0; 376 return 0;
diff --git a/lvm.c b/lvm.c
index 051b948c..27ade135 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.257 2015/10/28 14:50:09 roberto Exp roberto $ 2** $Id: lvm.c,v 2.258 2015/11/02 11:43:17 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*/
@@ -1274,23 +1274,21 @@ void luaV_execute (lua_State *L) {
1274 vmbreak; 1274 vmbreak;
1275 } 1275 }
1276 vmcase(OP_VARARG) { 1276 vmcase(OP_VARARG) {
1277 int b = GETARG_B(i) - 1; 1277 int b = GETARG_B(i) - 1; /* required results */
1278 int j; 1278 int j;
1279 int n = cast_int(base - ci->func) - cl->p->numparams - 1; 1279 int n = cast_int(base - ci->func) - cl->p->numparams - 1;
1280 if (n < 0) /* less arguments than parameters? */
1281 n = 0; /* no vararg arguments */
1280 if (b < 0) { /* B == 0? */ 1282 if (b < 0) { /* B == 0? */
1281 b = n; /* get all var. arguments */ 1283 b = n; /* get all var. arguments */
1282 Protect(luaD_checkstack(L, n)); 1284 Protect(luaD_checkstack(L, n));
1283 ra = RA(i); /* previous call may change the stack */ 1285 ra = RA(i); /* previous call may change the stack */
1284 L->top = ra + n; 1286 L->top = ra + n;
1285 } 1287 }
1286 for (j = 0; j < b; j++) { 1288 for (j = 0; j < b && j < n; j++)
1287 if (j < n) { 1289 setobjs2s(L, ra + j, base - n + j);
1288 setobjs2s(L, ra + j, base - n + j); 1290 for (; j < b; j++) /* complete required results with nil */
1289 } 1291 setnilvalue(ra + j);
1290 else {
1291 setnilvalue(ra + j);
1292 }
1293 }
1294 vmbreak; 1292 vmbreak;
1295 } 1293 }
1296 vmcase(OP_EXTRAARG) { 1294 vmcase(OP_EXTRAARG) {