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 | } | ||