aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-02-05 20:39:12 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-02-05 20:39:12 -0200
commit38b0e6128da7796300e2e8621e87835e16539f5b (patch)
tree5b0a7ad2b0fb850d47f0566fd06b8cda013bbc8b
parentaddbe8c8b0587fd316f33fb013034e035f9217ed (diff)
downloadlua-38b0e6128da7796300e2e8621e87835e16539f5b.tar.gz
lua-38b0e6128da7796300e2e8621e87835e16539f5b.tar.bz2
lua-38b0e6128da7796300e2e8621e87835e16539f5b.zip
simpler implementation for `for' loops
-rw-r--r--lcode.c11
-rw-r--r--lcode.h1
-rw-r--r--ldebug.c40
-rw-r--r--lopcodes.c12
-rw-r--r--lopcodes.h6
-rw-r--r--lparser.c15
-rw-r--r--lvm.c67
7 files changed, 57 insertions, 95 deletions
diff --git a/lcode.c b/lcode.c
index b8a4ed19..c50596fb 100644
--- a/lcode.c
+++ b/lcode.c
@@ -77,17 +77,6 @@ static void luaK_fixjump (FuncState *fs, int pc, int dest) {
77 77
78 78
79/* 79/*
80** prep-for instructions (OP_FORPREP & OP_TFORPREP) have a negated jump,
81** as they simulate the real jump...
82*/
83void luaK_fixfor (FuncState *fs, int pc, int dest) {
84 Instruction *jmp = &fs->f->code[pc];
85 int offset = dest-(pc+1);
86 SETARG_sBc(*jmp, -offset);
87}
88
89
90/*
91** returns current `pc' and marks it as a jump target (to avoid wrong 80** returns current `pc' and marks it as a jump target (to avoid wrong
92** optimizations with consecutive instructions not in the same basic block). 81** optimizations with consecutive instructions not in the same basic block).
93** discharge list of jumps to last target. 82** discharge list of jumps to last target.
diff --git a/lcode.h b/lcode.h
index e9058393..0a6d7bf5 100644
--- a/lcode.h
+++ b/lcode.h
@@ -57,7 +57,6 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
57void luaK_setcallreturns (FuncState *fs, expdesc *var, int nresults); 57void luaK_setcallreturns (FuncState *fs, expdesc *var, int nresults);
58int luaK_jump (FuncState *fs); 58int luaK_jump (FuncState *fs);
59void luaK_patchlist (FuncState *fs, int list, int target); 59void luaK_patchlist (FuncState *fs, int list, int target);
60void luaK_fixfor (FuncState *fs, int pc, int dest);
61void luaK_concat (FuncState *fs, int *l1, int l2); 60void luaK_concat (FuncState *fs, int *l1, int l2);
62int luaK_getlabel (FuncState *fs); 61int luaK_getlabel (FuncState *fs);
63void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); 62void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
diff --git a/ldebug.c b/ldebug.c
index 9bdf90be..48090ae7 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -54,13 +54,6 @@ LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func) {
54} 54}
55 55
56 56
57static CallInfo *ci_stack (lua_State *L, StkId obj) {
58 CallInfo *ci = L->ci;
59 while (ci->base > obj && ci > L->base_ci) ci--;
60 return ci;
61}
62
63
64LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { 57LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
65 int status; 58 int status;
66 lua_lock(L); 59 lua_lock(L);
@@ -283,6 +276,7 @@ static int checklineinfo (const Proto *pt) {
283 int *lineinfo = pt->lineinfo; 276 int *lineinfo = pt->lineinfo;
284 if (lineinfo == NULL) return 1; 277 if (lineinfo == NULL) return 1;
285 check(pt->sizelineinfo >= 2 && lineinfo[pt->sizelineinfo-1] == MAX_INT); 278 check(pt->sizelineinfo >= 2 && lineinfo[pt->sizelineinfo-1] == MAX_INT);
279 lua_assert(luaG_getline(lineinfo, pt->sizecode-1, 1, NULL) < MAX_INT);
286 if (*lineinfo < 0) lineinfo++; 280 if (*lineinfo < 0) lineinfo++;
287 check(*lineinfo == 0); 281 check(*lineinfo == 0);
288 return 1; 282 return 1;
@@ -292,7 +286,7 @@ static int checklineinfo (const Proto *pt) {
292static int precheck (const Proto *pt) { 286static int precheck (const Proto *pt) {
293 check(checklineinfo(pt)); 287 check(checklineinfo(pt));
294 check(pt->maxstacksize <= MAXSTACK); 288 check(pt->maxstacksize <= MAXSTACK);
295 check(pt->numparams+pt->is_vararg <= pt->maxstacksize); 289 lua_assert(pt->numparams+pt->is_vararg <= pt->maxstacksize);
296 check(GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); 290 check(GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
297 return 1; 291 return 1;
298} 292}
@@ -381,7 +375,9 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
381 check(c < MAXSTACK && b < c); 375 check(c < MAXSTACK && b < c);
382 break; 376 break;
383 } 377 }
384 case OP_JMP: { 378 case OP_JMP:
379 case OP_FORLOOP:
380 case OP_TFORLOOP: {
385 int dest = pc+1+b; 381 int dest = pc+1+b;
386 check(0 <= dest && dest < pt->sizecode); 382 check(0 <= dest && dest < pt->sizecode);
387 /* not full check and jump is forward and do not skip `lastpc'? */ 383 /* not full check and jump is forward and do not skip `lastpc'? */
@@ -407,21 +403,6 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
407 if (b > 0) checkreg(pt, a+b-1); 403 if (b > 0) checkreg(pt, a+b-1);
408 break; 404 break;
409 } 405 }
410 case OP_FORPREP:
411 case OP_TFORPREP: {
412 int dest = pc-b; /* jump is negated here */
413 check(0 <= dest && dest < pt->sizecode &&
414 GET_OPCODE(pt->code[dest]) == op+1);
415 break;
416 }
417 case OP_FORLOOP:
418 case OP_TFORLOOP: {
419 int dest = pc+b;
420 check(0 <= dest && dest < pt->sizecode &&
421 pt->code[dest] == SET_OPCODE(i, op-1));
422 checkreg(pt, a + ((op == OP_FORLOOP) ? 2 : 3));
423 break;
424 }
425 case OP_SETLIST: { 406 case OP_SETLIST: {
426 checkreg(pt, a + (b&(LFIELDS_PER_FLUSH-1)) + 1); 407 checkreg(pt, a + (b&(LFIELDS_PER_FLUSH-1)) + 1);
427 break; 408 break;
@@ -445,12 +426,11 @@ int luaG_checkcode (const Proto *pt) {
445} 426}
446 427
447 428
448static const char *getobjname (lua_State *L, StkId obj, const char **name) { 429static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
449 CallInfo *ci = ci_stack(L, obj); 430 const char **name) {
450 if (isLmark(ci)) { /* an active Lua function? */ 431 if (isLmark(ci)) { /* an active Lua function? */
451 Proto *p = ci_func(ci)->l.p; 432 Proto *p = ci_func(ci)->l.p;
452 int pc = currentpc(L, ci); 433 int pc = currentpc(L, ci);
453 int stackpos = obj - ci->base;
454 Instruction i; 434 Instruction i;
455 *name = luaF_getlocalname(p, stackpos+1, pc); 435 *name = luaF_getlocalname(p, stackpos+1, pc);
456 if (*name) /* is a local? */ 436 if (*name) /* is a local? */
@@ -467,7 +447,7 @@ static const char *getobjname (lua_State *L, StkId obj, const char **name) {
467 int a = GETARG_A(i); 447 int a = GETARG_A(i);
468 int b = GETARG_B(i); /* move from `b' to `a' */ 448 int b = GETARG_B(i); /* move from `b' to `a' */
469 if (b < a) 449 if (b < a)
470 return getobjname(L, ci->base+b, name); /* get name for `b' */ 450 return getobjname(L, ci, b, name); /* get name for `b' */
471 break; 451 break;
472 } 452 }
473 case OP_GETTABLE: 453 case OP_GETTABLE:
@@ -496,7 +476,7 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
496 Instruction i; 476 Instruction i;
497 i = p->code[pc]; 477 i = p->code[pc];
498 return (GET_OPCODE(i) == OP_CALL 478 return (GET_OPCODE(i) == OP_CALL
499 ? getobjname(L, ci->base+GETARG_A(i), name) 479 ? getobjname(L, ci, GETARG_A(i), name)
500 : NULL); /* no useful name found */ 480 : NULL); /* no useful name found */
501 } 481 }
502} 482}
@@ -504,7 +484,7 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
504 484
505void luaG_typeerror (lua_State *L, StkId o, const char *op) { 485void luaG_typeerror (lua_State *L, StkId o, const char *op) {
506 const char *name; 486 const char *name;
507 const char *kind = getobjname(L, o, &name); 487 const char *kind = getobjname(L, L->ci, o - L->ci->base, &name); /* ?? */
508 const char *t = luaT_typenames[ttype(o)]; 488 const char *t = luaT_typenames[ttype(o)];
509 if (kind) 489 if (kind)
510 luaO_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)", 490 luaO_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)",
diff --git a/lopcodes.c b/lopcodes.c
index 4d43a3b1..7c452783 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -46,9 +46,7 @@ const char *const luaP_opnames[] = {
46 "TESTF", 46 "TESTF",
47 "CALL", 47 "CALL",
48 "RETURN", 48 "RETURN",
49 "FORPREP",
50 "FORLOOP", 49 "FORLOOP",
51 "TFORPREP",
52 "TFORLOOP", 50 "TFORLOOP",
53 "SETLIST", 51 "SETLIST",
54 "SETLISTO", 52 "SETLISTO",
@@ -60,10 +58,10 @@ const char *const luaP_opnames[] = {
60 58
61#define opmode(t,x,b,c,sa,k,m) (((t)<<OpModeT) | \ 59#define opmode(t,x,b,c,sa,k,m) (((t)<<OpModeT) | \
62 ((b)<<OpModeBreg) | ((c)<<OpModeCreg) | \ 60 ((b)<<OpModeBreg) | ((c)<<OpModeCreg) | \
63 ((sa)<<OpModesetA) | ((k)<<OpModeK) | (m)) 61 ((sa)<<OpModesetA) | ((k)<<OpModeK) | (x)<<OpModeNoTrace | (m))
64 62
65const lu_byte luaP_opmodes[NUM_OPCODES] = { 63const lu_byte luaP_opmodes[NUM_OPCODES] = {
66/* T _ B C sA K mode opcode */ 64/* T n B C sA K mode opcode */
67 opmode(0,0,1,0, 1,0,iABC) /* OP_MOVE */ 65 opmode(0,0,1,0, 1,0,iABC) /* OP_MOVE */
68 ,opmode(0,0,0,0, 1,1,iABc) /* OP_LOADK */ 66 ,opmode(0,0,0,0, 1,1,iABc) /* OP_LOADK */
69 ,opmode(0,0,0,0, 1,0,iABC) /* OP_LOADBOOL */ 67 ,opmode(0,0,0,0, 1,0,iABC) /* OP_LOADBOOL */
@@ -95,10 +93,8 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
95 ,opmode(1,0,1,0, 1,0,iABC) /* OP_TESTF */ 93 ,opmode(1,0,1,0, 1,0,iABC) /* OP_TESTF */
96 ,opmode(0,0,0,0, 0,0,iABC) /* OP_CALL */ 94 ,opmode(0,0,0,0, 0,0,iABC) /* OP_CALL */
97 ,opmode(0,0,0,0, 0,0,iABC) /* OP_RETURN */ 95 ,opmode(0,0,0,0, 0,0,iABC) /* OP_RETURN */
98 ,opmode(0,0,0,0, 0,0,iAsBc) /* OP_FORPREP */ 96 ,opmode(0,1,0,0, 0,0,iAsBc) /* OP_FORLOOP */
99 ,opmode(0,0,0,0, 0,0,iAsBc) /* OP_FORLOOP */ 97 ,opmode(0,1,0,0, 0,0,iAsBc) /* OP_TFORLOOP */
100 ,opmode(0,0,0,0, 0,0,iAsBc) /* OP_TFORPREP */
101 ,opmode(0,0,0,0, 0,0,iAsBc) /* OP_TFORLOOP */
102 ,opmode(0,0,0,0, 0,0,iABc) /* OP_SETLIST */ 98 ,opmode(0,0,0,0, 0,0,iABc) /* OP_SETLIST */
103 ,opmode(0,0,0,0, 0,0,iABc) /* OP_SETLISTO */ 99 ,opmode(0,0,0,0, 0,0,iABc) /* OP_SETLISTO */
104 ,opmode(0,0,0,0, 0,0,iABC) /* OP_CLOSE */ 100 ,opmode(0,0,0,0, 0,0,iABC) /* OP_CLOSE */
diff --git a/lopcodes.h b/lopcodes.h
index f8db57cf..e72ac0cd 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -169,10 +169,7 @@ OP_TESTF,/* A B if not (R(B)) then R(A) := R(B) else pc++ */
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_FORPREP,/* A sBc */
173OP_FORLOOP,/* A sBc */ 172OP_FORLOOP,/* A sBc */
174
175OP_TFORPREP,/* A sBc */
176OP_TFORLOOP,/* A sBc */ 173OP_TFORLOOP,/* A sBc */
177 174
178OP_SETLIST,/* A Bc R(A)[Bc-Bc%FPF+i] := R(A+i), 1 <= i <= Bc%FPF+1 */ 175OP_SETLIST,/* A Bc R(A)[Bc-Bc%FPF+i] := R(A+i), 1 <= i <= Bc%FPF+1 */
@@ -206,7 +203,8 @@ enum OpModeMask {
206 OpModeCreg, /* C is a register/constant */ 203 OpModeCreg, /* C is a register/constant */
207 OpModesetA, /* instruction set register A */ 204 OpModesetA, /* instruction set register A */
208 OpModeK, /* Bc is a constant */ 205 OpModeK, /* Bc is a constant */
209 OpModeT /* operator is a test */ 206 OpModeT, /* operator is a test */
207 OpModeNoTrace /* operator should not be traced */
210}; 208};
211 209
212extern const lu_byte luaP_opmodes[NUM_OPCODES]; 210extern const lu_byte luaP_opmodes[NUM_OPCODES];
diff --git a/lparser.c b/lparser.c
index fe81ed1d..4ddca7a8 100644
--- a/lparser.c
+++ b/lparser.c
@@ -955,17 +955,17 @@ static void exp1 (LexState *ls) {
955} 955}
956 956
957 957
958static void forbody (LexState *ls, int nvar, OpCode prepfor, OpCode loopfor) { 958static void forbody (LexState *ls, int nvar, OpCode loopfor) {
959 /* forbody -> DO block END */ 959 /* forbody -> DO block END */
960 FuncState *fs = ls->fs; 960 FuncState *fs = ls->fs;
961 int basereg = fs->freereg - nvar; 961 int basereg = fs->freereg - nvar;
962 int prep = luaK_codeAsBc(fs, prepfor, basereg, NO_JUMP); 962 int prep = luaK_jump(fs);
963 int blockinit = luaK_getlabel(fs); 963 int blockinit = luaK_getlabel(fs);
964 check(ls, TK_DO); 964 check(ls, TK_DO);
965 adjustlocalvars(ls, nvar); /* scope for control variables */ 965 adjustlocalvars(ls, nvar); /* scope for control variables */
966 block(ls); 966 block(ls);
967 luaK_patchlist(fs, prep, luaK_getlabel(fs));
967 luaK_patchlist(fs, luaK_codeAsBc(fs, loopfor, basereg, NO_JUMP), blockinit); 968 luaK_patchlist(fs, luaK_codeAsBc(fs, loopfor, basereg, NO_JUMP), blockinit);
968 luaK_fixfor(fs, prep, luaK_getlabel(fs));
969 removelocalvars(ls, nvar, 1); 969 removelocalvars(ls, nvar, 1);
970} 970}
971 971
@@ -986,13 +986,15 @@ static void fornum (LexState *ls, TString *varname) {
986 new_localvar(ls, varname, 0); 986 new_localvar(ls, varname, 0);
987 new_localvarstr(ls, "(limit)", 1); 987 new_localvarstr(ls, "(limit)", 1);
988 new_localvarstr(ls, "(step)", 2); 988 new_localvarstr(ls, "(step)", 2);
989 forbody(ls, 3, OP_FORPREP, OP_FORLOOP); 989 luaK_codeABC(fs, OP_SUB, fs->freereg - 3, fs->freereg - 3, fs->freereg - 1);
990 forbody(ls, 3, OP_FORLOOP);
990} 991}
991 992
992 993
993static void forlist (LexState *ls, TString *indexname) { 994static void forlist (LexState *ls, TString *indexname) {
994 /* forlist -> NAME,NAME IN exp1 forbody */ 995 /* forlist -> NAME,NAME IN exp1 forbody */
995 TString *valname; 996 TString *valname;
997 FuncState *fs = ls->fs;
996 check(ls, ','); 998 check(ls, ',');
997 valname = str_checkname(ls); 999 valname = str_checkname(ls);
998 next(ls); /* skip var name */ 1000 next(ls); /* skip var name */
@@ -1002,8 +1004,9 @@ static void forlist (LexState *ls, TString *indexname) {
1002 new_localvarstr(ls, "(index)", 1); 1004 new_localvarstr(ls, "(index)", 1);
1003 new_localvar(ls, indexname, 2); 1005 new_localvar(ls, indexname, 2);
1004 new_localvar(ls, valname, 3); 1006 new_localvar(ls, valname, 3);
1005 luaK_reserveregs(ls->fs, 3); /* registers for control, index and val */ 1007 luaK_reserveregs(fs, 3); /* registers for control, index and val */
1006 forbody(ls, 4, OP_TFORPREP, OP_TFORLOOP); 1008 luaK_codeABc(fs, OP_LOADK, fs->freereg - 3, luaK_numberK(fs, -1));
1009 forbody(ls, 4, OP_TFORLOOP);
1007} 1010}
1008 1011
1009 1012
diff --git a/lvm.c b/lvm.c
index a3ced1bc..94165d97 100644
--- a/lvm.c
+++ b/lvm.c
@@ -26,6 +26,9 @@
26#include "lvm.h" 26#include "lvm.h"
27 27
28 28
29/* limit for table tag-method chains (to avoid loops) */
30#define MAXTAGLOOP 10000
31
29 32
30static void luaV_checkGC (lua_State *L, StkId top) { 33static void luaV_checkGC (lua_State *L, StkId top) {
31 if (G(L)->nblocks >= G(L)->GCthreshold) { 34 if (G(L)->nblocks >= G(L)->GCthreshold) {
@@ -65,6 +68,8 @@ static void traceexec (lua_State *L, lua_Hook linehook) {
65 int *lineinfo = ci_func(ci)->l.p->lineinfo; 68 int *lineinfo = ci_func(ci)->l.p->lineinfo;
66 int pc = cast(int, *ci->pc - ci_func(ci)->l.p->code) - 1; 69 int pc = cast(int, *ci->pc - ci_func(ci)->l.p->code) - 1;
67 int newline; 70 int newline;
71 if (testOpMode(GET_OPCODE(*(*ci->pc - 1)), OpModeNoTrace))
72 return;
68 if (ci->line == -1) return; /* no linehooks for this function */ 73 if (ci->line == -1) return; /* no linehooks for this function */
69 else if (ci->line == 0) { /* first linehook? */ 74 else if (ci->line == 0) { /* first linehook? */
70 if (pc == 0) { /* function is starting now? */ 75 if (pc == 0) { /* function is starting now? */
@@ -123,6 +128,7 @@ static void callTM (lua_State *L, const TObject *f,
123*/ 128*/
124void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) { 129void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) {
125 const TObject *tm; 130 const TObject *tm;
131 int loop = 0;
126 init: 132 init:
127 if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */ 133 if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */
128 Table *et = hvalue(t)->metatable; 134 Table *et = hvalue(t)->metatable;
@@ -145,6 +151,7 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) {
145 if (ttype(tm) == LUA_TFUNCTION) 151 if (ttype(tm) == LUA_TFUNCTION)
146 callTMres(L, tm, t, key, res); 152 callTMres(L, tm, t, key, res);
147 else { 153 else {
154 if (++loop == MAXTAGLOOP) luaD_error(L, "loop in gettable");
148 t = (StkId)tm; /* ?? */ 155 t = (StkId)tm; /* ?? */
149 goto init; /* return luaV_gettable(L, tm, key, res); */ 156 goto init; /* return luaV_gettable(L, tm, key, res); */
150 } 157 }
@@ -156,6 +163,7 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) {
156*/ 163*/
157void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) { 164void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) {
158 const TObject *tm; 165 const TObject *tm;
166 int loop = 0;
159 init: 167 init:
160 if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */ 168 if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */
161 Table *et = hvalue(t)->metatable; 169 Table *et = hvalue(t)->metatable;
@@ -173,6 +181,7 @@ void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) {
173 if (ttype(tm) == LUA_TFUNCTION) 181 if (ttype(tm) == LUA_TFUNCTION)
174 callTM(L, tm, t, key, val); 182 callTM(L, tm, t, key, val);
175 else { 183 else {
184 if (++loop == MAXTAGLOOP) luaD_error(L, "loop in settable");
176 t = (StkId)tm; /* ?? */ 185 t = (StkId)tm; /* ?? */
177 goto init; /* luaV_settable(L, tm, key, val); */ 186 goto init; /* luaV_settable(L, tm, key, val); */
178 } 187 }
@@ -301,8 +310,8 @@ static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) {
301#define Arith(op, optm) { \ 310#define Arith(op, optm) { \
302 const TObject *b = RB(i); const TObject *c = RKC(i); \ 311 const TObject *b = RB(i); const TObject *c = RKC(i); \
303 TObject tempb, tempc; \ 312 TObject tempb, tempc; \
304 if ((ttype(b) == LUA_TNUMBER || (b = luaV_tonumber(b, &tempb)) != NULL) && \ 313 if ((b = luaV_tonumber(b, &tempb)) != NULL && \
305 (ttype(c) == LUA_TNUMBER || (c = luaV_tonumber(c, &tempc)) != NULL)) { \ 314 (c = luaV_tonumber(c, &tempc)) != NULL) { \
306 setnvalue(ra, nvalue(b) op nvalue(c)); \ 315 setnvalue(ra, nvalue(b) op nvalue(c)); \
307 } else \ 316 } else \
308 call_arith(L, RB(i), RKC(i), ra, optm); \ 317 call_arith(L, RB(i), RKC(i), ra, optm); \
@@ -423,7 +432,7 @@ StkId luaV_execute (lua_State *L) {
423 } 432 }
424 case OP_UNM: { 433 case OP_UNM: {
425 const TObject *rb = RB(i); 434 const TObject *rb = RB(i);
426 if (ttype(rb) == LUA_TNUMBER || (rb=luaV_tonumber(rb, ra)) != NULL) { 435 if ((rb=luaV_tonumber(rb, ra)) != NULL) {
427 setnvalue(ra, -nvalue(rb)); 436 setnvalue(ra, -nvalue(rb));
428 } 437 }
429 else { 438 else {
@@ -441,7 +450,7 @@ StkId luaV_execute (lua_State *L) {
441 case OP_CONCAT: { 450 case OP_CONCAT: {
442 int b = GETARG_B(i); 451 int b = GETARG_B(i);
443 int c = GETARG_C(i); 452 int c = GETARG_C(i);
444 luaV_strconc(L, c-b+1, c); /* this call may change `base' (and `ra') */ 453 luaV_strconc(L, c-b+1, c); /* may change `base' (and `ra') */
445 setobj(base+GETARG_A(i), base+b); 454 setobj(base+GETARG_A(i), base+b);
446 luaV_checkGC(L, base+c+1); 455 luaV_checkGC(L, base+c+1);
447 break; 456 break;
@@ -532,53 +541,41 @@ StkId luaV_execute (lua_State *L) {
532 } 541 }
533 break; 542 break;
534 } 543 }
535 case OP_FORPREP: { 544 case OP_FORLOOP: {
536 if (luaV_tonumber(ra, ra) == NULL) 545 lua_Number step, index, limit;
546 int j = GETARG_sBc(i);
547 pc += j; /* jump back before tests (for error messages) */
548 if (ttype(ra) != LUA_TNUMBER)
537 luaD_error(L, "`for' initial value must be a number"); 549 luaD_error(L, "`for' initial value must be a number");
538 if (luaV_tonumber(ra+1, ra+1) == NULL) 550 if (luaV_tonumber(ra+1, ra+1) == NULL)
539 luaD_error(L, "`for' limit must be a number"); 551 luaD_error(L, "`for' limit must be a number");
540 if (luaV_tonumber(ra+2, ra+2) == NULL) 552 if (luaV_tonumber(ra+2, ra+2) == NULL)
541 luaD_error(L, "`for' step must be a number"); 553 luaD_error(L, "`for' step must be a number");
542 /* decrement index (to be incremented) */ 554 step = nvalue(ra+2);
543 chgnvalue(ra, nvalue(ra) - nvalue(ra+2)); 555 index = nvalue(ra) + step; /* increment index */
544 pc += -GETARG_sBc(i); /* `jump' to loop end (delta is negated here) */ 556 limit = nvalue(ra+1);
545 /* store in `ra+1' total number of repetitions */ 557 if (step > 0 ? index <= limit : index >= limit)
546 chgnvalue(ra+1, (nvalue(ra+1)-nvalue(ra))/nvalue(ra+2)); 558 chgnvalue(ra, index); /* update index */
547 /* go through */ 559 else
548 } 560 pc -= j; /* undo jump */
549 case OP_FORLOOP: {
550 runtime_check(L, ttype(ra+1) == LUA_TNUMBER &&
551 ttype(ra+2) == LUA_TNUMBER);
552 if (ttype(ra) != LUA_TNUMBER)
553 luaD_error(L, "`for' index must be a number");
554 chgnvalue(ra+1, nvalue(ra+1) - 1); /* decrement counter */
555 if (nvalue(ra+1) >= 0) {
556 chgnvalue(ra, nvalue(ra) + nvalue(ra+2)); /* increment index */
557 dojump(pc, i); /* repeat loop */
558 }
559 break; 561 break;
560 } 562 }
561 case OP_TFORPREP: {
562 if (ttype(ra) != LUA_TTABLE)
563 luaD_error(L, "`for' table must be a table");
564 setnvalue(ra+1, -1); /* initial index */
565 setnilvalue(ra+2);
566 setnilvalue(ra+3);
567 pc += -GETARG_sBc(i); /* `jump' to loop end (delta is negated here) */
568 /* go through */
569 }
570 case OP_TFORLOOP: { 563 case OP_TFORLOOP: {
571 Table *t; 564 Table *t;
572 int n; 565 int n;
573 runtime_check(L, ttype(ra) == LUA_TTABLE && 566 int j = GETARG_sBc(i);
574 ttype(ra+1) == LUA_TNUMBER); 567 pc += j; /* jump back before tests (for error messages) */
568 if (ttype(ra) != LUA_TTABLE)
569 luaD_error(L, "`for' table must be a table");
570 runtime_check(L, ttype(ra+1) == LUA_TNUMBER);
575 t = hvalue(ra); 571 t = hvalue(ra);
576 n = cast(int, nvalue(ra+1)); 572 n = cast(int, nvalue(ra+1));
577 n = luaH_nexti(t, n, ra+2); 573 n = luaH_nexti(t, n, ra+2);
578 if (n != -1) { /* repeat loop? */ 574 if (n != -1) { /* repeat loop? */
579 setnvalue(ra+1, n); /* index */ 575 setnvalue(ra+1, n); /* index */
580 dojump(pc, i); /* repeat loop */
581 } 576 }
577 else
578 pc -= j; /* undo jump */
582 break; 579 break;
583 } 580 }
584 case OP_SETLIST: 581 case OP_SETLIST: