Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ceguilua/src/lua/lstate.c @ 2227

Last change on this file since 2227 was 1806, checked in by rgrieder, 16 years ago

added single 5.1.3 directory for lua since CEGUILua 0.5 can also build against lua 5.1

  • Property svn:eol-style set to native
File size: 5.5 KB
RevLine 
[1806]1/*
2** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $
3** Global State
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stddef.h>
9
10#define lstate_c
11#define LUA_CORE
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#define state_size(x)   (sizeof(x) + LUAI_EXTRASPACE)
28#define fromstate(l)    (cast(lu_byte *, (l)) - LUAI_EXTRASPACE)
29#define tostate(l)   (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE))
30
31
32/*
33** Main thread combines a thread state and the global state
34*/
35typedef struct LG {
36  lua_State l;
37  global_State g;
38} LG;
39 
40
41
42static void stack_init (lua_State *L1, lua_State *L) {
43  /* initialize CallInfo array */
44  L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
45  L1->ci = L1->base_ci;
46  L1->size_ci = BASIC_CI_SIZE;
47  L1->end_ci = L1->base_ci + L1->size_ci - 1;
48  /* initialize stack array */
49  L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue);
50  L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
51  L1->top = L1->stack;
52  L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
53  /* initialize first ci */
54  L1->ci->func = L1->top;
55  setnilvalue(L1->top++);  /* `function' entry for this `ci' */
56  L1->base = L1->ci->base = L1->top;
57  L1->ci->top = L1->top + LUA_MINSTACK;
58}
59
60
61static void freestack (lua_State *L, lua_State *L1) {
62  luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo);
63  luaM_freearray(L, L1->stack, L1->stacksize, TValue);
64}
65
66
67/*
68** open parts that may cause memory-allocation errors
69*/
70static void f_luaopen (lua_State *L, void *ud) {
71  global_State *g = G(L);
72  UNUSED(ud);
73  stack_init(L, L);  /* init stack */
74  sethvalue(L, gt(L), luaH_new(L, 0, 2));  /* table of globals */
75  sethvalue(L, registry(L), luaH_new(L, 0, 2));  /* registry */
76  luaS_resize(L, MINSTRTABSIZE);  /* initial size of string table */
77  luaT_init(L);
78  luaX_init(L);
79  luaS_fix(luaS_newliteral(L, MEMERRMSG));
80  g->GCthreshold = 4*g->totalbytes;
81}
82
83
84static void preinit_state (lua_State *L, global_State *g) {
85  G(L) = g;
86  L->stack = NULL;
87  L->stacksize = 0;
88  L->errorJmp = NULL;
89  L->hook = NULL;
90  L->hookmask = 0;
91  L->basehookcount = 0;
92  L->allowhook = 1;
93  resethookcount(L);
94  L->openupval = NULL;
95  L->size_ci = 0;
96  L->nCcalls = L->baseCcalls = 0;
97  L->status = 0;
98  L->base_ci = L->ci = NULL;
99  L->savedpc = NULL;
100  L->errfunc = 0;
101  setnilvalue(gt(L));
102}
103
104
105static void close_state (lua_State *L) {
106  global_State *g = G(L);
107  luaF_close(L, L->stack);  /* close all upvalues for this thread */
108  luaC_freeall(L);  /* collect all objects */
109  lua_assert(g->rootgc == obj2gco(L));
110  lua_assert(g->strt.nuse == 0);
111  luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
112  luaZ_freebuffer(L, &g->buff);
113  freestack(L, L);
114  lua_assert(g->totalbytes == sizeof(LG));
115  (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0);
116}
117
118
119lua_State *luaE_newthread (lua_State *L) {
120  lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State)));
121  luaC_link(L, obj2gco(L1), LUA_TTHREAD);
122  preinit_state(L1, G(L));
123  stack_init(L1, L);  /* init stack */
124  setobj2n(L, gt(L1), gt(L));  /* share table of globals */
125  L1->hookmask = L->hookmask;
126  L1->basehookcount = L->basehookcount;
127  L1->hook = L->hook;
128  resethookcount(L1);
129  lua_assert(iswhite(obj2gco(L1)));
130  return L1;
131}
132
133
134void luaE_freethread (lua_State *L, lua_State *L1) {
135  luaF_close(L1, L1->stack);  /* close all upvalues for this thread */
136  lua_assert(L1->openupval == NULL);
137  luai_userstatefree(L1);
138  freestack(L, L1);
139  luaM_freemem(L, fromstate(L1), state_size(lua_State));
140}
141
142
143LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
144  int i;
145  lua_State *L;
146  global_State *g;
147  void *l = (*f)(ud, NULL, 0, state_size(LG));
148  if (l == NULL) return NULL;
149  L = tostate(l);
150  g = &((LG *)L)->g;
151  L->next = NULL;
152  L->tt = LUA_TTHREAD;
153  g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
154  L->marked = luaC_white(g);
155  set2bits(L->marked, FIXEDBIT, SFIXEDBIT);
156  preinit_state(L, g);
157  g->frealloc = f;
158  g->ud = ud;
159  g->mainthread = L;
160  g->uvhead.u.l.prev = &g->uvhead;
161  g->uvhead.u.l.next = &g->uvhead;
162  g->GCthreshold = 0;  /* mark it as unfinished state */
163  g->strt.size = 0;
164  g->strt.nuse = 0;
165  g->strt.hash = NULL;
166  setnilvalue(registry(L));
167  luaZ_initbuffer(L, &g->buff);
168  g->panic = NULL;
169  g->gcstate = GCSpause;
170  g->rootgc = obj2gco(L);
171  g->sweepstrgc = 0;
172  g->sweepgc = &g->rootgc;
173  g->gray = NULL;
174  g->grayagain = NULL;
175  g->weak = NULL;
176  g->tmudata = NULL;
177  g->totalbytes = sizeof(LG);
178  g->gcpause = LUAI_GCPAUSE;
179  g->gcstepmul = LUAI_GCMUL;
180  g->gcdept = 0;
181  for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL;
182  if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
183    /* memory allocation error: free partial state */
184    close_state(L);
185    L = NULL;
186  }
187  else
188    luai_userstateopen(L);
189  return L;
190}
191
192
193static void callallgcTM (lua_State *L, void *ud) {
194  UNUSED(ud);
195  luaC_callGCTM(L);  /* call GC metamethods for all udata */
196}
197
198
199LUA_API void lua_close (lua_State *L) {
200  L = G(L)->mainthread;  /* only the main thread can be closed */
201  lua_lock(L);
202  luaF_close(L, L->stack);  /* close all upvalues for this thread */
203  luaC_separateudata(L, 1);  /* separate udata that have GC metamethods */
204  L->errfunc = 0;  /* no error function during GC metamethods */
205  do {  /* repeat until no more errors */
206    L->ci = L->base_ci;
207    L->base = L->top = L->ci->base;
208    L->nCcalls = L->baseCcalls = 0;
209  } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
210  lua_assert(G(L)->tmudata == NULL);
211  luai_userstateclose(L);
212  close_state(L);
213}
214
Note: See TracBrowser for help on using the repository browser.