diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-05-13 10:04:33 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-05-13 10:04:33 -0300 |
| commit | 5c8770f8969a73cf4ca503f54c2217f76de62e04 (patch) | |
| tree | d5dac87490011d117277d94c81f6f2fd47b1b094 /ltm.c | |
| parent | 7647d5d13d016f114dac4be0b9da62d502eab400 (diff) | |
| download | lua-5c8770f8969a73cf4ca503f54c2217f76de62e04.tar.gz lua-5c8770f8969a73cf4ca503f54c2217f76de62e04.tar.bz2 lua-5c8770f8969a73cf4ca503f54c2217f76de62e04.zip | |
back to old-style vararg system (with vararg table collecting extra
arguments)
Diffstat (limited to 'ltm.c')
| -rw-r--r-- | ltm.c | 40 |
1 files changed, 39 insertions, 1 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltm.c,v 2.39 2017/04/11 18:41:09 roberto Exp roberto $ | 2 | ** $Id: ltm.c,v 2.40 2017/05/08 15:57:23 roberto Exp roberto $ |
| 3 | ** Tag methods | 3 | ** Tag methods |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -163,3 +163,41 @@ int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2, | |||
| 163 | return !l_isfalse(L->top); | 163 | return !l_isfalse(L->top); |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | |||
| 167 | void luaT_adjustvarargs (lua_State *L, Proto *p, int actual) { | ||
| 168 | int i; | ||
| 169 | Table *vtab; | ||
| 170 | TValue nname; | ||
| 171 | int nfixparams = p->numparams - 1; /* number of fixed parameters */ | ||
| 172 | actual -= nfixparams; /* number of extra arguments */ | ||
| 173 | vtab = luaH_new(L); /* create vararg table */ | ||
| 174 | sethvalue(L, L->top, vtab); /* anchor it for resizing */ | ||
| 175 | L->top++; /* space ensured by caller */ | ||
| 176 | luaH_resize(L, vtab, actual, 1); | ||
| 177 | for (i = 0; i < actual; i++) /* put extra arguments into vararg table */ | ||
| 178 | setobj2n(L, &vtab->array[i], L->top - actual + i - 1); | ||
| 179 | setsvalue(L, &nname, luaS_newliteral(L, "n")); /* get field 'n' */ | ||
| 180 | setivalue(luaH_set(L, vtab, &nname), actual); /* store counter there */ | ||
| 181 | L->top -= actual; /* remove extra elements from the stack */ | ||
| 182 | sethvalue(L, L->top - 1, vtab); /* move table to new top */ | ||
| 183 | } | ||
| 184 | |||
| 185 | |||
| 186 | void luaT_getvarargs (lua_State *L, StkId t, StkId where, int wanted) { | ||
| 187 | if (!ttistable(t)) | ||
| 188 | luaG_runerror(L, "'vararg' parameter is not a table"); | ||
| 189 | else { | ||
| 190 | int i; | ||
| 191 | Table *h = hvalue(t); | ||
| 192 | if (wanted < 0) { /* get all? */ | ||
| 193 | const TValue *ns = luaH_getstr(h, luaS_newliteral(L, "n")); | ||
| 194 | int n = (ttisinteger(ns)) ? ivalue(ns) : 0; | ||
| 195 | wanted = n; | ||
| 196 | checkstackp(L, n, where); | ||
| 197 | L->top = where + n; | ||
| 198 | } | ||
| 199 | for (i = 0; i < wanted; i++) /* get what is available */ | ||
| 200 | setobj2s(L, where + i, luaH_getint(h, i + 1)); | ||
| 201 | return; | ||
| 202 | } | ||
| 203 | } | ||
