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) { |
