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