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