summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c19
-rw-r--r--ldebug.c74
-rw-r--r--ldo.c8
-rw-r--r--lfunc.c9
-rw-r--r--lfunc.h5
-rw-r--r--lgc.c15
-rw-r--r--lmem.c5
-rw-r--r--lobject.c4
-rw-r--r--lobject.h24
-rw-r--r--lopcodes.h8
-rw-r--r--lparser.c73
-rw-r--r--lparser.h4
-rw-r--r--ltests.c4
-rw-r--r--lundump.c8
-rw-r--r--lvm.c100
15 files changed, 201 insertions, 159 deletions
diff --git a/lcode.c b/lcode.c
index 50ed11e6..98ad5078 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 1.37 2000/06/21 17:05:49 roberto Exp roberto $ 2** $Id: lcode.c,v 1.38 2000/06/21 18:13:56 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*/
@@ -283,7 +283,6 @@ static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) {
283 prevpos = fs->pc-1; 283 prevpos = fs->pc-1;
284 previous = &fs->f->code[prevpos]; 284 previous = &fs->f->code[prevpos];
285 LUA_ASSERT(L, *previous==previous_instruction(fs), "no jump allowed here"); 285 LUA_ASSERT(L, *previous==previous_instruction(fs), "no jump allowed here");
286 LUA_ASSERT(L, GET_OPCODE(*previous) != OP_SETLINE, "no setline allowed here");
287 if (!ISJUMP(GET_OPCODE(*previous))) 286 if (!ISJUMP(GET_OPCODE(*previous)))
288 prevpos = luaK_code1(fs, jump, NO_JUMP); 287 prevpos = luaK_code1(fs, jump, NO_JUMP);
289 else { /* last instruction is already a jump */ 288 else { /* last instruction is already a jump */
@@ -316,7 +315,6 @@ void luaK_tostack (LexState *ls, expdesc *v, int onlyone) {
316 FuncState *fs = ls->fs; 315 FuncState *fs = ls->fs;
317 if (!discharge(fs, v)) { /* `v' is an expression? */ 316 if (!discharge(fs, v)) { /* `v' is an expression? */
318 OpCode previous = GET_OPCODE(fs->f->code[fs->pc-1]); 317 OpCode previous = GET_OPCODE(fs->f->code[fs->pc-1]);
319 LUA_ASSERT(L, previous != OP_SETLINE, "bad place to set line");
320 if (!ISJUMP(previous) && v->u.l.f == NO_JUMP && v->u.l.t == NO_JUMP) { 318 if (!ISJUMP(previous) && v->u.l.f == NO_JUMP && v->u.l.t == NO_JUMP) {
321 /* expression has no jumps */ 319 /* expression has no jumps */
322 if (onlyone) 320 if (onlyone)
@@ -623,17 +621,15 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
623 case iS: i = CREATE_S(o, arg1); break; 621 case iS: i = CREATE_S(o, arg1); break;
624 case iAB: i = CREATE_AB(o, arg1, arg2); break; 622 case iAB: i = CREATE_AB(o, arg1, arg2); break;
625 } 623 }
626 /* check space for new instruction plus eventual SETLINE */ 624 if (fs->f->debug) {
627 luaM_growvector(fs->L, fs->f->code, fs->pc, 2, Instruction,
628 "code size overflow", MAX_INT);
629 /* check the need for SETLINE */
630 if (fs->debug && fs->ls->lastline != fs->lastsetline) {
631 LexState *ls = fs->ls; 625 LexState *ls = fs->ls;
632 luaX_checklimit(ls, ls->lastline, MAXARG_U, "lines in a chunk"); 626 luaX_checklimit(ls, ls->lastline, MAXARG_U, "lines in a chunk");
633 fs->f->code[fs->pc++] = CREATE_U(OP_SETLINE, ls->lastline); 627 luaM_growvector(fs->L, fs->f->lines, fs->pc, 1, int, "??", MAXARG_U);
634 fs->lastsetline = ls->lastline; 628 fs->f->lines[fs->pc] = ls->lastline;
635 } 629 }
636 /* put new instruction in code array */ 630 /* put new instruction in code array */
631 luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction,
632 "code size overflow", MAX_INT);
637 fs->f->code[fs->pc] = i; 633 fs->f->code[fs->pc] = i;
638 return fs->pc++; 634 return fs->pc++;
639} 635}
@@ -688,6 +684,5 @@ const struct OpProperties luaK_opproperties[NUM_OPCODES] = {
688 {iS, -3}, /* OP_FORLOOP */ 684 {iS, -3}, /* OP_FORLOOP */
689 {iS, 3}, /* OP_LFORPREP */ 685 {iS, 3}, /* OP_LFORPREP */
690 {iS, -4}, /* OP_LFORLOOP */ 686 {iS, -4}, /* OP_LFORLOOP */
691 {iAB, VD}, /* OP_CLOSURE */ 687 {iAB, VD} /* OP_CLOSURE */
692 {iU, 0} /* OP_SETLINE */
693}; 688};
diff --git a/ldebug.c b/ldebug.c
index 6d26029b..c816200d 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.22 2000/06/08 17:48:31 roberto Exp roberto $ 2** $Id: ldebug.c,v 1.23 2000/06/12 13:52:05 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*/
@@ -23,22 +23,21 @@
23#include "luadebug.h" 23#include "luadebug.h"
24 24
25 25
26static const lua_Type normtype[] = { /* ORDER LUA_T */
27 TAG_USERDATA, TAG_NUMBER, TAG_STRING, TAG_TABLE,
28 TAG_LCLOSURE, TAG_CCLOSURE, TAG_NIL,
29 TAG_LCLOSURE, TAG_CCLOSURE /* TAG_LMARK, TAG_CMARK */
30};
31
32 26
33static void setnormalized (TObject *d, const TObject *s) { 27static void setnormalized (TObject *d, const TObject *s) {
34 d->value = s->value; 28 switch (s->ttype) {
35 d->ttype = normtype[ttype(s)]; 29 case TAG_CMARK: {
36} 30 clvalue(d) = clvalue(s);
37 31 ttype(d) = TAG_CCLOSURE;
38 32 break;
39 33 }
40static int hasdebuginfo (lua_State *L, StkId f) { 34 case TAG_LMARK: {
41 return (f+1 < L->top && (f+1)->ttype == TAG_LINE); 35 clvalue(d) = infovalue(s)->func;
36 ttype(d) = TAG_LCLOSURE;
37 break;
38 }
39 default: *d = *s;
40 }
42} 41}
43 42
44 43
@@ -88,22 +87,35 @@ int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
88 87
89static int lua_nups (StkId f) { 88static int lua_nups (StkId f) {
90 switch (ttype(f)) { 89 switch (ttype(f)) {
91 case TAG_LCLOSURE: case TAG_CCLOSURE: 90 case TAG_LCLOSURE: case TAG_CCLOSURE: case TAG_CMARK:
92 case TAG_LMARK: case TAG_CMARK:
93 return clvalue(f)->nupvalues; 91 return clvalue(f)->nupvalues;
92 case TAG_LMARK:
93 return infovalue(f)->func->nupvalues;
94 default: 94 default:
95 return 0; 95 return 0;
96 } 96 }
97} 97}
98 98
99 99
100static int lua_currentline (lua_State *L, StkId f) { 100static int lua_currentline (StkId f) {
101 return hasdebuginfo(L, f) ? (f+1)->value.i : -1; 101 if (ttype(f) != TAG_LMARK)
102 return -1; /* only active lua functions have current-line information */
103 else {
104 CallInfo *ci = infovalue(f);
105 int *lines = ci->func->f.l->lines;
106 if (!lines) return -1; /* no static debug information */
107 else return lines[ci->pc];
108 }
109}
110
111
112static int lua_currentpc (StkId f) {
113 return infovalue(f)->pc;
102} 114}
103 115
104 116
105static Proto *getluaproto (StkId f) { 117static Proto *getluaproto (StkId f) {
106 return (ttype(f) == TAG_LMARK) ? clvalue(f)->f.l : NULL; 118 return (ttype(f) == TAG_LMARK) ? infovalue(f)->func->f.l : NULL;
107} 119}
108 120
109 121
@@ -111,12 +123,9 @@ int lua_getlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) {
111 StkId f = ar->_func; 123 StkId f = ar->_func;
112 Proto *fp = getluaproto(f); 124 Proto *fp = getluaproto(f);
113 if (!fp) return 0; /* `f' is not a Lua function? */ 125 if (!fp) return 0; /* `f' is not a Lua function? */
114 v->name = luaF_getlocalname(fp, v->index, lua_currentline(L, f)); 126 v->name = luaF_getlocalname(fp, v->index, lua_currentpc(f));
115 if (!v->name) return 0; 127 if (!v->name) return 0;
116 /* if `name', there must be a TAG_LINE */ 128 v->value = luaA_putluaObject(L, (f+1)+(v->index-1));
117 /* therefore, f+2 points to function base */
118 LUA_ASSERT(L, ttype(f+1) == TAG_LINE, "");
119 v->value = luaA_putluaObject(L, (f+2)+(v->index-1));
120 return 1; 129 return 1;
121} 130}
122 131
@@ -124,22 +133,27 @@ int lua_getlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) {
124int lua_setlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) { 133int lua_setlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) {
125 StkId f = ar->_func; 134 StkId f = ar->_func;
126 Proto *fp = getluaproto(f); 135 Proto *fp = getluaproto(f);
136 UNUSED(L);
127 if (!fp) return 0; /* `f' is not a Lua function? */ 137 if (!fp) return 0; /* `f' is not a Lua function? */
128 v->name = luaF_getlocalname(fp, v->index, lua_currentline(L, f)); 138 v->name = luaF_getlocalname(fp, v->index, lua_currentpc(f));
129 if (!v->name || v->name[0] == '*') return 0; /* `*' starts private locals */ 139 if (!v->name || v->name[0] == '*') return 0; /* `*' starts private locals */
130 LUA_ASSERT(L, ttype(f+1) == TAG_LINE, ""); 140 *((f+1)+(v->index-1)) = *v->value;
131 *((f+2)+(v->index-1)) = *v->value;
132 return 1; 141 return 1;
133} 142}
134 143
135 144
136static void lua_funcinfo (lua_Debug *ar, StkId func) { 145static void lua_funcinfo (lua_Debug *ar, StkId func) {
137 switch (ttype(func)) { 146 switch (ttype(func)) {
138 case TAG_LCLOSURE: case TAG_LMARK: 147 case TAG_LCLOSURE:
139 ar->source = clvalue(func)->f.l->source->str; 148 ar->source = clvalue(func)->f.l->source->str;
140 ar->linedefined = clvalue(func)->f.l->lineDefined; 149 ar->linedefined = clvalue(func)->f.l->lineDefined;
141 ar->what = "Lua"; 150 ar->what = "Lua";
142 break; 151 break;
152 case TAG_LMARK:
153 ar->source = infovalue(func)->func->f.l->source->str;
154 ar->linedefined = infovalue(func)->func->f.l->lineDefined;
155 ar->what = "Lua";
156 break;
143 case TAG_CCLOSURE: case TAG_CMARK: 157 case TAG_CCLOSURE: case TAG_CMARK:
144 ar->source = "(C)"; 158 ar->source = "(C)";
145 ar->linedefined = -1; 159 ar->linedefined = -1;
@@ -191,7 +205,7 @@ int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
191 lua_funcinfo(ar, func); 205 lua_funcinfo(ar, func);
192 break; 206 break;
193 case 'l': 207 case 'l':
194 ar->currentline = lua_currentline(L, func); 208 ar->currentline = lua_currentline(func);
195 break; 209 break;
196 case 'u': 210 case 'u':
197 ar->nups = lua_nups(func); 211 ar->nups = lua_nups(func);
diff --git a/ldo.c b/ldo.c
index 6f04c374..8fe2ca38 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.78 2000/06/12 13:52:05 roberto Exp roberto $ 2** $Id: ldo.c,v 1.79 2000/06/16 17:16:34 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -185,10 +185,14 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
185 retry: /* for `function' tag method */ 185 retry: /* for `function' tag method */
186 switch (ttype(func)) { 186 switch (ttype(func)) {
187 case TAG_LCLOSURE: { 187 case TAG_LCLOSURE: {
188 CallInfo ci;
189 ci.func = clvalue(func);
190 ci.pc = 0;
188 ttype(func) = TAG_LMARK; 191 ttype(func) = TAG_LMARK;
192 infovalue(func) = &ci;
189 if (callhook) 193 if (callhook)
190 luaD_callHook(L, func, callhook, "call"); 194 luaD_callHook(L, func, callhook, "call");
191 firstResult = luaV_execute(L, clvalue(func), func+1); 195 firstResult = luaV_execute(L, ci.func, func+1);
192 break; 196 break;
193 } 197 }
194 case TAG_CCLOSURE: { 198 case TAG_CCLOSURE: {
diff --git a/lfunc.c b/lfunc.c
index 39753bdc..cabe717f 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lfunc.c,v 1.23 2000/05/30 19:00:31 roberto Exp roberto $ 2** $Id: lfunc.c,v 1.24 2000/06/12 13:52:05 roberto Exp roberto $
3** Auxiliary functions to manipulate prototypes and closures 3** Auxiliary functions to manipulate prototypes and closures
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -35,6 +35,7 @@ Closure *luaF_newclosure (lua_State *L, int nelems) {
35Proto *luaF_newproto (lua_State *L) { 35Proto *luaF_newproto (lua_State *L) {
36 Proto *f = luaM_new(L, Proto); 36 Proto *f = luaM_new(L, Proto);
37 f->code = NULL; 37 f->code = NULL;
38 f->lines = NULL;
38 f->lineDefined = 0; 39 f->lineDefined = 0;
39 f->source = NULL; 40 f->source = NULL;
40 f->kstr = NULL; 41 f->kstr = NULL;
@@ -59,6 +60,7 @@ void luaF_freeproto (lua_State *L, Proto *f) {
59 luaM_free(L, f->kstr); 60 luaM_free(L, f->kstr);
60 luaM_free(L, f->knum); 61 luaM_free(L, f->knum);
61 luaM_free(L, f->kproto); 62 luaM_free(L, f->kproto);
63 luaM_free(L, f->lines);
62 luaM_free(L, f); 64 luaM_free(L, f);
63} 65}
64 66
@@ -73,14 +75,13 @@ void luaF_freeclosure (lua_State *L, Closure *c) {
73** Look for n-th local variable at line `line' in function `func'. 75** Look for n-th local variable at line `line' in function `func'.
74** Returns NULL if not found. 76** Returns NULL if not found.
75*/ 77*/
76const char *luaF_getlocalname (const Proto *func, 78const char *luaF_getlocalname (const Proto *func, int local_number, int pc) {
77 int local_number, int line) {
78 int count = 0; 79 int count = 0;
79 const char *varname = NULL; 80 const char *varname = NULL;
80 LocVar *lv = func->locvars; 81 LocVar *lv = func->locvars;
81 if (lv == NULL) 82 if (lv == NULL)
82 return NULL; 83 return NULL;
83 for (; lv->line != -1 && lv->line < line; lv++) { 84 for (; lv->pc != -1 && lv->pc <= pc; lv++) {
84 if (lv->varname) { /* register */ 85 if (lv->varname) { /* register */
85 if (++count == local_number) 86 if (++count == local_number)
86 varname = lv->varname->str; 87 varname = lv->varname->str;
diff --git a/lfunc.h b/lfunc.h
index a0dc7817..1182e3fa 100644
--- a/lfunc.h
+++ b/lfunc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lfunc.h,v 1.10 1999/12/27 17:33:22 roberto Exp roberto $ 2** $Id: lfunc.h,v 1.11 2000/03/10 18:37:44 roberto Exp roberto $
3** Auxiliary functions to manipulate prototypes and closures 3** Auxiliary functions to manipulate prototypes and closures
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -17,8 +17,7 @@ Closure *luaF_newclosure (lua_State *L, int nelems);
17void luaF_freeproto (lua_State *L, Proto *f); 17void luaF_freeproto (lua_State *L, Proto *f);
18void luaF_freeclosure (lua_State *L, Closure *c); 18void luaF_freeclosure (lua_State *L, Closure *c);
19 19
20const char *luaF_getlocalname (const Proto *func, 20const char *luaF_getlocalname (const Proto *func, int local_number, int pc);
21 int local_number, int line);
22 21
23 22
24#endif 23#endif
diff --git a/lgc.c b/lgc.c
index bc0494f0..3bcfd1b7 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.56 2000/06/08 17:48:31 roberto Exp roberto $ 2** $Id: lgc.c,v 1.57 2000/06/12 13:52:05 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -41,7 +41,7 @@ static void protomark (lua_State *L, Proto *f) {
41 protomark(L, f->kproto[i]); 41 protomark(L, f->kproto[i]);
42 if (f->locvars) { /* is there debug information? */ 42 if (f->locvars) { /* is there debug information? */
43 LocVar *lv; 43 LocVar *lv;
44 for (lv=f->locvars; lv->line != -1; lv++) /* mark local-variable names */ 44 for (lv=f->locvars; lv->pc != -1; lv++) /* mark local-variable names */
45 if (lv->varname) strmark(L, lv->varname); 45 if (lv->varname) strmark(L, lv->varname);
46 } 46 }
47 } 47 }
@@ -99,9 +99,16 @@ static int markobject (lua_State *L, TObject *o) {
99 case TAG_TABLE: 99 case TAG_TABLE:
100 tablemark(L, hvalue(o)); 100 tablemark(L, hvalue(o));
101 break; 101 break;
102 case TAG_LCLOSURE: case TAG_LMARK: 102 case TAG_LCLOSURE:
103 protomark(L, clvalue(o)->f.l); 103 protomark(L, clvalue(o)->f.l);
104 /* go trhough */ 104 closuremark(L, clvalue(o));
105 break;
106 case TAG_LMARK: {
107 Closure *cl = infovalue(o)->func;
108 protomark(L, cl->f.l);
109 closuremark(L, cl);
110 break;
111 }
105 case TAG_CCLOSURE: case TAG_CMARK: 112 case TAG_CCLOSURE: case TAG_CMARK:
106 closuremark(L, clvalue(o)); 113 closuremark(L, clvalue(o));
107 break; 114 break;
diff --git a/lmem.c b/lmem.c
index b60285a6..f41d92d5 100644
--- a/lmem.c
+++ b/lmem.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lmem.c,v 1.32 2000/05/31 16:53:30 roberto Exp roberto $ 2** $Id: lmem.c,v 1.33 2000/06/12 13:52:05 roberto Exp roberto $
3** Interface to Memory Manager 3** Interface to Memory Manager
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -47,7 +47,8 @@
47 47
48 48
49/* ensures maximum alignment for HEADER */ 49/* ensures maximum alignment for HEADER */
50#define HEADER (sizeof(union { double d; char *s; long l; })) 50union L_U { double d; char *s; long l; };
51#define HEADER (sizeof(union L_U))
51 52
52#define MARKSIZE 16 53#define MARKSIZE 16
53#define MARK 0x55 /* 01010101 (a nice pattern) */ 54#define MARK 0x55 /* 01010101 (a nice pattern) */
diff --git a/lobject.c b/lobject.c
index d500fd1c..7d26a981 100644
--- a/lobject.c
+++ b/lobject.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.c,v 1.40 2000/06/08 17:48:31 roberto Exp roberto $ 2** $Id: lobject.c,v 1.41 2000/06/12 13:52:05 roberto Exp roberto $
3** Some generic functions over Lua objects 3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -16,7 +16,7 @@
16 16
17const char *const luaO_typenames[] = { /* ORDER LUA_T */ 17const char *const luaO_typenames[] = { /* ORDER LUA_T */
18 "userdata", "number", "string", "table", "function", "function", "nil", 18 "userdata", "number", "string", "table", "function", "function", "nil",
19 "function", "function", "line" 19 "function", "function"
20}; 20};
21 21
22 22
diff --git a/lobject.h b/lobject.h
index 0395afa3..2a61d138 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 1.66 2000/05/30 19:00:31 roberto Exp roberto $ 2** $Id: lobject.h,v 1.67 2000/06/08 18:27:13 roberto Exp roberto $
3** Type definitions for Lua objects 3** Type definitions for Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -46,9 +46,8 @@ typedef enum {
46 TAG_NIL, /* last "pre-defined" tag */ 46 TAG_NIL, /* last "pre-defined" tag */
47 47
48 TAG_LMARK, /* mark for Lua closures */ 48 TAG_LMARK, /* mark for Lua closures */
49 TAG_CMARK, /* mark for C closures */ 49 TAG_CMARK /* mark for C closures */
50 50
51 TAG_LINE
52} lua_Type; 51} lua_Type;
53 52
54/* tags for values visible from Lua == first user-created tag */ 53/* tags for values visible from Lua == first user-created tag */
@@ -63,10 +62,10 @@ typedef enum {
63 62
64typedef union { 63typedef union {
65 struct TString *ts; /* TAG_STRING, TAG_USERDATA */ 64 struct TString *ts; /* TAG_STRING, TAG_USERDATA */
66 struct Closure *cl; /* TAG_[CL]CLOSURE, TAG_[CL]MARK */ 65 struct Closure *cl; /* TAG_[CL]CLOSURE, TAG_CMARK */
67 struct Hash *a; /* TAG_TABLE */ 66 struct Hash *a; /* TAG_TABLE */
67 struct CallInfo *i; /* TAG_LMARK */
68 Number n; /* TAG_NUMBER */ 68 Number n; /* TAG_NUMBER */
69 int i; /* TAG_LINE */
70} Value; 69} Value;
71 70
72 71
@@ -76,6 +75,7 @@ typedef union {
76#define tsvalue(o) ((o)->value.ts) 75#define tsvalue(o) ((o)->value.ts)
77#define clvalue(o) ((o)->value.cl) 76#define clvalue(o) ((o)->value.cl)
78#define hvalue(o) ((o)->value.a) 77#define hvalue(o) ((o)->value.a)
78#define infovalue(o) ((o)->value.i)
79#define svalue(o) (tsvalue(o)->str) 79#define svalue(o) (tsvalue(o)->str)
80 80
81 81
@@ -119,8 +119,10 @@ typedef struct Proto {
119 struct Proto **kproto; /* functions defined inside the function */ 119 struct Proto **kproto; /* functions defined inside the function */
120 int nkproto; /* size of `kproto' */ 120 int nkproto; /* size of `kproto' */
121 Instruction *code; /* ends with opcode ENDCODE */ 121 Instruction *code; /* ends with opcode ENDCODE */
122 int *lines; /* source line that generated each opcode */
122 int lineDefined; 123 int lineDefined;
123 TString *source; 124 TString *source;
125 int debug; /* flag for debug information */
124 int numparams; 126 int numparams;
125 int is_vararg; 127 int is_vararg;
126 int maxstacksize; 128 int maxstacksize;
@@ -130,7 +132,7 @@ typedef struct Proto {
130 132
131typedef struct LocVar { 133typedef struct LocVar {
132 TString *varname; /* NULL signals end of scope */ 134 TString *varname; /* NULL signals end of scope */
133 int line; 135 int pc;
134} LocVar; 136} LocVar;
135 137
136 138
@@ -165,6 +167,16 @@ typedef struct Hash {
165} Hash; 167} Hash;
166 168
167 169
170/*
171** informations about a call (for debugging)
172*/
173typedef struct CallInfo {
174 int pc; /* current pc of called function */
175 int line; /* current line */
176 struct Closure *func; /* function being called */
177} CallInfo;
178
179
168extern const char *const luaO_typenames[]; 180extern const char *const luaO_typenames[];
169extern const TObject luaO_nilobject; 181extern const TObject luaO_nilobject;
170 182
diff --git a/lopcodes.h b/lopcodes.h
index f98f562b..e5067493 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.63 2000/06/05 14:56:18 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.64 2000/06/21 17:05:49 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*/
@@ -146,13 +146,11 @@ OP_FORLOOP,/* J */
146OP_LFORPREP,/* J */ 146OP_LFORPREP,/* J */
147OP_LFORLOOP,/* J */ 147OP_LFORLOOP,/* J */
148 148
149OP_CLOSURE,/* A B v_b-v_1 closure(KPROTO[a], v_1-v_b) */ 149OP_CLOSURE/* A B v_b-v_1 closure(KPROTO[a], v_1-v_b) */
150
151OP_SETLINE/* U - - LINE=u */
152 150
153} OpCode; 151} OpCode;
154 152
155#define NUM_OPCODES ((int)OP_SETLINE+1) 153#define NUM_OPCODES ((int)OP_CLOSURE+1)
156 154
157 155
158#define ISJUMP(o) (OP_JMPNE <= (o) && (o) <= OP_JMP) 156#define ISJUMP(o) (OP_JMPNE <= (o) && (o) <= OP_JMP)
diff --git a/lparser.c b/lparser.c
index e920af3e..725ff0ed 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.97 2000/06/19 18:26:23 roberto Exp roberto $ 2** $Id: lparser.c,v 1.98 2000/06/21 18:13:56 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*/
@@ -152,19 +152,19 @@ static int checkname (LexState *ls) {
152} 152}
153 153
154 154
155static void luaI_registerlocalvar (LexState *ls, TString *varname, int line) { 155static void luaI_registerlocalvar (LexState *ls, TString *varname, int pc) {
156 FuncState *fs = ls->fs; 156 FuncState *fs = ls->fs;
157 if (fs->debug) { 157 if (fs->f->debug) {
158 Proto *f = fs->f; 158 Proto *f = fs->f;
159 luaM_growvector(ls->L, f->locvars, fs->nvars, 1, LocVar, "", MAX_INT); 159 luaM_growvector(ls->L, f->locvars, fs->nvars, 1, LocVar, "", MAX_INT);
160 f->locvars[fs->nvars].varname = varname; 160 f->locvars[fs->nvars].varname = varname;
161 f->locvars[fs->nvars].line = line; 161 f->locvars[fs->nvars].pc = pc;
162 fs->nvars++; 162 fs->nvars++;
163 } 163 }
164} 164}
165 165
166 166
167static void store_localvar (LexState *ls, TString *name, int n) { 167static void new_localvar (LexState *ls, TString *name, int n) {
168 FuncState *fs = ls->fs; 168 FuncState *fs = ls->fs;
169 luaX_checklimit(ls, fs->nlocalvar+n+1, MAXLOCALS, "local variables"); 169 luaX_checklimit(ls, fs->nlocalvar+n+1, MAXLOCALS, "local variables");
170 fs->localvar[fs->nlocalvar+n] = name; 170 fs->localvar[fs->nlocalvar+n] = name;
@@ -172,27 +172,27 @@ static void store_localvar (LexState *ls, TString *name, int n) {
172 172
173 173
174static void adjustlocalvars (LexState *ls, int nvars) { 174static void adjustlocalvars (LexState *ls, int nvars) {
175 int line = ls->fs->lastsetline;
176 FuncState *fs = ls->fs; 175 FuncState *fs = ls->fs;
177 int i; 176 int i;
177 /* `pc' is first opcode where variable is already active */
178 for (i=fs->nlocalvar; i<fs->nlocalvar+nvars; i++) 178 for (i=fs->nlocalvar; i<fs->nlocalvar+nvars; i++)
179 luaI_registerlocalvar(ls, fs->localvar[i], line); 179 luaI_registerlocalvar(ls, fs->localvar[i], fs->pc);
180 fs->nlocalvar += nvars; 180 fs->nlocalvar += nvars;
181} 181}
182 182
183 183
184static void removelocalvars (LexState *ls, int nvars) { 184static void removelocalvars (LexState *ls, int nvars) {
185 int line = ls->fs->lastsetline; 185 FuncState *fs = ls->fs;
186 int i; 186 int i;
187 /* `pc' is first opcode where variable is already dead */
187 for (i=0;i<nvars;i++) 188 for (i=0;i<nvars;i++)
188 luaI_registerlocalvar(ls, NULL, line); 189 luaI_registerlocalvar(ls, NULL, fs->pc);
189 ls->fs->nlocalvar -= nvars; 190 fs->nlocalvar -= nvars;
190} 191}
191 192
192 193
193static void add_localvar (LexState *ls, const char *name) { 194static void new_localvarstr (LexState *ls, const char *name, int n) {
194 store_localvar(ls, luaS_newfixed(ls->L, name), 0); 195 new_localvar(ls, luaS_newfixed(ls->L, name), n);
195 adjustlocalvars(ls, 1);
196} 196}
197 197
198 198
@@ -277,8 +277,10 @@ static void code_params (LexState *ls, int nparams, int dots) {
277 luaX_checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters"); 277 luaX_checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters");
278 fs->f->numparams = fs->nlocalvar; /* `self' could be there already */ 278 fs->f->numparams = fs->nlocalvar; /* `self' could be there already */
279 fs->f->is_vararg = dots; 279 fs->f->is_vararg = dots;
280 if (dots) 280 if (dots) {
281 add_localvar(ls, "arg"); 281 new_localvarstr(ls, "arg", 0);
282 adjustlocalvars(ls, 1);
283 }
282 luaK_deltastack(fs, fs->nlocalvar); /* count parameters in the stack */ 284 luaK_deltastack(fs, fs->nlocalvar); /* count parameters in the stack */
283} 285}
284 286
@@ -320,7 +322,6 @@ static void open_func (LexState *ls, FuncState *fs) {
320 fs->stacklevel = 0; 322 fs->stacklevel = 0;
321 fs->nlocalvar = 0; 323 fs->nlocalvar = 0;
322 fs->nupvalues = 0; 324 fs->nupvalues = 0;
323 fs->lastsetline = 0;
324 fs->bl = NULL; 325 fs->bl = NULL;
325 fs->f = f; 326 fs->f = f;
326 f->source = ls->source; 327 f->source = ls->source;
@@ -358,7 +359,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z) {
358 luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z))); 359 luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z)));
359 open_func(&lexstate, &funcstate); 360 open_func(&lexstate, &funcstate);
360 next(&lexstate); /* read first token */ 361 next(&lexstate); /* read first token */
361 funcstate.debug = L->debug; /* previous `next' may scan a pragma */ 362 funcstate.f->debug = L->debug; /* previous `next' may scan a pragma */
362 chunk(&lexstate); 363 chunk(&lexstate);
363 check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected"); 364 check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");
364 close_func(&lexstate); 365 close_func(&lexstate);
@@ -821,22 +822,23 @@ static void repeatstat (LexState *ls, int line) {
821} 822}
822 823
823 824
824static void forbody (LexState *ls, OpCode prepfor, OpCode loopfor) { 825static void forbody (LexState *ls, int nvar, OpCode prepfor, OpCode loopfor) {
825 /* forbody -> DO block END */ 826 /* forbody -> DO block END */
826 FuncState *fs = ls->fs; 827 FuncState *fs = ls->fs;
827 int prep = luaK_code1(fs, prepfor, NO_JUMP); 828 int prep = luaK_code1(fs, prepfor, NO_JUMP);
828 int blockinit = luaK_getlabel(fs); 829 int blockinit = luaK_getlabel(fs);
829 check(ls, TK_DO); 830 check(ls, TK_DO);
831 adjustlocalvars(ls, nvar); /* scope for control variables */
830 block(ls); 832 block(ls);
831 luaK_patchlist(fs, prep, luaK_getlabel(fs)); 833 luaK_patchlist(fs, prep, luaK_getlabel(fs));
832 luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit); 834 luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit);
835 removelocalvars(ls, nvar);
833} 836}
834 837
835 838
836static void fornum (LexState *ls, TString *varname) { 839static void fornum (LexState *ls, TString *varname) {
837 /* fornum -> NAME = exp1,exp1[,exp1] forbody */ 840 /* fornum -> NAME = exp1,exp1[,exp1] forbody */
838 FuncState *fs = ls->fs; 841 FuncState *fs = ls->fs;
839 store_localvar(ls, varname, 0);
840 check(ls, '='); 842 check(ls, '=');
841 exp1(ls); /* initial value */ 843 exp1(ls); /* initial value */
842 check(ls, ','); 844 check(ls, ',');
@@ -845,11 +847,10 @@ static void fornum (LexState *ls, TString *varname) {
845 exp1(ls); /* optional step */ 847 exp1(ls); /* optional step */
846 else 848 else
847 luaK_code1(fs, OP_PUSHINT, 1); /* default step */ 849 luaK_code1(fs, OP_PUSHINT, 1); /* default step */
848 adjustlocalvars(ls, 1); /* scope for control variables */ 850 new_localvar(ls, varname, 0);
849 add_localvar(ls, "*limit*"); 851 new_localvarstr(ls, "*limit*", 1);
850 add_localvar(ls, "*count*"); 852 new_localvarstr(ls, "*step*", 2);
851 forbody(ls, OP_FORPREP, OP_FORLOOP); 853 forbody(ls, 3, OP_FORPREP, OP_FORLOOP);
852 removelocalvars(ls, 3);
853} 854}
854 855
855 856
@@ -864,13 +865,11 @@ static void forlist (LexState *ls, TString *indexname) {
864 "`in' expected"); 865 "`in' expected");
865 next(ls); /* skip `in' */ 866 next(ls); /* skip `in' */
866 exp1(ls); /* table */ 867 exp1(ls); /* table */
867 add_localvar(ls, "*table*"); 868 new_localvarstr(ls, "*table*", 0);
868 add_localvar(ls, "*counter*"); 869 new_localvarstr(ls, "*counter*", 1);
869 store_localvar(ls, indexname, 0); 870 new_localvar(ls, indexname, 2);
870 store_localvar(ls, valname, 1); 871 new_localvar(ls, valname, 3);
871 adjustlocalvars(ls, 2); /* scope for control variable */ 872 forbody(ls, 4, OP_LFORPREP, OP_LFORLOOP);
872 forbody(ls, OP_LFORPREP, OP_LFORLOOP);
873 removelocalvars(ls, 4);
874} 873}
875 874
876 875
@@ -931,7 +930,7 @@ static void localstat (LexState *ls) {
931 int nexps; 930 int nexps;
932 do { 931 do {
933 next(ls); /* skip LOCAL or ',' */ 932 next(ls); /* skip LOCAL or ',' */
934 store_localvar(ls, str_checkname(ls), nvars++); 933 new_localvar(ls, str_checkname(ls), nvars++);
935 } while (ls->t.token == ','); 934 } while (ls->t.token == ',');
936 if (optional(ls, '=')) 935 if (optional(ls, '='))
937 nexps = explist1(ls); 936 nexps = explist1(ls);
@@ -1072,7 +1071,7 @@ static void parlist (LexState *ls) {
1072 do { 1071 do {
1073 switch (ls->t.token) { 1072 switch (ls->t.token) {
1074 case TK_DOTS: next(ls); dots = 1; break; 1073 case TK_DOTS: next(ls); dots = 1; break;
1075 case TK_NAME: store_localvar(ls, str_checkname(ls), nparams++); break; 1074 case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break;
1076 default: luaK_error(ls, "<name> or `...' expected"); 1075 default: luaK_error(ls, "<name> or `...' expected");
1077 } 1076 }
1078 } while (!dots && optional(ls, ',')); 1077 } while (!dots && optional(ls, ','));
@@ -1086,10 +1085,12 @@ static void body (LexState *ls, int needself, int line) {
1086 FuncState new_fs; 1085 FuncState new_fs;
1087 open_func(ls, &new_fs); 1086 open_func(ls, &new_fs);
1088 new_fs.f->lineDefined = line; 1087 new_fs.f->lineDefined = line;
1089 new_fs.debug = ls->L->debug; 1088 new_fs.f->debug = ls->L->debug;
1090 check(ls, '('); 1089 check(ls, '(');
1091 if (needself) 1090 if (needself) {
1092 add_localvar(ls, "self"); 1091 new_localvarstr(ls, "self", 0);
1092 adjustlocalvars(ls, 1);
1093 }
1093 parlist(ls); 1094 parlist(ls);
1094 check(ls, ')'); 1095 check(ls, ')');
1095 chunk(ls); 1096 chunk(ls);
diff --git a/lparser.h b/lparser.h
index 2fb8e000..2432c08e 100644
--- a/lparser.h
+++ b/lparser.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.h,v 1.17 2000/05/25 18:26:42 roberto Exp roberto $ 2** $Id: lparser.h,v 1.18 2000/06/21 18:13:56 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*/
@@ -48,8 +48,6 @@ typedef struct FuncState {
48 int nlocalvar; /* number of active local variables */ 48 int nlocalvar; /* number of active local variables */
49 int nupvalues; /* number of upvalues */ 49 int nupvalues; /* number of upvalues */
50 int nvars; /* number of entries in f->locvars */ 50 int nvars; /* number of entries in f->locvars */
51 int lastsetline; /* line where last SETLINE was issued */
52 int debug; /* flag to generate debug information */
53 struct Breaklabel *bl; /* chain of breakable blocks */ 51 struct Breaklabel *bl; /* chain of breakable blocks */
54 expdesc upvalues[MAXUPVALUES]; /* upvalues */ 52 expdesc upvalues[MAXUPVALUES]; /* upvalues */
55 TString *localvar[MAXLOCALS]; /* store local variable names */ 53 TString *localvar[MAXLOCALS]; /* store local variable names */
diff --git a/ltests.c b/ltests.c
index dd247b5b..7e7c980b 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 1.25 2000/06/12 13:52:05 roberto Exp roberto $ 2** $Id: ltests.c,v 1.26 2000/06/21 17:05:49 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -58,7 +58,7 @@ static const char *const instrname[NUM_OPCODES] = {
58 "ADD", "ADDI", "SUB", "MULT", "DIV", "POW", "CONCAT", "MINUS", "NOT", 58 "ADD", "ADDI", "SUB", "MULT", "DIV", "POW", "CONCAT", "MINUS", "NOT",
59 "JMPNE", "JMPEQ", "JMPLT", "JMPLE", "JMPGT", "JMPGE", "JMPT", "JMPF", 59 "JMPNE", "JMPEQ", "JMPLT", "JMPLE", "JMPGT", "JMPGE", "JMPT", "JMPF",
60 "JMPONT", "JMPONF", "JMP", "PUSHNILJMP", "FORPREP", "FORLOOP", "LFORPREP", 60 "JMPONT", "JMPONF", "JMP", "PUSHNILJMP", "FORPREP", "FORLOOP", "LFORPREP",
61 "LFORLOOP", "CLOSURE", "SETLINE" 61 "LFORLOOP", "CLOSURE"
62}; 62};
63 63
64 64
diff --git a/lundump.c b/lundump.c
index 97ceccaf..36c89704 100644
--- a/lundump.c
+++ b/lundump.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lundump.c,v 1.21 2000/05/08 19:32:53 roberto Exp roberto $ 2** $Id: lundump.c,v 1.22 2000/06/12 13:52:05 roberto Exp roberto $
3** load bytecodes from files 3** load bytecodes from files
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -93,7 +93,7 @@ static TString* LoadString (lua_State* L, ZIO* Z)
93static void SwapCode (lua_State* L, Instruction* code, int size, ZIO* Z) 93static void SwapCode (lua_State* L, Instruction* code, int size, ZIO* Z)
94{ 94{
95 unsigned char* p; 95 unsigned char* p;
96 int c; 96 unsigned char c;
97 if (sizeof(Instruction)==4) 97 if (sizeof(Instruction)==4)
98 while (size--) 98 while (size--)
99 { 99 {
@@ -138,10 +138,10 @@ static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z)
138 tf->locvars=luaM_newvector(L,n+1,LocVar); 138 tf->locvars=luaM_newvector(L,n+1,LocVar);
139 for (i=0; i<n; i++) 139 for (i=0; i<n; i++)
140 { 140 {
141 tf->locvars[i].line=LoadInt(L,Z,"too many lines"); 141 tf->locvars[i].pc=LoadInt(L,Z,"too many lines");
142 tf->locvars[i].varname=LoadString(L,Z); 142 tf->locvars[i].varname=LoadString(L,Z);
143 } 143 }
144 tf->locvars[i].line=-1; /* flag end of vector */ 144 tf->locvars[i].pc=-1; /* flag end of vector */
145 tf->locvars[i].varname=NULL; 145 tf->locvars[i].varname=NULL;
146} 146}
147 147
diff --git a/lvm.c b/lvm.c
index 1a21a116..77faadfa 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.115 2000/06/12 13:52:05 roberto Exp roberto $ 2** $Id: lvm.c,v 1.116 2000/06/19 18:04:41 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*/
@@ -67,6 +67,23 @@ int luaV_tostring (lua_State *L, TObject *obj) { /* LUA_NUMBER */
67} 67}
68 68
69 69
70static void traceexec (lua_State *L, StkId base, int pc) {
71 CallInfo *ci = infovalue(base-1);
72 int oldpc = ci->pc;
73 pc--; /* pc has been already incremented */
74 ci->pc = pc;
75 if (L->linehook && ci->func->f.l->debug) {
76 int *lines = ci->func->f.l->lines;
77 LUA_ASSERT(L, lines, "must have debug information");
78 /* calls linehook when jumps back (a loop) or enters a new line */
79 if (pc <= oldpc || lines[pc] != ci->line) {
80 ci->line = lines[pc];
81 luaD_lineHook(L, base-2, lines[pc]);
82 }
83 }
84}
85
86
70static Closure *luaV_closure (lua_State *L, lua_Type t, int nelems) { 87static Closure *luaV_closure (lua_State *L, lua_Type t, int nelems) {
71 Closure *c = luaF_newclosure(L, nelems); 88 Closure *c = luaF_newclosure(L, nelems);
72 L->top -= nelems; 89 L->top -= nelems;
@@ -226,13 +243,6 @@ static void call_arith (lua_State *L, StkId top, IMS event) {
226} 243}
227 244
228 245
229static void addK (lua_State *L, StkId top, int k) {
230 ttype(top) = TAG_NUMBER;
231 nvalue(top) = (Number)k;
232 call_arith(L, top+1, IM_ADD);
233}
234
235
236static int luaV_strcomp (const TString *ls, const TString *rs) { 246static int luaV_strcomp (const TString *ls, const TString *rs) {
237 const char *l = ls->str; 247 const char *l = ls->str;
238 size_t ll = ls->u.s.len; 248 size_t ll = ls->u.s.len;
@@ -338,6 +348,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
338 StkId top; /* keep top local, for performance */ 348 StkId top; /* keep top local, for performance */
339 const Instruction *pc = tf->code; 349 const Instruction *pc = tf->code;
340 TString **kstr = tf->kstr; 350 TString **kstr = tf->kstr;
351 int debug = tf->debug;
341 luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK); 352 luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK);
342 if (tf->is_vararg) { /* varargs? */ 353 if (tf->is_vararg) { /* varargs? */
343 adjust_varargs(L, base, tf->numparams); 354 adjust_varargs(L, base, tf->numparams);
@@ -346,8 +357,13 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
346 else 357 else
347 luaD_adjusttop(L, base, tf->numparams); 358 luaD_adjusttop(L, base, tf->numparams);
348 top = L->top; 359 top = L->top;
360 /* main loop of interpreter */
349 for (;;) { 361 for (;;) {
350 Instruction i = *pc++; 362 Instruction i = *pc++;
363 if (debug) {
364 L->top = top;
365 traceexec(L, base, pc - tf->code);
366 }
351 switch (GET_OPCODE(i)) { 367 switch (GET_OPCODE(i)) {
352 368
353 case OP_END: 369 case OP_END:
@@ -499,8 +515,11 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
499 break; 515 break;
500 516
501 case OP_ADDI: 517 case OP_ADDI:
502 if (tonumber(top-1)) 518 if (tonumber(top-1)) {
503 addK(L, top, GETARG_S(i)); 519 ttype(top) = TAG_NUMBER;
520 nvalue(top) = (Number)GETARG_S(i);
521 call_arith(L, top+1, IM_ADD);
522 }
504 else 523 else
505 nvalue(top-1) += (Number)GETARG_S(i); 524 nvalue(top-1) += (Number)GETARG_S(i);
506 break; 525 break;
@@ -622,35 +641,44 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
622 lua_error(L, "`for' limit must be a number"); 641 lua_error(L, "`for' limit must be a number");
623 if (tonumber(top-3)) 642 if (tonumber(top-3))
624 lua_error(L, "`for' initial value must be a number"); 643 lua_error(L, "`for' initial value must be a number");
625 /* number of steps */ 644 if (nvalue(top-1) > 0 ?
626 nvalue(top-2) = (nvalue(top-2)-nvalue(top-3))/nvalue(top-1); 645 nvalue(top-3) > nvalue(top-2) :
627 nvalue(top-3) -= nvalue(top-1); /* to be undone by first FORLOOP */ 646 nvalue(top-3) < nvalue(top-2)) { /* `empty' loop? */
628 pc += GETARG_S(i); 647 top -= 3; /* remove control variables */
648 pc += GETARG_S(i)+1; /* jump to loop end */
649 }
629 break; 650 break;
630 651
631 case OP_FORLOOP: { 652 case OP_FORLOOP: {
632 LUA_ASSERT(L, ttype(top-1) == TAG_NUMBER, "invalid step"); 653 LUA_ASSERT(L, ttype(top-1) == TAG_NUMBER, "invalid step");
633 LUA_ASSERT(L, ttype(top-2) == TAG_NUMBER, "invalid count"); 654 LUA_ASSERT(L, ttype(top-2) == TAG_NUMBER, "invalid limit");
634 if (nvalue(top-2) < 0) 655 if (ttype(top-3) != TAG_NUMBER)
656 lua_error(L, "`for' index must be a number");
657 nvalue(top-3) += nvalue(top-1); /* increment index */
658 if (nvalue(top-1) > 0 ?
659 nvalue(top-3) > nvalue(top-2) :
660 nvalue(top-3) < nvalue(top-2))
635 top -= 3; /* end loop: remove control variables */ 661 top -= 3; /* end loop: remove control variables */
636 else { 662 else
637 nvalue(top-2)--; /* decrement count */ 663 pc += GETARG_S(i); /* repeat loop */
638 if (ttype(top-3) != TAG_NUMBER)
639 lua_error(L, "`for' index must be a number");
640 nvalue(top-3) += nvalue(top-1); /* increment index */
641 pc += GETARG_S(i);
642 }
643 break; 664 break;
644 } 665 }
645 666
646 case OP_LFORPREP: { 667 case OP_LFORPREP: {
647 if (ttype(top-1) != TAG_TABLE) 668 if (ttype(top-1) != TAG_TABLE)
648 lua_error(L, "`for' table must be a table"); 669 lua_error(L, "`for' table must be a table");
649 top += 3; /* counter + index,value */ 670 top++; /* counter */
650 ttype(top-3) = TAG_NUMBER; 671 L->top = top;
651 nvalue(top-3) = 0.0; /* counter */ 672 ttype(top-1) = TAG_NUMBER;
652 ttype(top-2) = ttype(top-1) = TAG_NIL; 673 nvalue(top-1) = (Number)luaA_next(L, hvalue(top-2), 0); /* counter */
653 pc += GETARG_S(i); 674 if (nvalue(top-1) == 0) { /* `empty' loop? */
675 top -= 2; /* remove table and counter */
676 pc += GETARG_S(i)+1; /* jump to loop end */
677 }
678 else {
679 top += 2; /* index,value */
680 LUA_ASSERT(L, top==L->top, "bad top");
681 }
654 break; 682 break;
655 } 683 }
656 684
@@ -678,22 +706,6 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
678 luaC_checkGC(L); 706 luaC_checkGC(L);
679 break; 707 break;
680 708
681 case OP_SETLINE:
682 if ((base-1)->ttype != TAG_LINE) {
683 /* open space for LINE value */
684 int n = top-base;
685 while (n--) base[n+1] = base[n];
686 base++;
687 top++;
688 (base-1)->ttype = TAG_LINE;
689 }
690 (base-1)->value.i = GETARG_U(i);
691 if (L->linehook) {
692 L->top = top;
693 luaD_lineHook(L, base-2, GETARG_U(i));
694 }
695 break;
696
697 } 709 }
698 } 710 }
699} 711}