1 /*
2 ** $Id: lfunc.c,v 1.1 2002/02/14 10:46:59 jcatki Exp $
3 ** Auxiliary functions to manipulate prototypes and closures
4 ** See Copyright Notice in lua.h
5 */
6 
7 
8 #include <stdlib.h>
9 
10 #include "lua.h"
11 
12 #include "lfunc.h"
13 #include "lmem.h"
14 #include "lstate.h"
15 
16 
17 #define sizeclosure(n)	((int)sizeof(Closure) + (int)sizeof(TObject)*((n)-1))
18 
19 
luaF_newclosure(lua_State * L,int nelems)20 Closure *luaF_newclosure (lua_State *L, int nelems) {
21   int size = sizeclosure(nelems);
22   Closure *c = (Closure *)luaM_malloc(L, size);
23   c->next = L->rootcl;
24   L->rootcl = c;
25   c->mark = c;
26   c->nupvalues = nelems;
27   L->nblocks += size;
28   return c;
29 }
30 
31 
luaF_newproto(lua_State * L)32 Proto *luaF_newproto (lua_State *L) {
33   Proto *f = luaM_new(L, Proto);
34   f->knum = NULL;
35   f->nknum = 0;
36   f->kstr = NULL;
37   f->nkstr = 0;
38   f->kproto = NULL;
39   f->nkproto = 0;
40   f->code = NULL;
41   f->ncode = 0;
42   f->numparams = 0;
43   f->is_vararg = 0;
44   f->maxstacksize = 0;
45   f->marked = 0;
46   f->lineinfo = NULL;
47   f->nlineinfo = 0;
48   f->nlocvars = 0;
49   f->locvars = NULL;
50   f->lineDefined = 0;
51   f->source = NULL;
52   f->next = L->rootproto;  /* chain in list of protos */
53   L->rootproto = f;
54   return f;
55 }
56 
57 
protosize(Proto * f)58 static size_t protosize (Proto *f) {
59   return sizeof(Proto)
60        + f->nknum*sizeof(Number)
61        + f->nkstr*sizeof(TString *)
62        + f->nkproto*sizeof(Proto *)
63        + f->ncode*sizeof(Instruction)
64        + f->nlocvars*sizeof(struct LocVar)
65        + f->nlineinfo*sizeof(int);
66 }
67 
68 
luaF_protook(lua_State * L,Proto * f,int pc)69 void luaF_protook (lua_State *L, Proto *f, int pc) {
70   f->ncode = pc;  /* signal that proto was properly created */
71   L->nblocks += protosize(f);
72 }
73 
74 
luaF_freeproto(lua_State * L,Proto * f)75 void luaF_freeproto (lua_State *L, Proto *f) {
76   if (f->ncode > 0)  /* function was properly created? */
77     L->nblocks -= protosize(f);
78   luaM_free(L, f->code);
79   luaM_free(L, f->locvars);
80   luaM_free(L, f->kstr);
81   luaM_free(L, f->knum);
82   luaM_free(L, f->kproto);
83   luaM_free(L, f->lineinfo);
84   luaM_free(L, f);
85 }
86 
87 
luaF_freeclosure(lua_State * L,Closure * c)88 void luaF_freeclosure (lua_State *L, Closure *c) {
89   L->nblocks -= sizeclosure(c->nupvalues);
90   luaM_free(L, c);
91 }
92 
93 
94 /*
95 ** Look for n-th local variable at line `line' in function `func'.
96 ** Returns NULL if not found.
97 */
luaF_getlocalname(const Proto * f,int local_number,int pc)98 const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
99   int i;
100   for (i = 0; i<f->nlocvars && f->locvars[i].startpc <= pc; i++) {
101     if (pc < f->locvars[i].endpc) {  /* is variable active? */
102       local_number--;
103       if (local_number == 0)
104         return f->locvars[i].varname->str;
105     }
106   }
107   return NULL;  /* not found */
108 }
109 
110