LCOV - code coverage report
Current view: top level - external/lua/src - lstate.c (source / functions) Hit Total Coverage
Test: rapport Lines: 170 240 70.8 %
Date: 2021-12-10 16:22:55 Functions: 14 21 66.7 %
Branches: 18 36 50.0 %

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

Generated by: LCOV version 1.15