root/lib/lua/lfunc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. luaF_newCclosure
  2. luaF_newLclosure
  3. luaF_newupval
  4. luaF_findupval
  5. unlinkupval
  6. luaF_freeupval
  7. luaF_close
  8. luaF_newproto
  9. luaF_freeproto
  10. luaF_freeclosure
  11. luaF_getlocalname

   1 /*
   2 ** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 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 LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) {
  24   Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems)));
  25   luaC_link(L, obj2gco(c), LUA_TFUNCTION);
  26   c->c.isC = 1;
  27   c->c.env = e;
  28   c->c.nupvalues = cast_byte(nelems);
  29   return c;
  30 }
  31 
  32 
  33 LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) {
  34   Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
  35   luaC_link(L, obj2gco(c), LUA_TFUNCTION);
  36   c->l.isC = 0;
  37   c->l.env = e;
  38   c->l.nupvalues = cast_byte(nelems);
  39   while (nelems--) c->l.upvals[nelems] = NULL;
  40   return c;
  41 }
  42 
  43 
  44 LUAI_FUNC UpVal *luaF_newupval (lua_State *L) {
  45   UpVal *uv = luaM_new(L, UpVal);
  46   luaC_link(L, obj2gco(uv), LUA_TUPVAL);
  47   uv->v = &uv->u.value;
  48   setnilvalue(uv->v);
  49   return uv;
  50 }
  51 
  52 
  53 LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level) {
  54   global_State *g = G(L);
  55   GCObject **pp = &L->openupval;
  56   UpVal *p;
  57   UpVal *uv;
  58   while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) {
  59     lua_assert(p->v != &p->u.value);
  60     if (p->v == level) {  /* found a corresponding upvalue? */
  61       if (isdead(g, obj2gco(p)))  /* is it dead? */
  62         changewhite(obj2gco(p));  /* ressurect it */
  63       return p;
  64     }
  65     pp = &p->next;
  66   }
  67   uv = luaM_new(L, UpVal);  /* not found: create a new one */
  68   uv->tt = LUA_TUPVAL;
  69   uv->marked = luaC_white(g);
  70   uv->v = level;  /* current value lives in the stack */
  71   uv->next = *pp;  /* chain it in the proper position */
  72   *pp = obj2gco(uv);
  73   uv->u.l.prev = &g->uvhead;  /* double link it in `uvhead' list */
  74   uv->u.l.next = g->uvhead.u.l.next;
  75   uv->u.l.next->u.l.prev = uv;
  76   g->uvhead.u.l.next = uv;
  77   lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
  78   return uv;
  79 }
  80 
  81 
  82 static void unlinkupval (UpVal *uv) {
  83   lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
  84   uv->u.l.next->u.l.prev = uv->u.l.prev;  /* remove from `uvhead' list */
  85   uv->u.l.prev->u.l.next = uv->u.l.next;
  86 }
  87 
  88 
  89 LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv) {
  90   if (uv->v != &uv->u.value)  /* is it open? */
  91     unlinkupval(uv);  /* remove from open list */
  92   luaM_free(L, uv);  /* free upvalue */
  93 }
  94 
  95 
  96 LUAI_FUNC void luaF_close (lua_State *L, StkId level) {
  97   UpVal *uv;
  98   global_State *g = G(L);
  99   while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) {
 100     GCObject *o = obj2gco(uv);
 101     lua_assert(!isblack(o) && uv->v != &uv->u.value);
 102     L->openupval = uv->next;  /* remove from `open' list */
 103     if (isdead(g, o))
 104       luaF_freeupval(L, uv);  /* free upvalue */
 105     else {
 106       unlinkupval(uv);
 107       setobj(L, &uv->u.value, uv->v);
 108       uv->v = &uv->u.value;  /* now current value lives here */
 109       luaC_linkupval(L, uv);  /* link upvalue into `gcroot' list */
 110     }
 111   }
 112 }
 113 
 114 
 115 LUAI_FUNC Proto *luaF_newproto (lua_State *L) {
 116   Proto *f = luaM_new(L, Proto);
 117   luaC_link(L, obj2gco(f), LUA_TPROTO);
 118   f->k = NULL;
 119   f->sizek = 0;
 120   f->p = NULL;
 121   f->sizep = 0;
 122   f->code = NULL;
 123   f->sizecode = 0;
 124   f->sizelineinfo = 0;
 125   f->sizeupvalues = 0;
 126   f->nups = 0;
 127   f->upvalues = NULL;
 128   f->numparams = 0;
 129   f->is_vararg = 0;
 130   f->maxstacksize = 0;
 131   f->lineinfo = NULL;
 132   f->sizelocvars = 0;
 133   f->locvars = NULL;
 134   f->linedefined = 0;
 135   f->lastlinedefined = 0;
 136   f->source = NULL;
 137   return f;
 138 }
 139 
 140 
 141 LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f) {
 142   luaM_freearray(L, f->code, f->sizecode, Instruction);
 143   luaM_freearray(L, f->p, f->sizep, Proto *);
 144   luaM_freearray(L, f->k, f->sizek, TValue);
 145   luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
 146   luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
 147   luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
 148   luaM_free(L, f);
 149 }
 150 
 151 
 152 LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c) {
 153   int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) :
 154                           sizeLclosure(c->l.nupvalues);
 155   luaM_freemem(L, c, size);
 156 }
 157 
 158 
 159 /*
 160 ** Look for n-th local variable at line `line' in function `func'.
 161 ** Returns NULL if not found.
 162 */
 163 LUAI_FUNC const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
 164   int i;
 165   for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
 166     if (pc < f->locvars[i].endpc) {  /* is variable active? */
 167       local_number--;
 168       if (local_number == 0)
 169         return getstr(f->locvars[i].varname);
 170     }
 171   }
 172   return NULL;  /* not found */
 173 }
 174 

/* [<][>][^][v][top][bottom][index][help] */