lua/lstate.c

Go to the documentation of this file.
00001 /*
00002 ** $Id: lstate.c,v 2.92 2011/10/03 17:54:25 roberto Exp $
00003 ** Global State
00004 ** See Copyright Notice in lua.h
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  /* 200% */
00030 #endif
00031 
00032 #if !defined(LUAI_GCMAJOR)
00033 #define LUAI_GCMAJOR    200  /* 200% */
00034 #endif
00035 
00036 #if !defined(LUAI_GCMUL)
00037 #define LUAI_GCMUL  200 /* GC runs 'twice the speed' of memory allocation */
00038 #endif
00039 
00040 
00041 #define MEMERRMSG       "not enough memory"
00042 
00043 
00044 /*
00045 ** thread state + extra space
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 ** Main thread combines a thread state and the global state
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 ** set GCdebt to a new value keeping the value (totalbytes + GCdebt)
00070 ** invariant
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   /* initialize stack array */
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);  /* erase new stack */
00106   L1->top = L1->stack;
00107   L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
00108   /* initialize first ci */
00109   ci = &L1->base_ci;
00110   ci->next = ci->previous = NULL;
00111   ci->callstatus = 0;
00112   ci->func = L1->top;
00113   setnilvalue(L1->top++);  /* 'function' entry for this 'ci' */
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;  /* stack not completely built yet */
00122   L->ci = &L->base_ci;  /* free the entire 'ci' list */
00123   luaE_freeCI(L);
00124   luaM_freearray(L, L->stack, L->stacksize);  /* free stack array */
00125 }
00126 
00127 
00128 /*
00129 ** Create registry table and its predefined values
00130 */
00131 static void init_registry (lua_State *L, global_State *g) {
00132   TValue mt;
00133   /* create registry */
00134   Table *registry = luaH_new(L);
00135   sethvalue(L, &g->l_registry, registry);
00136   luaH_resize(L, registry, LUA_RIDX_LAST, 0);
00137   /* registry[LUA_RIDX_MAINTHREAD] = L */
00138   setthvalue(L, &mt, L);
00139   luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt);
00140   /* registry[LUA_RIDX_GLOBALS] = table of globals */
00141   sethvalue(L, &mt, luaH_new(L));
00142   luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt);
00143 }
00144 
00145 
00146 /*
00147 ** open parts of the state that may cause memory-allocation errors
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);  /* init stack */
00153   init_registry(L, g);
00154   luaS_resize(L, MINSTRTABSIZE);  /* initial size of string table */
00155   luaT_init(L);
00156   luaX_init(L);
00157   /* pre-create memory-error message */
00158   g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
00159   luaS_fix(g->memerrmsg);  /* it should never be collected */
00160   g->gcrunning = 1;  /* allow gc */
00161 }
00162 
00163 
00164 /*
00165 ** preinitialize a state with consistent values without allocating
00166 ** any memory (to avoid errors)
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);  /* close all upvalues for this thread */
00190   luaC_freeallobjects(L);  /* collect all objects */
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);  /* free main block */
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);  /* init stack */
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);  /* close all upvalues for this thread */
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;  /* no GC while building state */
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     /* memory allocation error: free partial state */
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;  /* only the main thread can be closed */
00281   lua_lock(L);
00282   luai_userstateclose(L);
00283   close_state(L);
00284 }
00285 
00286 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:04 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs