2 ** $Id: lfunc.c,v 2.30.1.1 2013/04/12 18:48:47 roberto Exp $
3 ** Auxiliary functions to manipulate prototypes and closures
4 ** See Copyright Notice in lua.h
11 #include <sys/lua/lua.h>
21 Closure
*luaF_newCclosure (lua_State
*L
, int n
) {
22 Closure
*c
= &luaC_newobj(L
, LUA_TCCL
, sizeCclosure(n
), NULL
, 0)->cl
;
23 c
->c
.nupvalues
= cast_byte(n
);
28 Closure
*luaF_newLclosure (lua_State
*L
, int n
) {
29 Closure
*c
= &luaC_newobj(L
, LUA_TLCL
, sizeLclosure(n
), NULL
, 0)->cl
;
31 c
->l
.nupvalues
= cast_byte(n
);
32 while (n
--) c
->l
.upvals
[n
] = NULL
;
37 UpVal
*luaF_newupval (lua_State
*L
) {
38 UpVal
*uv
= &luaC_newobj(L
, LUA_TUPVAL
, sizeof(UpVal
), NULL
, 0)->uv
;
45 UpVal
*luaF_findupval (lua_State
*L
, StkId level
) {
46 global_State
*g
= G(L
);
47 GCObject
**pp
= &L
->openupval
;
50 while (*pp
!= NULL
&& (p
= gco2uv(*pp
))->v
>= level
) {
51 GCObject
*o
= obj2gco(p
);
52 lua_assert(p
->v
!= &p
->u
.value
);
53 lua_assert(!isold(o
) || isold(obj2gco(L
)));
54 if (p
->v
== level
) { /* found a corresponding upvalue? */
55 if (isdead(g
, o
)) /* is it dead? */
56 changewhite(o
); /* resurrect it */
61 /* not found: create a new one */
62 uv
= &luaC_newobj(L
, LUA_TUPVAL
, sizeof(UpVal
), pp
, 0)->uv
;
63 uv
->v
= level
; /* current value lives in the stack */
64 uv
->u
.l
.prev
= &g
->uvhead
; /* double link it in `uvhead' list */
65 uv
->u
.l
.next
= g
->uvhead
.u
.l
.next
;
66 uv
->u
.l
.next
->u
.l
.prev
= uv
;
67 g
->uvhead
.u
.l
.next
= uv
;
68 lua_assert(uv
->u
.l
.next
->u
.l
.prev
== uv
&& uv
->u
.l
.prev
->u
.l
.next
== uv
);
73 static void unlinkupval (UpVal
*uv
) {
74 lua_assert(uv
->u
.l
.next
->u
.l
.prev
== uv
&& uv
->u
.l
.prev
->u
.l
.next
== uv
);
75 uv
->u
.l
.next
->u
.l
.prev
= uv
->u
.l
.prev
; /* remove from `uvhead' list */
76 uv
->u
.l
.prev
->u
.l
.next
= uv
->u
.l
.next
;
80 void luaF_freeupval (lua_State
*L
, UpVal
*uv
) {
81 if (uv
->v
!= &uv
->u
.value
) /* is it open? */
82 unlinkupval(uv
); /* remove from open list */
83 luaM_free(L
, uv
); /* free upvalue */
87 void luaF_close (lua_State
*L
, StkId level
) {
89 global_State
*g
= G(L
);
90 while (L
->openupval
!= NULL
&& (uv
= gco2uv(L
->openupval
))->v
>= level
) {
91 GCObject
*o
= obj2gco(uv
);
92 lua_assert(!isblack(o
) && uv
->v
!= &uv
->u
.value
);
93 L
->openupval
= uv
->next
; /* remove from `open' list */
95 luaF_freeupval(L
, uv
); /* free upvalue */
97 unlinkupval(uv
); /* remove upvalue from 'uvhead' list */
98 setobj(L
, &uv
->u
.value
, uv
->v
); /* move value to upvalue slot */
99 uv
->v
= &uv
->u
.value
; /* now current value lives here */
100 gch(o
)->next
= g
->allgc
; /* link upvalue into 'allgc' list */
102 luaC_checkupvalcolor(g
, uv
);
108 Proto
*luaF_newproto (lua_State
*L
) {
109 Proto
*f
= &luaC_newobj(L
, LUA_TPROTO
, sizeof(Proto
), NULL
, 0)->p
;
127 f
->lastlinedefined
= 0;
133 void luaF_freeproto (lua_State
*L
, Proto
*f
) {
134 luaM_freearray(L
, f
->code
, f
->sizecode
);
135 luaM_freearray(L
, f
->p
, f
->sizep
);
136 luaM_freearray(L
, f
->k
, f
->sizek
);
137 luaM_freearray(L
, f
->lineinfo
, f
->sizelineinfo
);
138 luaM_freearray(L
, f
->locvars
, f
->sizelocvars
);
139 luaM_freearray(L
, f
->upvalues
, f
->sizeupvalues
);
145 ** Look for n-th local variable at line `line' in function `func'.
146 ** Returns NULL if not found.
148 const char *luaF_getlocalname (const Proto
*f
, int local_number
, int pc
) {
150 for (i
= 0; i
<f
->sizelocvars
&& f
->locvars
[i
].startpc
<= pc
; i
++) {
151 if (pc
< f
->locvars
[i
].endpc
) { /* is variable active? */
153 if (local_number
== 0)
154 return getstr(f
->locvars
[i
].varname
);
157 return NULL
; /* not found */