2 ** Function handling (prototypes, functions and upvalues).
3 ** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h
5 ** Portions taken verbatim or adapted from the Lua interpreter.
6 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
18 /* -- Prototypes ---------------------------------------------------------- */
20 void LJ_FASTCALL
lj_func_freeproto(global_State
*g
, GCproto
*pt
)
22 lj_mem_free(g
, pt
, pt
->sizept
);
25 /* -- Upvalues ------------------------------------------------------------ */
27 static void unlinkuv(GCupval
*uv
)
29 lua_assert(uvprev(uvnext(uv
)) == uv
&& uvnext(uvprev(uv
)) == uv
);
30 setgcrefr(uvnext(uv
)->prev
, uv
->prev
);
31 setgcrefr(uvprev(uv
)->next
, uv
->next
);
34 /* Find existing open upvalue for a stack slot or create a new one. */
35 static GCupval
*func_finduv(lua_State
*L
, TValue
*slot
)
37 global_State
*g
= G(L
);
38 GCRef
*pp
= &L
->openupval
;
41 /* Search the sorted list of open upvalues. */
42 while (gcref(*pp
) != NULL
&& uvval((p
= gco2uv(gcref(*pp
)))) >= slot
) {
43 lua_assert(!p
->closed
&& uvval(p
) != &p
->tv
);
44 if (uvval(p
) == slot
) { /* Found open upvalue pointing to same slot? */
45 if (isdead(g
, obj2gco(p
))) /* Resurrect it, if it's dead. */
46 flipwhite(obj2gco(p
));
51 /* No matching upvalue found. Create a new one. */
52 uv
= lj_mem_newt(L
, sizeof(GCupval
), GCupval
);
55 uv
->closed
= 0; /* Still open. */
56 setmref(uv
->v
, slot
); /* Pointing to the stack slot. */
57 /* NOBARRIER: The GCupval is new (marked white) and open. */
58 setgcrefr(uv
->nextgc
, *pp
); /* Insert into sorted list of open upvalues. */
59 setgcref(*pp
, obj2gco(uv
));
60 setgcref(uv
->prev
, obj2gco(&g
->uvhead
)); /* Insert into GC list, too. */
61 setgcrefr(uv
->next
, g
->uvhead
.next
);
62 setgcref(uvnext(uv
)->prev
, obj2gco(uv
));
63 setgcref(g
->uvhead
.next
, obj2gco(uv
));
64 lua_assert(uvprev(uvnext(uv
)) == uv
&& uvnext(uvprev(uv
)) == uv
);
68 /* Create an empty and closed upvalue. */
69 static GCupval
*func_emptyuv(lua_State
*L
)
71 GCupval
*uv
= (GCupval
*)lj_mem_newgco(L
, sizeof(GCupval
));
75 setmref(uv
->v
, &uv
->tv
);
79 /* Close all open upvalues pointing to some stack level or above. */
80 void LJ_FASTCALL
lj_func_closeuv(lua_State
*L
, TValue
*level
)
83 global_State
*g
= G(L
);
84 while (gcref(L
->openupval
) != NULL
&&
85 uvval((uv
= gco2uv(gcref(L
->openupval
)))) >= level
) {
86 GCobj
*o
= obj2gco(uv
);
87 lua_assert(!isblack(o
) && !uv
->closed
&& uvval(uv
) != &uv
->tv
);
88 setgcrefr(L
->openupval
, uv
->nextgc
); /* No longer in open list. */
90 lj_func_freeuv(g
, uv
);
98 void LJ_FASTCALL
lj_func_freeuv(global_State
*g
, GCupval
*uv
)
105 /* -- Functions (closures) ------------------------------------------------ */
107 GCfunc
*lj_func_newC(lua_State
*L
, MSize nelems
, GCtab
*env
)
109 GCfunc
*fn
= (GCfunc
*)lj_mem_newgco(L
, sizeCfunc(nelems
));
110 fn
->c
.gct
= ~LJ_TFUNC
;
112 fn
->c
.nupvalues
= (uint8_t)nelems
;
113 /* NOBARRIER: The GCfunc is new (marked white). */
114 setmref(fn
->c
.pc
, &G(L
)->bc_cfunc_ext
);
115 setgcref(fn
->c
.env
, obj2gco(env
));
119 static GCfunc
*func_newL(lua_State
*L
, GCproto
*pt
, GCtab
*env
)
122 GCfunc
*fn
= (GCfunc
*)lj_mem_newgco(L
, sizeLfunc((MSize
)pt
->sizeuv
));
123 fn
->l
.gct
= ~LJ_TFUNC
;
125 fn
->l
.nupvalues
= 0; /* Set to zero until upvalues are initialized. */
126 /* NOBARRIER: Really a setgcref. But the GCfunc is new (marked white). */
127 setmref(fn
->l
.pc
, proto_bc(pt
));
128 setgcref(fn
->l
.env
, obj2gco(env
));
129 /* Saturating 3 bit counter (0..7) for created closures. */
130 count
= (uint32_t)pt
->flags
+ PROTO_CLCOUNT
;
131 pt
->flags
= (uint8_t)(count
- ((count
>> PROTO_CLC_BITS
) & PROTO_CLCOUNT
));
135 /* Create a new Lua function with empty upvalues. */
136 GCfunc
*lj_func_newL_empty(lua_State
*L
, GCproto
*pt
, GCtab
*env
)
138 GCfunc
*fn
= func_newL(L
, pt
, env
);
139 MSize i
, nuv
= pt
->sizeuv
;
140 /* NOBARRIER: The GCfunc is new (marked white). */
141 for (i
= 0; i
< nuv
; i
++) {
142 GCupval
*uv
= func_emptyuv(L
);
143 uv
->dhash
= (uint32_t)(uintptr_t)pt
^ ((uint32_t)proto_uv(pt
)[i
] << 24);
144 setgcref(fn
->l
.uvptr
[i
], obj2gco(uv
));
146 fn
->l
.nupvalues
= (uint8_t)nuv
;
150 /* Do a GC check and create a new Lua function with inherited upvalues. */
151 GCfunc
*lj_func_newL_gc(lua_State
*L
, GCproto
*pt
, GCfuncL
*parent
)
157 lj_gc_check_fixtop(L
);
158 fn
= func_newL(L
, pt
, tabref(parent
->env
));
159 /* NOBARRIER: The GCfunc is new (marked white). */
163 for (i
= 0; i
< nuv
; i
++) {
164 uint32_t v
= proto_uv(pt
)[i
];
166 if ((v
& PROTO_UV_LOCAL
)) {
167 uv
= func_finduv(L
, base
+ (v
& 0xff));
168 uv
->immutable
= ((v
/ PROTO_UV_IMMUTABLE
) & 1);
169 uv
->dhash
= (uint32_t)(uintptr_t)mref(parent
->pc
, char) ^ (v
<< 24);
171 uv
= &gcref(puv
[v
])->uv
;
173 setgcref(fn
->l
.uvptr
[i
], obj2gco(uv
));
175 fn
->l
.nupvalues
= (uint8_t)nuv
;
179 void LJ_FASTCALL
lj_func_free(global_State
*g
, GCfunc
*fn
)
181 MSize size
= isluafunc(fn
) ? sizeLfunc((MSize
)fn
->l
.nupvalues
) :
182 sizeCfunc((MSize
)fn
->c
.nupvalues
);
183 lj_mem_free(g
, fn
, size
);