diff options
| -rw-r--r-- | ldebug.c | 21 | ||||
| -rw-r--r-- | testes/errors.lua | 4 |
2 files changed, 19 insertions, 6 deletions
| @@ -37,6 +37,9 @@ | |||
| 37 | static const char *funcnamefromcall (lua_State *L, CallInfo *ci, | 37 | static const char *funcnamefromcall (lua_State *L, CallInfo *ci, |
| 38 | const char **name); | 38 | const char **name); |
| 39 | 39 | ||
| 40 | static const char strlocal[] = "local"; | ||
| 41 | static const char strupval[] = "upvalue"; | ||
| 42 | |||
| 40 | 43 | ||
| 41 | static int currentpc (CallInfo *ci) { | 44 | static int currentpc (CallInfo *ci) { |
| 42 | lua_assert(isLua(ci)); | 45 | lua_assert(isLua(ci)); |
| @@ -497,7 +500,7 @@ static const char *basicgetobjname (const Proto *p, int *ppc, int reg, | |||
| 497 | int pc = *ppc; | 500 | int pc = *ppc; |
| 498 | *name = luaF_getlocalname(p, reg + 1, pc); | 501 | *name = luaF_getlocalname(p, reg + 1, pc); |
| 499 | if (*name) /* is a local? */ | 502 | if (*name) /* is a local? */ |
| 500 | return "local"; | 503 | return strlocal; |
| 501 | /* else try symbolic execution */ | 504 | /* else try symbolic execution */ |
| 502 | *ppc = pc = findsetreg(p, pc, reg); | 505 | *ppc = pc = findsetreg(p, pc, reg); |
| 503 | if (pc != -1) { /* could find instruction? */ | 506 | if (pc != -1) { /* could find instruction? */ |
| @@ -512,7 +515,7 @@ static const char *basicgetobjname (const Proto *p, int *ppc, int reg, | |||
| 512 | } | 515 | } |
| 513 | case OP_GETUPVAL: { | 516 | case OP_GETUPVAL: { |
| 514 | *name = upvalname(p, GETARG_B(i)); | 517 | *name = upvalname(p, GETARG_B(i)); |
| 515 | return "upvalue"; | 518 | return strupval; |
| 516 | } | 519 | } |
| 517 | case OP_LOADK: return kname(p, GETARG_Bx(i), name); | 520 | case OP_LOADK: return kname(p, GETARG_Bx(i), name); |
| 518 | case OP_LOADKX: return kname(p, GETARG_Ax(p->code[pc + 1]), name); | 521 | case OP_LOADKX: return kname(p, GETARG_Ax(p->code[pc + 1]), name); |
| @@ -547,15 +550,21 @@ static void rkname (const Proto *p, int pc, Instruction i, const char **name) { | |||
| 547 | 550 | ||
| 548 | /* | 551 | /* |
| 549 | ** Check whether table being indexed by instruction 'i' is the | 552 | ** Check whether table being indexed by instruction 'i' is the |
| 550 | ** environment '_ENV' | 553 | ** environment '_ENV'. If the table is an upvalue, get its name; |
| 554 | ** otherwise, find some "name" for the table and check whether | ||
| 555 | ** that name is the name of a local variable (and not, for instance, | ||
| 556 | ** a string). Then check that, if there is a name, it is '_ENV'. | ||
| 551 | */ | 557 | */ |
| 552 | static const char *isEnv (const Proto *p, int pc, Instruction i, int isup) { | 558 | static const char *isEnv (const Proto *p, int pc, Instruction i, int isup) { |
| 553 | int t = GETARG_B(i); /* table index */ | 559 | int t = GETARG_B(i); /* table index */ |
| 554 | const char *name; /* name of indexed variable */ | 560 | const char *name; /* name of indexed variable */ |
| 555 | if (isup) /* is 't' an upvalue? */ | 561 | if (isup) /* is 't' an upvalue? */ |
| 556 | name = upvalname(p, t); | 562 | name = upvalname(p, t); |
| 557 | else /* 't' is a register */ | 563 | else { /* 't' is a register */ |
| 558 | basicgetobjname(p, &pc, t, &name); | 564 | const char *what = basicgetobjname(p, &pc, t, &name); |
| 565 | if (what != strlocal && what != strupval) | ||
| 566 | name = NULL; /* cannot be the variable _ENV */ | ||
| 567 | } | ||
| 559 | return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; | 568 | return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; |
| 560 | } | 569 | } |
| 561 | 570 | ||
| @@ -701,7 +710,7 @@ static const char *getupvalname (CallInfo *ci, const TValue *o, | |||
| 701 | for (i = 0; i < c->nupvalues; i++) { | 710 | for (i = 0; i < c->nupvalues; i++) { |
| 702 | if (c->upvals[i]->v.p == o) { | 711 | if (c->upvals[i]->v.p == o) { |
| 703 | *name = upvalname(c->p, i); | 712 | *name = upvalname(c->p, i); |
| 704 | return "upvalue"; | 713 | return strupval; |
| 705 | } | 714 | } |
| 706 | } | 715 | } |
| 707 | return NULL; | 716 | return NULL; |
diff --git a/testes/errors.lua b/testes/errors.lua index 80d91a92..15401b4f 100644 --- a/testes/errors.lua +++ b/testes/errors.lua | |||
| @@ -137,6 +137,10 @@ checkmessage("aaa=(1)..{}", "a table value") | |||
| 137 | -- bug in 5.4.6 | 137 | -- bug in 5.4.6 |
| 138 | checkmessage("a = {_ENV = {}}; print(a._ENV.x + 1)", "field 'x'") | 138 | checkmessage("a = {_ENV = {}}; print(a._ENV.x + 1)", "field 'x'") |
| 139 | 139 | ||
| 140 | -- a similar bug in 5.4.7, since 5.4.0 | ||
| 141 | checkmessage("print(('_ENV').x + 1)", "field 'x'") | ||
| 142 | |||
| 143 | |||
| 140 | _G.aaa, _G.bbbb = nil | 144 | _G.aaa, _G.bbbb = nil |
| 141 | 145 | ||
| 142 | -- calls | 146 | -- calls |
