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