diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-02-16 15:58:27 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-02-16 15:58:27 -0200 |
commit | 27600fe87a6fafdfd4ddddeb390591fe749b480f (patch) | |
tree | c12caaf125626f871f64e961c7fc0c411b07be28 | |
parent | f8509668dcb0e2f3842b9d0a58232f3ffa2f96d6 (diff) | |
download | lua-27600fe87a6fafdfd4ddddeb390591fe749b480f.tar.gz lua-27600fe87a6fafdfd4ddddeb390591fe749b480f.tar.bz2 lua-27600fe87a6fafdfd4ddddeb390591fe749b480f.zip |
better strucuture for code checker
-rw-r--r-- | ldebug.c | 95 |
1 files changed, 49 insertions, 46 deletions
@@ -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 | ||
329 | static int checklineinfo (const Proto *pt) { | 326 | static 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 | ||
350 | static 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 | ||
355 | static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos, | 360 | |
356 | unsigned char *sl) { | 361 | static 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 | ||
530 | int luaG_checkcode (lua_State *L, const Proto *pt) { | 540 | int 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 | |||
594 | void luaG_typeerror (lua_State *L, StkId o, const char *op) { | 597 | void 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); |