diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-05-13 10:09:00 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-05-13 10:09:00 -0300 |
commit | af19d556355b6e79296811cb18fe511f8784b8f1 (patch) | |
tree | 2126e8dec5d21939bb2ff298f29f0d429c62d7db | |
parent | b55fded18c270412e127259a5f28c785620dbf1a (diff) | |
download | lua-af19d556355b6e79296811cb18fe511f8784b8f1.tar.gz lua-af19d556355b6e79296811cb18fe511f8784b8f1.tar.bz2 lua-af19d556355b6e79296811cb18fe511f8784b8f1.zip |
generic for also coded to make test at the end of the loop
-rw-r--r-- | ldebug.c | 10 | ||||
-rw-r--r-- | lopcodes.c | 6 | ||||
-rw-r--r-- | lopcodes.h | 7 | ||||
-rw-r--r-- | lparser.c | 34 | ||||
-rw-r--r-- | lvm.c | 6 |
5 files changed, 36 insertions, 27 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.c,v 1.112 2002/05/07 17:36:56 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 1.113 2002/05/09 14:14:34 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 | */ |
@@ -336,6 +336,9 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { | |||
336 | check(c < MAXSTACK && b < c); | 336 | check(c < MAXSTACK && b < c); |
337 | break; | 337 | break; |
338 | } | 338 | } |
339 | case OP_TFORLOOP: | ||
340 | checkreg(pt, a+2+c); | ||
341 | /* go through */ | ||
339 | case OP_FORLOOP: | 342 | case OP_FORLOOP: |
340 | checkreg(pt, a+2); | 343 | checkreg(pt, a+2); |
341 | /* go through */ | 344 | /* go through */ |
@@ -347,11 +350,6 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { | |||
347 | pc += b; /* do the jump */ | 350 | pc += b; /* do the jump */ |
348 | break; | 351 | break; |
349 | } | 352 | } |
350 | case OP_TFORLOOP: { | ||
351 | checkreg(pt, a+2+c); | ||
352 | check(pc+2 < pt->sizecode); /* check skip */ | ||
353 | break; | ||
354 | } | ||
355 | case OP_CALL: { | 353 | case OP_CALL: { |
356 | if (b != 0) { | 354 | if (b != 0) { |
357 | checkreg(pt, a+b-1); | 355 | checkreg(pt, a+b-1); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.c,v 1.17 2002/04/24 20:07:46 roberto Exp roberto $ | 2 | ** $Id: lopcodes.c,v 1.18 2002/05/06 15:51:41 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 |
@@ -88,8 +88,8 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = { | |||
88 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_TAILCALL */ | 88 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_TAILCALL */ |
89 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_RETURN */ | 89 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_RETURN */ |
90 | ,opmode(0,0,0,0, 0,0,iAsBx) /* OP_FORLOOP */ | 90 | ,opmode(0,0,0,0, 0,0,iAsBx) /* OP_FORLOOP */ |
91 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_TFORLOOP */ | 91 | ,opmode(1,0,0,0, 0,0,iABC) /* OP_TFORLOOP */ |
92 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_TFORPREP */ | 92 | ,opmode(0,0,0,0, 0,0,iAsBx) /* OP_TFORPREP */ |
93 | ,opmode(0,0,0,0, 0,0,iABx) /* OP_SETLIST */ | 93 | ,opmode(0,0,0,0, 0,0,iABx) /* OP_SETLIST */ |
94 | ,opmode(0,0,0,0, 0,0,iABx) /* OP_SETLISTO */ | 94 | ,opmode(0,0,0,0, 0,0,iABx) /* OP_SETLISTO */ |
95 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_CLOSE */ | 95 | ,opmode(0,0,0,0, 0,0,iABC) /* OP_CLOSE */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.h,v 1.95 2002/04/24 20:07:46 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.96 2002/05/06 15:51:41 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 | */ |
@@ -170,7 +170,8 @@ OP_FORLOOP,/* A sBx R(A)+=R(A+2); if R(A) <?= R(A+1) then PC+= sBx */ | |||
170 | 170 | ||
171 | OP_TFORLOOP,/* A C R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); | 171 | OP_TFORLOOP,/* A C R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); |
172 | if R(A+2) ~= nil then pc++ */ | 172 | if R(A+2) ~= nil then pc++ */ |
173 | OP_TFORPREP,/* A if type(R(A)) == table then R(A+1):=R(A), R(A):=next */ | 173 | OP_TFORPREP,/* A sBx if type(R(A)) == table then R(A+1):=R(A), R(A):=next; |
174 | PC += sBx */ | ||
174 | 175 | ||
175 | OP_SETLIST,/* A Bx R(A)[Bx-Bx%FPF+i] := R(A+i), 1 <= i <= Bx%FPF+1 */ | 176 | OP_SETLIST,/* A Bx R(A)[Bx-Bx%FPF+i] := R(A+i), 1 <= i <= Bx%FPF+1 */ |
176 | OP_SETLISTO,/* A Bx */ | 177 | OP_SETLISTO,/* A Bx */ |
@@ -193,6 +194,8 @@ OP_CLOSURE/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ | |||
193 | (2) In OP_RETURN, if (B == 0) then return up to `top' | 194 | (2) In OP_RETURN, if (B == 0) then return up to `top' |
194 | 195 | ||
195 | (3) For comparisons, B specifies what conditions the test should accept. | 196 | (3) For comparisons, B specifies what conditions the test should accept. |
197 | |||
198 | (4) All `skips' (pc++) assume that next instruction is a jump | ||
196 | ===========================================================================*/ | 199 | ===========================================================================*/ |
197 | 200 | ||
198 | 201 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.180 2002/05/10 17:02:32 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.181 2002/05/10 19:22:11 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 | */ |
@@ -979,15 +979,16 @@ static void whilestat (LexState *ls, int line) { | |||
979 | int whileinit, blockinit, expinit; | 979 | int whileinit, blockinit, expinit; |
980 | expdesc v; | 980 | expdesc v; |
981 | BlockCnt bl; | 981 | BlockCnt bl; |
982 | next(ls); | 982 | next(ls); /* skip WHILE */ |
983 | whileinit = luaK_jump(fs); | 983 | whileinit = luaK_jump(fs); /* jump to condition (which will be moved) */ |
984 | expinit = luaK_getlabel(fs); | 984 | expinit = luaK_getlabel(fs); |
985 | expr(ls, &v); | 985 | expr(ls, &v); /* parse condition */ |
986 | if (v.k == VK) v.k = VTRUE; /* `trues' are all equal here */ | 986 | if (v.k == VK) v.k = VTRUE; /* `trues' are all equal here */ |
987 | lineexp = ls->linenumber; | 987 | lineexp = ls->linenumber; |
988 | luaK_goiffalse(fs, &v); | 988 | luaK_goiffalse(fs, &v); |
989 | luaK_dischargejpc(fs); | 989 | luaK_concat(fs, &v.f, fs->jpc); |
990 | sizeexp = fs->pc - expinit; | 990 | fs->jpc = NO_JUMP; |
991 | sizeexp = fs->pc - expinit; /* size of expression code */ | ||
991 | if (sizeexp > MAXEXPWHILE) | 992 | if (sizeexp > MAXEXPWHILE) |
992 | luaX_syntaxerror(ls, "while condition too complex"); | 993 | luaX_syntaxerror(ls, "while condition too complex"); |
993 | for (i = 0; i < sizeexp; i++) /* save `exp' code */ | 994 | for (i = 0; i < sizeexp; i++) /* save `exp' code */ |
@@ -998,14 +999,15 @@ static void whilestat (LexState *ls, int line) { | |||
998 | blockinit = luaK_getlabel(fs); | 999 | blockinit = luaK_getlabel(fs); |
999 | block(ls); | 1000 | block(ls); |
1000 | luaK_patchtohere(fs, whileinit); /* initial jump jumps to here */ | 1001 | luaK_patchtohere(fs, whileinit); /* initial jump jumps to here */ |
1002 | /* move `exp' back to code */ | ||
1001 | if (v.t != NO_JUMP) v.t += fs->pc - expinit; | 1003 | if (v.t != NO_JUMP) v.t += fs->pc - expinit; |
1002 | if (v.f != NO_JUMP) v.f += fs->pc - expinit; | 1004 | if (v.f != NO_JUMP) v.f += fs->pc - expinit; |
1003 | for (i=0; i<sizeexp; i++) | 1005 | for (i=0; i<sizeexp; i++) |
1004 | luaK_code(fs, codeexp[i], lineexp); | 1006 | luaK_code(fs, codeexp[i], lineexp); |
1005 | luaK_patchlist(fs, v.t, blockinit); | ||
1006 | luaK_patchtohere(fs, v.f); | ||
1007 | check_match(ls, TK_END, TK_WHILE, line); | 1007 | check_match(ls, TK_END, TK_WHILE, line); |
1008 | leaveblock(fs); | 1008 | leaveblock(fs); |
1009 | luaK_patchlist(fs, v.t, blockinit); /* true conditions go back to loop */ | ||
1010 | luaK_patchtohere(fs, v.f); /* false conditions finish the loop */ | ||
1009 | } | 1011 | } |
1010 | 1012 | ||
1011 | 1013 | ||
@@ -1061,8 +1063,8 @@ static void fornum (LexState *ls, TString *varname, int line) { | |||
1061 | block(ls); | 1063 | block(ls); |
1062 | luaK_patchtohere(fs, prep-1); | 1064 | luaK_patchtohere(fs, prep-1); |
1063 | endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); | 1065 | endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); |
1066 | luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ | ||
1064 | luaK_patchlist(fs, endfor, prep); | 1067 | luaK_patchlist(fs, endfor, prep); |
1065 | fs->f->lineinfo[endfor] = line; /* pretend that `OP_FOR' starts the loop */ | ||
1066 | } | 1068 | } |
1067 | 1069 | ||
1068 | 1070 | ||
@@ -1070,6 +1072,7 @@ static void forlist (LexState *ls, TString *indexname) { | |||
1070 | /* forlist -> NAME {,NAME} IN explist1 DO body */ | 1072 | /* forlist -> NAME {,NAME} IN explist1 DO body */ |
1071 | FuncState *fs = ls->fs; | 1073 | FuncState *fs = ls->fs; |
1072 | expdesc e; | 1074 | expdesc e; |
1075 | int line; | ||
1073 | int nvars = 0; | 1076 | int nvars = 0; |
1074 | int prep; | 1077 | int prep; |
1075 | int base = fs->freereg; | 1078 | int base = fs->freereg; |
@@ -1081,16 +1084,19 @@ static void forlist (LexState *ls, TString *indexname) { | |||
1081 | next(ls); | 1084 | next(ls); |
1082 | } | 1085 | } |
1083 | check(ls, TK_IN); | 1086 | check(ls, TK_IN); |
1087 | line = ls->linenumber; | ||
1084 | adjust_assign(ls, 3, explist1(ls, &e), &e); | 1088 | adjust_assign(ls, 3, explist1(ls, &e), &e); |
1085 | luaK_reserveregs(fs, nvars - 3); /* registers for other variables */ | 1089 | luaK_reserveregs(fs, nvars - 3); /* registers for other variables */ |
1086 | luaK_codeABC(fs, OP_TFORPREP, base, 0, 0); | 1090 | luaK_codeAsBx(fs, OP_TFORPREP, base, NO_JUMP); |
1087 | luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3); | ||
1088 | adjustlocalvars(ls, nvars); /* scope for all variables */ | 1091 | adjustlocalvars(ls, nvars); /* scope for all variables */ |
1089 | prep = luaK_jump(fs); | ||
1090 | check(ls, TK_DO); | 1092 | check(ls, TK_DO); |
1093 | prep = luaK_getlabel(fs); | ||
1091 | block(ls); | 1094 | block(ls); |
1092 | luaK_patchlist(fs, luaK_jump(fs), prep-1); | 1095 | luaK_patchtohere(fs, prep-1); |
1093 | luaK_patchtohere(fs, prep); | 1096 | removevars(fs->ls, fs->nactvar - nvars); /* deactivate locals for next op. */ |
1097 | luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3); | ||
1098 | luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ | ||
1099 | luaK_patchlist(fs, luaK_jump(fs), prep); | ||
1094 | } | 1100 | } |
1095 | 1101 | ||
1096 | 1102 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.229 2002/05/06 15:51:41 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.230 2002/05/09 14:14:34 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 | */ |
@@ -548,7 +548,8 @@ StkId luaV_execute (lua_State *L) { | |||
548 | L->top = ra+5; | 548 | L->top = ra+5; |
549 | luaD_call(L, ra+2, GETARG_C(i) + 1); | 549 | luaD_call(L, ra+2, GETARG_C(i) + 1); |
550 | L->top = L->ci->top; | 550 | L->top = L->ci->top; |
551 | if (ttype(ra+2) != LUA_TNIL) pc++; /* skip jump (keep looping) */ | 551 | if (ttype(ra+2) == LUA_TNIL) pc++; /* skip jump (break loop) */ |
552 | else dojump(pc, GETARG_sBx(*pc) + 1); /* else jump back */ | ||
552 | break; | 553 | break; |
553 | } | 554 | } |
554 | case OP_TFORPREP: { | 555 | case OP_TFORPREP: { |
@@ -557,6 +558,7 @@ StkId luaV_execute (lua_State *L) { | |||
557 | setsvalue(ra, luaS_new(L, "next")); | 558 | setsvalue(ra, luaS_new(L, "next")); |
558 | luaV_gettable(L, gt(L), ra, ra); | 559 | luaV_gettable(L, gt(L), ra, ra); |
559 | } | 560 | } |
561 | dojump(pc, GETARG_sBx(i)); | ||
560 | break; | 562 | break; |
561 | } | 563 | } |
562 | case OP_SETLIST: | 564 | case OP_SETLIST: |