gateway: simplify stopping the cleanup timer
[olsrd.git] / lib / tas / src / lua / lstate.c
1
2 /*
3 ** $Id: lstate.c,v 1.123 2003/04/03 13:35:34 roberto Exp $
4 ** Global State
5 ** See Copyright Notice in lua.h
6 */
7
8
9 #include <stdlib.h>
10
11 #define lstate_c
12
13 #include "lua.h"
14
15 #include "ldebug.h"
16 #include "ldo.h"
17 #include "lfunc.h"
18 #include "lgc.h"
19 #include "llex.h"
20 #include "lmem.h"
21 #include "lstate.h"
22 #include "lstring.h"
23 #include "ltable.h"
24 #include "ltm.h"
25
26
27 /*
28 ** macro to allow the inclusion of user information in Lua state
29 */
30 #ifndef LUA_USERSTATE
31 #define EXTRASPACE      0
32 #else
33 union UEXTRASPACE {
34   L_Umaxalign a;
35   LUA_USERSTATE b;
36 };
37 #define EXTRASPACE (sizeof(union UEXTRASPACE))
38 #endif
39
40
41
42 /*
43 ** you can change this function through the official API:
44 ** call `lua_setpanicf'
45 */
46 static int
47 default_panic(lua_State * L)
48 {
49   UNUSED(L);
50   return 0;
51 }
52
53
54 static lua_State *
55 mallocstate(lua_State * L)
56 {
57   lu_byte *block = (lu_byte *) luaM_malloc(L, sizeof(lua_State) + EXTRASPACE);
58   if (block == NULL)
59     return NULL;
60   else {
61     block += EXTRASPACE;
62     return cast_align(lua_State *, block);
63   }
64 }
65
66
67 static void
68 freestate(lua_State * L, lua_State * L1)
69 {
70   luaM_free(L, cast(lu_byte *, L1) - EXTRASPACE, sizeof(lua_State) + EXTRASPACE);
71 }
72
73
74 static void
75 stack_init(lua_State * L1, lua_State * L)
76 {
77   L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TObject);
78   L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
79   L1->top = L1->stack;
80   L1->stack_last = L1->stack + (L1->stacksize - EXTRA_STACK) - 1;
81   L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
82   L1->ci = L1->base_ci;
83   L1->ci->state = CI_C;         /*  not a Lua function */
84   setnilvalue(L1->top++);       /* `function' entry for this `ci' */
85   L1->base = L1->ci->base = L1->top;
86   L1->ci->top = L1->top + LUA_MINSTACK;
87   L1->size_ci = BASIC_CI_SIZE;
88   L1->end_ci = L1->base_ci + L1->size_ci;
89 }
90
91
92 static void
93 freestack(lua_State * L, lua_State * L1)
94 {
95   luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo);
96   luaM_freearray(L, L1->stack, L1->stacksize, TObject);
97 }
98
99
100 /*
101 ** open parts that may cause memory-allocation errors
102 */
103 static void
104 f_luaopen(lua_State * L, void *ud)
105 {
106   /* create a new global state */
107   global_State *g = luaM_new(NULL, global_State);
108   UNUSED(ud);
109   if (g == NULL)
110     luaD_throw(L, LUA_ERRMEM);
111   L->l_G = g;
112   g->mainthread = L;
113   g->GCthreshold = 0;           /* mark it as unfinished state */
114   g->strt.size = 0;
115   g->strt.nuse = 0;
116   g->strt.hash = NULL;
117   setnilvalue(defaultmeta(L));
118   setnilvalue(registry(L));
119   luaZ_initbuffer(L, &g->buff);
120   g->panic = default_panic;
121   g->rootgc = NULL;
122   g->rootudata = NULL;
123   g->tmudata = NULL;
124   setnilvalue(gkey(g->dummynode));
125   setnilvalue(gval(g->dummynode));
126   g->dummynode->next = NULL;
127   g->nblocks = sizeof(lua_State) + sizeof(global_State);
128   stack_init(L, L);             /* init stack */
129   /* create default meta table with a dummy table, and then close the loop */
130   defaultmeta(L)->tt = LUA_TTABLE;
131   sethvalue(defaultmeta(L), luaH_new(L, 0, 0));
132   hvalue(defaultmeta(L))->metatable = hvalue(defaultmeta(L));
133   sethvalue(gt(L), luaH_new(L, 0, 4));  /* table of globals */
134   sethvalue(registry(L), luaH_new(L, 4, 4));    /* registry */
135   luaS_resize(L, MINSTRTABSIZE);        /* initial size of string table */
136   luaT_init(L);
137   luaX_init(L);
138   luaS_fix(luaS_newliteral(L, MEMERRMSG));
139   g->GCthreshold = 4 * G(L)->nblocks;
140 }
141
142
143 static void
144 preinit_state(lua_State * L)
145 {
146   L->stack = NULL;
147   L->stacksize = 0;
148   L->errorJmp = NULL;
149   L->hook = NULL;
150   L->hookmask = L->hookinit = 0;
151   L->basehookcount = 0;
152   L->allowhook = 1;
153   resethookcount(L);
154   L->openupval = NULL;
155   L->size_ci = 0;
156   L->nCcalls = 0;
157   L->base_ci = L->ci = NULL;
158   L->errfunc = 0;
159   setnilvalue(gt(L));
160 }
161
162
163 static void
164 close_state(lua_State * L)
165 {
166   luaF_close(L, L->stack);      /* close all upvalues for this thread */
167   if (G(L)) {                   /* close global state */
168     luaC_sweep(L, 1);           /* collect all elements */
169     lua_assert(G(L)->rootgc == NULL);
170     lua_assert(G(L)->rootudata == NULL);
171     luaS_freeall(L);
172     luaZ_freebuffer(L, &G(L)->buff);
173   }
174   freestack(L, L);
175   if (G(L)) {
176     lua_assert(G(L)->nblocks == sizeof(lua_State) + sizeof(global_State));
177     luaM_freelem(NULL, G(L));
178   }
179   freestate(NULL, L);
180 }
181
182
183 lua_State *
184 luaE_newthread(lua_State * L)
185 {
186   lua_State *L1 = mallocstate(L);
187   luaC_link(L, valtogco(L1), LUA_TTHREAD);
188   preinit_state(L1);
189   L1->l_G = L->l_G;
190   stack_init(L1, L);            /* init stack */
191   setobj2n(gt(L1), gt(L));      /* share table of globals */
192   return L1;
193 }
194
195
196 void
197 luaE_freethread(lua_State * L, lua_State * L1)
198 {
199   luaF_close(L1, L1->stack);    /* close all upvalues for this thread */
200   lua_assert(L1->openupval == NULL);
201   freestack(L, L1);
202   freestate(L, L1);
203 }
204
205
206 LUA_API lua_State *
207 lua_open(void)
208 {
209   lua_State *L = mallocstate(NULL);
210   if (L) {                      /* allocation OK? */
211     L->tt = LUA_TTHREAD;
212     L->marked = 0;
213     L->next = L->gclist = NULL;
214     preinit_state(L);
215     L->l_G = NULL;
216     if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
217       /* memory allocation error: free partial state */
218       close_state(L);
219       L = NULL;
220     }
221   }
222   lua_userstateopen(L);
223   return L;
224 }
225
226
227 static void
228 callallgcTM(lua_State * L, void *ud)
229 {
230   UNUSED(ud);
231   luaC_callGCTM(L);             /* call GC metamethods for all udata */
232 }
233
234
235 LUA_API void
236 lua_close(lua_State * L)
237 {
238   lua_lock(L);
239   L = G(L)->mainthread;         /* only the main thread can be closed */
240   luaF_close(L, L->stack);      /* close all upvalues for this thread */
241   luaC_separateudata(L);        /* separate udata that have GC metamethods */
242   L->errfunc = 0;               /* no error function during GC metamethods */
243   do {                          /* repeat until no more errors */
244     L->ci = L->base_ci;
245     L->base = L->top = L->ci->base;
246     L->nCcalls = 0;
247   } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
248   lua_assert(G(L)->tmudata == NULL);
249   close_state(L);
250 }