From f90bc248b3c3c18941a96038b2a7517ad571d8b1 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 8 Aug 2000 15:26:05 -0300 Subject: new structure for line information --- lcode.c | 23 ++++++++++++++++------- ldebug.c | 37 +++++++++++++++++++++++++++++++++---- ldebug.h | 3 ++- lfunc.c | 6 +++--- lobject.h | 5 +++-- lparser.c | 8 +++++++- lparser.h | 4 +++- ltests.c | 9 +++++---- lvm.c | 18 ++++++++++++------ 9 files changed, 84 insertions(+), 29 deletions(-) diff --git a/lcode.c b/lcode.c index fd7c6683..2a47daee 100644 --- a/lcode.c +++ b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 1.41 2000/06/30 14:35:17 roberto Exp roberto $ +** $Id: lcode.c,v 1.42 2000/08/04 19:38:35 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -413,6 +413,19 @@ void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2) { } +static void codelineinfo (FuncState *fs) { + LexState *ls = fs->ls; + if (ls->lastline > fs->lastline) { + luaM_growvector(fs->L, fs->f->lineinfo, fs->nlineinfo, 2, int, + "line info overflow", MAX_INT); + if (ls->lastline > fs->lastline+1) + fs->f->lineinfo[fs->nlineinfo++] = -(ls->lastline - (fs->lastline+1)); + fs->f->lineinfo[fs->nlineinfo++] = fs->pc; + fs->lastline = ls->lastline; + } +} + + int luaK_code0 (FuncState *fs, OpCode o) { return luaK_code2(fs, o, 0, 0); } @@ -618,12 +631,8 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { case iS: i = CREATE_S(o, arg1); break; case iAB: i = CREATE_AB(o, arg1, arg2); break; } - if (fs->debug) { - LexState *ls = fs->ls; - luaM_growvector(fs->L, fs->f->lines, fs->pc, 1, int, - "code size overflow", MAX_INT); - fs->f->lines[fs->pc] = ls->lastline; - } + if (fs->debug) + codelineinfo(fs); /* put new instruction in code array */ luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, "code size overflow", MAX_INT); diff --git a/ldebug.c b/ldebug.c index bfc3763f..60fdfa37 100644 --- a/ldebug.c +++ b/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 1.27 2000/06/30 14:35:17 roberto Exp roberto $ +** $Id: ldebug.c,v 1.28 2000/08/07 20:21:34 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -99,6 +99,34 @@ static int lua_nups (StkId f) { } +int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) { + int refi = prefi ? *prefi : 0; + if (lineinfo[refi] < 0) + refline += -lineinfo[refi++]; + LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info"); + while (lineinfo[refi] > pc) { + refline--; + refi--; + if (lineinfo[refi] < 0) + refline -= -lineinfo[refi--]; + LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info"); + } + for (;;) { + int nextline = refline + 1; + int nextref = refi + 1; + if (lineinfo[nextref] < 0) + nextline += -lineinfo[nextref++]; + LUA_ASSERT(lineinfo[nextref] >= 0, "invalid line info"); + if (lineinfo[nextref] > pc) + break; + refline = nextline; + refi = nextref; + } + if (prefi) *prefi = refi; + return refline; +} + + static int lua_currentpc (StkId f) { CallInfo *ci = infovalue(f); LUA_ASSERT(ttype(f) == TAG_LMARK, "function has no pc"); @@ -111,9 +139,10 @@ static int lua_currentline (StkId f) { return -1; /* only active lua functions have current-line information */ else { CallInfo *ci = infovalue(f); - int *lines = ci->func->f.l->lines; - if (!lines) return -1; /* no static debug information */ - else return lines[lua_currentpc(f)]; + int *lineinfo = ci->func->f.l->lineinfo; + if (!lineinfo) return -1; /* no static debug information */ + else + return luaG_getline(lineinfo, lua_currentpc(f), 1, NULL); } } diff --git a/ldebug.h b/ldebug.h index d52a00a4..15be1eb4 100644 --- a/ldebug.h +++ b/ldebug.h @@ -1,5 +1,5 @@ /* -** $Id: ldebug.h,v 1.1 2000/01/14 17:15:44 roberto Exp roberto $ +** $Id: ldebug.h,v 1.2 2000/06/28 20:20:36 roberto Exp roberto $ ** Auxiliary functions from Debug Interface module ** See Copyright Notice in lua.h */ @@ -14,6 +14,7 @@ void luaG_callerror (lua_State *L, StkId func); void luaG_indexerror (lua_State *L, StkId t); +int luaG_getline (int *lineinfo, int pc, int refline, int *refi); #endif diff --git a/lfunc.c b/lfunc.c index 004b5d41..6280cf29 100644 --- a/lfunc.c +++ b/lfunc.c @@ -1,5 +1,5 @@ /* -** $Id: lfunc.c,v 1.25 2000/06/26 19:28:31 roberto Exp roberto $ +** $Id: lfunc.c,v 1.26 2000/08/07 20:21:34 roberto Exp roberto $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ @@ -35,7 +35,7 @@ Closure *luaF_newclosure (lua_State *L, int nelems) { Proto *luaF_newproto (lua_State *L) { Proto *f = luaM_new(L, Proto); f->code = NULL; - f->lines = NULL; + f->lineinfo = NULL; f->lineDefined = 0; f->source = NULL; f->kstr = NULL; @@ -60,7 +60,7 @@ void luaF_freeproto (lua_State *L, Proto *f) { luaM_free(L, f->kstr); luaM_free(L, f->knum); luaM_free(L, f->kproto); - luaM_free(L, f->lines); + luaM_free(L, f->lineinfo); luaM_free(L, f); } diff --git a/lobject.h b/lobject.h index b432c84a..76cf8663 100644 --- a/lobject.h +++ b/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 1.70 2000/06/30 14:35:17 roberto Exp roberto $ +** $Id: lobject.h,v 1.71 2000/08/07 20:21:34 roberto Exp roberto $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -119,7 +119,7 @@ typedef struct Proto { Instruction *code; /* ends with opcode ENDCODE */ struct Proto *next; int marked; - int *lines; /* source line that generated each opcode */ + int *lineinfo; /* map from opcodes to source lines */ int lineDefined; TString *source; int numparams; @@ -180,6 +180,7 @@ typedef struct CallInfo { const Instruction **pc; /* current pc of called function */ int lastpc; /* last pc traced */ int line; /* current line */ + int refi; /* current index in `lineinfo' */ } CallInfo; diff --git a/lparser.c b/lparser.c index 74dd8dc1..deae943f 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.101 2000/06/28 20:20:36 roberto Exp roberto $ +** $Id: lparser.c,v 1.102 2000/06/30 14:35:17 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -327,6 +327,8 @@ static void open_func (LexState *ls, FuncState *fs) { f->source = ls->source; fs->pc = 0; fs->lasttarget = 0; + fs->nlineinfo = 0; + fs->lastline = 0; fs->jlt = NO_JUMP; f->code = NULL; f->maxstacksize = 0; @@ -348,6 +350,10 @@ static void close_func (LexState *ls) { luaM_reallocvector(L, f->kproto, f->nkproto, Proto *); luaI_registerlocalvar(ls, NULL, -1); /* flag end of vector */ luaM_reallocvector(L, f->locvars, fs->nvars, LocVar); + if (fs->debug) { + luaM_reallocvector(L, f->lineinfo, fs->nlineinfo+1, int); + f->lineinfo[fs->nlineinfo] = MAX_INT; /* end flag */ + } ls->fs = fs->prev; LUA_ASSERT(fs->bl == NULL, "wrong list end"); } diff --git a/lparser.h b/lparser.h index 12f936ae..c7f87350 100644 --- a/lparser.h +++ b/lparser.h @@ -1,5 +1,5 @@ /* -** $Id: lparser.h,v 1.19 2000/06/26 19:28:31 roberto Exp roberto $ +** $Id: lparser.h,v 1.20 2000/06/28 20:20:36 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -49,6 +49,8 @@ typedef struct FuncState { int nupvalues; /* number of upvalues */ int debug; /* flag for debug information */ int nvars; /* number of entries in f->locvars */ + int lastline; /* line where last `lineinfo' was generated */ + int nlineinfo; /* index of next `lineinfo' to be generated */ struct Breaklabel *bl; /* chain of breakable blocks */ expdesc upvalues[MAXUPVALUES]; /* upvalues */ TString *localvar[MAXLOCALS]; /* store local variable names */ diff --git a/ltests.c b/ltests.c index 40ba3f4b..677f7c8d 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 1.29 2000/06/30 19:17:08 roberto Exp roberto $ +** $Id: ltests.c,v 1.30 2000/08/04 19:38:35 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -16,6 +16,7 @@ #include "lapi.h" #include "lauxlib.h" #include "lcode.h" +#include "ldebug.h" #include "ldo.h" #include "lfunc.h" #include "lmem.h" @@ -68,9 +69,9 @@ static int pushop (Proto *p, int pc) { Instruction i = p->code[pc]; OpCode o = GET_OPCODE(i); const char *name = instrname[o]; - int *line = p->lines; - if (line) - sprintf(buff, "%5d - ", line[pc]); + int *lineinfo = p->lineinfo; + if (lineinfo) + sprintf(buff, "%5d - ", luaG_getline(lineinfo, pc, 1, NULL)); else strcpy(buff, " "); switch ((enum Mode)luaK_opproperties[o].mode) { diff --git a/lvm.c b/lvm.c index ed29602c..0ea8ea9f 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.119 2000/06/28 20:20:36 roberto Exp roberto $ +** $Id: lvm.c,v 1.120 2000/06/30 14:35:17 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -69,14 +69,20 @@ int luaV_tostring (lua_State *L, TObject *obj) { /* LUA_NUMBER */ static void traceexec (lua_State *L, StkId base, StkId top, lua_Hook linehook) { CallInfo *ci = infovalue(base-1); - int *lines = ci->func->f.l->lines; + int *lineinfo = ci->func->f.l->lineinfo; int pc = (*ci->pc - 1) - ci->func->f.l->code; - if (lines) { + if (lineinfo) { + int newline; + if (ci->line == 0) { /* first time? */ + ci->line = 1; + ci->refi = 0; + } + newline = luaG_getline(lineinfo, pc, ci->line, &ci->refi); /* calls linehook when enters a new line or jumps back (loop) */ - if (lines[pc] != ci->line || pc <= ci->lastpc) { - ci->line = lines[pc]; + if (newline != ci->line || pc <= ci->lastpc) { + ci->line = newline; L->top = top; - luaD_lineHook(L, base-2, lines[pc], linehook); + luaD_lineHook(L, base-2, newline, linehook); } } ci->lastpc = pc; -- cgit v1.2.3-55-g6feb