2 ** $Id: lfunc.c,v 2.12a 2005/12/22 16:19:56 roberto Exp $
3 ** Auxiliary functions to manipulate prototypes and closures
4 ** See Copyright Notice in lua.h
23 Closure
*luaF_newCclosure (lua_State
*L
, int nelems
, Table
*e
) {
24 Closure
*c
= cast(Closure
*, luaM_malloc(L
, sizeCclosure(nelems
)));
25 luaC_link(L
, obj2gco(c
), LUA_TFUNCTION
);
28 c
->c
.nupvalues
= cast_byte(nelems
);
33 Closure
*luaF_newLclosure (lua_State
*L
, int nelems
, Table
*e
) {
34 Closure
*c
= cast(Closure
*, luaM_malloc(L
, sizeLclosure(nelems
)));
35 luaC_link(L
, obj2gco(c
), LUA_TFUNCTION
);
38 c
->l
.nupvalues
= cast_byte(nelems
);
39 while (nelems
--) c
->l
.upvals
[nelems
] = NULL
;
44 UpVal
*luaF_newupval (lua_State
*L
) {
45 UpVal
*uv
= luaM_new(L
, UpVal
);
46 luaC_link(L
, obj2gco(uv
), LUA_TUPVAL
);
53 UpVal
*luaF_findupval (lua_State
*L
, StkId level
) {
54 global_State
*g
= G(L
);
55 GCObject
**pp
= &L
->openupval
;
58 while (*pp
!= NULL
&& (p
= ngcotouv(*pp
))->v
>= level
) {
59 lua_assert(p
->v
!= &p
->u
.value
);
60 if (p
->v
== level
) { /* found a corresponding upvalue? */
61 if (isdead(g
, obj2gco(p
))) /* is it dead? */
62 changewhite(obj2gco(p
)); /* ressurect it */
67 uv
= luaM_new(L
, UpVal
); /* not found: create a new one */
69 uv
->marked
= luaC_white(g
);
70 uv
->v
= level
; /* current value lives in the stack */
71 uv
->next
= *pp
; /* chain it in the proper position */
73 uv
->u
.l
.prev
= &g
->uvhead
; /* double link it in `uvhead' list */
74 uv
->u
.l
.next
= g
->uvhead
.u
.l
.next
;
75 uv
->u
.l
.next
->u
.l
.prev
= uv
;
76 g
->uvhead
.u
.l
.next
= uv
;
77 lua_assert(uv
->u
.l
.next
->u
.l
.prev
== uv
&& uv
->u
.l
.prev
->u
.l
.next
== uv
);
82 static void unlinkupval (UpVal
*uv
) {
83 lua_assert(uv
->u
.l
.next
->u
.l
.prev
== uv
&& uv
->u
.l
.prev
->u
.l
.next
== uv
);
84 uv
->u
.l
.next
->u
.l
.prev
= uv
->u
.l
.prev
; /* remove from `uvhead' list */
85 uv
->u
.l
.prev
->u
.l
.next
= uv
->u
.l
.next
;
89 void luaF_freeupval (lua_State
*L
, UpVal
*uv
) {
90 if (uv
->v
!= &uv
->u
.value
) /* is it open? */
91 unlinkupval(uv
); /* remove from open list */
92 luaM_free(L
, uv
); /* free upvalue */
96 void luaF_close (lua_State
*L
, StkId level
) {
98 global_State
*g
= G(L
);
99 while (L
->openupval
!= NULL
&& (uv
= ngcotouv(L
->openupval
))->v
>= level
) {
100 GCObject
*o
= obj2gco(uv
);
101 lua_assert(!isblack(o
) && uv
->v
!= &uv
->u
.value
);
102 L
->openupval
= uv
->next
; /* remove from `open' list */
104 luaF_freeupval(L
, uv
); /* free upvalue */
107 setobj(L
, &uv
->u
.value
, uv
->v
);
108 uv
->v
= &uv
->u
.value
; /* now current value lives here */
109 luaC_linkupval(L
, uv
); /* link upvalue into `gcroot' list */
115 Proto
*luaF_newproto (lua_State
*L
) {
116 Proto
*f
= luaM_new(L
, Proto
);
117 luaC_link(L
, obj2gco(f
), LUA_TPROTO
);
135 f
->lastlinedefined
= 0;
141 void luaF_freeproto (lua_State
*L
, Proto
*f
) {
142 luaM_freearray(L
, f
->code
, f
->sizecode
, Instruction
);
143 luaM_freearray(L
, f
->p
, f
->sizep
, Proto
*);
144 luaM_freearray(L
, f
->k
, f
->sizek
, TValue
);
145 luaM_freearray(L
, f
->lineinfo
, f
->sizelineinfo
, int);
146 luaM_freearray(L
, f
->locvars
, f
->sizelocvars
, struct LocVar
);
147 luaM_freearray(L
, f
->upvalues
, f
->sizeupvalues
, TString
*);
152 void luaF_freeclosure (lua_State
*L
, Closure
*c
) {
153 int size
= (c
->c
.isC
) ? sizeCclosure(c
->c
.nupvalues
) :
154 sizeLclosure(c
->l
.nupvalues
);
155 luaM_freemem(L
, c
, size
);
160 ** Look for n-th local variable at line `line' in function `func'.
161 ** Returns NULL if not found.
163 const char *luaF_getlocalname (const Proto
*f
, int local_number
, int pc
) {
165 for (i
= 0; i
<f
->sizelocvars
&& f
->locvars
[i
].startpc
<= pc
; i
++) {
166 if (pc
< f
->locvars
[i
].endpc
) { /* is variable active? */
168 if (local_number
== 0)
169 return getstr(f
->locvars
[i
].varname
);
172 return NULL
; /* not found */