Browse Source

better strucuture for code checker

v5-2
Roberto Ierusalimschy 24 years ago
parent
commit
27600fe87a
  1. 95
      ldebug.c

95
ldebug.c

@ -1,5 +1,5 @@
/*
** $Id: ldebug.c,v 1.62 2001/02/09 20:22:29 roberto Exp roberto $
** $Id: ldebug.c,v 1.63 2001/02/12 19:54:28 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
@ -320,10 +320,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
** =======================================================
*/
/*#define check(x) if (!(x)) return 0;*/
#define check(x) assert(x)
#define checkjump(pt, pc) check(0 <= (pc) && (pc) < (pt)->sizecode)
#define check(x) if (!(x)) return 0;
static int checklineinfo (const Proto *pt) {
@ -348,21 +345,39 @@ static int precheck (const Proto *pt) {
/* value for non-initialized entries in array stacklevel */
#define SL_EMPTY 255
#define checkstacklevel(sl,top,pc) \
if (sl) { if (sl[pc] == SL_EMPTY) sl[pc] = top; else check(sl[pc] == top); }
#define checkjump(pt,sl,top,pc) if (!checkjump_aux(pt,sl,top,pc)) return 0;
static int checkjump_aux (const Proto *pt, unsigned char *sl, int top, int pc) {
check(0 <= pc && pc < pt->sizecode);
if (sl == NULL) return 1; /* not full checking */
if (sl[pc] == SL_EMPTY)
sl[pc] = top;
else
check(sl[pc] == top);
return 1;
}
static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos,
unsigned char *sl) {
static Instruction luaG_symbexec (lua_State *L, const Proto *pt,
int lastpc, int stackpos) {
int stack[MAXSTACK]; /* stores last instruction that changed a stack entry */
const Instruction *code = pt->code;
int top = pt->numparams;
int pc = 0;
unsigned char *sl = NULL;
int top;
int pc;
if (stackpos < 0) { /* full check? */
int i;
sl = (unsigned char *)luaO_openspace(L, pt->sizecode);
for (i=0; i<pt->sizecode; i++) /* initialize stack-level array */
sl[i] = SL_EMPTY;
check(precheck(pt));
}
top = pt->numparams;
pc = 0;
if (pt->is_vararg) /* varargs? */
top++; /* `arg' */
checkstacklevel(sl, top, pc);
if (sl) sl[0] = top;
while (pc < lastpc) {
const Instruction i = code[pc++];
const Instruction i = pt->code[pc++];
OpCode op = GET_OPCODE(i);
int arg1 = 0;
int arg2 = 0;
@ -458,24 +473,17 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos,
case OP_JMPGT:
case OP_JMPGE:
case OP_JMPT:
case OP_JMPF: {
checkjump(pt, pc+arg1);
check(pop <= top);
checkstacklevel(sl, top-pop, pc+arg1);
case OP_JMPF:
case OP_JMP: {
checkjump(pt, sl, top-pop, pc+arg1);
break;
}
case OP_JMP:
case OP_FORLOOP:
case OP_LFORLOOP: {
checkjump(pt, pc+arg1);
checkstacklevel(sl, top, pc+arg1);
break;
}
case OP_LFORLOOP:
case OP_JMPONT:
case OP_JMPONF: {
int newpc = pc+arg1;
checkjump(pt, newpc);
checkstacklevel(sl, top, newpc);
checkjump(pt, sl, top, newpc);
/* jump is forward and do not skip `lastpc' and not full check? */
if (pc < newpc && newpc <= lastpc && stackpos >= 0) {
stack[top-1] = pc-1; /* value comes from `and'/`or' */
@ -485,23 +493,23 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos,
break;
}
case OP_PUSHNILJMP: {
check(GET_OPCODE(code[pc]) == OP_PUSHINT); /* only valid sequence */
check(GET_OPCODE(pt->code[pc]) == OP_PUSHINT); /* only valid sequence */
break;
}
case OP_FORPREP: {
int newpc = pc-arg1; /* jump is `negative' here */
int endfor = pc-arg1-1; /* jump is `negative' here */
check(top >= 3);
checkjump(pt, newpc);
check(GET_OPCODE(code[newpc-1]) == OP_FORLOOP);
check(GETARG_S(code[newpc-1]) == arg1);
checkjump(pt, sl, top+push, endfor);
check(GET_OPCODE(pt->code[endfor]) == OP_FORLOOP);
check(GETARG_S(pt->code[endfor]) == arg1);
break;
}
case OP_LFORPREP: {
int newpc = pc-arg1; /* jump is `negative' here */
int endfor = pc-arg1-1; /* jump is `negative' here */
check(top >= 1);
checkjump(pt, newpc);
check(GET_OPCODE(code[newpc-1]) == OP_LFORLOOP);
check(GETARG_S(code[newpc-1]) == arg1);
checkjump(pt, sl, top+push, endfor);
check(GET_OPCODE(pt->code[endfor]) == OP_LFORLOOP);
check(GETARG_S(pt->code[endfor]) == arg1);
break;
}
case OP_PUSHINT:
@ -521,18 +529,16 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos,
top -= pop;
check(0 <= top && top+push <= pt->maxstacksize);
while (push--) stack[top++] = pc-1;
checkstacklevel(sl, top, pc);
checkjump(pt, sl, top, pc);
}
return (stackpos >= 0) ? code[stack[stackpos]] : 1;
return (stackpos >= 0) ? pt->code[stack[stackpos]] : 1;
}
/* }====================================================== */
int luaG_checkcode (lua_State *L, const Proto *pt) {
unsigned char *sl = (unsigned char *)luaO_openspace(L, pt->sizecode);
int i;
for (i=0; i<pt->sizecode; i++)
sl[i] = SL_EMPTY;
return precheck(pt) && luaG_symbexec(pt, pt->sizecode-1, -1, sl);
return luaG_symbexec(L, pt, pt->sizecode-1, -1);
}
@ -544,7 +550,7 @@ static const char *getobjname (lua_State *L, StkId obj, const char **name) {
Proto *p = infovalue(func)->func->f.l;
int pc = currentpc(func);
int stackpos = obj - (func+1); /* func+1 == function base */
Instruction i = luaG_symbexec(p, pc, stackpos, NULL);
Instruction i = luaG_symbexec(L, p, pc, stackpos);
lua_assert(pc != -1);
switch (GET_OPCODE(i)) {
case OP_GETGLOBAL: {
@ -588,9 +594,6 @@ static const char *getfuncname (lua_State *L, StkId f, const char **name) {
}
/* }====================================================== */
void luaG_typeerror (lua_State *L, StkId o, const char *op) {
const char *name;
const char *kind = getobjname(L, o, &name);

Loading…
Cancel
Save