Przeglądaj źródła

no more pseudoindex LUA_GLOBALSINDEX; global table now accessible
through registry

Roberto Ierusalimschy 15 lat temu
rodzic
commit
f84b575cfa
12 zmienionych plików z 63 dodań i 53 usunięć
  1. 6 7
      lapi.c
  2. 5 4
      lauxlib.c
  3. 7 7
      lbaselib.c
  4. 2 2
      ldo.c
  5. 3 4
      lgc.c
  6. 6 3
      linit.c
  7. 5 4
      loadlib.c
  8. 9 5
      lstate.c
  9. 2 2
      lstate.h
  10. 4 4
      ltests.c
  11. 5 5
      lua.c
  12. 9 6
      lua.h

+ 6 - 7
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 2.104 2009/12/15 11:25:36 roberto Exp roberto $
+** $Id: lapi.c,v 2.105 2009/12/17 16:20:01 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -41,7 +41,7 @@ const char lua_ident[] =
 
 static Table *getcurrenv (lua_State *L) {
   if (L->ci->previous == NULL)  /* no enclosing function? */
-    return hvalue(&G(L)->l_gt);  /* use global table as environment */
+    return G(L)->l_gt;  /* use global table as environment */
   else {
     Closure *func = curr_func(L);
     return func->c.env;
@@ -67,10 +67,9 @@ static TValue *index2addr (lua_State *L, int idx) {
       sethvalue(L, &L->env, getcurrenv(L));
       return &L->env;
     }
-    case LUA_GLOBALSINDEX: return &G(L)->l_gt;
     default: {
       Closure *func = curr_func(L);
-      idx = LUA_GLOBALSINDEX - idx;
+      idx = LUA_ENVIRONINDEX - idx;
       api_check(L, idx <= UCHAR_MAX + 1, "upvalue index too large");
       return (idx <= func->c.nupvalues)
                 ? &func->c.upvalue[idx-1]
@@ -204,11 +203,11 @@ static void moveto (lua_State *L, TValue *fr, int idx) {
   }
   else {
     setobj(L, to, fr);
-    if (idx < LUA_GLOBALSINDEX)  /* function upvalue? */
+    if (idx < LUA_ENVIRONINDEX)  /* function upvalue? */
       luaC_barrier(L, curr_func(L), fr);
   }
-  /* LUA_GLOBALSINDEX and LUA_REGISTRYINDEX do not need gc barrier
-     (collector revisits them before finishing collection) */
+  /* LUA_REGISTRYINDEX does not need gc barrier
+     (collector revisits it before finishing collection) */
 }
 
 

+ 5 - 4
lauxlib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lauxlib.c,v 1.194 2009/11/25 15:27:51 roberto Exp roberto $
+** $Id: lauxlib.c,v 1.195 2009/12/17 16:20:01 roberto Exp roberto $
 ** Auxiliary functions for building Lua libraries
 ** See Copyright Notice in lua.h
 */
@@ -73,7 +73,7 @@ static int findfield (lua_State *L, int objidx, int level) {
 static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
   int top = lua_gettop(L);
   lua_getinfo(L, "f", ar);  /* push function */
-  lua_pushvalue(L, LUA_GLOBALSINDEX);  /* push global table */
+  lua_pushglobaltable(L);
   if (findfield(L, top + 1, 2)) {
     lua_copy(L, -1, top + 1);  /* move name to proper place */
     lua_pop(L, 2);  /* remove pushed values */
@@ -678,7 +678,8 @@ LUALIB_API void luaL_register (lua_State *L, const char *libname,
     if (!lua_istable(L, -1)) {  /* not found? */
       lua_pop(L, 1);  /* remove previous result */
       /* try global variable (and create one if it does not exist) */
-      if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, libsize(l)) != NULL)
+      lua_pushglobaltable(L);
+      if (luaL_findtable(L, 0, libname, libsize(l)) != NULL)
         luaL_error(L, "name conflict for module " LUA_QS, libname);
       lua_pushvalue(L, -1);
       lua_setfield(L, -3, libname);  /* _LOADED[libname] = new table */
@@ -713,7 +714,7 @@ LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
 LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
                                        const char *fname, int szhint) {
   const char *e;
-  lua_pushvalue(L, idx);
+  if (idx) lua_pushvalue(L, idx);
   do {
     e = strchr(fname, '.');
     if (e == NULL) e = fname + strlen(fname);

+ 7 - 7
lbaselib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lbaselib.c,v 1.232 2009/12/15 11:25:16 roberto Exp roberto $
+** $Id: lbaselib.c,v 1.233 2009/12/17 16:20:01 roberto Exp roberto $
 ** Basic library
 ** See Copyright Notice in lua.h
 */
@@ -23,7 +23,7 @@
 static int luaB_print (lua_State *L) {
   int n = lua_gettop(L);  /* number of arguments */
   int i;
-  lua_getfield(L, LUA_GLOBALSINDEX, "tostring");
+  lua_getfield(L, LUA_ENVIRONINDEX, "tostring");
   for (i=1; i<=n; i++) {
     const char *s;
     size_t l;
@@ -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 global env. */
+    lua_pushglobaltable(L);  /* return the global env. */
   else
     lua_getfenv(L, -1);
   return 1;
@@ -695,12 +695,12 @@ static void auxopen (lua_State *L, const char *name,
 
 static void base_open (lua_State *L) {
   /* set global _G */
-  lua_pushvalue(L, LUA_GLOBALSINDEX);
-  lua_setfield(L, LUA_GLOBALSINDEX, "_G");
+  lua_pushglobaltable(L);
+  lua_setfield(L, LUA_ENVIRONINDEX, "_G");
   /* open lib into global table */
   luaL_register(L, "_G", base_funcs);
   lua_pushliteral(L, LUA_VERSION);
-  lua_setfield(L, LUA_GLOBALSINDEX, "_VERSION");  /* set global _VERSION */
+  lua_setfield(L, LUA_ENVIRONINDEX, "_VERSION");  /* set global _VERSION */
   /* `ipairs' and `pairs' need auxiliary functions as upvalues */
   auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
   auxopen(L, "pairs", luaB_pairs, luaB_next);
@@ -711,7 +711,7 @@ static void base_open (lua_State *L) {
   lua_pushliteral(L, "kv");
   lua_setfield(L, -2, "__mode");  /* metatable(w).__mode = "kv" */
   lua_pushcclosure(L, luaB_newproxy, 1);
-  lua_setfield(L, LUA_GLOBALSINDEX, "newproxy");  /* set global `newproxy' */
+  lua_setfield(L, LUA_ENVIRONINDEX, "newproxy");  /* set global `newproxy' */
 }
 
 

+ 2 - 2
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 2.77 2009/12/17 12:26:09 roberto Exp roberto $
+** $Id: ldo.c,v 2.78 2009/12/17 12:28:57 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -619,7 +619,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(&G(L)->l_gt));
+  cl = luaF_newLclosure(L, tf->sizeupvalues, G(L)->l_gt);
   cl->l.p = tf;
   setclvalue(L, L->top - 1, cl);
   for (i = 0; i < tf->sizeupvalues; i++)  /* initialize upvalues */

+ 3 - 4
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 2.65 2009/12/11 21:31:14 roberto Exp roberto $
+** $Id: lgc.c,v 2.66 2009/12/16 16:42:58 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -230,7 +230,7 @@ static void markroot (lua_State *L) {
   g->weak = g->ephemeron = g->allweak = NULL;
   markobject(g, g->mainthread);
   /* make global table and registry to be traversed before main stack */
-  markvalue(g, &g->l_gt);
+  markobject(g, g->l_gt);
   markvalue(g, &g->l_registry);
   markmt(g);
   markbeingfnz(g);  /* mark any finalizing object left from previous cycle */
@@ -703,8 +703,7 @@ static void atomic (lua_State *L) {
   g->gcstate = GCSatomic;
   lua_assert(!iswhite(obj2gco(g->mainthread)));
   markobject(g, L);  /* mark running thread */
-  /* global table, registry, and global metatables may be changed by API */
-  markvalue(g, &g->l_gt);
+  /* registry and global metatables may be changed by API */
   markvalue(g, &g->l_registry);
   markmt(g);  /* mark basic metatables */
   /* remark occasional upvalues of (maybe) dead threads */

+ 6 - 3
linit.c

@@ -1,5 +1,5 @@
 /*
-** $Id: linit.c,v 1.21 2009/12/11 13:40:44 roberto Exp roberto $
+** $Id: linit.c,v 1.22 2009/12/17 12:26:09 roberto Exp roberto $
 ** Initialization of libraries for lua.c and other clients        
 ** See Copyright Notice in lua.h
 */
@@ -57,16 +57,19 @@ LUALIB_API void luaL_openlibs (lua_State *L) {
     lua_call(L, 1, 0);
   }
   /* add open functions from 'preloadedlibs' into 'package.preload' table */
-  luaL_findtable(L, LUA_GLOBALSINDEX, "package.preload", 0);
+  lua_pushglobaltable(L);
+  luaL_findtable(L, 0, "package.preload", 0);
   for (lib = preloadedlibs; lib->func; lib++) {
     lua_pushcfunction(L, lib->func);
     lua_setfield(L, -2, lib->name);
   }
   lua_pop(L, 1);  /* remove package.preload table */
 #if defined(LUA_COMPAT_DEBUGLIB)
-  lua_getfield(L, LUA_GLOBALSINDEX, "require");
+  lua_pushglobaltable(L);
+  lua_getfield(L, -1, "require");
   lua_pushliteral(L, LUA_DBLIBNAME);
   lua_call(L, 1, 0);  /* call 'require"debug"' */
+  lua_pop(L, 1);  /* remove global table */
 #endif
 }
 

+ 5 - 4
loadlib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: loadlib.c,v 1.69 2009/12/17 12:26:09 roberto Exp roberto $
+** $Id: loadlib.c,v 1.70 2009/12/17 13:06:47 roberto Exp roberto $
 ** Dynamic library loader for Lua
 ** See Copyright Notice in lua.h
 **
@@ -608,7 +608,8 @@ static int ll_module (lua_State *L) {
   if (!lua_istable(L, -1)) {  /* not found? */
     lua_pop(L, 1);  /* remove previous result */
     /* try global variable (and create one if it does not exist) */
-    if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL)
+    lua_pushglobaltable(L);
+    if (luaL_findtable(L, 0, modname, 1) != NULL)
       return luaL_error(L, "name conflict for module " LUA_QS, modname);
     lua_pushvalue(L, -1);
     lua_setfield(L, loaded, modname);  /* _LOADED[modname] = new table */
@@ -635,7 +636,7 @@ static int ll_seeall (lua_State *L) {
     lua_pushvalue(L, -1);
     lua_setmetatable(L, 1);
   }
-  lua_pushvalue(L, LUA_GLOBALSINDEX);
+  lua_pushglobaltable(L);
   lua_setfield(L, -2, "__index");  /* mt.__index = _G */
   return 0;
 }
@@ -713,7 +714,7 @@ LUAMOD_API int luaopen_package (lua_State *L) {
   /* set field `preload' */
   lua_newtable(L);
   lua_setfield(L, -2, "preload");
-  lua_pushvalue(L, LUA_GLOBALSINDEX);
+  lua_pushglobaltable(L);
   luaL_register(L, NULL, ll_funcs);  /* open lib into global table */
   lua_pop(L, 1);
   return 1;  /* return 'package' table */

+ 9 - 5
lstate.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 2.66 2009/12/16 16:42:58 roberto Exp roberto $
+** $Id: lstate.c,v 2.67 2009/12/17 12:26:09 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -119,7 +119,8 @@ static int cpcall (lua_State *L) {
   lua_CFunction f = *(lua_CFunction *)lua_touserdata(L, 1);
   lua_remove(L, 1);  /* remove f from stack */
   /* restore original environment for 'cpcall' */
-  lua_copy(L, LUA_GLOBALSINDEX, LUA_ENVIRONINDEX);
+  lua_pushglobaltable(L);
+  lua_replace(L, LUA_ENVIRONINDEX);
   return f(L);
 }
 
@@ -138,10 +139,13 @@ static void init_registry (lua_State *L, global_State *g) {
   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(&g->l_gt));
+  cp = luaF_newCclosure(L, 0, g->l_gt);
   cp->c.f = cpcall;
   setclvalue(L, &mt, cp);
   setobj2t(L, luaH_setint(L, registry, LUA_RIDX_CPCALL), &mt);
+  /* registry[LUA_RIDX_GLOBALS] = l_gt */
+  sethvalue(L, &mt, g->l_gt);
+  setobj2t(L, luaH_setint(L, registry, LUA_RIDX_GLOBALS), &mt);
 }
 
 
@@ -152,7 +156,7 @@ static void f_luaopen (lua_State *L, void *ud) {
   global_State *g = G(L);
   UNUSED(ud);
   stack_init(L, L);  /* init stack */
-  sethvalue(L, &g->l_gt, luaH_new(L));  /* table of globals */
+  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);
@@ -253,7 +257,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
   g->strt.nuse = 0;
   g->strt.hash = NULL;
   setnilvalue(&g->l_registry);
-  setnilvalue(&g->l_gt);
+  g->l_gt = NULL;
   luaZ_initbuffer(L, &g->buff);
   g->panic = NULL;
   g->version = lua_version(NULL);

+ 2 - 2
lstate.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.h,v 2.50 2009/11/26 11:39:20 roberto Exp roberto $
+** $Id: lstate.h,v 2.51 2009/12/11 13:39:34 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -138,7 +138,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 Table *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 */

+ 4 - 4
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 2.84 2009/12/16 16:42:58 roberto Exp roberto $
+** $Id: ltests.c,v 2.85 2009/12/17 16:20:01 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -376,7 +376,7 @@ int lua_checkmemory (lua_State *L) {
   GCObject *o;
   UpVal *uv;
   checkliveness(g, &g->l_registry);
-  checkliveness(g, &g->l_gt);
+  lua_assert(!isdead(g, obj2gco(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)));
@@ -767,7 +767,7 @@ static int loadlib (lua_State *L) {
     {NULL, NULL}
   };
   lua_State *L1 = getstate(L);
-  lua_pushvalue(L1, LUA_GLOBALSINDEX);
+  lua_pushglobaltable(L1);
   luaL_register(L1, NULL, libs);
   return 0;
 }
@@ -878,7 +878,7 @@ static int getindex_aux (lua_State *L, lua_State *L1, const char **pc) {
   skip(pc);
   switch (*(*pc)++) {
     case 'R': return LUA_REGISTRYINDEX;
-    case 'G': return LUA_GLOBALSINDEX;
+    case 'G': return luaL_error(L, "deprecated index 'G'");
     case 'E': return LUA_ENVIRONINDEX;
     case 'U': return lua_upvalueindex(getnum_aux(L, L1, pc));
     default: (*pc)--; return getnum_aux(L, L1, pc);

+ 5 - 5
lua.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lua.c,v 1.179 2009/12/17 13:07:41 roberto Exp roberto $
+** $Id: lua.c,v 1.180 2009/12/17 16:20:01 roberto Exp roberto $
 ** Lua stand-alone interpreter
 ** See Copyright Notice in lua.h
 */
@@ -214,7 +214,7 @@ static int dostring (lua_State *L, const char *s, const char *name) {
 
 
 static int dolibrary (lua_State *L, const char *name) {
-  lua_getfield(L, LUA_GLOBALSINDEX, "require");
+  lua_getfield(L, LUA_ENVIRONINDEX, "require");
   lua_pushstring(L, name);
   return report(L, docall(L, 1, 1));
 }
@@ -222,7 +222,7 @@ static int dolibrary (lua_State *L, const char *name) {
 
 static const char *get_prompt (lua_State *L, int firstline) {
   const char *p;
-  lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2");
+  lua_getfield(L, LUA_ENVIRONINDEX, firstline ? "_PROMPT" : "_PROMPT2");
   p = lua_tostring(L, -1);
   if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
   lua_pop(L, 1);  /* remove global */
@@ -296,7 +296,7 @@ static void dotty (lua_State *L) {
     report(L, status);
     if (status == LUA_OK && lua_gettop(L) > 0) {  /* any result to print? */
       luaL_checkstack(L, LUA_MINSTACK, "too many results to print");
-      lua_getfield(L, LUA_GLOBALSINDEX, "print");
+      lua_getfield(L, LUA_ENVIRONINDEX, "print");
       lua_insert(L, 1);
       if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != LUA_OK)
         l_message(progname, lua_pushfstring(L,
@@ -315,7 +315,7 @@ static int handle_script (lua_State *L, char **argv, int n) {
   int status;
   const char *fname;
   int narg = getargs(L, argv, n);  /* collect arguments */
-  lua_setfield(L, LUA_GLOBALSINDEX, "arg");
+  lua_setfield(L, LUA_ENVIRONINDEX, "arg");
   fname = argv[n];
   if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0)
     fname = NULL;  /* stdin */

+ 9 - 6
lua.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lua.h,v 1.254 2009/12/17 16:20:01 roberto Exp roberto $
+** $Id: lua.h,v 1.255 2009/12/18 15:32:36 roberto Exp roberto $
 ** Lua - A Scripting Language
 ** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
 ** See Copyright Notice at the end of this file
@@ -35,8 +35,7 @@
 */
 #define LUA_REGISTRYINDEX	LUAI_FIRSTPSEUDOIDX
 #define LUA_ENVIRONINDEX	(LUA_REGISTRYINDEX - 1)
-#define LUA_GLOBALSINDEX	(LUA_ENVIRONINDEX - 1)
-#define lua_upvalueindex(i)	(LUA_GLOBALSINDEX-(i))
+#define lua_upvalueindex(i)	(LUA_ENVIRONINDEX - (i))
 
 
 /* thread status */
@@ -92,7 +91,8 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
 /* predefined values in the registry */
 #define LUA_RIDX_MAINTHREAD	1
 #define LUA_RIDX_CPCALL		2
-#define LUA_RIDX_LAST		LUA_RIDX_CPCALL
+#define LUA_RIDX_GLOBALS	3
+#define LUA_RIDX_LAST		LUA_RIDX_GLOBALS
 
 
 /* type of numbers in Lua */
@@ -315,8 +315,8 @@ LUA_API void      (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
 #define lua_pushliteral(L, s)	\
 	lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
 
-#define lua_setglobal(L,s)	lua_setfield(L, LUA_GLOBALSINDEX, (s))
-#define lua_getglobal(L,s)	lua_getfield(L, LUA_GLOBALSINDEX, (s))
+#define lua_pushglobaltable(L)  \
+	lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)
 
 #define lua_tostring(L,i)	lua_tolstring(L, (i), NULL)
 
@@ -343,6 +343,9 @@ LUA_API void      (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
 #define lua_equal(L,idx1,idx2)		lua_compare(L,(idx1),(idx2),LUA_OPEQ)
 #define lua_lessthan(L,idx1,idx2)	lua_compare(L,(idx1),(idx2),LUA_OPLT)
 
+#define lua_setglobal(L,s)	lua_setfield(L, LUA_ENVIRONINDEX, (s))
+#define lua_getglobal(L,s)	lua_getfield(L, LUA_ENVIRONINDEX, (s))
+
 #endif