diff options
-rw-r--r-- | ldebug.c | 95 |
1 files changed, 49 insertions, 46 deletions
@@ -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); |