aboutsummaryrefslogtreecommitdiff
path: root/ldebug.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-02-09 16:37:33 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-02-09 16:37:33 -0200
commitc81404cae57e40d0fa5dd1eb48237ca7e77c4d89 (patch)
tree368a1ab4b5a27b5fbc5c8137d28586ea605ac97b /ldebug.c
parentb6ce59043396110b95de4d772b4541d65661f62e (diff)
downloadlua-c81404cae57e40d0fa5dd1eb48237ca7e77c4d89.tar.gz
lua-c81404cae57e40d0fa5dd1eb48237ca7e77c4d89.tar.bz2
lua-c81404cae57e40d0fa5dd1eb48237ca7e77c4d89.zip
first version of code verification
Diffstat (limited to 'ldebug.c')
-rw-r--r--ldebug.c169
1 files changed, 123 insertions, 46 deletions
diff --git a/ldebug.c b/ldebug.c
index a54b293c..1c9546c4 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.59 2001/02/02 15:13:05 roberto Exp roberto $ 2** $Id: ldebug.c,v 1.60 2001/02/07 18:13:49 roberto Exp roberto $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -106,20 +106,20 @@ int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) {
106 return -1; /* no line info or function is not active */ 106 return -1; /* no line info or function is not active */
107 refi = prefi ? *prefi : 0; 107 refi = prefi ? *prefi : 0;
108 if (lineinfo[refi] < 0) 108 if (lineinfo[refi] < 0)
109 refline += -lineinfo[refi++]; 109 refline += -lineinfo[refi++];
110 lua_assert(lineinfo[refi] >= 0); 110 lua_assert(lineinfo[refi] >= 0);
111 while (lineinfo[refi] > pc) { 111 while (lineinfo[refi] > pc) {
112 refline--; 112 refline--;
113 refi--; 113 refi--;
114 if (lineinfo[refi] < 0) 114 if (lineinfo[refi] < 0)
115 refline -= -lineinfo[refi--]; 115 refline -= -lineinfo[refi--];
116 lua_assert(lineinfo[refi] >= 0); 116 lua_assert(lineinfo[refi] >= 0);
117 } 117 }
118 for (;;) { 118 for (;;) {
119 int nextline = refline + 1; 119 int nextline = refline + 1;
120 int nextref = refi + 1; 120 int nextref = refi + 1;
121 if (lineinfo[nextref] < 0) 121 if (lineinfo[nextref] < 0)
122 nextline += -lineinfo[nextref++]; 122 nextline += -lineinfo[nextref++];
123 lua_assert(lineinfo[nextref] >= 0); 123 lua_assert(lineinfo[nextref] >= 0);
124 if (lineinfo[nextref] > pc) 124 if (lineinfo[nextref] > pc)
125 break; 125 break;
@@ -248,7 +248,7 @@ static const char *travglobals (lua_State *L, const TObject *o) {
248 int i; 248 int i;
249 for (i=0; i<g->size; i++) { 249 for (i=0; i<g->size; i++) {
250 if (luaO_equalObj(o, val(node(g, i))) && 250 if (luaO_equalObj(o, val(node(g, i))) &&
251 ttype_key(node(g, i)) == LUA_TSTRING) 251 ttype_key(node(g, i)) == LUA_TSTRING)
252 return tsvalue_key(node(g, i))->str; 252 return tsvalue_key(node(g, i))->str;
253 } 253 }
254 return NULL; 254 return NULL;
@@ -321,12 +321,8 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
321*/ 321*/
322 322
323 323
324static int pushpc (int *stack, int pc, int top, int n) { 324#define check(x) if (!(x)) return 0;
325 while (n--) 325#define checkjump(pt, pc) check(0 <= (pc) && (pc) < (pt)->sizecode)
326 stack[top++] = pc-1;
327 return top;
328}
329
330 326
331static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) { 327static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) {
332 int stack[MAXSTACK]; /* stores last instruction that changed a stack entry */ 328 int stack[MAXSTACK]; /* stores last instruction that changed a stack entry */
@@ -335,78 +331,159 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) {
335 int pc = 0; 331 int pc = 0;
336 if (pt->is_vararg) /* varargs? */ 332 if (pt->is_vararg) /* varargs? */
337 top++; /* `arg' */ 333 top++; /* `arg' */
334 check (top <= pt->maxstacksize && pt->maxstacksize <= MAXSTACK);
338 while (pc < lastpc) { 335 while (pc < lastpc) {
339 const Instruction i = code[pc++]; 336 const Instruction i = code[pc++];
340 lua_assert(0 <= top && top <= pt->maxstacksize); 337 OpCode op = GET_OPCODE(i);
341 switch (GET_OPCODE(i)) { 338 int push = (int)luaK_opproperties[op].push;
339 int pop = (int)luaK_opproperties[op].pop;
340 int arg1 = 0;
341 int arg2 = 0;
342 switch ((enum Mode)luaK_opproperties[op].mode) {
343 case iO: break;
344 case iU: arg1 = GETARG_U(i); break;
345 case iS: arg1 = GETARG_S(i); break;
346 case iAB: arg1 = GETARG_A(i); arg2 = GETARG_B(i); break;
347 }
348 check(0 <= top && top <= pt->maxstacksize);
349 switch (op) {
342 case OP_RETURN: { 350 case OP_RETURN: {
343 lua_assert(top >= GETARG_U(i)); 351 pop = top-arg1;
344 top = GETARG_U(i);
345 break; 352 break;
346 } 353 }
347 case OP_TAILCALL: { 354 case OP_CALL: {
348 lua_assert(top >= GETARG_A(i)); 355 if (arg2 == MULT_RET) arg2 = 1;
349 top = GETARG_B(i); 356 pop = top-arg1;
357 push = arg2;
350 break; 358 break;
351 } 359 }
352 case OP_CALL: { 360 case OP_TAILCALL: {
353 int nresults = GETARG_B(i); 361 check(arg1 <= top);
354 if (nresults == MULT_RET) nresults = 1; 362 pop = top-arg2;
355 lua_assert(top >= GETARG_A(i));
356 top = pushpc(stack, pc, GETARG_A(i), nresults);
357 break; 363 break;
358 } 364 }
359 case OP_PUSHNIL: { 365 case OP_PUSHNIL: {
360 top = pushpc(stack, pc, top, GETARG_U(i)); 366 check(arg1 > 0);
367 push = arg1;
361 break; 368 break;
362 } 369 }
363 case OP_POP: { 370 case OP_POP: {
364 top -= GETARG_U(i); 371 pop = arg1;
372 break;
373 }
374 case OP_PUSHSTRING:
375 case OP_GETGLOBAL:
376 case OP_GETDOTTED:
377 case OP_PUSHSELF:
378 case OP_SETGLOBAL: {
379 check(arg1 < pt->sizekstr);
380 break;
381 }
382 case OP_PUSHNUM:
383 case OP_PUSHNEGNUM: {
384 check(arg1 < pt->sizeknum);
385 break;
386 }
387 case OP_PUSHUPVALUE: {
388 /* ?? */
389 break;
390 }
391 case OP_GETLOCAL:
392 case OP_GETINDEXED:
393 case OP_SETLOCAL: {
394 check(arg1 < top);
395 break;
396 }
397 case OP_SETTABLE: {
398 check(2 <= arg1 && arg1 <= top);
399 pop = arg2;
365 break; 400 break;
366 } 401 }
367 case OP_SETTABLE:
368 case OP_SETLIST: { 402 case OP_SETLIST: {
369 top -= GETARG_B(i); 403 pop = arg2;
404 check(top-pop >= 1); /* there must be a table below the list */
370 break; 405 break;
371 } 406 }
372 case OP_SETMAP: { 407 case OP_SETMAP: {
373 top -= 2*GETARG_U(i); 408 pop = 2*arg1;
409 check(top-pop >= 1);
374 break; 410 break;
375 } 411 }
376 case OP_CONCAT: { 412 case OP_CONCAT: {
377 top -= GETARG_U(i); 413 pop = arg1;
378 stack[top++] = pc-1;
379 break; 414 break;
380 } 415 }
381 case OP_CLOSURE: { 416 case OP_CLOSURE: {
382 top -= GETARG_B(i); 417 /* ?? */
383 stack[top++] = pc-1; 418 pop = arg2;
419 break;
420 }
421 case OP_JMPNE:
422 case OP_JMPEQ:
423 case OP_JMPLT:
424 case OP_JMPLE:
425 case OP_JMPGT:
426 case OP_JMPGE:
427 case OP_JMPT:
428 case OP_JMPF:
429 case OP_JMP:
430 case OP_FORLOOP:
431 case OP_LFORLOOP: {
432 checkjump(pt, pc+arg1);
433 break;
434 }
435 case OP_PUSHNILJMP: {
436 checkjump(pt, pc+1);
384 break; 437 break;
385 } 438 }
386 case OP_JMPONT: 439 case OP_JMPONT:
387 case OP_JMPONF: { 440 case OP_JMPONF: {
388 int newpc = pc + GETARG_S(i); 441 int newpc = pc + arg1;
389 /* jump is forward and do not skip `lastpc'? */ 442 checkjump(pt, newpc);
390 if (pc < newpc && newpc <= lastpc) { 443 /* jump is forward and do not skip `lastpc' and not full check? */
444 if (pc < newpc && newpc <= lastpc && stackpos >= 0) {
391 stack[top-1] = pc-1; /* value comes from `and'/`or' */ 445 stack[top-1] = pc-1; /* value comes from `and'/`or' */
392 pc = newpc; /* do the jump */ 446 pc = newpc; /* do the jump */
447 pop = 0; /* do not pop */
393 } 448 }
394 else
395 top--; /* do not jump; pop value */
396 break; 449 break;
397 } 450 }
398 default: { 451 case OP_FORPREP: {
399 OpCode op = GET_OPCODE(i); 452 check(top >= 3);
400 int push = (int)luaK_opproperties[op].push; 453 checkjump(pt, pc-arg1); /* jump is `negative' here */
401 int pop = (int)luaK_opproperties[op].pop; 454 break;
402 lua_assert(push != VD && pop != VD); 455 }
403 lua_assert(0 <= top-pop && top+push <= pt->maxstacksize); 456 case OP_LFORPREP: {
404 top -= pop; 457 check(top >= 1);
405 top = pushpc(stack, pc, top, push); 458 checkjump(pt, pc-arg1); /* jump is `negative' here */
459 break;
460 }
461 case OP_PUSHINT:
462 case OP_GETTABLE:
463 case OP_CREATETABLE:
464 case OP_ADD:
465 case OP_ADDI:
466 case OP_SUB:
467 case OP_MULT:
468 case OP_DIV:
469 case OP_POW:
470 case OP_MINUS:
471 case OP_NOT: {
472 break;
406 } 473 }
407 } 474 }
475 check(0 <= pop && 0 <= push);
476 check(0 <= top-pop && top+(push-pop) <= pt->maxstacksize);
477 top -= pop;
478 while (push--) stack[top++] = pc-1;
408 } 479 }
409 return code[stack[stackpos]]; 480 check(GET_OPCODE(code[pt->sizecode-1]) == OP_RETURN);
481 return (stackpos >= 0) ? code[stack[stackpos]] : 1;
482}
483
484
485int luaG_checkcode (const Proto *pt) {
486 return luaG_symbexec(pt, pt->sizecode-1, -1);
410} 487}
411 488
412 489