xref: /aosp_15_r20/external/lua/src/lstate.c (revision 088332b5b69e7ab13924864b272aabfc2509d2d5)
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