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