1 /* $NetBSD: lfunc.c,v 1.1.1.2 2012/03/15 00:08:10 alnsn Exp $ */
4 ** $Id: lfunc.c,v 1.1.1.2 2012/03/15 00:08:10 alnsn Exp $
5 ** Auxiliary functions to manipulate prototypes and closures
6 ** See Copyright Notice in lua.h
25 Closure
*luaF_newCclosure (lua_State
*L
, int nelems
, Table
*e
) {
26 Closure
*c
= cast(Closure
*, luaM_malloc(L
, sizeCclosure(nelems
)));
27 luaC_link(L
, obj2gco(c
), LUA_TFUNCTION
);
30 c
->c
.nupvalues
= cast_byte(nelems
);
35 Closure
*luaF_newLclosure (lua_State
*L
, int nelems
, Table
*e
) {
36 Closure
*c
= cast(Closure
*, luaM_malloc(L
, sizeLclosure(nelems
)));
37 luaC_link(L
, obj2gco(c
), LUA_TFUNCTION
);
40 c
->l
.nupvalues
= cast_byte(nelems
);
41 while (nelems
--) c
->l
.upvals
[nelems
] = NULL
;
46 UpVal
*luaF_newupval (lua_State
*L
) {
47 UpVal
*uv
= luaM_new(L
, UpVal
);
48 luaC_link(L
, obj2gco(uv
), LUA_TUPVAL
);
55 UpVal
*luaF_findupval (lua_State
*L
, StkId level
) {
56 global_State
*g
= G(L
);
57 GCObject
**pp
= &L
->openupval
;
60 while (*pp
!= NULL
&& (p
= ngcotouv(*pp
))->v
>= level
) {
61 lua_assert(p
->v
!= &p
->u
.value
);
62 if (p
->v
== level
) { /* found a corresponding upvalue? */
63 if (isdead(g
, obj2gco(p
))) /* is it dead? */
64 changewhite(obj2gco(p
)); /* ressurect it */
69 uv
= luaM_new(L
, UpVal
); /* not found: create a new one */
71 uv
->marked
= luaC_white(g
);
72 uv
->v
= level
; /* current value lives in the stack */
73 uv
->next
= *pp
; /* chain it in the proper position */
75 uv
->u
.l
.prev
= &g
->uvhead
; /* double link it in `uvhead' list */
76 uv
->u
.l
.next
= g
->uvhead
.u
.l
.next
;
77 uv
->u
.l
.next
->u
.l
.prev
= uv
;
78 g
->uvhead
.u
.l
.next
= uv
;
79 lua_assert(uv
->u
.l
.next
->u
.l
.prev
== uv
&& uv
->u
.l
.prev
->u
.l
.next
== uv
);
84 static void unlinkupval (UpVal
*uv
) {
85 lua_assert(uv
->u
.l
.next
->u
.l
.prev
== uv
&& uv
->u
.l
.prev
->u
.l
.next
== uv
);
86 uv
->u
.l
.next
->u
.l
.prev
= uv
->u
.l
.prev
; /* remove from `uvhead' list */
87 uv
->u
.l
.prev
->u
.l
.next
= uv
->u
.l
.next
;
91 void luaF_freeupval (lua_State
*L
, UpVal
*uv
) {
92 if (uv
->v
!= &uv
->u
.value
) /* is it open? */
93 unlinkupval(uv
); /* remove from open list */
94 luaM_free(L
, uv
); /* free upvalue */
98 void luaF_close (lua_State
*L
, StkId level
) {
100 global_State
*g
= G(L
);
101 while (L
->openupval
!= NULL
&& (uv
= ngcotouv(L
->openupval
))->v
>= level
) {
102 GCObject
*o
= obj2gco(uv
);
103 lua_assert(!isblack(o
) && uv
->v
!= &uv
->u
.value
);
104 L
->openupval
= uv
->next
; /* remove from `open' list */
106 luaF_freeupval(L
, uv
); /* free upvalue */
109 setobj(L
, &uv
->u
.value
, uv
->v
);
110 uv
->v
= &uv
->u
.value
; /* now current value lives here */
111 luaC_linkupval(L
, uv
); /* link upvalue into `gcroot' list */
117 Proto
*luaF_newproto (lua_State
*L
) {
118 Proto
*f
= luaM_new(L
, Proto
);
119 luaC_link(L
, obj2gco(f
), LUA_TPROTO
);
137 f
->lastlinedefined
= 0;
143 void luaF_freeproto (lua_State
*L
, Proto
*f
) {
144 luaM_freearray(L
, f
->code
, f
->sizecode
, Instruction
);
145 luaM_freearray(L
, f
->p
, f
->sizep
, Proto
*);
146 luaM_freearray(L
, f
->k
, f
->sizek
, TValue
);
147 luaM_freearray(L
, f
->lineinfo
, f
->sizelineinfo
, int);
148 luaM_freearray(L
, f
->locvars
, f
->sizelocvars
, struct LocVar
);
149 luaM_freearray(L
, f
->upvalues
, f
->sizeupvalues
, TString
*);
154 void luaF_freeclosure (lua_State
*L
, Closure
*c
) {
155 int size
= (c
->c
.isC
) ? sizeCclosure(c
->c
.nupvalues
) :
156 sizeLclosure(c
->l
.nupvalues
);
157 luaM_freemem(L
, c
, size
);
162 ** Look for n-th local variable at line `line' in function `func'.
163 ** Returns NULL if not found.
165 const char *luaF_getlocalname (const Proto
*f
, int local_number
, int pc
) {
167 for (i
= 0; i
<f
->sizelocvars
&& f
->locvars
[i
].startpc
<= pc
; i
++) {
168 if (pc
< f
->locvars
[i
].endpc
) { /* is variable active? */
170 if (local_number
== 0)
171 return getstr(f
->locvars
[i
].varname
);
174 return NULL
; /* not found */