1 /* $NetBSD: lfunc.c,v 1.3 2015/02/02 14:03:05 lneto Exp $ */
4 ** Id: lfunc.c,v 2.45 2014/11/02 19:19:04 roberto Exp
5 ** Auxiliary functions to manipulate prototypes and closures
6 ** See Copyright Notice in lua.h
29 CClosure
*luaF_newCclosure (lua_State
*L
, int n
) {
30 GCObject
*o
= luaC_newobj(L
, LUA_TCCL
, sizeCclosure(n
));
31 CClosure
*c
= gco2ccl(o
);
32 c
->nupvalues
= cast_byte(n
);
37 LClosure
*luaF_newLclosure (lua_State
*L
, int n
) {
38 GCObject
*o
= luaC_newobj(L
, LUA_TLCL
, sizeLclosure(n
));
39 LClosure
*c
= gco2lcl(o
);
41 c
->nupvalues
= cast_byte(n
);
42 while (n
--) c
->upvals
[n
] = NULL
;
47 ** fill a closure with new closed upvalues
49 void luaF_initupvals (lua_State
*L
, LClosure
*cl
) {
51 for (i
= 0; i
< cl
->nupvalues
; i
++) {
52 UpVal
*uv
= luaM_new(L
, UpVal
);
54 uv
->v
= &uv
->u
.value
; /* make it closed */
61 UpVal
*luaF_findupval (lua_State
*L
, StkId level
) {
62 UpVal
**pp
= &L
->openupval
;
65 lua_assert(isintwups(L
) || L
->openupval
== NULL
);
66 while (*pp
!= NULL
&& (p
= *pp
)->v
>= level
) {
67 lua_assert(upisopen(p
));
68 if (p
->v
== level
) /* found a corresponding upvalue? */
69 return p
; /* return it */
72 /* not found: create a new upvalue */
73 uv
= luaM_new(L
, UpVal
);
75 uv
->u
.open
.next
= *pp
; /* link it to list of open upvalues */
76 uv
->u
.open
.touched
= 1;
78 uv
->v
= level
; /* current value lives in the stack */
79 if (!isintwups(L
)) { /* thread not in list of threads with upvalues? */
80 L
->twups
= G(L
)->twups
; /* link it to the list */
87 void luaF_close (lua_State
*L
, StkId level
) {
89 while (L
->openupval
!= NULL
&& (uv
= L
->openupval
)->v
>= level
) {
90 lua_assert(upisopen(uv
));
91 L
->openupval
= uv
->u
.open
.next
; /* remove from 'open' list */
92 if (uv
->refcount
== 0) /* no references? */
93 luaM_free(L
, uv
); /* free upvalue */
95 setobj(L
, &uv
->u
.value
, uv
->v
); /* move value to upvalue slot */
96 uv
->v
= &uv
->u
.value
; /* now current value lives here */
97 luaC_upvalbarrier(L
, uv
);
103 Proto
*luaF_newproto (lua_State
*L
) {
104 GCObject
*o
= luaC_newobj(L
, LUA_TPROTO
, sizeof(Proto
));
123 f
->lastlinedefined
= 0;
129 void luaF_freeproto (lua_State
*L
, Proto
*f
) {
130 luaM_freearray(L
, f
->code
, f
->sizecode
);
131 luaM_freearray(L
, f
->p
, f
->sizep
);
132 luaM_freearray(L
, f
->k
, f
->sizek
);
133 luaM_freearray(L
, f
->lineinfo
, f
->sizelineinfo
);
134 luaM_freearray(L
, f
->locvars
, f
->sizelocvars
);
135 luaM_freearray(L
, f
->upvalues
, f
->sizeupvalues
);
141 ** Look for n-th local variable at line 'line' in function 'func'.
142 ** Returns NULL if not found.
144 const char *luaF_getlocalname (const Proto
*f
, int local_number
, int pc
) {
146 for (i
= 0; i
<f
->sizelocvars
&& f
->locvars
[i
].startpc
<= pc
; i
++) {
147 if (pc
< f
->locvars
[i
].endpc
) { /* is variable active? */
149 if (local_number
== 0)
150 return getstr(f
->locvars
[i
].varname
);
153 return NULL
; /* not found */