new version of debug system

This commit is contained in:
Roberto Ierusalimschy 2000-06-26 16:28:31 -03:00
parent b69e712713
commit afef009fce
15 changed files with 201 additions and 159 deletions

19
lcode.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lcode.c,v 1.37 2000/06/21 17:05:49 roberto Exp roberto $
** $Id: lcode.c,v 1.38 2000/06/21 18:13:56 roberto Exp roberto $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@ -283,7 +283,6 @@ static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) {
prevpos = fs->pc-1;
previous = &fs->f->code[prevpos];
LUA_ASSERT(L, *previous==previous_instruction(fs), "no jump allowed here");
LUA_ASSERT(L, GET_OPCODE(*previous) != OP_SETLINE, "no setline allowed here");
if (!ISJUMP(GET_OPCODE(*previous)))
prevpos = luaK_code1(fs, jump, NO_JUMP);
else { /* last instruction is already a jump */
@ -316,7 +315,6 @@ void luaK_tostack (LexState *ls, expdesc *v, int onlyone) {
FuncState *fs = ls->fs;
if (!discharge(fs, v)) { /* `v' is an expression? */
OpCode previous = GET_OPCODE(fs->f->code[fs->pc-1]);
LUA_ASSERT(L, previous != OP_SETLINE, "bad place to set line");
if (!ISJUMP(previous) && v->u.l.f == NO_JUMP && v->u.l.t == NO_JUMP) {
/* expression has no jumps */
if (onlyone)
@ -623,17 +621,15 @@ 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;
}
/* 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) {
if (fs->f->debug) {
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;
luaM_growvector(fs->L, fs->f->lines, fs->pc, 1, int, "??", MAXARG_U);
fs->f->lines[fs->pc] = ls->lastline;
}
/* put new instruction in code array */
luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction,
"code size overflow", MAX_INT);
fs->f->code[fs->pc] = i;
return fs->pc++;
}
@ -688,6 +684,5 @@ const struct OpProperties luaK_opproperties[NUM_OPCODES] = {
{iS, -3}, /* OP_FORLOOP */
{iS, 3}, /* OP_LFORPREP */
{iS, -4}, /* OP_LFORLOOP */
{iAB, VD}, /* OP_CLOSURE */
{iU, 0} /* OP_SETLINE */
{iAB, VD} /* OP_CLOSURE */
};

View File

@ -1,5 +1,5 @@
/*
** $Id: ldebug.c,v 1.22 2000/06/08 17:48:31 roberto Exp roberto $
** $Id: ldebug.c,v 1.23 2000/06/12 13:52:05 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
@ -23,22 +23,21 @@
#include "luadebug.h"
static const lua_Type normtype[] = { /* ORDER LUA_T */
TAG_USERDATA, TAG_NUMBER, TAG_STRING, TAG_TABLE,
TAG_LCLOSURE, TAG_CCLOSURE, TAG_NIL,
TAG_LCLOSURE, TAG_CCLOSURE /* TAG_LMARK, TAG_CMARK */
};
static void setnormalized (TObject *d, const TObject *s) {
d->value = s->value;
d->ttype = normtype[ttype(s)];
}
static int hasdebuginfo (lua_State *L, StkId f) {
return (f+1 < L->top && (f+1)->ttype == TAG_LINE);
switch (s->ttype) {
case TAG_CMARK: {
clvalue(d) = clvalue(s);
ttype(d) = TAG_CCLOSURE;
break;
}
case TAG_LMARK: {
clvalue(d) = infovalue(s)->func;
ttype(d) = TAG_LCLOSURE;
break;
}
default: *d = *s;
}
}
@ -88,22 +87,35 @@ int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
static int lua_nups (StkId f) {
switch (ttype(f)) {
case TAG_LCLOSURE: case TAG_CCLOSURE:
case TAG_LMARK: case TAG_CMARK:
case TAG_LCLOSURE: case TAG_CCLOSURE: case TAG_CMARK:
return clvalue(f)->nupvalues;
case TAG_LMARK:
return infovalue(f)->func->nupvalues;
default:
return 0;
}
}
static int lua_currentline (lua_State *L, StkId f) {
return hasdebuginfo(L, f) ? (f+1)->value.i : -1;
static int lua_currentline (StkId f) {
if (ttype(f) != TAG_LMARK)
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[ci->pc];
}
}
static int lua_currentpc (StkId f) {
return infovalue(f)->pc;
}
static Proto *getluaproto (StkId f) {
return (ttype(f) == TAG_LMARK) ? clvalue(f)->f.l : NULL;
return (ttype(f) == TAG_LMARK) ? infovalue(f)->func->f.l : NULL;
}
@ -111,12 +123,9 @@ int lua_getlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) {
StkId f = ar->_func;
Proto *fp = getluaproto(f);
if (!fp) return 0; /* `f' is not a Lua function? */
v->name = luaF_getlocalname(fp, v->index, lua_currentline(L, f));
v->name = luaF_getlocalname(fp, v->index, lua_currentpc(f));
if (!v->name) return 0;
/* if `name', there must be a TAG_LINE */
/* therefore, f+2 points to function base */
LUA_ASSERT(L, ttype(f+1) == TAG_LINE, "");
v->value = luaA_putluaObject(L, (f+2)+(v->index-1));
v->value = luaA_putluaObject(L, (f+1)+(v->index-1));
return 1;
}
@ -124,22 +133,27 @@ int lua_getlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) {
int lua_setlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) {
StkId f = ar->_func;
Proto *fp = getluaproto(f);
UNUSED(L);
if (!fp) return 0; /* `f' is not a Lua function? */
v->name = luaF_getlocalname(fp, v->index, lua_currentline(L, f));
v->name = luaF_getlocalname(fp, v->index, lua_currentpc(f));
if (!v->name || v->name[0] == '*') return 0; /* `*' starts private locals */
LUA_ASSERT(L, ttype(f+1) == TAG_LINE, "");
*((f+2)+(v->index-1)) = *v->value;
*((f+1)+(v->index-1)) = *v->value;
return 1;
}
static void lua_funcinfo (lua_Debug *ar, StkId func) {
switch (ttype(func)) {
case TAG_LCLOSURE: case TAG_LMARK:
case TAG_LCLOSURE:
ar->source = clvalue(func)->f.l->source->str;
ar->linedefined = clvalue(func)->f.l->lineDefined;
ar->what = "Lua";
break;
case TAG_LMARK:
ar->source = infovalue(func)->func->f.l->source->str;
ar->linedefined = infovalue(func)->func->f.l->lineDefined;
ar->what = "Lua";
break;
case TAG_CCLOSURE: case TAG_CMARK:
ar->source = "(C)";
ar->linedefined = -1;
@ -191,7 +205,7 @@ int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
lua_funcinfo(ar, func);
break;
case 'l':
ar->currentline = lua_currentline(L, func);
ar->currentline = lua_currentline(func);
break;
case 'u':
ar->nups = lua_nups(func);

8
ldo.c
View File

@ -1,5 +1,5 @@
/*
** $Id: ldo.c,v 1.78 2000/06/12 13:52:05 roberto Exp roberto $
** $Id: ldo.c,v 1.79 2000/06/16 17:16:34 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@ -185,10 +185,14 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
retry: /* for `function' tag method */
switch (ttype(func)) {
case TAG_LCLOSURE: {
CallInfo ci;
ci.func = clvalue(func);
ci.pc = 0;
ttype(func) = TAG_LMARK;
infovalue(func) = &ci;
if (callhook)
luaD_callHook(L, func, callhook, "call");
firstResult = luaV_execute(L, clvalue(func), func+1);
firstResult = luaV_execute(L, ci.func, func+1);
break;
}
case TAG_CCLOSURE: {

View File

@ -1,5 +1,5 @@
/*
** $Id: lfunc.c,v 1.23 2000/05/30 19:00:31 roberto Exp roberto $
** $Id: lfunc.c,v 1.24 2000/06/12 13:52:05 roberto Exp roberto $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
@ -35,6 +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->lineDefined = 0;
f->source = NULL;
f->kstr = NULL;
@ -59,6 +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);
}
@ -73,14 +75,13 @@ void luaF_freeclosure (lua_State *L, Closure *c) {
** Look for n-th local variable at line `line' in function `func'.
** Returns NULL if not found.
*/
const char *luaF_getlocalname (const Proto *func,
int local_number, int line) {
const char *luaF_getlocalname (const Proto *func, int local_number, int pc) {
int count = 0;
const char *varname = NULL;
LocVar *lv = func->locvars;
if (lv == NULL)
return NULL;
for (; lv->line != -1 && lv->line < line; lv++) {
for (; lv->pc != -1 && lv->pc <= pc; lv++) {
if (lv->varname) { /* register */
if (++count == local_number)
varname = lv->varname->str;

View File

@ -1,5 +1,5 @@
/*
** $Id: lfunc.h,v 1.10 1999/12/27 17:33:22 roberto Exp roberto $
** $Id: lfunc.h,v 1.11 2000/03/10 18:37:44 roberto Exp roberto $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
@ -17,8 +17,7 @@ Closure *luaF_newclosure (lua_State *L, int nelems);
void luaF_freeproto (lua_State *L, Proto *f);
void luaF_freeclosure (lua_State *L, Closure *c);
const char *luaF_getlocalname (const Proto *func,
int local_number, int line);
const char *luaF_getlocalname (const Proto *func, int local_number, int pc);
#endif

15
lgc.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lgc.c,v 1.56 2000/06/08 17:48:31 roberto Exp roberto $
** $Id: lgc.c,v 1.57 2000/06/12 13:52:05 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@ -41,7 +41,7 @@ static void protomark (lua_State *L, Proto *f) {
protomark(L, f->kproto[i]);
if (f->locvars) { /* is there debug information? */
LocVar *lv;
for (lv=f->locvars; lv->line != -1; lv++) /* mark local-variable names */
for (lv=f->locvars; lv->pc != -1; lv++) /* mark local-variable names */
if (lv->varname) strmark(L, lv->varname);
}
}
@ -99,9 +99,16 @@ static int markobject (lua_State *L, TObject *o) {
case TAG_TABLE:
tablemark(L, hvalue(o));
break;
case TAG_LCLOSURE: case TAG_LMARK:
case TAG_LCLOSURE:
protomark(L, clvalue(o)->f.l);
/* go trhough */
closuremark(L, clvalue(o));
break;
case TAG_LMARK: {
Closure *cl = infovalue(o)->func;
protomark(L, cl->f.l);
closuremark(L, cl);
break;
}
case TAG_CCLOSURE: case TAG_CMARK:
closuremark(L, clvalue(o));
break;

5
lmem.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lmem.c,v 1.32 2000/05/31 16:53:30 roberto Exp roberto $
** $Id: lmem.c,v 1.33 2000/06/12 13:52:05 roberto Exp roberto $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
@ -47,7 +47,8 @@
/* ensures maximum alignment for HEADER */
#define HEADER (sizeof(union { double d; char *s; long l; }))
union L_U { double d; char *s; long l; };
#define HEADER (sizeof(union L_U))
#define MARKSIZE 16
#define MARK 0x55 /* 01010101 (a nice pattern) */

View File

@ -1,5 +1,5 @@
/*
** $Id: lobject.c,v 1.40 2000/06/08 17:48:31 roberto Exp roberto $
** $Id: lobject.c,v 1.41 2000/06/12 13:52:05 roberto Exp roberto $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@ -16,7 +16,7 @@
const char *const luaO_typenames[] = { /* ORDER LUA_T */
"userdata", "number", "string", "table", "function", "function", "nil",
"function", "function", "line"
"function", "function"
};

View File

@ -1,5 +1,5 @@
/*
** $Id: lobject.h,v 1.66 2000/05/30 19:00:31 roberto Exp roberto $
** $Id: lobject.h,v 1.67 2000/06/08 18:27:13 roberto Exp roberto $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@ -46,9 +46,8 @@ typedef enum {
TAG_NIL, /* last "pre-defined" tag */
TAG_LMARK, /* mark for Lua closures */
TAG_CMARK, /* mark for C closures */
TAG_CMARK /* mark for C closures */
TAG_LINE
} lua_Type;
/* tags for values visible from Lua == first user-created tag */
@ -63,10 +62,10 @@ typedef enum {
typedef union {
struct TString *ts; /* TAG_STRING, TAG_USERDATA */
struct Closure *cl; /* TAG_[CL]CLOSURE, TAG_[CL]MARK */
struct Closure *cl; /* TAG_[CL]CLOSURE, TAG_CMARK */
struct Hash *a; /* TAG_TABLE */
struct CallInfo *i; /* TAG_LMARK */
Number n; /* TAG_NUMBER */
int i; /* TAG_LINE */
} Value;
@ -76,6 +75,7 @@ typedef union {
#define tsvalue(o) ((o)->value.ts)
#define clvalue(o) ((o)->value.cl)
#define hvalue(o) ((o)->value.a)
#define infovalue(o) ((o)->value.i)
#define svalue(o) (tsvalue(o)->str)
@ -119,8 +119,10 @@ typedef struct Proto {
struct Proto **kproto; /* functions defined inside the function */
int nkproto; /* size of `kproto' */
Instruction *code; /* ends with opcode ENDCODE */
int *lines; /* source line that generated each opcode */
int lineDefined;
TString *source;
int debug; /* flag for debug information */
int numparams;
int is_vararg;
int maxstacksize;
@ -130,7 +132,7 @@ typedef struct Proto {
typedef struct LocVar {
TString *varname; /* NULL signals end of scope */
int line;
int pc;
} LocVar;
@ -165,6 +167,16 @@ typedef struct Hash {
} Hash;
/*
** informations about a call (for debugging)
*/
typedef struct CallInfo {
int pc; /* current pc of called function */
int line; /* current line */
struct Closure *func; /* function being called */
} CallInfo;
extern const char *const luaO_typenames[];
extern const TObject luaO_nilobject;

View File

@ -1,5 +1,5 @@
/*
** $Id: lopcodes.h,v 1.63 2000/06/05 14:56:18 roberto Exp roberto $
** $Id: lopcodes.h,v 1.64 2000/06/21 17:05:49 roberto Exp roberto $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@ -146,13 +146,11 @@ OP_FORLOOP,/* J */
OP_LFORPREP,/* J */
OP_LFORLOOP,/* J */
OP_CLOSURE,/* A B v_b-v_1 closure(KPROTO[a], v_1-v_b) */
OP_SETLINE/* U - - LINE=u */
OP_CLOSURE/* A B v_b-v_1 closure(KPROTO[a], v_1-v_b) */
} OpCode;
#define NUM_OPCODES ((int)OP_SETLINE+1)
#define NUM_OPCODES ((int)OP_CLOSURE+1)
#define ISJUMP(o) (OP_JMPNE <= (o) && (o) <= OP_JMP)

View File

@ -1,5 +1,5 @@
/*
** $Id: lparser.c,v 1.97 2000/06/19 18:26:23 roberto Exp roberto $
** $Id: lparser.c,v 1.98 2000/06/21 18:13:56 roberto Exp roberto $
** LL(1) Parser and code generator for Lua
** See Copyright Notice in lua.h
*/
@ -152,19 +152,19 @@ static int checkname (LexState *ls) {
}
static void luaI_registerlocalvar (LexState *ls, TString *varname, int line) {
static void luaI_registerlocalvar (LexState *ls, TString *varname, int pc) {
FuncState *fs = ls->fs;
if (fs->debug) {
if (fs->f->debug) {
Proto *f = fs->f;
luaM_growvector(ls->L, f->locvars, fs->nvars, 1, LocVar, "", MAX_INT);
f->locvars[fs->nvars].varname = varname;
f->locvars[fs->nvars].line = line;
f->locvars[fs->nvars].pc = pc;
fs->nvars++;
}
}
static void store_localvar (LexState *ls, TString *name, int n) {
static void new_localvar (LexState *ls, TString *name, int n) {
FuncState *fs = ls->fs;
luaX_checklimit(ls, fs->nlocalvar+n+1, MAXLOCALS, "local variables");
fs->localvar[fs->nlocalvar+n] = name;
@ -172,27 +172,27 @@ static void store_localvar (LexState *ls, TString *name, int n) {
static void adjustlocalvars (LexState *ls, int nvars) {
int line = ls->fs->lastsetline;
FuncState *fs = ls->fs;
int i;
/* `pc' is first opcode where variable is already active */
for (i=fs->nlocalvar; i<fs->nlocalvar+nvars; i++)
luaI_registerlocalvar(ls, fs->localvar[i], line);
luaI_registerlocalvar(ls, fs->localvar[i], fs->pc);
fs->nlocalvar += nvars;
}
static void removelocalvars (LexState *ls, int nvars) {
int line = ls->fs->lastsetline;
FuncState *fs = ls->fs;
int i;
/* `pc' is first opcode where variable is already dead */
for (i=0;i<nvars;i++)
luaI_registerlocalvar(ls, NULL, line);
ls->fs->nlocalvar -= nvars;
luaI_registerlocalvar(ls, NULL, fs->pc);
fs->nlocalvar -= nvars;
}
static void add_localvar (LexState *ls, const char *name) {
store_localvar(ls, luaS_newfixed(ls->L, name), 0);
adjustlocalvars(ls, 1);
static void new_localvarstr (LexState *ls, const char *name, int n) {
new_localvar(ls, luaS_newfixed(ls->L, name), n);
}
@ -277,8 +277,10 @@ static void code_params (LexState *ls, int nparams, int dots) {
luaX_checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters");
fs->f->numparams = fs->nlocalvar; /* `self' could be there already */
fs->f->is_vararg = dots;
if (dots)
add_localvar(ls, "arg");
if (dots) {
new_localvarstr(ls, "arg", 0);
adjustlocalvars(ls, 1);
}
luaK_deltastack(fs, fs->nlocalvar); /* count parameters in the stack */
}
@ -320,7 +322,6 @@ static void open_func (LexState *ls, FuncState *fs) {
fs->stacklevel = 0;
fs->nlocalvar = 0;
fs->nupvalues = 0;
fs->lastsetline = 0;
fs->bl = NULL;
fs->f = f;
f->source = ls->source;
@ -358,7 +359,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 */
funcstate.f->debug = L->debug; /* previous `next' may scan a pragma */
chunk(&lexstate);
check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");
close_func(&lexstate);
@ -821,22 +822,23 @@ static void repeatstat (LexState *ls, int line) {
}
static void forbody (LexState *ls, OpCode prepfor, OpCode loopfor) {
static void forbody (LexState *ls, int nvar, OpCode prepfor, OpCode loopfor) {
/* forbody -> DO block END */
FuncState *fs = ls->fs;
int prep = luaK_code1(fs, prepfor, NO_JUMP);
int blockinit = luaK_getlabel(fs);
check(ls, TK_DO);
adjustlocalvars(ls, nvar); /* scope for control variables */
block(ls);
luaK_patchlist(fs, prep, luaK_getlabel(fs));
luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit);
removelocalvars(ls, nvar);
}
static void fornum (LexState *ls, TString *varname) {
/* fornum -> NAME = exp1,exp1[,exp1] forbody */
FuncState *fs = ls->fs;
store_localvar(ls, varname, 0);
check(ls, '=');
exp1(ls); /* initial value */
check(ls, ',');
@ -845,11 +847,10 @@ static void fornum (LexState *ls, TString *varname) {
exp1(ls); /* optional step */
else
luaK_code1(fs, OP_PUSHINT, 1); /* default step */
adjustlocalvars(ls, 1); /* scope for control variables */
add_localvar(ls, "*limit*");
add_localvar(ls, "*count*");
forbody(ls, OP_FORPREP, OP_FORLOOP);
removelocalvars(ls, 3);
new_localvar(ls, varname, 0);
new_localvarstr(ls, "*limit*", 1);
new_localvarstr(ls, "*step*", 2);
forbody(ls, 3, OP_FORPREP, OP_FORLOOP);
}
@ -864,13 +865,11 @@ static void forlist (LexState *ls, TString *indexname) {
"`in' expected");
next(ls); /* skip `in' */
exp1(ls); /* table */
add_localvar(ls, "*table*");
add_localvar(ls, "*counter*");
store_localvar(ls, indexname, 0);
store_localvar(ls, valname, 1);
adjustlocalvars(ls, 2); /* scope for control variable */
forbody(ls, OP_LFORPREP, OP_LFORLOOP);
removelocalvars(ls, 4);
new_localvarstr(ls, "*table*", 0);
new_localvarstr(ls, "*counter*", 1);
new_localvar(ls, indexname, 2);
new_localvar(ls, valname, 3);
forbody(ls, 4, OP_LFORPREP, OP_LFORLOOP);
}
@ -931,7 +930,7 @@ static void localstat (LexState *ls) {
int nexps;
do {
next(ls); /* skip LOCAL or ',' */
store_localvar(ls, str_checkname(ls), nvars++);
new_localvar(ls, str_checkname(ls), nvars++);
} while (ls->t.token == ',');
if (optional(ls, '='))
nexps = explist1(ls);
@ -1072,7 +1071,7 @@ static void parlist (LexState *ls) {
do {
switch (ls->t.token) {
case TK_DOTS: next(ls); dots = 1; break;
case TK_NAME: store_localvar(ls, str_checkname(ls), nparams++); break;
case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break;
default: luaK_error(ls, "<name> or `...' expected");
}
} while (!dots && optional(ls, ','));
@ -1086,10 +1085,12 @@ 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;
new_fs.f->debug = ls->L->debug;
check(ls, '(');
if (needself)
add_localvar(ls, "self");
if (needself) {
new_localvarstr(ls, "self", 0);
adjustlocalvars(ls, 1);
}
parlist(ls);
check(ls, ')');
chunk(ls);

View File

@ -1,5 +1,5 @@
/*
** $Id: lparser.h,v 1.17 2000/05/25 18:26:42 roberto Exp roberto $
** $Id: lparser.h,v 1.18 2000/06/21 18:13:56 roberto Exp roberto $
** LL(1) Parser and code generator for Lua
** See Copyright Notice in lua.h
*/
@ -48,8 +48,6 @@ typedef struct FuncState {
int nlocalvar; /* number of active local variables */
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 */

View File

@ -1,5 +1,5 @@
/*
** $Id: ltests.c,v 1.25 2000/06/12 13:52:05 roberto Exp roberto $
** $Id: ltests.c,v 1.26 2000/06/21 17:05:49 roberto Exp roberto $
** Internal Module for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/
@ -58,7 +58,7 @@ static const char *const instrname[NUM_OPCODES] = {
"ADD", "ADDI", "SUB", "MULT", "DIV", "POW", "CONCAT", "MINUS", "NOT",
"JMPNE", "JMPEQ", "JMPLT", "JMPLE", "JMPGT", "JMPGE", "JMPT", "JMPF",
"JMPONT", "JMPONF", "JMP", "PUSHNILJMP", "FORPREP", "FORLOOP", "LFORPREP",
"LFORLOOP", "CLOSURE", "SETLINE"
"LFORLOOP", "CLOSURE"
};

View File

@ -1,5 +1,5 @@
/*
** $Id: lundump.c,v 1.21 2000/05/08 19:32:53 roberto Exp roberto $
** $Id: lundump.c,v 1.22 2000/06/12 13:52:05 roberto Exp roberto $
** load bytecodes from files
** See Copyright Notice in lua.h
*/
@ -93,7 +93,7 @@ static TString* LoadString (lua_State* L, ZIO* Z)
static void SwapCode (lua_State* L, Instruction* code, int size, ZIO* Z)
{
unsigned char* p;
int c;
unsigned char c;
if (sizeof(Instruction)==4)
while (size--)
{
@ -138,10 +138,10 @@ static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z)
tf->locvars=luaM_newvector(L,n+1,LocVar);
for (i=0; i<n; i++)
{
tf->locvars[i].line=LoadInt(L,Z,"too many lines");
tf->locvars[i].pc=LoadInt(L,Z,"too many lines");
tf->locvars[i].varname=LoadString(L,Z);
}
tf->locvars[i].line=-1; /* flag end of vector */
tf->locvars[i].pc=-1; /* flag end of vector */
tf->locvars[i].varname=NULL;
}

100
lvm.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lvm.c,v 1.115 2000/06/12 13:52:05 roberto Exp roberto $
** $Id: lvm.c,v 1.116 2000/06/19 18:04:41 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@ -67,6 +67,23 @@ int luaV_tostring (lua_State *L, TObject *obj) { /* LUA_NUMBER */
}
static void traceexec (lua_State *L, StkId base, int pc) {
CallInfo *ci = infovalue(base-1);
int oldpc = ci->pc;
pc--; /* pc has been already incremented */
ci->pc = pc;
if (L->linehook && ci->func->f.l->debug) {
int *lines = ci->func->f.l->lines;
LUA_ASSERT(L, lines, "must have debug information");
/* calls linehook when jumps back (a loop) or enters a new line */
if (pc <= oldpc || lines[pc] != ci->line) {
ci->line = lines[pc];
luaD_lineHook(L, base-2, lines[pc]);
}
}
}
static Closure *luaV_closure (lua_State *L, lua_Type t, int nelems) {
Closure *c = luaF_newclosure(L, nelems);
L->top -= nelems;
@ -226,13 +243,6 @@ static void call_arith (lua_State *L, StkId top, IMS event) {
}
static void addK (lua_State *L, StkId top, int k) {
ttype(top) = TAG_NUMBER;
nvalue(top) = (Number)k;
call_arith(L, top+1, IM_ADD);
}
static int luaV_strcomp (const TString *ls, const TString *rs) {
const char *l = ls->str;
size_t ll = ls->u.s.len;
@ -338,6 +348,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
StkId top; /* keep top local, for performance */
const Instruction *pc = tf->code;
TString **kstr = tf->kstr;
int debug = tf->debug;
luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK);
if (tf->is_vararg) { /* varargs? */
adjust_varargs(L, base, tf->numparams);
@ -346,8 +357,13 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
else
luaD_adjusttop(L, base, tf->numparams);
top = L->top;
/* main loop of interpreter */
for (;;) {
Instruction i = *pc++;
if (debug) {
L->top = top;
traceexec(L, base, pc - tf->code);
}
switch (GET_OPCODE(i)) {
case OP_END:
@ -499,8 +515,11 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
break;
case OP_ADDI:
if (tonumber(top-1))
addK(L, top, GETARG_S(i));
if (tonumber(top-1)) {
ttype(top) = TAG_NUMBER;
nvalue(top) = (Number)GETARG_S(i);
call_arith(L, top+1, IM_ADD);
}
else
nvalue(top-1) += (Number)GETARG_S(i);
break;
@ -622,35 +641,44 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
lua_error(L, "`for' limit must be a number");
if (tonumber(top-3))
lua_error(L, "`for' initial value must be a number");
/* number of steps */
nvalue(top-2) = (nvalue(top-2)-nvalue(top-3))/nvalue(top-1);
nvalue(top-3) -= nvalue(top-1); /* to be undone by first FORLOOP */
pc += GETARG_S(i);
if (nvalue(top-1) > 0 ?
nvalue(top-3) > nvalue(top-2) :
nvalue(top-3) < nvalue(top-2)) { /* `empty' loop? */
top -= 3; /* remove control variables */
pc += GETARG_S(i)+1; /* jump to loop end */
}
break;
case OP_FORLOOP: {
LUA_ASSERT(L, ttype(top-1) == TAG_NUMBER, "invalid step");
LUA_ASSERT(L, ttype(top-2) == TAG_NUMBER, "invalid count");
if (nvalue(top-2) < 0)
LUA_ASSERT(L, ttype(top-2) == TAG_NUMBER, "invalid limit");
if (ttype(top-3) != TAG_NUMBER)
lua_error(L, "`for' index must be a number");
nvalue(top-3) += nvalue(top-1); /* increment index */
if (nvalue(top-1) > 0 ?
nvalue(top-3) > nvalue(top-2) :
nvalue(top-3) < nvalue(top-2))
top -= 3; /* end loop: remove control variables */
else {
nvalue(top-2)--; /* decrement count */
if (ttype(top-3) != TAG_NUMBER)
lua_error(L, "`for' index must be a number");
nvalue(top-3) += nvalue(top-1); /* increment index */
pc += GETARG_S(i);
}
else
pc += GETARG_S(i); /* repeat loop */
break;
}
case OP_LFORPREP: {
if (ttype(top-1) != TAG_TABLE)
lua_error(L, "`for' table must be a table");
top += 3; /* counter + index,value */
ttype(top-3) = TAG_NUMBER;
nvalue(top-3) = 0.0; /* counter */
ttype(top-2) = ttype(top-1) = TAG_NIL;
pc += GETARG_S(i);
top++; /* counter */
L->top = top;
ttype(top-1) = TAG_NUMBER;
nvalue(top-1) = (Number)luaA_next(L, hvalue(top-2), 0); /* counter */
if (nvalue(top-1) == 0) { /* `empty' loop? */
top -= 2; /* remove table and counter */
pc += GETARG_S(i)+1; /* jump to loop end */
}
else {
top += 2; /* index,value */
LUA_ASSERT(L, top==L->top, "bad top");
}
break;
}
@ -678,22 +706,6 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
luaC_checkGC(L);
break;
case OP_SETLINE:
if ((base-1)->ttype != TAG_LINE) {
/* open space for LINE value */
int n = top-base;
while (n--) base[n+1] = base[n];
base++;
top++;
(base-1)->ttype = TAG_LINE;
}
(base-1)->value.i = GETARG_U(i);
if (L->linehook) {
L->top = top;
luaD_lineHook(L, base-2, GETARG_U(i));
}
break;
}
}
}