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
Diffstat (limited to '')
| -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); |
