?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  1. /*
  2. ** $Id: lstate.c,v 2.133.1.1 2017/04/19 17:39:34 roberto Exp $
  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. #if !defined(LUAI_GCPAUSE)
  32. #define LUAI_GCPAUSE    200  /* 200% */
  33. #endif
  34.  
  35. #if !defined(LUAI_GCMUL)
  36. #define LUAI_GCMUL      200 /* GC runs 'twice the speed' of memory allocation */
  37. #endif
  38.  
  39.  
  40. /*
  41. ** a macro to help the creation of a unique random seed when a state is
  42. ** created; the seed is used to randomize hashes.
  43. */
  44. #if !defined(luai_makeseed)
  45. #include <time.h>
  46. #define luai_makeseed()         cast(unsigned int, time(NULL))
  47. #endif
  48.  
  49.  
  50.  
  51. /*
  52. ** thread state + extra space
  53. */
  54. typedef struct LX {
  55.   lu_byte extra_[LUA_EXTRASPACE];
  56.   lua_State l;
  57. } LX;
  58.  
  59.  
  60. /*
  61. ** Main thread combines a thread state and the global state
  62. */
  63. typedef struct LG {
  64.   LX l;
  65.   global_State g;
  66. } LG;
  67.  
  68.  
  69.  
  70. #define fromstate(L)    (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))
  71.  
  72.  
  73. /*
  74. ** Compute an initial seed as random as possible. Rely on Address Space
  75. ** Layout Randomization (if present) to increase randomness..
  76. */
  77. #define addbuff(b,p,e) \
  78.   { size_t t = cast(size_t, e); \
  79.     memcpy(b + p, &t, sizeof(t)); p += sizeof(t); }
  80.  
  81. static unsigned int makeseed (lua_State *L) {
  82.   char buff[4 * sizeof(size_t)];
  83.   unsigned int h = luai_makeseed();
  84.   int p = 0;
  85.   addbuff(buff, p, L);  /* heap variable */
  86.   addbuff(buff, p, &h);  /* local variable */
  87.   addbuff(buff, p, luaO_nilobject);  /* global variable */
  88.   addbuff(buff, p, &lua_newstate);  /* public function */
  89.   lua_assert(p == sizeof(buff));
  90.   return luaS_hash(buff, p, h);
  91. }
  92.  
  93.  
  94. /*
  95. ** set GCdebt to a new value keeping the value (totalbytes + GCdebt)
  96. ** invariant (and avoiding underflows in 'totalbytes')
  97. */
  98. void luaE_setdebt (global_State *g, l_mem debt) {
  99.   l_mem tb = gettotalbytes(g);
  100.   lua_assert(tb > 0);
  101.   if (debt < tb - MAX_LMEM)
  102.     debt = tb - MAX_LMEM;  /* will make 'totalbytes == MAX_LMEM' */
  103.   g->totalbytes = tb - debt;
  104.   g->GCdebt = debt;
  105. }
  106.  
  107.  
  108. CallInfo *luaE_extendCI (lua_State *L) {
  109.   CallInfo *ci = luaM_new(L, CallInfo);
  110.   lua_assert(L->ci->next == NULL);
  111.   L->ci->next = ci;
  112.   ci->previous = L->ci;
  113.   ci->next = NULL;
  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. */
  137. void luaE_shrinkCI (lua_State *L) {
  138.   CallInfo *ci = L->ci;
  139.   CallInfo *next2;  /* next's next */
  140.   /* while there are two nexts */
  141.   while (ci->next != NULL && (next2 = ci->next->next) != NULL) {
  142.     luaM_free(L, ci->next);  /* free next */
  143.     L->nci--;
  144.     ci->next = next2;  /* remove 'next' from the list */
  145.     next2->previous = ci;
  146.     ci = next2;  /* keep next's next */
  147.   }
  148. }
  149.  
  150.  
  151. static void stack_init (lua_State *L1, lua_State *L) {
  152.   int i; CallInfo *ci;
  153.   /* initialize stack array */
  154.   L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue);
  155.   L1->stacksize = BASIC_STACK_SIZE;
  156.   for (i = 0; i < BASIC_STACK_SIZE; i++)
  157.     setnilvalue(L1->stack + i);  /* erase new stack */
  158.   L1->top = L1->stack;
  159.   L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
  160.   /* initialize first ci */
  161.   ci = &L1->base_ci;
  162.   ci->next = ci->previous = NULL;
  163.   ci->callstatus = 0;
  164.   ci->func = L1->top;
  165.   setnilvalue(L1->top++);  /* 'function' entry for this 'ci' */
  166.   ci->top = L1->top + LUA_MINSTACK;
  167.   L1->ci = ci;
  168. }
  169.  
  170.  
  171. static void freestack (lua_State *L) {
  172.   if (L->stack == NULL)
  173.     return;  /* stack not completely built yet */
  174.   L->ci = &L->base_ci;  /* free the entire 'ci' list */
  175.   luaE_freeCI(L);
  176.   lua_assert(L->nci == 0);
  177.   luaM_freearray(L, L->stack, L->stacksize);  /* free stack array */
  178. }
  179.  
  180.  
  181. /*
  182. ** Create registry table and its predefined values
  183. */
  184. static void init_registry (lua_State *L, global_State *g) {
  185.   TValue temp;
  186.   /* create registry */
  187.   Table *registry = luaH_new(L);
  188.   sethvalue(L, &g->l_registry, registry);
  189.   luaH_resize(L, registry, LUA_RIDX_LAST, 0);
  190.   /* registry[LUA_RIDX_MAINTHREAD] = L */
  191.   setthvalue(L, &temp, L);  /* temp = L */
  192.   luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp);
  193.   /* registry[LUA_RIDX_GLOBALS] = table of globals */
  194.   sethvalue(L, &temp, luaH_new(L));  /* temp = new table (global table) */
  195.   luaH_setint(L, registry, LUA_RIDX_GLOBALS, &temp);
  196. }
  197.  
  198.  
  199. /*
  200. ** open parts of the state that may cause memory-allocation errors.
  201. ** ('g->version' != NULL flags that the state was completely build)
  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->gcrunning = 1;  /* allow gc */
  212.   g->version = lua_version(NULL);
  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 = NULL;
  224.   L->ci = NULL;
  225.   L->nci = 0;
  226.   L->stacksize = 0;
  227.   L->twups = L;  /* thread has no upvalues */
  228.   L->errorJmp = NULL;
  229.   L->nCcalls = 0;
  230.   L->hook = NULL;
  231.   L->hookmask = 0;
  232.   L->basehookcount = 0;
  233.   L->allowhook = 1;
  234.   resethookcount(L);
  235.   L->openupval = NULL;
  236.   L->nny = 1;
  237.   L->status = LUA_OK;
  238.   L->errfunc = 0;
  239. }
  240.  
  241.  
  242. static void close_state (lua_State *L) {
  243.   global_State *g = G(L);
  244.   luaF_close(L, L->stack);  /* close all upvalues for this thread */
  245.   luaC_freeallobjects(L);  /* collect all objects */
  246.   if (g->version)  /* closing a fully built state? */
  247.     luai_userstateclose(L);
  248.   luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
  249.   freestack(L);
  250.   lua_assert(gettotalbytes(g) == sizeof(LG));
  251.   (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0);  /* free main block */
  252. }
  253.  
  254.  
  255. LUA_API lua_State *lua_newthread (lua_State *L) {
  256.   global_State *g = G(L);
  257.   lua_State *L1;
  258.   lua_lock(L);
  259.   luaC_checkGC(L);
  260.   /* create new thread */
  261.   L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l;
  262.   L1->marked = luaC_white(g);
  263.   L1->tt = LUA_TTHREAD;
  264.   /* link it on list 'allgc' */
  265.   L1->next = g->allgc;
  266.   g->allgc = obj2gco(L1);
  267.   /* anchor it on L stack */
  268.   setthvalue(L, L->top, L1);
  269.   api_incr_top(L);
  270.   preinit_thread(L1, g);
  271.   L1->hookmask = L->hookmask;
  272.   L1->basehookcount = L->basehookcount;
  273.   L1->hook = L->hook;
  274.   resethookcount(L1);
  275.   /* initialize L1 extra space */
  276.   memcpy(lua_getextraspace(L1), lua_getextraspace(g->mainthread),
  277.          LUA_EXTRASPACE);
  278.   luai_userstatethread(L, L1);
  279.   stack_init(L1, L);  /* init stack */
  280.   lua_unlock(L);
  281.   return L1;
  282. }
  283.  
  284.  
  285. void luaE_freethread (lua_State *L, lua_State *L1) {
  286.   LX *l = fromstate(L1);
  287.   luaF_close(L1, L1->stack);  /* close all upvalues for this thread */
  288.   lua_assert(L1->openupval == NULL);
  289.   luai_userstatefree(L, L1);
  290.   freestack(L1);
  291.   luaM_free(L, l);
  292. }
  293.  
  294.  
  295. LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
  296.   int i;
  297.   lua_State *L;
  298.   global_State *g;
  299.   LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG)));
  300.   if (l == NULL) return NULL;
  301.   L = &l->l.l;
  302.   g = &l->g;
  303.   L->next = NULL;
  304.   L->tt = LUA_TTHREAD;
  305.   g->currentwhite = bitmask(WHITE0BIT);
  306.   L->marked = luaC_white(g);
  307.   preinit_thread(L, g);
  308.   g->frealloc = f;
  309.   g->ud = ud;
  310.   g->mainthread = L;
  311.   g->seed = makeseed(L);
  312.   g->gcrunning = 0;  /* no GC while building state */
  313.   g->GCestimate = 0;
  314.   g->strt.size = g->strt.nuse = 0;
  315.   g->strt.hash = NULL;
  316.   setnilvalue(&g->l_registry);
  317.   g->panic = NULL;
  318.   g->version = NULL;
  319.   g->gcstate = GCSpause;
  320.   g->gckind = KGC_NORMAL;
  321.   g->allgc = g->finobj = g->tobefnz = g->fixedgc = NULL;
  322.   g->sweepgc = NULL;
  323.   g->gray = g->grayagain = NULL;
  324.   g->weak = g->ephemeron = g->allweak = NULL;
  325.   g->twups = NULL;
  326.   g->totalbytes = sizeof(LG);
  327.   g->GCdebt = 0;
  328.   g->gcfinnum = 0;
  329.   g->gcpause = LUAI_GCPAUSE;
  330.   g->gcstepmul = LUAI_GCMUL;
  331.   for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
  332.   if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
  333.     /* memory allocation error: free partial state */
  334.     close_state(L);
  335.     L = NULL;
  336.   }
  337.   return L;
  338. }
  339.  
  340.  
  341. LUA_API void lua_close (lua_State *L) {
  342.   L = G(L)->mainthread;  /* only the main thread can be closed */
  343.   lua_lock(L);
  344.   close_state(L);
  345. }
  346.  
  347.  
  348.