Ver código fonte

new way to generate SETLINEs

Roberto Ierusalimschy 25 anos atrás
pai
commit
b69e712713
5 arquivos alterados com 41 adições e 57 exclusões
  1. 13 6
      lcode.c
  2. 2 1
      llex.c
  3. 2 1
      llex.h
  4. 22 48
      lparser.c
  5. 2 1
      lparser.h

+ 13 - 6
lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 1.36 2000/06/16 17:51:40 roberto Exp roberto $
+** $Id: lcode.c,v 1.37 2000/06/21 17:05:49 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -307,9 +307,8 @@ static void luaK_goiffalse (FuncState *fs, expdesc *v, int keepvalue) {
 
 
 static int code_label (FuncState *fs, OpCode op, int arg) {
-  int j = luaK_getlabel(fs);
-  luaK_code1(fs, op, arg);
-  return j;
+  luaK_getlabel(fs);  /* those instructions may be jump targets */
+  return luaK_code1(fs, op, arg);
 }
 
 
@@ -624,9 +623,17 @@ 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;
   }
-  /* put new instruction in code array */
-  luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction,
+  /* check space for new instruction plus eventual SETLINE */
+  luaM_growvector(fs->L, fs->f->code, fs->pc, 2, Instruction,
                   "code size overflow", MAX_INT);
+  /* check the need for SETLINE */
+  if (fs->debug && fs->ls->lastline != fs->lastsetline) {
+    LexState *ls = fs->ls;
+    luaX_checklimit(ls, ls->lastline, MAXARG_U, "lines in a chunk");
+    fs->f->code[fs->pc++] = CREATE_U(OP_SETLINE, ls->lastline);
+    fs->lastsetline = ls->lastline;
+  }
+  /* put new instruction in code array */
   fs->f->code[fs->pc] = i;
   return fs->pc++;
 }

+ 2 - 1
llex.c

@@ -1,5 +1,5 @@
 /*
-** $Id: llex.c,v 1.63 2000/06/12 13:52:05 roberto Exp roberto $
+** $Id: llex.c,v 1.64 2000/06/19 18:05:14 roberto Exp roberto $
 ** Lexical Analyzer
 ** See Copyright Notice in lua.h
 */
