diff options
-rw-r--r-- | lcode.c | 26 | ||||
-rw-r--r-- | ldebug.c | 26 | ||||
-rw-r--r-- | ldo.c | 37 | ||||
-rw-r--r-- | ldo.h | 10 | ||||
-rw-r--r-- | lopcodes.c | 4 | ||||
-rw-r--r-- | lopcodes.h | 10 | ||||
-rw-r--r-- | lparser.c | 22 | ||||
-rw-r--r-- | lstate.h | 3 | ||||
-rw-r--r-- | ltm.c | 55 | ||||
-rw-r--r-- | ltm.h | 10 | ||||
-rw-r--r-- | lvm.c | 40 |
11 files changed, 133 insertions, 110 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 2.151 2018/01/27 16:56:33 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 2.152 2018/01/28 15:13:26 roberto Exp roberto $ |
3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -31,7 +31,7 @@ | |||
31 | 31 | ||
32 | 32 | ||
33 | /* Maximum number of registers in a Lua function (must fit in 8 bits) */ | 33 | /* Maximum number of registers in a Lua function (must fit in 8 bits) */ |
34 | #define MAXREGS 255 | 34 | #define MAXREGS 254 |
35 | 35 | ||
36 | 36 | ||
37 | #define hasjumps(e) ((e)->t != (e)->f) | 37 | #define hasjumps(e) ((e)->t != (e)->f) |
@@ -157,17 +157,17 @@ int luaK_jump (FuncState *fs) { | |||
157 | ** Code a 'return' instruction | 157 | ** Code a 'return' instruction |
158 | */ | 158 | */ |
159 | void luaK_ret (FuncState *fs, int first, int nret) { | 159 | void luaK_ret (FuncState *fs, int first, int nret) { |
160 | switch (nret) { | 160 | OpCode op; |
161 | case 0: | 161 | if (fs->f->is_vararg) |
162 | luaK_codeABC(fs, OP_RETURN0, 0, 0, 0); | 162 | op = OP_RETVARARG; |
163 | break; | 163 | else { |
164 | case 1: | 164 | switch (nret) { |
165 | luaK_codeABC(fs, OP_RETURN1, first, 0, 0); | 165 | case 0: op = OP_RETURN0; break; |
166 | break; | 166 | case 1: op = OP_RETURN1; break; |
167 | default: | 167 | default: op = OP_RETURN; break; |
168 | luaK_codeABC(fs, OP_RETURN, first, nret + 1, 0); | 168 | } |
169 | break; | ||
170 | } | 169 | } |
170 | luaK_codeABC(fs, op, first, nret + 1, fs->f->numparams); | ||
171 | } | 171 | } |
172 | 172 | ||
173 | 173 | ||
@@ -1647,7 +1647,7 @@ void luaK_finish (FuncState *fs) { | |||
1647 | lua_assert(i == 0 || isOT(*(pc - 1)) == isIT(*pc)); | 1647 | lua_assert(i == 0 || isOT(*(pc - 1)) == isIT(*pc)); |
1648 | switch (GET_OPCODE(*pc)) { | 1648 | switch (GET_OPCODE(*pc)) { |
1649 | case OP_RETURN: case OP_RETURN0: case OP_RETURN1: | 1649 | case OP_RETURN: case OP_RETURN0: case OP_RETURN1: |
1650 | case OP_TAILCALL: { | 1650 | case OP_RETVARARG: case OP_TAILCALL: { |
1651 | if (p->sizep > 0) | 1651 | if (p->sizep > 0) |
1652 | SETARG_k(*pc, 1); /* signal that they must close upvalues */ | 1652 | SETARG_k(*pc, 1); /* signal that they must close upvalues */ |
1653 | break; | 1653 | break; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.c,v 2.152 2018/01/10 12:02:35 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 2.153 2018/02/06 19:16:56 roberto Exp roberto $ |
3 | ** Debug Interface | 3 | ** Debug Interface |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -187,12 +187,28 @@ static const char *upvalname (Proto *p, int uv) { | |||
187 | } | 187 | } |
188 | 188 | ||
189 | 189 | ||
190 | static const char *findvararg (CallInfo *ci, int n, StkId *pos) { | ||
191 | if (clLvalue(s2v(ci->func))->p->is_vararg) { | ||
192 | int nextra = ci->u.l.nextraargs; | ||
193 | if (n <= nextra) { | ||
194 | *pos = ci->func - nextra + (n - 1); | ||
195 | return "(*vararg)"; /* generic name for any vararg */ | ||
196 | } | ||
197 | } | ||
198 | return NULL; /* no such vararg */ | ||
199 | } | ||
200 | |||
201 | |||
190 | static const char *findlocal (lua_State *L, CallInfo *ci, int n, | 202 | static const char *findlocal (lua_State *L, CallInfo *ci, int n, |
191 | StkId *pos) { | 203 | StkId *pos) { |
192 | StkId base = ci->func + 1; | 204 | StkId base = ci->func + 1; |
193 | const char *name = (isLua(ci)) | 205 | const char *name = NULL; |
194 | ? luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)) | 206 | if (isLua(ci)) { |
195 | : NULL; | 207 | if (n < 0) /* access to vararg values? */ |
208 | return findvararg(ci, -n, pos); | ||
209 | else | ||
210 | name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); | ||
211 | } | ||
196 | if (name == NULL) { /* no 'standard' name? */ | 212 | if (name == NULL) { /* no 'standard' name? */ |
197 | StkId limit = (ci == L->ci) ? L->top : ci->next->func; | 213 | StkId limit = (ci == L->ci) ? L->top : ci->next->func; |
198 | if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ | 214 | if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ |
@@ -324,7 +340,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | |||
324 | } | 340 | } |
325 | else { | 341 | else { |
326 | ar->isvararg = f->l.p->is_vararg; | 342 | ar->isvararg = f->l.p->is_vararg; |
327 | ar->nparams = f->l.p->numparams + f->l.p->is_vararg; | 343 | ar->nparams = f->l.p->numparams; |
328 | } | 344 | } |
329 | break; | 345 | break; |
330 | } | 346 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 2.191 2018/02/07 15:18:04 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.192 2018/02/07 15:55:18 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 | */ |
@@ -310,7 +310,7 @@ void luaD_hookcall (lua_State *L, CallInfo *ci) { | |||
310 | } | 310 | } |
311 | 311 | ||
312 | 312 | ||
313 | static void rethook (lua_State *L, CallInfo *ci) { | 313 | void luaD_rethook (lua_State *L, CallInfo *ci) { |
314 | if (isLuacode(ci)) | 314 | if (isLuacode(ci)) |
315 | L->top = ci->top; /* prepare top */ | 315 | L->top = ci->top; /* prepare top */ |
316 | if (L->hookmask & LUA_MASKRET) /* is return hook on? */ | 316 | if (L->hookmask & LUA_MASKRET) /* is return hook on? */ |
@@ -343,8 +343,8 @@ void luaD_tryfuncTM (lua_State *L, StkId func) { | |||
343 | ** expressions, multiple results for tail calls/single parameters) | 343 | ** expressions, multiple results for tail calls/single parameters) |
344 | ** separated. | 344 | ** separated. |
345 | */ | 345 | */ |
346 | static void moveresults (lua_State *L, StkId firstResult, StkId res, | 346 | void luaD_moveresults (lua_State *L, StkId firstResult, StkId res, |
347 | int nres, int wanted) { | 347 | int nres, int wanted) { |
348 | switch (wanted) { /* handle typical cases separately */ | 348 | switch (wanted) { /* handle typical cases separately */ |
349 | case 0: break; /* nothing to move */ | 349 | case 0: break; /* nothing to move */ |
350 | case 1: { /* one result needed */ | 350 | case 1: { /* one result needed */ |
@@ -382,27 +382,22 @@ static void moveresults (lua_State *L, StkId firstResult, StkId res, | |||
382 | 382 | ||
383 | /* | 383 | /* |
384 | ** Finishes a function call: calls hook if necessary, removes CallInfo, | 384 | ** Finishes a function call: calls hook if necessary, removes CallInfo, |
385 | ** moves current number of results to proper place; returns 0 iff call | 385 | ** moves current number of results to proper place. |
386 | ** wanted multiple (variable number of) results. | ||
387 | */ | 386 | */ |
388 | void luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) { | 387 | void luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) { |
389 | if (L->hookmask) { | 388 | if (L->hookmask) { |
390 | ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ | 389 | ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ |
391 | rethook(L, ci); | 390 | luaD_rethook(L, ci); |
392 | firstResult = restorestack(L, fr); | 391 | firstResult = restorestack(L, fr); |
393 | } | 392 | } |
394 | L->ci = ci->previous; /* back to caller */ | 393 | L->ci = ci->previous; /* back to caller */ |
395 | /* move results to proper place */ | 394 | /* move results to proper place */ |
396 | moveresults(L, firstResult, ci->func, nres, ci->nresults); | 395 | luaD_moveresults(L, firstResult, ci->func, nres, ci->nresults); |
397 | } | 396 | } |
398 | 397 | ||
399 | 398 | ||
400 | 399 | ||
401 | #define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L)) | 400 | #define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) |
402 | |||
403 | |||
404 | #define checkstackGC(L,fsize) \ | ||
405 | luaD_checkstackaux(L, (fsize), (void)0, luaC_checkGC(L)) | ||
406 | 401 | ||
407 | 402 | ||
408 | /* | 403 | /* |
@@ -438,8 +433,6 @@ void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) { | |||
438 | void luaD_call (lua_State *L, StkId func, int nresults) { | 433 | void luaD_call (lua_State *L, StkId func, int nresults) { |
439 | lua_CFunction f; | 434 | lua_CFunction f; |
440 | TValue *funcv = s2v(func); | 435 | TValue *funcv = s2v(func); |
441 | CallInfo *ci = next_ci(L); | ||
442 | ci->nresults = nresults; | ||
443 | switch (ttype(funcv)) { | 436 | switch (ttype(funcv)) { |
444 | case LUA_TCCL: /* C closure */ | 437 | case LUA_TCCL: /* C closure */ |
445 | f = clCvalue(funcv)->f; | 438 | f = clCvalue(funcv)->f; |
@@ -448,12 +441,14 @@ void luaD_call (lua_State *L, StkId func, int nresults) { | |||
448 | f = fvalue(funcv); | 441 | f = fvalue(funcv); |
449 | Cfunc: { | 442 | Cfunc: { |
450 | int n; /* number of returns */ | 443 | int n; /* number of returns */ |
444 | CallInfo *ci; | ||
451 | checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ | 445 | checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ |
446 | ci = next_ci(L); | ||
447 | ci->nresults = nresults; | ||
452 | ci->callstatus = CIST_C; | 448 | ci->callstatus = CIST_C; |
453 | ci->top = L->top + LUA_MINSTACK; | 449 | ci->top = L->top + LUA_MINSTACK; |
454 | ci->func = func; | 450 | ci->func = func; |
455 | lua_assert(ci->top <= L->stack_last); | 451 | lua_assert(ci->top <= L->stack_last); |
456 | L->ci = ci; /* now 'enter' new function */ | ||
457 | if (L->hookmask & LUA_MASKCALL) | 452 | if (L->hookmask & LUA_MASKCALL) |
458 | luaD_hook(L, LUA_HOOKCALL, -1); | 453 | luaD_hook(L, LUA_HOOKCALL, -1); |
459 | lua_unlock(L); | 454 | lua_unlock(L); |
@@ -464,18 +459,20 @@ void luaD_call (lua_State *L, StkId func, int nresults) { | |||
464 | break; | 459 | break; |
465 | } | 460 | } |
466 | case LUA_TLCL: { /* Lua function */ | 461 | case LUA_TLCL: { /* Lua function */ |
462 | CallInfo *ci; | ||
467 | Proto *p = clLvalue(funcv)->p; | 463 | Proto *p = clLvalue(funcv)->p; |
468 | int narg = cast_int(L->top - func) - 1; /* number of real arguments */ | 464 | int narg = cast_int(L->top - func) - 1; /* number of real arguments */ |
469 | int nfixparams = p->numparams; | 465 | int nfixparams = p->numparams; |
470 | int fsize = p->maxstacksize; /* frame size */ | 466 | int fsize = p->maxstacksize; /* frame size */ |
471 | ci->u.l.savedpc = p->code; /* starting point */ | ||
472 | checkstackp(L, fsize, func); | 467 | checkstackp(L, fsize, func); |
473 | for (; narg < nfixparams; narg++) | 468 | ci = next_ci(L); |
474 | setnilvalue(s2v(L->top++)); /* complete missing arguments */ | 469 | ci->nresults = nresults; |
470 | ci->u.l.savedpc = p->code; /* starting point */ | ||
475 | ci->callstatus = 0; | 471 | ci->callstatus = 0; |
476 | ci->top = func + 1 + fsize; | 472 | ci->top = func + 1 + fsize; |
477 | ci->func = func; | 473 | ci->func = func; |
478 | L->ci = ci; /* now 'enter' new function */ | 474 | for (; narg < nfixparams; narg++) |
475 | setnilvalue(s2v(L->top++)); /* complete missing arguments */ | ||
479 | lua_assert(ci->top <= L->stack_last); | 476 | lua_assert(ci->top <= L->stack_last); |
480 | luaV_execute(L, ci); /* run the function */ | 477 | luaV_execute(L, ci); /* run the function */ |
481 | break; | 478 | break; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.h,v 2.39 2018/01/10 19:19:27 roberto Exp roberto $ | 2 | ** $Id: ldo.h,v 2.40 2018/02/06 19:16:56 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 | */ |
@@ -42,6 +42,11 @@ | |||
42 | p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ | 42 | p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ |
43 | 43 | ||
44 | 44 | ||
45 | /* macro to check stack size and GC */ | ||
46 | #define checkstackGC(L,fsize) \ | ||
47 | luaD_checkstackaux(L, (fsize), (void)0, luaC_checkGC(L)) | ||
48 | |||
49 | |||
45 | /* type of protected functions, to be ran by 'runprotected' */ | 50 | /* type of protected functions, to be ran by 'runprotected' */ |
46 | typedef void (*Pfunc) (lua_State *L, void *ud); | 51 | typedef void (*Pfunc) (lua_State *L, void *ud); |
47 | 52 | ||
@@ -57,7 +62,10 @@ LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, | |||
57 | ptrdiff_t oldtop, ptrdiff_t ef); | 62 | ptrdiff_t oldtop, ptrdiff_t ef); |
58 | LUAI_FUNC void luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, | 63 | LUAI_FUNC void luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, |
59 | int nres); | 64 | int nres); |
65 | LUAI_FUNC void luaD_rethook (lua_State *L, CallInfo *ci); | ||
60 | LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror); | 66 | LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror); |
67 | LUAI_FUNC void luaD_moveresults (lua_State *L, StkId firstResult, StkId res, | ||
68 | int nres, int wanted); | ||
61 | LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror); | 69 | LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror); |
62 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); | 70 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); |
63 | LUAI_FUNC void luaD_inctop (lua_State *L); | 71 | LUAI_FUNC void luaD_inctop (lua_State *L); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.c,v 1.75 2017/12/22 14:16:46 roberto Exp roberto $ | 2 | ** $Id: lopcodes.c,v 1.76 2018/02/07 15:18:04 roberto Exp roberto $ |
3 | ** Opcodes for Lua virtual machine | 3 | ** Opcodes for Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -80,6 +80,7 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { | |||
80 | "CALL", | 80 | "CALL", |
81 | "TAILCALL", | 81 | "TAILCALL", |
82 | "RETURN", | 82 | "RETURN", |
83 | "RETVARARG", | ||
83 | "RETURN0", | 84 | "RETURN0", |
84 | "RETURN1", | 85 | "RETURN1", |
85 | "FORLOOP1", | 86 | "FORLOOP1", |
@@ -161,6 +162,7 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { | |||
161 | ,opmode(1, 1, 0, 1, iABC) /* OP_CALL */ | 162 | ,opmode(1, 1, 0, 1, iABC) /* OP_CALL */ |
162 | ,opmode(1, 1, 0, 1, iABC) /* OP_TAILCALL */ | 163 | ,opmode(1, 1, 0, 1, iABC) /* OP_TAILCALL */ |
163 | ,opmode(0, 1, 0, 0, iABC) /* OP_RETURN */ | 164 | ,opmode(0, 1, 0, 0, iABC) /* OP_RETURN */ |
165 | ,opmode(0, 1, 0, 0, iABC) /* OP_RETVARARG */ | ||
164 | ,opmode(0, 0, 0, 0, iABC) /* OP_RETURN0 */ | 166 | ,opmode(0, 0, 0, 0, iABC) /* OP_RETURN0 */ |
165 | ,opmode(0, 0, 0, 0, iABC) /* OP_RETURN1 */ | 167 | ,opmode(0, 0, 0, 0, iABC) /* OP_RETURN1 */ |
166 | ,opmode(0, 0, 0, 1, iABx) /* OP_FORLOOP1 */ | 168 | ,opmode(0, 0, 0, 1, iABx) /* OP_FORLOOP1 */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.h,v 1.184 2018/01/28 15:13:26 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.186 2018/02/07 15:18:04 roberto Exp roberto $ |
3 | ** Opcodes for Lua virtual machine | 3 | ** Opcodes for Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -268,6 +268,7 @@ OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ | |||
268 | OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ | 268 | OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ |
269 | 269 | ||
270 | OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ | 270 | OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ |
271 | OP_RETVARARG,/* A B return R(A), ... ,R(A+B-2) (see note) */ | ||
271 | OP_RETURN0,/* return */ | 272 | OP_RETURN0,/* return */ |
272 | OP_RETURN1,/* A return R(A) */ | 273 | OP_RETURN1,/* A return R(A) */ |
273 | 274 | ||
@@ -286,7 +287,7 @@ OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */ | |||
286 | 287 | ||
287 | OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */ | 288 | OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */ |
288 | 289 | ||
289 | OP_VARARG,/* A B C R(A), R(A+1), ..., R(A+C-2) = vararg(B) */ | 290 | OP_VARARG,/* A B C R(A), R(A+1), ..., R(A+C-2) = vararg */ |
290 | 291 | ||
291 | OP_PREPVARARG,/*A (adjust vararg parameters) */ | 292 | OP_PREPVARARG,/*A (adjust vararg parameters) */ |
292 | 293 | ||
@@ -305,9 +306,10 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ | |||
305 | OP_SETLIST) may use 'top'. | 306 | OP_SETLIST) may use 'top'. |
306 | 307 | ||
307 | (*) In OP_VARARG, if (C == 0) then use actual number of varargs and | 308 | (*) In OP_VARARG, if (C == 0) then use actual number of varargs and |
308 | set top (like in OP_CALL with C == 0). B is the vararg parameter. | 309 | set top (like in OP_CALL with C == 0). |
309 | 310 | ||
310 | (*) In OP_RETURN, if (B == 0) then return up to 'top'. | 311 | (*) In OP_RETURN/OP_RETVARARG, if (B == 0) then return up to 'top'. |
312 | (OP_RETVARARG is the return instruction for vararg functions.) | ||
311 | 313 | ||
312 | (*) In OP_SETLIST, if (B == 0) then real B = 'top'; if (C == 0) then | 314 | (*) In OP_SETLIST, if (B == 0) then real B = 'top'; if (C == 0) then |
313 | next 'instruction' is EXTRAARG(real C). | 315 | next 'instruction' is EXTRAARG(real C). |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 2.175 2017/12/22 14:16:46 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 2.176 2018/02/07 15:18:04 roberto Exp roberto $ |
3 | ** Lua Parser | 3 | ** Lua Parser |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -568,6 +568,7 @@ static void close_func (LexState *ls) { | |||
568 | Proto *f = fs->f; | 568 | Proto *f = fs->f; |
569 | luaK_ret(fs, 0, 0); /* final return */ | 569 | luaK_ret(fs, 0, 0); /* final return */ |
570 | leaveblock(fs); | 570 | leaveblock(fs); |
571 | lua_assert(fs->bl == NULL); | ||
571 | luaK_finish(fs); | 572 | luaK_finish(fs); |
572 | luaM_shrinkvector(L, f->code, f->sizecode, fs->pc, Instruction); | 573 | luaM_shrinkvector(L, f->code, f->sizecode, fs->pc, Instruction); |
573 | luaM_shrinkvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte); | 574 | luaM_shrinkvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte); |
@@ -577,7 +578,8 @@ static void close_func (LexState *ls) { | |||
577 | luaM_shrinkvector(L, f->p, f->sizep, fs->np, Proto *); | 578 | luaM_shrinkvector(L, f->p, f->sizep, fs->np, Proto *); |
578 | luaM_shrinkvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); | 579 | luaM_shrinkvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); |
579 | luaM_shrinkvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); | 580 | luaM_shrinkvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); |
580 | lua_assert(fs->bl == NULL); | 581 | if (f->is_vararg) |
582 | f->maxstacksize++; /* ensure space to copy the function */ | ||
581 | ls->fs = fs->prev; | 583 | ls->fs = fs->prev; |
582 | luaC_checkGC(L); | 584 | luaC_checkGC(L); |
583 | } | 585 | } |
@@ -781,11 +783,6 @@ static void parlist (LexState *ls) { | |||
781 | } | 783 | } |
782 | case TK_DOTS: { /* param -> '...' */ | 784 | case TK_DOTS: { /* param -> '...' */ |
783 | luaX_next(ls); | 785 | luaX_next(ls); |
784 | if (testnext(ls, '=')) | ||
785 | new_localvar(ls, str_checkname(ls)); | ||
786 | else | ||
787 | new_localvarliteral(ls, "_ARG"); | ||
788 | nparams++; | ||
789 | isvararg = 1; | 786 | isvararg = 1; |
790 | break; | 787 | break; |
791 | } | 788 | } |
@@ -795,10 +792,8 @@ static void parlist (LexState *ls) { | |||
795 | } | 792 | } |
796 | adjustlocalvars(ls, nparams); | 793 | adjustlocalvars(ls, nparams); |
797 | f->numparams = cast_byte(fs->nactvar); | 794 | f->numparams = cast_byte(fs->nactvar); |
798 | if (isvararg) { | 795 | if (isvararg) |
799 | f->numparams--; /* exclude vararg parameter */ | ||
800 | setvararg(fs, f->numparams); /* declared vararg */ | 796 | setvararg(fs, f->numparams); /* declared vararg */ |
801 | } | ||
802 | luaK_reserveregs(fs, fs->nactvar); /* reserve registers for parameters */ | 797 | luaK_reserveregs(fs, fs->nactvar); /* reserve registers for parameters */ |
803 | } | 798 | } |
804 | 799 | ||
@@ -984,10 +979,9 @@ static void simpleexp (LexState *ls, expdesc *v) { | |||
984 | } | 979 | } |
985 | case TK_DOTS: { /* vararg */ | 980 | case TK_DOTS: { /* vararg */ |
986 | FuncState *fs = ls->fs; | 981 | FuncState *fs = ls->fs; |
987 | int lastparam = fs->f->numparams; | ||
988 | check_condition(ls, fs->f->is_vararg, | 982 | check_condition(ls, fs->f->is_vararg, |
989 | "cannot use '...' outside a vararg function"); | 983 | "cannot use '...' outside a vararg function"); |
990 | init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, lastparam, 1)); | 984 | init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 0, 1)); |
991 | break; | 985 | break; |
992 | } | 986 | } |
993 | case '{': { /* constructor */ | 987 | case '{': { /* constructor */ |
@@ -1703,10 +1697,6 @@ static void mainfunc (LexState *ls, FuncState *fs) { | |||
1703 | expdesc v; | 1697 | expdesc v; |
1704 | open_func(ls, fs, &bl); | 1698 | open_func(ls, fs, &bl); |
1705 | setvararg(fs, 0); /* main function is always declared vararg */ | 1699 | setvararg(fs, 0); /* main function is always declared vararg */ |
1706 | fs->f->numparams = 0; | ||
1707 | new_localvarliteral(ls, "_ARG"); | ||
1708 | adjustlocalvars(ls, 1); | ||
1709 | luaK_reserveregs(fs, 1); /* reserve register for vararg */ | ||
1710 | init_exp(&v, VLOCAL, 0); /* create and... */ | 1700 | init_exp(&v, VLOCAL, 0); /* create and... */ |
1711 | newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ | 1701 | newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ |
1712 | luaX_next(ls); /* read first token */ | 1702 | luaX_next(ls); /* read first token */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.h,v 2.152 2017/11/23 16:35:54 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 2.153 2017/12/19 16:40:17 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -92,6 +92,7 @@ typedef struct CallInfo { | |||
92 | struct { /* only for Lua functions */ | 92 | struct { /* only for Lua functions */ |
93 | const Instruction *savedpc; | 93 | const Instruction *savedpc; |
94 | l_signalT trap; | 94 | l_signalT trap; |
95 | int nextraargs; /* # of extra arguments in vararg functions */ | ||
95 | } l; | 96 | } l; |
96 | struct { /* only for C functions */ | 97 | struct { /* only for C functions */ |
97 | lua_KFunction k; /* continuation in case of yields */ | 98 | lua_KFunction k; /* continuation in case of yields */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltm.c,v 2.58 2018/01/28 13:39:52 roberto Exp roberto $ | 2 | ** $Id: ltm.c,v 2.59 2018/02/07 15:18:04 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 | */ |
@@ -216,41 +216,32 @@ int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, | |||
216 | } | 216 | } |
217 | 217 | ||
218 | 218 | ||
219 | void luaT_adjustvarargs (lua_State *L, int nfixparams, StkId base) { | 219 | void luaT_adjustvarargs (lua_State *L, int nfixparams, CallInfo *ci) { |
220 | int i; | 220 | int i; |
221 | Table *vtab; | 221 | int actual = cast_int(L->top - ci->func) - 1; /* number of arguments */ |
222 | TValue nname; | ||
223 | int actual = cast_int(L->top - base); /* number of arguments */ | ||
224 | int nextra = actual - nfixparams; /* number of extra arguments */ | 222 | int nextra = actual - nfixparams; /* number of extra arguments */ |
225 | vtab = luaH_new(L); /* create vararg table */ | 223 | ci->u.l.nextraargs = nextra; |
226 | sethvalue2s(L, L->top, vtab); /* anchor it for resizing */ | 224 | checkstackGC(L, nfixparams + 1); |
227 | L->top++; /* space ensured by caller */ | 225 | /* copy function and fixed parameters to the top of the stack */ |
228 | luaH_resize(L, vtab, nextra, 1); | 226 | for (i = 0; i <= nfixparams; i++) { |
229 | for (i = 0; i < nextra; i++) /* put extra arguments into vararg table */ | 227 | setobjs2s(L, L->top++, ci->func + i); |
230 | setobj2n(L, &vtab->array[i], s2v(L->top - nextra + i - 1)); | 228 | setnilvalue(s2v(ci->func + i)); /* erase original copy (for GC) */ |
231 | setsvalue(L, &nname, G(L)->nfield); /* get field 'n' */ | 229 | } |
232 | setivalue(luaH_set(L, vtab, &nname), nextra); /* store counter there */ | 230 | ci->func += actual + 1; |
233 | L->top -= nextra; /* remove extra elements from the stack */ | 231 | ci->top += actual + 1; |
234 | sethvalue2s(L, L->top - 1, vtab); /* move table to new top */ | ||
235 | luaC_checkGC(L); | ||
236 | } | 232 | } |
237 | 233 | ||
238 | 234 | ||
239 | void luaT_getvarargs (lua_State *L, TValue *t, StkId where, int wanted) { | 235 | void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) { |
240 | if (!ttistable(t)) | 236 | int i; |
241 | luaG_runerror(L, "'vararg' parameter is not a table"); | 237 | int nextra = ci->u.l.nextraargs; |
242 | else { | 238 | if (wanted < 0) { |
243 | int i; | 239 | wanted = nextra; /* get all extra arguments available */ |
244 | Table *h = hvalue(t); | 240 | checkstackp(L, nextra, where); /* ensure stack space */ |
245 | if (wanted < 0) { /* get all? */ | 241 | L->top = where + nextra; /* next instruction will need top */ |
246 | const TValue *ns = luaH_getstr(h, G(L)->nfield); | ||
247 | int n = (ttisinteger(ns)) ? cast_int(ivalue(ns)) : 0; | ||
248 | wanted = n; | ||
249 | checkstackp(L, n, where); | ||
250 | L->top = where + n; | ||
251 | } | ||
252 | for (i = 0; i < wanted; i++) /* get what is available */ | ||
253 | setobj2s(L, where + i, luaH_getint(h, i + 1)); | ||
254 | return; | ||
255 | } | 242 | } |
243 | for (i = 0; i < wanted && i < nextra; i++) | ||
244 | setobjs2s(L, where + i, ci->func - nextra + i); | ||
245 | for (; i < wanted; i++) /* complete required results with nil */ | ||
246 | setnilvalue(s2v(where + i)); | ||
256 | } | 247 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltm.h,v 2.29 2018/01/28 13:39:52 roberto Exp roberto $ | 2 | ** $Id: ltm.h,v 2.30 2018/02/07 15:18:04 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 | */ |
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | 10 | ||
11 | #include "lobject.h" | 11 | #include "lobject.h" |
12 | #include "lstate.h" | ||
12 | 13 | ||
13 | 14 | ||
14 | /* | 15 | /* |
@@ -77,9 +78,10 @@ LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, | |||
77 | LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, | 78 | LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, |
78 | int inv, TMS event); | 79 | int inv, TMS event); |
79 | 80 | ||
80 | LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams, StkId base); | 81 | LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams, |
81 | LUAI_FUNC void luaT_getvarargs (lua_State *L, TValue *t, StkId where, | 82 | struct CallInfo *ci); |
82 | int wanted); | 83 | LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci, |
84 | StkId where, int wanted); | ||
83 | 85 | ||
84 | 86 | ||
85 | #endif | 87 | #endif |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.337 2018/02/06 19:16:56 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.338 2018/02/07 15:18:04 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -1506,14 +1506,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1506 | luaF_close(L, base); /* close upvalues from current call */ | 1506 | luaF_close(L, base); /* close upvalues from current call */ |
1507 | if (!ttisLclosure(vra)) { /* C function? */ | 1507 | if (!ttisLclosure(vra)) { /* C function? */ |
1508 | ProtectNT(luaD_call(L, ra, LUA_MULTRET)); /* call it */ | 1508 | ProtectNT(luaD_call(L, ra, LUA_MULTRET)); /* call it */ |
1509 | if (trap) { | ||
1510 | updatebase(ci); | ||
1511 | ra = RA(i); | ||
1512 | } | ||
1513 | luaD_poscall(L, ci, ra, cast_int(L->top - ra)); | ||
1514 | return; | ||
1515 | } | 1509 | } |
1516 | else { /* Lua tail call */ | 1510 | else { /* Lua tail call */ |
1511 | if (cl->p->is_vararg) | ||
1512 | ci->func -= cl->p->numparams + ci->u.l.nextraargs + 1; | ||
1517 | luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ | 1513 | luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ |
1518 | goto tailcall; | 1514 | goto tailcall; |
1519 | } | 1515 | } |
@@ -1521,11 +1517,30 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1521 | } | 1517 | } |
1522 | vmcase(OP_RETURN) { | 1518 | vmcase(OP_RETURN) { |
1523 | int b = GETARG_B(i); | 1519 | int b = GETARG_B(i); |
1520 | int n = (b != 0 ? b - 1 : cast_int(L->top - ra)); | ||
1521 | if (TESTARG_k(i)) | ||
1522 | luaF_close(L, base); | ||
1523 | halfProtect(luaD_poscall(L, ci, ra, n)); | ||
1524 | return; | ||
1525 | } | ||
1526 | vmcase(OP_RETVARARG) { | ||
1527 | int b = GETARG_B(i); | ||
1528 | int nparams = GETARG_C(i); | ||
1529 | int nres = (b != 0 ? b - 1 : cast_int(L->top - ra)); | ||
1530 | int delta = ci->u.l.nextraargs + nparams + 2; | ||
1524 | if (TESTARG_k(i)) | 1531 | if (TESTARG_k(i)) |
1525 | luaF_close(L, base); | 1532 | luaF_close(L, base); |
1526 | halfProtect( | 1533 | savepc(L); |
1527 | luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra))) | 1534 | /* code similar to 'luaD_poscall', but with a delta */ |
1528 | ); | 1535 | if (L->hookmask) { |
1536 | luaD_rethook(L, ci); | ||
1537 | if (ci->u.l.trap) { | ||
1538 | updatebase(ci); | ||
1539 | ra = RA(i); | ||
1540 | } | ||
1541 | } | ||
1542 | L->ci = ci->previous; /* back to caller */ | ||
1543 | luaD_moveresults(L, ra, base - delta, nres, ci->nresults); | ||
1529 | return; | 1544 | return; |
1530 | } | 1545 | } |
1531 | vmcase(OP_RETURN0) { | 1546 | vmcase(OP_RETURN0) { |
@@ -1702,12 +1717,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1702 | } | 1717 | } |
1703 | vmcase(OP_VARARG) { | 1718 | vmcase(OP_VARARG) { |
1704 | int n = GETARG_C(i) - 1; /* required results */ | 1719 | int n = GETARG_C(i) - 1; /* required results */ |
1705 | TValue *vtab = vRB(i); /* vararg table */ | 1720 | ProtectNT(luaT_getvarargs(L, ci, ra, n)); |
1706 | Protect(luaT_getvarargs(L, vtab, ra, n)); | ||
1707 | vmbreak; | 1721 | vmbreak; |
1708 | } | 1722 | } |
1709 | vmcase(OP_PREPVARARG) { | 1723 | vmcase(OP_PREPVARARG) { |
1710 | luaT_adjustvarargs(L, GETARG_A(i), base); | 1724 | luaT_adjustvarargs(L, GETARG_A(i), ci); |
1711 | updatetrap(ci); | 1725 | updatetrap(ci); |
1712 | if (trap) { | 1726 | if (trap) { |
1713 | luaD_hookcall(L, ci); | 1727 | luaD_hookcall(L, ci); |