rpm
4.5
|
00001 /* 00002 ** $Id: lfunc.c,v 1.67 2003/03/18 12:50:04 roberto Exp $ 00003 ** Auxiliary functions to manipulate prototypes and closures 00004 ** See Copyright Notice in lua.h 00005 */ 00006 00007 00008 #include <stdlib.h> 00009 00010 #define lfunc_c 00011 00012 #include "lua.h" 00013 00014 #include "lfunc.h" 00015 #include "lgc.h" 00016 #include "lmem.h" 00017 #include "lobject.h" 00018 #include "lstate.h" 00019 00020 00021 #define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ 00022 cast(int, sizeof(TObject)*((n)-1))) 00023 00024 #define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ 00025 cast(int, sizeof(TObject *)*((n)-1))) 00026 00027 00028 00029 Closure *luaF_newCclosure (lua_State *L, int nelems) { 00030 Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); 00031 luaC_link(L, valtogco(c), LUA_TFUNCTION); 00032 c->c.isC = 1; 00033 c->c.nupvalues = cast(lu_byte, nelems); 00034 return c; 00035 } 00036 00037 00038 Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *e) { 00039 Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); 00040 luaC_link(L, valtogco(c), LUA_TFUNCTION); 00041 c->l.isC = 0; 00042 c->l.g = *e; 00043 c->l.nupvalues = cast(lu_byte, nelems); 00044 return c; 00045 } 00046 00047 00048 UpVal *luaF_findupval (lua_State *L, StkId level) { 00049 GCObject **pp = &L->openupval; 00050 UpVal *p; 00051 UpVal *v; 00052 while ((p = ngcotouv(*pp)) != NULL && p->v >= level) { 00053 if (p->v == level) return p; 00054 pp = &p->next; 00055 } 00056 v = luaM_new(L, UpVal); /* not found: create a new one */ 00057 v->tt = LUA_TUPVAL; 00058 v->marked = 1; /* open upvalues should not be collected */ 00059 v->v = level; /* current value lives in the stack */ 00060 v->next = *pp; /* chain it in the proper position */ 00061 *pp = valtogco(v); 00062 return v; 00063 } 00064 00065 00066 void luaF_close (lua_State *L, StkId level) { 00067 UpVal *p; 00068 while ((p = ngcotouv(L->openupval)) != NULL && p->v >= level) { 00069 setobj(&p->value, p->v); /* save current value (write barrier) */ 00070 p->v = &p->value; /* now current value lives here */ 00071 L->openupval = p->next; /* remove from `open' list */ 00072 luaC_link(L, valtogco(p), LUA_TUPVAL); 00073 } 00074 } 00075 00076 00077 Proto *luaF_newproto (lua_State *L) { 00078 Proto *f = luaM_new(L, Proto); 00079 luaC_link(L, valtogco(f), LUA_TPROTO); 00080 f->k = NULL; 00081 f->sizek = 0; 00082 f->p = NULL; 00083 f->sizep = 0; 00084 f->code = NULL; 00085 f->sizecode = 0; 00086 f->sizelineinfo = 0; 00087 f->sizeupvalues = 0; 00088 f->nups = 0; 00089 f->upvalues = NULL; 00090 f->numparams = 0; 00091 f->is_vararg = 0; 00092 f->maxstacksize = 0; 00093 f->lineinfo = NULL; 00094 f->sizelocvars = 0; 00095 f->locvars = NULL; 00096 f->lineDefined = 0; 00097 f->source = NULL; 00098 return f; 00099 } 00100 00101 00102 void luaF_freeproto (lua_State *L, Proto *f) { 00103 luaM_freearray(L, f->code, f->sizecode, Instruction); 00104 luaM_freearray(L, f->p, f->sizep, Proto *); 00105 luaM_freearray(L, f->k, f->sizek, TObject); 00106 luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); 00107 luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); 00108 luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); 00109 luaM_freelem(L, f); 00110 } 00111 00112 00113 void luaF_freeclosure (lua_State *L, Closure *c) { 00114 int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : 00115 sizeLclosure(c->l.nupvalues); 00116 luaM_free(L, c, size); 00117 } 00118 00119 00120 /* 00121 ** Look for n-th local variable at line `line' in function `func'. 00122 ** Returns NULL if not found. 00123 */ 00124 const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { 00125 int i; 00126 for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) { 00127 if (pc < f->locvars[i].endpc) { /* is variable active? */ 00128 local_number--; 00129 if (local_number == 0) 00130 return getstr(f->locvars[i].varname); 00131 } 00132 } 00133 return NULL; /* not found */ 00134 } 00135