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