mirror of https://github.com/rusefi/lua.git
new version of debug system
This commit is contained in:
parent
b69e712713
commit
afef009fce
19
lcode.c
19
lcode.c
|
@ -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 */
|
||||
};
|
||||
|
|
74
ldebug.c
74
ldebug.c
|
@ -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
8
ldo.c
|
@ -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: {
|
||||
|
|
9
lfunc.c
9
lfunc.c
|
@ -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;
|
||||
|
|
5
lfunc.h
5
lfunc.h
|
@ -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
15
lgc.c
|
@ -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
5
lmem.c
|
@ -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) */
|
||||
|
|
|
@ -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"
|
||||
};
|
||||
|
||||
|
||||
|
|
24
lobject.h
24
lobject.h
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
73
lparser.c
73
lparser.c
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
4
ltests.c
4
ltests.c
|
@ -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"
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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
100
lvm.c
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue