Browse Source

first version of _ENV; no more global variables

Roberto Ierusalimschy 15 years ago
parent
commit
25c557ec63
12 changed files with 52 additions and 124 deletions
  1. 2 2
      lbaselib.c
  2. 2 12
      lcode.c
  3. 27 21
      ldebug.c
  4. 1 2
      ldump.c
  5. 1 2
      lfunc.c
  6. 1 2
      lobject.h
  7. 1 5
      lopcodes.c
  8. 2 5
      lopcodes.h
  9. 10 37
      lparser.c
  10. 1 3
      lparser.h
  11. 1 2
      lundump.c
  12. 3 31
      lvm.c

+ 2 - 2
lbaselib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lbaselib.c,v 1.234 2009/12/22 15:32:50 roberto Exp roberto $
+** $Id: lbaselib.c,v 1.235 2009/12/28 16:30:31 roberto Exp roberto $
 ** Basic library
 ** See Copyright Notice in lua.h
 */
@@ -376,7 +376,7 @@ static int luaB_loadin (lua_State *L) {
   n = luaB_load_aux(L, 2);
   if (n == 1) {  /* success? */
     lua_pushvalue(L, 1);  /* environment for loaded function */
-    lua_setfenv(L, -2);
+    lua_setupvalue(L, -2, 1);
   }
   return n;
 }

+ 2 - 12
lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 2.43 2010/01/11 17:38:30 roberto Exp roberto $
+** $Id: lcode.c,v 2.44 2010/02/26 20:40:29 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -372,11 +372,6 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
       e->k = VRELOCABLE;
       break;
     }
-    case VGLOBAL: {
-      e->u.s.info = luaK_codeABxX(fs, OP_GETGLOBAL, 0, e->u.s.info);
-      e->k = VRELOCABLE;
-      break;
-    }
     case VINDEXED: {
       freereg(fs, e->u.s.aux);
       freereg(fs, e->u.s.info);
@@ -555,11 +550,6 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
       luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0);
       break;
     }
-    case VGLOBAL: {
-      int e = luaK_exp2anyreg(fs, ex);
-      luaK_codeABxX(fs, OP_SETGLOBAL, e, var->u.s.info);
-      break;
-    }
     case VINDEXED: {
       int e = luaK_exp2RK(fs, ex);
       luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e);
@@ -584,9 +574,9 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
   luaK_exp2anyreg(fs, e);
   freeexp(fs, e);
   func = fs->freereg;
-  luaK_reserveregs(fs, 2);
   luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key));
   freeexp(fs, key);
+  luaK_reserveregs(fs, 2);
   e->u.s.info = func;
   e->k = VNONRELOC;
 }

+ 27 - 21
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 2.64 2010/02/26 20:40:29 roberto Exp roberto $
+** $Id: ldebug.c,v 2.65 2010/03/05 14:01:29 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -260,11 +260,14 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
 */
 
 
-static const char *kname (Proto *p, int c) {
-  if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
-    return svalue(&p->k[INDEXK(c)]);
+static void kname (Proto *p, int c, int reg, const char *what,
+                   const char **name) {
+  if (c == reg && *what == 'c')
+    return;  /* index is a constant; name already correct */
+  else if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
+    *name = svalue(&p->k[INDEXK(c)]);
   else
-    return "?";
+    *name = "?";
 }
 
 
@@ -283,17 +286,6 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
     OpCode op = GET_OPCODE(i);
     int a = GETARG_A(i);
     switch (op) {
-      case OP_GETGLOBAL: {
-        if (reg == a) {
-          int g = GETARG_Bx(i);
-          if (g != 0) g--;
-          else g = GETARG_Ax(p->code[++pc]);
-          lua_assert(ttisstring(&p->k[g]));
-          *name = svalue(&p->k[g]);
-          what = "global";
-        }
-        break;
-      }
       case OP_MOVE: {
         if (reg == a) {
           int b = GETARG_B(i);  /* move from 'b' to 'a' */
@@ -307,8 +299,12 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
       case OP_GETTABLE: {
         if (reg == a) {
           int k = GETARG_C(i);  /* key index */
-          *name = kname(p, k);
-          what = "field";
+          int t = GETARG_B(i);
+          const char *tabname = (op == OP_GETTABLE)
+                                ? luaF_getlocalname(p, t + 1, pc)
+                                : getstr(p->upvalues[t].name);
+          kname(p, k, a, what, name);
+          what = (tabname && strcmp(tabname, "_ENV") == 0) ? "global" : "field";
         }
         break;
       }
@@ -321,6 +317,17 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
         }
         break;
       }
+      case OP_LOADK: {
+        if (reg == a) {
+          int b = GETARG_Bx(i);
+          b = (b > 0) ? b - 1 : GETARG_Ax(p->code[pc + 1]);
+          if (ttisstring(&p->k[b])) {
+            what = "constant";
+            *name = svalue(&p->k[b]);
+          }
+        }
+        break;
+      }
       case OP_LOADNIL: {
         int b = GETARG_B(i);  /* move from 'b' to 'a' */
         if (a <= reg && reg <= b)  /* set registers from 'a' to 'b' */
@@ -330,7 +337,7 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
       case OP_SELF: {
         if (reg == a) {
           int k = GETARG_C(i);  /* key index */
-          *name = kname(p, k);
+          kname(p, k, a, what, name);
           what = "method";
         }
         break;
@@ -378,11 +385,10 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
       *name = "for iterator";
        return "for iterator";
     }
-    case OP_GETGLOBAL:
     case OP_SELF:
     case OP_GETTABUP:
     case OP_GETTABLE: tm = TM_INDEX; break;
-    case OP_SETGLOBAL:
+    case OP_SETTABUP:
     case OP_SETTABLE: tm = TM_NEWINDEX; break;
     case OP_EQ: tm = TM_EQ; break;
     case OP_ADD: tm = TM_ADD; break;

+ 1 - 2
ldump.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldump.c,v 2.11 2009/09/28 16:32:50 roberto Exp roberto $
+** $Id: ldump.c,v 2.12 2009/09/30 15:38:37 roberto Exp roberto $
 ** save precompiled Lua chunks
 ** See Copyright Notice in lua.h
 */
@@ -145,7 +145,6 @@ static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
  DumpChar(f->numparams,D);
  DumpChar(f->is_vararg,D);
  DumpChar(f->maxstacksize,D);
- DumpChar(f->envreg,D);
  DumpCode(f,D);
  DumpConstants(f,D);
  DumpUpvalues(f,D);

+ 1 - 2
lfunc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lfunc.c,v 2.18 2009/12/11 13:39:34 roberto Exp roberto $
+** $Id: lfunc.c,v 2.19 2009/12/16 16:42:58 roberto Exp roberto $
 ** Auxiliary functions to manipulate prototypes and closures
 ** See Copyright Notice in lua.h
 */
@@ -127,7 +127,6 @@ Proto *luaF_newproto (lua_State *L) {
   f->linedefined = 0;
   f->lastlinedefined = 0;
   f->source = NULL;
-  f->envreg = NO_REG;
   return f;
 }
 

+ 1 - 2
lobject.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.h,v 2.33 2009/11/19 19:06:52 roberto Exp roberto $
+** $Id: lobject.h,v 2.34 2010/01/08 20:00:20 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -264,7 +264,6 @@ typedef struct Proto {
   lu_byte numparams;
   lu_byte is_vararg;
   lu_byte maxstacksize;
-  lu_byte envreg;  /* register in outer function with initial environment */
 } Proto;
 
 

+ 1 - 5
lopcodes.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lopcodes.c,v 1.41 2009/11/19 19:06:52 roberto Exp roberto $
+** $Id: lopcodes.c,v 1.42 2010/02/26 20:40:29 roberto Exp roberto $
 ** See Copyright Notice in lua.h
 */
 
@@ -19,10 +19,8 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
   "LOADBOOL",
   "LOADNIL",
   "GETUPVAL",
-  "GETGLOBAL",
   "GETTABUP",
   "GETTABLE",
-  "SETGLOBAL",
   "SETTABUP",
   "SETUPVAL",
   "SETTABLE",
@@ -69,10 +67,8 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
  ,opmode(0, 1, OpArgU, OpArgU, iABC)		/* OP_LOADBOOL */
  ,opmode(0, 1, OpArgR, OpArgN, iABC)		/* OP_LOADNIL */
  ,opmode(0, 1, OpArgU, OpArgN, iABC)		/* OP_GETUPVAL */
- ,opmode(0, 1, OpArgK, OpArgN, iABx)		/* OP_GETGLOBAL */
  ,opmode(0, 1, OpArgU, OpArgK, iABC)		/* OP_GETTABUP */
  ,opmode(0, 1, OpArgR, OpArgK, iABC)		/* OP_GETTABLE */
- ,opmode(0, 0, OpArgK, OpArgN, iABx)		/* OP_SETGLOBAL */
  ,opmode(0, 0, OpArgK, OpArgK, iABC)		/* OP_SETTABUP */
  ,opmode(0, 0, OpArgU, OpArgN, iABC)		/* OP_SETUPVAL */
  ,opmode(0, 0, OpArgK, OpArgK, iABC)		/* OP_SETTABLE */

+ 2 - 5
lopcodes.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lopcodes.h,v 1.133 2009/11/19 19:06:52 roberto Exp roberto $
+** $Id: lopcodes.h,v 1.134 2010/02/26 20:40:29 roberto Exp roberto $
 ** Opcodes for Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -171,11 +171,9 @@ OP_LOADBOOL,/*	A B C	R(A) := (Bool)B; if (C) pc++			*/
 OP_LOADNIL,/*	A B	R(A) := ... := R(B) := nil			*/
 OP_GETUPVAL,/*	A B	R(A) := UpValue[B]				*/
 
-OP_GETGLOBAL,/*	A Bx	R(A) := Gbl[Kst(Bx - 1)]			*/
 OP_GETTABUP,/*	A B C	R(A) := UpValue[B][RK(C)]			*/
 OP_GETTABLE,/*	A B C	R(A) := R(B)[RK(C)]				*/
 
-OP_SETGLOBAL,/*	A Bx	Gbl[Kst(Bx - 1)] := R(A)			*/
 OP_SETTABUP,/*	A B C	UpValue[A][RK(B)] := RK(C)			*/
 OP_SETUPVAL,/*	A B	UpValue[B] := R(A)				*/
 OP_SETTABLE,/*	A B C	R(A)[RK(B)] := RK(C)				*/
@@ -245,8 +243,7 @@ OP_EXTRAARG/*	Ax	extra (larger) argument for previous opcode	*/
   (*) In OP_SETLIST, if (B == 0) then B = `top'; if (C == 0) then next
   'instruction' is EXTRAARG(real C).
 
-  (*) In OP_LOADK, OP_GETGLOBAL, and OP_SETGLOBAL, if (Bx == 0) then next
-  'instruction' is EXTRAARG(real Bx).
+  (*) In OP_LOADK, if (Bx == 0) then next 'instruction' is EXTRAARG(real Bx).
 
   (*) For comparisons, A specifies what condition the test should accept
   (true or false).

+ 10 - 37
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 2.77 2010/03/04 18:12:57 roberto Exp roberto $
+** $Id: lparser.c,v 2.78 2010/03/08 16:55:52 roberto Exp roberto $
 ** Lua Parser
 ** See Copyright Notice in lua.h
 */
@@ -259,7 +259,7 @@ static void markupval (FuncState *fs, int level) {
 */
 static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
   if (fs == NULL)  /* no more levels? */
-    return VGLOBAL;  /* default is global variable */
+    return VVOID;  /* default is global */
   else {
     int v = searchvar(fs, n);  /* look up locals at current level */
     if (v >= 0) {  /* found? */
@@ -271,8 +271,8 @@ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
     else {  /* not found as local at current level; try upvalues */
       int idx = searchupvalue(fs, n);  /* try existing upvalues */
       if (idx < 0) {  /* not found? */
-        if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) /* try upper levels */
-          return VGLOBAL;  /* not found; is a global */
+        if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */
+          return VVOID;  /* not found; is a global */
         /* else was LOCAL or UPVAL */
         idx  = newupvalue(fs, n, var);  /* will be a new upvalue */
       }
@@ -286,15 +286,12 @@ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
 static void singlevar (LexState *ls, expdesc *var) {
   TString *varname = str_checkname(ls);
   FuncState *fs = ls->fs;
-  if (singlevaraux(fs, varname, var, 1) == VGLOBAL) {
-    if (fs->envreg == NO_REG)  /* regular global? */
-      init_exp(var, VGLOBAL, luaK_stringK(fs, varname));
-    else {  /* "globals" are in current lexical environment */
-      expdesc key;
-      init_exp(var, VLOCAL, fs->envreg);  /* current environment */
-      codestring(ls, &key, varname);  /* key is variable name */
-      luaK_indexed(fs, var, &key);  /* env[varname] */
-    }
+  if (singlevaraux(fs, varname, var, 1) == VVOID) {  /* global name? */
+    expdesc key;
+    singlevaraux(fs, ls->envn, var, 1);  /* get _ENV variable */
+    lua_assert(var->k == VLOCAL || var->k == VUPVAL);
+    codestring(ls, &key, varname);  /* key is variable name */
+    luaK_indexed(fs, var, &key);  /* env[varname] */
   }
 }
 
@@ -363,7 +360,6 @@ static void pushclosure (LexState *ls, Proto *clp, expdesc *v) {
   while (oldsize < f->sizep) f->p[oldsize++] = NULL;
   f->p[fs->np++] = clp;
   /* initial environment for new function is current lexical environment */
-  clp->envreg = fs->envreg;
   luaC_objbarrier(ls->L, f, clp);
   init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
 }
@@ -386,7 +382,6 @@ static void open_func (LexState *ls, FuncState *fs) {
   fs->nlocvars = 0;
   fs->nactvar = 0;
   fs->firstlocal = ls->varl->nactvar;
-  fs->envreg = NO_REG;
   fs->bl = NULL;
   f = luaF_newproto(L);
   fs->f = f;
@@ -1304,24 +1299,6 @@ static void funcstat (LexState *ls, int line) {
 }
 
 
-static void instat (LexState *ls, int line) {
-  /* instat -> IN exp DO block END */
-  FuncState *fs = ls->fs;
-  int oldenv = fs->envreg;  /* save current environment */
-  BlockCnt bl;
-  luaX_next(ls);  /* skip IN */
-  enterblock(fs, &bl, 0);  /* scope for environment variable */
-  new_localvarliteral(ls, "(environment)");
-  fs->envreg = exp1(ls);  /* new environment */
-  adjustlocalvars(ls, 1);
-  checknext(ls, TK_DO);
-  block(ls);
-  leaveblock(fs);
-  check_match(ls, TK_END, TK_IN, line);
-  fs->envreg = oldenv;  /* restore outer environment */
-}
-
-
 static void exprstat (LexState *ls) {
   /* stat -> func | assignment */
   FuncState *fs = ls->fs;
@@ -1386,10 +1363,6 @@ static int statement (LexState *ls) {
       check_match(ls, TK_END, TK_DO, line);
       return 0;
     }
-    case TK_IN: {
-      instat(ls, line);
-      return 0;
-    }
     case TK_FOR: {  /* stat -> forstat */
       forstat(ls, line);
       return 0;

+ 1 - 3
lparser.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.h,v 1.61 2009/10/11 20:02:19 roberto Exp roberto $
+** $Id: lparser.h,v 1.62 2010/02/26 20:40:29 roberto Exp roberto $
 ** Lua Parser
 ** See Copyright Notice in lua.h
 */
@@ -25,7 +25,6 @@ typedef enum {
   VKNUM,	/* nval = numerical value */
   VLOCAL,	/* info = local register */
   VUPVAL,       /* info = index of upvalue in 'upvalues' */
-  VGLOBAL,	/* info =  index of global name in 'k' */
   VINDEXED,	/* info = table R/K; aux = index R/K */
   VINDEXEDUP,	/* info = table upvalue; aux = R/K */
   VJMP,		/* info = instruction pc */
@@ -81,7 +80,6 @@ typedef struct FuncState {
   short nlocvars;  /* number of elements in `locvars' */
   lu_byte nactvar;  /* number of active local variables */
   lu_byte nups;  /* number of upvalues */
-  lu_byte envreg;  /* register holding current lexical environment */
 } FuncState;
 
 

+ 1 - 2
lundump.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lundump.c,v 2.11 2009/09/28 16:32:50 roberto Exp roberto $
+** $Id: lundump.c,v 2.12 2009/09/30 15:38:37 roberto Exp roberto $
 ** load precompiled Lua chunks
 ** See Copyright Notice in lua.h
 */
@@ -180,7 +180,6 @@ static Proto* LoadFunction(LoadState* S, TString* p)
  f->numparams=LoadByte(S);
  f->is_vararg=LoadByte(S);
  f->maxstacksize=LoadByte(S);
- f->envreg=LoadByte(S);
  LoadCode(S,f);
  LoadConstants(S,f);
  LoadUpvalues(S,f);

+ 3 - 31
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 2.104 2010/02/26 20:40:29 roberto Exp roberto $
+** $Id: lvm.c,v 2.105 2010/02/27 21:16:24 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -355,14 +355,10 @@ void luaV_finishOp (lua_State *L) {
   StkId base = ci->u.l.base;
   Instruction inst = *(ci->u.l.savedpc - 1);  /* interrupted instruction */
   OpCode op = GET_OPCODE(inst);
-  if (op == OP_EXTRAARG) {  /* extra argument? */
-    inst = *(ci->u.l.savedpc - 2);  /* get its 'main' instruction */
-    op = GET_OPCODE(inst);
-  }
   switch (op) {  /* finish its execution */
     case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV:
     case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN:
-    case OP_GETGLOBAL: case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: {
+    case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: {
       setobjs2s(L, base + GETARG_A(inst), --L->top);
       break;
     }
@@ -403,7 +399,7 @@ void luaV_finishOp (lua_State *L) {
         L->top = ci->top;  /* adjust results */
       break;
     }
-    case OP_TAILCALL: case OP_SETGLOBAL: case OP_SETTABUP:  case OP_SETTABLE:
+    case OP_TAILCALL: case OP_SETTABUP:  case OP_SETTABLE:
       break;
     default: lua_assert(0);
   }
@@ -501,14 +497,6 @@ void luaV_execute (lua_State *L) {
         setobj2s(L, ra, cl->upvals[b]->v);
         break;
       }
-      case OP_GETGLOBAL: {
-        TValue g;
-        TValue *rb = KBx(i);
-        sethvalue(L, &g, cl->env);
-        lua_assert(ttisstring(rb));
-        Protect(luaV_gettable(L, &g, rb, ra));
-        break;
-      }
       case OP_GETTABUP: {
         int b = GETARG_B(i);
         Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra));
@@ -518,14 +506,6 @@ void luaV_execute (lua_State *L) {
         Protect(luaV_gettable(L, RB(i), RKC(i), ra));
         break;
       }
-      case OP_SETGLOBAL: {
-        TValue g;
-        TValue *rb = KBx(i);
-        sethvalue(L, &g, cl->env);
-        lua_assert(ttisstring(rb));
-        Protect(luaV_settable(L, &g, rb, ra));
-        break;
-      }
       case OP_SETTABUP: {
         int a = GETARG_A(i);
         Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i)));
@@ -796,14 +776,6 @@ void luaV_execute (lua_State *L) {
         int j;
         ncl->l.p = p;
         setclvalue(L, ra, ncl);  /* anchor new closure in stack */
-        if (p->envreg != NO_REG) {  /* lexical environment? */
-          StkId env = base + p->envreg;
-          if (!ttistable(env))
-            luaG_runerror(L, "environment is not a table: "
-                             "cannot create closure");
-          else
-            ncl->l.env = hvalue(env);
-        }
         for (j = 0; j < nup; j++) {  /* fill in upvalues */
           if (uv[j].instack)  /* upvalue refers to local variable? */
             ncl->l.upvals[j] = luaF_findupval(L, base + uv[j].idx);