diff options
Diffstat (limited to 'src/lfunc.c')
| -rw-r--r-- | src/lfunc.c | 130 |
1 files changed, 78 insertions, 52 deletions
diff --git a/src/lfunc.c b/src/lfunc.c index 6841ef71..31044fa5 100644 --- a/src/lfunc.c +++ b/src/lfunc.c @@ -1,5 +1,5 @@ /* -** $Id: lfunc.c,v 1.34 2000/10/30 12:20:29 roberto Exp $ +** $Id: lfunc.c,v 1.67 2003/03/18 12:50:04 roberto Exp $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ @@ -7,87 +7,113 @@ #include <stdlib.h> +#define lfunc_c + #include "lua.h" #include "lfunc.h" +#include "lgc.h" #include "lmem.h" +#include "lobject.h" #include "lstate.h" -#define sizeclosure(n) ((int)sizeof(Closure) + (int)sizeof(TObject)*((n)-1)) +#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ + cast(int, sizeof(TObject)*((n)-1))) + +#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ + cast(int, sizeof(TObject *)*((n)-1))) + -Closure *luaF_newclosure (lua_State *L, int nelems) { - int size = sizeclosure(nelems); - Closure *c = (Closure *)luaM_malloc(L, size); - c->next = L->rootcl; - L->rootcl = c; - c->mark = c; - c->nupvalues = nelems; - L->nblocks += size; +Closure *luaF_newCclosure (lua_State *L, int nelems) { + Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); + luaC_link(L, valtogco(c), LUA_TFUNCTION); + c->c.isC = 1; + c->c.nupvalues = cast(lu_byte, nelems); return c; } +Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *e) { + Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); + luaC_link(L, valtogco(c), LUA_TFUNCTION); + c->l.isC = 0; + c->l.g = *e; + c->l.nupvalues = cast(lu_byte, nelems); + return c; +} + + +UpVal *luaF_findupval (lua_State *L, StkId level) { + GCObject **pp = &L->openupval; + UpVal *p; + UpVal *v; + while ((p = ngcotouv(*pp)) != NULL && p->v >= level) { + if (p->v == level) return p; + pp = &p->next; + } + v = luaM_new(L, UpVal); /* not found: create a new one */ + v->tt = LUA_TUPVAL; + v->marked = 1; /* open upvalues should not be collected */ + v->v = level; /* current value lives in the stack */ + v->next = *pp; /* chain it in the proper position */ + *pp = valtogco(v); + return v; +} + + +void luaF_close (lua_State *L, StkId level) { + UpVal *p; + while ((p = ngcotouv(L->openupval)) != NULL && p->v >= level) { + setobj(&p->value, p->v); /* save current value (write barrier) */ + p->v = &p->value; /* now current value lives here */ + L->openupval = p->next; /* remove from `open' list */ + luaC_link(L, valtogco(p), LUA_TUPVAL); + } +} + + Proto *luaF_newproto (lua_State *L) { Proto *f = luaM_new(L, Proto); - f->knum = NULL; - f->nknum = 0; - f->kstr = NULL; - f->nkstr = 0; - f->kproto = NULL; - f->nkproto = 0; + luaC_link(L, valtogco(f), LUA_TPROTO); + f->k = NULL; + f->sizek = 0; + f->p = NULL; + f->sizep = 0; f->code = NULL; - f->ncode = 0; + f->sizecode = 0; + f->sizelineinfo = 0; + f->sizeupvalues = 0; + f->nups = 0; + f->upvalues = NULL; f->numparams = 0; f->is_vararg = 0; f->maxstacksize = 0; - f->marked = 0; f->lineinfo = NULL; - f->nlineinfo = 0; - f->nlocvars = 0; + f->sizelocvars = 0; f->locvars = NULL; f->lineDefined = 0; f->source = NULL; - f->next = L->rootproto; /* chain in list of protos */ - L->rootproto = f; return f; } -static size_t protosize (Proto *f) { - return sizeof(Proto) - + f->nknum*sizeof(Number) - + f->nkstr*sizeof(TString *) - + f->nkproto*sizeof(Proto *) - + f->ncode*sizeof(Instruction) - + f->nlocvars*sizeof(struct LocVar) - + f->nlineinfo*sizeof(int); -} - - -void luaF_protook (lua_State *L, Proto *f, int pc) { - f->ncode = pc; /* signal that proto was properly created */ - L->nblocks += protosize(f); -} - - void luaF_freeproto (lua_State *L, Proto *f) { - if (f->ncode > 0) /* function was properly created? */ - L->nblocks -= protosize(f); - luaM_free(L, f->code); - luaM_free(L, f->locvars); - luaM_free(L, f->kstr); - luaM_free(L, f->knum); - luaM_free(L, f->kproto); - luaM_free(L, f->lineinfo); - luaM_free(L, f); + luaM_freearray(L, f->code, f->sizecode, Instruction); + luaM_freearray(L, f->p, f->sizep, Proto *); + luaM_freearray(L, f->k, f->sizek, TObject); + luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); + luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); + luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); + luaM_freelem(L, f); } void luaF_freeclosure (lua_State *L, Closure *c) { - L->nblocks -= sizeclosure(c->nupvalues); - luaM_free(L, c); + int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : + sizeLclosure(c->l.nupvalues); + luaM_free(L, c, size); } @@ -97,11 +123,11 @@ void luaF_freeclosure (lua_State *L, Closure *c) { */ const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { int i; - for (i = 0; i<f->nlocvars && f->locvars[i].startpc <= pc; i++) { + for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) { if (pc < f->locvars[i].endpc) { /* is variable active? */ local_number--; if (local_number == 0) - return f->locvars[i].varname->str; + return getstr(f->locvars[i].varname); } } return NULL; /* not found */ |
