aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c13
-rw-r--r--lcode.h3
-rw-r--r--lparser.c4
-rw-r--r--lvm.c38
4 files changed, 29 insertions, 29 deletions
diff --git a/lcode.c b/lcode.c
index 30a25a65..8fb0f70c 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 1.57 2001/01/19 13:20:30 roberto Exp roberto $ 2** $Id: lcode.c,v 1.58 2001/01/29 13:14:49 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*/
@@ -59,6 +59,17 @@ static void luaK_fixjump (FuncState *fs, int pc, int dest) {
59} 59}
60 60
61 61
62/*
63** prep-for instructions (OP_FORPREP & OP_LFORPREP) have a negated jump,
64** as they simulate the real jump...
65*/
66void luaK_fixfor (FuncState *fs, int pc, int dest) {
67 Instruction *jmp = &fs->f->code[pc];
68 int offset = dest-(pc+1);
69 SETARG_S(*jmp, -offset);
70}
71
72
62static int luaK_getjump (FuncState *fs, int pc) { 73static int luaK_getjump (FuncState *fs, int pc) {
63 int offset = GETARG_S(fs->f->code[pc]); 74 int offset = GETARG_S(fs->f->code[pc]);
64 if (offset == NO_JUMP) /* point to itself represents end of list */ 75 if (offset == NO_JUMP) /* point to itself represents end of list */
diff --git a/lcode.h b/lcode.h
index 6090d04e..3c8a13a7 100644
--- a/lcode.h
+++ b/lcode.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.h,v 1.17 2000/11/30 18:50:47 roberto Exp roberto $ 2** $Id: lcode.h,v 1.18 2000/12/04 18:33:40 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*/
@@ -53,6 +53,7 @@ int luaK_code1 (FuncState *fs, OpCode o, int arg1);
53int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2); 53int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2);
54int luaK_jump (FuncState *fs); 54int luaK_jump (FuncState *fs);
55void luaK_patchlist (FuncState *fs, int list, int target); 55void luaK_patchlist (FuncState *fs, int list, int target);
56void luaK_fixfor (FuncState *fs, int pc, int dest);
56void luaK_concat (FuncState *fs, int *l1, int l2); 57void luaK_concat (FuncState *fs, int *l1, int l2);
57void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue); 58void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue);
58int luaK_getlabel (FuncState *fs); 59int luaK_getlabel (FuncState *fs);
diff --git a/lparser.c b/lparser.c
index 83496128..09a5d4f5 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.125 2001/01/19 13:20:30 roberto Exp roberto $ 2** $Id: lparser.c,v 1.126 2001/01/29 13:14:49 roberto Exp roberto $
3** LL(1) Parser and code generator for Lua 3** LL(1) Parser and code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -854,7 +854,7 @@ static void forbody (LexState *ls, int nvar, OpCode prepfor, OpCode loopfor) {
854 adjustlocalvars(ls, nvar); /* scope for control variables */ 854 adjustlocalvars(ls, nvar); /* scope for control variables */
855 block(ls); 855 block(ls);
856 luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit); 856 luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit);
857 luaK_patchlist(fs, prep, luaK_getlabel(fs)); 857 luaK_fixfor(fs, prep, luaK_getlabel(fs));
858 removelocalvars(ls, nvar); 858 removelocalvars(ls, nvar);
859} 859}
860 860
diff --git a/lvm.c b/lvm.c
index 1da0ce20..04b4a610 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.158 2001/01/26 18:43:22 roberto Exp roberto $ 2** $Id: lvm.c,v 1.159 2001/01/29 13:02:20 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*/
@@ -330,7 +330,7 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
330 330
331 331
332 332
333#define dojump(pc, i) { int d = GETARG_S(i); pc += d; } 333#define dojump(pc, i) ((pc) += GETARG_S(i))
334 334
335/* 335/*
336** Executes the given Lua function. Parameters are between [base,top). 336** Executes the given Lua function. Parameters are between [base,top).
@@ -615,19 +615,15 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
615 break; 615 break;
616 } 616 }
617 case OP_FORPREP: { 617 case OP_FORPREP: {
618 int jmp = GETARG_S(i);
618 if (tonumber(top-1)) 619 if (tonumber(top-1))
619 luaD_error(L, "`for' step must be a number"); 620 luaD_error(L, "`for' step must be a number");
620 if (tonumber(top-2)) 621 if (tonumber(top-2))
621 luaD_error(L, "`for' limit must be a number"); 622 luaD_error(L, "`for' limit must be a number");
622 if (tonumber(top-3)) 623 if (tonumber(top-3))
623 luaD_error(L, "`for' initial value must be a number"); 624 luaD_error(L, "`for' initial value must be a number");
624 if (nvalue(top-1) > 0 ? 625 pc += -jmp; /* "jump" to loop end (delta is negated here) */
625 nvalue(top-3) > nvalue(top-2) : 626 goto forloop; /* do not increment index */
626 nvalue(top-3) < nvalue(top-2)) { /* `empty' loop? */
627 top -= 3; /* remove control variables */
628 dojump(pc, i); /* jump to loop end */
629 }
630 break;
631 } 627 }
632 case OP_FORLOOP: { 628 case OP_FORLOOP: {
633 lua_assert(ttype(top-1) == LUA_TNUMBER); 629 lua_assert(ttype(top-1) == LUA_TNUMBER);
@@ -635,6 +631,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
635 if (ttype(top-3) != LUA_TNUMBER) 631 if (ttype(top-3) != LUA_TNUMBER)
636 luaD_error(L, "`for' index must be a number"); 632 luaD_error(L, "`for' index must be a number");
637 nvalue(top-3) += nvalue(top-1); /* increment index */ 633 nvalue(top-3) += nvalue(top-1); /* increment index */
634 forloop:
638 if (nvalue(top-1) > 0 ? 635 if (nvalue(top-1) > 0 ?
639 nvalue(top-3) > nvalue(top-2) : 636 nvalue(top-3) > nvalue(top-2) :
640 nvalue(top-3) < nvalue(top-2)) 637 nvalue(top-3) < nvalue(top-2))
@@ -644,24 +641,15 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
644 break; 641 break;
645 } 642 }
646 case OP_LFORPREP: { 643 case OP_LFORPREP: {
647 int n; 644 int jmp = GETARG_S(i);
648 Hash *t;
649 if (ttype(top-1) != LUA_TTABLE) 645 if (ttype(top-1) != LUA_TTABLE)
650 luaD_error(L, "`for' table must be a table"); 646 luaD_error(L, "`for' table must be a table");
651 t = hvalue(top-1); 647 top += 3; /* index,key,value */
652 n = luaH_nexti(t, -1); 648 setnvalue(top-3, -1); /* initial index */
653 if (n == -1) { /* `empty' loop? */ 649 setnilvalue(top-2);
654 top--; /* remove table */ 650 setnilvalue(top-1);
655 dojump(pc, i); /* jump to loop end */ 651 pc += -jmp; /* "jump" to loop end (delta is negated here) */
656 } 652 /* go through */
657 else {
658 Node *node = node(t, n);
659 top += 3; /* index,key,value */
660 setnvalue(top-3, n); /* index */
661 setobj(top-2, key(node));
662 setobj(top-1, val(node));
663 }
664 break;
665 } 653 }
666 case OP_LFORLOOP: { 654 case OP_LFORLOOP: {
667 Hash *t = hvalue(top-4); 655 Hash *t = hvalue(top-4);