Bläddra i källkod

new structure for line information

Roberto Ierusalimschy 25 år sedan
förälder
incheckning
f90bc248b3
9 ändrade filer med 84 tillägg och 29 borttagningar
  1. 16 7
      lcode.c
  2. 33 4
      ldebug.c
  3. 2 1
      ldebug.h
  4. 3 3
      lfunc.c
  5. 3 2
      lobject.h
  6. 7 1
      lparser.c
  7. 3 1
      lparser.h
  8. 5 4
      ltests.c
  9. 12 6
      lvm.c

+ 16 - 7
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);

+ 33 - 4
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);
   }
 }
 

+ 2 - 1
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

+ 3 - 3
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);
 }
 

+ 3 - 2
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;
 
 

+ 7 - 1
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");
 }

+ 3 - 1
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 */

+ 5 - 4
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) {  

+ 12 - 6
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;