aboutsummaryrefslogtreecommitdiff
path: root/ltm.c
diff options
context:
space:
mode:
authorRoberto I <roberto@inf.puc-rio.br>2025-09-16 13:26:24 -0300
committerRoberto I <roberto@inf.puc-rio.br>2025-09-16 13:26:24 -0300
commit140b672e2ee2ac842661ece4b48e1a64f0cd11ea (patch)
treeb925cd1e40712ab09a75ef2c0e30095aac0af0aa /ltm.c
parent9ea06e61f20ae34974226074fc6123dbb54a07c2 (diff)
downloadlua-140b672e2ee2ac842661ece4b48e1a64f0cd11ea.tar.gz
lua-140b672e2ee2ac842661ece4b48e1a64f0cd11ea.tar.bz2
lua-140b672e2ee2ac842661ece4b48e1a64f0cd11ea.zip
Vararg table
Not yet optimized nor documented.
Diffstat (limited to 'ltm.c')
-rw-r--r--ltm.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/ltm.c b/ltm.c
index d1a61a62..619be59e 100644
--- a/ltm.c
+++ b/ltm.c
@@ -224,11 +224,38 @@ int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2,
224} 224}
225 225
226 226
227void luaT_adjustvarargs (lua_State *L, int nfixparams, CallInfo *ci, 227/*
228 const Proto *p) { 228** Create a vararg table at the top of the stack, with 'n' elements
229** starting at 'f'.
230*/
231static void createvarargtab (lua_State *L, StkId f, int n) {
229 int i; 232 int i;
230 int actual = cast_int(L->top.p - ci->func.p) - 1; /* number of arguments */ 233 TValue key, value;
231 int nextra = actual - nfixparams; /* number of extra arguments */ 234 Table *t = luaH_new(L);
235 sethvalue(L, s2v(L->top.p), t);
236 L->top.p++;
237 luaH_resize(L, t, cast_uint(n), 1);
238 setsvalue(L, &key, luaS_new(L, "n")); /* key is "n" */
239 setivalue(&value, n); /* value is n */
240 /* No need to anchor the key: Due to the resize, the next operation
241 cannot trigger a garbage collection */
242 luaH_set(L, t, &key, &value); /* t.n = n */
243 for (i = 0; i < n; i++)
244 luaH_setint(L, t, i + 1, s2v(f + i));
245}
246
247
248/*
249** initial stack: func arg1 ... argn extra1 ...
250** ^ ci->func ^ L->top
251** final stack: func nil ... nil extra1 ... func arg1 ... argn
252** ^ ci->func ^ L->top
253*/
254void luaT_adjustvarargs (lua_State *L, CallInfo *ci, const Proto *p) {
255 int i;
256 int totalargs = cast_int(L->top.p - ci->func.p) - 1;
257 int nfixparams = p->numparams;
258 int nextra = totalargs - nfixparams; /* number of extra arguments */
232 ci->u.l.nextraargs = nextra; 259 ci->u.l.nextraargs = nextra;
233 luaD_checkstack(L, p->maxstacksize + 1); 260 luaD_checkstack(L, p->maxstacksize + 1);
234 /* copy function to the top of the stack */ 261 /* copy function to the top of the stack */
@@ -238,8 +265,14 @@ void luaT_adjustvarargs (lua_State *L, int nfixparams, CallInfo *ci,
238 setobjs2s(L, L->top.p++, ci->func.p + i); 265 setobjs2s(L, L->top.p++, ci->func.p + i);
239 setnilvalue(s2v(ci->func.p + i)); /* erase original parameter (for GC) */ 266 setnilvalue(s2v(ci->func.p + i)); /* erase original parameter (for GC) */
240 } 267 }
241 ci->func.p += actual + 1; 268 if (p->flag & (PF_VAPTAB | PF_VATAB)) { /* is there a vararg table? */
242 ci->top.p += actual + 1; 269 if (p->flag & PF_VAPTAB) /* is vararg table fake? */
270 setnilvalue(s2v(L->top.p)); /* initialize it */
271 else
272 createvarargtab(L, ci->func.p + nfixparams + 1, nextra);
273 }
274 ci->func.p += totalargs + 1;
275 ci->top.p += totalargs + 1;
243 lua_assert(L->top.p <= ci->top.p && ci->top.p <= L->stack_last.p); 276 lua_assert(L->top.p <= ci->top.p && ci->top.p <= L->stack_last.p);
244} 277}
245 278