Line data Source code
1 : /*
2 : ** $Id: lstate.c,v 2.99.1.2 2013/11/08 17:45:31 roberto Exp $
3 : ** Global State
4 : ** See Copyright Notice in lua.h
5 : */
6 :
7 :
8 : #include <stddef.h>
9 : #include <string.h>
10 :
11 : #define lstate_c
12 : #define LUA_CORE
13 :
14 : #include "lua.h"
15 :
16 : #include "lapi.h"
17 : #include "ldebug.h"
18 : #include "ldo.h"
19 : #include "lfunc.h"
20 : #include "lgc.h"
21 : #include "llex.h"
22 : #include "lmem.h"
23 : #include "lstate.h"
24 : #include "lstring.h"
25 : #include "ltable.h"
26 : #include "ltm.h"
27 :
28 :
29 : #if !defined(LUAI_GCPAUSE)
30 : #define LUAI_GCPAUSE 200 /* 200% */
31 : #endif
32 :
33 : #if !defined(LUAI_GCMAJOR)
34 : #define LUAI_GCMAJOR 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 104 : static unsigned int makeseed (lua_State *L) {
90 : char buff[4 * sizeof(size_t)];
91 104 : unsigned int h = luai_makeseed();
92 104 : int p = 0;
93 104 : addbuff(buff, p, L); /* heap variable */
94 104 : addbuff(buff, p, &h); /* local variable */
95 104 : addbuff(buff, p, luaO_nilobject); /* global variable */
96 104 : addbuff(buff, p, &lua_newstate); /* public function */
97 : lua_assert(p == sizeof(buff));
98 104 : 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 2032 : void luaE_setdebt (global_State *g, l_mem debt) {
107 2032 : g->totalbytes -= (debt - g->GCdebt);
108 2032 : g->GCdebt = debt;
109 2032 : }
110 :
111 :
112 782 : CallInfo *luaE_extendCI (lua_State *L) {
113 782 : CallInfo *ci = luaM_new(L, CallInfo);
114 : lua_assert(L->ci->next == NULL);
115 782 : L->ci->next = ci;
116 782 : ci->previous = L->ci;
117 782 : ci->next = NULL;
118 782 : return ci;
119 : }
120 :
121 :
122 316 : void luaE_freeCI (lua_State *L) {
123 316 : CallInfo *ci = L->ci;
124 316 : CallInfo *next = ci->next;
125 316 : ci->next = NULL;
126 1040 : while ((ci = next) != NULL) {
127 724 : next = ci->next;
128 724 : luaM_free(L, ci);
129 : }
130 316 : }
131 :
132 :
133 130 : static void stack_init (lua_State *L1, lua_State *L) {
134 : int i; CallInfo *ci;
135 : /* initialize stack array */
136 130 : L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue);
137 130 : L1->stacksize = BASIC_STACK_SIZE;
138 5330 : for (i = 0; i < BASIC_STACK_SIZE; i++)
139 5200 : setnilvalue(L1->stack + i); /* erase new stack */
140 130 : L1->top = L1->stack;
141 130 : L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
142 : /* initialize first ci */
143 130 : ci = &L1->base_ci;
144 130 : ci->next = ci->previous = NULL;
145 130 : ci->callstatus = 0;
146 130 : ci->func = L1->top;
147 130 : setnilvalue(L1->top++); /* 'function' entry for this 'ci' */
148 130 : ci->top = L1->top + LUA_MINSTACK;
149 130 : L1->ci = ci;
150 130 : }
151 :
152 :
153 114 : static void freestack (lua_State *L) {
154 114 : if (L->stack == NULL)
155 0 : return; /* stack not completely built yet */
156 114 : L->ci = &L->base_ci; /* free the entire 'ci' list */
157 114 : luaE_freeCI(L);
158 114 : luaM_freearray(L, L->stack, L->stacksize); /* free stack array */
159 : }
160 :
161 :
162 : /*
163 : ** Create registry table and its predefined values
164 : */
165 104 : static void init_registry (lua_State *L, global_State *g) {
166 : TValue mt;
167 : /* create registry */
168 104 : Table *registry = luaH_new(L);
169 104 : sethvalue(L, &g->l_registry, registry);
170 104 : luaH_resize(L, registry, LUA_RIDX_LAST, 0);
171 : /* registry[LUA_RIDX_MAINTHREAD] = L */
172 104 : setthvalue(L, &mt, L);
173 104 : luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt);
174 : /* registry[LUA_RIDX_GLOBALS] = table of globals */
175 104 : sethvalue(L, &mt, luaH_new(L));
176 104 : luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt);
177 104 : }
178 :
179 :
180 : /*
181 : ** open parts of the state that may cause memory-allocation errors
182 : */
183 104 : static void f_luaopen (lua_State *L, void *ud) {
184 104 : global_State *g = G(L);
185 : UNUSED(ud);
186 104 : stack_init(L, L); /* init stack */
187 104 : init_registry(L, g);
188 104 : luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
189 104 : luaT_init(L);
190 104 : luaX_init(L);
191 : /* pre-create memory-error message */
192 104 : g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
193 104 : luaS_fix(g->memerrmsg); /* it should never be collected */
194 104 : g->gcrunning = 1; /* allow gc */
195 104 : g->version = lua_version(NULL);
196 : luai_userstateopen(L);
197 104 : }
198 :
199 :
200 : /*
201 : ** preinitialize a state with consistent values without allocating
202 : ** any memory (to avoid errors)
203 : */
204 130 : static void preinit_state (lua_State *L, global_State *g) {
205 130 : G(L) = g;
206 130 : L->stack = NULL;
207 130 : L->ci = NULL;
208 130 : L->stacksize = 0;
209 130 : L->errorJmp = NULL;
210 130 : L->nCcalls = 0;
211 130 : L->hook = NULL;
212 130 : L->hookmask = 0;
213 130 : L->basehookcount = 0;
214 130 : L->allowhook = 1;
215 130 : resethookcount(L);
216 130 : L->openupval = NULL;
217 130 : L->nny = 1;
218 130 : L->status = LUA_OK;
219 130 : L->errfunc = 0;
220 130 : }
221 :
222 :
223 88 : static void close_state (lua_State *L) {
224 88 : global_State *g = G(L);
225 88 : luaF_close(L, L->stack); /* close all upvalues for this thread */
226 88 : luaC_freeallobjects(L); /* collect all objects */
227 88 : if (g->version) /* closing a fully built state? */
228 : luai_userstateclose(L);
229 88 : luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
230 88 : luaZ_freebuffer(L, &g->buff);
231 88 : freestack(L);
232 : lua_assert(gettotalbytes(g) == sizeof(LG));
233 88 : (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
234 88 : }
235 :
236 :
237 26 : LUA_API lua_State *lua_newthread (lua_State *L) {
238 : lua_State *L1;
239 : lua_lock(L);
240 26 : luaC_checkGC(L);
241 26 : L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th;
242 26 : setthvalue(L, L->top, L1);
243 26 : api_incr_top(L);
244 26 : preinit_state(L1, G(L));
245 26 : L1->hookmask = L->hookmask;
246 26 : L1->basehookcount = L->basehookcount;
247 26 : L1->hook = L->hook;
248 26 : resethookcount(L1);
249 : luai_userstatethread(L, L1);
250 26 : stack_init(L1, L); /* init stack */
251 : lua_unlock(L);
252 26 : return L1;
253 : }
254 :
255 :
256 26 : void luaE_freethread (lua_State *L, lua_State *L1) {
257 26 : LX *l = fromstate(L1);
258 26 : luaF_close(L1, L1->stack); /* close all upvalues for this thread */
259 : lua_assert(L1->openupval == NULL);
260 : luai_userstatefree(L, L1);
261 26 : freestack(L1);
262 26 : luaM_free(L, l);
263 26 : }
264 :
265 :
266 104 : LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
267 : int i;
268 : lua_State *L;
269 : global_State *g;
270 104 : LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG)));
271 104 : if (l == NULL) return NULL;
272 104 : L = &l->l.l;
273 104 : g = &l->g;
274 104 : L->next = NULL;
275 104 : L->tt = LUA_TTHREAD;
276 104 : g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
277 104 : L->marked = luaC_white(g);
278 104 : g->gckind = KGC_NORMAL;
279 104 : preinit_state(L, g);
280 104 : g->frealloc = f;
281 104 : g->ud = ud;
282 104 : g->mainthread = L;
283 104 : g->seed = makeseed(L);
284 104 : g->uvhead.u.l.prev = &g->uvhead;
285 104 : g->uvhead.u.l.next = &g->uvhead;
286 104 : g->gcrunning = 0; /* no GC while building state */
287 104 : g->GCestimate = 0;
288 104 : g->strt.size = 0;
289 104 : g->strt.nuse = 0;
290 104 : g->strt.hash = NULL;
291 104 : setnilvalue(&g->l_registry);
292 104 : luaZ_initbuffer(L, &g->buff);
293 104 : g->panic = NULL;
294 104 : g->version = NULL;
295 104 : g->gcstate = GCSpause;
296 104 : g->allgc = NULL;
297 104 : g->finobj = NULL;
298 104 : g->tobefnz = NULL;
299 104 : g->sweepgc = g->sweepfin = NULL;
300 104 : g->gray = g->grayagain = NULL;
301 104 : g->weak = g->ephemeron = g->allweak = NULL;
302 104 : g->totalbytes = sizeof(LG);
303 104 : g->GCdebt = 0;
304 104 : g->gcpause = LUAI_GCPAUSE;
305 104 : g->gcmajorinc = LUAI_GCMAJOR;
306 104 : g->gcstepmul = LUAI_GCMUL;
307 1040 : for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
308 104 : if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
309 : /* memory allocation error: free partial state */
310 0 : close_state(L);
311 0 : L = NULL;
312 : }
313 104 : return L;
314 : }
315 :
316 :
317 88 : LUA_API void lua_close (lua_State *L) {
318 88 : L = G(L)->mainthread; /* only the main thread can be closed */
319 : lua_lock(L);
320 88 : close_state(L);
321 88 : }
322 :
323 :
|