diff options
| author | Roberto I <roberto@inf.puc-rio.br> | 2025-09-16 13:26:24 -0300 |
|---|---|---|
| committer | Roberto I <roberto@inf.puc-rio.br> | 2025-09-16 13:26:24 -0300 |
| commit | 140b672e2ee2ac842661ece4b48e1a64f0cd11ea (patch) | |
| tree | b925cd1e40712ab09a75ef2c0e30095aac0af0aa /ltm.c | |
| parent | 9ea06e61f20ae34974226074fc6123dbb54a07c2 (diff) | |
| download | lua-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.c | 45 |
1 files changed, 39 insertions, 6 deletions
| @@ -224,11 +224,38 @@ int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, | |||
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | 226 | ||
| 227 | void 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 | */ | ||
| 231 | static 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 | */ | ||
| 254 | void 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 | ||
