aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-02-16 15:58:27 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-02-16 15:58:27 -0200
commit27600fe87a6fafdfd4ddddeb390591fe749b480f (patch)
treec12caaf125626f871f64e961c7fc0c411b07be28
parentf8509668dcb0e2f3842b9d0a58232f3ffa2f96d6 (diff)
downloadlua-27600fe87a6fafdfd4ddddeb390591fe749b480f.tar.gz
lua-27600fe87a6fafdfd4ddddeb390591fe749b480f.tar.bz2
lua-27600fe87a6fafdfd4ddddeb390591fe749b480f.zip
better strucuture for code checker
-rw-r--r--ldebug.c95
1 files changed, 49 insertions, 46 deletions
diff --git a/ldebug.c b/ldebug.c
index b1248bb7..f27fa362 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.62 2001/02/09 20:22:29 roberto Exp roberto $ 2** $Id: ldebug.c,v 1.63 2001/02/12 19:54:28 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*/
@@ -320,10 +320,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
320** ======================================================= 320** =======================================================
321*/ 321*/
322 322
323 323#define check(x) if (!(x)) return 0;
324/*#define check(x) if (!(x)) return 0;*/
325#define check(x) assert(x)
326#define checkjump(pt, pc) check(0 <= (pc) && (pc) < (pt)->sizecode)
327 324
328 325
329static int checklineinfo (const Proto *pt) { 326static int checklineinfo (const Proto *pt) {
@@ -348,21 +345,39 @@ static int precheck (const Proto *pt) {
348/* value for non-initialized entries in array stacklevel */ 345/* value for non-initialized entries in array stacklevel */
349#define SL_EMPTY 255 346#define SL_EMPTY 255
350 347
351#define checkstacklevel(sl,top,pc) \ 348#define checkjump(pt,sl,top,pc) if (!checkjump_aux(pt,sl,top,pc)) return 0;
352 if (sl) { if (sl[pc] == SL_EMPTY) sl[pc] = top; else check(sl[pc] == top); }
353 349
350static int checkjump_aux (const Proto *pt, unsigned char *sl, int top, int pc) {
351 check(0 <= pc && pc < pt->sizecode);
352 if (sl == NULL) return 1; /* not full checking */
353 if (sl[pc] == SL_EMPTY)
354 sl[pc] = top;
355 else
356 check(sl[pc] == top);
357 return 1;
358}
354 359
355static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos, 360
356 unsigned char *sl) { 361static Instruction luaG_symbexec (lua_State *L, const Proto *pt,
362 int lastpc, int stackpos) {
357 int stack[MAXSTACK]; /* stores last instruction that changed a stack entry */ 363 int stack[MAXSTACK]; /* stores last instruction that changed a stack entry */
358 const Instruction *code = pt->code; 364 unsigned char *sl = NULL;
359 int top = pt->numparams; 365 int top;
360 int pc = 0; 366 int pc;
367 if (stackpos < 0) { /* full check? */
368 int i;
369 sl = (unsigned char *)luaO_openspace(L, pt->sizecode);
370 for (i=0; i<pt->sizecode; i++) /* initialize stack-level array */
371 sl[i] = SL_EMPTY;
372 check(precheck(pt));
373 }
374 top = pt->numparams;
375 pc = 0;
361 if (pt->is_vararg) /* varargs? */ 376 if (pt->is_vararg) /* varargs? */
362 top++; /* `arg' */ 377 top++; /* `arg' */
363 checkstacklevel(sl, top, pc); 378 if (sl) sl[0] = top;
364 while (pc < lastpc) { 379 while (pc < lastpc) {
365 const Instruction i = code[pc++]; 380 const Instruction i = pt->code[pc++];
366 OpCode op = GET_OPCODE(i); 381 OpCode op = GET_OPCODE(i);
367 int arg1 = 0; 382 int arg1 = 0;
368 int arg2 = 0; 383 int arg2 = 0;
@@ -458,24 +473,17 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos,
458 case OP_JMPGT: 473 case OP_JMPGT:
459 case OP_JMPGE: 474 case OP_JMPGE:
460 case OP_JMPT: 475 case OP_JMPT:
461 case OP_JMPF: { 476 case OP_JMPF:
462 checkjump(pt, pc+arg1); 477 case OP_JMP: {
463 check(pop <= top); 478 checkjump(pt, sl, top-pop, pc+arg1);
464 checkstacklevel(sl, top-pop, pc+arg1);
465 break; 479 break;
466 } 480 }
467 case OP_JMP:
468 case OP_FORLOOP: 481 case OP_FORLOOP:
469 case OP_LFORLOOP: { 482 case OP_LFORLOOP:
470 checkjump(pt, pc+arg1);
471 checkstacklevel(sl, top, pc+arg1);
472 break;
473 }
474 case OP_JMPONT: 483 case OP_JMPONT:
475 case OP_JMPONF: { 484 case OP_JMPONF: {
476 int newpc = pc+arg1; 485 int newpc = pc+arg1;
477 checkjump(pt, newpc); 486 checkjump(pt, sl, top, newpc);
478 checkstacklevel(sl, top, newpc);
479 /* jump is forward and do not skip `lastpc' and not full check? */ 487 /* jump is forward and do not skip `lastpc' and not full check? */
480 if (pc < newpc && newpc <= lastpc && stackpos >= 0) { 488 if (pc < newpc && newpc <= lastpc && stackpos >= 0) {
481 stack[top-1] = pc-1; /* value comes from `and'/`or' */ 489 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,
485 break; 493 break;
486 } 494 }
487 case OP_PUSHNILJMP: { 495 case OP_PUSHNILJMP: {
488 check(GET_OPCODE(code[pc]) == OP_PUSHINT); /* only valid sequence */ 496 check(GET_OPCODE(pt->code[pc]) == OP_PUSHINT); /* only valid sequence */
489 break; 497 break;
490 } 498 }
491 case OP_FORPREP: { 499 case OP_FORPREP: {
492 int newpc = pc-arg1; /* jump is `negative' here */ 500 int endfor = pc-arg1-1; /* jump is `negative' here */
493 check(top >= 3); 501 check(top >= 3);
494 checkjump(pt, newpc); 502 checkjump(pt, sl, top+push, endfor);
495 check(GET_OPCODE(code[newpc-1]) == OP_FORLOOP); 503 check(GET_OPCODE(pt->code[endfor]) == OP_FORLOOP);
496 check(GETARG_S(code[newpc-1]) == arg1); 504 check(GETARG_S(pt->code[endfor]) == arg1);
497 break; 505 break;
498 } 506 }
499 case OP_LFORPREP: { 507 case OP_LFORPREP: {
500 int newpc = pc-arg1; /* jump is `negative' here */ 508 int endfor = pc-arg1-1; /* jump is `negative' here */
501 check(top >= 1); 509 check(top >= 1);
502 checkjump(pt, newpc); 510 checkjump(pt, sl, top+push, endfor);
503 check(GET_OPCODE(code[newpc-1]) == OP_LFORLOOP); 511 check(GET_OPCODE(pt->code[endfor]) == OP_LFORLOOP);
504 check(GETARG_S(code[newpc-1]) == arg1); 512 check(GETARG_S(pt->code[endfor]) == arg1);
505 break; 513 break;
506 } 514 }
507 case OP_PUSHINT: 515 case OP_PUSHINT:
@@ -521,18 +529,16 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos,
521 top -= pop; 529 top -= pop;
522 check(0 <= top && top+push <= pt->maxstacksize); 530 check(0 <= top && top+push <= pt->maxstacksize);
523 while (push--) stack[top++] = pc-1; 531 while (push--) stack[top++] = pc-1;
524 checkstacklevel(sl, top, pc); 532 checkjump(pt, sl, top, pc);
525 } 533 }
526 return (stackpos >= 0) ? code[stack[stackpos]] : 1; 534 return (stackpos >= 0) ? pt->code[stack[stackpos]] : 1;
527} 535}
528 536
537/* }====================================================== */
538
529 539
530int luaG_checkcode (lua_State *L, const Proto *pt) { 540int luaG_checkcode (lua_State *L, const Proto *pt) {
531 unsigned char *sl = (unsigned char *)luaO_openspace(L, pt->sizecode); 541 return luaG_symbexec(L, pt, pt->sizecode-1, -1);
532 int i;
533 for (i=0; i<pt->sizecode; i++)
534 sl[i] = SL_EMPTY;
535 return precheck(pt) && luaG_symbexec(pt, pt->sizecode-1, -1, sl);
536} 542}
537 543
538 544
@@ -544,7 +550,7 @@ static const char *getobjname (lua_State *L, StkId obj, const char **name) {
544 Proto *p = infovalue(func)->func->f.l; 550 Proto *p = infovalue(func)->func->f.l;
545 int pc = currentpc(func); 551 int pc = currentpc(func);
546 int stackpos = obj - (func+1); /* func+1 == function base */ 552 int stackpos = obj - (func+1); /* func+1 == function base */
547 Instruction i = luaG_symbexec(p, pc, stackpos, NULL); 553 Instruction i = luaG_symbexec(L, p, pc, stackpos);
548 lua_assert(pc != -1); 554 lua_assert(pc != -1);
549 switch (GET_OPCODE(i)) { 555 switch (GET_OPCODE(i)) {
550 case OP_GETGLOBAL: { 556 case OP_GETGLOBAL: {
@@ -588,9 +594,6 @@ static const char *getfuncname (lua_State *L, StkId f, const char **name) {
588} 594}
589 595
590 596
591/* }====================================================== */
592
593
594void luaG_typeerror (lua_State *L, StkId o, const char *op) { 597void luaG_typeerror (lua_State *L, StkId o, const char *op) {
595 const char *name; 598 const char *name;
596 const char *kind = getobjname(L, o, &name); 599 const char *kind = getobjname(L, o, &name);