no more pseudoindex LUA_GLOBALSINDEX; global table now accessible

through registry
This commit is contained in:
Roberto Ierusalimschy 2009-12-22 13:32:50 -02:00
parent 3cb343efd6
commit f84b575cfa
12 changed files with 63 additions and 53 deletions

13
lapi.c
View File

@ -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) */
}

View File

@ -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);

View File

@ -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' */
}

4
ldo.c
View File

@ -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 */

7
lgc.c
View File

@ -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 */

View File

@ -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
}

View File

@ -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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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);

10
lua.c
View File

@ -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 */

15
lua.h
View File

@ -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