diff options
| -rw-r--r-- | lcode.c | 52 | ||||
| -rw-r--r-- | ldebug.c | 92 | ||||
| -rw-r--r-- | ldebug.h | 10 | ||||
| -rw-r--r-- | ldump.c | 8 | ||||
| -rw-r--r-- | lfunc.c | 5 | ||||
| -rw-r--r-- | lobject.h | 25 | ||||
| -rw-r--r-- | lparser.c | 13 | ||||
| -rw-r--r-- | lparser.h | 5 | ||||
| -rw-r--r-- | ltests.c | 4 | ||||
| -rw-r--r-- | ltests.h | 3 | ||||
| -rw-r--r-- | lundump.c | 11 |
11 files changed, 195 insertions, 33 deletions
| @@ -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 | */ | ||
| 300 | static 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 | */ |
| 1265 | void luaK_fixline (FuncState *fs, int line) { | 1294 | void 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 | ||
| @@ -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 | */ | ||
| 58 | static 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 | */ | ||
| 89 | int 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 | |||
| 51 | static int currentline (CallInfo *ci) { | 104 | static 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 | ||
| 267 | static 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 | |||
| 214 | static void collectvalidlines (lua_State *L, Closure *f) { | 275 | static 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 | */ | ||
| 752 | static 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 | |||
| 684 | void luaG_traceexec (lua_State *L) { | 761 | void 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? */ |
| @@ -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 | ||
| 24 | LUAI_FUNC int luaG_getfuncline (Proto *f, int pc); | ||
| 21 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, | 25 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, |
| 22 | const char *opname); | 26 | const char *opname); |
| 23 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, | 27 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, |
| @@ -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++) { |
| @@ -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); |
| @@ -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 | */ | ||
| 430 | typedef struct AbsLineInfo { | ||
| 431 | int pc; | ||
| 432 | int line; | ||
| 433 | } AbsLineInfo; | ||
| 434 | |||
| 435 | /* | ||
| 421 | ** Function Prototypes | 436 | ** Function Prototypes |
| 422 | */ | 437 | */ |
| 423 | typedef struct Proto { | 438 | typedef 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; |
| @@ -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 | ||
| 529 | static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { | 529 | static 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 *); |
| @@ -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 | ||
| @@ -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: |
| @@ -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 */ |
| @@ -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) { | |||
| 180 | static void LoadDebug (LoadState *S, Proto *f) { | 180 | static 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++) |
