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