?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

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