Subversion Repositories WoWGM

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 tristanc 1
/*
2
** $Id: lstate.c,v 2.36 2006/05/24 14:15:50 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
*/
35
typedef struct LG {
36
  lua_State l;
37
  global_State g;
38
} LG;
39
 
40
 
41
 
42
static 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
 
61
static 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
*/
70
static 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
 
84
static 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 = 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
 
105
static 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
 
119
lua_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
 
134
void 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
 
143
LUA_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
 
193
static void callallgcTM (lua_State *L, void *ud) {
194
  UNUSED(ud);
195
  luaC_callGCTM(L);  /* call GC metamethods for all udata */
196
}
197
 
198
 
199
LUA_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 = 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