no more code checking
This commit is contained in:
127
ldebug.c
127
ldebug.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldebug.c,v 2.47 2009/04/17 22:00:01 roberto Exp roberto $
|
** $Id: ldebug.c,v 2.48 2009/04/27 18:58:31 roberto Exp roberto $
|
||||||
** Debug Interface
|
** Debug Interface
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -264,89 +264,33 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** {======================================================
|
** {======================================================
|
||||||
** Symbolic Execution and code checker
|
** Symbolic Execution
|
||||||
** =======================================================
|
** =======================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define check(x) if (!(x)) return 0;
|
|
||||||
|
|
||||||
#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int precheck (const Proto *pt) {
|
|
||||||
check(pt->maxstacksize <= MAXSTACK);
|
|
||||||
check(pt->numparams <= pt->maxstacksize);
|
|
||||||
check(pt->sizeupvalues == pt->nups || pt->sizeupvalues == 0);
|
|
||||||
check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
|
|
||||||
check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1])
|
|
||||||
|
|
||||||
int luaG_checkopenop (Instruction i) {
|
|
||||||
switch (GET_OPCODE(i)) {
|
|
||||||
case OP_CALL:
|
|
||||||
case OP_TAILCALL:
|
|
||||||
case OP_RETURN:
|
|
||||||
case OP_SETLIST: {
|
|
||||||
check(GETARG_B(i) == 0);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
default: return 0; /* invalid instruction after an open call */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) {
|
|
||||||
switch (mode) {
|
|
||||||
case OpArgN: check(r == 0); break;
|
|
||||||
case OpArgU: break;
|
|
||||||
case OpArgR: checkreg(pt, r); break;
|
|
||||||
case OpArgK:
|
|
||||||
check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static Instruction symbexec (const Proto *pt, int lastpc, int reg) {
|
static Instruction symbexec (const Proto *pt, int lastpc, int reg) {
|
||||||
int pc;
|
int pc;
|
||||||
int last; /* stores position of last instruction that changed `reg' */
|
int last; /* stores position of last instruction that changed `reg' */
|
||||||
last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */
|
last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */
|
||||||
check(precheck(pt));
|
|
||||||
for (pc = 0; pc < lastpc; pc++) {
|
for (pc = 0; pc < lastpc; pc++) {
|
||||||
Instruction i = pt->code[pc];
|
Instruction i = pt->code[pc];
|
||||||
OpCode op = GET_OPCODE(i);
|
OpCode op = GET_OPCODE(i);
|
||||||
int a = GETARG_A(i);
|
int a = GETARG_A(i);
|
||||||
int b = 0;
|
int b = 0;
|
||||||
int c = 0;
|
int c = 0;
|
||||||
check(op < NUM_OPCODES);
|
|
||||||
switch (getOpMode(op)) {
|
switch (getOpMode(op)) {
|
||||||
case iABC: {
|
case iABC: {
|
||||||
checkreg(pt, a);
|
|
||||||
b = GETARG_B(i);
|
b = GETARG_B(i);
|
||||||
c = GETARG_C(i);
|
c = GETARG_C(i);
|
||||||
check(checkArgMode(pt, b, getBMode(op)));
|
|
||||||
check(checkArgMode(pt, c, getCMode(op)));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case iABx: {
|
case iABx: {
|
||||||
checkreg(pt, a);
|
|
||||||
b = GETARG_Bx(i);
|
b = GETARG_Bx(i);
|
||||||
if (getBMode(op) == OpArgK) check(b < pt->sizek);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case iAsBx: {
|
case iAsBx: {
|
||||||
checkreg(pt, a);
|
|
||||||
b = GETARG_sBx(i);
|
b = GETARG_sBx(i);
|
||||||
if (getBMode(op) == OpArgR) {
|
|
||||||
int dest = pc+1+b;
|
|
||||||
check(0 <= dest && dest < pt->sizecode);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case iAx: break;
|
case iAx: break;
|
||||||
@@ -354,49 +298,23 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) {
|
|||||||
if (testAMode(op)) {
|
if (testAMode(op)) {
|
||||||
if (a == reg) last = pc; /* change register `a' */
|
if (a == reg) last = pc; /* change register `a' */
|
||||||
}
|
}
|
||||||
if (testTMode(op))
|
|
||||||
check(GET_OPCODE(pt->code[pc+1]) == OP_JMP);
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case OP_LOADBOOL: {
|
|
||||||
check(c == 0 || pc+2 < pt->sizecode); /* check its jump */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OP_LOADNIL: {
|
case OP_LOADNIL: {
|
||||||
if (a <= reg && reg <= b)
|
if (a <= reg && reg <= b)
|
||||||
last = pc; /* set registers from `a' to `b' */
|
last = pc; /* set registers from `a' to `b' */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_GETUPVAL:
|
|
||||||
case OP_SETUPVAL: {
|
|
||||||
check(b < pt->nups);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OP_GETGLOBAL:
|
|
||||||
case OP_SETGLOBAL: {
|
|
||||||
check(ttisstring(&pt->k[b]));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OP_SELF: {
|
case OP_SELF: {
|
||||||
checkreg(pt, a+1);
|
|
||||||
if (reg == a+1) last = pc;
|
if (reg == a+1) last = pc;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_CONCAT: {
|
|
||||||
check(b < c); /* at least two operands */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OP_TFORCALL: {
|
case OP_TFORCALL: {
|
||||||
check(c >= 1); /* at least one result (control variable) */
|
|
||||||
checkreg(pt, a+2+c); /* space for results */
|
|
||||||
check(GET_OPCODE(pt->code[pc+1]) == OP_TFORLOOP);
|
|
||||||
if (reg >= a+2) last = pc; /* affect all regs above its base */
|
if (reg >= a+2) last = pc; /* affect all regs above its base */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_TFORLOOP:
|
case OP_TFORLOOP:
|
||||||
case OP_FORLOOP:
|
case OP_FORLOOP:
|
||||||
case OP_FORPREP:
|
case OP_FORPREP:
|
||||||
checkreg(pt, a+3);
|
|
||||||
/* go through */
|
|
||||||
case OP_JMP: {
|
case OP_JMP: {
|
||||||
int dest = pc+1+b;
|
int dest = pc+1+b;
|
||||||
/* not full check and jump is forward and do not skip `lastpc'? */
|
/* not full check and jump is forward and do not skip `lastpc'? */
|
||||||
@@ -406,46 +324,16 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) {
|
|||||||
}
|
}
|
||||||
case OP_CALL:
|
case OP_CALL:
|
||||||
case OP_TAILCALL: {
|
case OP_TAILCALL: {
|
||||||
if (b != 0) {
|
|
||||||
checkreg(pt, a+b-1);
|
|
||||||
}
|
|
||||||
c--; /* c = num. returns */
|
|
||||||
if (c == LUA_MULTRET) {
|
|
||||||
check(checkopenop(pt, pc));
|
|
||||||
}
|
|
||||||
else if (c != 0)
|
|
||||||
checkreg(pt, a+c-1);
|
|
||||||
if (reg >= a) last = pc; /* affect all registers above base */
|
if (reg >= a) last = pc; /* affect all registers above base */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_RETURN: {
|
|
||||||
b--; /* b = num. returns */
|
|
||||||
if (b > 0) checkreg(pt, a+b-1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OP_SETLIST: {
|
|
||||||
if (b > 0) checkreg(pt, a + b);
|
|
||||||
if (c == 0) check(GET_OPCODE(pt->code[pc + 1]) == OP_EXTRAARG);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OP_CLOSURE: {
|
case OP_CLOSURE: {
|
||||||
int nup, j;
|
int nup = pt->p[b]->nups;
|
||||||
check(b < pt->sizep);
|
pc += nup; /* do not 'execute' pseudo-instructions */
|
||||||
nup = pt->p[b]->nups;
|
|
||||||
check(pc + nup < pt->sizecode);
|
|
||||||
for (j = 1; j <= nup; j++) {
|
|
||||||
OpCode op1 = GET_OPCODE(pt->code[pc + j]);
|
|
||||||
check(op1 == OP_GETUPVAL || op1 == OP_MOVE);
|
|
||||||
}
|
|
||||||
if (reg != NO_REG) /* tracing? */
|
|
||||||
pc += nup; /* do not 'execute' these pseudo-instructions */
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_VARARG: {
|
case OP_VARARG: {
|
||||||
check(pt->is_vararg);
|
b--; /* ??? */
|
||||||
b--;
|
|
||||||
if (b == LUA_MULTRET) check(checkopenop(pt, pc));
|
|
||||||
checkreg(pt, a+b-1);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: break;
|
default: break;
|
||||||
@@ -460,11 +348,6 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) {
|
|||||||
/* }====================================================== */
|
/* }====================================================== */
|
||||||
|
|
||||||
|
|
||||||
int luaG_checkcode (const Proto *pt) {
|
|
||||||
return (symbexec(pt, pt->sizecode, NO_REG) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static const char *kname (Proto *p, int c) {
|
static const char *kname (Proto *p, int c) {
|
||||||
if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
|
if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
|
||||||
return svalue(&p->k[INDEXK(c)]);
|
return svalue(&p->k[INDEXK(c)]);
|
||||||
|
|||||||
4
ldebug.h
4
ldebug.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldebug.h,v 2.2 2004/06/02 19:07:55 roberto Exp roberto $
|
** $Id: ldebug.h,v 2.3 2005/04/25 19:24:10 roberto Exp roberto $
|
||||||
** Auxiliary functions from Debug Interface module
|
** Auxiliary functions from Debug Interface module
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -27,7 +27,5 @@ LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1,
|
|||||||
const TValue *p2);
|
const TValue *p2);
|
||||||
LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...);
|
LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...);
|
||||||
LUAI_FUNC void luaG_errormsg (lua_State *L);
|
LUAI_FUNC void luaG_errormsg (lua_State *L);
|
||||||
LUAI_FUNC int luaG_checkcode (const Proto *pt);
|
|
||||||
LUAI_FUNC int luaG_checkopenop (Instruction i);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lparser.c,v 2.60 2008/10/30 15:39:30 roberto Exp roberto $
|
** $Id: lparser.c,v 2.61 2009/03/26 12:56:38 roberto Exp roberto $
|
||||||
** Lua Parser
|
** Lua Parser
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -376,7 +376,6 @@ static void close_func (LexState *ls) {
|
|||||||
f->sizelocvars = fs->nlocvars;
|
f->sizelocvars = fs->nlocvars;
|
||||||
luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
|
luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
|
||||||
f->sizeupvalues = f->nups;
|
f->sizeupvalues = f->nups;
|
||||||
lua_assert(luaG_checkcode(f));
|
|
||||||
lua_assert(fs->bl == NULL);
|
lua_assert(fs->bl == NULL);
|
||||||
ls->fs = fs->prev;
|
ls->fs = fs->prev;
|
||||||
L->top -= 2; /* remove table and prototype from the stack */
|
L->top -= 2; /* remove table and prototype from the stack */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lundump.c,v 2.8 2006/09/11 14:07:24 roberto Exp roberto $
|
** $Id: lundump.c,v 2.9 2008/04/07 18:44:23 roberto Exp roberto $
|
||||||
** load precompiled Lua chunks
|
** load precompiled Lua chunks
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -173,7 +173,6 @@ static Proto* LoadFunction(LoadState* S, TString* p)
|
|||||||
LoadCode(S,f);
|
LoadCode(S,f);
|
||||||
LoadConstants(S,f);
|
LoadConstants(S,f);
|
||||||
LoadDebug(S,f);
|
LoadDebug(S,f);
|
||||||
IF (!luaG_checkcode(f), "bad code");
|
|
||||||
S->L->top--;
|
S->L->top--;
|
||||||
G(S->L)->nCcalls--;
|
G(S->L)->nCcalls--;
|
||||||
return f;
|
return f;
|
||||||
|
|||||||
3
lvm.c
3
lvm.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lvm.c,v 2.85 2009/04/17 14:28:06 roberto Exp roberto $
|
** $Id: lvm.c,v 2.86 2009/04/17 22:00:01 roberto Exp roberto $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -468,7 +468,6 @@ void luaV_execute (lua_State *L) {
|
|||||||
ra = RA(i);
|
ra = RA(i);
|
||||||
lua_assert(base == ci->base && base == L->base);
|
lua_assert(base == ci->base && base == L->base);
|
||||||
lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
|
lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
|
||||||
lua_assert(L->top == ci->top || luaG_checkopenop(i));
|
|
||||||
switch (GET_OPCODE(i)) {
|
switch (GET_OPCODE(i)) {
|
||||||
case OP_MOVE: {
|
case OP_MOVE: {
|
||||||
setobjs2s(L, ra, RB(i));
|
setobjs2s(L, ra, RB(i));
|
||||||
|
|||||||
Reference in New Issue
Block a user