mirror of https://github.com/rusefi/lua.git
in 'luaD_precall', in vararg functions, complete missing parameters
only after moving them to final place (avoids checking the stack again)
This commit is contained in:
parent
332a06bbd1
commit
c5363a1b58
28
ldo.c
28
ldo.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: ldo.c,v 2.144 2015/10/28 17:28:40 roberto Exp roberto $
|
** $Id: ldo.c,v 2.145 2015/11/02 11:48:59 roberto Exp roberto $
|
||||||
** Stack and Call structure of Lua
|
** Stack and Call structure of Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -273,15 +273,15 @@ static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
|
||||||
int i;
|
int i;
|
||||||
int nfixargs = p->numparams;
|
int nfixargs = p->numparams;
|
||||||
StkId base, fixed;
|
StkId base, fixed;
|
||||||
lua_assert(actual >= nfixargs);
|
|
||||||
/* move fixed parameters to final position */
|
/* move fixed parameters to final position */
|
||||||
luaD_checkstack(L, p->maxstacksize); /* check again for new 'base' */
|
|
||||||
fixed = L->top - actual; /* first fixed argument */
|
fixed = L->top - actual; /* first fixed argument */
|
||||||
base = L->top; /* final position of first argument */
|
base = L->top; /* final position of first argument */
|
||||||
for (i=0; i<nfixargs; i++) {
|
for (i = 0; i < nfixargs && i < actual; i++) {
|
||||||
setobjs2s(L, L->top++, fixed + i);
|
setobjs2s(L, L->top++, fixed + i);
|
||||||
setnilvalue(fixed + i);
|
setnilvalue(fixed + i); /* erase original copy (for GC) */
|
||||||
}
|
}
|
||||||
|
for (; i < nfixargs; i++)
|
||||||
|
setnilvalue(L->top++); /* complete missing arguments */
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,25 +354,23 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||||
StkId base;
|
StkId base;
|
||||||
Proto *p = clLvalue(func)->p;
|
Proto *p = clLvalue(func)->p;
|
||||||
int n = cast_int(L->top - func) - 1; /* number of real arguments */
|
int n = cast_int(L->top - func) - 1; /* number of real arguments */
|
||||||
checkstackp(L, p->maxstacksize, func);
|
int fsize = p->maxstacksize; /* frame size */
|
||||||
for (; n < p->numparams; n++)
|
checkstackp(L, fsize, func);
|
||||||
setnilvalue(L->top++); /* complete missing arguments */
|
if (p->is_vararg != 1) { /* do not use vararg? */
|
||||||
if (p->is_vararg != 1) /* do not use vararg? */
|
for (; n < p->numparams; n++)
|
||||||
|
setnilvalue(L->top++); /* complete missing arguments */
|
||||||
base = func + 1;
|
base = func + 1;
|
||||||
else {
|
|
||||||
ptrdiff_t funcr = savestack(L, func);
|
|
||||||
base = adjust_varargs(L, p, n);
|
|
||||||
func = restorestack(L, funcr); /* previous call can change stack */
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
base = adjust_varargs(L, p, n);
|
||||||
ci = next_ci(L); /* now 'enter' new function */
|
ci = next_ci(L); /* now 'enter' new function */
|
||||||
ci->nresults = nresults;
|
ci->nresults = nresults;
|
||||||
ci->func = func;
|
ci->func = func;
|
||||||
ci->u.l.base = base;
|
ci->u.l.base = base;
|
||||||
ci->top = base + p->maxstacksize;
|
L->top = ci->top = base + fsize;
|
||||||
lua_assert(ci->top <= L->stack_last);
|
lua_assert(ci->top <= L->stack_last);
|
||||||
ci->u.l.savedpc = p->code; /* starting point */
|
ci->u.l.savedpc = p->code; /* starting point */
|
||||||
ci->callstatus = CIST_LUA;
|
ci->callstatus = CIST_LUA;
|
||||||
L->top = ci->top;
|
|
||||||
if (L->hookmask & LUA_MASKCALL)
|
if (L->hookmask & LUA_MASKCALL)
|
||||||
callhook(L, ci);
|
callhook(L, ci);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
18
lvm.c
18
lvm.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lvm.c,v 2.257 2015/10/28 14:50:09 roberto Exp roberto $
|
** $Id: lvm.c,v 2.258 2015/11/02 11:43:17 roberto Exp roberto $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -1274,23 +1274,21 @@ void luaV_execute (lua_State *L) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_VARARG) {
|
vmcase(OP_VARARG) {
|
||||||
int b = GETARG_B(i) - 1;
|
int b = GETARG_B(i) - 1; /* required results */
|
||||||
int j;
|
int j;
|
||||||
int n = cast_int(base - ci->func) - cl->p->numparams - 1;
|
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? */
|
if (b < 0) { /* B == 0? */
|
||||||
b = n; /* get all var. arguments */
|
b = n; /* get all var. arguments */
|
||||||
Protect(luaD_checkstack(L, n));
|
Protect(luaD_checkstack(L, n));
|
||||||
ra = RA(i); /* previous call may change the stack */
|
ra = RA(i); /* previous call may change the stack */
|
||||||
L->top = ra + n;
|
L->top = ra + n;
|
||||||
}
|
}
|
||||||
for (j = 0; j < b; j++) {
|
for (j = 0; j < b && j < n; j++)
|
||||||
if (j < n) {
|
setobjs2s(L, ra + j, base - n + j);
|
||||||
setobjs2s(L, ra + j, base - n + j);
|
for (; j < b; j++) /* complete required results with nil */
|
||||||
}
|
setnilvalue(ra + j);
|
||||||
else {
|
|
||||||
setnilvalue(ra + j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_EXTRAARG) {
|
vmcase(OP_EXTRAARG) {
|
||||||
|
|
Loading…
Reference in New Issue