- Main Page
- Related Pages
- Modules
- Data Structures
- Files

# lua/lfunc.c

Go to the documentation of this file.

    00001 /*
    00002 ** $Id: lfunc.c,v 2.12a 2005/12/22 16:19:56 roberto Exp $
    00003 ** Auxiliary functions to manipulate prototypes and closures
    00004 ** See Copyright Notice in lua.h
    00005 */
    00006
    00007
    00008 #include <stddef.h>
    00009
    00010 #define lfunc_c
    00011 #define LUA_CORE
    00012
    00013 #include "lua.h"
    00014
    00015 #include "lfunc.h"
    00016 #include "lgc.h"
    00017 #include "lmem.h"
    00018 #include "lobject.h"
    00019 #include "lstate.h"
    00020
    00021
    00022
    00023 Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) {
    00024   Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems)));
    00025   luaC_link(L, obj2gco(c), LUA_TFUNCTION);
    00026   c->c.isC = 1;
    00027   c->c.env = e;
    00028   c->c.nupvalues = cast_byte(nelems);
    00029   return c;
    00030 }
    00031
    00032
    00033 Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) {
    00034   Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
    00035   luaC_link(L, obj2gco(c), LUA_TFUNCTION);
    00036   c->l.isC = 0;
    00037   c->l.env = e;
    00038   c->l.nupvalues = cast_byte(nelems);
    00039   while (nelems--) c->l.upvals[nelems] = NULL;
    00040   return c;
    00041 }
    00042
    00043
    00044 UpVal *luaF_newupval (lua_State *L) {
    00045   UpVal *uv = luaM_new(L, UpVal);
    00046   luaC_link(L, obj2gco(uv), LUA_TUPVAL);
    00047   uv->v = &uv->u.value;
    00048   setnilvalue(uv->v);
    00049   return uv;
    00050 }
    00051
    00052
    00053 UpVal *luaF_findupval (lua_State *L, StkId level) {
    00054   global_State *g = G(L);
    00055   GCObject **pp = &L->openupval;
    00056   UpVal *p;
    00057   UpVal *uv;
    00058   while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) {
    00059     lua_assert(p->v != &p->u.value);
    00060     if (p->v == level) {  /* found a corresponding upvalue? */
    00061       if (isdead(g, obj2gco(p)))  /* is it dead? */
    00062         changewhite(obj2gco(p));  /* ressurect it */
    00063       return p;
    00064     }
    00065     pp = &p->next;
    00066   }
    00067   uv = luaM_new(L, UpVal);  /* not found: create a new one */
    00068   uv->tt = LUA_TUPVAL;
    00069   uv->marked = luaC_white(g);
    00070   uv->v = level;  /* current value lives in the stack */
    00071   uv->next = *pp;  /* chain it in the proper position */
    00072   *pp = obj2gco(uv);
    00073   uv->u.l.prev = &g->uvhead;  /* double link it in `uvhead' list */
    00074   uv->u.l.next = g->uvhead.u.l.next;
    00075   uv->u.l.next->u.l.prev = uv;
    00076   g->uvhead.u.l.next = uv;
    00077   lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
    00078   return uv;
    00079 }
    00080
    00081
    00082 static void unlinkupval (UpVal *uv) {
    00083   lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
    00084   uv->u.l.next->u.l.prev = uv->u.l.prev;  /* remove from `uvhead' list */
    00085   uv->u.l.prev->u.l.next = uv->u.l.next;
    00086 }
    00087
    00088
    00089 void luaF_freeupval (lua_State *L, UpVal *uv) {
    00090   if (uv->v != &uv->u.value)  /* is it open? */
    00091     unlinkupval(uv);  /* remove from open list */
    00092   luaM_free(L, uv);  /* free upvalue */
    00093 }
    00094
    00095
    00096 void luaF_close (lua_State *L, StkId level) {
    00097   UpVal *uv;
    00098   global_State *g = G(L);
    00099   while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) {
    00100     GCObject *o = obj2gco(uv);
    00101     lua_assert(!isblack(o) && uv->v != &uv->u.value);
    00102     L->openupval = uv->next;  /* remove from `open' list */
    00103     if (isdead(g, o))
    00104       luaF_freeupval(L, uv);  /* free upvalue */
    00105     else {
    00106       unlinkupval(uv);
    00107       setobj(L, &uv->u.value, uv->v);
    00108       uv->v = &uv->u.value;  /* now current value lives here */
    00109       luaC_linkupval(L, uv);  /* link upvalue into `gcroot' list */
    00110     }
    00111   }
    00112 }
    00113
    00114
    00115 Proto *luaF_newproto (lua_State *L) {
    00116   Proto *f = luaM_new(L, Proto);
    00117   luaC_link(L, obj2gco(f), LUA_TPROTO);
    00118   f->k = NULL;
    00119   f->sizek = 0;
    00120   f->p = NULL;
    00121   f->sizep = 0;
    00122   f->code = NULL;
    00123   f->sizecode = 0;
    00124   f->sizelineinfo = 0;
    00125   f->sizeupvalues = 0;
    00126   f->nups = 0;
    00127   f->upvalues = NULL;
    00128   f->numparams = 0;
    00129   f->is_vararg = 0;
    00130   f->maxstacksize = 0;
    00131   f->lineinfo = NULL;
    00132   f->sizelocvars = 0;
    00133   f->locvars = NULL;
    00134   f->linedefined = 0;
    00135   f->lastlinedefined = 0;
    00136   f->source = NULL;
    00137   return f;
    00138 }
    00139
    00140
    00141 void luaF_freeproto (lua_State *L, Proto *f) {
    00142   luaM_freearray(L, f->code, f->sizecode, Instruction);
    00143   luaM_freearray(L, f->p, f->sizep, Proto *);
    00144   luaM_freearray(L, f->k, f->sizek, TValue);
    00145   luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
    00146   luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
    00147   luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
    00148   luaM_free(L, f);
    00149 }
    00150
    00151
    00152 void luaF_freeclosure (lua_State *L, Closure *c) {
    00153   int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) :
    00154                           sizeLclosure(c->l.nupvalues);
    00155   luaM_freemem(L, c, size);
    00156 }
    00157
    00158
    00159 /*
    00160 ** Look for n-th local variable at line `line' in function `func'.
    00161 ** Returns NULL if not found.
    00162 */
    00163 const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
    00164   int i;
    00165   for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
    00166     if (pc < f->locvars[i].endpc) {  /* is variable active? */
    00167       local_number--;
    00168       if (local_number == 0)
    00169         return getstr(f->locvars[i].varname);
    00170     }
    00171   }
    00172   return NULL;  /* not found */
    00173 }
    00174