aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldebug.c5
-rw-r--r--lopcodes.c4
-rw-r--r--lopcodes.h4
-rw-r--r--lparser.c44
-rw-r--r--lvm.c52
5 files changed, 59 insertions, 50 deletions
diff --git a/ldebug.c b/ldebug.c
index 468c2358..d42b161a 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.150 2003/03/19 21:24:04 roberto Exp roberto $ 2** $Id: ldebug.c,v 1.151 2003/04/28 13:31:06 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*/
@@ -374,10 +374,11 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
374 break; 374 break;
375 } 375 }
376 case OP_TFORLOOP: 376 case OP_TFORLOOP:
377 checkreg(pt, a+c+5); 377 checkreg(pt, a+5);
378 if (reg >= a) last = pc; /* affect all registers above base */ 378 if (reg >= a) last = pc; /* affect all registers above base */
379 /* go through */ 379 /* go through */
380 case OP_FORLOOP: 380 case OP_FORLOOP:
381 case OP_FORPREP:
381 checkreg(pt, a+2); 382 checkreg(pt, a+2);
382 /* go through */ 383 /* go through */
383 case OP_JMP: { 384 case OP_JMP: {
diff --git a/lopcodes.c b/lopcodes.c
index 16950461..b10e5bd1 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.c,v 1.21 2002/08/20 20:03:05 roberto Exp roberto $ 2** $Id: lopcodes.c,v 1.22 2002/12/04 17:38:31 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
@@ -46,6 +46,7 @@ const char *const luaP_opnames[] = {
46 "TAILCALL", 46 "TAILCALL",
47 "RETURN", 47 "RETURN",
48 "FORLOOP", 48 "FORLOOP",
49 "FORPREP",
49 "TFORLOOP", 50 "TFORLOOP",
50 "TFORPREP", 51 "TFORPREP",
51 "SETLIST", 52 "SETLIST",
@@ -92,6 +93,7 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
92 ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_TAILCALL */ 93 ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_TAILCALL */
93 ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_RETURN */ 94 ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_RETURN */
94 ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_FORLOOP */ 95 ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_FORLOOP */
96 ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_FORPREP */
95 ,opmode(1, 0, 0, 0, 0, 0, iABC) /* OP_TFORLOOP */ 97 ,opmode(1, 0, 0, 0, 0, 0, iABC) /* OP_TFORLOOP */
96 ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_TFORPREP */ 98 ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_TFORPREP */
97 ,opmode(0, 0, 0, 0, 0, 0, iABx) /* OP_SETLIST */ 99 ,opmode(0, 0, 0, 0, 0, 0, iABx) /* OP_SETLIST */
diff --git a/lopcodes.h b/lopcodes.h
index 5386bb21..259b5f5d 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.101 2002/08/20 20:03:05 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.102 2002/08/21 18:56:09 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*/
@@ -172,6 +172,7 @@ OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
172OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ 172OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
173 173
174OP_FORLOOP,/* A sBx R(A)+=R(A+2); if R(A) <?= R(A+1) then PC+= sBx */ 174OP_FORLOOP,/* A sBx R(A)+=R(A+2); if R(A) <?= R(A+1) then PC+= sBx */
175OP_FORPREP,/* A sBx R(A)-=R(A+2); PC += sBx */
175 176
176OP_TFORLOOP,/* A C R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); 177OP_TFORLOOP,/* A C R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
177 if R(A+2) ~= nil then pc++ */ 178 if R(A+2) ~= nil then pc++ */
@@ -214,7 +215,6 @@ enum OpModeMask {
214 OpModesetA, /* instruction set register A */ 215 OpModesetA, /* instruction set register A */
215 OpModeK, /* Bx is a constant */ 216 OpModeK, /* Bx is a constant */
216 OpModeT /* operator is a test */ 217 OpModeT /* operator is a test */
217
218}; 218};
219 219
220 220
diff --git a/lparser.c b/lparser.c
index 0ebb1ee3..ffbe49d9 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.207 2003/02/28 17:19:47 roberto Exp roberto $ 2** $Id: lparser.c,v 1.208 2003/04/03 13:35:34 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*/
@@ -1027,30 +1027,34 @@ static int exp1 (LexState *ls) {
1027 1027
1028 1028
1029static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { 1029static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
1030 /* forbody -> DO block */
1030 BlockCnt bl; 1031 BlockCnt bl;
1031 FuncState *fs = ls->fs; 1032 FuncState *fs = ls->fs;
1032 int prep, endfor; 1033 int prep, endfor;
1033 adjustlocalvars(ls, nvars); /* scope for all variables */ 1034 adjustlocalvars(ls, 3); /* control variables */
1034 check(ls, TK_DO); 1035 check(ls, TK_DO);
1035 enterblock(fs, &bl, 1); /* loop block */ 1036 prep = luaK_codeAsBx(fs, (isnum ? OP_FORPREP : OP_TFORPREP), base, NO_JUMP);
1036 prep = luaK_getlabel(fs); 1037 enterblock(fs, &bl, 0); /* scope for declared variables */
1038 adjustlocalvars(ls, nvars);
1039 luaK_reserveregs(fs, nvars);
1037 block(ls); 1040 block(ls);
1038 luaK_patchtohere(fs, prep-1); 1041 leaveblock(fs); /* end of scope for declared variables */
1042 luaK_patchtohere(fs, prep);
1039 endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : 1043 endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
1040 luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3); 1044 luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
1041 luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ 1045 luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
1042 luaK_patchlist(fs, (isnum) ? endfor : luaK_jump(fs), prep); 1046 luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
1043 leaveblock(fs);
1044} 1047}
1045 1048
1046 1049
1047static void fornum (LexState *ls, TString *varname, int line) { 1050static void fornum (LexState *ls, TString *varname, int line) {
1048 /* fornum -> NAME = exp1,exp1[,exp1] DO body */ 1051 /* fornum -> NAME = exp1,exp1[,exp1] forbody */
1049 FuncState *fs = ls->fs; 1052 FuncState *fs = ls->fs;
1050 int base = fs->freereg; 1053 int base = fs->freereg;
1051 new_localvar(ls, varname, 0); 1054 new_localvarstr(ls, "(for index)", 0);
1052 new_localvarstr(ls, "(for limit)", 1); 1055 new_localvarstr(ls, "(for limit)", 1);
1053 new_localvarstr(ls, "(for step)", 2); 1056 new_localvarstr(ls, "(for step)", 2);
1057 new_localvar(ls, varname, 3);
1054 check(ls, '='); 1058 check(ls, '=');
1055 exp1(ls); /* initial value */ 1059 exp1(ls); /* initial value */
1056 check(ls, ','); 1060 check(ls, ',');
@@ -1061,39 +1065,39 @@ static void fornum (LexState *ls, TString *varname, int line) {
1061 luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); 1065 luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
1062 luaK_reserveregs(fs, 1); 1066 luaK_reserveregs(fs, 1);
1063 } 1067 }
1064 luaK_codeABC(fs, OP_SUB, fs->freereg - 3, fs->freereg - 3, fs->freereg - 1); 1068 forbody(ls, base, line, 1, 1);
1065 luaK_jump(fs);
1066 forbody(ls, base, line, 3, 1);
1067} 1069}
1068 1070
1069 1071
1070static void forlist (LexState *ls, TString *indexname) { 1072static void forlist (LexState *ls, TString *indexname) {
1071 /* forlist -> NAME {,NAME} IN explist1 DO body */ 1073 /* forlist -> NAME {,NAME} IN explist1 forbody */
1072 FuncState *fs = ls->fs; 1074 FuncState *fs = ls->fs;
1073 expdesc e; 1075 expdesc e;
1074 int nvars = 0; 1076 int nvars = 0;
1075 int line; 1077 int line;
1076 int base = fs->freereg; 1078 int base = fs->freereg;
1079 /* create control variables */
1077 new_localvarstr(ls, "(for generator)", nvars++); 1080 new_localvarstr(ls, "(for generator)", nvars++);
1078 new_localvarstr(ls, "(for state)", nvars++); 1081 new_localvarstr(ls, "(for state)", nvars++);
1082 new_localvarstr(ls, "(for control)", nvars++);
1083 /* create declared variables */
1079 new_localvar(ls, indexname, nvars++); 1084 new_localvar(ls, indexname, nvars++);
1080 while (testnext(ls, ',')) 1085 while (testnext(ls, ','))
1081 new_localvar(ls, str_checkname(ls), nvars++); 1086 new_localvar(ls, str_checkname(ls), nvars++);
1082 check(ls, TK_IN); 1087 check(ls, TK_IN);
1083 line = ls->linenumber; 1088 line = ls->linenumber;
1084 adjust_assign(ls, nvars, explist1(ls, &e), &e); 1089 adjust_assign(ls, 3, explist1(ls, &e), &e);
1085 luaK_checkstack(fs, 3); /* extra space to call generator */ 1090 luaK_checkstack(fs, 3); /* extra space to call generator */
1086 luaK_codeAsBx(fs, OP_TFORPREP, base, NO_JUMP); 1091 forbody(ls, base, line, nvars - 3, 0);
1087 forbody(ls, base, line, nvars, 0);
1088} 1092}
1089 1093
1090 1094
1091static void forstat (LexState *ls, int line) { 1095static void forstat (LexState *ls, int line) {
1092 /* forstat -> fornum | forlist */ 1096 /* forstat -> FOR (fornum | forlist) END */
1093 FuncState *fs = ls->fs; 1097 FuncState *fs = ls->fs;
1094 TString *varname; 1098 TString *varname;
1095 BlockCnt bl; 1099 BlockCnt bl;
1096 enterblock(fs, &bl, 0); /* block to control variable scope */ 1100 enterblock(fs, &bl, 1); /* scope for loop and control variables */
1097 next(ls); /* skip `for' */ 1101 next(ls); /* skip `for' */
1098 varname = str_checkname(ls); /* first variable name */ 1102 varname = str_checkname(ls); /* first variable name */
1099 switch (ls->t.token) { 1103 switch (ls->t.token) {
@@ -1102,7 +1106,7 @@ static void forstat (LexState *ls, int line) {
1102 default: luaX_syntaxerror(ls, "`=' or `in' expected"); 1106 default: luaX_syntaxerror(ls, "`=' or `in' expected");
1103 } 1107 }
1104 check_match(ls, TK_END, TK_FOR, line); 1108 check_match(ls, TK_END, TK_FOR, line);
1105 leaveblock(fs); 1109 leaveblock(fs); /* loop scope (`break' jumps to this point) */
1106} 1110}
1107 1111
1108 1112
diff --git a/lvm.c b/lvm.c
index a3fa1ae7..f5348881 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.284 2003/04/03 13:35:34 roberto Exp roberto $ 2** $Id: lvm.c,v 1.285 2003/05/05 18:39:57 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*/
@@ -639,43 +639,45 @@ StkId luaV_execute (lua_State *L) {
639 } 639 }
640 } 640 }
641 case OP_FORLOOP: { 641 case OP_FORLOOP: {
642 lua_Number step, idx, limit; 642 lua_Number step = nvalue(ra+2);
643 lua_Number idx = nvalue(ra) + step; /* increment index */
644 lua_Number limit = nvalue(ra+1);
645 if (step > 0 ? idx <= limit : idx >= limit) {
646 dojump(pc, GETARG_sBx(i)); /* jump back */
647 setnvalue(ra, idx); /* update internal index... */
648 setnvalue(ra+3, idx); /* ...and external index */
649 }
650 break;
651 }
652 case OP_FORPREP: {
653 const TObject *init = ra;
643 const TObject *plimit = ra+1; 654 const TObject *plimit = ra+1;
644 const TObject *pstep = ra+2; 655 const TObject *pstep = ra+2;
645 if (!ttisnumber(ra)) 656 if (!tonumber(init, ra))
646 luaG_runerror(L, "`for' initial value must be a number"); 657 luaG_runerror(L, "`for' initial value must be a number");
647 if (!tonumber(plimit, ra+1)) 658 else if (!tonumber(plimit, ra+1))
648 luaG_runerror(L, "`for' limit must be a number"); 659 luaG_runerror(L, "`for' limit must be a number");
649 if (!tonumber(pstep, ra+2)) 660 else if (!tonumber(pstep, ra+2))
650 luaG_runerror(L, "`for' step must be a number"); 661 luaG_runerror(L, "`for' step must be a number");
651 step = nvalue(pstep); 662 setnvalue(ra, nvalue(ra) - nvalue(pstep));
652 idx = nvalue(ra) + step; /* increment index */ 663 dojump(pc, GETARG_sBx(i));
653 limit = nvalue(plimit);
654 if (step > 0 ? idx <= limit : idx >= limit) {
655 dojump(pc, GETARG_sBx(i)); /* jump back */
656 chgnvalue(ra, idx); /* update index */
657 }
658 break; 664 break;
659 } 665 }
660 case OP_TFORLOOP: { 666 case OP_TFORLOOP: {
661 int nvar = GETARG_C(i) + 1; 667 StkId cb = ra + 3; /* call base */
662 StkId cb = ra + nvar + 2; /* call base */
663 setobjs2s(cb, ra);
664 setobjs2s(cb+1, ra+1);
665 setobjs2s(cb+2, ra+2); 668 setobjs2s(cb+2, ra+2);
669 setobjs2s(cb+1, ra+1);
670 setobjs2s(cb, ra);
666 L->top = cb+3; /* func. + 2 args (state and index) */ 671 L->top = cb+3; /* func. + 2 args (state and index) */
667 luaD_call(L, cb, nvar); 672 luaD_call(L, cb, GETARG_C(i));
668 L->top = L->ci->top; 673 L->top = L->ci->top;
669 ra = XRA(i) + 2; /* final position of first result */ 674 cb = XRA(i) + 3; /* previous call may change the stack */
670 cb = ra + nvar; 675 if (ttisnil(cb)) /* break loop? */
671 do { /* move results to proper positions */
672 nvar--;
673 setobjs2s(ra+nvar, cb+nvar);
674 } while (nvar > 0);
675 if (ttisnil(ra)) /* break loop? */
676 pc++; /* skip jump (break loop) */ 676 pc++; /* skip jump (break loop) */
677 else 677 else {
678 setobjs2s(cb-1, cb); /* save control variable */
678 dojump(pc, GETARG_sBx(*pc) + 1); /* jump back */ 679 dojump(pc, GETARG_sBx(*pc) + 1); /* jump back */
680 }
679 break; 681 break;
680 } 682 }
681 case OP_TFORPREP: { /* for compatibility only */ 683 case OP_TFORPREP: { /* for compatibility only */