Branch data Line data Source code
1 : : /*
2 : : ** $Id: lstate.c $
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 : :
32 : : /*
33 : : ** thread state + extra space
34 : : */
35 : : typedef struct LX {
36 : : lu_byte extra_[LUA_EXTRASPACE];
37 : : lua_State l;
38 : : } LX;
39 : :
40 : :
41 : : /*
42 : : ** Main thread combines a thread state and the global state
43 : : */
44 : : typedef struct LG {
45 : : LX l;
46 : : global_State g;
47 : : } LG;
48 : :
49 : :
50 : :
51 : : #define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))
52 : :
53 : :
54 : : /*
55 : : ** A macro to create a "random" seed when a state is created;
56 : : ** the seed is used to randomize string hashes.
57 : : */
58 : : #if !defined(luai_makeseed)
59 : :
60 : : #include <time.h>
61 : :
62 : : /*
63 : : ** Compute an initial seed with some level of randomness.
64 : : ** Rely on Address Space Layout Randomization (if present) and
65 : : ** current time.
66 : : */
67 : : #define addbuff(b,p,e) \
68 : : { size_t t = cast_sizet(e); \
69 : : memcpy(b + p, &t, sizeof(t)); p += sizeof(t); }
70 : :
71 : 810 : static unsigned int luai_makeseed (lua_State *L) {
72 : : char buff[3 * sizeof(size_t)];
73 : 810 : unsigned int h = cast_uint(time(NULL));
74 : 810 : int p = 0;
75 : 810 : addbuff(buff, p, L); /* heap variable */
76 : 810 : addbuff(buff, p, &h); /* local variable */
77 : 810 : addbuff(buff, p, &lua_newstate); /* public function */
78 : : lua_assert(p == sizeof(buff));
79 : 810 : return luaS_hash(buff, p, h);
80 : : }
81 : :
82 : : #endif
83 : :
84 : :
85 : : /*
86 : : ** set GCdebt to a new value keeping the value (totalbytes + GCdebt)
87 : : ** invariant (and avoiding underflows in 'totalbytes')
88 : : */
89 : 1965 : void luaE_setdebt (global_State *g, l_mem debt) {
90 : 1965 : l_mem tb = gettotalbytes(g);
91 : : lua_assert(tb > 0);
92 [ + - ]: 1965 : if (debt < tb - MAX_LMEM)
93 : 0 : debt = tb - MAX_LMEM; /* will make 'totalbytes == MAX_LMEM' */
94 : 1965 : g->totalbytes = tb - debt;
95 : 1965 : g->GCdebt = debt;
96 : 1965 : }
97 : :
98 : :
99 : 0 : LUA_API int lua_setcstacklimit (lua_State *L, unsigned int limit) {
100 : 0 : UNUSED(L); UNUSED(limit);
101 : 0 : return LUAI_MAXCCALLS; /* warning?? */
102 : : }
103 : :
104 : :
105 : 1462 : CallInfo *luaE_extendCI (lua_State *L) {
106 : : CallInfo *ci;
107 : : lua_assert(L->ci->next == NULL);
108 : 1462 : ci = luaM_new(L, CallInfo);
109 : : lua_assert(L->ci->next == NULL);
110 : 1462 : L->ci->next = ci;
111 : 1462 : ci->previous = L->ci;
112 : 1462 : ci->next = NULL;
113 : 1462 : ci->u.l.trap = 0;
114 : 1462 : L->nci++;
115 : 1462 : return ci;
116 : : }
117 : :
118 : :
119 : : /*
120 : : ** free all CallInfo structures not in use by a thread
121 : : */
122 : 40 : void luaE_freeCI (lua_State *L) {
123 : 40 : CallInfo *ci = L->ci;
124 : 40 : CallInfo *next = ci->next;
125 : 40 : ci->next = NULL;
126 [ + + ]: 112 : while ((ci = next) != NULL) {
127 : 72 : next = ci->next;
128 : 72 : luaM_free(L, ci);
129 : 72 : L->nci--;
130 : : }
131 : 40 : }
132 : :
133 : :
134 : : /*
135 : : ** free half of the CallInfo structures not in use by a thread,
136 : : ** keeping the first one.
137 : : */
138 : 2254 : void luaE_shrinkCI (lua_State *L) {
139 : 2254 : CallInfo *ci = L->ci->next; /* first free CallInfo */
140 : : CallInfo *next;
141 [ + + ]: 2254 : if (ci == NULL)
142 : 1784 : return; /* no extra elements */
143 [ + + ]: 479 : while ((next = ci->next) != NULL) { /* two extra elements? */
144 : 284 : CallInfo *next2 = next->next; /* next's next */
145 : 284 : ci->next = next2; /* remove next from the list */
146 : 284 : L->nci--;
147 : 284 : luaM_free(L, next); /* free next */
148 [ + + ]: 284 : if (next2 == NULL)
149 : 275 : break; /* no more elements */
150 : : else {
151 : 9 : next2->previous = ci;
152 : 9 : ci = next2; /* continue */
153 : : }
154 : : }
155 : 2254 : }
156 : :
157 : :
158 : : /*
159 : : ** Called when 'getCcalls(L)' larger or equal to LUAI_MAXCCALLS.
160 : : ** If equal, raises an overflow error. If value is larger than
161 : : ** LUAI_MAXCCALLS (which means it is handling an overflow) but
162 : : ** not much larger, does not report an error (to allow overflow
163 : : ** handling to work).
164 : : */
165 : 0 : void luaE_checkcstack (lua_State *L) {
166 [ # # ]: 0 : if (getCcalls(L) == LUAI_MAXCCALLS)
167 : 0 : luaG_runerror(L, "C stack overflow");
168 [ # # ]: 0 : else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11))
169 : 0 : luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
170 : 0 : }
171 : :
172 : :
173 : 3165 : LUAI_FUNC void luaE_incCstack (lua_State *L) {
174 : 3165 : L->nCcalls++;
175 [ - + ]: 3165 : if (unlikely(getCcalls(L) >= LUAI_MAXCCALLS))
176 : 0 : luaE_checkcstack(L);
177 : 3165 : }
178 : :
179 : :
180 : 810 : static void stack_init (lua_State *L1, lua_State *L) {
181 : : int i; CallInfo *ci;
182 : : /* initialize stack array */
183 : 810 : L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue);
184 [ + + ]: 37260 : for (i = 0; i < BASIC_STACK_SIZE + EXTRA_STACK; i++)
185 : 36450 : setnilvalue(s2v(L1->stack + i)); /* erase new stack */
186 : 810 : L1->top = L1->stack;
187 : 810 : L1->stack_last = L1->stack + BASIC_STACK_SIZE;
188 : : /* initialize first ci */
189 : 810 : ci = &L1->base_ci;
190 : 810 : ci->next = ci->previous = NULL;
191 : 810 : ci->callstatus = CIST_C;
192 : 810 : ci->func = L1->top;
193 : 810 : ci->u.c.k = NULL;
194 : 810 : ci->nresults = 0;
195 : 810 : setnilvalue(s2v(L1->top)); /* 'function' entry for this 'ci' */
196 : 810 : L1->top++;
197 : 810 : ci->top = L1->top + LUA_MINSTACK;
198 : 810 : L1->ci = ci;
199 : 810 : }
200 : :
201 : :
202 : 40 : static void freestack (lua_State *L) {
203 [ - + ]: 40 : if (L->stack == NULL)
204 : 0 : return; /* stack not completely built yet */
205 : 40 : L->ci = &L->base_ci; /* free the entire 'ci' list */
206 : 40 : luaE_freeCI(L);
207 : : lua_assert(L->nci == 0);
208 : 40 : luaM_freearray(L, L->stack, stacksize(L) + EXTRA_STACK); /* free stack */
209 : 40 : }
210 : :
211 : :
212 : : /*
213 : : ** Create registry table and its predefined values
214 : : */
215 : 810 : static void init_registry (lua_State *L, global_State *g) {
216 : : TValue temp;
217 : : /* create registry */
218 : 810 : Table *registry = luaH_new(L);
219 : 810 : sethvalue(L, &g->l_registry, registry);
220 : 810 : luaH_resize(L, registry, LUA_RIDX_LAST, 0);
221 : : /* registry[LUA_RIDX_MAINTHREAD] = L */
222 : 810 : setthvalue(L, &temp, L); /* temp = L */
223 : 810 : luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp);
224 : : /* registry[LUA_RIDX_GLOBALS] = table of globals */
225 : 810 : sethvalue(L, &temp, luaH_new(L)); /* temp = new table (global table) */
226 : 810 : luaH_setint(L, registry, LUA_RIDX_GLOBALS, &temp);
227 : 810 : }
228 : :
229 : :
230 : : /*
231 : : ** open parts of the state that may cause memory-allocation errors.
232 : : ** ('g->nilvalue' being a nil value flags that the state was completely
233 : : ** build.)
234 : : */
235 : 810 : static void f_luaopen (lua_State *L, void *ud) {
236 : 810 : global_State *g = G(L);
237 : 810 : UNUSED(ud);
238 : 810 : stack_init(L, L); /* init stack */
239 : 810 : init_registry(L, g);
240 : 810 : luaS_init(L);
241 : 810 : luaT_init(L);
242 : 810 : luaX_init(L);
243 : 810 : g->gcrunning = 1; /* allow gc */
244 : 810 : setnilvalue(&g->nilvalue);
245 : 810 : luai_userstateopen(L);
246 : 810 : }
247 : :
248 : :
249 : : /*
250 : : ** preinitialize a thread with consistent values without allocating
251 : : ** any memory (to avoid errors)
252 : : */
253 : 810 : static void preinit_thread (lua_State *L, global_State *g) {
254 : 810 : G(L) = g;
255 : 810 : L->stack = NULL;
256 : 810 : L->ci = NULL;
257 : 810 : L->nci = 0;
258 : 810 : L->twups = L; /* thread has no upvalues */
259 : 810 : L->errorJmp = NULL;
260 : 810 : L->hook = NULL;
261 : 810 : L->hookmask = 0;
262 : 810 : L->basehookcount = 0;
263 : 810 : L->allowhook = 1;
264 : 810 : resethookcount(L);
265 : 810 : L->openupval = NULL;
266 : 810 : L->status = LUA_OK;
267 : 810 : L->errfunc = 0;
268 : 810 : L->oldpc = 0;
269 : 810 : }
270 : :
271 : :
272 : 40 : static void close_state (lua_State *L) {
273 : 40 : global_State *g = G(L);
274 : 40 : luaF_close(L, L->stack, CLOSEPROTECT); /* close all upvalues */
275 : 40 : luaC_freeallobjects(L); /* collect all objects */
276 [ + - ]: 40 : if (ttisnil(&g->nilvalue)) /* closing a fully built state? */
277 : 40 : luai_userstateclose(L);
278 : 40 : luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
279 : 40 : freestack(L);
280 : : lua_assert(gettotalbytes(g) == sizeof(LG));
281 : 40 : (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
282 : 40 : }
283 : :
284 : :
285 : 0 : LUA_API lua_State *lua_newthread (lua_State *L) {
286 : : global_State *g;
287 : : lua_State *L1;
288 : : lua_lock(L);
289 : 0 : g = G(L);
290 [ # # ]: 0 : luaC_checkGC(L);
291 : : /* create new thread */
292 : 0 : L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l;
293 : 0 : L1->marked = luaC_white(g);
294 : 0 : L1->tt = LUA_VTHREAD;
295 : : /* link it on list 'allgc' */
296 : 0 : L1->next = g->allgc;
297 : 0 : g->allgc = obj2gco(L1);
298 : : /* anchor it on L stack */
299 : 0 : setthvalue2s(L, L->top, L1);
300 : 0 : api_incr_top(L);
301 : 0 : preinit_thread(L1, g);
302 : 0 : L1->nCcalls = 0;
303 : 0 : L1->hookmask = L->hookmask;
304 : 0 : L1->basehookcount = L->basehookcount;
305 : 0 : L1->hook = L->hook;
306 : 0 : resethookcount(L1);
307 : : /* initialize L1 extra space */
308 : 0 : memcpy(lua_getextraspace(L1), lua_getextraspace(g->mainthread),
309 : : LUA_EXTRASPACE);
310 : 0 : luai_userstatethread(L, L1);
311 : 0 : stack_init(L1, L); /* init stack */
312 : : lua_unlock(L);
313 : 0 : return L1;
314 : : }
315 : :
316 : :
317 : 0 : void luaE_freethread (lua_State *L, lua_State *L1) {
318 : 0 : LX *l = fromstate(L1);
319 : 0 : luaF_close(L1, L1->stack, NOCLOSINGMETH); /* close all upvalues */
320 : : lua_assert(L1->openupval == NULL);
321 : 0 : luai_userstatefree(L, L1);
322 : 0 : freestack(L1);
323 : 0 : luaM_free(L, l);
324 : 0 : }
325 : :
326 : :
327 : 0 : int lua_resetthread (lua_State *L) {
328 : : CallInfo *ci;
329 : : int status;
330 : : lua_lock(L);
331 : 0 : L->ci = ci = &L->base_ci; /* unwind CallInfo list */
332 : 0 : setnilvalue(s2v(L->stack)); /* 'function' entry for basic 'ci' */
333 : 0 : ci->func = L->stack;
334 : 0 : ci->callstatus = CIST_C;
335 : 0 : status = luaF_close(L, L->stack, CLOSEPROTECT);
336 [ # # ]: 0 : if (status != CLOSEPROTECT) /* real errors? */
337 : 0 : luaD_seterrorobj(L, status, L->stack + 1);
338 : : else {
339 : 0 : status = LUA_OK;
340 : 0 : L->top = L->stack + 1;
341 : : }
342 : 0 : ci->top = L->top + LUA_MINSTACK;
343 : 0 : L->status = status;
344 : : lua_unlock(L);
345 : 0 : return status;
346 : : }
347 : :
348 : :
349 : 810 : LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
350 : : int i;
351 : : lua_State *L;
352 : : global_State *g;
353 : 810 : LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG)));
354 [ - + ]: 810 : if (l == NULL) return NULL;
355 : 810 : L = &l->l.l;
356 : 810 : g = &l->g;
357 : 810 : L->tt = LUA_VTHREAD;
358 : 810 : g->currentwhite = bitmask(WHITE0BIT);
359 : 810 : L->marked = luaC_white(g);
360 : 810 : preinit_thread(L, g);
361 : 810 : g->allgc = obj2gco(L); /* by now, only object is the main thread */
362 : 810 : L->next = NULL;
363 : 810 : L->nCcalls = 0;
364 : 810 : incnny(L); /* main thread is always non yieldable */
365 : 810 : g->frealloc = f;
366 : 810 : g->ud = ud;
367 : 810 : g->warnf = NULL;
368 : 810 : g->ud_warn = NULL;
369 : 810 : g->mainthread = L;
370 : 810 : g->seed = luai_makeseed(L);
371 : 810 : g->gcrunning = 0; /* no GC while building state */
372 : 810 : g->strt.size = g->strt.nuse = 0;
373 : 810 : g->strt.hash = NULL;
374 : 810 : setnilvalue(&g->l_registry);
375 : 810 : g->panic = NULL;
376 : 810 : g->gcstate = GCSpause;
377 : 810 : g->gckind = KGC_INC;
378 : 810 : g->gcemergency = 0;
379 : 810 : g->finobj = g->tobefnz = g->fixedgc = NULL;
380 : 810 : g->firstold1 = g->survival = g->old1 = g->reallyold = NULL;
381 : 810 : g->finobjsur = g->finobjold1 = g->finobjrold = NULL;
382 : 810 : g->sweepgc = NULL;
383 : 810 : g->gray = g->grayagain = NULL;
384 : 810 : g->weak = g->ephemeron = g->allweak = NULL;
385 : 810 : g->twups = NULL;
386 : 810 : g->totalbytes = sizeof(LG);
387 : 810 : g->GCdebt = 0;
388 : 810 : g->lastatomic = 0;
389 : 810 : setivalue(&g->nilvalue, 0); /* to signal that state is not yet built */
390 : 810 : setgcparam(g->gcpause, LUAI_GCPAUSE);
391 : 810 : setgcparam(g->gcstepmul, LUAI_GCMUL);
392 : 810 : g->gcstepsize = LUAI_GCSTEPSIZE;
393 : 810 : setgcparam(g->genmajormul, LUAI_GENMAJORMUL);
394 : 810 : g->genminormul = LUAI_GENMINORMUL;
395 [ + + ]: 8100 : for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
396 [ + - ]: 810 : if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
397 : : /* memory allocation error: free partial state */
398 : 0 : close_state(L);
399 : 0 : L = NULL;
400 : 0 : }
401 : 810 : return L;
402 : 810 : }
403 : :
404 : :
405 : 40 : LUA_API void lua_close (lua_State *L) {
406 : : lua_lock(L);
407 : 40 : L = G(L)->mainthread; /* only the main thread can be closed */
408 : 40 : close_state(L);
409 : 40 : }
410 : :
411 : :
412 : 0 : void luaE_warning (lua_State *L, const char *msg, int tocont) {
413 : 0 : lua_WarnFunction wf = G(L)->warnf;
414 [ # # ]: 0 : if (wf != NULL)
415 : 0 : wf(G(L)->ud_warn, msg, tocont);
416 : 0 : }
417 : :
418 : :
419 : : /*
420 : : ** Generate a warning from an error message
421 : : */
422 : 0 : void luaE_warnerror (lua_State *L, const char *where) {
423 : 0 : TValue *errobj = s2v(L->top - 1); /* error object */
424 [ # # ]: 0 : const char *msg = (ttisstring(errobj))
425 : 0 : ? svalue(errobj)
426 : : : "error object is not a string";
427 : : /* produce warning "error in %s (%s)" (where, msg) */
428 : 0 : luaE_warning(L, "error in ", 1);
429 : 0 : luaE_warning(L, where, 1);
430 : 0 : luaE_warning(L, " (", 1);
431 : 0 : luaE_warning(L, msg, 1);
432 : 0 : luaE_warning(L, ")", 0);
433 : 0 : }
434 : :
|