2 ** $Id: lfunc.c,v 2.30 2012/10/03 12:36:46 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 n
) {
24 Closure
*c
= &luaC_newobj(L
, LUA_TCCL
, sizeCclosure(n
), NULL
, 0)->cl
;
25 c
->c
.nupvalues
= cast_byte(n
);
30 Closure
*luaF_newLclosure (lua_State
*L
, int n
) {
31 Closure
*c
= &luaC_newobj(L
, LUA_TLCL
, sizeLclosure(n
), NULL
, 0)->cl
;
33 c
->l
.nupvalues
= cast_byte(n
);
34 while (n
--) c
->l
.upvals
[n
] = NULL
;
39 UpVal
*luaF_newupval (lua_State
*L
) {
40 UpVal
*uv
= &luaC_newobj(L
, LUA_TUPVAL
, sizeof(UpVal
), NULL
, 0)->uv
;
47 UpVal
*luaF_findupval (lua_State
*L
, StkId level
) {
48 global_State
*g
= G(L
);
49 GCObject
**pp
= &L
->openupval
;
52 while (*pp
!= NULL
&& (p
= gco2uv(*pp
))->v
>= level
) {
53 GCObject
*o
= obj2gco(p
);
54 lua_assert(p
->v
!= &p
->u
.value
);
55 lua_assert(!isold(o
) || isold(obj2gco(L
)));
56 if (p
->v
== level
) { /* found a corresponding upvalue? */
57 if (isdead(g
, o
)) /* is it dead? */
58 changewhite(o
); /* resurrect it */
63 /* not found: create a new one */
64 uv
= &luaC_newobj(L
, LUA_TUPVAL
, sizeof(UpVal
), pp
, 0)->uv
;
65 uv
->v
= level
; /* current value lives in the stack */
66 uv
->u
.l
.prev
= &g
->uvhead
; /* double link it in `uvhead' list */
67 uv
->u
.l
.next
= g
->uvhead
.u
.l
.next
;
68 uv
->u
.l
.next
->u
.l
.prev
= uv
;
69 g
->uvhead
.u
.l
.next
= uv
;
70 lua_assert(uv
->u
.l
.next
->u
.l
.prev
== uv
&& uv
->u
.l
.prev
->u
.l
.next
== uv
);
75 static void unlinkupval (UpVal
*uv
) {
76 lua_assert(uv
->u
.l
.next
->u
.l
.prev
== uv
&& uv
->u
.l
.prev
->u
.l
.next
== uv
);
77 uv
->u
.l
.next
->u
.l
.prev
= uv
->u
.l
.prev
; /* remove from `uvhead' list */
78 uv
->u
.l
.prev
->u
.l
.next
= uv
->u
.l
.next
;
82 void luaF_freeupval (lua_State
*L
, UpVal
*uv
) {
83 if (uv
->v
!= &uv
->u
.value
) /* is it open? */
84 unlinkupval(uv
); /* remove from open list */
85 luaM_free(L
, uv
); /* free upvalue */
89 void luaF_close (lua_State
*L
, StkId level
) {
91 global_State
*g
= G(L
);
92 while (L
->openupval
!= NULL
&& (uv
= gco2uv(L
->openupval
))->v
>= level
) {
93 GCObject
*o
= obj2gco(uv
);
94 lua_assert(!isblack(o
) && uv
->v
!= &uv
->u
.value
);
95 L
->openupval
= uv
->next
; /* remove from `open' list */
97 luaF_freeupval(L
, uv
); /* free upvalue */
99 unlinkupval(uv
); /* remove upvalue from 'uvhead' list */
100 setobj(L
, &uv
->u
.value
, uv
->v
); /* move value to upvalue slot */
101 uv
->v
= &uv
->u
.value
; /* now current value lives here */
102 gch(o
)->next
= g
->allgc
; /* link upvalue into 'allgc' list */
104 luaC_checkupvalcolor(g
, uv
);
110 Proto
*luaF_newproto (lua_State
*L
) {
111 Proto
*f
= &luaC_newobj(L
, LUA_TPROTO
, sizeof(Proto
), NULL
, 0)->p
;
129 f
->lastlinedefined
= 0;
135 void luaF_freeproto (lua_State
*L
, Proto
*f
) {
136 luaM_freearray(L
, f
->code
, f
->sizecode
);
137 luaM_freearray(L
, f
->p
, f
->sizep
);
138 luaM_freearray(L
, f
->k
, f
->sizek
);
139 luaM_freearray(L
, f
->lineinfo
, f
->sizelineinfo
);
140 luaM_freearray(L
, f
->locvars
, f
->sizelocvars
);
141 luaM_freearray(L
, f
->upvalues
, f
->sizeupvalues
);
147 ** Look for n-th local variable at line `line' in function `func'.
148 ** Returns NULL if not found.
150 const char *luaF_getlocalname (const Proto
*f
, int local_number
, int pc
) {
152 for (i
= 0; i
<f
->sizelocvars
&& f
->locvars
[i
].startpc
<= pc
; i
++) {
153 if (pc
< f
->locvars
[i
].endpc
) { /* is variable active? */
155 if (local_number
== 0)
156 return getstr(f
->locvars
[i
].varname
);
159 return NULL
; /* not found */