aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c52
-rw-r--r--ldebug.c92
-rw-r--r--ldebug.h10
-rw-r--r--ldump.c8
-rw-r--r--lfunc.c5
-rw-r--r--lobject.h25
-rw-r--r--lparser.c13
-rw-r--r--lparser.h5
-rw-r--r--ltests.c4
-rw-r--r--ltests.h3
-rw-r--r--lundump.c11
11 files changed, 195 insertions, 33 deletions
diff --git a/lcode.c b/lcode.c
index 2d396000..740cf564 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.118 2017/04/28 20:57:45 roberto Exp roberto $ 2** $Id: lcode.c,v 2.119 2017/05/18 19:44:19 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*/
@@ -10,6 +10,7 @@
10#include "lprefix.h" 10#include "lprefix.h"
11 11
12 12
13#include <limits.h>
13#include <math.h> 14#include <math.h>
14#include <stdlib.h> 15#include <stdlib.h>
15 16
@@ -285,6 +286,33 @@ void luaK_patchclose (FuncState *fs, int list, int level) {
285 } 286 }
286} 287}
287 288
289#if !defined(MAXIWTHABS)
290#define MAXIWTHABS 120
291#endif
292
293/*
294** Save line info for a new instruction. If difference from last line
295** does not fit in a byte, of after that many instructions, save a new
296** absolute line info; (in that case, the special value 'ABSLINEINFO'
297** in 'lineinfo' signals the existence of this absolute information.)
298** Otherwise, store the difference from last line in 'lineinfo'.
299*/
300static void savelineinfo (FuncState *fs, Proto *f, int pc, int line) {
301 int linedif = line - fs->previousline;
302 if (abs(linedif) >= 0x80 || fs->iwthabs++ > MAXIWTHABS) {
303 luaM_growvector(fs->ls->L, f->abslineinfo, fs->nabslineinfo,
304 f->sizeabslineinfo, AbsLineInfo, MAX_INT, "lines");
305 f->abslineinfo[fs->nabslineinfo].pc = pc;
306 f->abslineinfo[fs->nabslineinfo++].line = line;
307 linedif = ABSLINEINFO; /* signal there is absolute information */
308 fs->iwthabs = 0; /* restart counter */
309 }
310 luaM_growvector(fs->ls->L, f->lineinfo, pc, f->sizelineinfo, ls_byte,
311 MAX_INT, "opcodes");
312 f->lineinfo[pc] = linedif;
313 fs->previousline = line; /* last line saved */
314}
315
288 316
289/* 317/*
290** Emit instruction 'i', checking for array sizes and saving also its 318** Emit instruction 'i', checking for array sizes and saving also its
@@ -297,10 +325,7 @@ static int luaK_code (FuncState *fs, Instruction i) {
297 luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, 325 luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
298 MAX_INT, "opcodes"); 326 MAX_INT, "opcodes");
299 f->code[fs->pc] = i; 327 f->code[fs->pc] = i;
300 /* save corresponding line information */ 328 savelineinfo(fs, f, fs->pc, fs->ls->lastline);
301 luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
302 MAX_INT, "opcodes");
303 f->lineinfo[fs->pc] = fs->ls->lastline;
304 return fs->pc++; 329 return fs->pc++;
305} 330}
306 331
@@ -1260,10 +1285,23 @@ void luaK_posfix (FuncState *fs, BinOpr op,
1260 1285
1261 1286
1262/* 1287/*
1263** Change line information associated with current position. 1288** Change line information associated with current position. If that
1289** information is absolute, just change it and correct 'previousline'.
1290** Otherwise, restore 'previousline' to its value before saving the
1291** current position and than saves the line information again, with the
1292** new line.
1264*/ 1293*/
1265void luaK_fixline (FuncState *fs, int line) { 1294void luaK_fixline (FuncState *fs, int line) {
1266 fs->f->lineinfo[fs->pc - 1] = line; 1295 Proto *f = fs->f;
1296 if (f->lineinfo[fs->pc - 1] == ABSLINEINFO) {
1297 lua_assert(f->abslineinfo[fs->nabslineinfo - 1].pc == fs->pc - 1);
1298 f->abslineinfo[fs->nabslineinfo - 1].line = line;
1299 fs->previousline = line;
1300 }
1301 else {
1302 fs->previousline -= f->lineinfo[fs->pc - 1]; /* undo previous info. */
1303 savelineinfo(fs, f, fs->pc - 1, line); /* redo it */
1304 }
1267} 1305}
1268 1306
1269 1307
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? */
diff --git a/ldebug.h b/ldebug.h
index 9c0a03a6..9062f4bd 100644
--- a/ldebug.h
+++ b/ldebug.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.h,v 2.13 2015/03/11 16:10:41 roberto Exp roberto $ 2** $Id: ldebug.h,v 2.14 2015/05/22 17:45:56 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*/
@@ -13,11 +13,15 @@
13 13
14#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) 14#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
15 15
16#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1)
17
18#define resethookcount(L) (L->hookcount = L->basehookcount) 16#define resethookcount(L) (L->hookcount = L->basehookcount)
19 17
18/*
19** mark for entries in 'lineinfo' array that has absolute information in
20** 'abslineinfo' array
21*/
22#define ABSLINEINFO (-0x80)
20 23
24LUAI_FUNC int luaG_getfuncline (Proto *f, int pc);
21LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, 25LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
22 const char *opname); 26 const char *opname);
23LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, 27LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1,
diff --git a/ldump.c b/ldump.c
index 19030edc..a22d6197 100644
--- a/ldump.c
+++ b/ldump.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldump.c,v 2.36 2015/03/30 15:43:51 roberto Exp roberto $ 2** $Id: ldump.c,v 2.37 2015/10/08 15:53:49 roberto Exp roberto $
3** save precompiled Lua chunks 3** save precompiled Lua chunks
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -149,6 +149,12 @@ static void DumpDebug (const Proto *f, DumpState *D) {
149 n = (D->strip) ? 0 : f->sizelineinfo; 149 n = (D->strip) ? 0 : f->sizelineinfo;
150 DumpInt(n, D); 150 DumpInt(n, D);
151 DumpVector(f->lineinfo, n, D); 151 DumpVector(f->lineinfo, n, D);
152 n = (D->strip) ? 0 : f->sizeabslineinfo;
153 DumpInt(n, D);
154 for (i = 0; i < n; i++) {
155 DumpInt(f->abslineinfo[i].pc, D);
156 DumpInt(f->abslineinfo[i].line, D);
157 }
152 n = (D->strip) ? 0 : f->sizelocvars; 158 n = (D->strip) ? 0 : f->sizelocvars;
153 DumpInt(n, D); 159 DumpInt(n, D);
154 for (i = 0; i < n; i++) { 160 for (i = 0; i < n; i++) {
diff --git a/lfunc.c b/lfunc.c
index e84538c9..a4a4e29d 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lfunc.c,v 2.48 2017/04/30 20:43:26 roberto Exp roberto $ 2** $Id: lfunc.c,v 2.49 2017/05/24 18:54:54 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*/
@@ -119,6 +119,8 @@ Proto *luaF_newproto (lua_State *L) {
119 f->sizecode = 0; 119 f->sizecode = 0;
120 f->lineinfo = NULL; 120 f->lineinfo = NULL;
121 f->sizelineinfo = 0; 121 f->sizelineinfo = 0;
122 f->abslineinfo = NULL;
123 f->sizeabslineinfo = 0;
122 f->upvalues = NULL; 124 f->upvalues = NULL;
123 f->sizeupvalues = 0; 125 f->sizeupvalues = 0;
124 f->numparams = 0; 126 f->numparams = 0;
@@ -138,6 +140,7 @@ void luaF_freeproto (lua_State *L, Proto *f) {
138 luaM_freearray(L, f->p, f->sizep); 140 luaM_freearray(L, f->p, f->sizep);
139 luaM_freearray(L, f->k, f->sizek); 141 luaM_freearray(L, f->k, f->sizek);
140 luaM_freearray(L, f->lineinfo, f->sizelineinfo); 142 luaM_freearray(L, f->lineinfo, f->sizelineinfo);
143 luaM_freearray(L, f->abslineinfo, f->sizeabslineinfo);
141 luaM_freearray(L, f->locvars, f->sizelocvars); 144 luaM_freearray(L, f->locvars, f->sizelocvars);
142 luaM_freearray(L, f->upvalues, f->sizeupvalues); 145 luaM_freearray(L, f->upvalues, f->sizeupvalues);
143 luaM_free(L, f); 146 luaM_free(L, f);
diff --git a/lobject.h b/lobject.h
index e245f306..9af501af 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 2.122 2017/06/09 16:48:44 roberto Exp roberto $ 2** $Id: lobject.h,v 2.123 2017/06/12 14:21:44 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*/
@@ -418,6 +418,21 @@ typedef struct LocVar {
418 418
419 419
420/* 420/*
421** Associates the absolute line source for a given instruction ('pc').
422** The array 'lineinfo' gives, for each instruction, the difference in
423** lines from the previous instruction. When that difference does not
424** fit into a byte, Lua saves the absolute line for that instruction.
425** (Lua also saves the absolute line periodically, to speed up the
426** computation of a line number: we can use binary search in the
427** absolute-line array, but we must traverse the 'lineinfo' array
428** linearly to compute a line.)
429*/
430typedef struct AbsLineInfo {
431 int pc;
432 int line;
433} AbsLineInfo;
434
435/*
421** Function Prototypes 436** Function Prototypes
422*/ 437*/
423typedef struct Proto { 438typedef struct Proto {
@@ -432,15 +447,17 @@ typedef struct Proto {
432 int sizelineinfo; 447 int sizelineinfo;
433 int sizep; /* size of 'p' */ 448 int sizep; /* size of 'p' */
434 int sizelocvars; 449 int sizelocvars;
450 int sizeabslineinfo; /* size of 'abslineinfo' */
435 int linedefined; /* debug information */ 451 int linedefined; /* debug information */
436 int lastlinedefined; /* debug information */ 452 int lastlinedefined; /* debug information */
437 TValue *k; /* constants used by the function */ 453 TValue *k; /* constants used by the function */
454 struct LClosure *cache; /* last-created closure with this prototype */
438 Instruction *code; /* opcodes */ 455 Instruction *code; /* opcodes */
439 struct Proto **p; /* functions defined inside the function */ 456 struct Proto **p; /* functions defined inside the function */
440 int *lineinfo; /* map from opcodes to source lines (debug information) */
441 LocVar *locvars; /* information about local variables (debug information) */
442 Upvaldesc *upvalues; /* upvalue information */ 457 Upvaldesc *upvalues; /* upvalue information */
443 struct LClosure *cache; /* last-created closure with this prototype */ 458 ls_byte *lineinfo; /* information about source lines (debug information) */
459 AbsLineInfo *abslineinfo; /* idem */
460 LocVar *locvars; /* information about local variables (debug information) */
444 TString *source; /* used for debug information */ 461 TString *source; /* used for debug information */
445 GCObject *gclist; 462 GCObject *gclist;
446} Proto; 463} Proto;
diff --git a/lparser.c b/lparser.c
index 37f84cce..5e244e24 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.158 2017/04/29 18:09:17 roberto Exp roberto $ 2** $Id: lparser.c,v 2.159 2017/05/13 12:57:20 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*/
@@ -527,22 +527,24 @@ static void codeclosure (LexState *ls, expdesc *v) {
527 527
528 528
529static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { 529static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
530 Proto *f; 530 Proto *f = fs->f;
531 fs->prev = ls->fs; /* linked list of funcstates */ 531 fs->prev = ls->fs; /* linked list of funcstates */
532 fs->ls = ls; 532 fs->ls = ls;
533 ls->fs = fs; 533 ls->fs = fs;
534 fs->pc = 0; 534 fs->pc = 0;
535 fs->previousline = f->linedefined;
536 fs->iwthabs = 0;
535 fs->lasttarget = 0; 537 fs->lasttarget = 0;
536 fs->jpc = NO_JUMP; 538 fs->jpc = NO_JUMP;
537 fs->freereg = 0; 539 fs->freereg = 0;
538 fs->nk = 0; 540 fs->nk = 0;
541 fs->nabslineinfo = 0;
539 fs->np = 0; 542 fs->np = 0;
540 fs->nups = 0; 543 fs->nups = 0;
541 fs->nlocvars = 0; 544 fs->nlocvars = 0;
542 fs->nactvar = 0; 545 fs->nactvar = 0;
543 fs->firstlocal = ls->dyd->actvar.n; 546 fs->firstlocal = ls->dyd->actvar.n;
544 fs->bl = NULL; 547 fs->bl = NULL;
545 f = fs->f;
546 f->source = ls->source; 548 f->source = ls->source;
547 f->maxstacksize = 2; /* registers 0/1 are always valid */ 549 f->maxstacksize = 2; /* registers 0/1 are always valid */
548 enterblock(fs, bl, 0); 550 enterblock(fs, bl, 0);
@@ -557,8 +559,11 @@ static void close_func (LexState *ls) {
557 leaveblock(fs); 559 leaveblock(fs);
558 luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); 560 luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
559 f->sizecode = fs->pc; 561 f->sizecode = fs->pc;
560 luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); 562 luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte);
561 f->sizelineinfo = fs->pc; 563 f->sizelineinfo = fs->pc;
564 luaM_reallocvector(L, f->abslineinfo, f->sizeabslineinfo,
565 fs->nabslineinfo, AbsLineInfo);
566 f->sizeabslineinfo = fs->nabslineinfo;
562 luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); 567 luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
563 f->sizek = fs->nk; 568 f->sizek = fs->nk;
564 luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); 569 luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
diff --git a/lparser.h b/lparser.h
index 16124181..3ab6065d 100644
--- a/lparser.h
+++ b/lparser.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.h,v 1.76 2015/12/30 18:16:13 roberto Exp roberto $ 2** $Id: lparser.h,v 1.77 2017/04/28 20:57:45 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*/
@@ -123,14 +123,17 @@ typedef struct FuncState {
123 struct BlockCnt *bl; /* chain of current blocks */ 123 struct BlockCnt *bl; /* chain of current blocks */
124 int pc; /* next position to code (equivalent to 'ncode') */ 124 int pc; /* next position to code (equivalent to 'ncode') */
125 int lasttarget; /* 'label' of last 'jump label' */ 125 int lasttarget; /* 'label' of last 'jump label' */
126 int previousline; /* last line that was saved in 'lineinfo' */
126 int jpc; /* list of pending jumps to 'pc' */ 127 int jpc; /* list of pending jumps to 'pc' */
127 int nk; /* number of elements in 'k' */ 128 int nk; /* number of elements in 'k' */
128 int np; /* number of elements in 'p' */ 129 int np; /* number of elements in 'p' */
130 int nabslineinfo; /* number of elements in 'abslineinfo' */
129 int firstlocal; /* index of first local var (in Dyndata array) */ 131 int firstlocal; /* index of first local var (in Dyndata array) */
130 short nlocvars; /* number of elements in 'f->locvars' */ 132 short nlocvars; /* number of elements in 'f->locvars' */
131 lu_byte nactvar; /* number of active local variables */ 133 lu_byte nactvar; /* number of active local variables */
132 lu_byte nups; /* number of upvalues */ 134 lu_byte nups; /* number of upvalues */
133 lu_byte freereg; /* first free register */ 135 lu_byte freereg; /* first free register */
136 lu_byte iwthabs; /* instructions issued since last absolute line info */
134} FuncState; 137} FuncState;
135 138
136 139
diff --git a/ltests.c b/ltests.c
index 733e47d4..8b2c0ee1 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.219 2017/06/09 16:48:44 roberto Exp roberto $ 2** $Id: ltests.c,v 2.220 2017/06/12 14:21:44 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*/
@@ -537,7 +537,7 @@ static char *buildop (Proto *p, int pc, char *buff) {
537 Instruction i = p->code[pc]; 537 Instruction i = p->code[pc];
538 OpCode o = GET_OPCODE(i); 538 OpCode o = GET_OPCODE(i);
539 const char *name = luaP_opnames[o]; 539 const char *name = luaP_opnames[o];
540 int line = getfuncline(p, pc); 540 int line = luaG_getfuncline(p, pc);
541 sprintf(buff, "(%4d) %4d - ", line, pc); 541 sprintf(buff, "(%4d) %4d - ", line, pc);
542 switch (getOpMode(o)) { 542 switch (getOpMode(o)) {
543 case iABC: 543 case iABC:
diff --git a/ltests.h b/ltests.h
index 9d26fcb0..82ccc97c 100644
--- a/ltests.h
+++ b/ltests.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.h,v 2.49 2015/09/22 14:18:24 roberto Exp roberto $ 2** $Id: ltests.h,v 2.50 2016/07/19 17:13:00 roberto Exp roberto $
3** Internal Header for Debugging of the Lua Implementation 3** Internal Header for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -111,6 +111,7 @@ LUA_API void *debug_realloc (void *ud, void *block,
111#define LUAL_BUFFERSIZE 23 111#define LUAL_BUFFERSIZE 23
112#define MINSTRTABSIZE 2 112#define MINSTRTABSIZE 2
113#define MAXINDEXRK 1 113#define MAXINDEXRK 1
114#define MAXIWTHABS 3
114 115
115 116
116/* make stack-overflow tests run faster */ 117/* make stack-overflow tests run faster */
diff --git a/lundump.c b/lundump.c
index 13916bc1..7fb05762 100644
--- a/lundump.c
+++ b/lundump.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lundump.c,v 2.43 2015/09/17 15:51:05 roberto Exp roberto $ 2** $Id: lundump.c,v 2.44 2015/11/02 16:09:30 roberto Exp roberto $
3** load precompiled Lua chunks 3** load precompiled Lua chunks
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -180,10 +180,17 @@ static void LoadUpvalues (LoadState *S, Proto *f) {
180static void LoadDebug (LoadState *S, Proto *f) { 180static void LoadDebug (LoadState *S, Proto *f) {
181 int i, n; 181 int i, n;
182 n = LoadInt(S); 182 n = LoadInt(S);
183 f->lineinfo = luaM_newvector(S->L, n, int); 183 f->lineinfo = luaM_newvector(S->L, n, ls_byte);
184 f->sizelineinfo = n; 184 f->sizelineinfo = n;
185 LoadVector(S, f->lineinfo, n); 185 LoadVector(S, f->lineinfo, n);
186 n = LoadInt(S); 186 n = LoadInt(S);
187 f->abslineinfo = luaM_newvector(S->L, n, AbsLineInfo);
188 f->sizeabslineinfo = n;
189 for (i = 0; i < n; i++) {
190 f->abslineinfo[i].pc = LoadInt(S);
191 f->abslineinfo[i].line = LoadInt(S);
192 }
193 n = LoadInt(S);
187 f->locvars = luaM_newvector(S->L, n, LocVar); 194 f->locvars = luaM_newvector(S->L, n, LocVar);
188 f->sizelocvars = n; 195 f->sizelocvars = n;
189 for (i = 0; i < n; i++) 196 for (i = 0; i < n; i++)