00001
00002
00003
00004
00005
00006
00007
00008 #include <stddef.h>
00009
00010 #define lstate_c
00011 #define LUA_CORE
00012
00013 #include "lua.h"
00014
00015 #include "lapi.h"
00016 #include "ldebug.h"
00017 #include "ldo.h"
00018 #include "lfunc.h"
00019 #include "lgc.h"
00020 #include "llex.h"
00021 #include "lmem.h"
00022 #include "lstate.h"
00023 #include "lstring.h"
00024 #include "ltable.h"
00025 #include "ltm.h"
00026
00027
00028 #if !defined(LUAI_GCPAUSE)
00029 #define LUAI_GCPAUSE 200
00030 #endif
00031
00032 #if !defined(LUAI_GCMAJOR)
00033 #define LUAI_GCMAJOR 200
00034 #endif
00035
00036 #if !defined(LUAI_GCMUL)
00037 #define LUAI_GCMUL 200
00038 #endif
00039
00040
00041 #define MEMERRMSG "not enough memory"
00042
00043
00044
00045
00046
00047 typedef struct LX {
00048 #if defined(LUAI_EXTRASPACE)
00049 char buff[LUAI_EXTRASPACE];
00050 #endif
00051 lua_State l;
00052 } LX;
00053
00054
00055
00056
00057
00058 typedef struct LG {
00059 LX l;
00060 global_State g;
00061 } LG;
00062
00063
00064
00065 #define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))
00066
00067
00068
00069
00070
00071
00072 void luaE_setdebt (global_State *g, l_mem debt) {
00073 g->totalbytes -= (debt - g->GCdebt);
00074 g->GCdebt = debt;
00075 }
00076
00077
00078 CallInfo *luaE_extendCI (lua_State *L) {
00079 CallInfo *ci = luaM_new(L, CallInfo);
00080 lua_assert(L->ci->next == NULL);
00081 L->ci->next = ci;
00082 ci->previous = L->ci;
00083 ci->next = NULL;
00084 return ci;
00085 }
00086
00087
00088 void luaE_freeCI (lua_State *L) {
00089 CallInfo *ci = L->ci;
00090 CallInfo *next = ci->next;
00091 ci->next = NULL;
00092 while ((ci = next) != NULL) {
00093 next = ci->next;
00094 luaM_free(L, ci);
00095 }
00096 }
00097
00098
00099 static void stack_init (lua_State *L1, lua_State *L) {
00100 int i; CallInfo *ci;
00101
00102 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue);
00103 L1->stacksize = BASIC_STACK_SIZE;
00104 for (i = 0; i < BASIC_STACK_SIZE; i++)
00105 setnilvalue(L1->stack + i);
00106 L1->top = L1->stack;
00107 L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
00108
00109 ci = &L1->base_ci;
00110 ci->next = ci->previous = NULL;
00111 ci->callstatus = 0;
00112 ci->func = L1->top;
00113 setnilvalue(L1->top++);
00114 ci->top = L1->top + LUA_MINSTACK;
00115 L1->ci = ci;
00116 }
00117
00118
00119 static void freestack (lua_State *L) {
00120 if (L->stack == NULL)
00121 return;
00122 L->ci = &L->base_ci;
00123 luaE_freeCI(L);
00124 luaM_freearray(L, L->stack, L->stacksize);
00125 }
00126
00127
00128
00129
00130
00131 static void init_registry (lua_State *L, global_State *g) {
00132 TValue mt;
00133
00134 Table *registry = luaH_new(L);
00135 sethvalue(L, &g->l_registry, registry);
00136 luaH_resize(L, registry, LUA_RIDX_LAST, 0);
00137
00138 setthvalue(L, &mt, L);
00139 luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt);
00140
00141 sethvalue(L, &mt, luaH_new(L));
00142 luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt);
00143 }
00144
00145
00146
00147
00148
00149 static void f_luaopen (lua_State *L, void *ud) {
00150 global_State *g = G(L);
00151 UNUSED(ud);
00152 stack_init(L, L);
00153 init_registry(L, g);
00154 luaS_resize(L, MINSTRTABSIZE);
00155 luaT_init(L);
00156 luaX_init(L);
00157
00158 g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
00159 luaS_fix(g->memerrmsg);
00160 g->gcrunning = 1;
00161 }
00162
00163
00164
00165
00166
00167
00168 static void preinit_state (lua_State *L, global_State *g) {
00169 G(L) = g;
00170 L->stack = NULL;
00171 L->ci = NULL;
00172 L->stacksize = 0;
00173 L->errorJmp = NULL;
00174 L->nCcalls = 0;
00175 L->hook = NULL;
00176 L->hookmask = 0;
00177 L->basehookcount = 0;
00178 L->allowhook = 1;
00179 resethookcount(L);
00180 L->openupval = NULL;
00181 L->nny = 1;
00182 L->status = LUA_OK;
00183 L->errfunc = 0;
00184 }
00185
00186
00187 static void close_state (lua_State *L) {
00188 global_State *g = G(L);
00189 luaF_close(L, L->stack);
00190 luaC_freeallobjects(L);
00191 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
00192 luaZ_freebuffer(L, &g->buff);
00193 freestack(L);
00194 lua_assert(gettotalbytes(g) == sizeof(LG));
00195 (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0);
00196 }
00197
00198
00199 LUA_API lua_State *lua_newthread (lua_State *L) {
00200 lua_State *L1;
00201 lua_lock(L);
00202 luaC_checkGC(L);
00203 L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th;
00204 setthvalue(L, L->top, L1);
00205 api_incr_top(L);
00206 preinit_state(L1, G(L));
00207 L1->hookmask = L->hookmask;
00208 L1->basehookcount = L->basehookcount;
00209 L1->hook = L->hook;
00210 resethookcount(L1);
00211 luai_userstatethread(L, L1);
00212 stack_init(L1, L);
00213 lua_unlock(L);
00214 return L1;
00215 }
00216
00217
00218 void luaE_freethread (lua_State *L, lua_State *L1) {
00219 LX *l = fromstate(L1);
00220 luaF_close(L1, L1->stack);
00221 lua_assert(L1->openupval == NULL);
00222 luai_userstatefree(L, L1);
00223 freestack(L1);
00224 luaM_free(L, l);
00225 }
00226
00227
00228 LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
00229 int i;
00230 lua_State *L;
00231 global_State *g;
00232 LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG)));
00233 if (l == NULL) return NULL;
00234 L = &l->l.l;
00235 g = &l->g;
00236 L->next = NULL;
00237 L->tt = LUA_TTHREAD;
00238 g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
00239 L->marked = luaC_white(g);
00240 g->gckind = KGC_NORMAL;
00241 preinit_state(L, g);
00242 g->frealloc = f;
00243 g->ud = ud;
00244 g->mainthread = L;
00245 g->uvhead.u.l.prev = &g->uvhead;
00246 g->uvhead.u.l.next = &g->uvhead;
00247 g->gcrunning = 0;
00248 g->lastmajormem = 0;
00249 g->strt.size = 0;
00250 g->strt.nuse = 0;
00251 g->strt.hash = NULL;
00252 setnilvalue(&g->l_registry);
00253 luaZ_initbuffer(L, &g->buff);
00254 g->panic = NULL;
00255 g->version = lua_version(NULL);
00256 g->gcstate = GCSpause;
00257 g->allgc = NULL;
00258 g->finobj = NULL;
00259 g->tobefnz = NULL;
00260 g->gray = g->grayagain = NULL;
00261 g->weak = g->ephemeron = g->allweak = NULL;
00262 g->totalbytes = sizeof(LG);
00263 g->GCdebt = 0;
00264 g->gcpause = LUAI_GCPAUSE;
00265 g->gcmajorinc = LUAI_GCMAJOR;
00266 g->gcstepmul = LUAI_GCMUL;
00267 for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
00268 if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
00269
00270 close_state(L);
00271 L = NULL;
00272 }
00273 else
00274 luai_userstateopen(L);
00275 return L;
00276 }
00277
00278
00279 LUA_API void lua_close (lua_State *L) {
00280 L = G(L)->mainthread;
00281 lua_lock(L);
00282 luai_userstateclose(L);
00283 close_state(L);
00284 }
00285
00286