From b69e712713785394ceefa11ab3e5f9636abea733 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 21 Jun 2000 15:13:56 -0300 Subject: [PATCH] new way to generate SETLINEs --- lcode.c | 19 ++++++++++----- llex.c | 3 ++- llex.h | 3 ++- lparser.c | 70 +++++++++++++++++-------------------------------------- lparser.h | 3 ++- 5 files changed, 41 insertions(+), 57 deletions(-) diff --git a/lcode.c b/lcode.c index 6e43f499..50ed11e6 100644 --- a/lcode.c +++ b/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++; } diff --git a/llex.c b/llex.c index f251ab9c..50ffc951 100644 --- a/llex.c +++ b/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 == '#') { diff --git a/llex.h b/llex.h index 8528dc20..604b8bf1 100644 --- a/llex.h +++ b/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; diff --git a/lparser.c b/lparser.c index 7b46c0ea..e920af3e 100644 --- a/lparser.c +++ b/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), " 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); } diff --git a/lparser.h b/lparser.h index 42f11d42..2fb8e000 100644 --- a/lparser.h +++ b/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 */