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