aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c5
-rw-r--r--lobject.h5
-rw-r--r--lopcodes.h2
-rw-r--r--lparser.c24
-rw-r--r--ltm.c64
-rw-r--r--ltm.h4
-rw-r--r--lvm.c5
-rw-r--r--manual/manual.of68
-rw-r--r--testes/coroutine.lua4
-rw-r--r--testes/db.lua9
-rw-r--r--testes/vararg.lua33
11 files changed, 154 insertions, 69 deletions
diff --git a/lcode.c b/lcode.c
index 95ef900c..afed05d1 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1951,6 +1951,11 @@ void luaK_finish (FuncState *fs) {
1951 SET_OPCODE(*pc, OP_GETTABLE); /* must get vararg there */ 1951 SET_OPCODE(*pc, OP_GETTABLE); /* must get vararg there */
1952 break; 1952 break;
1953 } 1953 }
1954 case OP_VARARG: {
1955 if (p->flag & PF_VATAB) /* function has a vararg table? */
1956 SETARG_k(*pc, 1); /* must get vararg there */
1957 break;
1958 }
1954 case OP_JMP: { /* to optimize jumps to jumps */ 1959 case OP_JMP: { /* to optimize jumps to jumps */
1955 int target = finaltarget(p->code, i); 1960 int target = finaltarget(p->code, i);
1956 fixjump(fs, i, target); /* jump directly to final target */ 1961 fixjump(fs, i, target); /* jump directly to final target */
diff --git a/lobject.h b/lobject.h
index 841ab5b9..070f12a4 100644
--- a/lobject.h
+++ b/lobject.h
@@ -584,9 +584,8 @@ typedef struct AbsLineInfo {
584** Flags in Prototypes 584** Flags in Prototypes
585*/ 585*/
586#define PF_ISVARARG 1 /* function is vararg */ 586#define PF_ISVARARG 1 /* function is vararg */
587#define PF_VAVAR 2 /* function has vararg parameter */ 587#define PF_VATAB 2 /* function has vararg table */
588#define PF_VATAB 4 /* function has vararg table */ 588#define PF_FIXED 4 /* prototype has parts in fixed memory */
589#define PF_FIXED 8 /* prototype has parts in fixed memory */
590 589
591 590
592/* 591/*
diff --git a/lopcodes.h b/lopcodes.h
index f5c95151..fac87da2 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -336,7 +336,7 @@ 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+1], ..., R[A+C-2] = vararg */ 339OP_VARARG,/* A C R[A], ..., R[A+C-2] = vararg, R[B] is vararg param. */
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
diff --git a/lparser.c b/lparser.c
index 77141e79..a07044b8 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1056,9 +1056,8 @@ static void constructor (LexState *ls, expdesc *t) {
1056/* }====================================================================== */ 1056/* }====================================================================== */
1057 1057
1058 1058
1059static void setvararg (FuncState *fs, int kind) { 1059static void setvararg (FuncState *fs) {
1060 lua_assert(kind & PF_ISVARARG); 1060 fs->f->flag |= PF_ISVARARG;
1061 fs->f->flag |= cast_byte(kind);
1062 luaK_codeABC(fs, OP_VARARGPREP, 0, 0, 0); 1061 luaK_codeABC(fs, OP_VARARGPREP, 0, 0, 0);
1063} 1062}
1064 1063
@@ -1078,12 +1077,12 @@ static void parlist (LexState *ls) {
1078 break; 1077 break;
1079 } 1078 }
1080 case TK_DOTS: { 1079 case TK_DOTS: {
1081 varargk |= PF_ISVARARG; 1080 varargk = 1;
1082 luaX_next(ls); /* skip '...' */ 1081 luaX_next(ls); /* skip '...' */
1083 if (ls->t.token == TK_NAME) { 1082 if (ls->t.token == TK_NAME)
1084 new_varkind(ls, str_checkname(ls), RDKVAVAR); 1083 new_varkind(ls, str_checkname(ls), RDKVAVAR);
1085 varargk |= PF_VAVAR; 1084 else
1086 } 1085 new_localvarliteral(ls, "(vararg table)");
1087 break; 1086 break;
1088 } 1087 }
1089 default: luaX_syntaxerror(ls, "<name> or '...' expected"); 1088 default: luaX_syntaxerror(ls, "<name> or '...' expected");
@@ -1092,10 +1091,9 @@ static void parlist (LexState *ls) {
1092 } 1091 }
1093 adjustlocalvars(ls, nparams); 1092 adjustlocalvars(ls, nparams);
1094 f->numparams = cast_byte(fs->nactvar); 1093 f->numparams = cast_byte(fs->nactvar);
1095 if (varargk != 0) { 1094 if (varargk) {
1096 setvararg(fs, varargk); /* declared vararg */ 1095 setvararg(fs); /* declared vararg */
1097 if (varargk & PF_VAVAR) 1096 adjustlocalvars(ls, 1); /* vararg parameter */
1098 adjustlocalvars(ls, 1); /* vararg parameter */
1099 } 1097 }
1100 /* reserve registers for parameters (plus vararg parameter, if present) */ 1098 /* reserve registers for parameters (plus vararg parameter, if present) */
1101 luaK_reserveregs(fs, fs->nactvar); 1099 luaK_reserveregs(fs, fs->nactvar);
@@ -1287,7 +1285,7 @@ static void simpleexp (LexState *ls, expdesc *v) {
1287 FuncState *fs = ls->fs; 1285 FuncState *fs = ls->fs;
1288 check_condition(ls, fs->f->flag & PF_ISVARARG, 1286 check_condition(ls, fs->f->flag & PF_ISVARARG,
1289 "cannot use '...' outside a vararg function"); 1287 "cannot use '...' outside a vararg function");
1290 init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 0, 1)); 1288 init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, fs->f->numparams, 1));
1291 break; 1289 break;
1292 } 1290 }
1293 case '{' /*}*/: { /* constructor */ 1291 case '{' /*}*/: { /* constructor */
@@ -2153,7 +2151,7 @@ static void mainfunc (LexState *ls, FuncState *fs) {
2153 BlockCnt bl; 2151 BlockCnt bl;
2154 Upvaldesc *env; 2152 Upvaldesc *env;
2155 open_func(ls, fs, &bl); 2153 open_func(ls, fs, &bl);
2156 setvararg(fs, PF_ISVARARG); /* main function is always vararg */ 2154 setvararg(fs); /* main function is always vararg */
2157 env = allocupvalue(fs); /* ...set environment upvalue */ 2155 env = allocupvalue(fs); /* ...set environment upvalue */
2158 env->instack = 1; 2156 env->instack = 1;
2159 env->idx = 0; 2157 env->idx = 0;
diff --git a/ltm.c b/ltm.c
index 8d64235e..39ac59d4 100644
--- a/ltm.c
+++ b/ltm.c
@@ -242,6 +242,7 @@ static void createvarargtab (lua_State *L, StkId f, int n) {
242 luaH_set(L, t, &key, &value); /* t.n = n */ 242 luaH_set(L, t, &key, &value); /* t.n = n */
243 for (i = 0; i < n; i++) 243 for (i = 0; i < n; i++)
244 luaH_setint(L, t, i + 1, s2v(f + i)); 244 luaH_setint(L, t, i + 1, s2v(f + i));
245 luaC_checkGC(L);
245} 246}
246 247
247 248
@@ -265,11 +266,11 @@ void luaT_adjustvarargs (lua_State *L, CallInfo *ci, const Proto *p) {
265 setobjs2s(L, L->top.p++, ci->func.p + i); 266 setobjs2s(L, L->top.p++, ci->func.p + i);
266 setnilvalue(s2v(ci->func.p + i)); /* erase original parameter (for GC) */ 267 setnilvalue(s2v(ci->func.p + i)); /* erase original parameter (for GC) */
267 } 268 }
268 if (p->flag & PF_VAVAR) { /* is there a vararg parameter? */ 269 if (p->flag & PF_VATAB) /* does it need a vararg table? */
269 if (p->flag & PF_VATAB) /* does it need a vararg table? */ 270 createvarargtab(L, ci->func.p + nfixparams + 1, nextra);
270 createvarargtab(L, ci->func.p + nfixparams + 1, nextra); 271 else { /* no table; set parameter to nil */
271 else /* no table; set parameter to nil */ 272 setnilvalue(s2v(L->top.p));
272 setnilvalue(s2v(L->top.p)); 273 L->top.p++;
273 } 274 }
274 ci->func.p += totalargs + 1; 275 ci->func.p += totalargs + 1;
275 ci->top.p += totalargs + 1; 276 ci->top.p += totalargs + 1;
@@ -299,16 +300,53 @@ void luaT_getvararg (CallInfo *ci, StkId ra, TValue *rc) {
299} 300}
300 301
301 302
302void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) { 303/*
303 int i; 304** Get the number of extra arguments in a vararg function. If vararg
304 int nextra = ci->u.l.nextraargs; 305** table has been optimized away, that number is in the call info.
306** Otherwise, get the field 'n' from the vararg table and check that it
307** has a proper value (non-negative integer not larger than the stack
308** limit).
309*/
310static int getnumargs (lua_State *L, CallInfo *ci, Table *h) {
311 if (h == NULL) /* no vararg table? */
312 return ci->u.l.nextraargs;
313 else {
314 TValue res;
315 if (luaH_getshortstr(h, luaS_new(L, "n"), &res) != LUA_VNUMINT ||
316 l_castS2U(ivalue(&res)) > cast_uint(INT_MAX/2))
317 luaG_runerror(L, "vararg table has no proper 'n'");
318 return cast_int(ivalue(&res));
319 }
320}
321
322
323/*
324** Get 'wanted' vararg arguments and put them in 'where'. 'vatab' is
325** the register of the vararg table or -1 if there is no vararg table.
326*/
327void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted,
328 int vatab) {
329 Table *h = (vatab < 0) ? NULL : hvalue(s2v(ci->func.p + vatab + 1));
330 int nargs = getnumargs(L, ci, h); /* number of available vararg args. */
331 int i, touse; /* 'touse' is minimum between 'wanted' and 'nargs' */
305 if (wanted < 0) { 332 if (wanted < 0) {
306 wanted = nextra; /* get all extra arguments available */ 333 touse = wanted = nargs; /* get all extra arguments available */
307 checkstackp(L, nextra, where); /* ensure stack space */ 334 checkstackp(L, nargs, where); /* ensure stack space */
308 L->top.p = where + nextra; /* next instruction will need top */ 335 L->top.p = where + nargs; /* next instruction will need top */
336 }
337 else
338 touse = (nargs > wanted) ? wanted : nargs;
339 if (h == NULL) { /* no vararg table? */
340 for (i = 0; i < touse; i++) /* get vararg values from the stack */
341 setobjs2s(L, where + i, ci->func.p - nargs + i);
342 }
343 else { /* get vararg values from vararg table */
344 for (i = 0; i < touse; i++) {
345 lu_byte tag = luaH_getint(h, i + 1, s2v(where + i));
346 if (tagisempty(tag))
347 setnilvalue(s2v(where + i));
348 }
309 } 349 }
310 for (i = 0; i < wanted && i < nextra; i++)
311 setobjs2s(L, where + i, ci->func.p - nextra + i);
312 for (; i < wanted; i++) /* complete required results with nil */ 350 for (; i < wanted; i++) /* complete required results with nil */
313 setnilvalue(s2v(where + i)); 351 setnilvalue(s2v(where + i));
314} 352}
diff --git a/ltm.h b/ltm.h
index 86f457eb..07fc8c1c 100644
--- a/ltm.h
+++ b/ltm.h
@@ -98,8 +98,8 @@ LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2,
98LUAI_FUNC void luaT_adjustvarargs (lua_State *L, struct CallInfo *ci, 98LUAI_FUNC void luaT_adjustvarargs (lua_State *L, struct CallInfo *ci,
99 const Proto *p); 99 const Proto *p);
100LUAI_FUNC void luaT_getvararg (CallInfo *ci, StkId ra, TValue *rc); 100LUAI_FUNC void luaT_getvararg (CallInfo *ci, StkId ra, TValue *rc);
101LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci, 101LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci, StkId where,
102 StkId where, int wanted); 102 int wanted, int vatab);
103 103
104 104
105#endif 105#endif
diff --git a/lvm.c b/lvm.c
index 2c868c21..c70e2b8a 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1935,8 +1935,9 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1935 } 1935 }
1936 vmcase(OP_VARARG) { 1936 vmcase(OP_VARARG) {
1937 StkId ra = RA(i); 1937 StkId ra = RA(i);
1938 int n = GETARG_C(i) - 1; /* required results */ 1938 int n = GETARG_C(i) - 1; /* required results (-1 means all) */
1939 Protect(luaT_getvarargs(L, ci, ra, n)); 1939 int vatab = GETARG_k(i) ? GETARG_B(i) : -1;
1940 Protect(luaT_getvarargs(L, ci, ra, n, vatab));
1940 vmbreak; 1941 vmbreak;
1941 } 1942 }
1942 vmcase(OP_GETVARG) { 1943 vmcase(OP_GETVARG) {
diff --git a/manual/manual.of b/manual/manual.of
index 96203d7f..9b8e144d 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -2221,7 +2221,7 @@ The form
2221} 2221}
2222can be used to emulate methods. 2222can be used to emulate methods.
2223A call @T{v:name(@rep{args})} 2223A call @T{v:name(@rep{args})}
2224is syntactic sugar for @T{v.name(v,@rep{args})}, 2224is syntactic sugar for @T{v.name(v, @rep{args})},
2225except that @id{v} is evaluated only once. 2225except that @id{v} is evaluated only once.
2226 2226
2227Arguments have the following syntax: 2227Arguments have the following syntax:
@@ -2372,12 +2372,10 @@ which is indicated by three dots (@Char{...})
2372at the end of its parameter list. 2372at the end of its parameter list.
2373A variadic function does not adjust its argument list; 2373A variadic function does not adjust its argument list;
2374instead, it collects all extra arguments and supplies them 2374instead, it collects all extra arguments and supplies them
2375to the function through a @def{vararg expression} and, 2375to the function through a @def{vararg table}.
2376if present, a @def{vararg table}. 2376In that table,
2377 2377the values at indices 1, 2, etc. are the extra arguments,
2378A vararg expression is also written as three dots, 2378and the value at index @St{n} is the number of extra arguments.
2379and its value is a list of all actual extra arguments,
2380similar to a function with multiple results @see{multires}.
2381 2379
2382As an example, consider the following definitions: 2380As an example, consider the following definitions:
2383@verbatim{ 2381@verbatim{
@@ -2386,7 +2384,7 @@ function g(a, b, ...) end
2386function r() return 1,2,3 end 2384function r() return 1,2,3 end
2387} 2385}
2388Then, we have the following mapping from arguments to parameters and 2386Then, we have the following mapping from arguments to parameters and
2389to the vararg expression: 2387to the vararg table:
2390@verbatim{ 2388@verbatim{
2391CALL PARAMETERS 2389CALL PARAMETERS
2392 2390
@@ -2396,33 +2394,39 @@ f(3, 4, 5) a=3, b=4
2396f(r(), 10) a=1, b=10 2394f(r(), 10) a=1, b=10
2397f(r()) a=1, b=2 2395f(r()) a=1, b=2
2398 2396
2399g(3) a=3, b=nil, ... -> (nothing) 2397g(3) a=3, b=nil, va. table -> {n = 0}
2400g(3, 4) a=3, b=4, ... -> (nothing) 2398g(3, 4) a=3, b=4, va. table -> {n = 0}
2401g(3, 4, 5, 8) a=3, b=4, ... -> 5 8 2399g(3, 4, 5, 8) a=3, b=4, va. table -> {5, 8, n = 2}
2402g(5, r()) a=5, b=1, ... -> 2 3 2400g(5, r()) a=5, b=1, va. table -> {2, 3, n = 2}
2403} 2401}
2404 2402
2405The presence of a vararg table in a variadic function is indicated 2403A vararg table in a variadic function can have an optional name,
2406by a name after the three dots. 2404given after the three dots.
2407When present, 2405When present,
2408a vararg table behaves like a read-only local variable 2406that name denotes a read-only local variable that
2409with the given name that is initialized with a table. 2407refers to the vararg table.
2410In that table, 2408If the vararg table does not have a name,
2411the values at indices 1, 2, etc. are the extra arguments, 2409it can only be accessed through a vararg expression.
2412and the value at index @St{n} is the number of extra arguments. 2410
2413In other words, the code behaves as if the function started with 2411A vararg expression is also written as three dots,
2414the following statement, 2412and its value is a list of the values in the vararg table,
2415assuming the standard behavior of @Lid{table.pack}: 2413from 1 to the integer value at index @St{n}.
2416@verbatim{ 2414(Therefore, if the code does not modify the vararg table,
2417local <const> name = table.pack(...) 2415this list corresponds to the extra arguments in the function call.)
2418} 2416This list behaves like the results from a
2417function with multiple results @see{multires}.
2419 2418
2420As an optimization, 2419As an optimization,
2421if the vararg table is used only as the base table 2420if the vararg table satisfies some conditions,
2422in the syntactic constructions @T{t[exp]} or @T{t.id})
2423and it is not an upvalue,
2424the code does not create an actual table and instead translates 2421the code does not create an actual table and instead translates
2425the indexing expressions into accesses to the internal vararg data. 2422the indexing expressions and the vararg expressions
2423into accesses to the internal vararg data.
2424The conditions are as follows:
2425If the vararg table has a name,
2426that name is not an upvalue in a nested function
2427and it is used only as the base table
2428in the syntactic constructions @T{t[exp]} or @T{t.id}).
2429Note that an anonymous vararg table always satisfy these conditions.
2426 2430
2427} 2431}
2428 2432
@@ -3103,7 +3107,7 @@ void *luaL_alloc (void *ud, void *ptr, size_t osize,
3103} 3107}
3104Note that @N{ISO C} ensures 3108Note that @N{ISO C} ensures
3105that @T{free(NULL)} has no effect and that 3109that @T{free(NULL)} has no effect and that
3106@T{realloc(NULL,size)} is equivalent to @T{malloc(size)}. 3110@T{realloc(NULL, size)} is equivalent to @T{malloc(size)}.
3107 3111
3108} 3112}
3109 3113
@@ -9197,6 +9201,10 @@ Compile-time constants may not appear in this listing,
9197if they were optimized away by the compiler. 9201if they were optimized away by the compiler.
9198Negative indices refer to vararg arguments; 9202Negative indices refer to vararg arguments;
9199@num{-1} is the first vararg argument. 9203@num{-1} is the first vararg argument.
9204These negative indices are only available when the vararg table
9205has been optimized away;
9206otherwise, the vararg arguments are available in the vararg table.
9207
9200The function returns @fail 9208The function returns @fail
9201if there is no variable with the given index, 9209if there is no variable with the given index,
9202and raises an error when called with a level out of range. 9210and raises an error when called with a level out of range.
diff --git a/testes/coroutine.lua b/testes/coroutine.lua
index 4881d964..ba394e0c 100644
--- a/testes/coroutine.lua
+++ b/testes/coroutine.lua
@@ -702,7 +702,9 @@ else
702 assert(t.currentline == t.linedefined + 2) 702 assert(t.currentline == t.linedefined + 2)
703 assert(not debug.getinfo(c, 1)) -- no other level 703 assert(not debug.getinfo(c, 1)) -- no other level
704 assert(coroutine.resume(c)) -- run next line 704 assert(coroutine.resume(c)) -- run next line
705 local n,v = debug.getlocal(c, 0, 2) -- check next local 705 local n,v = debug.getlocal(c, 0, 2) -- check vararg table
706 assert(n == "(vararg table)" and v == nil)
707 local n,v = debug.getlocal(c, 0, 3) -- check next local
706 assert(n == "b" and v == 10) 708 assert(n == "b" and v == 10)
707 v = {coroutine.resume(c)} -- finish coroutine 709 v = {coroutine.resume(c)} -- finish coroutine
708 assert(v[1] == true and v[2] == 2 and v[3] == 3 and v[4] == undef) 710 assert(v[1] == true and v[2] == 2 and v[3] == 3 and v[4] == undef)
diff --git a/testes/db.lua b/testes/db.lua
index 0f174f17..4220b68b 100644
--- a/testes/db.lua
+++ b/testes/db.lua
@@ -356,8 +356,8 @@ function f(a,b)
356 global assert, g, string 356 global assert, g, string
357 local _, y = debug.getlocal(1, 2) 357 local _, y = debug.getlocal(1, 2)
358 assert(x == a and y == b) 358 assert(x == a and y == b)
359 assert(debug.setlocal(2, 3, "pera") == "AA".."AA") 359 assert(debug.setlocal(2, 4, "pera") == "AA".."AA")
360 assert(debug.setlocal(2, 4, "manga") == "B") 360 assert(debug.setlocal(2, 5, "manga") == "B")
361 x = debug.getinfo(2) 361 x = debug.getinfo(2)
362 assert(x.func == g and x.what == "Lua" and x.name == 'g' and 362 assert(x.func == g and x.what == "Lua" and x.name == 'g' and
363 x.nups == 2 and string.find(x.source, "^@.*db%.lua$")) 363 x.nups == 2 and string.find(x.source, "^@.*db%.lua$"))
@@ -392,7 +392,7 @@ function g (...)
392 global * 392 global *
393 local B = 13 393 local B = 13
394 global<const> assert 394 global<const> assert
395 local x,y = debug.getlocal(1,5) 395 local x,y = debug.getlocal(1,6)
396 assert(x == 'B' and y == 13) 396 assert(x == 'B' and y == 13)
397 end 397 end
398end 398end
@@ -458,7 +458,8 @@ local function collectlocals (level)
458 local tab = {} 458 local tab = {}
459 for i = 1, math.huge do 459 for i = 1, math.huge do
460 local n, v = debug.getlocal(level + 1, i) 460 local n, v = debug.getlocal(level + 1, i)
461 if not (n and string.find(n, "^[a-zA-Z0-9_]+$")) then 461 if not (n and string.find(n, "^[a-zA-Z0-9_]+$") or
462 n == "(vararg table)") then
462 break -- consider only real variables 463 break -- consider only real variables
463 end 464 end
464 tab[n] = v 465 tab[n] = v
diff --git a/testes/vararg.lua b/testes/vararg.lua
index a01598ff..043fa7d4 100644
--- a/testes/vararg.lua
+++ b/testes/vararg.lua
@@ -101,6 +101,38 @@ a,b,c,d,e = f(4)
101assert(a==nil and b==nil and c==nil and d==nil and e==nil) 101assert(a==nil and b==nil and c==nil and d==nil and e==nil)
102 102
103 103
104do -- vararg expressions using unpack
105 local function aux (a, v, ...t)
106 for k, val in pairs(v) do t[k] = val end
107 return ...
108 end
109
110 local t = table.pack(aux(10, {11, [5] = 24}, 1, 2, 3, nil, 4))
111 assert(t.n == 5 and t[1] == 11 and t[2] == 2 and t[3] == 3
112 and t[4] == nil and t[5] == 24)
113
114 local t = table.pack(aux(nil, {1, [20] = "a", [30] = "b", n = 30}))
115 assert(t.n == 30 and t[1] == 1 and t[20] == "a" and t[30] == "b")
116 -- table has only those four elements
117 assert(next(t, next(t, next(t, next(t, next(t, nil))))) == nil)
118
119 local a, b, c, d = aux(nil, {}, 10, 20, 30)
120 assert(a == 10 and b == 20 and c == 30 and d == nil)
121
122 local function aux (a, b, n, ...t) t.n = n; return b, ... end
123 local t = table.pack(aux(10, 1, 10000))
124 assert(t.n == 10001 and t[1] == 1 and #t == 1)
125
126 local function checkerr (emsg, f, ...)
127 local st, msg = pcall(f, ...)
128 assert(not st and string.find(msg, emsg))
129 end
130 checkerr("no proper 'n'", aux, 1, 1, -1)
131 checkerr("no proper 'n'", aux, 1, 1, math.maxinteger)
132 checkerr("no proper 'n'", aux, 1, 1, math.mininteger)
133 checkerr("no proper 'n'", aux, 1, 1, 1.0)
134end
135
104-- varargs for main chunks 136-- varargs for main chunks
105local f = assert(load[[ return {...} ]]) 137local f = assert(load[[ return {...} ]])
106local x = f(2,3) 138local x = f(2,3)
@@ -205,6 +237,7 @@ do -- access to vararg parameter
205 assert(t[k] == v[k]) 237 assert(t[k] == v[k])
206 end 238 end
207 assert(t.n == v.n) 239 assert(t.n == v.n)
240 return ...
208 end 241 end
209 242
210 local t = table.pack(10, 20, 30) 243 local t = table.pack(10, 20, 30)