00001
00002
00003
00004
00005
00006
00007
00008 #include <stdlib.h>
00009
00010 #define lstate_c
00011
00012 #include "lua.h"
00013
00014 #include "ldebug.h"
00015 #include "ldo.h"
00016 #include "lfunc.h"
00017 #include "lgc.h"
00018 #include "llex.h"
00019 #include "lmem.h"
00020 #include "lstate.h"
00021 #include "lstring.h"
00022 #include "ltable.h"
00023 #include "ltm.h"
00024
00025
00026
00027
00028
00029 #ifndef LUA_USERSTATE
00030 #define EXTRASPACE 0
00031 #else
00032 union UEXTRASPACE {L_Umaxalign a; LUA_USERSTATE b;};
00033 #define EXTRASPACE (sizeof(union UEXTRASPACE))
00034 #endif
00035
00036
00037
00038
00039
00040
00041
00042 static int default_panic (lua_State *L)
00043
00044 {
00045 UNUSED(L);
00046 return 0;
00047 }
00048
00049
00050
00051 static lua_State *mallocstate ( lua_State *L)
00052
00053 {
00054 lu_byte *block = (lu_byte *)luaM_malloc(L, sizeof(lua_State) + EXTRASPACE);
00055 if (block == NULL) return NULL;
00056 else {
00057 block += EXTRASPACE;
00058 return cast(lua_State *, block);
00059 }
00060 }
00061
00062
00063 static void freestate ( lua_State *L, lua_State *L1)
00064
00065 {
00066 luaM_free(L, cast(lu_byte *, L1) - EXTRASPACE,
00067 sizeof(lua_State) + EXTRASPACE);
00068 }
00069
00070
00071 static void stack_init (lua_State *L1, lua_State *L)
00072
00073 {
00074 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TObject);
00075 L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
00076 L1->top = L1->stack;
00077 L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
00078 L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
00079 L1->ci = L1->base_ci;
00080 L1->ci->state = CI_C;
00081 setnilvalue(L1->top++);
00082 L1->base = L1->ci->base = L1->top;
00083 L1->ci->top = L1->top + LUA_MINSTACK;
00084 L1->size_ci = BASIC_CI_SIZE;
00085 L1->end_ci = L1->base_ci + L1->size_ci;
00086 }
00087
00088
00089 static void freestack (lua_State *L, lua_State *L1)
00090
00091 {
00092 luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo);
00093 luaM_freearray(L, L1->stack, L1->stacksize, TObject);
00094 }
00095
00096
00097
00098
00099
00100 static void f_luaopen (lua_State *L, void *ud)
00101
00102 {
00103
00104 global_State *g = luaM_new(NULL, global_State);
00105 UNUSED(ud);
00106 if (g == NULL) luaD_throw(L, LUA_ERRMEM);
00107 L->l_G = g;
00108 g->mainthread = L;
00109 g->GCthreshold = 0;
00110 g->strt.size = 0;
00111 g->strt.nuse = 0;
00112 g->strt.hash = NULL;
00113 setnilvalue(defaultmeta(L));
00114 setnilvalue(registry(L));
00115 luaZ_initbuffer(L, &g->buff);
00116 g->panic = default_panic;
00117 g->rootgc = NULL;
00118 g->rootudata = NULL;
00119 g->tmudata = NULL;
00120 setnilvalue(gkey(g->dummynode));
00121 setnilvalue(gval(g->dummynode));
00122 g->dummynode->next = NULL;
00123 g->nblocks = sizeof(lua_State) + sizeof(global_State);
00124 stack_init(L, L);
00125
00126 defaultmeta(L)->tt = LUA_TTABLE;
00127 sethvalue(defaultmeta(L), luaH_new(L, 0, 0));
00128 hvalue(defaultmeta(L))->metatable = hvalue(defaultmeta(L));
00129 sethvalue(gt(L), luaH_new(L, 0, 4));
00130 sethvalue(registry(L), luaH_new(L, 4, 4));
00131 luaS_resize(L, MINSTRTABSIZE);
00132 luaT_init(L);
00133 luaX_init(L);
00134 luaS_fix(luaS_newliteral(L, MEMERRMSG));
00135 g->GCthreshold = 4*G(L)->nblocks;
00136 }
00137
00138
00139 static void preinit_state (lua_State *L)
00140
00141 {
00142 L->stack = NULL;
00143 L->stacksize = 0;
00144 L->errorJmp = NULL;
00145 L->hook = NULL;
00146 L->hookmask = L->hookinit = 0;
00147 L->basehookcount = 0;
00148 L->allowhook = 1;
00149 resethookcount(L);
00150 L->openupval = NULL;
00151 L->size_ci = 0;
00152 L->nCcalls = 0;
00153 L->ci = L->base_ci = NULL;
00154 L->errfunc = 0;
00155 setnilvalue(gt(L));
00156 }
00157
00158
00159 static void close_state (lua_State *L)
00160
00161 {
00162 luaF_close(L, L->stack);
00163 if (G(L)) {
00164 luaC_sweep(L, 1);
00165 lua_assert(G(L)->rootgc == NULL);
00166 lua_assert(G(L)->rootudata == NULL);
00167 luaS_freeall(L);
00168 luaZ_freebuffer(L, &G(L)->buff);
00169 }
00170 freestack(L, L);
00171 if (G(L)) {
00172 lua_assert(G(L)->nblocks == sizeof(lua_State) + sizeof(global_State));
00173 luaM_freelem(NULL, G(L));
00174 }
00175 freestate(NULL, L);
00176 }
00177
00178
00179 lua_State *luaE_newthread (lua_State *L) {
00180 lua_State *L1 = mallocstate(L);
00181 luaC_link(L, valtogco(L1), LUA_TTHREAD);
00182 preinit_state(L1);
00183 L1->l_G = L->l_G;
00184 stack_init(L1, L);
00185 setobj2n(gt(L1), gt(L));
00186 return L1;
00187 }
00188
00189
00190 void luaE_freethread (lua_State *L, lua_State *L1) {
00191 luaF_close(L1, L1->stack);
00192 lua_assert(L1->openupval == NULL);
00193 freestack(L, L1);
00194 freestate(L, L1);
00195 }
00196
00197
00198
00199 LUA_API lua_State *lua_open (void) {
00200 lua_State *L = mallocstate(NULL);
00201 if (L) {
00202 L->tt = LUA_TTHREAD;
00203 L->marked = 0;
00204 L->next = L->gclist = NULL;
00205 preinit_state(L);
00206 L->l_G = NULL;
00207 if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
00208
00209 close_state(L);
00210 L = NULL;
00211 }
00212 }
00213 lua_userstateopen(L);
00214 return L;
00215 }
00216
00217
00218 static void callallgcTM (lua_State *L, void *ud)
00219
00220 {
00221 UNUSED(ud);
00222 luaC_callGCTM(L);
00223 }
00224
00225
00226 LUA_API void lua_close (lua_State *L) {
00227 lua_lock(L);
00228 L = G(L)->mainthread;
00229 luaF_close(L, L->stack);
00230 luaC_separateudata(L);
00231 L->errfunc = 0;
00232 do {
00233 L->ci = L->base_ci;
00234 L->base = L->top = L->ci->base;
00235 L->nCcalls = 0;
00236 } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
00237 lua_assert(G(L)->tmudata == NULL);
00238 close_state(L);
00239 }
00240