diff --git a/lcode.c b/lcode.c
index 119d91ab..7ca895f1 100644
--- a/lcode.c
+++ b/lcode.c
@@ -753,10 +753,11 @@ void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
 /*
 ** Convert a VKSTR to a VK
 */
-static void str2K (FuncState *fs, expdesc *e) {
+static int str2K (FuncState *fs, expdesc *e) {
   lua_assert(e->k == VKSTR);
   e->u.info = stringK(fs, e->u.strval);
   e->k = VK;
+  return e->u.info;
 }
 
 
@@ -1307,8 +1308,9 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
 ** values in registers.
 */
 void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
+  int keystr = -1;
   if (k->k == VKSTR)
-    str2K(fs, k);
+    keystr = str2K(fs, k);
   lua_assert(!hasjumps(t) &&
              (t->k == VLOCAL || t->k == VNONRELOC || t->k == VUPVAL));
   if (t->k == VUPVAL && !isKstr(fs, k))  /* upvalue indexed by non 'Kstr'? */
@@ -1336,7 +1338,8 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
       t->k = VINDEXED;
     }
   }
-  t->u.ind.vidx = -1;  /* by default, not a declared global */
+  t->u.ind.keystr = keystr;  /* string index in 'k' */
+  t->u.ind.ro = 0;  /* by default, not read-only */
 }
 
 
diff --git a/lparser.c b/lparser.c
index 6658bb20..3c2f57ab 100644
--- a/lparser.c
+++ b/lparser.c
@@ -304,11 +304,9 @@ static void check_readonly (LexState *ls, expdesc *e) {
         varname = up->name;
       break;
     }
-    case VINDEXUP: case VINDEXSTR: case VINDEXED: {
-      int vidx = e->u.ind.vidx;
-      /* is it a read-only declared global? */
-      if (vidx != -1 && ls->dyd->actvar.arr[vidx].vd.kind == GDKCONST)
-        varname = ls->dyd->actvar.arr[vidx].vd.name;
+    case VINDEXUP: case VINDEXSTR: case VINDEXED: {  /* global variable */
+      if (e->u.ind.ro)  /* read-only? */
+        varname = tsvalue(&fs->f->k[e->u.ind.keystr]);
       break;
     }
     default:
@@ -483,8 +481,6 @@ static void buildvar (LexState *ls, TString *varname, expdesc *var) {
   if (var->k == VGLOBAL) {  /* global name? */
     expdesc key;
     int info = var->u.info;
-    lua_assert(info == -1 ||
-               eqstr(ls->dyd->actvar.arr[info].vd.name, varname));
     /* global by default in the scope of a global declaration? */
     if (info == -1 && fs->bl->globdec)
       luaK_semerror(ls, "variable '%s' not declared", getstr(varname));
@@ -495,7 +491,10 @@ static void buildvar (LexState *ls, TString *varname, expdesc *var) {
     luaK_exp2anyregup(fs, var);  /* but could be a constant */
     codestring(&key, varname);  /* key is variable name */
     luaK_indexed(fs, var, &key);  /* env[varname] */
-    var->u.ind.vidx = cast_short(info);  /* mark it as a declared global */
+    if (info != -1 && ls->dyd->actvar.arr[info].vd.kind == GDKCONST)
+      var->u.ind.ro = 1;  /* mark variable as read-only */
+    else  /* anyway must be a global */
+      lua_assert(info == -1 || ls->dyd->actvar.arr[info].vd.kind == GDKREG);
   }
 }
 
diff --git a/lparser.h b/lparser.h
index 274fb1c4..524df6ea 100644
--- a/lparser.h
+++ b/lparser.h
@@ -45,16 +45,19 @@ typedef enum {
               info = absolute index in 'actvar.arr'  */
   VINDEXED,  /* indexed variable;
                 ind.t = table register;
-                ind.idx = key's R index */
+                ind.idx = key's R index;
+                ind.ro = true if it represents a read-only global;
+                ind.keystr = if key is a string, index in 'k' of that string;
+                             -1 if key is not a string */
   VINDEXUP,  /* indexed upvalue;
-                ind.t = table upvalue;
-                ind.idx = key's K index */
+                ind.idx = key's K index;
+                ind.* as in VINDEXED */
   VINDEXI, /* indexed variable with constant integer;
                 ind.t = table register;
                 ind.idx = key's value */
   VINDEXSTR, /* indexed variable with literal string;
-                ind.t = table register;
-                ind.idx = key's K index */
+                ind.idx = key's K index;
+                ind.* as in VINDEXED */
   VJMP,  /* expression is a test/comparison;
             info = pc of corresponding jump instruction */
   VRELOC,  /* expression can put result in any register;
@@ -77,8 +80,9 @@ typedef struct expdesc {
     int info;  /* for generic use */
     struct {  /* for indexed variables */
       short idx;  /* index (R or "long" K) */
-      short vidx;  /* index in 'actvar.arr' or -1 if not a declared global */
       lu_byte t;  /* table (register or upvalue) */
+      lu_byte ro;  /* true if variable is read-only */
+      int keystr;  /* index in 'k' of string key, or -1 if not a string */
     } ind;
     struct {  /* for local variables */
       lu_byte ridx;  /* register holding the variable */