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