aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c12
-rw-r--r--ldebug.c8
-rw-r--r--ldo.c2
-rw-r--r--lobject.h10
-rw-r--r--lopcodes.h31
-rw-r--r--lparser.c6
-rw-r--r--ltm.c39
-rw-r--r--manual/manual.of2
-rw-r--r--testes/db.lua3
9 files changed, 70 insertions, 43 deletions
diff --git a/lcode.c b/lcode.c
index afed05d1..b0a81421 100644
--- a/lcode.c
+++ b/lcode.c
@@ -806,7 +806,7 @@ void luaK_setoneret (FuncState *fs, expdesc *e) {
806** Change a vararg parameter into a regular local variable 806** Change a vararg parameter into a regular local variable
807*/ 807*/
808void luaK_vapar2local (FuncState *fs, expdesc *var) { 808void luaK_vapar2local (FuncState *fs, expdesc *var) {
809 fs->f->flag |= PF_VATAB; /* function will need a vararg table */ 809 needvatab(fs->f); /* function will need a vararg table */
810 /* now a vararg parameter is equivalent to a regular local variable */ 810 /* now a vararg parameter is equivalent to a regular local variable */
811 var->k = VLOCAL; 811 var->k = VLOCAL;
812} 812}
@@ -1127,7 +1127,7 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
1127 break; 1127 break;
1128 } 1128 }
1129 case VVARGIND: { 1129 case VVARGIND: {
1130 fs->f->flag |= PF_VATAB; /* function will need a vararg table */ 1130 needvatab(fs->f); /* function will need a vararg table */
1131 /* now, assignment is to a regular table */ 1131 /* now, assignment is to a regular table */
1132 } /* FALLTHROUGH */ 1132 } /* FALLTHROUGH */
1133 case VINDEXED: { 1133 case VINDEXED: {
@@ -1927,6 +1927,8 @@ static int finaltarget (Instruction *code, int i) {
1927void luaK_finish (FuncState *fs) { 1927void luaK_finish (FuncState *fs) {
1928 int i; 1928 int i;
1929 Proto *p = fs->f; 1929 Proto *p = fs->f;
1930 if (p->flag & PF_VATAB) /* will it use a vararg table? */
1931 p->flag &= cast_byte(~PF_VAHID); /* then it will not use hidden args. */
1930 for (i = 0; i < fs->pc; i++) { 1932 for (i = 0; i < fs->pc; i++) {
1931 Instruction *pc = &p->code[i]; 1933 Instruction *pc = &p->code[i];
1932 /* avoid "not used" warnings when assert is off (for 'onelua.c') */ 1934 /* avoid "not used" warnings when assert is off (for 'onelua.c') */
@@ -1934,7 +1936,7 @@ void luaK_finish (FuncState *fs) {
1934 lua_assert(i == 0 || luaP_isOT(*(pc - 1)) == luaP_isIT(*pc)); 1936 lua_assert(i == 0 || luaP_isOT(*(pc - 1)) == luaP_isIT(*pc));
1935 switch (GET_OPCODE(*pc)) { 1937 switch (GET_OPCODE(*pc)) {
1936 case OP_RETURN0: case OP_RETURN1: { 1938 case OP_RETURN0: case OP_RETURN1: {
1937 if (!(fs->needclose || (p->flag & PF_ISVARARG))) 1939 if (!(fs->needclose || (p->flag & PF_VAHID)))
1938 break; /* no extra work */ 1940 break; /* no extra work */
1939 /* else use OP_RETURN to do the extra work */ 1941 /* else use OP_RETURN to do the extra work */
1940 SET_OPCODE(*pc, OP_RETURN); 1942 SET_OPCODE(*pc, OP_RETURN);
@@ -1942,8 +1944,8 @@ void luaK_finish (FuncState *fs) {
1942 case OP_RETURN: case OP_TAILCALL: { 1944 case OP_RETURN: case OP_TAILCALL: {
1943 if (fs->needclose) 1945 if (fs->needclose)
1944 SETARG_k(*pc, 1); /* signal that it needs to close */ 1946 SETARG_k(*pc, 1); /* signal that it needs to close */
1945 if (p->flag & PF_ISVARARG) 1947 if (p->flag & PF_VAHID) /* does it use hidden arguments? */
1946 SETARG_C(*pc, p->numparams + 1); /* signal that it is vararg */ 1948 SETARG_C(*pc, p->numparams + 1); /* signal that */
1947 break; 1949 break;
1948 } 1950 }
1949 case OP_GETVARG: { 1951 case OP_GETVARG: {
diff --git a/ldebug.c b/ldebug.c
index abead91c..8df5f5f2 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -184,7 +184,7 @@ static const char *upvalname (const Proto *p, int uv) {
184 184
185 185
186static const char *findvararg (CallInfo *ci, int n, StkId *pos) { 186static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
187 if (clLvalue(s2v(ci->func.p))->p->flag & PF_ISVARARG) { 187 if (clLvalue(s2v(ci->func.p))->p->flag & PF_VAHID) {
188 int nextra = ci->u.l.nextraargs; 188 int nextra = ci->u.l.nextraargs;
189 if (n >= -nextra) { /* 'n' is negative */ 189 if (n >= -nextra) { /* 'n' is negative */
190 *pos = ci->func.p - nextra - (n + 1); 190 *pos = ci->func.p - nextra - (n + 1);
@@ -304,7 +304,7 @@ static void collectvalidlines (lua_State *L, Closure *f) {
304 int i; 304 int i;
305 TValue v; 305 TValue v;
306 setbtvalue(&v); /* boolean 'true' to be the value of all indices */ 306 setbtvalue(&v); /* boolean 'true' to be the value of all indices */
307 if (!(p->flag & PF_ISVARARG)) /* regular function? */ 307 if (!(isvararg(p))) /* regular function? */
308 i = 0; /* consider all instructions */ 308 i = 0; /* consider all instructions */
309 else { /* vararg function */ 309 else { /* vararg function */
310 lua_assert(GET_OPCODE(p->code[0]) == OP_VARARGPREP); 310 lua_assert(GET_OPCODE(p->code[0]) == OP_VARARGPREP);
@@ -348,7 +348,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
348 ar->nparams = 0; 348 ar->nparams = 0;
349 } 349 }
350 else { 350 else {
351 ar->isvararg = (f->l.p->flag & PF_ISVARARG) ? 1 : 0; 351 ar->isvararg = (isvararg(f->l.p)) ? 1 : 0;
352 ar->nparams = f->l.p->numparams; 352 ar->nparams = f->l.p->numparams;
353 } 353 }
354 break; 354 break;
@@ -912,7 +912,7 @@ int luaG_tracecall (lua_State *L) {
912 Proto *p = ci_func(ci)->p; 912 Proto *p = ci_func(ci)->p;
913 ci->u.l.trap = 1; /* ensure hooks will be checked */ 913 ci->u.l.trap = 1; /* ensure hooks will be checked */
914 if (ci->u.l.savedpc == p->code) { /* first instruction (not resuming)? */ 914 if (ci->u.l.savedpc == p->code) { /* first instruction (not resuming)? */
915 if (p->flag & PF_ISVARARG) 915 if (isvararg(p))
916 return 0; /* hooks will start at VARARGPREP instruction */ 916 return 0; /* hooks will start at VARARGPREP instruction */
917 else if (!(ci->callstatus & CIST_HOOKYIELD)) /* not yielded? */ 917 else if (!(ci->callstatus & CIST_HOOKYIELD)) /* not yielded? */
918 luaD_hookcall(L, ci); /* check 'call' hook */ 918 luaD_hookcall(L, ci); /* check 'call' hook */
diff --git a/ldo.c b/ldo.c
index 44937068..75ce1488 100644
--- a/ldo.c
+++ b/ldo.c
@@ -487,7 +487,7 @@ static void rethook (lua_State *L, CallInfo *ci, int nres) {
487 int ftransfer; 487 int ftransfer;
488 if (isLua(ci)) { 488 if (isLua(ci)) {
489 Proto *p = ci_func(ci)->p; 489 Proto *p = ci_func(ci)->p;
490 if (p->flag & PF_ISVARARG) 490 if (p->flag & PF_VAHID)
491 delta = ci->u.l.nextraargs + p->numparams + 1; 491 delta = ci->u.l.nextraargs + p->numparams + 1;
492 } 492 }
493 ci->func.p += delta; /* if vararg, back to virtual 'func' */ 493 ci->func.p += delta; /* if vararg, back to virtual 'func' */
diff --git a/lobject.h b/lobject.h
index 070f12a4..156c942f 100644
--- a/lobject.h
+++ b/lobject.h
@@ -583,10 +583,18 @@ typedef struct AbsLineInfo {
583/* 583/*
584** Flags in Prototypes 584** Flags in Prototypes
585*/ 585*/
586#define PF_ISVARARG 1 /* function is vararg */ 586#define PF_VAHID 1 /* function has hidden vararg arguments */
587#define PF_VATAB 2 /* function has vararg table */ 587#define PF_VATAB 2 /* function has vararg table */
588#define PF_FIXED 4 /* prototype has parts in fixed memory */ 588#define PF_FIXED 4 /* prototype has parts in fixed memory */
589 589
590/* a vararg function either has hidden args. or a vararg table */
591#define isvararg(p) ((p)->flag & (PF_VAHID | PF_VATAB))
592
593/*
594** mark that a function needs a vararg table. (The flag PF_VAHID will
595** be cleared later.)
596*/
597#define needvatab(p) ((p)->flag |= PF_VATAB)
590 598
591/* 599/*
592** Function Prototypes 600** Function Prototypes
diff --git a/lopcodes.h b/lopcodes.h
index fac87da2..b6bd182e 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -224,8 +224,8 @@ enum OpMode {iABC, ivABC, iABx, iAsBx, iAx, isJ};
224 224
225 225
226/* 226/*
227** Grep "ORDER OP" if you change these enums. Opcodes marked with a (*) 227** Grep "ORDER OP" if you change this enum.
228** has extra descriptions in the notes after the enumeration. 228** See "Notes" below for more information about some instructions.
229*/ 229*/
230 230
231typedef enum { 231typedef enum {
@@ -238,7 +238,7 @@ OP_LOADF,/* A sBx R[A] := (lua_Number)sBx */
238OP_LOADK,/* A Bx R[A] := K[Bx] */ 238OP_LOADK,/* A Bx R[A] := K[Bx] */
239OP_LOADKX,/* A R[A] := K[extra arg] */ 239OP_LOADKX,/* A R[A] := K[extra arg] */
240OP_LOADFALSE,/* A R[A] := false */ 240OP_LOADFALSE,/* A R[A] := false */
241OP_LFALSESKIP,/*A R[A] := false; pc++ (*) */ 241OP_LFALSESKIP,/*A R[A] := false; pc++ */
242OP_LOADTRUE,/* A R[A] := true */ 242OP_LOADTRUE,/* A R[A] := true */
243OP_LOADNIL,/* A B R[A], R[A+1], ..., R[A+B] := nil */ 243OP_LOADNIL,/* A B R[A], R[A+1], ..., R[A+B] := nil */
244OP_GETUPVAL,/* A B R[A] := UpValue[B] */ 244OP_GETUPVAL,/* A B R[A] := UpValue[B] */
@@ -289,7 +289,7 @@ OP_BXOR,/* A B C R[A] := R[B] ~ R[C] */
289OP_SHL,/* A B C R[A] := R[B] << R[C] */ 289OP_SHL,/* A B C R[A] := R[B] << R[C] */
290OP_SHR,/* A B C R[A] := R[B] >> R[C] */ 290OP_SHR,/* A B C R[A] := R[B] >> R[C] */
291 291
292OP_MMBIN,/* A B C call C metamethod over R[A] and R[B] (*) */ 292OP_MMBIN,/* A B C call C metamethod over R[A] and R[B] */
293OP_MMBINI,/* A sB C k call C metamethod over R[A] and sB */ 293OP_MMBINI,/* A sB C k call C metamethod over R[A] and sB */
294OP_MMBINK,/* A B C k call C metamethod over R[A] and K[B] */ 294OP_MMBINK,/* A B C k call C metamethod over R[A] and K[B] */
295 295
@@ -315,12 +315,12 @@ OP_GTI,/* A sB k if ((R[A] > sB) ~= k) then pc++ */
315OP_GEI,/* A sB k if ((R[A] >= sB) ~= k) then pc++ */ 315OP_GEI,/* A sB k if ((R[A] >= sB) ~= k) then pc++ */
316 316
317OP_TEST,/* A k if (not R[A] == k) then pc++ */ 317OP_TEST,/* A k if (not R[A] == k) then pc++ */
318OP_TESTSET,/* A B k if (not R[B] == k) then pc++ else R[A] := R[B] (*) */ 318OP_TESTSET,/* A B k if (not R[B] == k) then pc++ else R[A] := R[B] */
319 319
320OP_CALL,/* A B C R[A], ... ,R[A+C-2] := R[A](R[A+1], ... ,R[A+B-1]) */ 320OP_CALL,/* A B C R[A], ... ,R[A+C-2] := R[A](R[A+1], ... ,R[A+B-1]) */
321OP_TAILCALL,/* A B C k return R[A](R[A+1], ... ,R[A+B-1]) */ 321OP_TAILCALL,/* A B C k return R[A](R[A+1], ... ,R[A+B-1]) */
322 322
323OP_RETURN,/* A B C k return R[A], ... ,R[A+B-2] (see note) */ 323OP_RETURN,/* A B C k return R[A], ... ,R[A+B-2] */
324OP_RETURN0,/* return */ 324OP_RETURN0,/* return */
325OP_RETURN1,/* A return R[A] */ 325OP_RETURN1,/* A return R[A] */
326 326
@@ -336,13 +336,13 @@ OP_SETLIST,/* A vB vC k R[A][vC+i] := R[A+i], 1 <= i <= vB */
336 336
337OP_CLOSURE,/* A Bx R[A] := closure(KPROTO[Bx]) */ 337OP_CLOSURE,/* A Bx R[A] := closure(KPROTO[Bx]) */
338 338
339OP_VARARG,/* A C R[A], ..., R[A+C-2] = vararg, R[B] is vararg param. */ 339OP_VARARG,/* A B C k R[A], ..., R[A+C-2] = varargs */
340 340
341OP_GETVARG, /* A B C R[A] := R[B][R[C]], R[B] is vararg parameter */ 341OP_GETVARG, /* A B C R[A] := R[B][R[C]], R[B] is vararg parameter */
342 342
343OP_ERRNNIL,/* A Bx raise error if R[A] ~= nil (K[Bx - 1] is global name)*/ 343OP_ERRNNIL,/* A Bx raise error if R[A] ~= nil (K[Bx - 1] is global name)*/
344 344
345OP_VARARGPREP,/* (adjust vararg parameters) */ 345OP_VARARGPREP,/* (adjust varargs) */
346 346
347OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ 347OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
348} OpCode; 348} OpCode;
@@ -371,7 +371,8 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
371 OP_RETURN*, OP_SETLIST) may use 'top'. 371 OP_RETURN*, OP_SETLIST) may use 'top'.
372 372
373 (*) In OP_VARARG, if (C == 0) then use actual number of varargs and 373 (*) In OP_VARARG, if (C == 0) then use actual number of varargs and
374 set top (like in OP_CALL with C == 0). 374 set top (like in OP_CALL with C == 0). 'k' means function has a
375 vararg table, which is in R[B].
375 376
376 (*) In OP_RETURN, if (B == 0) then return up to 'top'. 377 (*) In OP_RETURN, if (B == 0) then return up to 'top'.
377 378
@@ -387,20 +388,22 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
387 is vC. Otherwise, the array size is EXTRAARG _ vC. 388 is vC. Otherwise, the array size is EXTRAARG _ vC.
388 389
389 (*) In OP_ERRNNIL, (Bx == 0) means index of global name doesn't 390 (*) In OP_ERRNNIL, (Bx == 0) means index of global name doesn't
390 fit in Bx. (So, that name is not available for the instruction.) 391 fit in Bx. (So, that name is not available for the error message.)
391 392
392 (*) For comparisons, k specifies what condition the test should accept 393 (*) For comparisons, k specifies what condition the test should accept
393 (true or false). 394 (true or false).
394 395
395 (*) In OP_MMBINI/OP_MMBINK, k means the arguments were flipped 396 (*) In OP_MMBINI/OP_MMBINK, k means the arguments were flipped
396 (the constant is the first operand). 397 (the constant is the first operand).
397 398
398 (*) All 'skips' (pc++) assume that next instruction is a jump. 399 (*) All comparison and test instructions assume that the instruction
400 being skipped (pc++) is a jump.
399 401
400 (*) In instructions OP_RETURN/OP_TAILCALL, 'k' specifies that the 402 (*) In instructions OP_RETURN/OP_TAILCALL, 'k' specifies that the
401 function builds upvalues, which may need to be closed. C > 0 means 403 function builds upvalues, which may need to be closed. C > 0 means
402 the function is vararg, so that its 'func' must be corrected before 404 the function has hidden vararg arguments, so that its 'func' must be
403 returning; in this case, (C - 1) is its number of fixed parameters. 405 corrected before returning; in this case, (C - 1) is its number of
406 fixed parameters.
404 407
405 (*) In comparisons with an immediate operand, C signals whether the 408 (*) In comparisons with an immediate operand, C signals whether the
406 original operand was a float. (It must be corrected in case of 409 original operand was a float. (It must be corrected in case of
diff --git a/lparser.c b/lparser.c
index a07044b8..e015dfc5 100644
--- a/lparser.c
+++ b/lparser.c
@@ -304,7 +304,7 @@ static void check_readonly (LexState *ls, expdesc *e) {
304 break; 304 break;
305 } 305 }
306 case VVARGIND: { 306 case VVARGIND: {
307 fs->f->flag |= PF_VATAB; /* function will need a vararg table */ 307 needvatab(fs->f); /* function will need a vararg table */
308 e->k = VINDEXED; 308 e->k = VINDEXED;
309 } /* FALLTHROUGH */ 309 } /* FALLTHROUGH */
310 case VINDEXUP: case VINDEXSTR: case VINDEXED: { /* global variable */ 310 case VINDEXUP: case VINDEXSTR: case VINDEXED: { /* global variable */
@@ -1057,7 +1057,7 @@ static void constructor (LexState *ls, expdesc *t) {
1057 1057
1058 1058
1059static void setvararg (FuncState *fs) { 1059static void setvararg (FuncState *fs) {
1060 fs->f->flag |= PF_ISVARARG; 1060 fs->f->flag |= PF_VAHID; /* by default, use hidden vararg arguments */
1061 luaK_codeABC(fs, OP_VARARGPREP, 0, 0, 0); 1061 luaK_codeABC(fs, OP_VARARGPREP, 0, 0, 0);
1062} 1062}
1063 1063
@@ -1283,7 +1283,7 @@ static void simpleexp (LexState *ls, expdesc *v) {
1283 } 1283 }
1284 case TK_DOTS: { /* vararg */ 1284 case TK_DOTS: { /* vararg */
1285 FuncState *fs = ls->fs; 1285 FuncState *fs = ls->fs;
1286 check_condition(ls, fs->f->flag & PF_ISVARARG, 1286 check_condition(ls, isvararg(fs->f),
1287 "cannot use '...' outside a vararg function"); 1287 "cannot use '...' outside a vararg function");
1288 init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, fs->f->numparams, 1)); 1288 init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, fs->f->numparams, 1));
1289 break; 1289 break;
diff --git a/ltm.c b/ltm.c
index 39ac59d4..f2a373f8 100644
--- a/ltm.c
+++ b/ltm.c
@@ -250,31 +250,42 @@ static void createvarargtab (lua_State *L, StkId f, int n) {
250** initial stack: func arg1 ... argn extra1 ... 250** initial stack: func arg1 ... argn extra1 ...
251** ^ ci->func ^ L->top 251** ^ ci->func ^ L->top
252** final stack: func nil ... nil extra1 ... func arg1 ... argn 252** final stack: func nil ... nil extra1 ... func arg1 ... argn
253** ^ ci->func ^ L->top 253** ^ ci->func
254*/ 254*/
255void luaT_adjustvarargs (lua_State *L, CallInfo *ci, const Proto *p) { 255static void buildhiddenargs (lua_State *L, CallInfo *ci, const Proto *p,
256 int totalargs, int nfixparams, int nextra) {
256 int i; 257 int i;
257 int totalargs = cast_int(L->top.p - ci->func.p) - 1;
258 int nfixparams = p->numparams;
259 int nextra = totalargs - nfixparams; /* number of extra arguments */
260 ci->u.l.nextraargs = nextra; 258 ci->u.l.nextraargs = nextra;
261 luaD_checkstack(L, p->maxstacksize + 1); 259 luaD_checkstack(L, p->maxstacksize + 1);
262 /* copy function to the top of the stack */ 260 /* copy function to the top of the stack, after extra arguments */
263 setobjs2s(L, L->top.p++, ci->func.p); 261 setobjs2s(L, L->top.p++, ci->func.p);
264 /* move fixed parameters to the top of the stack */ 262 /* move fixed parameters to after the copied function */
265 for (i = 1; i <= nfixparams; i++) { 263 for (i = 1; i <= nfixparams; i++) {
266 setobjs2s(L, L->top.p++, ci->func.p + i); 264 setobjs2s(L, L->top.p++, ci->func.p + i);
267 setnilvalue(s2v(ci->func.p + i)); /* erase original parameter (for GC) */ 265 setnilvalue(s2v(ci->func.p + i)); /* erase original parameter (for GC) */
268 } 266 }
269 if (p->flag & PF_VATAB) /* does it need a vararg table? */ 267 ci->func.p += totalargs + 1; /* 'func' now lives after hidden arguments */
268 ci->top.p += totalargs + 1;
269}
270
271
272void luaT_adjustvarargs (lua_State *L, CallInfo *ci, const Proto *p) {
273 int totalargs = cast_int(L->top.p - ci->func.p) - 1;
274 int nfixparams = p->numparams;
275 int nextra = totalargs - nfixparams; /* number of extra arguments */
276 if (p->flag & PF_VATAB) { /* does it need a vararg table? */
277 lua_assert(!(p->flag & PF_VAHID));
270 createvarargtab(L, ci->func.p + nfixparams + 1, nextra); 278 createvarargtab(L, ci->func.p + nfixparams + 1, nextra);
271 else { /* no table; set parameter to nil */ 279 /* move table to proper place (last parameter) */
272 setnilvalue(s2v(L->top.p)); 280 setobjs2s(L, ci->func.p + nfixparams + 1, L->top.p - 1);
273 L->top.p++; 281 }
282 else { /* no table */
283 lua_assert(p->flag & PF_VAHID);
284 buildhiddenargs(L, ci, p, totalargs, nfixparams, nextra);
285 /* set vararg parameter to nil */
286 setnilvalue(s2v(ci->func.p + nfixparams + 1));
287 lua_assert(L->top.p <= ci->top.p && ci->top.p <= L->stack_last.p);
274 } 288 }
275 ci->func.p += totalargs + 1;
276 ci->top.p += totalargs + 1;
277 lua_assert(L->top.p <= ci->top.p && ci->top.p <= L->stack_last.p);
278} 289}
279 290
280 291
diff --git a/manual/manual.of b/manual/manual.of
index 9b8e144d..54f67b3e 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -2425,7 +2425,7 @@ The conditions are as follows:
2425If the vararg table has a name, 2425If the vararg table has a name,
2426that name is not an upvalue in a nested function 2426that name is not an upvalue in a nested function
2427and it is used only as the base table 2427and it is used only as the base table
2428in the syntactic constructions @T{t[exp]} or @T{t.id}). 2428in the syntactic constructions @T{t[exp]} or @T{t.id}.
2429Note that an anonymous vararg table always satisfy these conditions. 2429Note that an anonymous vararg table always satisfy these conditions.
2430 2430
2431} 2431}
diff --git a/testes/db.lua b/testes/db.lua
index 4220b68b..e15a5be6 100644
--- a/testes/db.lua
+++ b/testes/db.lua
@@ -726,6 +726,9 @@ assert(t.isvararg == false and t.nparams == 3 and t.nups == 0)
726t = debug.getinfo(function (a,b,...) return t[a] end, "u") 726t = debug.getinfo(function (a,b,...) return t[a] end, "u")
727assert(t.isvararg == true and t.nparams == 2 and t.nups == 1) 727assert(t.isvararg == true and t.nparams == 2 and t.nups == 1)
728 728
729t = debug.getinfo(function (a,b,...t) t.n = 2; return t[a] end, "u")
730assert(t.isvararg == true and t.nparams == 2 and t.nups == 0)
731
729t = debug.getinfo(1) -- main 732t = debug.getinfo(1) -- main
730assert(t.isvararg == true and t.nparams == 0 and t.nups == 1 and 733assert(t.isvararg == true and t.nparams == 0 and t.nups == 1 and
731 debug.getupvalue(t.func, 1) == "_ENV") 734 debug.getupvalue(t.func, 1) == "_ENV")