Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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