summaryrefslogtreecommitdiff
path: root/ldebug.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-06-27 08:35:31 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-06-27 08:35:31 -0300
commitb42430fd3a6200eaaf4020be90c4d47f7e251b67 (patch)
treec47c23ac9d461b79554986769375019dc6dc469c /ldebug.c
parent60a7492d249860d20098ac2f0b9d863606c38450 (diff)
downloadlua-b42430fd3a6200eaaf4020be90c4d47f7e251b67.tar.gz
lua-b42430fd3a6200eaaf4020be90c4d47f7e251b67.tar.bz2
lua-b42430fd3a6200eaaf4020be90c4d47f7e251b67.zip
'lineinfo' in prototypes saved as differences instead of absolute
values, so that the array can use bytes instead of ints, reducing its size. (A new array 'abslineinfo' is used when line differences do not fit in a byte.)
Diffstat (limited to 'ldebug.c')
-rw-r--r--ldebug.c92
1 files changed, 85 insertions, 7 deletions
diff --git a/ldebug.c b/ldebug.c
index 4193cda8..6971e475 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 2.125 2017/05/13 13:04:33 roberto Exp roberto $ 2** $Id: ldebug.c,v 2.126 2017/05/13 13:54:47 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*/
@@ -48,8 +48,61 @@ static int currentpc (CallInfo *ci) {
48} 48}
49 49
50 50
51/*
52** Get a "base line" to find the line corresponding to an instruction.
53** For that, search the array of absolute line info for the largest saved
54** instruction smaller or equal to the wanted instrution. A special
55** case is when there is no absolute info or the instruction is before
56** the first absolute one.
57*/
58static int getbaseline (Proto *f, int pc, int *basepc) {
59 if (f->sizeabslineinfo == 0 || pc < f->abslineinfo[0].pc) {
60 *basepc = -1; /* start from the beginning */
61 return f->linedefined;
62 }
63 else {
64 unsigned int i;
65 if (pc >= f->abslineinfo[f->sizeabslineinfo - 1].pc)
66 i = f->sizeabslineinfo - 1; /* instruction is after last saved one */
67 else { /* binary search */
68 unsigned int j = f->sizeabslineinfo - 1; /* pc < anchorlines[j] */
69 i = 0; /* abslineinfo[i] <= pc */
70 while (i < j - 1) {
71 unsigned int m = (j + i) / 2;
72 if (pc >= f->abslineinfo[m].pc)
73 i = m;
74 else
75 j = m;
76 }
77 }
78 *basepc = f->abslineinfo[i].pc;
79 return f->abslineinfo[i].line;
80 }
81}
82
83
84/*
85** Get the line corresponding to instruction 'pc' in function 'f';
86** first gets a base line and from there does the increments until
87** the desired instruction.
88*/
89int luaG_getfuncline (Proto *f, int pc) {
90 if (f->lineinfo == NULL) /* no debug information? */
91 return -1;
92 else {
93 int basepc;
94 int baseline = getbaseline(f, pc, &basepc);
95 while (basepc++ < pc) { /* walk until given instruction */
96 lua_assert(f->lineinfo[basepc] != ABSLINEINFO);
97 baseline += f->lineinfo[basepc]; /* correct line */
98 }
99 return baseline;
100 }
101}
102
103
51static int currentline (CallInfo *ci) { 104static int currentline (CallInfo *ci) {
52 return getfuncline(ci_func(ci)->p, currentpc(ci)); 105 return luaG_getfuncline(ci_func(ci)->p, currentpc(ci));
53} 106}
54 107
55 108
@@ -211,6 +264,14 @@ static void funcinfo (lua_Debug *ar, Closure *cl) {
211} 264}
212 265
213 266
267static int nextline (Proto *p, int currentline, int pc) {
268 if (p->lineinfo[pc] != ABSLINEINFO)
269 return currentline + p->lineinfo[pc];
270 else
271 return luaG_getfuncline(p, pc);
272}
273
274
214static void collectvalidlines (lua_State *L, Closure *f) { 275static void collectvalidlines (lua_State *L, Closure *f) {
215 if (noLuaClosure(f)) { 276 if (noLuaClosure(f)) {
216 setnilvalue(L->top); 277 setnilvalue(L->top);
@@ -219,13 +280,16 @@ static void collectvalidlines (lua_State *L, Closure *f) {
219 else { 280 else {
220 int i; 281 int i;
221 TValue v; 282 TValue v;
222 int *lineinfo = f->l.p->lineinfo; 283 Proto *p = f->l.p;
284 int currentline = p->linedefined;
223 Table *t = luaH_new(L); /* new table to store active lines */ 285 Table *t = luaH_new(L); /* new table to store active lines */
224 sethvalue(L, L->top, t); /* push it on stack */ 286 sethvalue(L, L->top, t); /* push it on stack */
225 api_incr_top(L); 287 api_incr_top(L);
226 setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */ 288 setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */
227 for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */ 289 for (i = 0; i < p->sizelineinfo; i++) { /* for all lines with code */
228 luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */ 290 currentline = nextline(p, currentline, i);
291 luaH_setint(L, t, currentline, &v); /* table[line] = true */
292 }
229 } 293 }
230} 294}
231 295
@@ -681,6 +745,19 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
681} 745}
682 746
683 747
748/*
749** Check whether new instruction 'newpc' is in a different line from
750** previous instruction 'oldpc'.
751*/
752static int changedline (Proto *p, int oldpc, int newpc) {
753 while (oldpc++ < newpc) {
754 if (p->lineinfo[oldpc] != 0)
755 return (luaG_getfuncline(p, oldpc - 1) != luaG_getfuncline(p, newpc));
756 }
757 return 0; /* no line changes in the way */
758}
759
760
684void luaG_traceexec (lua_State *L) { 761void luaG_traceexec (lua_State *L) {
685 CallInfo *ci = L->ci; 762 CallInfo *ci = L->ci;
686 lu_byte mask = L->hookmask; 763 lu_byte mask = L->hookmask;
@@ -698,11 +775,12 @@ void luaG_traceexec (lua_State *L) {
698 if (mask & LUA_MASKLINE) { 775 if (mask & LUA_MASKLINE) {
699 Proto *p = ci_func(ci)->p; 776 Proto *p = ci_func(ci)->p;
700 int npc = pcRel(ci->u.l.savedpc, p); 777 int npc = pcRel(ci->u.l.savedpc, p);
701 int newline = getfuncline(p, npc);
702 if (npc == 0 || /* call linehook when enter a new function, */ 778 if (npc == 0 || /* call linehook when enter a new function, */
703 ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ 779 ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */
704 newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ 780 changedline(p, pcRel(L->oldpc, p), npc)) { /* enter new line */
781 int newline = luaG_getfuncline(p, npc); /* new line */
705 luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ 782 luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */
783 }
706 } 784 }
707 L->oldpc = ci->u.l.savedpc; 785 L->oldpc = ci->u.l.savedpc;
708 if (L->status == LUA_YIELD) { /* did hook yield? */ 786 if (L->status == LUA_YIELD) { /* did hook yield? */