mirror of
https://github.com/lua/lua
synced 2025-04-13 08:22:51 +03:00
Main thread is a regular field of global_State
They were already allocated as a single block, so there is no need for the global_State to point to its main thread.
This commit is contained in:
parent
d1e677c52b
commit
fa1382b5cd
2
lapi.c
2
lapi.c
@ -655,7 +655,7 @@ LUA_API int lua_pushthread (lua_State *L) {
|
||||
setthvalue(L, s2v(L->top.p), L);
|
||||
api_incr_top(L);
|
||||
lua_unlock(L);
|
||||
return (G(L)->mainthread == L);
|
||||
return (mainthread(G(L)) == L);
|
||||
}
|
||||
|
||||
|
||||
|
9
ldo.c
9
ldo.c
@ -132,11 +132,12 @@ l_noret luaD_throw (lua_State *L, TStatus errcode) {
|
||||
}
|
||||
else { /* thread has no error handler */
|
||||
global_State *g = G(L);
|
||||
lua_State *mainth = mainthread(g);
|
||||
errcode = luaE_resetthread(L, errcode); /* close all upvalues */
|
||||
L->status = errcode;
|
||||
if (g->mainthread->errorJmp) { /* main thread has a handler? */
|
||||
setobjs2s(L, g->mainthread->top.p++, L->top.p - 1); /* copy error obj. */
|
||||
luaD_throw(g->mainthread, errcode); /* re-throw in main thread */
|
||||
if (mainth->errorJmp) { /* main thread has a handler? */
|
||||
setobjs2s(L, mainth->top.p++, L->top.p - 1); /* copy error obj. */
|
||||
luaD_throw(mainth, errcode); /* re-throw in main thread */
|
||||
}
|
||||
else { /* no handler at all; abort */
|
||||
if (g->panic) { /* panic function? */
|
||||
@ -961,7 +962,7 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
|
||||
ci = L->ci;
|
||||
api_checkpop(L, nresults);
|
||||
if (l_unlikely(!yieldable(L))) {
|
||||
if (L != G(L)->mainthread)
|
||||
if (L != mainthread(G(L)))
|
||||
luaG_runerror(L, "attempt to yield across a C-call boundary");
|
||||
else
|
||||
luaG_runerror(L, "attempt to yield from outside a coroutine");
|
||||
|
8
lgc.c
8
lgc.c
@ -78,7 +78,7 @@
|
||||
((*getArrTag(t,i) & BIT_ISCOLLECTABLE) ? getArrVal(t,i)->gc : NULL)
|
||||
|
||||
|
||||
#define markvalue(g,o) { checkliveness(g->mainthread,o); \
|
||||
#define markvalue(g,o) { checkliveness(mainthread(g),o); \
|
||||
if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
|
||||
|
||||
#define markkey(g, n) { if keyiswhite(n) reallymarkobject(g,gckey(n)); }
|
||||
@ -441,7 +441,7 @@ static void cleargraylists (global_State *g) {
|
||||
static void restartcollection (global_State *g) {
|
||||
cleargraylists(g);
|
||||
g->GCmarked = 0;
|
||||
markobject(g, g->mainthread);
|
||||
markobject(g, mainthread(g));
|
||||
markvalue(g, &g->l_registry);
|
||||
markmt(g);
|
||||
markbeingfnz(g); /* mark any finalizing object left from previous cycle */
|
||||
@ -1513,7 +1513,7 @@ void luaC_freeallobjects (lua_State *L) {
|
||||
separatetobefnz(g, 1); /* separate all objects with finalizers */
|
||||
lua_assert(g->finobj == NULL);
|
||||
callallpendingfinalizers(L);
|
||||
deletelist(L, g->allgc, obj2gco(g->mainthread));
|
||||
deletelist(L, g->allgc, obj2gco(mainthread(g)));
|
||||
lua_assert(g->finobj == NULL); /* no new finalizers */
|
||||
deletelist(L, g->fixedgc, NULL); /* collect fixed objects */
|
||||
lua_assert(g->strt.nuse == 0);
|
||||
@ -1526,7 +1526,7 @@ static void atomic (lua_State *L) {
|
||||
GCObject *grayagain = g->grayagain; /* save original list */
|
||||
g->grayagain = NULL;
|
||||
lua_assert(g->ephemeron == NULL && g->weak == NULL);
|
||||
lua_assert(!iswhite(g->mainthread));
|
||||
lua_assert(!iswhite(mainthread(g)));
|
||||
g->gcstate = GCSatomic;
|
||||
markobject(g, L); /* mark running thread */
|
||||
/* registry and global metatables may be changed by API */
|
||||
|
39
lstate.c
39
lstate.c
@ -29,25 +29,6 @@
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** thread state + extra space
|
||||
*/
|
||||
typedef struct LX {
|
||||
lu_byte extra_[LUA_EXTRASPACE];
|
||||
lua_State l;
|
||||
} LX;
|
||||
|
||||
|
||||
/*
|
||||
** Main thread combines a thread state and the global state
|
||||
*/
|
||||
typedef struct LG {
|
||||
LX l;
|
||||
global_State g;
|
||||
} LG;
|
||||
|
||||
|
||||
|
||||
#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))
|
||||
|
||||
|
||||
@ -278,8 +259,8 @@ static void close_state (lua_State *L) {
|
||||
}
|
||||
luaM_freearray(L, G(L)->strt.hash, cast_sizet(G(L)->strt.size));
|
||||
freestack(L);
|
||||
lua_assert(gettotalbytes(g) == sizeof(LG));
|
||||
(*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
|
||||
lua_assert(gettotalbytes(g) == sizeof(global_State));
|
||||
(*g->frealloc)(g->ud, g, sizeof(global_State), 0); /* free main block */
|
||||
}
|
||||
|
||||
|
||||
@ -301,7 +282,7 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
|
||||
L1->hook = L->hook;
|
||||
resethookcount(L1);
|
||||
/* initialize L1 extra space */
|
||||
memcpy(lua_getextraspace(L1), lua_getextraspace(g->mainthread),
|
||||
memcpy(lua_getextraspace(L1), lua_getextraspace(mainthread(g)),
|
||||
LUA_EXTRASPACE);
|
||||
luai_userstatethread(L, L1);
|
||||
stack_init(L1, L); /* init stack */
|
||||
@ -352,11 +333,10 @@ LUA_API int lua_closethread (lua_State *L, lua_State *from) {
|
||||
LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud, unsigned seed) {
|
||||
int i;
|
||||
lua_State *L;
|
||||
global_State *g;
|
||||
LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG)));
|
||||
if (l == NULL) return NULL;
|
||||
L = &l->l.l;
|
||||
g = &l->g;
|
||||
global_State *g = cast(global_State*,
|
||||
(*f)(ud, NULL, LUA_TTHREAD, sizeof(global_State)));
|
||||
if (g == NULL) return NULL;
|
||||
L = &g->mainth.l;
|
||||
L->tt = LUA_VTHREAD;
|
||||
g->currentwhite = bitmask(WHITE0BIT);
|
||||
L->marked = luaC_white(g);
|
||||
@ -368,7 +348,6 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud, unsigned seed) {
|
||||
g->ud = ud;
|
||||
g->warnf = NULL;
|
||||
g->ud_warn = NULL;
|
||||
g->mainthread = L;
|
||||
g->seed = seed;
|
||||
g->gcstp = GCSTPGC; /* no GC while building state */
|
||||
g->strt.size = g->strt.nuse = 0;
|
||||
@ -386,7 +365,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud, unsigned seed) {
|
||||
g->gray = g->grayagain = NULL;
|
||||
g->weak = g->ephemeron = g->allweak = NULL;
|
||||
g->twups = NULL;
|
||||
g->GCtotalbytes = sizeof(LG);
|
||||
g->GCtotalbytes = sizeof(global_State);
|
||||
g->GCmarked = 0;
|
||||
g->GCdebt = 0;
|
||||
setivalue(&g->nilvalue, 0); /* to signal that state is not yet built */
|
||||
@ -408,7 +387,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud, unsigned seed) {
|
||||
|
||||
LUA_API void lua_close (lua_State *L) {
|
||||
lua_lock(L);
|
||||
L = G(L)->mainthread; /* only the main thread can be closed */
|
||||
L = mainthread(G(L)); /* only the main thread can be closed */
|
||||
close_state(L);
|
||||
}
|
||||
|
||||
|
78
lstate.h
78
lstate.h
@ -283,6 +283,48 @@ struct CallInfo {
|
||||
#define getoah(ci) (((ci)->callstatus & CIST_OAH) ? 1 : 0)
|
||||
|
||||
|
||||
/*
|
||||
** 'per thread' state
|
||||
*/
|
||||
struct lua_State {
|
||||
CommonHeader;
|
||||
lu_byte allowhook;
|
||||
TStatus status;
|
||||
unsigned short nci; /* number of items in 'ci' list */
|
||||
StkIdRel top; /* first free slot in the stack */
|
||||
struct global_State *l_G;
|
||||
CallInfo *ci; /* call info for current function */
|
||||
StkIdRel stack_last; /* end of stack (last element + 1) */
|
||||
StkIdRel stack; /* stack base */
|
||||
UpVal *openupval; /* list of open upvalues in this stack */
|
||||
StkIdRel tbclist; /* list of to-be-closed variables */
|
||||
GCObject *gclist;
|
||||
struct lua_State *twups; /* list of threads with open upvalues */
|
||||
struct lua_longjmp *errorJmp; /* current error recover point */
|
||||
CallInfo base_ci; /* CallInfo for first level (C host) */
|
||||
volatile lua_Hook hook;
|
||||
ptrdiff_t errfunc; /* current error handling function (stack index) */
|
||||
l_uint32 nCcalls; /* number of nested non-yieldable or C calls */
|
||||
int oldpc; /* last pc traced */
|
||||
int basehookcount;
|
||||
int hookcount;
|
||||
volatile l_signalT hookmask;
|
||||
struct { /* info about transferred values (for call/return hooks) */
|
||||
int ftransfer; /* offset of first value transferred */
|
||||
int ntransfer; /* number of values transferred */
|
||||
} transferinfo;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** thread state + extra space
|
||||
*/
|
||||
typedef struct LX {
|
||||
lu_byte extra_[LUA_EXTRASPACE];
|
||||
lua_State l;
|
||||
} LX;
|
||||
|
||||
|
||||
/*
|
||||
** 'global state', shared by all threads of this state
|
||||
*/
|
||||
@ -324,50 +366,18 @@ typedef struct global_State {
|
||||
GCObject *finobjrold; /* list of really old objects with finalizers */
|
||||
struct lua_State *twups; /* list of threads with open upvalues */
|
||||
lua_CFunction panic; /* to be called in unprotected errors */
|
||||
struct lua_State *mainthread;
|
||||
TString *memerrmsg; /* message for memory-allocation errors */
|
||||
TString *tmname[TM_N]; /* array with tag-method names */
|
||||
struct Table *mt[LUA_NUMTYPES]; /* metatables for basic types */
|
||||
TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */
|
||||
lua_WarnFunction warnf; /* warning function */
|
||||
void *ud_warn; /* auxiliary data to 'warnf' */
|
||||
LX mainth; /* main thread of this state */
|
||||
} global_State;
|
||||
|
||||
|
||||
/*
|
||||
** 'per thread' state
|
||||
*/
|
||||
struct lua_State {
|
||||
CommonHeader;
|
||||
lu_byte allowhook;
|
||||
TStatus status;
|
||||
unsigned short nci; /* number of items in 'ci' list */
|
||||
StkIdRel top; /* first free slot in the stack */
|
||||
global_State *l_G;
|
||||
CallInfo *ci; /* call info for current function */
|
||||
StkIdRel stack_last; /* end of stack (last element + 1) */
|
||||
StkIdRel stack; /* stack base */
|
||||
UpVal *openupval; /* list of open upvalues in this stack */
|
||||
StkIdRel tbclist; /* list of to-be-closed variables */
|
||||
GCObject *gclist;
|
||||
struct lua_State *twups; /* list of threads with open upvalues */
|
||||
struct lua_longjmp *errorJmp; /* current error recover point */
|
||||
CallInfo base_ci; /* CallInfo for first level (C host) */
|
||||
volatile lua_Hook hook;
|
||||
ptrdiff_t errfunc; /* current error handling function (stack index) */
|
||||
l_uint32 nCcalls; /* number of nested non-yieldable or C calls */
|
||||
int oldpc; /* last pc traced */
|
||||
int basehookcount;
|
||||
int hookcount;
|
||||
volatile l_signalT hookmask;
|
||||
struct { /* info about transferred values (for call/return hooks) */
|
||||
int ftransfer; /* offset of first value transferred */
|
||||
int ntransfer; /* number of values transferred */
|
||||
} transferinfo;
|
||||
};
|
||||
|
||||
|
||||
#define G(L) (L->l_G)
|
||||
#define mainthread(G) (&(G)->mainth.l)
|
||||
|
||||
/*
|
||||
** 'g->nilvalue' being a nil value flags that the state was completely
|
||||
|
4
ltests.c
4
ltests.c
@ -408,7 +408,7 @@ static void checktable (global_State *g, Table *h) {
|
||||
for (n = gnode(h, 0); n < limit; n++) {
|
||||
if (!isempty(gval(n))) {
|
||||
TValue k;
|
||||
getnodekey(g->mainthread, &k, n);
|
||||
getnodekey(mainthread(g), &k, n);
|
||||
assert(!keyisnil(n));
|
||||
checkvalref(g, hgc, &k);
|
||||
checkvalref(g, hgc, gval(n));
|
||||
@ -672,7 +672,7 @@ int lua_checkmemory (lua_State *L) {
|
||||
l_mem totalin; /* total of objects that are in gray lists */
|
||||
l_mem totalshould; /* total of objects that should be in gray lists */
|
||||
if (keepinvariant(g)) {
|
||||
assert(!iswhite(g->mainthread));
|
||||
assert(!iswhite(mainthread(g)));
|
||||
assert(!iswhite(gcvalue(&g->l_registry)));
|
||||
}
|
||||
assert(!isdead(g, gcvalue(&g->l_registry)));
|
||||
|
Loading…
x
Reference in New Issue
Block a user