LCOV - code coverage report
Current view: top level - src - lfunc.c Coverage Total Hit
Test: Lua 5.2.4 Lines: 100.0 % 93 93
Test Date: 2024-04-28 10:23:12
Legend: Lines: hit not hit

            Line data    Source code
       1              : /*
       2              : ** $Id: lfunc.c,v 2.30.1.1 2013/04/12 18:48:47 roberto Exp $
       3              : ** Auxiliary functions to manipulate prototypes and closures
       4              : ** See Copyright Notice in lua.h
       5              : */
       6              : 
       7              : 
       8              : #include <stddef.h>
       9              : 
      10              : #define lfunc_c
      11              : #define LUA_CORE
      12              : 
      13              : #include "lua.h"
      14              : 
      15              : #include "lfunc.h"
      16              : #include "lgc.h"
      17              : #include "lmem.h"
      18              : #include "lobject.h"
      19              : #include "lstate.h"
      20              : 
      21              : 
      22              : 
      23          535 : Closure *luaF_newCclosure (lua_State *L, int n) {
      24          535 :   Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n), NULL, 0)->cl;
      25          535 :   c->c.nupvalues = cast_byte(n);
      26          535 :   return c;
      27              : }
      28              : 
      29              : 
      30         3408 : Closure *luaF_newLclosure (lua_State *L, int n) {
      31         3408 :   Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n), NULL, 0)->cl;
      32         3408 :   c->l.p = NULL;
      33         3408 :   c->l.nupvalues = cast_byte(n);
      34        13802 :   while (n--) c->l.upvals[n] = NULL;
      35         3408 :   return c;
      36              : }
      37              : 
      38              : 
      39          464 : UpVal *luaF_newupval (lua_State *L) {
      40          464 :   UpVal *uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), NULL, 0)->uv;
      41          464 :   uv->v = &uv->u.value;
      42          464 :   setnilvalue(uv->v);
      43          464 :   return uv;
      44              : }
      45              : 
      46              : 
      47         6871 : UpVal *luaF_findupval (lua_State *L, StkId level) {
      48         6871 :   global_State *g = G(L);
      49         6871 :   GCObject **pp = &L->openupval;
      50              :   UpVal *p;
      51              :   UpVal *uv;
      52        15166 :   while (*pp != NULL && (p = gco2uv(*pp))->v >= level) {
      53         9459 :     GCObject *o = obj2gco(p);
      54              :     lua_assert(p->v != &p->u.value);
      55              :     lua_assert(!isold(o) || isold(obj2gco(L)));
      56         9459 :     if (p->v == level) {  /* found a corresponding upvalue? */
      57         1164 :       if (isdead(g, o))  /* is it dead? */
      58            1 :         changewhite(o);  /* resurrect it */
      59         1164 :       return p;
      60              :     }
      61         8295 :     pp = &p->next;
      62              :   }
      63              :   /* not found: create a new one */
      64         5707 :   uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), pp, 0)->uv;
      65         5707 :   uv->v = level;  /* current value lives in the stack */
      66         5707 :   uv->u.l.prev = &g->uvhead;  /* double link it in `uvhead' list */
      67         5707 :   uv->u.l.next = g->uvhead.u.l.next;
      68         5707 :   uv->u.l.next->u.l.prev = uv;
      69         5707 :   g->uvhead.u.l.next = uv;
      70              :   lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
      71         5707 :   return uv;
      72              : }
      73              : 
      74              : 
      75         5707 : static void unlinkupval (UpVal *uv) {
      76              :   lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
      77         5707 :   uv->u.l.next->u.l.prev = uv->u.l.prev;  /* remove from `uvhead' list */
      78         5707 :   uv->u.l.prev->u.l.next = uv->u.l.next;
      79         5707 : }
      80              : 
      81              : 
      82         6048 : void luaF_freeupval (lua_State *L, UpVal *uv) {
      83         6048 :   if (uv->v != &uv->u.value)  /* is it open? */
      84            4 :     unlinkupval(uv);  /* remove from open list */
      85         6048 :   luaM_free(L, uv);  /* free upvalue */
      86         6048 : }
      87              : 
      88              : 
      89         2059 : void luaF_close (lua_State *L, StkId level) {
      90              :   UpVal *uv;
      91         2059 :   global_State *g = G(L);
      92         7765 :   while (L->openupval != NULL && (uv = gco2uv(L->openupval))->v >= level) {
      93         5706 :     GCObject *o = obj2gco(uv);
      94              :     lua_assert(!isblack(o) && uv->v != &uv->u.value);
      95         5706 :     L->openupval = uv->next;  /* remove from `open' list */
      96         5706 :     if (isdead(g, o))
      97            3 :       luaF_freeupval(L, uv);  /* free upvalue */
      98              :     else {
      99         5703 :       unlinkupval(uv);  /* remove upvalue from 'uvhead' list */
     100         5703 :       setobj(L, &uv->u.value, uv->v);  /* move value to upvalue slot */
     101         5703 :       uv->v = &uv->u.value;  /* now current value lives here */
     102         5703 :       gch(o)->next = g->allgc;  /* link upvalue into 'allgc' list */
     103         5703 :       g->allgc = o;
     104         5703 :       luaC_checkupvalcolor(g, uv);
     105              :     }
     106              :   }
     107         2059 : }
     108              : 
     109              : 
     110         2211 : Proto *luaF_newproto (lua_State *L) {
     111         2211 :   Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p;
     112         2211 :   f->k = NULL;
     113         2211 :   f->sizek = 0;
     114         2211 :   f->p = NULL;
     115         2211 :   f->sizep = 0;
     116         2211 :   f->code = NULL;
     117         2211 :   f->cache = NULL;
     118         2211 :   f->sizecode = 0;
     119         2211 :   f->lineinfo = NULL;
     120         2211 :   f->sizelineinfo = 0;
     121         2211 :   f->upvalues = NULL;
     122         2211 :   f->sizeupvalues = 0;
     123         2211 :   f->numparams = 0;
     124         2211 :   f->is_vararg = 0;
     125         2211 :   f->maxstacksize = 0;
     126         2211 :   f->locvars = NULL;
     127         2211 :   f->sizelocvars = 0;
     128         2211 :   f->linedefined = 0;
     129         2211 :   f->lastlinedefined = 0;
     130         2211 :   f->source = NULL;
     131         2211 :   return f;
     132              : }
     133              : 
     134              : 
     135         2056 : void luaF_freeproto (lua_State *L, Proto *f) {
     136         2056 :   luaM_freearray(L, f->code, f->sizecode);
     137         2056 :   luaM_freearray(L, f->p, f->sizep);
     138         2056 :   luaM_freearray(L, f->k, f->sizek);
     139         2056 :   luaM_freearray(L, f->lineinfo, f->sizelineinfo);
     140         2056 :   luaM_freearray(L, f->locvars, f->sizelocvars);
     141         2056 :   luaM_freearray(L, f->upvalues, f->sizeupvalues);
     142         2056 :   luaM_free(L, f);
     143         2056 : }
     144              : 
     145              : 
     146              : /*
     147              : ** Look for n-th local variable at line `line' in function `func'.
     148              : ** Returns NULL if not found.
     149              : */
     150          152 : const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
     151              :   int i;
     152          191 :   for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
     153           50 :     if (pc < f->locvars[i].endpc) {  /* is variable active? */
     154           33 :       local_number--;
     155           33 :       if (local_number == 0)
     156           11 :         return getstr(f->locvars[i].varname);
     157              :     }
     158              :   }
     159          141 :   return NULL;  /* not found */
     160              : }
     161              : 
        

Generated by: LCOV version 2.0-1