diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-10-23 17:12:19 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-10-23 17:12:19 -0200 |
commit | 5bc91c640588ca77b9f84146fc88fcc9bdbfbcd1 (patch) | |
tree | d5d049ad2357648cabe25c19a8620566e9f27131 | |
parent | f5073de0a72562e1998f23052715e56a3b9fde18 (diff) | |
download | lua-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.c | 14 | ||||
-rw-r--r-- | lbaselib.c | 13 | ||||
-rw-r--r-- | ldo.c | 4 | ||||
-rw-r--r-- | lgc.c | 9 | ||||
-rw-r--r-- | lstate.c | 19 | ||||
-rw-r--r-- | lstate.h | 10 | ||||
-rw-r--r-- | ltests.c | 5 |
7 files changed, 27 insertions, 47 deletions
@@ -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 | ||
77 | static Table *getcurrenv (lua_State *L) { | 77 | static 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; |
@@ -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) { | |||
125 | static int luaB_getfenv (lua_State *L) { | 125 | static 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; |
@@ -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 */ |
@@ -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? */ |
@@ -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 | */ |
111 | static void init_registry (lua_State *L) { | 111 | static 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 | */ |
132 | static void f_luaopen (lua_State *L, void *ud) { | 132 | static 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); |
@@ -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 @@ | |||
44 | struct lua_longjmp; /* defined in ldo.c */ | 44 | struct 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; |
@@ -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))); |