| 523 | |
| 524 | |
| 525 | static const char *getobjname (const Proto *p, int lastpc, int reg, |
| 526 | const char **name) { |
| 527 | int pc; |
| 528 | *name = luaF_getlocalname(p, reg + 1, lastpc); |
| 529 | if (*name) /* is a local? */ |
| 530 | return "local"; |
| 531 | /* else try symbolic execution */ |
| 532 | pc = findsetreg(p, lastpc, reg); |
| 533 | if (pc != -1) { /* could find instruction? */ |
| 534 | Instruction i = p->code[pc]; |
| 535 | OpCode op = GET_OPCODE(i); |
| 536 | switch (op) { |
| 537 | case OP_MOVE: { |
| 538 | int b = GETARG_B(i); /* move from 'b' to 'a' */ |
| 539 | if (b < GETARG_A(i)) |
| 540 | return getobjname(p, pc, b, name); /* get name for 'b' */ |
| 541 | break; |
| 542 | } |
| 543 | case OP_GETTABUP: { |
| 544 | int k = GETARG_C(i); /* key index */ |
| 545 | kname(p, k, name); |
| 546 | return gxf(p, pc, i, 1); |
| 547 | } |
| 548 | case OP_GETTABLE: { |
| 549 | int k = GETARG_C(i); /* key index */ |
| 550 | rname(p, pc, k, name); |
| 551 | return gxf(p, pc, i, 0); |
| 552 | } |
| 553 | case OP_GETI: { |
| 554 | *name = "integer index"; |
| 555 | return "field"; |
| 556 | } |
| 557 | case OP_GETFIELD: { |
| 558 | int k = GETARG_C(i); /* key index */ |
| 559 | kname(p, k, name); |
| 560 | return gxf(p, pc, i, 0); |
| 561 | } |
| 562 | case OP_GETUPVAL: { |
| 563 | *name = upvalname(p, GETARG_B(i)); |
| 564 | return "upvalue"; |
| 565 | } |
| 566 | case OP_LOADK: |
| 567 | case OP_LOADKX: { |
| 568 | int b = (op == OP_LOADK) ? GETARG_Bx(i) |
| 569 | : GETARG_Ax(p->code[pc + 1]); |
| 570 | if (ttisstring(&p->k[b])) { |
| 571 | *name = svalue(&p->k[b]); |
| 572 | return "constant"; |
| 573 | } |
| 574 | break; |
| 575 | } |
| 576 | case OP_SELF: { |
| 577 | rkname(p, pc, i, name); |
| 578 | return "method"; |
| 579 | } |
| 580 | default: break; /* go through to return NULL */ |
| 581 | } |
| 582 | } |
no test coverage detected