?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2. ** $Id: lstate.c,v 2.99.1.2 2013/11/08 17:45:31 roberto Exp $
  3. ** Global State
  4. ** See Copyright Notice in lua.h
  5. */
  6.  
  7.  
  8. #include <stddef.h>
  9. #include <string.h>
  10.  
  11. #define lstate_c
  12. #define LUA_CORE
  13.  
  14. #include "lua.h"
  15.  
  16. #include "lapi.h"
  17. #include "ldebug.h"
  18. #include "ldo.h"
  19. #include "lfunc.h"
  20. #include "lgc.h"
  21. #include "llex.h"
  22. #include "lmem.h"
  23. #include "lstate.h"
  24. #include "lstring.h"
  25. #include "ltable.h"
  26. #include "ltm.h"
  27.  
  28.  
  29. #if !defined(LUAI_GCPAUSE)
  30. #define LUAI_GCPAUSE    200  /* 200% */
  31. #endif
  32.  
  33. #if !defined(LUAI_GCMAJOR)
  34. #define LUAI_GCMAJOR    200  /* 200% */
  35. #endif
  36.  
  37. #if !defined(LUAI_GCMUL)
  38. #define LUAI_GCMUL      200 /* GC runs 'twice the speed' of memory allocation */
  39. #endif
  40.  
  41.  
  42. #define MEMERRMSG       "not enough memory"
  43.  
  44.  
  45. /*
  46. ** a macro to help the creation of a unique random seed when a state is
  47. ** created; the seed is used to randomize hashes.
  48. */
  49. #if !defined(luai_makeseed)
  50. #include <time.h>
  51. #define luai_makeseed()         cast(unsigned int, time(NULL))
  52. #endif
  53.  
  54.  
  55.  
  56. /*
  57. ** thread state + extra space
  58. */
  59. typedef struct LX {
  60. #if defined(LUAI_EXTRASPACE)
  61.   char buff[LUAI_EXTRASPACE];
  62. #endif
  63.   lua_State l;
  64. } LX;
  65.  
  66.  
  67. /*
  68. ** Main thread combines a thread state and the global state
  69. */
  70. typedef struct LG {
  71.   LX l;
  72.   global_State g;
  73. } LG;
  74.  
  75.  
  76.  
  77. #define fromstate(L)    (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))
  78.  
  79.  
  80. /*
  81. ** Compute an initial seed as random as possible. In ANSI, rely on
  82. ** Address Space Layout Randomization (if present) to increase
  83. ** randomness..
  84. */
  85. #define addbuff(b,p,e) \
  86.   { size_t t = cast(size_t, e); \
  87.     memcpy(buff + p, &t, sizeof(t)); p += sizeof(t); }
  88.  
  89. static unsigned int makeseed (lua_State *L) {
  90.   char buff[4 * sizeof(size_t)];
  91.   unsigned int h = luai_makeseed();
  92.   int p = 0;
  93.   addbuff(buff, p, L);  /* heap variable */
  94.   addbuff(buff, p, &h);  /* local variable */
  95.   addbuff(buff, p, luaO_nilobject);  /* global variable */
  96.   addbuff(buff, p, &lua_newstate);  /* public function */
  97.   lua_assert(p == sizeof(buff));
  98.   return luaS_hash(buff, p, h);
  99. }
  100.  
  101.  
  102. /*
  103. ** set GCdebt to a new value keeping the value (totalbytes + GCdebt)
  104. ** invariant
  105. */
  106. void luaE_setdebt (global_State *g, l_mem debt) {
  107.   g->totalbytes -= (debt - g->GCdebt);
  108.   g->GCdebt = debt;
  109. }
  110.  
  111.  
  112. CallInfo *luaE_extendCI (lua_State *L) {
  113.   CallInfo *ci = luaM_new(L, CallInfo);
  114.   lua_assert(L->ci->next == NULL);
  115.   L->ci->next = ci;
  116.   ci->previous = L->ci;
  117.   ci->next = NULL;
  118.   return ci;
  119. }
  120.  
  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.   }
  130. }
  131.  
  132.  
  133. static void stack_init (lua_State *L1, lua_State *L) {
  134.   int i; CallInfo *ci;
  135.   /* initialize stack array */
  136.   L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue);
  137.   L1->stacksize = BASIC_STACK_SIZE;
  138.   for (i = 0; i < BASIC_STACK_SIZE; i++)
  139.     setnilvalue(L1->stack + i);  /* erase new stack */
  140.   L1->top = L1->stack;
  141.   L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
  142.   /* initialize first ci */
  143.   ci = &L1->base_ci;
  144.   ci->next = ci->previous = NULL;
  145.   ci->callstatus = 0;
  146.   ci->func = L1->top;
  147.   setnilvalue(L1->top++);  /* 'function' entry for this 'ci' */
  148.   ci->top = L1->top + LUA_MINSTACK;
  149.   L1->ci = ci;
  150. }
  151.  
  152.  
  153. static void freestack (lua_State *L) {
  154.   if (L->stack == NULL)
  155.     return;  /* stack not completely built yet */
  156.   L->ci = &L->base_ci;  /* free the entire 'ci' list */
  157.   luaE_freeCI(L);
  158.   luaM_freearray(L, L->stack, L->stacksize);  /* free stack array */
  159. }
  160.  
  161.  
  162. /*
  163. ** Create registry table and its predefined values
  164. */
  165. static void init_registry (lua_State *L, global_State *g) {
  166.   TValue mt;
  167.   /* create registry */
  168.   Table *registry = luaH_new(L);
  169.   sethvalue(L, &g->l_registry, registry);
  170.   luaH_resize(L, registry, LUA_RIDX_LAST, 0);
  171.   /* registry[LUA_RIDX_MAINTHREAD] = L */
  172.   setthvalue(L, &mt, L);
  173.   luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt);
  174.   /* registry[LUA_RIDX_GLOBALS] = table of globals */
  175.   sethvalue(L, &mt, luaH_new(L));
  176.   luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt);
  177. }
  178.  
  179.  
  180. /*
  181. ** open parts of the state that may cause memory-allocation errors
  182. */
  183. static void f_luaopen (lua_State *L, void *ud) {
  184.   global_State *g = G(L);
  185.   UNUSED(ud);
  186.   stack_init(L, L);  /* init stack */
  187.   init_registry(L, g);
  188.   luaS_resize(L, MINSTRTABSIZE);  /* initial size of string table */
  189.   luaT_init(L);
  190.   luaX_init(L);
  191.   /* pre-create memory-error message */
  192.   g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
  193.   luaS_fix(g->memerrmsg);  /* it should never be collected */
  194.   g->gcrunning = 1;  /* allow gc */
  195.   g->version = lua_version(NULL);
  196.   luai_userstateopen(L);
  197. }
  198.  
  199.  
  200. /*
  201. ** preinitialize a state with consistent values without allocating
  202. ** any memory (to avoid errors)
  203. */
  204. static void preinit_state (lua_State *L, global_State *g) {
  205.   G(L) = g;
  206.   L->stack = NULL;
  207.   L->ci = NULL;
  208.   L->stacksize = 0;
  209.   L->errorJmp = NULL;
  210.   L->nCcalls = 0;
  211.   L->hook = NULL;
  212.   L->hookmask = 0;
  213.   L->basehookcount = 0;
  214.   L->allowhook = 1;
  215.   resethookcount(L);
  216.   L->openupval = NULL;
  217.   L->nny = 1;
  218.   L->status = LUA_OK;
  219.   L->errfunc = 0;
  220. }
  221.  
  222.  
  223. static void close_state (lua_State *L) {
  224.   global_State *g = G(L);
  225.   luaF_close(L, L->stack);  /* close all upvalues for this thread */
  226.   luaC_freeallobjects(L);  /* collect all objects */
  227.   if (g->version)  /* closing a fully built state? */
  228.     luai_userstateclose(L);
  229.   luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
  230.   luaZ_freebuffer(L, &g->buff);
  231.   freestack(L);
  232.   lua_assert(gettotalbytes(g) == sizeof(LG));
  233.   (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0);  /* free main block */
  234. }
  235.  
  236.  
  237. LUA_API lua_State *lua_newthread (lua_State *L) {
  238.   lua_State *L1;
  239.   lua_lock(L);
  240.   luaC_checkGC(L);
  241.   L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th;
  242.   setthvalue(L, L->top, L1);
  243.   api_incr_top(L);
  244.   preinit_state(L1, G(L));
  245.   L1->hookmask = L->hookmask;
  246.   L1->basehookcount = L->basehookcount;
  247.   L1->hook = L->hook;
  248.   resethookcount(L1);
  249.   luai_userstatethread(L, L1);
  250.   stack_init(L1, L);  /* init stack */
  251.   lua_unlock(L);
  252.   return L1;
  253. }
  254.  
  255.  
  256. void luaE_freethread (lua_State *L, lua_State *L1) {
  257.   LX *l = fromstate(L1);
  258.   luaF_close(L1, L1->stack);  /* close all upvalues for this thread */
  259.   lua_assert(L1->openupval == NULL);
  260.   luai_userstatefree(L, L1);
  261.   freestack(L1);
  262.   luaM_free(L, l);
  263. }
  264.  
  265.  
  266. LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
  267.   int i;
  268.   lua_State *L;
  269.   global_State *g;
  270.   LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG)));
  271.   if (l == NULL) return NULL;
  272.   L = &l->l.l;
  273.   g = &l->g;
  274.   L->next = NULL;
  275.   L->tt = LUA_TTHREAD;
  276.   g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
  277.   L->marked = luaC_white(g);
  278.   g->gckind = KGC_NORMAL;
  279.   preinit_state(L, g);
  280.   g->frealloc = f;
  281.   g->ud = ud;
  282.   g->mainthread = L;
  283.   g->seed = makeseed(L);
  284.   g->uvhead.u.l.prev = &g->uvhead;
  285.   g->uvhead.u.l.next = &g->uvhead;
  286.   g->gcrunning = 0;  /* no GC while building state */
  287.   g->GCestimate = 0;
  288.   g->strt.size = 0;
  289.   g->strt.nuse = 0;
  290.   g->strt.hash = NULL;
  291.   setnilvalue(&g->l_registry);
  292.   luaZ_initbuffer(L, &g->buff);
  293.   g->panic = NULL;
  294.   g->version = NULL;
  295.   g->gcstate = GCSpause;
  296.   g->allgc = NULL;
  297.   g->finobj = NULL;
  298.   g->tobefnz = NULL;
  299.   g->sweepgc = g->sweepfin = NULL;
  300.   g->gray = g->grayagain = NULL;
  301.   g->weak = g->ephemeron = g->allweak = NULL;
  302.   g->totalbytes = sizeof(LG);
  303.   g->GCdebt = 0;
  304.   g->gcpause = LUAI_GCPAUSE;
  305.   g->gcmajorinc = LUAI_GCMAJOR;
  306.   g->gcstepmul = LUAI_GCMUL;
  307.   for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
  308.   if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
  309.     /* memory allocation error: free partial state */
  310.     close_state(L);
  311.     L = NULL;
  312.   }
  313.   return L;
  314. }
  315.  
  316.  
  317. LUA_API void lua_close (lua_State *L) {
  318.   L = G(L)->mainthread;  /* only the main thread can be closed */
  319.   lua_lock(L);
  320.   close_state(L);
  321. }
  322.  
  323.  
  324.