diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-08-08 15:26:05 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-08-08 15:26:05 -0300 |
| commit | f90bc248b3c3c18941a96038b2a7517ad571d8b1 (patch) | |
| tree | 696583e7b4f462d01b07b8510faecd47b9baaf62 | |
| parent | d9e61e8ceafe8c3f6ad936979719ca7c446ce228 (diff) | |
| download | lua-f90bc248b3c3c18941a96038b2a7517ad571d8b1.tar.gz lua-f90bc248b3c3c18941a96038b2a7517ad571d8b1.tar.bz2 lua-f90bc248b3c3c18941a96038b2a7517ad571d8b1.zip | |
new structure for line information
| -rw-r--r-- | lcode.c | 23 | ||||
| -rw-r--r-- | ldebug.c | 37 | ||||
| -rw-r--r-- | ldebug.h | 3 | ||||
| -rw-r--r-- | lfunc.c | 6 | ||||
| -rw-r--r-- | lobject.h | 5 | ||||
| -rw-r--r-- | lparser.c | 8 | ||||
| -rw-r--r-- | lparser.h | 4 | ||||
| -rw-r--r-- | ltests.c | 9 | ||||
| -rw-r--r-- | lvm.c | 18 |
9 files changed, 84 insertions, 29 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 1.41 2000/06/30 14:35:17 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.42 2000/08/04 19:38:35 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 | */ |
| @@ -413,6 +413,19 @@ void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2) { | |||
| 413 | } | 413 | } |
| 414 | 414 | ||
| 415 | 415 | ||
| 416 | static void codelineinfo (FuncState *fs) { | ||
| 417 | LexState *ls = fs->ls; | ||
| 418 | if (ls->lastline > fs->lastline) { | ||
| 419 | luaM_growvector(fs->L, fs->f->lineinfo, fs->nlineinfo, 2, int, | ||
| 420 | "line info overflow", MAX_INT); | ||
| 421 | if (ls->lastline > fs->lastline+1) | ||
| 422 | fs->f->lineinfo[fs->nlineinfo++] = -(ls->lastline - (fs->lastline+1)); | ||
| 423 | fs->f->lineinfo[fs->nlineinfo++] = fs->pc; | ||
| 424 | fs->lastline = ls->lastline; | ||
| 425 | } | ||
| 426 | } | ||
| 427 | |||
| 428 | |||
| 416 | int luaK_code0 (FuncState *fs, OpCode o) { | 429 | int luaK_code0 (FuncState *fs, OpCode o) { |
| 417 | return luaK_code2(fs, o, 0, 0); | 430 | return luaK_code2(fs, o, 0, 0); |
| 418 | } | 431 | } |
| @@ -618,12 +631,8 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
| 618 | case iS: i = CREATE_S(o, arg1); break; | 631 | case iS: i = CREATE_S(o, arg1); break; |
| 619 | case iAB: i = CREATE_AB(o, arg1, arg2); break; | 632 | case iAB: i = CREATE_AB(o, arg1, arg2); break; |
| 620 | } | 633 | } |
| 621 | if (fs->debug) { | 634 | if (fs->debug) |
| 622 | LexState *ls = fs->ls; | 635 | codelineinfo(fs); |
| 623 | luaM_growvector(fs->L, fs->f->lines, fs->pc, 1, int, | ||
| 624 | "code size overflow", MAX_INT); | ||
| 625 | fs->f->lines[fs->pc] = ls->lastline; | ||
| 626 | } | ||
| 627 | /* put new instruction in code array */ | 636 | /* put new instruction in code array */ |
| 628 | luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, | 637 | luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, |
| 629 | "code size overflow", MAX_INT); | 638 | "code size overflow", MAX_INT); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 1.27 2000/06/30 14:35:17 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 1.28 2000/08/07 20:21:34 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 | */ |
| @@ -99,6 +99,34 @@ static int lua_nups (StkId f) { | |||
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | 101 | ||
| 102 | int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) { | ||
| 103 | int refi = prefi ? *prefi : 0; | ||
| 104 | if (lineinfo[refi] < 0) | ||
| 105 | refline += -lineinfo[refi++]; | ||
| 106 | LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info"); | ||
| 107 | while (lineinfo[refi] > pc) { | ||
| 108 | refline--; | ||
| 109 | refi--; | ||
| 110 | if (lineinfo[refi] < 0) | ||
| 111 | refline -= -lineinfo[refi--]; | ||
| 112 | LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info"); | ||
| 113 | } | ||
| 114 | for (;;) { | ||
| 115 | int nextline = refline + 1; | ||
| 116 | int nextref = refi + 1; | ||
| 117 | if (lineinfo[nextref] < 0) | ||
| 118 | nextline += -lineinfo[nextref++]; | ||
| 119 | LUA_ASSERT(lineinfo[nextref] >= 0, "invalid line info"); | ||
| 120 | if (lineinfo[nextref] > pc) | ||
| 121 | break; | ||
| 122 | refline = nextline; | ||
| 123 | refi = nextref; | ||
| 124 | } | ||
| 125 | if (prefi) *prefi = refi; | ||
| 126 | return refline; | ||
| 127 | } | ||
| 128 | |||
| 129 | |||
| 102 | static int lua_currentpc (StkId f) { | 130 | static int lua_currentpc (StkId f) { |
| 103 | CallInfo *ci = infovalue(f); | 131 | CallInfo *ci = infovalue(f); |
| 104 | LUA_ASSERT(ttype(f) == TAG_LMARK, "function has no pc"); | 132 | LUA_ASSERT(ttype(f) == TAG_LMARK, "function has no pc"); |
| @@ -111,9 +139,10 @@ static int lua_currentline (StkId f) { | |||
| 111 | return -1; /* only active lua functions have current-line information */ | 139 | return -1; /* only active lua functions have current-line information */ |
| 112 | else { | 140 | else { |
| 113 | CallInfo *ci = infovalue(f); | 141 | CallInfo *ci = infovalue(f); |
| 114 | int *lines = ci->func->f.l->lines; | 142 | int *lineinfo = ci->func->f.l->lineinfo; |
| 115 | if (!lines) return -1; /* no static debug information */ | 143 | if (!lineinfo) return -1; /* no static debug information */ |
| 116 | else return lines[lua_currentpc(f)]; | 144 | else |
| 145 | return luaG_getline(lineinfo, lua_currentpc(f), 1, NULL); | ||
| 117 | } | 146 | } |
| 118 | } | 147 | } |
| 119 | 148 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.h,v 1.1 2000/01/14 17:15:44 roberto Exp roberto $ | 2 | ** $Id: ldebug.h,v 1.2 2000/06/28 20:20:36 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 | */ |
| @@ -14,6 +14,7 @@ | |||
| 14 | 14 | ||
| 15 | void luaG_callerror (lua_State *L, StkId func); | 15 | void luaG_callerror (lua_State *L, StkId func); |
| 16 | void luaG_indexerror (lua_State *L, StkId t); | 16 | void luaG_indexerror (lua_State *L, StkId t); |
| 17 | int luaG_getline (int *lineinfo, int pc, int refline, int *refi); | ||
| 17 | 18 | ||
| 18 | 19 | ||
| 19 | #endif | 20 | #endif |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lfunc.c,v 1.25 2000/06/26 19:28:31 roberto Exp roberto $ | 2 | ** $Id: lfunc.c,v 1.26 2000/08/07 20:21:34 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,7 +35,7 @@ Closure *luaF_newclosure (lua_State *L, int nelems) { | |||
| 35 | Proto *luaF_newproto (lua_State *L) { | 35 | Proto *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->lineinfo = NULL; |
| 39 | f->lineDefined = 0; | 39 | f->lineDefined = 0; |
| 40 | f->source = NULL; | 40 | f->source = NULL; |
| 41 | f->kstr = NULL; | 41 | f->kstr = NULL; |
| @@ -60,7 +60,7 @@ void luaF_freeproto (lua_State *L, Proto *f) { | |||
| 60 | luaM_free(L, f->kstr); | 60 | luaM_free(L, f->kstr); |
| 61 | luaM_free(L, f->knum); | 61 | luaM_free(L, f->knum); |
| 62 | luaM_free(L, f->kproto); | 62 | luaM_free(L, f->kproto); |
| 63 | luaM_free(L, f->lines); | 63 | luaM_free(L, f->lineinfo); |
| 64 | luaM_free(L, f); | 64 | luaM_free(L, f); |
| 65 | } | 65 | } |
| 66 | 66 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.h,v 1.70 2000/06/30 14:35:17 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 1.71 2000/08/07 20:21:34 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 | */ |
| @@ -119,7 +119,7 @@ typedef struct Proto { | |||
| 119 | Instruction *code; /* ends with opcode ENDCODE */ | 119 | Instruction *code; /* ends with opcode ENDCODE */ |
| 120 | struct Proto *next; | 120 | struct Proto *next; |
| 121 | int marked; | 121 | int marked; |
| 122 | int *lines; /* source line that generated each opcode */ | 122 | int *lineinfo; /* map from opcodes to source lines */ |
| 123 | int lineDefined; | 123 | int lineDefined; |
| 124 | TString *source; | 124 | TString *source; |
| 125 | int numparams; | 125 | int numparams; |
| @@ -180,6 +180,7 @@ typedef struct CallInfo { | |||
| 180 | const Instruction **pc; /* current pc of called function */ | 180 | const Instruction **pc; /* current pc of called function */ |
| 181 | int lastpc; /* last pc traced */ | 181 | int lastpc; /* last pc traced */ |
| 182 | int line; /* current line */ | 182 | int line; /* current line */ |
| 183 | int refi; /* current index in `lineinfo' */ | ||
| 183 | } CallInfo; | 184 | } CallInfo; |
| 184 | 185 | ||
| 185 | 186 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.101 2000/06/28 20:20:36 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.102 2000/06/30 14:35:17 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 | */ |
| @@ -327,6 +327,8 @@ static void open_func (LexState *ls, FuncState *fs) { | |||
| 327 | f->source = ls->source; | 327 | f->source = ls->source; |
| 328 | fs->pc = 0; | 328 | fs->pc = 0; |
| 329 | fs->lasttarget = 0; | 329 | fs->lasttarget = 0; |
| 330 | fs->nlineinfo = 0; | ||
| 331 | fs->lastline = 0; | ||
| 330 | fs->jlt = NO_JUMP; | 332 | fs->jlt = NO_JUMP; |
| 331 | f->code = NULL; | 333 | f->code = NULL; |
| 332 | f->maxstacksize = 0; | 334 | f->maxstacksize = 0; |
| @@ -348,6 +350,10 @@ static void close_func (LexState *ls) { | |||
| 348 | luaM_reallocvector(L, f->kproto, f->nkproto, Proto *); | 350 | luaM_reallocvector(L, f->kproto, f->nkproto, Proto *); |
| 349 | luaI_registerlocalvar(ls, NULL, -1); /* flag end of vector */ | 351 | luaI_registerlocalvar(ls, NULL, -1); /* flag end of vector */ |
| 350 | luaM_reallocvector(L, f->locvars, fs->nvars, LocVar); | 352 | luaM_reallocvector(L, f->locvars, fs->nvars, LocVar); |
| 353 | if (fs->debug) { | ||
| 354 | luaM_reallocvector(L, f->lineinfo, fs->nlineinfo+1, int); | ||
| 355 | f->lineinfo[fs->nlineinfo] = MAX_INT; /* end flag */ | ||
| 356 | } | ||
| 351 | ls->fs = fs->prev; | 357 | ls->fs = fs->prev; |
| 352 | LUA_ASSERT(fs->bl == NULL, "wrong list end"); | 358 | LUA_ASSERT(fs->bl == NULL, "wrong list end"); |
| 353 | } | 359 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.h,v 1.19 2000/06/26 19:28:31 roberto Exp roberto $ | 2 | ** $Id: lparser.h,v 1.20 2000/06/28 20:20:36 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 | */ |
| @@ -49,6 +49,8 @@ typedef struct FuncState { | |||
| 49 | int nupvalues; /* number of upvalues */ | 49 | int nupvalues; /* number of upvalues */ |
| 50 | int debug; /* flag for debug information */ | 50 | int debug; /* flag for debug information */ |
| 51 | int nvars; /* number of entries in f->locvars */ | 51 | int nvars; /* number of entries in f->locvars */ |
| 52 | int lastline; /* line where last `lineinfo' was generated */ | ||
| 53 | int nlineinfo; /* index of next `lineinfo' to be generated */ | ||
| 52 | struct Breaklabel *bl; /* chain of breakable blocks */ | 54 | struct Breaklabel *bl; /* chain of breakable blocks */ |
| 53 | expdesc upvalues[MAXUPVALUES]; /* upvalues */ | 55 | expdesc upvalues[MAXUPVALUES]; /* upvalues */ |
| 54 | TString *localvar[MAXLOCALS]; /* store local variable names */ | 56 | TString *localvar[MAXLOCALS]; /* store local variable names */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltests.c,v 1.29 2000/06/30 19:17:08 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 1.30 2000/08/04 19:38:35 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 | */ |
| @@ -16,6 +16,7 @@ | |||
| 16 | #include "lapi.h" | 16 | #include "lapi.h" |
| 17 | #include "lauxlib.h" | 17 | #include "lauxlib.h" |
| 18 | #include "lcode.h" | 18 | #include "lcode.h" |
| 19 | #include "ldebug.h" | ||
| 19 | #include "ldo.h" | 20 | #include "ldo.h" |
| 20 | #include "lfunc.h" | 21 | #include "lfunc.h" |
| 21 | #include "lmem.h" | 22 | #include "lmem.h" |
| @@ -68,9 +69,9 @@ static int pushop (Proto *p, int pc) { | |||
| 68 | Instruction i = p->code[pc]; | 69 | Instruction i = p->code[pc]; |
| 69 | OpCode o = GET_OPCODE(i); | 70 | OpCode o = GET_OPCODE(i); |
| 70 | const char *name = instrname[o]; | 71 | const char *name = instrname[o]; |
| 71 | int *line = p->lines; | 72 | int *lineinfo = p->lineinfo; |
| 72 | if (line) | 73 | if (lineinfo) |
| 73 | sprintf(buff, "%5d - ", line[pc]); | 74 | sprintf(buff, "%5d - ", luaG_getline(lineinfo, pc, 1, NULL)); |
| 74 | else | 75 | else |
| 75 | strcpy(buff, " "); | 76 | strcpy(buff, " "); |
| 76 | switch ((enum Mode)luaK_opproperties[o].mode) { | 77 | switch ((enum Mode)luaK_opproperties[o].mode) { |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.119 2000/06/28 20:20:36 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.120 2000/06/30 14:35:17 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 | */ |
| @@ -69,14 +69,20 @@ int luaV_tostring (lua_State *L, TObject *obj) { /* LUA_NUMBER */ | |||
| 69 | 69 | ||
| 70 | static void traceexec (lua_State *L, StkId base, StkId top, lua_Hook linehook) { | 70 | static 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 *lines = ci->func->f.l->lines; | 72 | int *lineinfo = ci->func->f.l->lineinfo; |
| 73 | int pc = (*ci->pc - 1) - ci->func->f.l->code; | 73 | int pc = (*ci->pc - 1) - ci->func->f.l->code; |
| 74 | if (lines) { | 74 | if (lineinfo) { |
| 75 | int newline; | ||
| 76 | if (ci->line == 0) { /* first time? */ | ||
| 77 | ci->line = 1; | ||
| 78 | ci->refi = 0; | ||
| 79 | } | ||
| 80 | newline = luaG_getline(lineinfo, pc, ci->line, &ci->refi); | ||
| 75 | /* calls linehook when enters a new line or jumps back (loop) */ | 81 | /* calls linehook when enters a new line or jumps back (loop) */ |
| 76 | if (lines[pc] != ci->line || pc <= ci->lastpc) { | 82 | if (newline != ci->line || pc <= ci->lastpc) { |
| 77 | ci->line = lines[pc]; | 83 | ci->line = newline; |
| 78 | L->top = top; | 84 | L->top = top; |
| 79 | luaD_lineHook(L, base-2, lines[pc], linehook); | 85 | luaD_lineHook(L, base-2, newline, linehook); |
| 80 | } | 86 | } |
| 81 | } | 87 | } |
| 82 | ci->lastpc = pc; | 88 | ci->lastpc = pc; |
