aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-03-08 16:10:32 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-03-08 16:10:32 -0300
commitbd8b9c94b38ddaa3cd7324cbca98571633e03f91 (patch)
tree599551d4713dc039c2603e1830cc13acc9552779
parent4db04555f06b90f3b2cda96c2f4aaeb78266ea86 (diff)
downloadlua-bd8b9c94b38ddaa3cd7324cbca98571633e03f91.tar.gz
lua-bd8b9c94b38ddaa3cd7324cbca98571633e03f91.tar.bz2
lua-bd8b9c94b38ddaa3cd7324cbca98571633e03f91.zip
generic for (with any number of control variables)
-rw-r--r--lcode.c27
-rw-r--r--lcode.h4
-rw-r--r--ldebug.c21
-rw-r--r--lopcodes.c5
-rw-r--r--lopcodes.h10
-rw-r--r--lparser.c84
-rw-r--r--lvm.c15
7 files changed, 98 insertions, 68 deletions
diff --git a/lcode.c b/lcode.c
index ffd77f2e..3cc0ea5c 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 1.89 2002/02/05 22:39:12 roberto Exp roberto $ 2** $Id: lcode.c,v 1.90 2002/03/05 12:42:47 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*/
@@ -158,6 +158,11 @@ void luaK_patchlist (FuncState *fs, int list, int target) {
158} 158}
159 159
160 160
161void luaK_patchtohere (FuncState *fs, int list) {
162 luaK_patchlist(fs, list, luaK_getlabel(fs));
163}
164
165
161void luaK_concat (FuncState *fs, int *l1, int l2) { 166void luaK_concat (FuncState *fs, int *l1, int l2) {
162 if (*l1 == NO_JUMP) 167 if (*l1 == NO_JUMP)
163 *l1 = l2; 168 *l1 = l2;
@@ -171,16 +176,22 @@ void luaK_concat (FuncState *fs, int *l1, int l2) {
171} 176}
172 177
173 178
174void luaK_reserveregs (FuncState *fs, int n) { 179void luaK_checkstack (FuncState *fs, int n) {
175 fs->freereg += n; 180 int newstack = fs->freereg + n;
176 if (fs->freereg > fs->f->maxstacksize) { 181 if (newstack > fs->f->maxstacksize) {
177 if (fs->freereg >= MAXSTACK) 182 if (newstack >= MAXSTACK)
178 luaK_error(fs->ls, "function or expression too complex"); 183 luaK_error(fs->ls, "function or expression too complex");
179 fs->f->maxstacksize = cast(lu_byte, fs->freereg); 184 fs->f->maxstacksize = cast(lu_byte, newstack);
180 } 185 }
181} 186}
182 187
183 188
189void luaK_reserveregs (FuncState *fs, int n) {
190 luaK_checkstack(fs, n);
191 fs->freereg += n;
192}
193
194
184static void freereg (FuncState *fs, int reg) { 195static void freereg (FuncState *fs, int reg) {
185 if (reg >= fs->nactloc && reg < MAXSTACK) { 196 if (reg >= fs->nactloc && reg < MAXSTACK) {
186 fs->freereg--; 197 fs->freereg--;
@@ -533,7 +544,7 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
533 } 544 }
534 } 545 }
535 luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ 546 luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
536 luaK_patchlist(fs, e->t, luaK_getlabel(fs)); 547 luaK_patchtohere(fs, e->t);
537 e->t = NO_JUMP; 548 e->t = NO_JUMP;
538} 549}
539 550
@@ -560,7 +571,7 @@ static void luaK_goiffalse (FuncState *fs, expdesc *e) {
560 } 571 }
561 } 572 }
562 luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ 573 luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
563 luaK_patchlist(fs, e->f, luaK_getlabel(fs)); 574 luaK_patchtohere(fs, e->f);
564 e->f = NO_JUMP; 575 e->f = NO_JUMP;
565} 576}
566 577
diff --git a/lcode.h b/lcode.h
index 0a6d7bf5..ef6b1f61 100644
--- a/lcode.h
+++ b/lcode.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $ 2** $Id: lcode.h,v 1.27 2002/02/05 22:39:12 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*/
@@ -42,6 +42,7 @@ void luaK_error (LexState *ls, const char *msg);
42int luaK_codeABc (FuncState *fs, OpCode o, int A, unsigned int Bc); 42int luaK_codeABc (FuncState *fs, OpCode o, int A, unsigned int Bc);
43int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); 43int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
44void luaK_nil (FuncState *fs, int from, int n); 44void luaK_nil (FuncState *fs, int from, int n);
45void luaK_checkstack (FuncState *fs, int n);
45void luaK_reserveregs (FuncState *fs, int n); 46void luaK_reserveregs (FuncState *fs, int n);
46int luaK_stringK (FuncState *fs, TString *s); 47int luaK_stringK (FuncState *fs, TString *s);
47int luaK_numberK (FuncState *fs, lua_Number r); 48int luaK_numberK (FuncState *fs, lua_Number r);
@@ -57,6 +58,7 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
57void luaK_setcallreturns (FuncState *fs, expdesc *var, int nresults); 58void luaK_setcallreturns (FuncState *fs, expdesc *var, int nresults);
58int luaK_jump (FuncState *fs); 59int luaK_jump (FuncState *fs);
59void luaK_patchlist (FuncState *fs, int list, int target); 60void luaK_patchlist (FuncState *fs, int list, int target);
61void luaK_patchtohere (FuncState *fs, int list);
60void luaK_concat (FuncState *fs, int *l1, int l2); 62void luaK_concat (FuncState *fs, int *l1, int l2);
61int luaK_getlabel (FuncState *fs); 63int luaK_getlabel (FuncState *fs);
62void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); 64void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
diff --git a/ldebug.c b/ldebug.c
index 48090ae7..6f9bf9e9 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.97 2002/01/09 22:02:47 roberto Exp $ 2** $Id: ldebug.c,v 1.100 2002/02/05 22:39:12 roberto Exp $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -375,9 +375,10 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
375 check(c < MAXSTACK && b < c); 375 check(c < MAXSTACK && b < c);
376 break; 376 break;
377 } 377 }
378 case OP_JMP:
379 case OP_FORLOOP: 378 case OP_FORLOOP:
380 case OP_TFORLOOP: { 379 checkreg(pt, a+2);
380 /* go through */
381 case OP_JMP: {
381 int dest = pc+1+b; 382 int dest = pc+1+b;
382 check(0 <= dest && dest < pt->sizecode); 383 check(0 <= dest && dest < pt->sizecode);
383 /* not full check and jump is forward and do not skip `lastpc'? */ 384 /* not full check and jump is forward and do not skip `lastpc'? */
@@ -385,6 +386,12 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
385 pc += b; /* do the jump */ 386 pc += b; /* do the jump */
386 break; 387 break;
387 } 388 }
389 case OP_TFORLOOP: {
390 checkreg(pt, a+c);
391 checkreg(pt, a+2); /* at least 2 for table generators */
392 check(pc+2 < pt->sizecode); /* check skip */
393 break;
394 }
388 case OP_CALL: { 395 case OP_CALL: {
389 if (b != 0) { 396 if (b != 0) {
390 checkreg(pt, a+b-1); 397 checkreg(pt, a+b-1);
@@ -408,8 +415,14 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
408 break; 415 break;
409 } 416 }
410 case OP_CLOSURE: { 417 case OP_CLOSURE: {
418 int nup;
411 check(b < pt->sizep); 419 check(b < pt->sizep);
412 check(pc + pt->p[b]->nupvalues < pt->sizecode); 420 nup = pt->p[b]->nupvalues;
421 check(pc + nup < pt->sizecode);
422 for (; nup>0; nup--) {
423 OpCode op1 = GET_OPCODE(pt->code[pc+nup]);
424 check(op1 == OP_GETUPVAL || op1 == OP_MOVE);
425 }
413 break; 426 break;
414 } 427 }
415 default: break; 428 default: break;
diff --git a/lopcodes.c b/lopcodes.c
index 7c452783..b48d1f71 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.c,v 1.8 2001/12/11 22:48:44 roberto Exp $ 2** $Id: lopcodes.c,v 1.11 2002/02/05 22:39:12 roberto Exp roberto $
3** extracted automatically from lopcodes.h by mkprint.lua 3** extracted automatically from lopcodes.h by mkprint.lua
4** DO NOT EDIT 4** DO NOT EDIT
5** See Copyright Notice in lua.h 5** See Copyright Notice in lua.h
@@ -60,6 +60,7 @@ const char *const luaP_opnames[] = {
60 ((b)<<OpModeBreg) | ((c)<<OpModeCreg) | \ 60 ((b)<<OpModeBreg) | ((c)<<OpModeCreg) | \
61 ((sa)<<OpModesetA) | ((k)<<OpModeK) | (x)<<OpModeNoTrace | (m)) 61 ((sa)<<OpModesetA) | ((k)<<OpModeK) | (x)<<OpModeNoTrace | (m))
62 62
63
63const lu_byte luaP_opmodes[NUM_OPCODES] = { 64const lu_byte luaP_opmodes[NUM_OPCODES] = {
64/* T n B C sA K mode opcode */ 65/* T n B C sA K mode opcode */
65 opmode(0,0,1,0, 1,0,iABC) /* OP_MOVE */ 66 opmode(0,0,1,0, 1,0,iABC) /* OP_MOVE */
@@ -94,7 +95,7 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
94 ,opmode(0,0,0,0, 0,0,iABC) /* OP_CALL */ 95 ,opmode(0,0,0,0, 0,0,iABC) /* OP_CALL */
95 ,opmode(0,0,0,0, 0,0,iABC) /* OP_RETURN */ 96 ,opmode(0,0,0,0, 0,0,iABC) /* OP_RETURN */
96 ,opmode(0,1,0,0, 0,0,iAsBc) /* OP_FORLOOP */ 97 ,opmode(0,1,0,0, 0,0,iAsBc) /* OP_FORLOOP */
97 ,opmode(0,1,0,0, 0,0,iAsBc) /* OP_TFORLOOP */ 98 ,opmode(0,0,0,0, 0,0,iABC) /* OP_TFORLOOP */
98 ,opmode(0,0,0,0, 0,0,iABc) /* OP_SETLIST */ 99 ,opmode(0,0,0,0, 0,0,iABc) /* OP_SETLIST */
99 ,opmode(0,0,0,0, 0,0,iABc) /* OP_SETLISTO */ 100 ,opmode(0,0,0,0, 0,0,iABc) /* OP_SETLISTO */
100 ,opmode(0,0,0,0, 0,0,iABC) /* OP_CLOSE */ 101 ,opmode(0,0,0,0, 0,0,iABC) /* OP_CLOSE */
diff --git a/lopcodes.h b/lopcodes.h
index 29ff40aa..4568fe46 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.85 2002/01/09 22:02:47 roberto Exp $ 2** $Id: lopcodes.h,v 1.89 2002/02/14 21:43:01 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*/
@@ -166,11 +166,13 @@ OP_TESTGE,/* A C if not (R(A) >= R/K(C)) then pc++ */
166OP_TESTT,/* A B if (R(B)) then R(A) := R(B) else pc++ */ 166OP_TESTT,/* A B if (R(B)) then R(A) := R(B) else pc++ */
167OP_TESTF,/* A B if not (R(B)) then R(A) := R(B) else pc++ */ 167OP_TESTF,/* A B if not (R(B)) then R(A) := R(B) else pc++ */
168 168
169OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1))*/ 169OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
170OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see (3)) */ 170OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see (3)) */
171 171
172OP_FORLOOP,/* A sBc */ 172OP_FORLOOP,/* A sBc R(A)+=R(A+2); if R(A) <?= R(A+1) then PC+= sBc */
173OP_TFORLOOP,/* A sBc */ 173
174OP_TFORLOOP,/* A C R(A+1), ... ,R(A+C) := R(A)();
175 if R(A+1) ~= nil then pc++ */
174 176
175OP_SETLIST,/* A Bc R(A)[Bc-Bc%FPF+i] := R(A+i), 1 <= i <= Bc%FPF+1 */ 177OP_SETLIST,/* A Bc R(A)[Bc-Bc%FPF+i] := R(A+i), 1 <= i <= Bc%FPF+1 */
176OP_SETLISTO,/* A Bc */ 178OP_SETLISTO,/* A Bc */
diff --git a/lparser.c b/lparser.c
index 67aa21ab..507bddfe 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $ 2** $Id: lparser.c,v 1.167 2002/02/14 21:46:58 roberto Exp $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -247,12 +247,12 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
247} 247}
248 248
249 249
250static void code_params (LexState *ls, int nparams, short dots) { 250static void code_params (LexState *ls, int nparams, int dots) {
251 FuncState *fs = ls->fs; 251 FuncState *fs = ls->fs;
252 adjustlocalvars(ls, nparams); 252 adjustlocalvars(ls, nparams);
253 luaX_checklimit(ls, fs->nactloc, MAXPARAMS, "parameters"); 253 luaX_checklimit(ls, fs->nactloc, MAXPARAMS, "parameters");
254 fs->f->numparams = cast(short, fs->nactloc); /* `self' could be there already */ 254 fs->f->numparams = cast(lu_byte, fs->nactloc);
255 fs->f->is_vararg = dots; 255 fs->f->is_vararg = cast(lu_byte, dots);
256 if (dots) { 256 if (dots) {
257 new_localvarstr(ls, "arg", 0); 257 new_localvarstr(ls, "arg", 0);
258 adjustlocalvars(ls, 1); 258 adjustlocalvars(ls, 1);
@@ -271,7 +271,7 @@ static void enterbreak (FuncState *fs, Breaklabel *bl) {
271 271
272static void leavebreak (FuncState *fs, Breaklabel *bl) { 272static void leavebreak (FuncState *fs, Breaklabel *bl) {
273 fs->bl = bl->previous; 273 fs->bl = bl->previous;
274 luaK_patchlist(fs, bl->breaklist, luaK_getlabel(fs)); 274 luaK_patchtohere(fs, bl->breaklist);
275 lua_assert(bl->nactloc == fs->nactloc); 275 lua_assert(bl->nactloc == fs->nactloc);
276} 276}
277 277
@@ -471,8 +471,11 @@ static void recfield (LexState *ls, struct ConsControl *cc) {
471 FuncState *fs = ls->fs; 471 FuncState *fs = ls->fs;
472 int reg = ls->fs->freereg; 472 int reg = ls->fs->freereg;
473 expdesc key, val; 473 expdesc key, val;
474 if (ls->t.token == TK_NAME) 474 if (ls->t.token == TK_NAME) {
475 luaX_checklimit(ls, cc->nh, MAX_INT, "items in a constructor");
476 cc->nh++;
475 checkname(ls, &key); 477 checkname(ls, &key);
478 }
476 else /* ls->t.token == '[' */ 479 else /* ls->t.token == '[' */
477 luaY_index(ls, &key); 480 luaY_index(ls, &key);
478 check(ls, '='); 481 check(ls, '=');
@@ -481,8 +484,6 @@ static void recfield (LexState *ls, struct ConsControl *cc) {
481 luaK_exp2anyreg(fs, &val); 484 luaK_exp2anyreg(fs, &val);
482 luaK_codeABC(fs, OP_SETTABLE, val.info, cc->t->info, luaK_exp2RK(fs, &key)); 485 luaK_codeABC(fs, OP_SETTABLE, val.info, cc->t->info, luaK_exp2RK(fs, &key));
483 fs->freereg = reg; /* free registers */ 486 fs->freereg = reg; /* free registers */
484 luaX_checklimit(ls, cc->nh, MAX_INT, "items in a constructor");
485 cc->nh++;
486} 487}
487 488
488 489
@@ -893,7 +894,7 @@ static void whilestat (LexState *ls, int line) {
893 check(ls, TK_DO); 894 check(ls, TK_DO);
894 block(ls); 895 block(ls);
895 luaK_patchlist(fs, luaK_jump(fs), while_init); 896 luaK_patchlist(fs, luaK_jump(fs), while_init);
896 luaK_patchlist(fs, v.f, luaK_getlabel(fs)); 897 luaK_patchtohere(fs, v.f);
897 check_match(ls, TK_END, TK_WHILE, line); 898 check_match(ls, TK_END, TK_WHILE, line);
898 leavebreak(fs, &bl); 899 leavebreak(fs, &bl);
899} 900}
@@ -922,24 +923,11 @@ static void exp1 (LexState *ls) {
922} 923}
923 924
924 925
925static void forbody (LexState *ls, OpCode loopfor) {
926 /* forbody -> DO block END */
927 FuncState *fs = ls->fs;
928 int basereg = fs->freereg - 3;
929 int prep = luaK_jump(fs);
930 int blockinit = luaK_getlabel(fs);
931 check(ls, TK_DO);
932 adjustlocalvars(ls, 3); /* scope for control variables */
933 block(ls);
934 luaK_patchlist(fs, prep, luaK_getlabel(fs));
935 luaK_patchlist(fs, luaK_codeAsBc(fs, loopfor, basereg, NO_JUMP), blockinit);
936 removelocalvars(ls, 3, 1);
937}
938
939
940static void fornum (LexState *ls, TString *varname) { 926static void fornum (LexState *ls, TString *varname) {
941 /* fornum -> NAME = exp1,exp1[,exp1] forbody */ 927 /* fornum -> NAME = exp1,exp1[,exp1] DO body */
942 FuncState *fs = ls->fs; 928 FuncState *fs = ls->fs;
929 int prep;
930 int base = fs->freereg;
943 new_localvar(ls, varname, 0); 931 new_localvar(ls, varname, 0);
944 new_localvarstr(ls, "(limit)", 1); 932 new_localvarstr(ls, "(limit)", 1);
945 new_localvarstr(ls, "(step)", 2); 933 new_localvarstr(ls, "(step)", 2);
@@ -954,26 +942,42 @@ static void fornum (LexState *ls, TString *varname) {
954 luaK_reserveregs(fs, 1); 942 luaK_reserveregs(fs, 1);
955 } 943 }
956 luaK_codeABC(fs, OP_SUB, fs->freereg - 3, fs->freereg - 3, fs->freereg - 1); 944 luaK_codeABC(fs, OP_SUB, fs->freereg - 3, fs->freereg - 3, fs->freereg - 1);
957 forbody(ls, OP_FORLOOP); 945 luaK_jump(fs);
946 prep = luaK_getlabel(fs);
947 check(ls, TK_DO);
948 adjustlocalvars(ls, 3); /* scope for control variables */
949 block(ls);
950 luaK_patchtohere(fs, prep-1);
951 luaK_patchlist(fs, luaK_codeAsBc(fs, OP_FORLOOP, base, NO_JUMP), prep);
952 removelocalvars(ls, 3, 1);
958} 953}
959 954
960 955
961static void forlist (LexState *ls, TString *indexname) { 956static void forlist (LexState *ls, TString *indexname) {
962 /* forlist -> NAME,NAME IN exp1 forbody */ 957 /* forlist -> NAME {,NAME} IN exp1 DO body */
963 FuncState *fs = ls->fs; 958 FuncState *fs = ls->fs;
959 int nvars = 0;
960 int prep;
961 int base = fs->freereg;
964 new_localvarstr(ls, "(table)", 0); 962 new_localvarstr(ls, "(table)", 0);
965 new_localvar(ls, indexname, 1); 963 new_localvar(ls, indexname, ++nvars);
966 if (optional(ls, ',')) { 964 while (optional(ls, ',')) {
967 new_localvar(ls, str_checkname(ls), 2); 965 new_localvar(ls, str_checkname(ls), ++nvars);
968 next(ls); /* skip var name */ 966 next(ls);
969 } 967 }
970 else
971 new_localvarstr(ls, "(val)", 2);
972 check(ls, TK_IN); 968 check(ls, TK_IN);
973 exp1(ls); /* table */ 969 exp1(ls); /* table */
974 luaK_reserveregs(fs, 2); /* registers for index and val */ 970 luaK_checkstack(fs, 2); /* at least two slots, to traverse tables */
975 luaK_codeABC(fs, OP_LOADNIL, fs->freereg - 2, fs->freereg - 1, 0); 971 luaK_reserveregs(fs, nvars); /* registers for vars */
976 forbody(ls, OP_TFORLOOP); 972 luaK_codeABC(fs, OP_LOADNIL, base+1, base+nvars, 0);
973 adjustlocalvars(ls, nvars+1); /* scope for control variables */
974 luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
975 prep = luaK_jump(fs);
976 check(ls, TK_DO);
977 block(ls);
978 luaK_patchlist(fs, luaK_jump(fs), prep-1);
979 luaK_patchtohere(fs, prep);
980 removelocalvars(ls, nvars+1, 1);
977} 981}
978 982
979 983
@@ -1013,18 +1017,18 @@ static void ifstat (LexState *ls, int line) {
1013 test_then_block(ls, &v); /* IF cond THEN block */ 1017 test_then_block(ls, &v); /* IF cond THEN block */
1014 while (ls->t.token == TK_ELSEIF) { 1018 while (ls->t.token == TK_ELSEIF) {
1015 luaK_concat(fs, &escapelist, luaK_jump(fs)); 1019 luaK_concat(fs, &escapelist, luaK_jump(fs));
1016 luaK_patchlist(fs, v.f, luaK_getlabel(fs)); 1020 luaK_patchtohere(fs, v.f);
1017 test_then_block(ls, &v); /* ELSEIF cond THEN block */ 1021 test_then_block(ls, &v); /* ELSEIF cond THEN block */
1018 } 1022 }
1019 if (ls->t.token == TK_ELSE) { 1023 if (ls->t.token == TK_ELSE) {
1020 luaK_concat(fs, &escapelist, luaK_jump(fs)); 1024 luaK_concat(fs, &escapelist, luaK_jump(fs));
1021 luaK_patchlist(fs, v.f, luaK_getlabel(fs)); 1025 luaK_patchtohere(fs, v.f);
1022 next(ls); /* skip ELSE */ 1026 next(ls); /* skip ELSE */
1023 block(ls); /* `else' part */ 1027 block(ls); /* `else' part */
1024 } 1028 }
1025 else 1029 else
1026 luaK_concat(fs, &escapelist, v.f); 1030 luaK_concat(fs, &escapelist, v.f);
1027 luaK_patchlist(fs, escapelist, luaK_getlabel(fs)); 1031 luaK_patchtohere(fs, escapelist);
1028 check_match(ls, TK_END, TK_IF, line); 1032 check_match(ls, TK_END, TK_IF, line);
1029} 1033}
1030 1034
@@ -1182,7 +1186,7 @@ static int statement (LexState *ls) {
1182static void parlist (LexState *ls) { 1186static void parlist (LexState *ls) {
1183 /* parlist -> [ param { `,' param } ] */ 1187 /* parlist -> [ param { `,' param } ] */
1184 int nparams = 0; 1188 int nparams = 0;
1185 short dots = 0; 1189 int dots = 0;
1186 if (ls->t.token != ')') { /* is `parlist' not empty? */ 1190 if (ls->t.token != ')') { /* is `parlist' not empty? */
1187 do { 1191 do {
1188 switch (ls->t.token) { 1192 switch (ls->t.token) {
diff --git a/lvm.c b/lvm.c
index 6a282196..7058af88 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.217 2002/03/04 15:40:04 roberto Exp roberto $ 2** $Id: lvm.c,v 1.218 2002/03/04 21:33:09 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*/
@@ -560,24 +560,21 @@ StkId luaV_execute (lua_State *L) {
560 break; 560 break;
561 } 561 }
562 case OP_TFORLOOP: { 562 case OP_TFORLOOP: {
563 int j = GETARG_sBc(i);
564 int loop = 0;
565 pc += j; /* jump back before tests (for error messages) */
566 if (ttype(ra) == LUA_TTABLE) { 563 if (ttype(ra) == LUA_TTABLE) {
567 Table *t = hvalue(ra); 564 Table *t = hvalue(ra);
568 loop = luaH_next(L, t, ra+1); 565 if (luaH_next(L, t, ra+1))
566 pc++; /* skip jump (keep looping) */
569 } 567 }
570 else if (ttype(ra) == LUA_TFUNCTION) { 568 else if (ttype(ra) == LUA_TFUNCTION) {
571 setobj(ra+1, ra); 569 setobj(ra+1, ra);
572 L->top = ra+2; /* no arguments */ 570 L->top = ra+2; /* no arguments */
573 luaD_call(L, ra+1, 2); 571 luaD_call(L, ra+1, GETARG_C(i));
574 L->top = L->ci->top; 572 L->top = L->ci->top;
575 loop = (ttype(ra+1) != LUA_TNIL); 573 if (ttype(ra+1) != LUA_TNIL)
574 pc++; /* skip jump (keep looping) */
576 } 575 }
577 else 576 else
578 luaD_error(L, "`for' generator must be a table or function"); 577 luaD_error(L, "`for' generator must be a table or function");
579 if (!loop)
580 pc -= j; /* undo jump */
581 break; 578 break;
582 } 579 }
583 case OP_SETLIST: 580 case OP_SETLIST: