Browse Source

no more one environment per thread: all threads share a single global
environment

Roberto Ierusalimschy 16 years ago
parent
commit
5bc91c6405
7 changed files with 27 additions and 47 deletions
  1. 4 10
      lapi.c
  2. 3 10
      lbaselib.c
  3. 2 2
      ldo.c
  4. 4 5
      lgc.c
  5. 9 10
      lstate.c
  6. 2 8
      lstate.h
  7. 3 2
      ltests.c

+ 4 - 10
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 2.92 2009/09/28 16:32:50 roberto Exp roberto $
+** $Id: lapi.c,v 2.93 2009/10/05 16:44:33 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -55,13 +55,13 @@ static TValue *index2addr (lua_State *L, int idx) {
     return L->top + idx;
   }
   else switch (idx) {  /* pseudo-indices */
-    case LUA_REGISTRYINDEX: return registry(L);
+    case LUA_REGISTRYINDEX: return &G(L)->l_registry;
     case LUA_ENVIRONINDEX: {
       Closure *func = curr_func(L);
       sethvalue(L, &L->env, func->c.env);
       return &L->env;
     }
-    case LUA_GLOBALSINDEX: return gt(L);
+    case LUA_GLOBALSINDEX: return &G(L)->l_gt;
     default: {
       Closure *func = curr_func(L);
       idx = LUA_GLOBALSINDEX - idx;
@@ -76,7 +76,7 @@ static TValue *index2addr (lua_State *L, int idx) {
 
 static Table *getcurrenv (lua_State *L) {
   if (L->ci->previous == NULL)  /* no enclosing function? */
-    return hvalue(gt(L));  /* use global table as environment */
+    return hvalue(&G(L)->l_gt);  /* use global table as environment */
   else {
     Closure *func = curr_func(L);
     return func->c.env;
@@ -633,9 +633,6 @@ LUA_API void lua_getfenv (lua_State *L, int idx) {
     case LUA_TUSERDATA:
       sethvalue(L, L->top, uvalue(o)->env);
       break;
-    case LUA_TTHREAD:
-      setobj2s(L, L->top,  gt(thvalue(o)));
-      break;
     default:
       setnilvalue(L->top);
       break;
@@ -755,9 +752,6 @@ LUA_API int lua_setfenv (lua_State *L, int idx) {
     case LUA_TUSERDATA:
       uvalue(o)->env = hvalue(L->top - 1);
       break;
-    case LUA_TTHREAD:
-      sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1));
-      break;
     default:
       res = 0;
       break;

+ 3 - 10
lbaselib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lbaselib.c,v 1.219 2009/10/05 16:44:33 roberto Exp roberto $
+** $Id: lbaselib.c,v 1.220 2009/10/23 12:50:25 roberto Exp roberto $
 ** Basic library
 ** See Copyright Notice in lua.h
 */
@@ -125,7 +125,7 @@ static void getfunc (lua_State *L, int opt) {
 static int luaB_getfenv (lua_State *L) {
   getfunc(L, 1);
   if (lua_iscfunction(L, -1))  /* is a C function? */
-    lua_pushvalue(L, LUA_GLOBALSINDEX);  /* return the thread's global env. */
+    lua_pushvalue(L, LUA_GLOBALSINDEX);  /* return the global env. */
   else
     lua_getfenv(L, -1);
   return 1;
@@ -136,14 +136,7 @@ static int luaB_setfenv (lua_State *L) {
   luaL_checktype(L, 2, LUA_TTABLE);
   getfunc(L, 0);
   lua_pushvalue(L, 2);
-  if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
-    /* change environment of current thread */
-    lua_pushthread(L);
-    lua_insert(L, -2);
-    lua_setfenv(L, -2);
-    return 0;
-  }
-  else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
+  if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
     return luaL_error(L,
              LUA_QL("setfenv") " cannot change environment of given object");
   return 1;

+ 2 - 2
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 2.68 2009/09/28 16:32:50 roberto Exp roberto $
+** $Id: ldo.c,v 2.69 2009/10/11 20:02:19 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -579,7 +579,7 @@ static void f_parser (lua_State *L, void *ud) {
            : luaY_parser(L, p->z, &p->buff, &p->varl, p->name);
   setptvalue2s(L, L->top, tf);
   incr_top(L);
-  cl = luaF_newLclosure(L, tf->sizeupvalues, hvalue(gt(L)));
+  cl = luaF_newLclosure(L, tf->sizeupvalues, hvalue(&G(L)->l_gt));
   cl->l.p = tf;
   setclvalue(L, L->top - 1, cl);
   for (i = 0; i < tf->sizeupvalues; i++)  /* initialize upvalues */

+ 4 - 5
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 2.56 2009/09/28 13:50:34 roberto Exp roberto $
+** $Id: lgc.c,v 2.57 2009/09/28 16:32:50 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -221,9 +221,9 @@ static void markroot (lua_State *L) {
   g->grayagain = NULL;
   g->weak = g->ephemeron = g->allweak = NULL;
   markobject(g, g->mainthread);
-  /* make global table be traversed before main stack */
-  markvalue(g, gt(g->mainthread));
-  markvalue(g, registry(L));
+  /* make global table and registry to be traversed before main stack */
+  markvalue(g, &g->l_gt);
+  markvalue(g, &g->l_registry);
   markmt(g);
   markbeingfnz(g);  /* mark any finalizing object left from previous cycle */
   g->gcstate = GCSpropagate;
@@ -383,7 +383,6 @@ static void traversestack (global_State *g, lua_State *L) {
   StkId o;
   if (L->stack == NULL)
     return;  /* stack not completely built yet */
-  markvalue(g, gt(L));  /* mark global table */
   for (o = L->stack; o < L->top; o++)
     markvalue(g, o);
   if (g->gcstate == GCSatomic) {  /* final traversal? */

+ 9 - 10
lstate.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 2.61 2009/09/30 20:49:47 roberto Exp roberto $
+** $Id: lstate.c,v 2.62 2009/10/05 16:44:33 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -108,18 +108,18 @@ static int cpcall (lua_State *L) {
 /*
 ** Create registry table and its predefined values
 */
-static void init_registry (lua_State *L) {
+static void init_registry (lua_State *L, global_State *g) {
   Closure *cp;
   TValue mt;
   /* create registry */
   Table *registry = luaH_new(L);
-  sethvalue(L, registry(L), registry);
+  sethvalue(L, &g->l_registry, registry);
   luaH_resize(L, registry, LUA_RIDX_LAST, 0);
   /* registry[LUA_RIDX_MAINTHREAD] = L */
   setthvalue(L, &mt, L);
   setobj2t(L, luaH_setint(L, registry, LUA_RIDX_MAINTHREAD), &mt);
   /* registry[LUA_RIDX_CPCALL] = cpcall */
-  cp = luaF_newCclosure(L, 0, hvalue(gt(L)));
+  cp = luaF_newCclosure(L, 0, hvalue(&g->l_gt));
   cp->c.f = cpcall;
   setclvalue(L, &mt, cp);
   setobj2t(L, luaH_setint(L, registry, LUA_RIDX_CPCALL), &mt);
@@ -127,14 +127,14 @@ static void init_registry (lua_State *L) {
 
 
 /*
-** open parts of a state that may cause memory-allocation errors
+** open parts of the state that may cause memory-allocation errors
 */
 static void f_luaopen (lua_State *L, void *ud) {
   global_State *g = G(L);
   UNUSED(ud);
   stack_init(L, L);  /* init stack */
-  sethvalue(L, gt(L), luaH_new(L));  /* table of globals */
-  init_registry(L);
+  sethvalue(L, &g->l_gt, luaH_new(L));  /* table of globals */
+  init_registry(L, g);
   luaS_resize(L, MINSTRTABSIZE);  /* initial size of string table */
   luaT_init(L);
   luaX_init(L);
@@ -164,7 +164,6 @@ static void preinit_state (lua_State *L, global_State *g) {
   L->base_ci.next = L->base_ci.previous = NULL;
   L->ci = &L->base_ci;
   L->errfunc = 0;
-  setnilvalue(gt(L));
 }
 
 
@@ -190,7 +189,6 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
   api_incr_top(L);
   preinit_state(L1, G(L));
   stack_init(L1, L);  /* init stack */
-  setobj2n(L, gt(L1), gt(L));  /* share table of globals */
   L1->hookmask = L->hookmask;
   L1->basehookcount = L->basehookcount;
   L1->hook = L->hook;
@@ -236,7 +234,8 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   g->strt.size = 0;
   g->strt.nuse = 0;
   g->strt.hash = NULL;
-  setnilvalue(registry(L));
+  setnilvalue(&g->l_registry);
+  setnilvalue(&g->l_gt);
   luaZ_initbuffer(L, &g->buff);
   g->panic = NULL;
   g->version = lua_version(NULL);

+ 2 - 8
lstate.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.h,v 2.45 2009/06/18 18:59:18 roberto Exp roberto $
+** $Id: lstate.h,v 2.46 2009/07/15 17:26:14 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -44,12 +44,6 @@
 struct lua_longjmp;  /* defined in ldo.c */
 
 
-/* table of globals */
-#define gt(L)	(&L->l_gt)
-
-/* registry */
-#define registry(L)	(&G(L)->l_registry)
-
 
 /* extra stack space to handle TM calls and some other extras */
 #define EXTRA_STACK   5
@@ -146,6 +140,7 @@ typedef struct global_State {
   int gcstepmul;  /* GC `granularity' */
   lua_CFunction panic;  /* to be called in unprotected errors */
   TValue l_registry;
+  TValue l_gt;  /* table of globals */
   struct lua_State *mainthread;
   UpVal uvhead;  /* head of double-linked list of all open upvalues */
   const lua_Number *version;  /* pointer to version number */
@@ -173,7 +168,6 @@ struct lua_State {
   int basehookcount;
   int hookcount;
   lua_Hook hook;
-  TValue l_gt;  /* table of globals */
   TValue env;  /* temporary place for environments */
   GCObject *openupval;  /* list of open upvalues in this stack */
   GCObject *gclist;

+ 3 - 2
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 2.75 2009/10/05 16:44:33 roberto Exp roberto $
+** $Id: ltests.c,v 2.76 2009/10/11 20:02:19 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -305,7 +305,6 @@ static void checkstack (global_State *g, lua_State *L1) {
     lua_assert(uv->v != &uv->u.value);  /* must be open */
     lua_assert(!isblack(uvo));  /* open upvalues cannot be black */
   }
-  checkliveness(g, gt(L1));
   for (ci = L1->ci; ci != NULL; ci = ci->previous) {
     lua_assert(ci->top <= L1->stack_last);
     lua_assert(lua_checkpc(ci));
@@ -366,6 +365,8 @@ int lua_checkmemory (lua_State *L) {
   global_State *g = G(L);
   GCObject *o;
   UpVal *uv;
+  checkliveness(g, &g->l_registry);
+  checkliveness(g, &g->l_gt);
   checkstack(g, g->mainthread);
   for (o = g->rootgc; o != obj2gco(g->mainthread); o = gch(o)->next) {
     lua_assert(!testbits(o->gch.marked, bit2mask(SEPARATED, SFIXEDBIT)));