summaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-05-31 15:51:50 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-05-31 15:51:50 -0300
commit616438fe9ab5e3ae7d73e9ad838e9b7bdea1ea59 (patch)
tree78322d820e3af1ca6645ed08eaa65a8f0aa04fec /ldo.c
parent47eda6ebd83785908ac26f8dd06dff36a7d42664 (diff)
downloadlua-616438fe9ab5e3ae7d73e9ad838e9b7bdea1ea59.tar.gz
lua-616438fe9ab5e3ae7d73e9ad838e9b7bdea1ea59.tar.bz2
lua-616438fe9ab5e3ae7d73e9ad838e9b7bdea1ea59.zip
new way to use `vararg' parameters (with `...')
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c66
1 files changed, 43 insertions, 23 deletions
diff --git a/ldo.c b/ldo.c
index fc1caa7f..293e66a3 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.4 2004/05/10 17:50:51 roberto Exp roberto $ 2** $Id: ldo.c,v 2.5 2004/05/14 19:25:09 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*/
@@ -113,6 +113,7 @@ static void correctstack (lua_State *L, TValue *oldstack) {
113 for (ci = L->base_ci; ci <= L->ci; ci++) { 113 for (ci = L->base_ci; ci <= L->ci; ci++) {
114 ci->top = (ci->top - oldstack) + L->stack; 114 ci->top = (ci->top - oldstack) + L->stack;
115 ci->base = (ci->base - oldstack) + L->stack; 115 ci->base = (ci->base - oldstack) + L->stack;
116 ci->func = (ci->func - oldstack) + L->stack;
116 } 117 }
117 L->base = L->ci->base; 118 L->base = L->ci->base;
118} 119}
@@ -181,26 +182,37 @@ void luaD_callhook (lua_State *L, int event, int line) {
181} 182}
182 183
183 184
184static void adjust_varargs (lua_State *L, int nfixargs, StkId base) { 185static StkId adjust_varargs (lua_State *L, int nfixargs, int actual,
186 int style) {
185 int i; 187 int i;
186 Table *htab; 188 Table *htab = NULL;
187 int actual = L->top - base; /* actual number of arguments */ 189 StkId base, fixed;
188 if (actual < nfixargs) { 190 if (actual < nfixargs) {
189 luaD_checkstack(L, nfixargs - actual);
190 for (; actual < nfixargs; ++actual) 191 for (; actual < nfixargs; ++actual)
191 setnilvalue(L->top++); 192 setnilvalue(L->top++);
192 } 193 }
193 actual -= nfixargs; /* number of extra arguments */ 194 if (style != NEWSTYLEVARARG) { /* compatibility with old-style vararg */
194 htab = luaH_new(L, actual, 1); /* create `arg' table */ 195 int nvar = actual - nfixargs; /* number of extra arguments */
195 for (i=0; i<actual; i++) /* put extra arguments into `arg' table */ 196 htab = luaH_new(L, nvar, 1); /* create `arg' table */
196 setobj2n(L, luaH_setnum(L, htab, i+LUA_FIRSTINDEX), L->top - actual + i); 197 for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */
197 /* store counter in field `n' */ 198 setobj2n(L, luaH_setnum(L, htab, i+LUA_FIRSTINDEX), L->top - nvar + i);
198 setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), 199 /* store counter in field `n' */
199 cast(lua_Number, actual)); 200 setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")),
200 L->top -= actual; /* remove extra elements from the stack */ 201 cast(lua_Number, nvar));
201 sethvalue(L, L->top, htab); 202 }
202 lua_assert(iswhite(obj2gco(htab))); 203 /* move fixed parameters to final position */
203 incr_top(L); 204 fixed = L->top - actual; /* first fixed argument */
205 base = L->top; /* final position of first argument */
206 for (i=0; i<nfixargs; i++) {
207 setobjs2s(L, L->top++, fixed+i);
208 setnilvalue(fixed+i);
209 }
210 /* add `arg' parameter */
211 if (htab) {
212 sethvalue(L, L->top++, htab);
213 lua_assert(iswhite(obj2gco(htab)));
214 }
215 return base;
204} 216}
205 217
206 218
@@ -221,21 +233,28 @@ static StkId tryfuncTM (lua_State *L, StkId func) {
221 233
222int luaD_precall (lua_State *L, StkId func, int nresults) { 234int luaD_precall (lua_State *L, StkId func, int nresults) {
223 LClosure *cl; 235 LClosure *cl;
224 ptrdiff_t funcr = savestack(L, func); 236 ptrdiff_t funcr;
225 if (!ttisfunction(func)) /* `func' is not a function? */ 237 if (!ttisfunction(func)) /* `func' is not a function? */
226 func = tryfuncTM(L, func); /* check the `function' tag method */ 238 func = tryfuncTM(L, func); /* check the `function' tag method */
239 funcr = savestack(L, func);
227 if (L->ci + 1 == L->end_ci) luaD_growCI(L); 240 if (L->ci + 1 == L->end_ci) luaD_growCI(L);
228 else condhardstacktests(luaD_reallocCI(L, L->size_ci)); 241 else condhardstacktests(luaD_reallocCI(L, L->size_ci));
229 cl = &clvalue(func)->l; 242 cl = &clvalue(func)->l;
230 if (!cl->isC) { /* Lua function? prepare its call */ 243 if (!cl->isC) { /* Lua function? prepare its call */
231 CallInfo *ci; 244 CallInfo *ci;
232 StkId st; 245 StkId st, base;
233 Proto *p = cl->p; 246 Proto *p = cl->p;
234 if (p->is_vararg) /* varargs? */
235 adjust_varargs(L, p->numparams, func+1);
236 luaD_checkstack(L, p->maxstacksize); 247 luaD_checkstack(L, p->maxstacksize);
248 func = restorestack(L, funcr);
249 if (p->is_vararg) { /* varargs? */
250 int nargs = L->top - func - 1;
251 base = adjust_varargs(L, p->numparams, nargs, p->is_vararg);
252 }
253 else
254 base = func + 1;
237 ci = ++L->ci; /* now `enter' new function */ 255 ci = ++L->ci; /* now `enter' new function */
238 L->base = L->ci->base = restorestack(L, funcr) + 1; 256 ci->func = func;
257 L->base = ci->base = base;
239 ci->top = L->base + p->maxstacksize; 258 ci->top = L->base + p->maxstacksize;
240 ci->u.l.savedpc = p->code; /* starting point */ 259 ci->u.l.savedpc = p->code; /* starting point */
241 ci->u.l.tailcalls = 0; 260 ci->u.l.tailcalls = 0;
@@ -250,7 +269,8 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
250 int n; 269 int n;
251 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 270 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
252 ci = ++L->ci; /* now `enter' new function */ 271 ci = ++L->ci; /* now `enter' new function */
253 L->base = L->ci->base = restorestack(L, funcr) + 1; 272 ci->func = restorestack(L, funcr);
273 L->base = ci->base = ci->func + 1;
254 ci->top = L->top + LUA_MINSTACK; 274 ci->top = L->top + LUA_MINSTACK;
255 if (L->hookmask & LUA_MASKCALL) 275 if (L->hookmask & LUA_MASKCALL)
256 luaD_callhook(L, LUA_HOOKCALL, -1); 276 luaD_callhook(L, LUA_HOOKCALL, -1);
@@ -284,7 +304,7 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
284 StkId res; 304 StkId res;
285 if (L->hookmask & LUA_MASKRET) 305 if (L->hookmask & LUA_MASKRET)
286 firstResult = callrethooks(L, firstResult); 306 firstResult = callrethooks(L, firstResult);
287 res = L->base - 1; /* res == final position of 1st result */ 307 res = L->ci->func; /* res == final position of 1st result */
288 L->ci--; 308 L->ci--;
289 L->base = L->ci->base; /* restore base */ 309 L->base = L->ci->base; /* restore base */
290 /* move results to correct place */ 310 /* move results to correct place */