diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-11-02 12:06:01 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-11-02 12:06:01 -0200 |
commit | c5363a1b58573162ef13ba4a345bd48ad3c355d9 (patch) | |
tree | 7c4ee5559a42ce93d770aa0253f0695439a7d2e3 | |
parent | 332a06bbd1a8835c810e52bbf68014d6956b50b8 (diff) | |
download | lua-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.c | 28 | ||||
-rw-r--r-- | lvm.c | 18 |
2 files changed, 21 insertions, 25 deletions
@@ -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; |
@@ -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) { |