Line data Source code
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 106 : static unsigned int makeseed (lua_State *L) {
82 : char buff[4 * sizeof(size_t)];
83 106 : unsigned int h = luai_makeseed();
84 106 : int p = 0;
85 106 : addbuff(buff, p, L); /* heap variable */
86 106 : addbuff(buff, p, &h); /* local variable */
87 106 : addbuff(buff, p, luaO_nilobject); /* global variable */
88 106 : addbuff(buff, p, &lua_newstate); /* public function */
89 : lua_assert(p == sizeof(buff));
90 106 : 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 1183 : void luaE_setdebt (global_State *g, l_mem debt) {
99 1183 : l_mem tb = gettotalbytes(g);
100 : lua_assert(tb > 0);
101 1183 : if (debt < tb - MAX_LMEM)
102 0 : debt = tb - MAX_LMEM; /* will make 'totalbytes == MAX_LMEM' */
103 1183 : g->totalbytes = tb - debt;
104 1183 : g->GCdebt = debt;
105 1183 : }
106 :
107 :
108 1220 : CallInfo *luaE_extendCI (lua_State *L) {
109 1220 : CallInfo *ci = luaM_new(L, CallInfo);
110 : lua_assert(L->ci->next == NULL);
111 1220 : L->ci->next = ci;
112 1220 : ci->previous = L->ci;
113 1220 : ci->next = NULL;
114 1220 : L->nci++;
115 1220 : return ci;
116 : }
117 :
118 :
119 : /*
120 : ** free all CallInfo structures not in use by a thread
121 : */
122 115 : void luaE_freeCI (lua_State *L) {
123 115 : CallInfo *ci = L->ci;
124 115 : CallInfo *next = ci->next;
125 115 : ci->next = NULL;
126 742 : while ((ci = next) != NULL) {
127 627 : next = ci->next;
128 627 : luaM_free(L, ci);
129 627 : L->nci--;
130 : }
131 115 : }
132 :
133 :
134 : /*
135 : ** free half of the CallInfo structures not in use by a thread
136 : */
137 788 : void luaE_shrinkCI (lua_State *L) {
138 788 : CallInfo *ci = L->ci;
139 : CallInfo *next2; /* next's next */
140 : /* while there are two nexts */
141 1326 : while (ci->next != NULL && (next2 = ci->next->next) != NULL) {
142 538 : luaM_free(L, ci->next); /* free next */
143 538 : L->nci--;
144 538 : ci->next = next2; /* remove 'next' from the list */
145 538 : next2->previous = ci;
146 538 : ci = next2; /* keep next's next */
147 : }
148 788 : }
149 :
150 :
151 133 : static void stack_init (lua_State *L1, lua_State *L) {
152 : int i; CallInfo *ci;
153 : /* initialize stack array */
154 133 : L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue);
155 133 : L1->stacksize = BASIC_STACK_SIZE;
156 5453 : for (i = 0; i < BASIC_STACK_SIZE; i++)
157 5320 : setnilvalue(L1->stack + i); /* erase new stack */
158 133 : L1->top = L1->stack;
159 133 : L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
160 : /* initialize first ci */
161 133 : ci = &L1->base_ci;
162 133 : ci->next = ci->previous = NULL;
163 133 : ci->callstatus = 0;
164 133 : ci->func = L1->top;
165 133 : setnilvalue(L1->top++); /* 'function' entry for this 'ci' */
166 133 : ci->top = L1->top + LUA_MINSTACK;
167 133 : L1->ci = ci;
168 133 : }
169 :
170 :
171 115 : static void freestack (lua_State *L) {
172 115 : if (L->stack == NULL)
173 0 : return; /* stack not completely built yet */
174 115 : L->ci = &L->base_ci; /* free the entire 'ci' list */
175 115 : luaE_freeCI(L);
176 : lua_assert(L->nci == 0);
177 115 : luaM_freearray(L, L->stack, L->stacksize); /* free stack array */
178 : }
179 :
180 :
181 : /*
182 : ** Create registry table and its predefined values
183 : */
184 106 : static void init_registry (lua_State *L, global_State *g) {
185 : TValue temp;
186 : /* create registry */
187 106 : Table *registry = luaH_new(L);
188 106 : sethvalue(L, &g->l_registry, registry);
189 106 : luaH_resize(L, registry, LUA_RIDX_LAST, 0);
190 : /* registry[LUA_RIDX_MAINTHREAD] = L */
191 106 : setthvalue(L, &temp, L); /* temp = L */
192 106 : luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp);
193 : /* registry[LUA_RIDX_GLOBALS] = table of globals */
194 106 : sethvalue(L, &temp, luaH_new(L)); /* temp = new table (global table) */
195 106 : luaH_setint(L, registry, LUA_RIDX_GLOBALS, &temp);
196 106 : }
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 106 : static void f_luaopen (lua_State *L, void *ud) {
204 106 : global_State *g = G(L);
205 : UNUSED(ud);
206 106 : stack_init(L, L); /* init stack */
207 106 : init_registry(L, g);
208 106 : luaS_init(L);
209 106 : luaT_init(L);
210 106 : luaX_init(L);
211 106 : g->gcrunning = 1; /* allow gc */
212 106 : g->version = lua_version(NULL);
213 : luai_userstateopen(L);
214 106 : }
215 :
216 :
217 : /*
218 : ** preinitialize a thread with consistent values without allocating
219 : ** any memory (to avoid errors)
220 : */
221 133 : static void preinit_thread (lua_State *L, global_State *g) {
222 133 : G(L) = g;
223 133 : L->stack = NULL;
224 133 : L->ci = NULL;
225 133 : L->nci = 0;
226 133 : L->stacksize = 0;
227 133 : L->twups = L; /* thread has no upvalues */
228 133 : L->errorJmp = NULL;
229 133 : L->nCcalls = 0;
230 133 : L->hook = NULL;
231 133 : L->hookmask = 0;
232 133 : L->basehookcount = 0;
233 133 : L->allowhook = 1;
234 133 : resethookcount(L);
235 133 : L->openupval = NULL;
236 133 : L->nny = 1;
237 133 : L->status = LUA_OK;
238 133 : L->errfunc = 0;
239 133 : }
240 :
241 :
242 88 : static void close_state (lua_State *L) {
243 88 : global_State *g = G(L);
244 88 : luaF_close(L, L->stack); /* close all upvalues for this thread */
245 88 : luaC_freeallobjects(L); /* collect all objects */
246 88 : if (g->version) /* closing a fully built state? */
247 : luai_userstateclose(L);
248 88 : luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
249 88 : freestack(L);
250 : lua_assert(gettotalbytes(g) == sizeof(LG));
251 88 : (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
252 88 : }
253 :
254 :
255 27 : LUA_API lua_State *lua_newthread (lua_State *L) {
256 27 : global_State *g = G(L);
257 : lua_State *L1;
258 : lua_lock(L);
259 27 : luaC_checkGC(L);
260 : /* create new thread */
261 27 : L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l;
262 27 : L1->marked = luaC_white(g);
263 27 : L1->tt = LUA_TTHREAD;
264 : /* link it on list 'allgc' */
265 27 : L1->next = g->allgc;
266 27 : g->allgc = obj2gco(L1);
267 : /* anchor it on L stack */
268 27 : setthvalue(L, L->top, L1);
269 27 : api_incr_top(L);
270 27 : preinit_thread(L1, g);
271 27 : L1->hookmask = L->hookmask;
272 27 : L1->basehookcount = L->basehookcount;
273 27 : L1->hook = L->hook;
274 27 : resethookcount(L1);
275 : /* initialize L1 extra space */
276 27 : memcpy(lua_getextraspace(L1), lua_getextraspace(g->mainthread),
277 : LUA_EXTRASPACE);
278 : luai_userstatethread(L, L1);
279 27 : stack_init(L1, L); /* init stack */
280 : lua_unlock(L);
281 27 : return L1;
282 : }
283 :
284 :
285 27 : void luaE_freethread (lua_State *L, lua_State *L1) {
286 27 : LX *l = fromstate(L1);
287 27 : luaF_close(L1, L1->stack); /* close all upvalues for this thread */
288 : lua_assert(L1->openupval == NULL);
289 : luai_userstatefree(L, L1);
290 27 : freestack(L1);
291 27 : luaM_free(L, l);
292 27 : }
293 :
294 :
295 106 : LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
296 : int i;
297 : lua_State *L;
298 : global_State *g;
299 106 : LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG)));
300 106 : if (l == NULL) return NULL;
301 106 : L = &l->l.l;
302 106 : g = &l->g;
303 106 : L->next = NULL;
304 106 : L->tt = LUA_TTHREAD;
305 106 : g->currentwhite = bitmask(WHITE0BIT);
306 106 : L->marked = luaC_white(g);
307 106 : preinit_thread(L, g);
308 106 : g->frealloc = f;
309 106 : g->ud = ud;
310 106 : g->mainthread = L;
311 106 : g->seed = makeseed(L);
312 106 : g->gcrunning = 0; /* no GC while building state */
313 106 : g->GCestimate = 0;
314 106 : g->strt.size = g->strt.nuse = 0;
315 106 : g->strt.hash = NULL;
316 106 : setnilvalue(&g->l_registry);
317 106 : g->panic = NULL;
318 106 : g->version = NULL;
319 106 : g->gcstate = GCSpause;
320 106 : g->gckind = KGC_NORMAL;
321 106 : g->allgc = g->finobj = g->tobefnz = g->fixedgc = NULL;
322 106 : g->sweepgc = NULL;
323 106 : g->gray = g->grayagain = NULL;
324 106 : g->weak = g->ephemeron = g->allweak = NULL;
325 106 : g->twups = NULL;
326 106 : g->totalbytes = sizeof(LG);
327 106 : g->GCdebt = 0;
328 106 : g->gcfinnum = 0;
329 106 : g->gcpause = LUAI_GCPAUSE;
330 106 : g->gcstepmul = LUAI_GCMUL;
331 1060 : for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
332 106 : if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
333 : /* memory allocation error: free partial state */
334 0 : close_state(L);
335 0 : L = NULL;
336 : }
337 106 : return L;
338 : }
339 :
340 :
341 88 : LUA_API void lua_close (lua_State *L) {
342 88 : L = G(L)->mainthread; /* only the main thread can be closed */
343 : lua_lock(L);
344 88 : close_state(L);
345 88 : }
346 :
347 :
|