@@ -138,6 +138,7 @@ void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) {
   LS->z = z;
   LS->fs = NULL;
   LS->linenumber = 1;
+  LS->lastline = 1;
   LS->source = source;
   next(LS);  /* read first char */
   if (LS->current == '#') {

+ 2 - 1
llex.h

@@ -1,5 +1,5 @@
 /*
-** $Id: llex.h,v 1.28 2000/05/26 14:04:04 roberto Exp roberto $
+** $Id: llex.h,v 1.29 2000/06/19 18:05:14 roberto Exp roberto $
 ** Lexical Analyzer
 ** See Copyright Notice in lua.h
 */
@@ -51,6 +51,7 @@ typedef struct LexState {
   struct lua_State *L;
   struct zio *z;  /* input stream */
   int linenumber;  /* input line counter */
+  int lastline;  /* line of last token `consumed' */
   TString *source;  /* current source name */
 } LexState;
 

+ 22 - 48
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 1.96 2000/06/19 18:05:14 roberto Exp roberto $
+** $Id: lparser.c,v 1.97 2000/06/19 18:26:23 roberto Exp roberto $
 ** LL(1) Parser and code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -56,6 +56,7 @@ static void exp1 (LexState *ls);
 
 
 static void next (LexState *ls) {
+  ls->lastline = ls->linenumber;
   if (ls->lookahead.token != TK_EOS) {  /* is there a look-ahead token? */
     ls->t = ls->lookahead;  /* use this one */
     ls->lookahead.token = TK_EOS;  /* and discharge it */
@@ -91,16 +92,6 @@ static void check_condition (LexState *ls, int c, const char *msg) {
 }
 
 
-static void setline (LexState *ls) {
-  FuncState *fs = ls->fs;
-  if (ls->L->debug && ls->linenumber != fs->lastsetline) {
-    luaX_checklimit(ls, ls->linenumber, MAXARG_U, "lines in a chunk");
-    luaK_code1(fs, OP_SETLINE, ls->linenumber);
-    fs->lastsetline = ls->linenumber;
-  }
-}
-
-
 static int optional (LexState *ls, int c) {
   if (ls->t.token == c) {
     next(ls);
@@ -128,18 +119,6 @@ static void check_match (LexState *ls, int what, int who, int where) {
 }
 
 
-static void setline_and_next (LexState *ls) {
-  setline(ls);
-  next(ls);
-}
-
-
-static void check_END (LexState *ls, int who, int where) {
-  setline(ls);  /* setline for END */
-  check_match(ls, TK_END, who, where);
-}
-
-
 static int string_constant (FuncState *fs, TString *s) {
   Proto *f = fs->f;
   int c = s->u.s.constindex;
@@ -175,9 +154,7 @@ static int checkname (LexState *ls) {
 
 static void luaI_registerlocalvar (LexState *ls, TString *varname, int line) {
   FuncState *fs = ls->fs;
-  /* start debug only when there are no active local variables,
-     but keep going after starting */
-  if ((ls->L->debug && fs->nlocalvar == 0) || fs->nvars != 0) {
+  if (fs->debug) {
     Proto *f = fs->f;
     luaM_growvector(ls->L, f->locvars, fs->nvars, 1, LocVar, "", MAX_INT);
     f->locvars[fs->nvars].varname = varname;
@@ -368,10 +345,8 @@ static void close_func (LexState *ls) {
   luaM_reallocvector(L, f->kstr, f->nkstr, TString *);
   luaM_reallocvector(L, f->knum, f->nknum, Number);
   luaM_reallocvector(L, f->kproto, f->nkproto, Proto *);
-  if (f->locvars) {  /* debug information? */
-    luaI_registerlocalvar(ls, NULL, -1);  /* flag end of vector */
-    luaM_reallocvector(L, f->locvars, fs->nvars, LocVar);
-  }
+  luaI_registerlocalvar(ls, NULL, -1);  /* flag end of vector */
+  luaM_reallocvector(L, f->locvars, fs->nvars, LocVar);
   ls->fs = fs->prev;
   LUA_ASSERT(L, fs->bl == NULL, "wrong list end");
 }
@@ -383,6 +358,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z) {
   luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z)));
   open_func(&lexstate, &funcstate);
   next(&lexstate);  /* read first token */
+  funcstate.debug = L->debug;  /* previous `next' may scan a pragma */
   chunk(&lexstate);
   check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");
   close_func(&lexstate);
@@ -639,7 +615,6 @@ static void constructor (LexState *ls) {
 
 static void simpleexp (LexState *ls, expdesc *v) {
   FuncState *fs = ls->fs;
-  setline(ls);
   switch (ls->t.token) {
     case TK_NUMBER: {  /* simpleexp -> NUMBER */
       Number r = ls->t.seminfo.r;
@@ -819,13 +794,13 @@ static void whilestat (LexState *ls, int line) {
   expdesc v;
   Breaklabel bl;
   enterbreak(fs, &bl);
-  setline_and_next(ls);  /* trace WHILE when looping */
+  next(ls);
   cond(ls, &v);
   check(ls, TK_DO);
   block(ls);
   luaK_patchlist(fs, luaK_jump(fs), while_init);
   luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
-  check_END(ls, TK_WHILE, line);  /* trace END when loop ends */
+  check_match(ls, TK_END, TK_WHILE, line);
   leavebreak(fs, &bl);
 }
 
@@ -837,7 +812,7 @@ static void repeatstat (LexState *ls, int line) {
   expdesc v;
   Breaklabel bl;
   enterbreak(fs, &bl);
-  setline_and_next(ls);  /* trace REPEAT when looping */
+  next(ls);
   block(ls);
   check_match(ls, TK_UNTIL, TK_REPEAT, line);
   cond(ls, &v);
@@ -905,23 +880,22 @@ static void forstat (LexState *ls, int line) {
   TString *varname;
   Breaklabel bl;
   enterbreak(fs, &bl);
-  setline_and_next(ls);  /* skip `for' */
+  next(ls);  /* skip `for' */
   varname = str_checkname(ls);  /* first variable name */
   switch (ls->t.token) {
     case '=': fornum(ls, varname); break;
     case ',': forlist(ls, varname); break;
     default: luaK_error(ls, "`=' or `,' expected");
   }
-  check_END(ls, TK_FOR, line);
+  check_match(ls, TK_END, TK_FOR, line);
   leavebreak(fs, &bl);
 }
 
 
 static void test_then_block (LexState *ls, expdesc *v) {
   /* test_then_block -> [IF | ELSEIF] cond THEN block */
-  setline_and_next(ls);  /* skip IF or ELSEIF */
+  next(ls);  /* skip IF or ELSEIF */
   cond(ls, v);
-  setline(ls);  /* to trace the THEN */
   check(ls, TK_THEN);
   block(ls);  /* `then' part */
 }
@@ -941,13 +915,13 @@ static void ifstat (LexState *ls, int line) {
   if (ls->t.token == TK_ELSE) {
     luaK_concat(fs, &escapelist, luaK_jump(fs));
     luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
-    setline_and_next(ls);  /* skip ELSE */
+    next(ls);  /* skip ELSE */
     block(ls);  /* `else' part */
   }
   else
     luaK_concat(fs, &escapelist, v.u.l.f);
   luaK_patchlist(fs, escapelist, luaK_getlabel(fs));
-  check_END(ls, TK_IF, line);
+  check_match(ls, TK_END, TK_IF, line);
 }
 
 
@@ -956,7 +930,7 @@ static void localstat (LexState *ls) {
   int nvars = 0;
   int nexps;
   do {
-    setline_and_next(ls);  /* skip LOCAL or ',' */
+    next(ls);  /* skip LOCAL or ',' */
     store_localvar(ls, str_checkname(ls), nvars++);
   } while (ls->t.token == ',');
   if (optional(ls, '='))
@@ -989,7 +963,7 @@ static void funcstat (LexState *ls, int line) {
   expdesc v;
   check_condition(ls, (ls->fs->prev == NULL),
                   "cannot nest this kind of function declaration");
-  setline_and_next(ls);  /* skip FUNCTION */
+  next(ls);  /* skip FUNCTION */
   needself = funcname(ls, &v);
   body(ls, needself, line);
   luaK_storevar(ls, &v);
@@ -1000,7 +974,6 @@ static void namestat (LexState *ls) {
   /* stat -> func | ['%'] NAME assignment */
   FuncState *fs = ls->fs;
   expdesc v;
-  setline(ls);
   var_or_func(ls, &v);
   if (v.k == VEXP) {  /* stat -> func */
     check_condition(ls, luaK_lastisopen(fs), "syntax error");  /* an upvalue? */
@@ -1016,7 +989,7 @@ static void namestat (LexState *ls) {
 static void retstat (LexState *ls) {
   /* stat -> RETURN explist */
   FuncState *fs = ls->fs;
-  setline_and_next(ls);  /* skip RETURN */
+  next(ls);  /* skip RETURN */
   if (!block_follow(ls->t.token))
     explist1(ls);  /* optional return values */
   luaK_code1(fs, OP_RETURN, ls->fs->nlocalvar);
@@ -1031,7 +1004,7 @@ static void breakstat (LexState *ls) {
   Breaklabel *bl = fs->bl;
   if (!bl)
     luaK_error(ls, "no loop to break");
-  setline_and_next(ls);  /* skip BREAK */
+  next(ls);  /* skip BREAK */
   luaK_adjuststack(fs, currentlevel - bl->stacklevel);
   luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
   fs->stacklevel = currentlevel;
@@ -1050,9 +1023,9 @@ static int stat (LexState *ls) {
       return 0;
     }
     case TK_DO: {  /* stat -> DO block END */
-      setline_and_next(ls);  /* skip DO */
+      next(ls);  /* skip DO */
       block(ls);
-      check_END(ls, TK_DO, line);
+      check_match(ls, TK_END, TK_DO, line);
       return 0;
     }
     case TK_FOR: {  /* stat -> forstat */
@@ -1113,13 +1086,14 @@ static void body (LexState *ls, int needself, int line) {
   FuncState new_fs;
   open_func(ls, &new_fs);
   new_fs.f->lineDefined = line;
+  new_fs.debug = ls->L->debug;
   check(ls, '(');
   if (needself)
     add_localvar(ls, "self");
   parlist(ls);
   check(ls, ')');
   chunk(ls);
-  check_END(ls, TK_FUNCTION, line);
+  check_match(ls, TK_END, TK_FUNCTION, line);
   close_func(ls);
   pushclosure(ls, &new_fs);
 }

+ 2 - 1
lparser.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.h,v 1.16 2000/04/06 17:36:52 roberto Exp roberto $
+** $Id: lparser.h,v 1.17 2000/05/25 18:26:42 roberto Exp roberto $
 ** LL(1) Parser and code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -49,6 +49,7 @@ typedef struct FuncState {
   int nupvalues;  /* number of upvalues */
   int nvars;  /* number of entries in f->locvars */
   int lastsetline;  /* line where last SETLINE was issued */
+  int debug;  /* flag to generate debug information */
   struct Breaklabel *bl;  /* chain of breakable blocks */
   expdesc upvalues[MAXUPVALUES];  /* upvalues */
   TString *localvar[MAXLOCALS];  /* store local variable names */