lua

A copy of the Lua development repository
Log | Files | Refs | README

lstate.c (11041B)


      1 /*
      2 ** $Id: lstate.c $
      3 ** Global State
      4 ** See Copyright Notice in lua.h
      5 */
      6 
      7 #define lstate_c
      8 #define LUA_CORE
      9 
     10 #include "lprefix.h"
     11 
     12 
     13 #include <stddef.h>
     14 #include <string.h>
     15 
     16 #include "lua.h"
     17 
     18 #include "lapi.h"
     19 #include "ldebug.h"
     20 #include "ldo.h"
     21 #include "lfunc.h"
     22 #include "lgc.h"
     23 #include "llex.h"
     24 #include "lmem.h"
     25 #include "lstate.h"
     26 #include "lstring.h"
     27 #include "ltable.h"
     28 #include "ltm.h"
     29 
     30 
     31 
     32 #define fromstate(L)	(cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))
     33 
     34 
     35 /*
     36 ** these macros allow user-specific actions when a thread is
     37 ** created/deleted
     38 */
     39 #if !defined(luai_userstateopen)
     40 #define luai_userstateopen(L)		((void)L)
     41 #endif
     42 
     43 #if !defined(luai_userstateclose)
     44 #define luai_userstateclose(L)		((void)L)
     45 #endif
     46 
     47 #if !defined(luai_userstatethread)
     48 #define luai_userstatethread(L,L1)	((void)L)
     49 #endif
     50 
     51 #if !defined(luai_userstatefree)
     52 #define luai_userstatefree(L,L1)	((void)L)
     53 #endif
     54 
     55 
     56 /*
     57 ** set GCdebt to a new value keeping the real number of allocated
     58 ** objects (GCtotalobjs - GCdebt) invariant and avoiding overflows in
     59 ** 'GCtotalobjs'.
     60 */
     61 void luaE_setdebt (global_State *g, l_mem debt) {
     62   l_mem tb = gettotalbytes(g);
     63   lua_assert(tb > 0);
     64   if (debt > MAX_LMEM - tb)
     65     debt = MAX_LMEM - tb;  /* will make GCtotalbytes == MAX_LMEM */
     66   g->GCtotalbytes = tb + debt;
     67   g->GCdebt = debt;
     68 }
     69 
     70 
     71 CallInfo *luaE_extendCI (lua_State *L) {
     72   CallInfo *ci;
     73   lua_assert(L->ci->next == NULL);
     74   ci = luaM_new(L, CallInfo);
     75   lua_assert(L->ci->next == NULL);
     76   L->ci->next = ci;
     77   ci->previous = L->ci;
     78   ci->next = NULL;
     79   ci->u.l.trap = 0;
     80   L->nci++;
     81   return ci;
     82 }
     83 
     84 
     85 /*
     86 ** free all CallInfo structures not in use by a thread
     87 */
     88 static void freeCI (lua_State *L) {
     89   CallInfo *ci = L->ci;
     90   CallInfo *next = ci->next;
     91   ci->next = NULL;
     92   while ((ci = next) != NULL) {
     93     next = ci->next;
     94     luaM_free(L, ci);
     95     L->nci--;
     96   }
     97 }
     98 
     99 
    100 /*
    101 ** free half of the CallInfo structures not in use by a thread,
    102 ** keeping the first one.
    103 */
    104 void luaE_shrinkCI (lua_State *L) {
    105   CallInfo *ci = L->ci->next;  /* first free CallInfo */
    106   CallInfo *next;
    107   if (ci == NULL)
    108     return;  /* no extra elements */
    109   while ((next = ci->next) != NULL) {  /* two extra elements? */
    110     CallInfo *next2 = next->next;  /* next's next */
    111     ci->next = next2;  /* remove next from the list */
    112     L->nci--;
    113     luaM_free(L, next);  /* free next */
    114     if (next2 == NULL)
    115       break;  /* no more elements */
    116     else {
    117       next2->previous = ci;
    118       ci = next2;  /* continue */
    119     }
    120   }
    121 }
    122 
    123 
    124 /*
    125 ** Called when 'getCcalls(L)' larger or equal to LUAI_MAXCCALLS.
    126 ** If equal, raises an overflow error. If value is larger than
    127 ** LUAI_MAXCCALLS (which means it is handling an overflow) but
    128 ** not much larger, does not report an error (to allow overflow
    129 ** handling to work).
    130 */
    131 void luaE_checkcstack (lua_State *L) {
    132   if (getCcalls(L) == LUAI_MAXCCALLS)
    133     luaG_runerror(L, "C stack overflow");
    134   else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11))
    135     luaD_throw(L, LUA_ERRERR);  /* error while handling stack error */
    136 }
    137 
    138 
    139 LUAI_FUNC void luaE_incCstack (lua_State *L) {
    140   L->nCcalls++;
    141   if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS))
    142     luaE_checkcstack(L);
    143 }
    144 
    145 
    146 static void stack_init (lua_State *L1, lua_State *L) {
    147   int i; CallInfo *ci;
    148   /* initialize stack array */
    149   L1->stack.p = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue);
    150   L1->tbclist.p = L1->stack.p;
    151   for (i = 0; i < BASIC_STACK_SIZE + EXTRA_STACK; i++)
    152     setnilvalue(s2v(L1->stack.p + i));  /* erase new stack */
    153   L1->top.p = L1->stack.p;
    154   L1->stack_last.p = L1->stack.p + BASIC_STACK_SIZE;
    155   /* initialize first ci */
    156   ci = &L1->base_ci;
    157   ci->next = ci->previous = NULL;
    158   ci->callstatus = CIST_C;
    159   ci->func.p = L1->top.p;
    160   ci->u.c.k = NULL;
    161   setnilvalue(s2v(L1->top.p));  /* 'function' entry for this 'ci' */
    162   L1->top.p++;
    163   ci->top.p = L1->top.p + LUA_MINSTACK;
    164   L1->ci = ci;
    165 }
    166 
    167 
    168 static void freestack (lua_State *L) {
    169   if (L->stack.p == NULL)
    170     return;  /* stack not completely built yet */
    171   L->ci = &L->base_ci;  /* free the entire 'ci' list */
    172   freeCI(L);
    173   lua_assert(L->nci == 0);
    174   /* free stack */
    175   luaM_freearray(L, L->stack.p, cast_sizet(stacksize(L) + EXTRA_STACK));
    176 }
    177 
    178 
    179 /*
    180 ** Create registry table and its predefined values
    181 */
    182 static void init_registry (lua_State *L, global_State *g) {
    183   /* create registry */
    184   TValue aux;
    185   Table *registry = luaH_new(L);
    186   sethvalue(L, &g->l_registry, registry);
    187   luaH_resize(L, registry, LUA_RIDX_LAST, 0);
    188   /* registry[1] = false */
    189   setbfvalue(&aux);
    190   luaH_setint(L, registry, 1, &aux);
    191   /* registry[LUA_RIDX_MAINTHREAD] = L */
    192   setthvalue(L, &aux, L);
    193   luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &aux);
    194   /* registry[LUA_RIDX_GLOBALS] = new table (table of globals) */
    195   sethvalue(L, &aux, luaH_new(L));
    196   luaH_setint(L, registry, LUA_RIDX_GLOBALS, &aux);
    197 }
    198 
    199 
    200 /*
    201 ** open parts of the state that may cause memory-allocation errors.
    202 */
    203 static void f_luaopen (lua_State *L, void *ud) {
    204   global_State *g = G(L);
    205   UNUSED(ud);
    206   stack_init(L, L);  /* init stack */
    207   init_registry(L, g);
    208   luaS_init(L);
    209   luaT_init(L);
    210   luaX_init(L);
    211   g->gcstp = 0;  /* allow gc */
    212   setnilvalue(&g->nilvalue);  /* now state is complete */
    213   luai_userstateopen(L);
    214 }
    215 
    216 
    217 /*
    218 ** preinitialize a thread with consistent values without allocating
    219 ** any memory (to avoid errors)
    220 */
    221 static void preinit_thread (lua_State *L, global_State *g) {
    222   G(L) = g;
    223   L->stack.p = NULL;
    224   L->ci = NULL;
    225   L->nci = 0;
    226   L->twups = L;  /* thread has no upvalues */
    227   L->nCcalls = 0;
    228   L->errorJmp = NULL;
    229   L->hook = NULL;
    230   L->hookmask = 0;
    231   L->basehookcount = 0;
    232   L->allowhook = 1;
    233   resethookcount(L);
    234   L->openupval = NULL;
    235   L->status = LUA_OK;
    236   L->errfunc = 0;
    237   L->oldpc = 0;
    238 }
    239 
    240 
    241 lu_mem luaE_threadsize (lua_State *L) {
    242   lu_mem sz = cast(lu_mem, sizeof(LX))
    243             + cast_uint(L->nci) * sizeof(CallInfo);
    244   if (L->stack.p != NULL)
    245     sz += cast_uint(stacksize(L) + EXTRA_STACK) * sizeof(StackValue);
    246   return sz;
    247 }
    248 
    249 
    250 static void close_state (lua_State *L) {
    251   global_State *g = G(L);
    252   if (!completestate(g))  /* closing a partially built state? */
    253     luaC_freeallobjects(L);  /* just collect its objects */
    254   else {  /* closing a fully built state */
    255     L->ci = &L->base_ci;  /* unwind CallInfo list */
    256     luaD_closeprotected(L, 1, LUA_OK);  /* close all upvalues */
    257     luaC_freeallobjects(L);  /* collect all objects */
    258     luai_userstateclose(L);
    259   }
    260   luaM_freearray(L, G(L)->strt.hash, cast_sizet(G(L)->strt.size));
    261   freestack(L);
    262   lua_assert(gettotalbytes(g) == sizeof(global_State));
    263   (*g->frealloc)(g->ud, g, sizeof(global_State), 0);  /* free main block */
    264 }
    265 
    266 
    267 LUA_API lua_State *lua_newthread (lua_State *L) {
    268   global_State *g = G(L);
    269   GCObject *o;
    270   lua_State *L1;
    271   lua_lock(L);
    272   luaC_checkGC(L);
    273   /* create new thread */
    274   o = luaC_newobjdt(L, LUA_TTHREAD, sizeof(LX), offsetof(LX, l));
    275   L1 = gco2th(o);
    276   /* anchor it on L stack */
    277   setthvalue2s(L, L->top.p, L1);
    278   api_incr_top(L);
    279   preinit_thread(L1, g);
    280   L1->hookmask = L->hookmask;
    281   L1->basehookcount = L->basehookcount;
    282   L1->hook = L->hook;
    283   resethookcount(L1);
    284   /* initialize L1 extra space */
    285   memcpy(lua_getextraspace(L1), lua_getextraspace(mainthread(g)),
    286          LUA_EXTRASPACE);
    287   luai_userstatethread(L, L1);
    288   stack_init(L1, L);  /* init stack */
    289   lua_unlock(L);
    290   return L1;
    291 }
    292 
    293 
    294 void luaE_freethread (lua_State *L, lua_State *L1) {
    295   LX *l = fromstate(L1);
    296   luaF_closeupval(L1, L1->stack.p);  /* close all upvalues */
    297   lua_assert(L1->openupval == NULL);
    298   luai_userstatefree(L, L1);
    299   freestack(L1);
    300   luaM_free(L, l);
    301 }
    302 
    303 
    304 TStatus luaE_resetthread (lua_State *L, TStatus status) {
    305   CallInfo *ci = L->ci = &L->base_ci;  /* unwind CallInfo list */
    306   setnilvalue(s2v(L->stack.p));  /* 'function' entry for basic 'ci' */
    307   ci->func.p = L->stack.p;
    308   ci->callstatus = CIST_C;
    309   if (status == LUA_YIELD)
    310     status = LUA_OK;
    311   L->status = LUA_OK;  /* so it can run __close metamethods */
    312   status = luaD_closeprotected(L, 1, status);
    313   if (status != LUA_OK)  /* errors? */
    314     luaD_seterrorobj(L, status, L->stack.p + 1);
    315   else
    316     L->top.p = L->stack.p + 1;
    317   ci->top.p = L->top.p + LUA_MINSTACK;
    318   luaD_reallocstack(L, cast_int(ci->top.p - L->stack.p), 0);
    319   return status;
    320 }
    321 
    322 
    323 LUA_API int lua_closethread (lua_State *L, lua_State *from) {
    324   TStatus status;
    325   lua_lock(L);
    326   L->nCcalls = (from) ? getCcalls(from) : 0;
    327   status = luaE_resetthread(L, L->status);
    328   lua_unlock(L);
    329   return APIstatus(status);
    330 }
    331 
    332 
    333 LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud, unsigned seed) {
    334   int i;
    335   lua_State *L;
    336   global_State *g = cast(global_State*,
    337                        (*f)(ud, NULL, LUA_TTHREAD, sizeof(global_State)));
    338   if (g == NULL) return NULL;
    339   L = &g->mainth.l;
    340   L->tt = LUA_VTHREAD;
    341   g->currentwhite = bitmask(WHITE0BIT);
    342   L->marked = luaC_white(g);
    343   preinit_thread(L, g);
    344   g->allgc = obj2gco(L);  /* by now, only object is the main thread */
    345   L->next = NULL;
    346   incnny(L);  /* main thread is always non yieldable */
    347   g->frealloc = f;
    348   g->ud = ud;
    349   g->warnf = NULL;
    350   g->ud_warn = NULL;
    351   g->seed = seed;
    352   g->gcstp = GCSTPGC;  /* no GC while building state */
    353   g->strt.size = g->strt.nuse = 0;
    354   g->strt.hash = NULL;
    355   setnilvalue(&g->l_registry);
    356   g->panic = NULL;
    357   g->gcstate = GCSpause;
    358   g->gckind = KGC_INC;
    359   g->gcstopem = 0;
    360   g->gcemergency = 0;
    361   g->finobj = g->tobefnz = g->fixedgc = NULL;
    362   g->firstold1 = g->survival = g->old1 = g->reallyold = NULL;
    363   g->finobjsur = g->finobjold1 = g->finobjrold = NULL;
    364   g->sweepgc = NULL;
    365   g->gray = g->grayagain = NULL;
    366   g->weak = g->ephemeron = g->allweak = NULL;
    367   g->twups = NULL;
    368   g->GCtotalbytes = sizeof(global_State);
    369   g->GCmarked = 0;
    370   g->GCdebt = 0;
    371   setivalue(&g->nilvalue, 0);  /* to signal that state is not yet built */
    372   setgcparam(g, PAUSE, LUAI_GCPAUSE);
    373   setgcparam(g, STEPMUL, LUAI_GCMUL);
    374   setgcparam(g, STEPSIZE, LUAI_GCSTEPSIZE);
    375   setgcparam(g, MINORMUL, LUAI_GENMINORMUL);
    376   setgcparam(g, MINORMAJOR, LUAI_MINORMAJOR);
    377   setgcparam(g, MAJORMINOR, LUAI_MAJORMINOR);
    378   for (i=0; i < LUA_NUMTYPES; i++) g->mt[i] = NULL;
    379   if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
    380     /* memory allocation error: free partial state */
    381     close_state(L);
    382     L = NULL;
    383   }
    384   return L;
    385 }
    386 
    387 
    388 LUA_API void lua_close (lua_State *L) {
    389   lua_lock(L);
    390   L = mainthread(G(L));  /* only the main thread can be closed */
    391   close_state(L);
    392 }
    393 
    394 
    395 void luaE_warning (lua_State *L, const char *msg, int tocont) {
    396   lua_WarnFunction wf = G(L)->warnf;
    397   if (wf != NULL)
    398     wf(G(L)->ud_warn, msg, tocont);
    399 }
    400 
    401 
    402 /*
    403 ** Generate a warning from an error message
    404 */
    405 void luaE_warnerror (lua_State *L, const char *where) {
    406   TValue *errobj = s2v(L->top.p - 1);  /* error object */
    407   const char *msg = (ttisstring(errobj))
    408                   ? getstr(tsvalue(errobj))
    409                   : "error object is not a string";
    410   /* produce warning "error in %s (%s)" (where, msg) */
    411   luaE_warning(L, "error in ", 1);
    412   luaE_warning(L, where, 1);
    413   luaE_warning(L, " (", 1);
    414   luaE_warning(L, msg, 1);
    415   luaE_warning(L, ")", 0);
    416 }
    417