annotate src/lua/lfunc.c @ 331:6ec288064d49

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