summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c28
-rw-r--r--lcode.h7
-rw-r--r--ldebug.c13
-rw-r--r--ldo.c66
-rw-r--r--lobject.h6
-rw-r--r--lopcodes.c6
-rw-r--r--lopcodes.h21
-rw-r--r--lparser.c60
-rw-r--r--lparser.h5
-rw-r--r--lstate.c3
-rw-r--r--lstate.h9
-rw-r--r--lua.c37
-rw-r--r--lvm.c37
13 files changed, 192 insertions, 106 deletions
diff --git a/lcode.c b/lcode.c
index e9bcb5f1..8ea811d8 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.1 2003/12/10 12:13:36 roberto Exp roberto $ 2** $Id: lcode.c,v 2.2 2004/04/30 20:13:38 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*/
@@ -252,13 +252,26 @@ static int nil_constant (FuncState *fs) {
252} 252}
253 253
254 254
255void luaK_setcallreturns (FuncState *fs, expdesc *e, int nresults) { 255void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
256 if (e->k == VCALL) { /* expression is an open function call? */ 256 if (e->k == VCALL) { /* expression is an open function call? */
257 SETARG_C(getcode(fs, e), nresults+1); 257 SETARG_C(getcode(fs, e), nresults+1);
258 if (nresults == 1) { /* `regular' expression? */ 258 }
259 e->k = VNONRELOC; 259 else if (e->k == VVARARG) {
260 e->info = GETARG_A(getcode(fs, e)); 260 SETARG_B(getcode(fs, e), nresults+1);
261 } 261 SETARG_A(getcode(fs, e), fs->freereg);
262 luaK_reserveregs(fs, 1);
263 }
264}
265
266
267void luaK_setoneret (FuncState *fs, expdesc *e) {
268 if (e->k == VCALL) { /* expression is an open function call? */
269 e->k = VNONRELOC;
270 e->info = GETARG_A(getcode(fs, e));
271 }
272 else if (e->k == VVARARG) {
273 SETARG_B(getcode(fs, e), 2);
274 e->k = VRELOCABLE; /* can relocate its simple result */
262 } 275 }
263} 276}
264 277
@@ -286,8 +299,9 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
286 e->k = VRELOCABLE; 299 e->k = VRELOCABLE;
287 break; 300 break;
288 } 301 }
302 case VVARARG:
289 case VCALL: { 303 case VCALL: {
290 luaK_setcallreturns(fs, e, 1); 304 luaK_setoneret(fs, e);
291 break; 305 break;
292 } 306 }
293 default: break; /* there is one value available (somewhere) */ 307 default: break; /* there is one value available (somewhere) */
diff --git a/lcode.h b/lcode.h
index 8a0eece9..65dea30e 100644
--- a/lcode.h
+++ b/lcode.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.h,v 1.37 2002/06/12 19:16:00 roberto Exp roberto $ 2** $Id: lcode.h,v 1.38 2002/12/11 12:34:22 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*/
@@ -41,6 +41,8 @@ typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr;
41 41
42#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) 42#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
43 43
44#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)
45
44int luaK_code (FuncState *fs, Instruction i, int line); 46int luaK_code (FuncState *fs, Instruction i, int line);
45int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); 47int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
46int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); 48int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
@@ -60,7 +62,8 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
60void luaK_goiftrue (FuncState *fs, expdesc *e); 62void luaK_goiftrue (FuncState *fs, expdesc *e);
61void luaK_goiffalse (FuncState *fs, expdesc *e); 63void luaK_goiffalse (FuncState *fs, expdesc *e);
62void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); 64void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
63void luaK_setcallreturns (FuncState *fs, expdesc *var, int nresults); 65void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
66void luaK_setoneret (FuncState *fs, expdesc *e);
64int luaK_jump (FuncState *fs); 67int luaK_jump (FuncState *fs);
65void luaK_patchlist (FuncState *fs, int list, int target); 68void luaK_patchlist (FuncState *fs, int list, int target);
66void luaK_patchtohere (FuncState *fs, int list); 69void luaK_patchtohere (FuncState *fs, int list);
diff --git a/ldebug.c b/ldebug.c
index 3a1509f0..044eb57f 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 2.3 2004/03/23 13:10:16 roberto Exp roberto $ 2** $Id: ldebug.c,v 2.4 2004/04/30 20:13:38 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*/
@@ -221,8 +221,8 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
221 } 221 }
222 else if (ar->i_ci != 0) { /* no tail call? */ 222 else if (ar->i_ci != 0) { /* no tail call? */
223 CallInfo *ci = L->base_ci + ar->i_ci; 223 CallInfo *ci = L->base_ci + ar->i_ci;
224 lua_assert(ttisfunction(ci->base - 1)); 224 lua_assert(ttisfunction(ci->func));
225 status = auxgetinfo(L, what, ar, ci->base - 1, ci); 225 status = auxgetinfo(L, what, ar, ci->func, ci);
226 } 226 }
227 else 227 else
228 info_tailcall(L, ar); 228 info_tailcall(L, ar);
@@ -405,6 +405,13 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
405 } 405 }
406 break; 406 break;
407 } 407 }
408 case OP_VARARG: {
409 check(pt->is_vararg & NEWSTYLEVARARG);
410 b--;
411 if (b == LUA_MULTRET) check(checkopenop(pt, pc));
412 checkreg(pt, a+b-1);
413 break;
414 }
408 default: break; 415 default: break;
409 } 416 }
410 } 417 }
diff --git a/ldo.c b/ldo.c
index fc1caa7f..293e66a3 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.4 2004/05/10 17:50:51 roberto Exp roberto $ 2** $Id: ldo.c,v 2.5 2004/05/14 19:25:09 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*/
@@ -113,6 +113,7 @@ static void correctstack (lua_State *L, TValue *oldstack) {
113 for (ci = L->base_ci; ci <= L->ci; ci++) { 113 for (ci = L->base_ci; ci <= L->ci; ci++) {
114 ci->top = (ci->top - oldstack) + L->stack; 114 ci->top = (ci->top - oldstack) + L->stack;
115 ci->base = (ci->base - oldstack) + L->stack; 115 ci->base = (ci->base - oldstack) + L->stack;
116 ci->func = (ci->func - oldstack) + L->stack;
116 } 117 }
117 L->base = L->ci->base; 118 L->base = L->ci->base;
118} 119}
@@ -181,26 +182,37 @@ void luaD_callhook (lua_State *L, int event, int line) {
181} 182}
182 183
183 184
184static void adjust_varargs (lua_State *L, int nfixargs, StkId base) { 185static StkId adjust_varargs (lua_State *L, int nfixargs, int actual,
186 int style) {
185 int i; 187 int i;
186 Table *htab; 188 Table *htab = NULL;
187 int actual = L->top - base; /* actual number of arguments */ 189 StkId base, fixed;
188 if (actual < nfixargs) { 190 if (actual < nfixargs) {
189 luaD_checkstack(L, nfixargs - actual);
190 for (; actual < nfixargs; ++actual) 191 for (; actual < nfixargs; ++actual)
191 setnilvalue(L->top++); 192 setnilvalue(L->top++);
192 } 193 }
193 actual -= nfixargs; /* number of extra arguments */ 194 if (style != NEWSTYLEVARARG) { /* compatibility with old-style vararg */
194 htab = luaH_new(L, actual, 1); /* create `arg' table */ 195 int nvar = actual - nfixargs; /* number of extra arguments */
195 for (i=0; i<actual; i++) /* put extra arguments into `arg' table */ 196 htab = luaH_new(L, nvar, 1); /* create `arg' table */
196 setobj2n(L, luaH_setnum(L, htab, i+LUA_FIRSTINDEX), L->top - actual + i); 197 for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */
197 /* store counter in field `n' */ 198 setobj2n(L, luaH_setnum(L, htab, i+LUA_FIRSTINDEX), L->top - nvar + i);
198 setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), 199 /* store counter in field `n' */
199 cast(lua_Number, actual)); 200 setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")),
200 L->top -= actual; /* remove extra elements from the stack */ 201 cast(lua_Number, nvar));
201 sethvalue(L, L->top, htab); 202 }
202 lua_assert(iswhite(obj2gco(htab))); 203 /* move fixed parameters to final position */
203 incr_top(L); 204 fixed = L->top - actual; /* first fixed argument */
205 base = L->top; /* final position of first argument */
206 for (i=0; i<nfixargs; i++) {
207 setobjs2s(L, L->top++, fixed+i);
208 setnilvalue(fixed+i);
209 }
210 /* add `arg' parameter */
211 if (htab) {
212 sethvalue(L, L->top++, htab);
213 lua_assert(iswhite(obj2gco(htab)));
214 }
215 return base;
204} 216}
205 217
206 218
@@ -221,21 +233,28 @@ static StkId tryfuncTM (lua_State *L, StkId func) {
221 233
222int luaD_precall (lua_State *L, StkId func, int nresults) { 234int luaD_precall (lua_State *L, StkId func, int nresults) {
223 LClosure *cl; 235 LClosure *cl;
224 ptrdiff_t funcr = savestack(L, func); 236 ptrdiff_t funcr;
225 if (!ttisfunction(func)) /* `func' is not a function? */ 237 if (!ttisfunction(func)) /* `func' is not a function? */
226 func = tryfuncTM(L, func); /* check the `function' tag method */ 238 func = tryfuncTM(L, func); /* check the `function' tag method */
239 funcr = savestack(L, func);
227 if (L->ci + 1 == L->end_ci) luaD_growCI(L); 240 if (L->ci + 1 == L->end_ci) luaD_growCI(L);
228 else condhardstacktests(luaD_reallocCI(L, L->size_ci)); 241 else condhardstacktests(luaD_reallocCI(L, L->size_ci));
229 cl = &clvalue(func)->l; 242 cl = &clvalue(func)->l;
230 if (!cl->isC) { /* Lua function? prepare its call */ 243 if (!cl->isC) { /* Lua function? prepare its call */
231 CallInfo *ci; 244 CallInfo *ci;
232 StkId st; 245 StkId st, base;
233 Proto *p = cl->p; 246 Proto *p = cl->p;
234 if (p->is_vararg) /* varargs? */
235 adjust_varargs(L, p->numparams, func+1);
236 luaD_checkstack(L, p->maxstacksize); 247 luaD_checkstack(L, p->maxstacksize);
248 func = restorestack(L, funcr);
249 if (p->is_vararg) { /* varargs? */
250 int nargs = L->top - func - 1;
251 base = adjust_varargs(L, p->numparams, nargs, p->is_vararg);
252 }
253 else
254 base = func + 1;
237 ci = ++L->ci; /* now `enter' new function */ 255 ci = ++L->ci; /* now `enter' new function */
238 L->base = L->ci->base = restorestack(L, funcr) + 1; 256 ci->func = func;
257 L->base = ci->base = base;
239 ci->top = L->base + p->maxstacksize; 258 ci->top = L->base + p->maxstacksize;
240 ci->u.l.savedpc = p->code; /* starting point */ 259 ci->u.l.savedpc = p->code; /* starting point */
241 ci->u.l.tailcalls = 0; 260 ci->u.l.tailcalls = 0;
@@ -250,7 +269,8 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
250 int n; 269 int n;
251 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 270 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
252 ci = ++L->ci; /* now `enter' new function */ 271 ci = ++L->ci; /* now `enter' new function */
253 L->base = L->ci->base = restorestack(L, funcr) + 1; 272 ci->func = restorestack(L, funcr);
273 L->base = ci->base = ci->func + 1;
254 ci->top = L->top + LUA_MINSTACK; 274 ci->top = L->top + LUA_MINSTACK;
255 if (L->hookmask & LUA_MASKCALL) 275 if (L->hookmask & LUA_MASKCALL)
256 luaD_callhook(L, LUA_HOOKCALL, -1); 276 luaD_callhook(L, LUA_HOOKCALL, -1);
@@ -284,7 +304,7 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
284 StkId res; 304 StkId res;
285 if (L->hookmask & LUA_MASKRET) 305 if (L->hookmask & LUA_MASKRET)
286 firstResult = callrethooks(L, firstResult); 306 firstResult = callrethooks(L, firstResult);
287 res = L->base - 1; /* res == final position of 1st result */ 307 res = L->ci->func; /* res == final position of 1st result */
288 L->ci--; 308 L->ci--;
289 L->base = L->ci->base; /* restore base */ 309 L->base = L->ci->base; /* restore base */
290 /* move results to correct place */ 310 /* move results to correct place */
diff --git a/lobject.h b/lobject.h
index ee23f3db..ada627fd 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 2.3 2004/02/20 16:01:05 roberto Exp roberto $ 2** $Id: lobject.h,v 2.4 2004/03/15 21:04:33 roberto Exp roberto $
3** Type definitions for Lua objects 3** Type definitions for Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -249,6 +249,10 @@ typedef struct Proto {
249} Proto; 249} Proto;
250 250
251 251
252/* mask for new-style vararg */
253#define NEWSTYLEVARARG 2
254
255
252typedef struct LocVar { 256typedef struct LocVar {
253 TString *varname; 257 TString *varname;
254 int startpc; /* first point where variable is active */ 258 int startpc; /* first point where variable is active */
diff --git a/lopcodes.c b/lopcodes.c
index d84f402e..d0a3dcf1 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.c,v 1.25 2003/05/14 21:09:53 roberto Exp roberto $ 2** $Id: lopcodes.c,v 1.26 2004/04/30 20:13:38 roberto Exp roberto $
3** See Copyright Notice in lua.h 3** See Copyright Notice in lua.h
4*/ 4*/
5 5
@@ -53,7 +53,8 @@ const char *const luaP_opnames[NUM_OPCODES] = {
53 "SETLIST", 53 "SETLIST",
54 "SETLISTO", 54 "SETLISTO",
55 "CLOSE", 55 "CLOSE",
56 "CLOSURE" 56 "CLOSURE",
57 "VARARG"
57}; 58};
58 59
59#endif 60#endif
@@ -98,5 +99,6 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
98 ,opmode(0, 0, OpArgU, OpArgN, iABx) /* OP_SETLISTO */ 99 ,opmode(0, 0, OpArgU, OpArgN, iABx) /* OP_SETLISTO */
99 ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ 100 ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
100 ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ 101 ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
102 ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
101}; 103};
102 104
diff --git a/lopcodes.h b/lopcodes.h
index be5bde30..8fdaf6b1 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.107 2004/04/30 20:13:38 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.108 2004/05/17 12:34:00 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*/
@@ -79,7 +79,7 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
79#define GET_OPCODE(i) (cast(OpCode, (i)&MASK1(SIZE_OP,0))) 79#define GET_OPCODE(i) (cast(OpCode, (i)&MASK1(SIZE_OP,0)))
80#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,0)) | cast(Instruction, o))) 80#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,0)) | cast(Instruction, o)))
81 81
82#define GETARG_A(i) (cast(int, (i)>>POS_A) & MASK1(SIZE_A,0)) 82#define GETARG_A(i) (cast(int, ((i)>>POS_A) & MASK1(SIZE_A,0)))
83#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ 83#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
84 ((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A)))) 84 ((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A))))
85 85
@@ -183,25 +183,30 @@ OP_SETLIST,/* A Bx R(A)[Bx-Bx%FPF+i] := R(A+i), 1 <= i <= Bx%FPF+1 */
183OP_SETLISTO,/* A Bx */ 183OP_SETLISTO,/* A Bx */
184 184
185OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ 185OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
186OP_CLOSURE/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ 186OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
187
188OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
187} OpCode; 189} OpCode;
188 190
189 191
190#define NUM_OPCODES (cast(int, OP_CLOSURE+1)) 192#define NUM_OPCODES (cast(int, OP_VARARG+1))
191 193
192 194
193 195
194/*=========================================================================== 196/*===========================================================================
195 Notes: 197 Notes:
196 (1) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, 198 (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
197 and can be 0: OP_CALL then sets `top' to last_result+1, so 199 and can be 0: OP_CALL then sets `top' to last_result+1, so
198 next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. 200 next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
199 201
200 (2) In OP_RETURN, if (B == 0) then return up to `top' 202 (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
203 set top (like in OP_CALL).
204
205 (*) In OP_RETURN, if (B == 0) then return up to `top'
201 206
202 (3) For comparisons, B specifies what conditions the test should accept. 207 (*) For comparisons, B specifies what conditions the test should accept.
203 208
204 (4) All `skips' (pc++) assume that next instruction is a jump 209 (*) All `skips' (pc++) assume that next instruction is a jump
205===========================================================================*/ 210===========================================================================*/
206 211
207 212
diff --git a/lparser.c b/lparser.c
index d9f6cbd4..06fd8951 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.3 2004/03/26 14:02:41 roberto Exp roberto $ 2** $Id: lparser.c,v 2.4 2004/04/30 20:13:38 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*/
@@ -27,6 +27,8 @@
27 27
28 28
29 29
30#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
31
30#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) 32#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])
31 33
32#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) luaY_errorlimit(fs,l,m) 34#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) luaY_errorlimit(fs,l,m)
@@ -272,11 +274,11 @@ static TString *singlevar (LexState *ls, expdesc *var, int base) {
272static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { 274static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
273 FuncState *fs = ls->fs; 275 FuncState *fs = ls->fs;
274 int extra = nvars - nexps; 276 int extra = nvars - nexps;
275 if (e->k == VCALL) { 277 if (hasmultret(e->k)) {
276 extra++; /* includes call itself */ 278 extra++; /* includes call itself */
277 if (extra <= 0) extra = 0; 279 if (extra < 0) extra = 0;
278 else luaK_reserveregs(fs, extra-1); 280 luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
279 luaK_setcallreturns(fs, e, extra); /* call provides the difference */ 281 if (extra > 1) luaK_reserveregs(fs, extra-1);
280 } 282 }
281 else { 283 else {
282 if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ 284 if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
@@ -392,6 +394,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
392 lexstate.nestlevel = 0; 394 lexstate.nestlevel = 0;
393 luaX_setinput(L, &lexstate, z, luaS_new(L, name)); 395 luaX_setinput(L, &lexstate, z, luaS_new(L, name));
394 open_func(&lexstate, &funcstate); 396 open_func(&lexstate, &funcstate);
397 funcstate.f->is_vararg = NEWSTYLEVARARG;
395 next(&lexstate); /* read first token */ 398 next(&lexstate); /* read first token */
396 chunk(&lexstate); 399 chunk(&lexstate);
397 check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected"); 400 check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");
@@ -481,8 +484,8 @@ static void closelistfield (FuncState *fs, struct ConsControl *cc) {
481 484
482static void lastlistfield (FuncState *fs, struct ConsControl *cc) { 485static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
483 if (cc->tostore == 0) return; 486 if (cc->tostore == 0) return;
484 if (cc->v.k == VCALL) { 487 if (hasmultret(cc->v.k)) {
485 luaK_setcallreturns(fs, &cc->v, LUA_MULTRET); 488 luaK_setmultret(fs, &cc->v);
486 luaK_codeABx(fs, OP_SETLISTO, cc->t->info, cc->na-1); 489 luaK_codeABx(fs, OP_SETLISTO, cc->t->info, cc->na-1);
487 cc->na--; /* do not count last expression (unknown number of elements) */ 490 cc->na--; /* do not count last expression (unknown number of elements) */
488 } 491 }
@@ -558,12 +561,8 @@ static void parlist (LexState *ls) {
558 if (ls->t.token != ')') { /* is `parlist' not empty? */ 561 if (ls->t.token != ')') { /* is `parlist' not empty? */
559 do { 562 do {
560 switch (ls->t.token) { 563 switch (ls->t.token) {
561 case TK_NAME: { /* param -> NAME [ `=' `...' ] */ 564 case TK_NAME: { /* param -> NAME */
562 new_localvar(ls, str_checkname(ls), nparams++); 565 new_localvar(ls, str_checkname(ls), nparams++);
563 if (testnext(ls, '=')) {
564 check(ls, TK_DOTS);
565 f->is_vararg = 1;
566 }
567 break; 566 break;
568 } 567 }
569 case TK_DOTS: { /* param -> `...' */ 568 case TK_DOTS: { /* param -> `...' */
@@ -629,7 +628,7 @@ static void funcargs (LexState *ls, expdesc *f) {
629 args.k = VVOID; 628 args.k = VVOID;
630 else { 629 else {
631 explist1(ls, &args); 630 explist1(ls, &args);
632 luaK_setcallreturns(fs, &args, LUA_MULTRET); 631 luaK_setmultret(fs, &args);
633 } 632 }
634 check_match(ls, ')', '(', line); 633 check_match(ls, ')', '(', line);
635 break; 634 break;
@@ -650,7 +649,7 @@ static void funcargs (LexState *ls, expdesc *f) {
650 } 649 }
651 lua_assert(f->k == VNONRELOC); 650 lua_assert(f->k == VNONRELOC);
652 base = f->info; /* base register for call */ 651 base = f->info; /* base register for call */
653 if (args.k == VCALL) 652 if (hasmultret(args.k))
654 nparams = LUA_MULTRET; /* open call */ 653 nparams = LUA_MULTRET; /* open call */
655 else { 654 else {
656 if (args.k != VVOID) 655 if (args.k != VVOID)
@@ -739,43 +738,47 @@ static void simpleexp (LexState *ls, expdesc *v) {
739 switch (ls->t.token) { 738 switch (ls->t.token) {
740 case TK_NUMBER: { 739 case TK_NUMBER: {
741 init_exp(v, VK, luaK_numberK(ls->fs, ls->t.seminfo.r)); 740 init_exp(v, VK, luaK_numberK(ls->fs, ls->t.seminfo.r));
742 next(ls); /* must use `seminfo' before `next' */
743 break; 741 break;
744 } 742 }
745 case TK_STRING: { 743 case TK_STRING: {
746 codestring(ls, v, ls->t.seminfo.ts); 744 codestring(ls, v, ls->t.seminfo.ts);
747 next(ls); /* must use `seminfo' before `next' */
748 break; 745 break;
749 } 746 }
750 case TK_NIL: { 747 case TK_NIL: {
751 init_exp(v, VNIL, 0); 748 init_exp(v, VNIL, 0);
752 next(ls);
753 break; 749 break;
754 } 750 }
755 case TK_TRUE: { 751 case TK_TRUE: {
756 init_exp(v, VTRUE, 0); 752 init_exp(v, VTRUE, 0);
757 next(ls);
758 break; 753 break;
759 } 754 }
760 case TK_FALSE: { 755 case TK_FALSE: {
761 init_exp(v, VFALSE, 0); 756 init_exp(v, VFALSE, 0);
762 next(ls); 757 break;
758 }
759 case TK_DOTS: { /* vararg */
760 FuncState *fs = ls->fs;
761 check_condition(ls, fs->f->is_vararg,
762 "cannot use `...' outside a vararg function");
763 fs->f->is_vararg = NEWSTYLEVARARG;
764 init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
763 break; 765 break;
764 } 766 }
765 case '{': { /* constructor */ 767 case '{': { /* constructor */
766 constructor(ls, v); 768 constructor(ls, v);
767 break; 769 return;
768 } 770 }
769 case TK_FUNCTION: { 771 case TK_FUNCTION: {
770 next(ls); 772 next(ls);
771 body(ls, v, 0, ls->linenumber); 773 body(ls, v, 0, ls->linenumber);
772 break; 774 return;
773 } 775 }
774 default: { 776 default: {
775 primaryexp(ls, v); 777 primaryexp(ls, v);
776 break; 778 return;
777 } 779 }
778 } 780 }
781 next(ls);
779} 782}
780 783
781 784
@@ -952,7 +955,7 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
952 ls->fs->freereg -= nexps - nvars; /* remove extra values */ 955 ls->fs->freereg -= nexps - nvars; /* remove extra values */
953 } 956 }
954 else { 957 else {
955 luaK_setcallreturns(ls->fs, &e, 1); /* close last expression */ 958 luaK_setoneret(ls->fs, &e); /* close last expression */
956 luaK_storevar(ls->fs, &lh->v, &e); 959 luaK_storevar(ls->fs, &lh->v, &e);
957 return; /* avoid default */ 960 return; /* avoid default */
958 } 961 }
@@ -1236,9 +1239,8 @@ static void exprstat (LexState *ls) {
1236 FuncState *fs = ls->fs; 1239 FuncState *fs = ls->fs;
1237 struct LHS_assign v; 1240 struct LHS_assign v;
1238 primaryexp(ls, &v.v); 1241 primaryexp(ls, &v.v);
1239 if (v.v.k == VCALL) { /* stat -> func */ 1242 if (v.v.k == VCALL) /* stat -> func */
1240 luaK_setcallreturns(fs, &v.v, 0); /* call statement uses no results */ 1243 SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */
1241 }
1242 else { /* stat -> assignment */ 1244 else { /* stat -> assignment */
1243 v.prev = NULL; 1245 v.prev = NULL;
1244 assignment(ls, &v, 1); 1246 assignment(ls, &v, 1);
@@ -1256,9 +1258,9 @@ static void retstat (LexState *ls) {
1256 first = nret = 0; /* return no values */ 1258 first = nret = 0; /* return no values */
1257 else { 1259 else {
1258 nret = explist1(ls, &e); /* optional return values */ 1260 nret = explist1(ls, &e); /* optional return values */
1259 if (e.k == VCALL) { 1261 if (hasmultret(e.k)) {
1260 luaK_setcallreturns(fs, &e, LUA_MULTRET); 1262 luaK_setmultret(fs, &e);
1261 if (nret == 1) { /* tail call? */ 1263 if (e.k == VCALL && nret == 1) { /* tail call? */
1262 SET_OPCODE(getcode(fs,&e), OP_TAILCALL); 1264 SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
1263 lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); 1265 lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
1264 } 1266 }
diff --git a/lparser.h b/lparser.h
index 42d46783..f4398ccc 100644
--- a/lparser.h
+++ b/lparser.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.h,v 1.49 2003/07/09 20:11:30 roberto Exp roberto $ 2** $Id: lparser.h,v 1.50 2003/08/25 19:51:54 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*/
@@ -30,7 +30,8 @@ typedef enum {
30 VJMP, /* info = instruction pc */ 30 VJMP, /* info = instruction pc */
31 VRELOCABLE, /* info = instruction pc */ 31 VRELOCABLE, /* info = instruction pc */
32 VNONRELOC, /* info = result register */ 32 VNONRELOC, /* info = result register */
33 VCALL /* info = result register */ 33 VCALL, /* info = instruction pc */
34 VVARARG /* info = instruction pc */
34} expkind; 35} expkind;
35 36
36typedef struct expdesc { 37typedef struct expdesc {
diff --git a/lstate.c b/lstate.c
index 4ee1c743..890d1d77 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 2.5 2004/03/23 12:57:12 roberto Exp roberto $ 2** $Id: lstate.c,v 2.6 2004/04/30 20:13:38 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*/
@@ -57,6 +57,7 @@ static void stack_init (lua_State *L1, lua_State *L) {
57 L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; 57 L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
58 L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); 58 L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
59 L1->ci = L1->base_ci; 59 L1->ci = L1->base_ci;
60 L1->ci->func = L1->top;
60 setnilvalue(L1->top++); /* `function' entry for this `ci' */ 61 setnilvalue(L1->top++); /* `function' entry for this `ci' */
61 L1->base = L1->ci->base = L1->top; 62 L1->base = L1->ci->base = L1->top;
62 L1->ci->top = L1->top + LUA_MINSTACK; 63 L1->ci->top = L1->top + LUA_MINSTACK;
diff --git a/lstate.h b/lstate.h
index 3a1eb329..0ac69529 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 2.2 2004/03/23 17:02:58 roberto Exp roberto $ 2** $Id: lstate.h,v 2.3 2004/05/14 19:25:09 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*/
@@ -71,6 +71,7 @@ typedef struct stringtable {
71*/ 71*/
72typedef struct CallInfo { 72typedef struct CallInfo {
73 StkId base; /* base for this function */ 73 StkId base; /* base for this function */
74 StkId func; /* function index in the stack */
74 StkId top; /* top for this function */ 75 StkId top; /* top for this function */
75 int nresults; /* expected number of results from this function */ 76 int nresults; /* expected number of results from this function */
76 union { 77 union {
@@ -86,10 +87,10 @@ typedef struct CallInfo {
86 87
87 88
88 89
89#define curr_func(L) (clvalue(L->base - 1)) 90#define curr_func(L) (clvalue(L->ci->func))
90#define ci_func(ci) (clvalue((ci)->base - 1)) 91#define ci_func(ci) (clvalue((ci)->func))
91#define f_isLua(ci) (!ci_func(ci)->c.isC) 92#define f_isLua(ci) (!ci_func(ci)->c.isC)
92#define isLua(ci) (ttisfunction((ci)->base - 1) && f_isLua(ci)) 93#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
93 94
94 95
95/* 96/*
diff --git a/lua.c b/lua.c
index 05ffc88e..cabc5592 100644
--- a/lua.c
+++ b/lua.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lua.c,v 1.124 2003/10/23 18:06:22 roberto Exp roberto $ 2** $Id: lua.c,v 1.125 2004/04/30 20:13:38 roberto Exp roberto $
3** Lua stand-alone interpreter 3** Lua stand-alone interpreter
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -113,30 +113,32 @@ static void print_version (void) {
113} 113}
114 114
115 115
116static void getargs (char *argv[], int n) { 116static int getargs (char *argv[], int n) {
117 int i; 117 int i, narg;
118 for (i=n+1; argv[i]; i++) {
119 luaL_checkstack(L, 1, "too many arguments to script");
120 lua_pushstring(L, argv[i]);
121 }
122 narg = i-(n+1); /* number of arguments to the script (not to `lua.c') */
118 lua_newtable(L); 123 lua_newtable(L);
119 for (i=0; argv[i]; i++) { 124 for (i=0; argv[i]; i++) {
120 lua_pushnumber(L, i - n); 125 lua_pushnumber(L, i - n);
121 lua_pushstring(L, argv[i]); 126 lua_pushstring(L, argv[i]);
122 lua_rawset(L, -3); 127 lua_rawset(L, -3);
123 } 128 }
124} 129 return narg;
125
126
127static int docall (int status) {
128 if (status == 0) status = lcall(0, 1);
129 return report(status);
130} 130}
131 131
132 132
133static int file_input (const char *name) { 133static int file_input (const char *name) {
134 return docall(luaL_loadfile(L, name)); 134 int status = luaL_loadfile(L, name) || lcall(0, 1);
135 return report(status);
135} 136}
136 137
137 138
138static int dostring (const char *s, const char *name) { 139static int dostring (const char *s, const char *name) {
139 return docall(luaL_loadbuffer(L, s, strlen(s), name)); 140 int status = luaL_loadbuffer(L, s, strlen(s), name) || lcall(0, 1);
141 return report(status);
140} 142}
141 143
142 144
@@ -329,10 +331,17 @@ static int handle_argv (char *argv[], int *interactive) {
329 } endloop: 331 } endloop:
330 if (argv[i] != NULL) { 332 if (argv[i] != NULL) {
331 const char *filename = argv[i]; 333 const char *filename = argv[i];
332 getargs(argv, i); /* collect arguments */ 334 int narg = getargs(argv, i); /* collect arguments */
333 clearinteractive(interactive); 335 int status;
334 lua_setglobal(L, "arg"); 336 lua_setglobal(L, "arg");
335 return file_input(filename); /* stop scanning arguments */ 337 clearinteractive(interactive);
338 status = luaL_loadfile(L, filename);
339 lua_insert(L, -(narg+1));
340 if (status == 0)
341 status = lcall(narg, 0);
342 else
343 lua_pop(L, narg);
344 return report(status);
336 } 345 }
337 } 346 }
338 return 0; 347 return 0;
diff --git a/lvm.c b/lvm.c
index 4c5a7ec7..5363ebef 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.5 2004/05/10 17:50:51 roberto Exp roberto $ 2** $Id: lvm.c,v 2.6 2004/05/14 19:25:09 roberto Exp $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -387,8 +387,8 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
387 luaD_callhook(L, LUA_HOOKCALL, -1); 387 luaD_callhook(L, LUA_HOOKCALL, -1);
388 retentry: /* entry point when returning to old functions */ 388 retentry: /* entry point when returning to old functions */
389 pc = L->ci->u.l.savedpc; 389 pc = L->ci->u.l.savedpc;
390 cl = &clvalue(L->ci->func)->l;
390 base = L->base; 391 base = L->base;
391 cl = &clvalue(base - 1)->l;
392 k = cl->p->k; 392 k = cl->p->k;
393 /* main loop of interpreter */ 393 /* main loop of interpreter */
394 for (;;) { 394 for (;;) {
@@ -615,17 +615,19 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
615 pcr = luaD_precall(L, ra, LUA_MULTRET); 615 pcr = luaD_precall(L, ra, LUA_MULTRET);
616 if (pcr == PCRLUA) { 616 if (pcr == PCRLUA) {
617 /* tail call: put new frame in place of previous one */ 617 /* tail call: put new frame in place of previous one */
618 CallInfo *ci = L->ci - 1; /* previous frame */
618 int aux; 619 int aux;
619 base = (L->ci - 1)->base; /* `luaD_precall' may change the stack */ 620 StkId func = ci->func;
620 ra = RA(i); 621 StkId pfunc = (ci+1)->func; /* previous function index */
622 base = ci->base = ci->func + ((ci+1)->base - pfunc);
623 L->base = base;
621 if (L->openupval) luaF_close(L, base); 624 if (L->openupval) luaF_close(L, base);
622 for (aux = 0; ra+aux < L->top; aux++) /* move frame down */ 625 for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */
623 setobjs2s(L, base+aux-1, ra+aux); 626 setobjs2s(L, func+aux, pfunc+aux);
624 (L->ci - 1)->top = L->top = base+aux; /* correct top */ 627 ci->top = L->top = base+aux; /* correct top */
625 (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc; 628 ci->u.l.savedpc = L->ci->u.l.savedpc;
626 (L->ci - 1)->u.l.tailcalls++; /* one more call lost */ 629 ci->u.l.tailcalls++; /* one more call lost */
627 L->ci--; /* remove new frame */ 630 L->ci--; /* remove new frame */
628 L->base = L->ci->base;
629 goto callentry; 631 goto callentry;
630 } 632 }
631 else if (pcr == PCRC) { 633 else if (pcr == PCRC) {
@@ -758,6 +760,21 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
758 base = L->base; 760 base = L->base;
759 break; 761 break;
760 } 762 }
763 case OP_VARARG: {
764 int b = GETARG_B(i) - 1;
765 int j;
766 CallInfo *ci = L->ci;
767 int n = ci->base - ci->func - cl->p->numparams - 1;
768 if (b == LUA_MULTRET) {
769 b = n;
770 L->top = ra + n;
771 }
772 for (j=0; j<b && j<n; j++)
773 setobjs2s(L, ra+j, ci->base - n + j);
774 for (; j<b; j++)
775 setnilvalue(ra+j);
776 break;
777 }
761 } 778 }
762 } 779 }
763} 780}