diff options
Diffstat (limited to 'ldebug.c')
-rw-r--r-- | ldebug.c | 153 |
1 files changed, 84 insertions, 69 deletions
@@ -417,40 +417,6 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | |||
417 | ** ======================================================= | 417 | ** ======================================================= |
418 | */ | 418 | */ |
419 | 419 | ||
420 | static const char *getobjname (const Proto *p, int lastpc, int reg, | ||
421 | const char **name); | ||
422 | |||
423 | |||
424 | /* | ||
425 | ** Find a "name" for the constant 'c'. | ||
426 | */ | ||
427 | static void kname (const Proto *p, int c, const char **name) { | ||
428 | TValue *kvalue = &p->k[c]; | ||
429 | *name = (ttisstring(kvalue)) ? getstr(tsvalue(kvalue)) : "?"; | ||
430 | } | ||
431 | |||
432 | |||
433 | /* | ||
434 | ** Find a "name" for the register 'c'. | ||
435 | */ | ||
436 | static void rname (const Proto *p, int pc, int c, const char **name) { | ||
437 | const char *what = getobjname(p, pc, c, name); /* search for 'c' */ | ||
438 | if (!(what && *what == 'c')) /* did not find a constant name? */ | ||
439 | *name = "?"; | ||
440 | } | ||
441 | |||
442 | |||
443 | /* | ||
444 | ** Find a "name" for a 'C' value in an RK instruction. | ||
445 | */ | ||
446 | static void rkname (const Proto *p, int pc, Instruction i, const char **name) { | ||
447 | int c = GETARG_C(i); /* key index */ | ||
448 | if (GETARG_k(i)) /* is 'c' a constant? */ | ||
449 | kname(p, c, name); | ||
450 | else /* 'c' is a register */ | ||
451 | rname(p, pc, c, name); | ||
452 | } | ||
453 | |||
454 | 420 | ||
455 | static int filterpc (int pc, int jmptarget) { | 421 | static int filterpc (int pc, int jmptarget) { |
456 | if (pc < jmptarget) /* is code conditional (inside a jump)? */ | 422 | if (pc < jmptarget) /* is code conditional (inside a jump)? */ |
@@ -509,28 +475,29 @@ static int findsetreg (const Proto *p, int lastpc, int reg) { | |||
509 | 475 | ||
510 | 476 | ||
511 | /* | 477 | /* |
512 | ** Check whether table being indexed by instruction 'i' is the | 478 | ** Find a "name" for the constant 'c'. |
513 | ** environment '_ENV' | ||
514 | */ | 479 | */ |
515 | static const char *gxf (const Proto *p, int pc, Instruction i, int isup) { | 480 | static const char *kname (const Proto *p, int index, const char **name) { |
516 | int t = GETARG_B(i); /* table index */ | 481 | TValue *kvalue = &p->k[index]; |
517 | const char *name; /* name of indexed variable */ | 482 | if (ttisstring(kvalue)) { |
518 | if (isup) /* is an upvalue? */ | 483 | *name = getstr(tsvalue(kvalue)); |
519 | name = upvalname(p, t); | 484 | return "constant"; |
520 | else | 485 | } |
521 | getobjname(p, pc, t, &name); | 486 | else { |
522 | return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; | 487 | *name = "?"; |
488 | return NULL; | ||
489 | } | ||
523 | } | 490 | } |
524 | 491 | ||
525 | 492 | ||
526 | static const char *getobjname (const Proto *p, int lastpc, int reg, | 493 | static const char *basicgetobjname (const Proto *p, int *ppc, int reg, |
527 | const char **name) { | 494 | const char **name) { |
528 | int pc; | 495 | int pc = *ppc; |
529 | *name = luaF_getlocalname(p, reg + 1, lastpc); | 496 | *name = luaF_getlocalname(p, reg + 1, pc); |
530 | if (*name) /* is a local? */ | 497 | if (*name) /* is a local? */ |
531 | return "local"; | 498 | return "local"; |
532 | /* else try symbolic execution */ | 499 | /* else try symbolic execution */ |
533 | pc = findsetreg(p, lastpc, reg); | 500 | *ppc = pc = findsetreg(p, pc, reg); |
534 | if (pc != -1) { /* could find instruction? */ | 501 | if (pc != -1) { /* could find instruction? */ |
535 | Instruction i = p->code[pc]; | 502 | Instruction i = p->code[pc]; |
536 | OpCode op = GET_OPCODE(i); | 503 | OpCode op = GET_OPCODE(i); |
@@ -538,18 +505,80 @@ static const char *getobjname (const Proto *p, int lastpc, int reg, | |||
538 | case OP_MOVE: { | 505 | case OP_MOVE: { |
539 | int b = GETARG_B(i); /* move from 'b' to 'a' */ | 506 | int b = GETARG_B(i); /* move from 'b' to 'a' */ |
540 | if (b < GETARG_A(i)) | 507 | if (b < GETARG_A(i)) |
541 | return getobjname(p, pc, b, name); /* get name for 'b' */ | 508 | return basicgetobjname(p, ppc, b, name); /* get name for 'b' */ |
542 | break; | 509 | break; |
543 | } | 510 | } |
511 | case OP_GETUPVAL: { | ||
512 | *name = upvalname(p, GETARG_B(i)); | ||
513 | return "upvalue"; | ||
514 | } | ||
515 | case OP_LOADK: return kname(p, GETARG_Bx(i), name); | ||
516 | case OP_LOADKX: return kname(p, GETARG_Ax(p->code[pc + 1]), name); | ||
517 | default: break; | ||
518 | } | ||
519 | } | ||
520 | return NULL; /* could not find reasonable name */ | ||
521 | } | ||
522 | |||
523 | |||
524 | /* | ||
525 | ** Find a "name" for the register 'c'. | ||
526 | */ | ||
527 | static void rname (const Proto *p, int pc, int c, const char **name) { | ||
528 | const char *what = basicgetobjname(p, &pc, c, name); /* search for 'c' */ | ||
529 | if (!(what && *what == 'c')) /* did not find a constant name? */ | ||
530 | *name = "?"; | ||
531 | } | ||
532 | |||
533 | |||
534 | /* | ||
535 | ** Find a "name" for a 'C' value in an RK instruction. | ||
536 | */ | ||
537 | static void rkname (const Proto *p, int pc, Instruction i, const char **name) { | ||
538 | int c = GETARG_C(i); /* key index */ | ||
539 | if (GETARG_k(i)) /* is 'c' a constant? */ | ||
540 | kname(p, c, name); | ||
541 | else /* 'c' is a register */ | ||
542 | rname(p, pc, c, name); | ||
543 | } | ||
544 | |||
545 | |||
546 | /* | ||
547 | ** Check whether table being indexed by instruction 'i' is the | ||
548 | ** environment '_ENV' | ||
549 | */ | ||
550 | static const char *isEnv (const Proto *p, int pc, Instruction i, int isup) { | ||
551 | int t = GETARG_B(i); /* table index */ | ||
552 | const char *name; /* name of indexed variable */ | ||
553 | if (isup) /* is 't' an upvalue? */ | ||
554 | name = upvalname(p, t); | ||
555 | else /* 't' is a register */ | ||
556 | basicgetobjname(p, &pc, t, &name); | ||
557 | return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; | ||
558 | } | ||
559 | |||
560 | |||
561 | /* | ||
562 | ** Extend 'basicgetobjname' to handle table accesses | ||
563 | */ | ||
564 | static const char *getobjname (const Proto *p, int lastpc, int reg, | ||
565 | const char **name) { | ||
566 | const char *kind = basicgetobjname(p, &lastpc, reg, name); | ||
567 | if (kind != NULL) | ||
568 | return kind; | ||
569 | else if (lastpc != -1) { /* could find instruction? */ | ||
570 | Instruction i = p->code[lastpc]; | ||
571 | OpCode op = GET_OPCODE(i); | ||
572 | switch (op) { | ||
544 | case OP_GETTABUP: { | 573 | case OP_GETTABUP: { |
545 | int k = GETARG_C(i); /* key index */ | 574 | int k = GETARG_C(i); /* key index */ |
546 | kname(p, k, name); | 575 | kname(p, k, name); |
547 | return gxf(p, pc, i, 1); | 576 | return isEnv(p, lastpc, i, 1); |
548 | } | 577 | } |
549 | case OP_GETTABLE: { | 578 | case OP_GETTABLE: { |
550 | int k = GETARG_C(i); /* key index */ | 579 | int k = GETARG_C(i); /* key index */ |
551 | rname(p, pc, k, name); | 580 | rname(p, lastpc, k, name); |
552 | return gxf(p, pc, i, 0); | 581 | return isEnv(p, lastpc, i, 0); |
553 | } | 582 | } |
554 | case OP_GETI: { | 583 | case OP_GETI: { |
555 | *name = "integer index"; | 584 | *name = "integer index"; |
@@ -558,24 +587,10 @@ static const char *getobjname (const Proto *p, int lastpc, int reg, | |||
558 | case OP_GETFIELD: { | 587 | case OP_GETFIELD: { |
559 | int k = GETARG_C(i); /* key index */ | 588 | int k = GETARG_C(i); /* key index */ |
560 | kname(p, k, name); | 589 | kname(p, k, name); |
561 | return gxf(p, pc, i, 0); | 590 | return isEnv(p, lastpc, i, 0); |
562 | } | ||
563 | case OP_GETUPVAL: { | ||
564 | *name = upvalname(p, GETARG_B(i)); | ||
565 | return "upvalue"; | ||
566 | } | ||
567 | case OP_LOADK: | ||
568 | case OP_LOADKX: { | ||
569 | int b = (op == OP_LOADK) ? GETARG_Bx(i) | ||
570 | : GETARG_Ax(p->code[pc + 1]); | ||
571 | if (ttisstring(&p->k[b])) { | ||
572 | *name = getstr(tsvalue(&p->k[b])); | ||
573 | return "constant"; | ||
574 | } | ||
575 | break; | ||
576 | } | 591 | } |
577 | case OP_SELF: { | 592 | case OP_SELF: { |
578 | rkname(p, pc, i, name); | 593 | rkname(p, lastpc, i, name); |
579 | return "method"; | 594 | return "method"; |
580 | } | 595 | } |
581 | default: break; /* go through to return NULL */ | 596 | default: break; /* go through to return NULL */ |