new way to generate SETLINEs

This commit is contained in:
Roberto Ierusalimschy 2000-06-21 15:13:56 -03:00
parent f517759507
commit b69e712713
5 changed files with 41 additions and 57 deletions

19
lcode.c
View File

@ -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++;
}

3
llex.c
View File

@ -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 == '#') {

3
llex.h
View File

@ -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;

View File

@ -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);
}

View File

@ -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 */