aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-10-23 17:12:19 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-10-23 17:12:19 -0200
commit5bc91c640588ca77b9f84146fc88fcc9bdbfbcd1 (patch)
treed5d049ad2357648cabe25c19a8620566e9f27131
parentf5073de0a72562e1998f23052715e56a3b9fde18 (diff)
downloadlua-5bc91c640588ca77b9f84146fc88fcc9bdbfbcd1.tar.gz
lua-5bc91c640588ca77b9f84146fc88fcc9bdbfbcd1.tar.bz2
lua-5bc91c640588ca77b9f84146fc88fcc9bdbfbcd1.zip
no more one environment per thread: all threads share a single global
environment
-rw-r--r--lapi.c14
-rw-r--r--lbaselib.c13
-rw-r--r--ldo.c4
-rw-r--r--lgc.c9
-rw-r--r--lstate.c19
-rw-r--r--lstate.h10
-rw-r--r--ltests.c5
7 files changed, 27 insertions, 47 deletions
diff --git a/lapi.c b/lapi.c
index 8426dea0..acf50b14 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.92 2009/09/28 16:32:50 roberto Exp roberto $ 2** $Id: lapi.c,v 2.93 2009/10/05 16:44:33 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -55,13 +55,13 @@ static TValue *index2addr (lua_State *L, int idx) {
55 return L->top + idx; 55 return L->top + idx;
56 } 56 }
57 else switch (idx) { /* pseudo-indices */ 57 else switch (idx) { /* pseudo-indices */
58 case LUA_REGISTRYINDEX: return registry(L); 58 case LUA_REGISTRYINDEX: return &G(L)->l_registry;
59 case LUA_ENVIRONINDEX: { 59 case LUA_ENVIRONINDEX: {
60 Closure *func = curr_func(L); 60 Closure *func = curr_func(L);
61 sethvalue(L, &L->env, func->c.env); 61 sethvalue(L, &L->env, func->c.env);
62 return &L->env; 62 return &L->env;
63 } 63 }
64 case LUA_GLOBALSINDEX: return gt(L); 64 case LUA_GLOBALSINDEX: return &G(L)->l_gt;
65 default: { 65 default: {
66 Closure *func = curr_func(L); 66 Closure *func = curr_func(L);
67 idx = LUA_GLOBALSINDEX - idx; 67 idx = LUA_GLOBALSINDEX - idx;
@@ -76,7 +76,7 @@ static TValue *index2addr (lua_State *L, int idx) {
76 76
77static Table *getcurrenv (lua_State *L) { 77static Table *getcurrenv (lua_State *L) {
78 if (L->ci->previous == NULL) /* no enclosing function? */ 78 if (L->ci->previous == NULL) /* no enclosing function? */
79 return hvalue(gt(L)); /* use global table as environment */ 79 return hvalue(&G(L)->l_gt); /* use global table as environment */
80 else { 80 else {
81 Closure *func = curr_func(L); 81 Closure *func = curr_func(L);
82 return func->c.env; 82 return func->c.env;
@@ -633,9 +633,6 @@ LUA_API void lua_getfenv (lua_State *L, int idx) {
633 case LUA_TUSERDATA: 633 case LUA_TUSERDATA:
634 sethvalue(L, L->top, uvalue(o)->env); 634 sethvalue(L, L->top, uvalue(o)->env);
635 break; 635 break;
636 case LUA_TTHREAD:
637 setobj2s(L, L->top, gt(thvalue(o)));
638 break;
639 default: 636 default:
640 setnilvalue(L->top); 637 setnilvalue(L->top);
641 break; 638 break;
@@ -755,9 +752,6 @@ LUA_API int lua_setfenv (lua_State *L, int idx) {
755 case LUA_TUSERDATA: 752 case LUA_TUSERDATA:
756 uvalue(o)->env = hvalue(L->top - 1); 753 uvalue(o)->env = hvalue(L->top - 1);
757 break; 754 break;
758 case LUA_TTHREAD:
759 sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1));
760 break;
761 default: 755 default:
762 res = 0; 756 res = 0;
763 break; 757 break;
diff --git a/lbaselib.c b/lbaselib.c
index a2ebaeb1..050ba6a6 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbaselib.c,v 1.219 2009/10/05 16:44:33 roberto Exp roberto $ 2** $Id: lbaselib.c,v 1.220 2009/10/23 12:50:25 roberto Exp roberto $
3** Basic library 3** Basic library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -125,7 +125,7 @@ static void getfunc (lua_State *L, int opt) {
125static int luaB_getfenv (lua_State *L) { 125static int luaB_getfenv (lua_State *L) {
126 getfunc(L, 1); 126 getfunc(L, 1);
127 if (lua_iscfunction(L, -1)) /* is a C function? */ 127 if (lua_iscfunction(L, -1)) /* is a C function? */
128 lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */ 128 lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the global env. */
129 else 129 else
130 lua_getfenv(L, -1); 130 lua_getfenv(L, -1);
131 return 1; 131 return 1;
@@ -136,14 +136,7 @@ static int luaB_setfenv (lua_State *L) {
136 luaL_checktype(L, 2, LUA_TTABLE); 136 luaL_checktype(L, 2, LUA_TTABLE);
137 getfunc(L, 0); 137 getfunc(L, 0);
138 lua_pushvalue(L, 2); 138 lua_pushvalue(L, 2);
139 if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) { 139 if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
140 /* change environment of current thread */
141 lua_pushthread(L);
142 lua_insert(L, -2);
143 lua_setfenv(L, -2);
144 return 0;
145 }
146 else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
147 return luaL_error(L, 140 return luaL_error(L,
148 LUA_QL("setfenv") " cannot change environment of given object"); 141 LUA_QL("setfenv") " cannot change environment of given object");
149 return 1; 142 return 1;
diff --git a/ldo.c b/ldo.c
index 6affe61f..1af502ff 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.68 2009/09/28 16:32:50 roberto Exp roberto $ 2** $Id: ldo.c,v 2.69 2009/10/11 20:02:19 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -579,7 +579,7 @@ static void f_parser (lua_State *L, void *ud) {
579 : luaY_parser(L, p->z, &p->buff, &p->varl, p->name); 579 : luaY_parser(L, p->z, &p->buff, &p->varl, p->name);
580 setptvalue2s(L, L->top, tf); 580 setptvalue2s(L, L->top, tf);
581 incr_top(L); 581 incr_top(L);
582 cl = luaF_newLclosure(L, tf->sizeupvalues, hvalue(gt(L))); 582 cl = luaF_newLclosure(L, tf->sizeupvalues, hvalue(&G(L)->l_gt));
583 cl->l.p = tf; 583 cl->l.p = tf;
584 setclvalue(L, L->top - 1, cl); 584 setclvalue(L, L->top - 1, cl);
585 for (i = 0; i < tf->sizeupvalues; i++) /* initialize upvalues */ 585 for (i = 0; i < tf->sizeupvalues; i++) /* initialize upvalues */
diff --git a/lgc.c b/lgc.c
index 06a5a249..b372bb09 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.56 2009/09/28 13:50:34 roberto Exp roberto $ 2** $Id: lgc.c,v 2.57 2009/09/28 16:32:50 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -221,9 +221,9 @@ static void markroot (lua_State *L) {
221 g->grayagain = NULL; 221 g->grayagain = NULL;
222 g->weak = g->ephemeron = g->allweak = NULL; 222 g->weak = g->ephemeron = g->allweak = NULL;
223 markobject(g, g->mainthread); 223 markobject(g, g->mainthread);
224 /* make global table be traversed before main stack */ 224 /* make global table and registry to be traversed before main stack */
225 markvalue(g, gt(g->mainthread)); 225 markvalue(g, &g->l_gt);
226 markvalue(g, registry(L)); 226 markvalue(g, &g->l_registry);
227 markmt(g); 227 markmt(g);
228 markbeingfnz(g); /* mark any finalizing object left from previous cycle */ 228 markbeingfnz(g); /* mark any finalizing object left from previous cycle */
229 g->gcstate = GCSpropagate; 229 g->gcstate = GCSpropagate;
@@ -383,7 +383,6 @@ static void traversestack (global_State *g, lua_State *L) {
383 StkId o; 383 StkId o;
384 if (L->stack == NULL) 384 if (L->stack == NULL)
385 return; /* stack not completely built yet */ 385 return; /* stack not completely built yet */
386 markvalue(g, gt(L)); /* mark global table */
387 for (o = L->stack; o < L->top; o++) 386 for (o = L->stack; o < L->top; o++)
388 markvalue(g, o); 387 markvalue(g, o);
389 if (g->gcstate == GCSatomic) { /* final traversal? */ 388 if (g->gcstate == GCSatomic) { /* final traversal? */
diff --git a/lstate.c b/lstate.c
index b571c828..cb52eac3 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 2.61 2009/09/30 20:49:47 roberto Exp roberto $ 2** $Id: lstate.c,v 2.62 2009/10/05 16:44:33 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -108,18 +108,18 @@ static int cpcall (lua_State *L) {
108/* 108/*
109** Create registry table and its predefined values 109** Create registry table and its predefined values
110*/ 110*/
111static void init_registry (lua_State *L) { 111static void init_registry (lua_State *L, global_State *g) {
112 Closure *cp; 112 Closure *cp;
113 TValue mt; 113 TValue mt;
114 /* create registry */ 114 /* create registry */
115 Table *registry = luaH_new(L); 115 Table *registry = luaH_new(L);
116 sethvalue(L, registry(L), registry); 116 sethvalue(L, &g->l_registry, registry);
117 luaH_resize(L, registry, LUA_RIDX_LAST, 0); 117 luaH_resize(L, registry, LUA_RIDX_LAST, 0);
118 /* registry[LUA_RIDX_MAINTHREAD] = L */ 118 /* registry[LUA_RIDX_MAINTHREAD] = L */
119 setthvalue(L, &mt, L); 119 setthvalue(L, &mt, L);
120 setobj2t(L, luaH_setint(L, registry, LUA_RIDX_MAINTHREAD), &mt); 120 setobj2t(L, luaH_setint(L, registry, LUA_RIDX_MAINTHREAD), &mt);
121 /* registry[LUA_RIDX_CPCALL] = cpcall */ 121 /* registry[LUA_RIDX_CPCALL] = cpcall */
122 cp = luaF_newCclosure(L, 0, hvalue(gt(L))); 122 cp = luaF_newCclosure(L, 0, hvalue(&g->l_gt));
123 cp->c.f = cpcall; 123 cp->c.f = cpcall;
124 setclvalue(L, &mt, cp); 124 setclvalue(L, &mt, cp);
125 setobj2t(L, luaH_setint(L, registry, LUA_RIDX_CPCALL), &mt); 125 setobj2t(L, luaH_setint(L, registry, LUA_RIDX_CPCALL), &mt);
@@ -127,14 +127,14 @@ static void init_registry (lua_State *L) {
127 127
128 128
129/* 129/*
130** open parts of a state that may cause memory-allocation errors 130** open parts of the state that may cause memory-allocation errors
131*/ 131*/
132static void f_luaopen (lua_State *L, void *ud) { 132static void f_luaopen (lua_State *L, void *ud) {
133 global_State *g = G(L); 133 global_State *g = G(L);
134 UNUSED(ud); 134 UNUSED(ud);
135 stack_init(L, L); /* init stack */ 135 stack_init(L, L); /* init stack */
136 sethvalue(L, gt(L), luaH_new(L)); /* table of globals */ 136 sethvalue(L, &g->l_gt, luaH_new(L)); /* table of globals */
137 init_registry(L); 137 init_registry(L, g);
138 luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ 138 luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
139 luaT_init(L); 139 luaT_init(L);
140 luaX_init(L); 140 luaX_init(L);
@@ -164,7 +164,6 @@ static void preinit_state (lua_State *L, global_State *g) {
164 L->base_ci.next = L->base_ci.previous = NULL; 164 L->base_ci.next = L->base_ci.previous = NULL;
165 L->ci = &L->base_ci; 165 L->ci = &L->base_ci;
166 L->errfunc = 0; 166 L->errfunc = 0;
167 setnilvalue(gt(L));
168} 167}
169 168
170 169
@@ -190,7 +189,6 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
190 api_incr_top(L); 189 api_incr_top(L);
191 preinit_state(L1, G(L)); 190 preinit_state(L1, G(L));
192 stack_init(L1, L); /* init stack */ 191 stack_init(L1, L); /* init stack */
193 setobj2n(L, gt(L1), gt(L)); /* share table of globals */
194 L1->hookmask = L->hookmask; 192 L1->hookmask = L->hookmask;
195 L1->basehookcount = L->basehookcount; 193 L1->basehookcount = L->basehookcount;
196 L1->hook = L->hook; 194 L1->hook = L->hook;
@@ -236,7 +234,8 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
236 g->strt.size = 0; 234 g->strt.size = 0;
237 g->strt.nuse = 0; 235 g->strt.nuse = 0;
238 g->strt.hash = NULL; 236 g->strt.hash = NULL;
239 setnilvalue(registry(L)); 237 setnilvalue(&g->l_registry);
238 setnilvalue(&g->l_gt);
240 luaZ_initbuffer(L, &g->buff); 239 luaZ_initbuffer(L, &g->buff);
241 g->panic = NULL; 240 g->panic = NULL;
242 g->version = lua_version(NULL); 241 g->version = lua_version(NULL);
diff --git a/lstate.h b/lstate.h
index 2ddffaf1..dcceefe1 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 2.45 2009/06/18 18:59:18 roberto Exp roberto $ 2** $Id: lstate.h,v 2.46 2009/07/15 17:26:14 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -44,12 +44,6 @@
44struct lua_longjmp; /* defined in ldo.c */ 44struct lua_longjmp; /* defined in ldo.c */
45 45
46 46
47/* table of globals */
48#define gt(L) (&L->l_gt)
49
50/* registry */
51#define registry(L) (&G(L)->l_registry)
52
53 47
54/* extra stack space to handle TM calls and some other extras */ 48/* extra stack space to handle TM calls and some other extras */
55#define EXTRA_STACK 5 49#define EXTRA_STACK 5
@@ -146,6 +140,7 @@ typedef struct global_State {
146 int gcstepmul; /* GC `granularity' */ 140 int gcstepmul; /* GC `granularity' */
147 lua_CFunction panic; /* to be called in unprotected errors */ 141 lua_CFunction panic; /* to be called in unprotected errors */
148 TValue l_registry; 142 TValue l_registry;
143 TValue l_gt; /* table of globals */
149 struct lua_State *mainthread; 144 struct lua_State *mainthread;
150 UpVal uvhead; /* head of double-linked list of all open upvalues */ 145 UpVal uvhead; /* head of double-linked list of all open upvalues */
151 const lua_Number *version; /* pointer to version number */ 146 const lua_Number *version; /* pointer to version number */
@@ -173,7 +168,6 @@ struct lua_State {
173 int basehookcount; 168 int basehookcount;
174 int hookcount; 169 int hookcount;
175 lua_Hook hook; 170 lua_Hook hook;
176 TValue l_gt; /* table of globals */
177 TValue env; /* temporary place for environments */ 171 TValue env; /* temporary place for environments */
178 GCObject *openupval; /* list of open upvalues in this stack */ 172 GCObject *openupval; /* list of open upvalues in this stack */
179 GCObject *gclist; 173 GCObject *gclist;
diff --git a/ltests.c b/ltests.c
index 4fb7a4d2..ad7f418c 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.75 2009/10/05 16:44:33 roberto Exp roberto $ 2** $Id: ltests.c,v 2.76 2009/10/11 20:02:19 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -305,7 +305,6 @@ static void checkstack (global_State *g, lua_State *L1) {
305 lua_assert(uv->v != &uv->u.value); /* must be open */ 305 lua_assert(uv->v != &uv->u.value); /* must be open */
306 lua_assert(!isblack(uvo)); /* open upvalues cannot be black */ 306 lua_assert(!isblack(uvo)); /* open upvalues cannot be black */
307 } 307 }
308 checkliveness(g, gt(L1));
309 for (ci = L1->ci; ci != NULL; ci = ci->previous) { 308 for (ci = L1->ci; ci != NULL; ci = ci->previous) {
310 lua_assert(ci->top <= L1->stack_last); 309 lua_assert(ci->top <= L1->stack_last);
311 lua_assert(lua_checkpc(ci)); 310 lua_assert(lua_checkpc(ci));
@@ -366,6 +365,8 @@ int lua_checkmemory (lua_State *L) {
366 global_State *g = G(L); 365 global_State *g = G(L);
367 GCObject *o; 366 GCObject *o;
368 UpVal *uv; 367 UpVal *uv;
368 checkliveness(g, &g->l_registry);
369 checkliveness(g, &g->l_gt);
369 checkstack(g, g->mainthread); 370 checkstack(g, g->mainthread);
370 for (o = g->rootgc; o != obj2gco(g->mainthread); o = gch(o)->next) { 371 for (o = g->rootgc; o != obj2gco(g->mainthread); o = gch(o)->next) {
371 lua_assert(!testbits(o->gch.marked, bit2mask(SEPARATED, SFIXEDBIT))); 372 lua_assert(!testbits(o->gch.marked, bit2mask(SEPARATED, SFIXEDBIT)));