1*eda14cbcSMatt Macy /* BEGIN CSTYLED */ 2*eda14cbcSMatt Macy /* 3*eda14cbcSMatt Macy ** $Id: lstate.c,v 2.99.1.2 2013/11/08 17:45:31 roberto Exp $ 4*eda14cbcSMatt Macy ** Global State 5*eda14cbcSMatt Macy ** See Copyright Notice in lua.h 6*eda14cbcSMatt Macy */ 7*eda14cbcSMatt Macy 8*eda14cbcSMatt Macy 9*eda14cbcSMatt Macy #define lstate_c 10*eda14cbcSMatt Macy #define LUA_CORE 11*eda14cbcSMatt Macy 12*eda14cbcSMatt Macy #include <sys/lua/lua.h> 13*eda14cbcSMatt Macy 14*eda14cbcSMatt Macy #include "lapi.h" 15*eda14cbcSMatt Macy #include "ldebug.h" 16*eda14cbcSMatt Macy #include "ldo.h" 17*eda14cbcSMatt Macy #include "lfunc.h" 18*eda14cbcSMatt Macy #include "lgc.h" 19*eda14cbcSMatt Macy #include "llex.h" 20*eda14cbcSMatt Macy #include "lmem.h" 21*eda14cbcSMatt Macy #include "lstate.h" 22*eda14cbcSMatt Macy #include "lstring.h" 23*eda14cbcSMatt Macy #include "ltable.h" 24*eda14cbcSMatt Macy #include "ltm.h" 25*eda14cbcSMatt Macy 26*eda14cbcSMatt Macy 27*eda14cbcSMatt Macy #if !defined(LUAI_GCPAUSE) 28*eda14cbcSMatt Macy #define LUAI_GCPAUSE 200 /* 200% */ 29*eda14cbcSMatt Macy #endif 30*eda14cbcSMatt Macy 31*eda14cbcSMatt Macy #if !defined(LUAI_GCMAJOR) 32*eda14cbcSMatt Macy #define LUAI_GCMAJOR 200 /* 200% */ 33*eda14cbcSMatt Macy #endif 34*eda14cbcSMatt Macy 35*eda14cbcSMatt Macy #if !defined(LUAI_GCMUL) 36*eda14cbcSMatt Macy #define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ 37*eda14cbcSMatt Macy #endif 38*eda14cbcSMatt Macy 39*eda14cbcSMatt Macy 40*eda14cbcSMatt Macy #define MEMERRMSG "not enough memory" 41*eda14cbcSMatt Macy 42*eda14cbcSMatt Macy 43*eda14cbcSMatt Macy /* 44*eda14cbcSMatt Macy ** a macro to help the creation of a unique random seed when a state is 45*eda14cbcSMatt Macy ** created; the seed is used to randomize hashes. 46*eda14cbcSMatt Macy */ 47*eda14cbcSMatt Macy #if !defined(luai_makeseed) 48*eda14cbcSMatt Macy #define luai_makeseed() cast(unsigned int, gethrtime()) 49*eda14cbcSMatt Macy #endif 50*eda14cbcSMatt Macy 51*eda14cbcSMatt Macy 52*eda14cbcSMatt Macy 53*eda14cbcSMatt Macy /* 54*eda14cbcSMatt Macy ** thread state + extra space 55*eda14cbcSMatt Macy */ 56*eda14cbcSMatt Macy typedef struct LX { 57*eda14cbcSMatt Macy #if defined(LUAI_EXTRASPACE) 58*eda14cbcSMatt Macy char buff[LUAI_EXTRASPACE]; 59*eda14cbcSMatt Macy #endif 60*eda14cbcSMatt Macy lua_State l; 61*eda14cbcSMatt Macy } LX; 62*eda14cbcSMatt Macy 63*eda14cbcSMatt Macy 64*eda14cbcSMatt Macy /* 65*eda14cbcSMatt Macy ** Main thread combines a thread state and the global state 66*eda14cbcSMatt Macy */ 67*eda14cbcSMatt Macy typedef struct LG { 68*eda14cbcSMatt Macy LX l; 69*eda14cbcSMatt Macy global_State g; 70*eda14cbcSMatt Macy } LG; 71*eda14cbcSMatt Macy 72*eda14cbcSMatt Macy 73*eda14cbcSMatt Macy 74*eda14cbcSMatt Macy #define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) 75*eda14cbcSMatt Macy 76*eda14cbcSMatt Macy 77*eda14cbcSMatt Macy /* 78*eda14cbcSMatt Macy ** Compute an initial seed as random as possible. In ANSI, rely on 79*eda14cbcSMatt Macy ** Address Space Layout Randomization (if present) to increase 80*eda14cbcSMatt Macy ** randomness.. 81*eda14cbcSMatt Macy */ 82*eda14cbcSMatt Macy #define addbuff(b,p,e) \ 83*eda14cbcSMatt Macy { size_t t = cast(size_t, e); \ 84*eda14cbcSMatt Macy memcpy(buff + p, &t, sizeof(t)); p += sizeof(t); } 85*eda14cbcSMatt Macy 86*eda14cbcSMatt Macy static unsigned int makeseed (lua_State *L) { 87*eda14cbcSMatt Macy char buff[4 * sizeof(size_t)]; 88*eda14cbcSMatt Macy unsigned int h = luai_makeseed(); 89*eda14cbcSMatt Macy int p = 0; 90*eda14cbcSMatt Macy addbuff(buff, p, L); /* heap variable */ 91*eda14cbcSMatt Macy addbuff(buff, p, &h); /* local variable */ 92*eda14cbcSMatt Macy addbuff(buff, p, luaO_nilobject); /* global variable */ 93*eda14cbcSMatt Macy addbuff(buff, p, &lua_newstate); /* public function */ 94*eda14cbcSMatt Macy lua_assert(p == sizeof(buff)); 95*eda14cbcSMatt Macy return luaS_hash(buff, p, h); 96*eda14cbcSMatt Macy } 97*eda14cbcSMatt Macy 98*eda14cbcSMatt Macy 99*eda14cbcSMatt Macy /* 100*eda14cbcSMatt Macy ** set GCdebt to a new value keeping the value (totalbytes + GCdebt) 101*eda14cbcSMatt Macy ** invariant 102*eda14cbcSMatt Macy */ 103*eda14cbcSMatt Macy void luaE_setdebt (global_State *g, l_mem debt) { 104*eda14cbcSMatt Macy g->totalbytes -= (debt - g->GCdebt); 105*eda14cbcSMatt Macy g->GCdebt = debt; 106*eda14cbcSMatt Macy } 107*eda14cbcSMatt Macy 108*eda14cbcSMatt Macy 109*eda14cbcSMatt Macy CallInfo *luaE_extendCI (lua_State *L) { 110*eda14cbcSMatt Macy CallInfo *ci = luaM_new(L, CallInfo); 111*eda14cbcSMatt Macy lua_assert(L->ci->next == NULL); 112*eda14cbcSMatt Macy L->ci->next = ci; 113*eda14cbcSMatt Macy ci->previous = L->ci; 114*eda14cbcSMatt Macy ci->next = NULL; 115*eda14cbcSMatt Macy return ci; 116*eda14cbcSMatt Macy } 117*eda14cbcSMatt Macy 118*eda14cbcSMatt Macy 119*eda14cbcSMatt Macy void luaE_freeCI (lua_State *L) { 120*eda14cbcSMatt Macy CallInfo *ci = L->ci; 121*eda14cbcSMatt Macy CallInfo *next = ci->next; 122*eda14cbcSMatt Macy ci->next = NULL; 123*eda14cbcSMatt Macy while ((ci = next) != NULL) { 124*eda14cbcSMatt Macy next = ci->next; 125*eda14cbcSMatt Macy luaM_free(L, ci); 126*eda14cbcSMatt Macy } 127*eda14cbcSMatt Macy } 128*eda14cbcSMatt Macy 129*eda14cbcSMatt Macy 130*eda14cbcSMatt Macy static void stack_init (lua_State *L1, lua_State *L) { 131*eda14cbcSMatt Macy int i; CallInfo *ci; 132*eda14cbcSMatt Macy /* initialize stack array */ 133*eda14cbcSMatt Macy L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue); 134*eda14cbcSMatt Macy L1->stacksize = BASIC_STACK_SIZE; 135*eda14cbcSMatt Macy for (i = 0; i < BASIC_STACK_SIZE; i++) 136*eda14cbcSMatt Macy setnilvalue(L1->stack + i); /* erase new stack */ 137*eda14cbcSMatt Macy L1->top = L1->stack; 138*eda14cbcSMatt Macy L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; 139*eda14cbcSMatt Macy /* initialize first ci */ 140*eda14cbcSMatt Macy ci = &L1->base_ci; 141*eda14cbcSMatt Macy ci->next = ci->previous = NULL; 142*eda14cbcSMatt Macy ci->callstatus = 0; 143*eda14cbcSMatt Macy ci->func = L1->top; 144*eda14cbcSMatt Macy setnilvalue(L1->top++); /* 'function' entry for this 'ci' */ 145*eda14cbcSMatt Macy ci->top = L1->top + LUA_MINSTACK; 146*eda14cbcSMatt Macy L1->ci = ci; 147*eda14cbcSMatt Macy } 148*eda14cbcSMatt Macy 149*eda14cbcSMatt Macy 150*eda14cbcSMatt Macy static void freestack (lua_State *L) { 151*eda14cbcSMatt Macy if (L->stack == NULL) 152*eda14cbcSMatt Macy return; /* stack not completely built yet */ 153*eda14cbcSMatt Macy L->ci = &L->base_ci; /* free the entire 'ci' list */ 154*eda14cbcSMatt Macy luaE_freeCI(L); 155*eda14cbcSMatt Macy luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ 156*eda14cbcSMatt Macy } 157*eda14cbcSMatt Macy 158*eda14cbcSMatt Macy 159*eda14cbcSMatt Macy /* 160*eda14cbcSMatt Macy ** Create registry table and its predefined values 161*eda14cbcSMatt Macy */ 162*eda14cbcSMatt Macy static void init_registry (lua_State *L, global_State *g) { 163*eda14cbcSMatt Macy TValue mt; 164*eda14cbcSMatt Macy /* create registry */ 165*eda14cbcSMatt Macy Table *registry = luaH_new(L); 166*eda14cbcSMatt Macy sethvalue(L, &g->l_registry, registry); 167*eda14cbcSMatt Macy luaH_resize(L, registry, LUA_RIDX_LAST, 0); 168*eda14cbcSMatt Macy /* registry[LUA_RIDX_MAINTHREAD] = L */ 169*eda14cbcSMatt Macy setthvalue(L, &mt, L); 170*eda14cbcSMatt Macy luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt); 171*eda14cbcSMatt Macy /* registry[LUA_RIDX_GLOBALS] = table of globals */ 172*eda14cbcSMatt Macy sethvalue(L, &mt, luaH_new(L)); 173*eda14cbcSMatt Macy luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt); 174*eda14cbcSMatt Macy } 175*eda14cbcSMatt Macy 176*eda14cbcSMatt Macy 177*eda14cbcSMatt Macy /* 178*eda14cbcSMatt Macy ** open parts of the state that may cause memory-allocation errors 179*eda14cbcSMatt Macy */ 180*eda14cbcSMatt Macy static void f_luaopen (lua_State *L, void *ud) { 181*eda14cbcSMatt Macy global_State *g = G(L); 182*eda14cbcSMatt Macy UNUSED(ud); 183*eda14cbcSMatt Macy stack_init(L, L); /* init stack */ 184*eda14cbcSMatt Macy init_registry(L, g); 185*eda14cbcSMatt Macy luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ 186*eda14cbcSMatt Macy luaT_init(L); 187*eda14cbcSMatt Macy luaX_init(L); 188*eda14cbcSMatt Macy /* pre-create memory-error message */ 189*eda14cbcSMatt Macy g->memerrmsg = luaS_newliteral(L, MEMERRMSG); 190*eda14cbcSMatt Macy luaS_fix(g->memerrmsg); /* it should never be collected */ 191*eda14cbcSMatt Macy g->gcrunning = 1; /* allow gc */ 192*eda14cbcSMatt Macy g->version = lua_version(NULL); 193*eda14cbcSMatt Macy luai_userstateopen(L); 194*eda14cbcSMatt Macy } 195*eda14cbcSMatt Macy 196*eda14cbcSMatt Macy 197*eda14cbcSMatt Macy /* 198*eda14cbcSMatt Macy ** preinitialize a state with consistent values without allocating 199*eda14cbcSMatt Macy ** any memory (to avoid errors) 200*eda14cbcSMatt Macy */ 201*eda14cbcSMatt Macy static void preinit_state (lua_State *L, global_State *g) { 202*eda14cbcSMatt Macy G(L) = g; 203*eda14cbcSMatt Macy L->stack = NULL; 204*eda14cbcSMatt Macy L->ci = NULL; 205*eda14cbcSMatt Macy L->stacksize = 0; 206*eda14cbcSMatt Macy L->errorJmp = NULL; 207*eda14cbcSMatt Macy L->nCcalls = 0; 208*eda14cbcSMatt Macy L->hook = NULL; 209*eda14cbcSMatt Macy L->hookmask = 0; 210*eda14cbcSMatt Macy L->basehookcount = 0; 211*eda14cbcSMatt Macy L->allowhook = 1; 212*eda14cbcSMatt Macy resethookcount(L); 213*eda14cbcSMatt Macy L->openupval = NULL; 214*eda14cbcSMatt Macy L->nny = 1; 215*eda14cbcSMatt Macy L->status = LUA_OK; 216*eda14cbcSMatt Macy L->errfunc = 0; 217*eda14cbcSMatt Macy L->runerror = 0; 218*eda14cbcSMatt Macy } 219*eda14cbcSMatt Macy 220*eda14cbcSMatt Macy 221*eda14cbcSMatt Macy static void close_state (lua_State *L) { 222*eda14cbcSMatt Macy global_State *g = G(L); 223*eda14cbcSMatt Macy luaF_close(L, L->stack); /* close all upvalues for this thread */ 224*eda14cbcSMatt Macy luaC_freeallobjects(L); /* collect all objects */ 225*eda14cbcSMatt Macy if (g->version) /* closing a fully built state? */ 226*eda14cbcSMatt Macy luai_userstateclose(L); 227*eda14cbcSMatt Macy luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); 228*eda14cbcSMatt Macy luaZ_freebuffer(L, &g->buff); 229*eda14cbcSMatt Macy freestack(L); 230*eda14cbcSMatt Macy lua_assert(gettotalbytes(g) == sizeof(LG)); 231*eda14cbcSMatt Macy (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */ 232*eda14cbcSMatt Macy } 233*eda14cbcSMatt Macy 234*eda14cbcSMatt Macy 235*eda14cbcSMatt Macy LUA_API lua_State *lua_newthread (lua_State *L) { 236*eda14cbcSMatt Macy lua_State *L1; 237*eda14cbcSMatt Macy lua_lock(L); 238*eda14cbcSMatt Macy luaC_checkGC(L); 239*eda14cbcSMatt Macy L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th; 240*eda14cbcSMatt Macy setthvalue(L, L->top, L1); 241*eda14cbcSMatt Macy api_incr_top(L); 242*eda14cbcSMatt Macy preinit_state(L1, G(L)); 243*eda14cbcSMatt Macy L1->hookmask = L->hookmask; 244*eda14cbcSMatt Macy L1->basehookcount = L->basehookcount; 245*eda14cbcSMatt Macy L1->hook = L->hook; 246*eda14cbcSMatt Macy resethookcount(L1); 247*eda14cbcSMatt Macy luai_userstatethread(L, L1); 248*eda14cbcSMatt Macy stack_init(L1, L); /* init stack */ 249*eda14cbcSMatt Macy lua_unlock(L); 250*eda14cbcSMatt Macy return L1; 251*eda14cbcSMatt Macy } 252*eda14cbcSMatt Macy 253*eda14cbcSMatt Macy 254*eda14cbcSMatt Macy void luaE_freethread (lua_State *L, lua_State *L1) { 255*eda14cbcSMatt Macy LX *l = fromstate(L1); 256*eda14cbcSMatt Macy luaF_close(L1, L1->stack); /* close all upvalues for this thread */ 257*eda14cbcSMatt Macy lua_assert(L1->openupval == NULL); 258*eda14cbcSMatt Macy luai_userstatefree(L, L1); 259*eda14cbcSMatt Macy freestack(L1); 260*eda14cbcSMatt Macy luaM_free(L, l); 261*eda14cbcSMatt Macy } 262*eda14cbcSMatt Macy 263*eda14cbcSMatt Macy 264*eda14cbcSMatt Macy LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { 265*eda14cbcSMatt Macy int i; 266*eda14cbcSMatt Macy lua_State *L; 267*eda14cbcSMatt Macy global_State *g; 268*eda14cbcSMatt Macy LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG))); 269*eda14cbcSMatt Macy if (l == NULL) return NULL; 270*eda14cbcSMatt Macy L = &l->l.l; 271*eda14cbcSMatt Macy g = &l->g; 272*eda14cbcSMatt Macy L->next = NULL; 273*eda14cbcSMatt Macy L->tt = LUA_TTHREAD; 274*eda14cbcSMatt Macy g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); 275*eda14cbcSMatt Macy L->marked = luaC_white(g); 276*eda14cbcSMatt Macy g->gckind = KGC_NORMAL; 277*eda14cbcSMatt Macy preinit_state(L, g); 278*eda14cbcSMatt Macy g->frealloc = f; 279*eda14cbcSMatt Macy g->ud = ud; 280*eda14cbcSMatt Macy g->mainthread = L; 281*eda14cbcSMatt Macy g->seed = makeseed(L); 282*eda14cbcSMatt Macy g->uvhead.u.l.prev = &g->uvhead; 283*eda14cbcSMatt Macy g->uvhead.u.l.next = &g->uvhead; 284*eda14cbcSMatt Macy g->gcrunning = 0; /* no GC while building state */ 285*eda14cbcSMatt Macy g->GCestimate = 0; 286*eda14cbcSMatt Macy g->strt.size = 0; 287*eda14cbcSMatt Macy g->strt.nuse = 0; 288*eda14cbcSMatt Macy g->strt.hash = NULL; 289*eda14cbcSMatt Macy setnilvalue(&g->l_registry); 290*eda14cbcSMatt Macy luaZ_initbuffer(L, &g->buff); 291*eda14cbcSMatt Macy g->panic = NULL; 292*eda14cbcSMatt Macy g->version = NULL; 293*eda14cbcSMatt Macy g->gcstate = GCSpause; 294*eda14cbcSMatt Macy g->allgc = NULL; 295*eda14cbcSMatt Macy g->finobj = NULL; 296*eda14cbcSMatt Macy g->tobefnz = NULL; 297*eda14cbcSMatt Macy g->sweepgc = g->sweepfin = NULL; 298*eda14cbcSMatt Macy g->gray = g->grayagain = NULL; 299*eda14cbcSMatt Macy g->weak = g->ephemeron = g->allweak = NULL; 300*eda14cbcSMatt Macy g->totalbytes = sizeof(LG); 301*eda14cbcSMatt Macy g->GCdebt = 0; 302*eda14cbcSMatt Macy g->gcpause = LUAI_GCPAUSE; 303*eda14cbcSMatt Macy g->gcmajorinc = LUAI_GCMAJOR; 304*eda14cbcSMatt Macy g->gcstepmul = LUAI_GCMUL; 305*eda14cbcSMatt Macy for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; 306*eda14cbcSMatt Macy if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { 307*eda14cbcSMatt Macy /* memory allocation error: free partial state */ 308*eda14cbcSMatt Macy close_state(L); 309*eda14cbcSMatt Macy L = NULL; 310*eda14cbcSMatt Macy } 311*eda14cbcSMatt Macy return L; 312*eda14cbcSMatt Macy } 313*eda14cbcSMatt Macy 314*eda14cbcSMatt Macy 315*eda14cbcSMatt Macy LUA_API void lua_close (lua_State *L) { 316*eda14cbcSMatt Macy L = G(L)->mainthread; /* only the main thread can be closed */ 317*eda14cbcSMatt Macy lua_lock(L); 318*eda14cbcSMatt Macy close_state(L); 319*eda14cbcSMatt Macy } 320*eda14cbcSMatt Macy /* END CSTYLED */ 321