3737static const char * funcnamefromcall (lua_State * L , CallInfo * ci ,
3838 const char * * name );
3939
40+ static const char strlocal [] = "local" ;
41+ static const char strupval [] = "upvalue" ;
42+
4043
4144static int currentpc (CallInfo * ci ) {
4245 lua_assert (isLua (ci ));
@@ -497,7 +500,7 @@ static const char *basicgetobjname (const Proto *p, int *ppc, int reg,
497500 int pc = * ppc ;
498501 * name = luaF_getlocalname (p , reg + 1 , pc );
499502 if (* name ) /* is a local? */
500- return "local" ;
503+ return strlocal ;
501504 /* else try symbolic execution */
502505 * ppc = pc = findsetreg (p , pc , reg );
503506 if (pc != -1 ) { /* could find instruction? */
@@ -512,7 +515,7 @@ static const char *basicgetobjname (const Proto *p, int *ppc, int reg,
512515 }
513516 case OP_GETUPVAL : {
514517 * name = upvalname (p , GETARG_B (i ));
515- return "upvalue" ;
518+ return strupval ;
516519 }
517520 case OP_LOADK : return kname (p , GETARG_Bx (i ), name );
518521 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) {
547550
548551/*
549552** 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'.
551557*/
552558static const char * isEnv (const Proto * p , int pc , Instruction i , int isup ) {
553559 int t = GETARG_B (i ); /* table index */
554560 const char * name ; /* name of indexed variable */
555561 if (isup ) /* is 't' an upvalue? */
556562 name = upvalname (p , t );
557- else /* 't' is a register */
558- basicgetobjname (p , & pc , t , & name );
563+ else { /* 't' is a register */
564+ const char * what = basicgetobjname (p , & pc , t , & name );
565+ if (what != strlocal && what != strupval )
566+ name = NULL ; /* cannot be the variable _ENV */
567+ }
559568 return (name && strcmp (name , LUA_ENV ) == 0 ) ? "global" : "field" ;
560569}
561570
@@ -701,7 +710,7 @@ static const char *getupvalname (CallInfo *ci, const TValue *o,
701710 for (i = 0 ; i < c -> nupvalues ; i ++ ) {
702711 if (c -> upvals [i ]-> v .p == o ) {
703712 * name = upvalname (c -> p , i );
704- return "upvalue" ;
713+ return strupval ;
705714 }
706715 }
707716 return NULL ;
0 commit comments