aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c108
-rw-r--r--lcode.h7
-rw-r--r--ldebug.c148
-rw-r--r--ldebug.h8
-rw-r--r--ldo.c8
-rw-r--r--ldo.h4
-rw-r--r--lobject.h8
-rw-r--r--lparser.c8
-rw-r--r--lparser.h3
-rw-r--r--lvm.c32
10 files changed, 230 insertions, 104 deletions
diff --git a/lcode.c b/lcode.c
index 98ad5078..4163c66d 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 1.38 2000/06/21 18:13:56 roberto Exp roberto $ 2** $Id: lcode.c,v 1.39 2000/06/26 19:28:31 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*/
@@ -423,12 +423,9 @@ int luaK_code1 (FuncState *fs, OpCode o, int arg1) {
423} 423}
424 424
425 425
426#define VD 100 /* flag for variable delta */
427
428
429int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { 426int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
430 Instruction i = previous_instruction(fs); 427 Instruction i = previous_instruction(fs);
431 int delta = luaK_opproperties[o].delta; 428 int delta = luaK_opproperties[o].push - luaK_opproperties[o].pop;
432 int optm = 0; /* 1 when there is an optimization */ 429 int optm = 0; /* 1 when there is an optimization */
433 switch (o) { 430 switch (o) {
434 case OP_CLOSURE: { 431 case OP_CLOSURE: {
@@ -621,7 +618,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
621 case iS: i = CREATE_S(o, arg1); break; 618 case iS: i = CREATE_S(o, arg1); break;
622 case iAB: i = CREATE_AB(o, arg1, arg2); break; 619 case iAB: i = CREATE_AB(o, arg1, arg2); break;
623 } 620 }
624 if (fs->f->debug) { 621 if (fs->debug) {
625 LexState *ls = fs->ls; 622 LexState *ls = fs->ls;
626 luaX_checklimit(ls, ls->lastline, MAXARG_U, "lines in a chunk"); 623 luaX_checklimit(ls, ls->lastline, MAXARG_U, "lines in a chunk");
627 luaM_growvector(fs->L, fs->f->lines, fs->pc, 1, int, "??", MAXARG_U); 624 luaM_growvector(fs->L, fs->f->lines, fs->pc, 1, int, "??", MAXARG_U);
@@ -636,53 +633,54 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
636 633
637 634
638const struct OpProperties luaK_opproperties[NUM_OPCODES] = { 635const struct OpProperties luaK_opproperties[NUM_OPCODES] = {
639 {iO, 0}, /* OP_END */ 636 {iO, 0, 0}, /* OP_END */
640 {iU, 0}, /* OP_RETURN */ 637 {iU, 0, 0}, /* OP_RETURN */
641 {iAB, 0}, /* OP_CALL */ 638 {iAB, 0, 0}, /* OP_CALL */
642 {iAB, 0}, /* OP_TAILCALL */ 639 {iAB, 0, 0}, /* OP_TAILCALL */
643 {iU, VD}, /* OP_PUSHNIL */ 640 {iU, VD, 0}, /* OP_PUSHNIL */
644 {iU, VD}, /* OP_POP */ 641 {iU, VD, 0}, /* OP_POP */
645 {iS, 1}, /* OP_PUSHINT */ 642 {iS, 1, 0}, /* OP_PUSHINT */
646 {iU, 1}, /* OP_PUSHSTRING */ 643 {iU, 1, 0}, /* OP_PUSHSTRING */
647 {iU, 1}, /* OP_PUSHNUM */ 644 {iU, 1, 0}, /* OP_PUSHNUM */
648 {iU, 1}, /* OP_PUSHNEGNUM */ 645 {iU, 1, 0}, /* OP_PUSHNEGNUM */
649 {iU, 1}, /* OP_PUSHUPVALUE */ 646 {iU, 1, 0}, /* OP_PUSHUPVALUE */
650 {iU, 1}, /* OP_GETLOCAL */ 647 {iU, 1, 0}, /* OP_GETLOCAL */
651 {iU, 1}, /* OP_GETGLOBAL */ 648 {iU, 1, 0}, /* OP_GETGLOBAL */
652 {iO, -1}, /* OP_GETTABLE */ 649 {iO, 1, 2}, /* OP_GETTABLE */
653 {iU, 0}, /* OP_GETDOTTED */ 650 {iU, 1, 1}, /* OP_GETDOTTED */
654 {iU, 0}, /* OP_GETINDEXED */ 651 {iU, 1, 1}, /* OP_GETINDEXED */
655 {iU, 1}, /* OP_PUSHSELF */ 652 {iU, 2, 1}, /* OP_PUSHSELF */
656 {iU, 1}, /* OP_CREATETABLE */ 653 {iU, 1, 0}, /* OP_CREATETABLE */
657 {iU, -1}, /* OP_SETLOCAL */ 654 {iU, 0, 1}, /* OP_SETLOCAL */
658 {iU, -1}, /* OP_SETGLOBAL */ 655 {iU, 0, 1}, /* OP_SETGLOBAL */
659 {iAB, VD}, /* OP_SETTABLE */ 656 {iAB, VD, 0}, /* OP_SETTABLE */
660 {iAB, VD}, /* OP_SETLIST */ 657 {iAB, VD, 0}, /* OP_SETLIST */
661 {iU, VD}, /* OP_SETMAP */ 658 {iU, VD, 0}, /* OP_SETMAP */
662 {iO, -1}, /* OP_ADD */ 659 {iO, 1, 2}, /* OP_ADD */
663 {iS, 0}, /* OP_ADDI */ 660 {iS, 1, 1}, /* OP_ADDI */
664 {iO, -1}, /* OP_SUB */ 661 {iO, 1, 2}, /* OP_SUB */
665 {iO, -1}, /* OP_MULT */ 662 {iO, 1, 2}, /* OP_MULT */
666 {iO, -1}, /* OP_DIV */ 663 {iO, 1, 2}, /* OP_DIV */
667 {iO, -1}, /* OP_POW */ 664 {iO, 1, 2}, /* OP_POW */
668 {iU, VD}, /* OP_CONCAT */ 665 {iU, VD, 0}, /* OP_CONCAT */
669 {iO, 0}, /* OP_MINUS */ 666 {iO, 1, 1}, /* OP_MINUS */
670 {iO, 0}, /* OP_NOT */ 667 {iO, 1, 1}, /* OP_NOT */
671 {iS, -2}, /* OP_JMPNE */ 668 {iS, 0, 2}, /* OP_JMPNE */
672 {iS, -2}, /* OP_JMPEQ */ 669 {iS, 0, 2}, /* OP_JMPEQ */
673 {iS, -2}, /* OP_JMPLT */ 670 {iS, 0, 2}, /* OP_JMPLT */
674 {iS, -2}, /* OP_JMPLE */ 671 {iS, 0, 2}, /* OP_JMPLE */
675 {iS, -2}, /* OP_JMPGT */ 672 {iS, 0, 2}, /* OP_JMPGT */
676 {iS, -2}, /* OP_JMPGE */ 673 {iS, 0, 2}, /* OP_JMPGE */
677 {iS, -1}, /* OP_JMPT */ 674 {iS, 0, 1}, /* OP_JMPT */
678 {iS, -1}, /* OP_JMPF */ 675 {iS, 0, 1}, /* OP_JMPF */
679 {iS, -1}, /* OP_JMPONT */ 676 {iS, 0, 1}, /* OP_JMPONT */
680 {iS, -1}, /* OP_JMPONF */ 677 {iS, 0, 1}, /* OP_JMPONF */
681 {iS, 0}, /* OP_JMP */ 678 {iS, 0, 0}, /* OP_JMP */
682 {iO, 1}, /* OP_PUSHNILJMP */ 679 {iO, 1, 0}, /* OP_PUSHNILJMP */
683 {iS, 0}, /* OP_FORPREP */ 680 {iS, 0, 0}, /* OP_FORPREP */
684 {iS, -3}, /* OP_FORLOOP */ 681 {iS, 0, 3}, /* OP_FORLOOP */
685 {iS, 3}, /* OP_LFORPREP */ 682 {iS, 3, 0}, /* OP_LFORPREP */
686 {iS, -4}, /* OP_LFORLOOP */ 683 {iS, 0, 4}, /* OP_LFORLOOP */
687 {iAB, VD} /* OP_CLOSURE */ 684 {iAB, VD, 0} /* OP_CLOSURE */
688}; 685};
686
diff --git a/lcode.h b/lcode.h
index 283c0f84..f7cf5e2c 100644
--- a/lcode.h
+++ b/lcode.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.h,v 1.13 2000/05/22 18:44:46 roberto Exp roberto $ 2** $Id: lcode.h,v 1.14 2000/06/16 17:51: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*/
@@ -22,9 +22,12 @@
22 22
23enum Mode {iO, iU, iS, iAB}; /* instruction format */ 23enum Mode {iO, iU, iS, iAB}; /* instruction format */
24 24
25#define VD 100 /* flag for variable delta */
26
25extern const struct OpProperties { 27extern const struct OpProperties {
26 char mode; 28 char mode;
27 signed char delta; 29 unsigned char push;
30 unsigned char pop;
28} luaK_opproperties[]; 31} luaK_opproperties[];
29 32
30 33
diff --git a/ldebug.c b/ldebug.c
index c816200d..050cc6c8 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.23 2000/06/12 13:52:05 roberto Exp roberto $ 2** $Id: ldebug.c,v 1.24 2000/06/26 19:28:31 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*/
@@ -13,10 +13,12 @@
13 13
14#include "lapi.h" 14#include "lapi.h"
15#include "lauxlib.h" 15#include "lauxlib.h"
16#include "lcode.h"
16#include "ldebug.h" 17#include "ldebug.h"
17#include "ldo.h" 18#include "ldo.h"
18#include "lfunc.h" 19#include "lfunc.h"
19#include "lobject.h" 20#include "lobject.h"
21#include "lopcodes.h"
20#include "lstate.h" 22#include "lstate.h"
21#include "ltable.h" 23#include "ltable.h"
22#include "ltm.h" 24#include "ltm.h"
@@ -97,6 +99,13 @@ static int lua_nups (StkId f) {
97} 99}
98 100
99 101
102static int lua_currentpc (StkId f) {
103 CallInfo *ci = infovalue(f);
104 LUA_ASSERT(L, ttype(f) == TAG_LMARK, "function has no pc");
105 return (*ci->pc - 1) - ci->func->f.l->code;
106}
107
108
100static int lua_currentline (StkId f) { 109static int lua_currentline (StkId f) {
101 if (ttype(f) != TAG_LMARK) 110 if (ttype(f) != TAG_LMARK)
102 return -1; /* only active lua functions have current-line information */ 111 return -1; /* only active lua functions have current-line information */
@@ -104,15 +113,11 @@ static int lua_currentline (StkId f) {
104 CallInfo *ci = infovalue(f); 113 CallInfo *ci = infovalue(f);
105 int *lines = ci->func->f.l->lines; 114 int *lines = ci->func->f.l->lines;
106 if (!lines) return -1; /* no static debug information */ 115 if (!lines) return -1; /* no static debug information */
107 else return lines[ci->pc]; 116 else return lines[lua_currentpc(f)];
108 } 117 }
109} 118}
110 119
111 120
112static int lua_currentpc (StkId f) {
113 return infovalue(f)->pc;
114}
115
116 121
117static Proto *getluaproto (StkId f) { 122static Proto *getluaproto (StkId f) {
118 return (ttype(f) == TAG_LMARK) ? infovalue(f)->func->f.l : NULL; 123 return (ttype(f) == TAG_LMARK) ? infovalue(f)->func->f.l : NULL;
@@ -225,17 +230,136 @@ int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
225} 230}
226 231
227 232
233/*
234** {======================================================
235** Symbolic Execution
236** =======================================================
237*/
238
239static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) {
240 int stack[MAXSTACK]; /* stores last instruction that changes each value */
241 const Instruction *code = pt->code;
242 int top = pt->numparams;
243 int pc = 0;
244 if (pt->is_vararg) /* varargs? */
245 top++; /* `arg' */
246 while (pc < lastpc) {
247 const Instruction i = code[pc++];
248 switch (GET_OPCODE(i)) {
249 case OP_CALL: {
250 int nresults = GETARG_B(i);
251 if (nresults == MULT_RET) nresults = 1;
252 top = GETARG_A(i);
253 while (nresults--)
254 stack[top++] = pc-1;
255 break;
256 }
257 case OP_PUSHNIL: {
258 int n;
259 for (n=0; n<GETARG_U(i); n++)
260 stack[top++] = pc-1;
261 break;
262 }
263 case OP_POP: {
264 top -= GETARG_U(i);
265 break;
266 }
267 case OP_SETTABLE:
268 case OP_SETLIST: {
269 top -= GETARG_B(i);
270 break;
271 }
272 case OP_SETMAP: {
273 top -= 2*GETARG_U(i);
274 break;
275 }
276 case OP_CONCAT: {
277 top -= GETARG_U(i);
278 stack[top++] = pc-1;
279 break;
280 }
281 case OP_JMPONT:
282 case OP_JMPONF: {
283 int newpc = pc + GETARG_S(i);
284 if (newpc >= lastpc) {
285 stack[top-1] = pc-1; /* value generated by or-and */
286 pc = newpc; /* do the jump */
287 }
288 else
289 top--; /* original code did not jump; condition was false */
290 break;
291 }
292 case OP_PUSHNILJMP: {
293 break; /* do not `push', to compensate next instruction */
294 }
295 case OP_CLOSURE: {
296 top -= GETARG_B(i);
297 stack[top++] = pc-1;
298 break;
299 }
300 default: {
301 int n;
302 LUA_ASSERT(NULL, luaK_opproperties[GET_OPCODE(i)].push != VD,
303 "invalid opcode for default");
304 top -= luaK_opproperties[GET_OPCODE(i)].pop;
305 for (n=0; n<luaK_opproperties[GET_OPCODE(i)].push; n++)
306 stack[top++] = pc-1;
307 }
308 }
309 }
310 return code[stack[stackpos]];
311}
312
313
314static const char *getname (lua_State *L, StkId obj, const char **name) {
315 StkId func = aux_stackedfunction(L, 0, obj);
316 if (func == NULL || ttype(func) != TAG_LMARK)
317 return NULL; /* not a Lua function */
318 else {
319 Proto *p = infovalue(func)->func->f.l;
320 int pc = lua_currentpc(func);
321 int stackpos = obj - (func+1); /* func+1 == function base */
322 Instruction i = luaG_symbexec(p, pc, stackpos);
323 switch (GET_OPCODE(i)) {
324 case OP_GETGLOBAL: {
325 *name = p->kstr[GETARG_U(i)]->str;
326 return "global";
327 }
328 case OP_GETLOCAL: {
329 *name = luaF_getlocalname(p, GETARG_U(i)+1, pc);
330 return (*name) ? "local" : NULL;
331 }
332 case OP_PUSHSELF:
333 case OP_GETDOTTED: {
334 *name = p->kstr[GETARG_U(i)]->str;
335 return "field";
336 }
337 default:
338 return NULL; /* no usefull name found */
339 }
340 }
341}
342
343
344/* }====================================================== */
345
228 346
229static void call_index_error (lua_State *L, TObject *o, const char *v) { 347static void call_index_error (lua_State *L, StkId o, const char *op,
230 luaL_verror(L, "attempt to %.10s a %.10s value", v, lua_type(L, o)); 348 const char *tp) {
349 const char *name;
350 const char *kind = getname(L, o, &name);
351 if (kind)
352 luaL_verror(L, "%s `%s' is not a %s", kind, name, tp);
353 else
354 luaL_verror(L, "attempt to %.10s a %.10s value", op, lua_type(L, o));
231} 355}
232 356
233 357
234void luaG_callerror (lua_State *L, TObject *func) { 358void luaG_callerror (lua_State *L, StkId func) {
235 call_index_error(L, func, "call"); 359 call_index_error(L, func, "call", "function");
236} 360}
237 361
238 362
239void luaG_indexerror (lua_State *L, TObject *t) { 363void luaG_indexerror (lua_State *L, StkId t) {
240 call_index_error(L, t, "index"); 364 call_index_error(L, t, "index", "table");
241} 365}
diff --git a/ldebug.h b/ldebug.h
index 6a9ef086..d52a00a4 100644
--- a/ldebug.h
+++ b/ldebug.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: $ 2** $Id: ldebug.h,v 1.1 2000/01/14 17:15:44 roberto Exp roberto $
3** Auxiliary functions from Debug Interface module 3** Auxiliary functions from Debug Interface module
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -8,12 +8,12 @@
8#define ldebug_h 8#define ldebug_h
9 9
10 10
11#include "lobject.h" 11#include "lstate.h"
12#include "luadebug.h" 12#include "luadebug.h"
13 13
14 14
15void luaG_callerror (lua_State *L, TObject *func); 15void luaG_callerror (lua_State *L, StkId func);
16void luaG_indexerror (lua_State *L, TObject *t); 16void luaG_indexerror (lua_State *L, StkId t);
17 17
18 18
19#endif 19#endif
diff --git a/ldo.c b/ldo.c
index 8fe2ca38..92da2991 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.79 2000/06/16 17:16:34 roberto Exp roberto $ 2** $Id: ldo.c,v 1.80 2000/06/26 19:28:31 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*/
@@ -103,7 +103,7 @@ void luaD_openstack (lua_State *L, StkId pos) {
103} 103}
104 104
105 105
106void luaD_lineHook (lua_State *L, StkId func, int line) { 106void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) {
107 if (L->allowhooks) { 107 if (L->allowhooks) {
108 lua_Debug ar; 108 lua_Debug ar;
109 struct C_Lua_Stack oldCLS = L->Cstack; 109 struct C_Lua_Stack oldCLS = L->Cstack;
@@ -113,7 +113,7 @@ void luaD_lineHook (lua_State *L, StkId func, int line) {
113 ar.event = "line"; 113 ar.event = "line";
114 ar.currentline = line; 114 ar.currentline = line;
115 L->allowhooks = 0; /* cannot call hooks inside a hook */ 115 L->allowhooks = 0; /* cannot call hooks inside a hook */
116 (*L->linehook)(L, &ar); 116 (*linehook)(L, &ar);
117 L->allowhooks = 1; 117 L->allowhooks = 1;
118 L->top = old_top; 118 L->top = old_top;
119 L->Cstack = oldCLS; 119 L->Cstack = oldCLS;
@@ -187,7 +187,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
187 case TAG_LCLOSURE: { 187 case TAG_LCLOSURE: {
188 CallInfo ci; 188 CallInfo ci;
189 ci.func = clvalue(func); 189 ci.func = clvalue(func);
190 ci.pc = 0; 190 ci.line = 0;
191 ttype(func) = TAG_LMARK; 191 ttype(func) = TAG_LMARK;
192 infovalue(func) = &ci; 192 infovalue(func) = &ci;
193 if (callhook) 193 if (callhook)
diff --git a/ldo.h b/ldo.h
index a137699e..67d3f5fc 100644
--- a/ldo.h
+++ b/ldo.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.h,v 1.19 2000/03/29 20:19:20 roberto Exp roberto $ 2** $Id: ldo.h,v 1.20 2000/04/14 18:12:35 roberto Exp $
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*/
@@ -22,7 +22,7 @@
22void luaD_init (lua_State *L, int stacksize); 22void luaD_init (lua_State *L, int stacksize);
23void luaD_adjusttop (lua_State *L, StkId base, int extra); 23void luaD_adjusttop (lua_State *L, StkId base, int extra);
24void luaD_openstack (lua_State *L, StkId pos); 24void luaD_openstack (lua_State *L, StkId pos);
25void luaD_lineHook (lua_State *L, StkId func, int line); 25void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook);
26void luaD_call (lua_State *L, StkId func, int nResults); 26void luaD_call (lua_State *L, StkId func, int nResults);
27void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults); 27void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults);
28int luaD_protectedrun (lua_State *L); 28int luaD_protectedrun (lua_State *L);
diff --git a/lobject.h b/lobject.h
index 2a61d138..01235ffa 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 1.67 2000/06/08 18:27:13 roberto Exp roberto $ 2** $Id: lobject.h,v 1.68 2000/06/26 19:28:31 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*/
@@ -122,7 +122,6 @@ typedef struct Proto {
122 int *lines; /* source line that generated each opcode */ 122 int *lines; /* source line that generated each opcode */
123 int lineDefined; 123 int lineDefined;
124 TString *source; 124 TString *source;
125 int debug; /* flag for debug information */
126 int numparams; 125 int numparams;
127 int is_vararg; 126 int is_vararg;
128 int maxstacksize; 127 int maxstacksize;
@@ -171,9 +170,10 @@ typedef struct Hash {
171** informations about a call (for debugging) 170** informations about a call (for debugging)
172*/ 171*/
173typedef struct CallInfo { 172typedef struct CallInfo {
174 int pc; /* current pc of called function */
175 int line; /* current line */
176 struct Closure *func; /* function being called */ 173 struct Closure *func; /* function being called */
174 const Instruction **pc; /* current pc of called function */
175 int lastpc; /* last pc traced */
176 int line; /* current line */
177} CallInfo; 177} CallInfo;
178 178
179 179
diff --git a/lparser.c b/lparser.c
index 315122fd..9ebd01be 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.99 2000/06/26 19:28:31 roberto Exp roberto $ 2** $Id: lparser.c,v 1.100 2000/06/28 17:06:07 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*/
@@ -154,7 +154,7 @@ static int checkname (LexState *ls) {
154 154
155static void luaI_registerlocalvar (LexState *ls, TString *varname, int pc) { 155static void luaI_registerlocalvar (LexState *ls, TString *varname, int pc) {
156 FuncState *fs = ls->fs; 156 FuncState *fs = ls->fs;
157 if (fs->f->debug) { 157 if (fs->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;
@@ -359,7 +359,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z) {
359 luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z))); 359 luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z)));
360 open_func(&lexstate, &funcstate); 360 open_func(&lexstate, &funcstate);
361 next(&lexstate); /* read first token */ 361 next(&lexstate); /* read first token */
362 funcstate.f->debug = L->debug; /* previous `next' may scan a pragma */ 362 funcstate.debug = L->debug; /* previous `next' may scan a pragma */
363 chunk(&lexstate); 363 chunk(&lexstate);
364 check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected"); 364 check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");
365 close_func(&lexstate); 365 close_func(&lexstate);
@@ -1085,7 +1085,7 @@ static void body (LexState *ls, int needself, int line) {
1085 FuncState new_fs; 1085 FuncState new_fs;
1086 open_func(ls, &new_fs); 1086 open_func(ls, &new_fs);
1087 new_fs.f->lineDefined = line; 1087 new_fs.f->lineDefined = line;
1088 new_fs.f->debug = ls->L->debug; 1088 new_fs.debug = ls->L->debug;
1089 check(ls, '('); 1089 check(ls, '(');
1090 if (needself) { 1090 if (needself) {
1091 new_localvarstr(ls, "self", 0); 1091 new_localvarstr(ls, "self", 0);
diff --git a/lparser.h b/lparser.h
index 2432c08e..12f936ae 100644
--- a/lparser.h
+++ b/lparser.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.h,v 1.18 2000/06/21 18:13:56 roberto Exp roberto $ 2** $Id: lparser.h,v 1.19 2000/06/26 19:28:31 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*/
@@ -47,6 +47,7 @@ typedef struct FuncState {
47 int stacklevel; /* number of values on activation register */ 47 int stacklevel; /* number of values on activation register */
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 debug; /* flag for debug information */
50 int nvars; /* number of entries in f->locvars */ 51 int nvars; /* number of entries in f->locvars */
51 struct Breaklabel *bl; /* chain of breakable blocks */ 52 struct Breaklabel *bl; /* chain of breakable blocks */
52 expdesc upvalues[MAXUPVALUES]; /* upvalues */ 53 expdesc upvalues[MAXUPVALUES]; /* upvalues */
diff --git a/lvm.c b/lvm.c
index 254b6c35..2fccacc6 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.117 2000/06/26 19:28:31 roberto Exp roberto $ 2** $Id: lvm.c,v 1.118 2000/06/27 19:00:36 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,20 +67,19 @@ 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, StkId top) { 70static void traceexec (lua_State *L, StkId base, StkId top, lua_Hook linehook) {
71 CallInfo *ci = infovalue(base-1); 71 CallInfo *ci = infovalue(base-1);
72 int oldpc = ci->pc; 72 int *lines = ci->func->f.l->lines;
73 ci->pc = pc; 73 int pc = (*ci->pc - 1) - ci->func->f.l->code;
74 if (L->linehook && ci->func->f.l->debug) { 74 if (lines) {
75 int *lines = ci->func->f.l->lines; 75 /* calls linehook when enters a new line or jumps back (loop) */
76 LUA_ASSERT(L, lines, "must have debug information"); 76 if (lines[pc] != ci->line || pc <= ci->lastpc) {
77 /* calls linehook when jumps back (loop) or enters a new line */
78 if (pc <= oldpc || lines[pc] != ci->line) {
79 ci->line = lines[pc]; 77 ci->line = lines[pc];
80 L->top = top; 78 L->top = top;
81 luaD_lineHook(L, base-2, lines[pc]); 79 luaD_lineHook(L, base-2, lines[pc], linehook);
82 } 80 }
83 } 81 }
82 ci->lastpc = pc;
84} 83}
85 84
86 85
@@ -113,7 +112,7 @@ void luaV_Lclosure (lua_State *L, Proto *l, int nelems) {
113** Receives the table at top-2 and the index at top-1. 112** Receives the table at top-2 and the index at top-1.
114*/ 113*/
115void luaV_gettable (lua_State *L, StkId top) { 114void luaV_gettable (lua_State *L, StkId top) {
116 TObject *table = top-2; 115 StkId table = top-2;
117 const TObject *im; 116 const TObject *im;
118 if (ttype(table) != TAG_TABLE) { /* not a table, get gettable TM */ 117 if (ttype(table) != TAG_TABLE) { /* not a table, get gettable TM */
119 im = luaT_getimbyObj(L, table, IM_GETTABLE); 118 im = luaT_getimbyObj(L, table, IM_GETTABLE);
@@ -348,7 +347,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
348 StkId top; /* keep top local, for performance */ 347 StkId top; /* keep top local, for performance */
349 const Instruction *pc = tf->code; 348 const Instruction *pc = tf->code;
350 TString **kstr = tf->kstr; 349 TString **kstr = tf->kstr;
351 int debug = tf->debug; 350 lua_Hook linehook = L->linehook;
351 infovalue(base-1)->pc = &pc;
352 luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK); 352 luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK);
353 if (tf->is_vararg) { /* varargs? */ 353 if (tf->is_vararg) { /* varargs? */
354 adjust_varargs(L, base, tf->numparams); 354 adjust_varargs(L, base, tf->numparams);
@@ -359,9 +359,9 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
359 top = L->top; 359 top = L->top;
360 /* main loop of interpreter */ 360 /* main loop of interpreter */
361 for (;;) { 361 for (;;) {
362 if (debug) 362 const Instruction i = *pc++;
363 traceexec(L, base, pc - tf->code, top); 363 if (linehook)
364 {const Instruction i = *pc++; 364 traceexec(L, base, top, linehook);
365 switch (GET_OPCODE(i)) { 365 switch (GET_OPCODE(i)) {
366 366
367 case OP_END: 367 case OP_END:
@@ -705,5 +705,5 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
705 break; 705 break;
706 706
707 } 707 }
708 }} 708 }
709} 709}