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