]>
git.zerfleddert.de Git - proxmark3-svn/blob - liblua/lapi.c
2 ** $Id: lapi.c,v 2.171 2013/03/16 21:10:18 roberto Exp $
4 ** See Copyright Notice in lua.h
32 const char lua_ident
[] =
33 "$LuaVersion: " LUA_COPYRIGHT
" $"
34 "$LuaAuthors: " LUA_AUTHORS
" $";
37 /* value at a non-valid index */
38 #define NONVALIDVALUE cast(TValue *, luaO_nilobject)
40 /* corresponding test */
41 #define isvalid(o) ((o) != luaO_nilobject)
43 /* test for pseudo index */
44 #define ispseudo(i) ((i) <= LUA_REGISTRYINDEX)
46 /* test for valid but not pseudo index */
47 #define isstackindex(i, o) (isvalid(o) && !ispseudo(i))
49 #define api_checkvalidindex(L, o) api_check(L, isvalid(o), "invalid index")
51 #define api_checkstackindex(L, i, o) \
52 api_check(L, isstackindex(i, o), "index not in the stack")
55 static TValue
*index2addr (lua_State
*L
, int idx
) {
58 TValue
*o
= ci
->func
+ idx
;
59 api_check(L
, idx
<= ci
->top
- (ci
->func
+ 1), "unacceptable index");
60 if (o
>= L
->top
) return NONVALIDVALUE
;
63 else if (!ispseudo(idx
)) { /* negative index */
64 api_check(L
, idx
!= 0 && -idx
<= L
->top
- (ci
->func
+ 1), "invalid index");
67 else if (idx
== LUA_REGISTRYINDEX
)
68 return &G(L
)->l_registry
;
70 idx
= LUA_REGISTRYINDEX
- idx
;
71 api_check(L
, idx
<= MAXUPVAL
+ 1, "upvalue index too large");
72 if (ttislcf(ci
->func
)) /* light C function? */
73 return NONVALIDVALUE
; /* it has no upvalues */
75 CClosure
*func
= clCvalue(ci
->func
);
76 return (idx
<= func
->nupvalues
) ? &func
->upvalue
[idx
-1] : NONVALIDVALUE
;
83 ** to be called by 'lua_checkstack' in protected mode, to grow stack
84 ** capturing memory errors
86 static void growstack (lua_State
*L
, void *ud
) {
87 int size
= *(int *)ud
;
88 luaD_growstack(L
, size
);
92 LUA_API
int lua_checkstack (lua_State
*L
, int size
) {
96 if (L
->stack_last
- L
->top
> size
) /* stack large enough? */
97 res
= 1; /* yes; check is OK */
98 else { /* no; need to grow stack */
99 int inuse
= cast_int(L
->top
- L
->stack
) + EXTRA_STACK
;
100 if (inuse
> LUAI_MAXSTACK
- size
) /* can grow without overflow? */
102 else /* try to grow stack */
103 res
= (luaD_rawrunprotected(L
, &growstack
, &size
) == LUA_OK
);
105 if (res
&& ci
->top
< L
->top
+ size
)
106 ci
->top
= L
->top
+ size
; /* adjust frame top */
112 LUA_API
void lua_xmove (lua_State
*from
, lua_State
*to
, int n
) {
114 if (from
== to
) return;
116 api_checknelems(from
, n
);
117 api_check(from
, G(from
) == G(to
), "moving among independent states");
118 api_check(from
, to
->ci
->top
- to
->top
>= n
, "not enough elements to move");
120 for (i
= 0; i
< n
; i
++) {
121 setobj2s(to
, to
->top
++, from
->top
+ i
);
127 LUA_API lua_CFunction
lua_atpanic (lua_State
*L
, lua_CFunction panicf
) {
131 G(L
)->panic
= panicf
;
137 LUA_API
const lua_Number
*lua_version (lua_State
*L
) {
138 static const lua_Number version
= LUA_VERSION_NUM
;
139 if (L
== NULL
) return &version
;
140 else return G(L
)->version
;
146 ** basic stack manipulation
151 ** convert an acceptable stack index into an absolute index
153 LUA_API
int lua_absindex (lua_State
*L
, int idx
) {
154 return (idx
> 0 || ispseudo(idx
))
156 : cast_int(L
->top
- L
->ci
->func
+ idx
);
160 LUA_API
int lua_gettop (lua_State
*L
) {
161 return cast_int(L
->top
- (L
->ci
->func
+ 1));
165 LUA_API
void lua_settop (lua_State
*L
, int idx
) {
166 StkId func
= L
->ci
->func
;
169 api_check(L
, idx
<= L
->stack_last
- (func
+ 1), "new top too large");
170 while (L
->top
< (func
+ 1) + idx
)
171 setnilvalue(L
->top
++);
172 L
->top
= (func
+ 1) + idx
;
175 api_check(L
, -(idx
+1) <= (L
->top
- (func
+ 1)), "invalid new top");
176 L
->top
+= idx
+1; /* `subtract' index (index is negative) */
182 LUA_API
void lua_remove (lua_State
*L
, int idx
) {
185 p
= index2addr(L
, idx
);
186 api_checkstackindex(L
, idx
, p
);
187 while (++p
< L
->top
) setobjs2s(L
, p
-1, p
);
193 LUA_API
void lua_insert (lua_State
*L
, int idx
) {
197 p
= index2addr(L
, idx
);
198 api_checkstackindex(L
, idx
, p
);
199 for (q
= L
->top
; q
> p
; q
--) /* use L->top as a temporary */
200 setobjs2s(L
, q
, q
- 1);
201 setobjs2s(L
, p
, L
->top
);
206 static void moveto (lua_State
*L
, TValue
*fr
, int idx
) {
207 TValue
*to
= index2addr(L
, idx
);
208 api_checkvalidindex(L
, to
);
210 if (idx
< LUA_REGISTRYINDEX
) /* function upvalue? */
211 luaC_barrier(L
, clCvalue(L
->ci
->func
), fr
);
212 /* LUA_REGISTRYINDEX does not need gc barrier
213 (collector revisits it before finishing collection) */
217 LUA_API
void lua_replace (lua_State
*L
, int idx
) {
219 api_checknelems(L
, 1);
220 moveto(L
, L
->top
- 1, idx
);
226 LUA_API
void lua_copy (lua_State
*L
, int fromidx
, int toidx
) {
229 fr
= index2addr(L
, fromidx
);
230 moveto(L
, fr
, toidx
);
235 LUA_API
void lua_pushvalue (lua_State
*L
, int idx
) {
237 setobj2s(L
, L
->top
, index2addr(L
, idx
));
245 ** access functions (stack -> C)
249 LUA_API
int lua_type (lua_State
*L
, int idx
) {
250 StkId o
= index2addr(L
, idx
);
251 return (isvalid(o
) ? ttypenv(o
) : LUA_TNONE
);
255 LUA_API
const char *lua_typename (lua_State
*L
, int t
) {
261 LUA_API
int lua_iscfunction (lua_State
*L
, int idx
) {
262 StkId o
= index2addr(L
, idx
);
263 return (ttislcf(o
) || (ttisCclosure(o
)));
267 LUA_API
int lua_isnumber (lua_State
*L
, int idx
) {
269 const TValue
*o
= index2addr(L
, idx
);
270 return tonumber(o
, &n
);
274 LUA_API
int lua_isstring (lua_State
*L
, int idx
) {
275 int t
= lua_type(L
, idx
);
276 return (t
== LUA_TSTRING
|| t
== LUA_TNUMBER
);
280 LUA_API
int lua_isuserdata (lua_State
*L
, int idx
) {
281 const TValue
*o
= index2addr(L
, idx
);
282 return (ttisuserdata(o
) || ttislightuserdata(o
));
286 LUA_API
int lua_rawequal (lua_State
*L
, int index1
, int index2
) {
287 StkId o1
= index2addr(L
, index1
);
288 StkId o2
= index2addr(L
, index2
);
289 return (isvalid(o1
) && isvalid(o2
)) ? luaV_rawequalobj(o1
, o2
) : 0;
293 LUA_API
void lua_arith (lua_State
*L
, int op
) {
294 StkId o1
; /* 1st operand */
295 StkId o2
; /* 2nd operand */
297 if (op
!= LUA_OPUNM
) /* all other operations expect two operands */
298 api_checknelems(L
, 2);
299 else { /* for unary minus, add fake 2nd operand */
300 api_checknelems(L
, 1);
301 setobjs2s(L
, L
->top
, L
->top
- 1);
306 if (ttisnumber(o1
) && ttisnumber(o2
)) {
307 setnvalue(o1
, luaO_arith(op
, nvalue(o1
), nvalue(o2
)));
310 luaV_arith(L
, o1
, o1
, o2
, cast(TMS
, op
- LUA_OPADD
+ TM_ADD
));
316 LUA_API
int lua_compare (lua_State
*L
, int index1
, int index2
, int op
) {
319 lua_lock(L
); /* may call tag method */
320 o1
= index2addr(L
, index1
);
321 o2
= index2addr(L
, index2
);
322 if (isvalid(o1
) && isvalid(o2
)) {
324 case LUA_OPEQ
: i
= equalobj(L
, o1
, o2
); break;
325 case LUA_OPLT
: i
= luaV_lessthan(L
, o1
, o2
); break;
326 case LUA_OPLE
: i
= luaV_lessequal(L
, o1
, o2
); break;
327 default: api_check(L
, 0, "invalid option");
335 LUA_API lua_Number
lua_tonumberx (lua_State
*L
, int idx
, int *isnum
) {
337 const TValue
*o
= index2addr(L
, idx
);
338 if (tonumber(o
, &n
)) {
339 if (isnum
) *isnum
= 1;
343 if (isnum
) *isnum
= 0;
349 LUA_API lua_Integer
lua_tointegerx (lua_State
*L
, int idx
, int *isnum
) {
351 const TValue
*o
= index2addr(L
, idx
);
352 if (tonumber(o
, &n
)) {
354 lua_Number num
= nvalue(o
);
355 lua_number2integer(res
, num
);
356 if (isnum
) *isnum
= 1;
360 if (isnum
) *isnum
= 0;
366 LUA_API lua_Unsigned
lua_tounsignedx (lua_State
*L
, int idx
, int *isnum
) {
368 const TValue
*o
= index2addr(L
, idx
);
369 if (tonumber(o
, &n
)) {
371 lua_Number num
= nvalue(o
);
372 lua_number2unsigned(res
, num
);
373 if (isnum
) *isnum
= 1;
377 if (isnum
) *isnum
= 0;
383 LUA_API
int lua_toboolean (lua_State
*L
, int idx
) {
384 const TValue
*o
= index2addr(L
, idx
);
385 return !l_isfalse(o
);
389 LUA_API
const char *lua_tolstring (lua_State
*L
, int idx
, size_t *len
) {
390 StkId o
= index2addr(L
, idx
);
391 if (!ttisstring(o
)) {
392 lua_lock(L
); /* `luaV_tostring' may create a new string */
393 if (!luaV_tostring(L
, o
)) { /* conversion failed? */
394 if (len
!= NULL
) *len
= 0;
399 o
= index2addr(L
, idx
); /* previous call may reallocate the stack */
402 if (len
!= NULL
) *len
= tsvalue(o
)->len
;
407 LUA_API
size_t lua_rawlen (lua_State
*L
, int idx
) {
408 StkId o
= index2addr(L
, idx
);
409 switch (ttypenv(o
)) {
410 case LUA_TSTRING
: return tsvalue(o
)->len
;
411 case LUA_TUSERDATA
: return uvalue(o
)->len
;
412 case LUA_TTABLE
: return luaH_getn(hvalue(o
));
418 LUA_API lua_CFunction
lua_tocfunction (lua_State
*L
, int idx
) {
419 StkId o
= index2addr(L
, idx
);
420 if (ttislcf(o
)) return fvalue(o
);
421 else if (ttisCclosure(o
))
422 return clCvalue(o
)->f
;
423 else return NULL
; /* not a C function */
427 LUA_API
void *lua_touserdata (lua_State
*L
, int idx
) {
428 StkId o
= index2addr(L
, idx
);
429 switch (ttypenv(o
)) {
430 case LUA_TUSERDATA
: return (rawuvalue(o
) + 1);
431 case LUA_TLIGHTUSERDATA
: return pvalue(o
);
432 default: return NULL
;
437 LUA_API lua_State
*lua_tothread (lua_State
*L
, int idx
) {
438 StkId o
= index2addr(L
, idx
);
439 return (!ttisthread(o
)) ? NULL
: thvalue(o
);
443 LUA_API
const void *lua_topointer (lua_State
*L
, int idx
) {
444 StkId o
= index2addr(L
, idx
);
446 case LUA_TTABLE
: return hvalue(o
);
447 case LUA_TLCL
: return clLvalue(o
);
448 case LUA_TCCL
: return clCvalue(o
);
449 case LUA_TLCF
: return cast(void *, cast(size_t, fvalue(o
)));
450 case LUA_TTHREAD
: return thvalue(o
);
452 case LUA_TLIGHTUSERDATA
:
453 return lua_touserdata(L
, idx
);
454 default: return NULL
;
461 ** push functions (C -> stack)
465 LUA_API
void lua_pushnil (lua_State
*L
) {
473 LUA_API
void lua_pushnumber (lua_State
*L
, lua_Number n
) {
475 setnvalue(L
->top
, n
);
476 luai_checknum(L
, L
->top
,
477 luaG_runerror(L
, "C API - attempt to push a signaling NaN"));
483 LUA_API
void lua_pushinteger (lua_State
*L
, lua_Integer n
) {
485 setnvalue(L
->top
, cast_num(n
));
491 LUA_API
void lua_pushunsigned (lua_State
*L
, lua_Unsigned u
) {
494 n
= lua_unsigned2number(u
);
495 setnvalue(L
->top
, n
);
501 LUA_API
const char *lua_pushlstring (lua_State
*L
, const char *s
, size_t len
) {
505 ts
= luaS_newlstr(L
, s
, len
);
506 setsvalue2s(L
, L
->top
, ts
);
513 LUA_API
const char *lua_pushstring (lua_State
*L
, const char *s
) {
523 setsvalue2s(L
, L
->top
, ts
);
531 LUA_API
const char *lua_pushvfstring (lua_State
*L
, const char *fmt
,
536 ret
= luaO_pushvfstring(L
, fmt
, argp
);
542 LUA_API
const char *lua_pushfstring (lua_State
*L
, const char *fmt
, ...) {
548 ret
= luaO_pushvfstring(L
, fmt
, argp
);
555 LUA_API
void lua_pushcclosure (lua_State
*L
, lua_CFunction fn
, int n
) {
558 setfvalue(L
->top
, fn
);
562 api_checknelems(L
, n
);
563 api_check(L
, n
<= MAXUPVAL
, "upvalue index too large");
565 cl
= luaF_newCclosure(L
, n
);
569 setobj2n(L
, &cl
->c
.upvalue
[n
], L
->top
+ n
);
570 setclCvalue(L
, L
->top
, cl
);
577 LUA_API
void lua_pushboolean (lua_State
*L
, int b
) {
579 setbvalue(L
->top
, (b
!= 0)); /* ensure that true is 1 */
585 LUA_API
void lua_pushlightuserdata (lua_State
*L
, void *p
) {
587 setpvalue(L
->top
, p
);
593 LUA_API
int lua_pushthread (lua_State
*L
) {
595 setthvalue(L
, L
->top
, L
);
598 return (G(L
)->mainthread
== L
);
604 ** get functions (Lua -> stack)
608 LUA_API
void lua_getglobal (lua_State
*L
, const char *var
) {
609 Table
*reg
= hvalue(&G(L
)->l_registry
);
610 const TValue
*gt
; /* global table */
612 gt
= luaH_getint(reg
, LUA_RIDX_GLOBALS
);
613 setsvalue2s(L
, L
->top
++, luaS_new(L
, var
));
614 luaV_gettable(L
, gt
, L
->top
- 1, L
->top
- 1);
619 LUA_API
void lua_gettable (lua_State
*L
, int idx
) {
622 t
= index2addr(L
, idx
);
623 luaV_gettable(L
, t
, L
->top
- 1, L
->top
- 1);
628 LUA_API
void lua_getfield (lua_State
*L
, int idx
, const char *k
) {
631 t
= index2addr(L
, idx
);
632 setsvalue2s(L
, L
->top
, luaS_new(L
, k
));
634 luaV_gettable(L
, t
, L
->top
- 1, L
->top
- 1);
639 LUA_API
void lua_rawget (lua_State
*L
, int idx
) {
642 t
= index2addr(L
, idx
);
643 api_check(L
, ttistable(t
), "table expected");
644 setobj2s(L
, L
->top
- 1, luaH_get(hvalue(t
), L
->top
- 1));
649 LUA_API
void lua_rawgeti (lua_State
*L
, int idx
, int n
) {
652 t
= index2addr(L
, idx
);
653 api_check(L
, ttistable(t
), "table expected");
654 setobj2s(L
, L
->top
, luaH_getint(hvalue(t
), n
));
660 LUA_API
void lua_rawgetp (lua_State
*L
, int idx
, const void *p
) {
664 t
= index2addr(L
, idx
);
665 api_check(L
, ttistable(t
), "table expected");
666 setpvalue(&k
, cast(void *, p
));
667 setobj2s(L
, L
->top
, luaH_get(hvalue(t
), &k
));
673 LUA_API
void lua_createtable (lua_State
*L
, int narray
, int nrec
) {
678 sethvalue(L
, L
->top
, t
);
680 if (narray
> 0 || nrec
> 0)
681 luaH_resize(L
, t
, narray
, nrec
);
686 LUA_API
int lua_getmetatable (lua_State
*L
, int objindex
) {
691 obj
= index2addr(L
, objindex
);
692 switch (ttypenv(obj
)) {
694 mt
= hvalue(obj
)->metatable
;
697 mt
= uvalue(obj
)->metatable
;
700 mt
= G(L
)->mt
[ttypenv(obj
)];
706 sethvalue(L
, L
->top
, mt
);
715 LUA_API
void lua_getuservalue (lua_State
*L
, int idx
) {
718 o
= index2addr(L
, idx
);
719 api_check(L
, ttisuserdata(o
), "userdata expected");
720 if (uvalue(o
)->env
) {
721 sethvalue(L
, L
->top
, uvalue(o
)->env
);
730 ** set functions (stack -> Lua)
734 LUA_API
void lua_setglobal (lua_State
*L
, const char *var
) {
735 Table
*reg
= hvalue(&G(L
)->l_registry
);
736 const TValue
*gt
; /* global table */
738 api_checknelems(L
, 1);
739 gt
= luaH_getint(reg
, LUA_RIDX_GLOBALS
);
740 setsvalue2s(L
, L
->top
++, luaS_new(L
, var
));
741 luaV_settable(L
, gt
, L
->top
- 1, L
->top
- 2);
742 L
->top
-= 2; /* pop value and key */
747 LUA_API
void lua_settable (lua_State
*L
, int idx
) {
750 api_checknelems(L
, 2);
751 t
= index2addr(L
, idx
);
752 luaV_settable(L
, t
, L
->top
- 2, L
->top
- 1);
753 L
->top
-= 2; /* pop index and value */
758 LUA_API
void lua_setfield (lua_State
*L
, int idx
, const char *k
) {
761 api_checknelems(L
, 1);
762 t
= index2addr(L
, idx
);
763 setsvalue2s(L
, L
->top
++, luaS_new(L
, k
));
764 luaV_settable(L
, t
, L
->top
- 1, L
->top
- 2);
765 L
->top
-= 2; /* pop value and key */
770 LUA_API
void lua_rawset (lua_State
*L
, int idx
) {
773 api_checknelems(L
, 2);
774 t
= index2addr(L
, idx
);
775 api_check(L
, ttistable(t
), "table expected");
776 setobj2t(L
, luaH_set(L
, hvalue(t
), L
->top
-2), L
->top
-1);
777 invalidateTMcache(hvalue(t
));
778 luaC_barrierback(L
, gcvalue(t
), L
->top
-1);
784 LUA_API
void lua_rawseti (lua_State
*L
, int idx
, int n
) {
787 api_checknelems(L
, 1);
788 t
= index2addr(L
, idx
);
789 api_check(L
, ttistable(t
), "table expected");
790 luaH_setint(L
, hvalue(t
), n
, L
->top
- 1);
791 luaC_barrierback(L
, gcvalue(t
), L
->top
-1);
797 LUA_API
void lua_rawsetp (lua_State
*L
, int idx
, const void *p
) {
801 api_checknelems(L
, 1);
802 t
= index2addr(L
, idx
);
803 api_check(L
, ttistable(t
), "table expected");
804 setpvalue(&k
, cast(void *, p
));
805 setobj2t(L
, luaH_set(L
, hvalue(t
), &k
), L
->top
- 1);
806 luaC_barrierback(L
, gcvalue(t
), L
->top
- 1);
812 LUA_API
int lua_setmetatable (lua_State
*L
, int objindex
) {
816 api_checknelems(L
, 1);
817 obj
= index2addr(L
, objindex
);
818 if (ttisnil(L
->top
- 1))
821 api_check(L
, ttistable(L
->top
- 1), "table expected");
822 mt
= hvalue(L
->top
- 1);
824 switch (ttypenv(obj
)) {
826 hvalue(obj
)->metatable
= mt
;
828 luaC_objbarrierback(L
, gcvalue(obj
), mt
);
829 luaC_checkfinalizer(L
, gcvalue(obj
), mt
);
833 case LUA_TUSERDATA
: {
834 uvalue(obj
)->metatable
= mt
;
836 luaC_objbarrier(L
, rawuvalue(obj
), mt
);
837 luaC_checkfinalizer(L
, gcvalue(obj
), mt
);
842 G(L
)->mt
[ttypenv(obj
)] = mt
;
852 LUA_API
void lua_setuservalue (lua_State
*L
, int idx
) {
855 api_checknelems(L
, 1);
856 o
= index2addr(L
, idx
);
857 api_check(L
, ttisuserdata(o
), "userdata expected");
858 if (ttisnil(L
->top
- 1))
859 uvalue(o
)->env
= NULL
;
861 api_check(L
, ttistable(L
->top
- 1), "table expected");
862 uvalue(o
)->env
= hvalue(L
->top
- 1);
863 luaC_objbarrier(L
, gcvalue(o
), hvalue(L
->top
- 1));
871 ** `load' and `call' functions (run Lua code)
875 #define checkresults(L,na,nr) \
876 api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
877 "results from function overflow current stack size")
880 LUA_API
int lua_getctx (lua_State
*L
, int *ctx
) {
881 if (L
->ci
->callstatus
& CIST_YIELDED
) {
882 if (ctx
) *ctx
= L
->ci
->u
.c
.ctx
;
883 return L
->ci
->u
.c
.status
;
889 LUA_API
void lua_callk (lua_State
*L
, int nargs
, int nresults
, int ctx
,
893 api_check(L
, k
== NULL
|| !isLua(L
->ci
),
894 "cannot use continuations inside hooks");
895 api_checknelems(L
, nargs
+1);
896 api_check(L
, L
->status
== LUA_OK
, "cannot do calls on non-normal thread");
897 checkresults(L
, nargs
, nresults
);
898 func
= L
->top
- (nargs
+1);
899 if (k
!= NULL
&& L
->nny
== 0) { /* need to prepare continuation? */
900 L
->ci
->u
.c
.k
= k
; /* save continuation */
901 L
->ci
->u
.c
.ctx
= ctx
; /* save context */
902 luaD_call(L
, func
, nresults
, 1); /* do the call */
904 else /* no continuation or no yieldable */
905 luaD_call(L
, func
, nresults
, 0); /* just do the call */
906 adjustresults(L
, nresults
);
913 ** Execute a protected call.
915 struct CallS
{ /* data to `f_call' */
921 static void f_call (lua_State
*L
, void *ud
) {
922 struct CallS
*c
= cast(struct CallS
*, ud
);
923 luaD_call(L
, c
->func
, c
->nresults
, 0);
928 LUA_API
int lua_pcallk (lua_State
*L
, int nargs
, int nresults
, int errfunc
,
929 int ctx
, lua_CFunction k
) {
934 api_check(L
, k
== NULL
|| !isLua(L
->ci
),
935 "cannot use continuations inside hooks");
936 api_checknelems(L
, nargs
+1);
937 api_check(L
, L
->status
== LUA_OK
, "cannot do calls on non-normal thread");
938 checkresults(L
, nargs
, nresults
);
942 StkId o
= index2addr(L
, errfunc
);
943 api_checkstackindex(L
, errfunc
, o
);
944 func
= savestack(L
, o
);
946 c
.func
= L
->top
- (nargs
+1); /* function to be called */
947 if (k
== NULL
|| L
->nny
> 0) { /* no continuation or no yieldable? */
948 c
.nresults
= nresults
; /* do a 'conventional' protected call */
949 status
= luaD_pcall(L
, f_call
, &c
, savestack(L
, c
.func
), func
);
951 else { /* prepare continuation (call is already protected by 'resume') */
952 CallInfo
*ci
= L
->ci
;
953 ci
->u
.c
.k
= k
; /* save continuation */
954 ci
->u
.c
.ctx
= ctx
; /* save context */
955 /* save information for error recovery */
956 ci
->extra
= savestack(L
, c
.func
);
957 ci
->u
.c
.old_allowhook
= L
->allowhook
;
958 ci
->u
.c
.old_errfunc
= L
->errfunc
;
960 /* mark that function may do error recovery */
961 ci
->callstatus
|= CIST_YPCALL
;
962 luaD_call(L
, c
.func
, nresults
, 1); /* do the call */
963 ci
->callstatus
&= ~CIST_YPCALL
;
964 L
->errfunc
= ci
->u
.c
.old_errfunc
;
965 status
= LUA_OK
; /* if it is here, there were no errors */
967 adjustresults(L
, nresults
);
973 LUA_API
int lua_load (lua_State
*L
, lua_Reader reader
, void *data
,
974 const char *chunkname
, const char *mode
) {
978 if (!chunkname
) chunkname
= "?";
979 luaZ_init(L
, &z
, reader
, data
);
980 status
= luaD_protectedparser(L
, &z
, chunkname
, mode
);
981 if (status
== LUA_OK
) { /* no errors? */
982 LClosure
*f
= clLvalue(L
->top
- 1); /* get newly created function */
983 if (f
->nupvalues
== 1) { /* does it have one upvalue? */
984 /* get global table from registry */
985 Table
*reg
= hvalue(&G(L
)->l_registry
);
986 const TValue
*gt
= luaH_getint(reg
, LUA_RIDX_GLOBALS
);
987 /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
988 setobj(L
, f
->upvals
[0]->v
, gt
);
989 luaC_barrier(L
, f
->upvals
[0], gt
);
997 LUA_API
int lua_dump (lua_State
*L
, lua_Writer writer
, void *data
) {
1001 api_checknelems(L
, 1);
1004 status
= luaU_dump(L
, getproto(o
), writer
, data
, 0);
1012 LUA_API
int lua_status (lua_State
*L
) {
1018 ** Garbage-collection function
1021 LUA_API
int lua_gc (lua_State
*L
, int what
, int data
) {
1031 case LUA_GCRESTART
: {
1036 case LUA_GCCOLLECT
: {
1041 /* GC values are expressed in Kbytes: #bytes/2^10 */
1042 res
= cast_int(gettotalbytes(g
) >> 10);
1045 case LUA_GCCOUNTB
: {
1046 res
= cast_int(gettotalbytes(g
) & 0x3ff);
1050 if (g
->gckind
== KGC_GEN
) { /* generational mode? */
1051 res
= (g
->GCestimate
== 0); /* true if it will do major collection */
1052 luaC_forcestep(L
); /* do a single step */
1055 lu_mem debt
= cast(lu_mem
, data
) * 1024 - GCSTEPSIZE
;
1057 debt
+= g
->GCdebt
; /* include current debt */
1058 luaE_setdebt(g
, debt
);
1060 if (g
->gcstate
== GCSpause
) /* end of cycle? */
1061 res
= 1; /* signal it */
1065 case LUA_GCSETPAUSE
: {
1070 case LUA_GCSETMAJORINC
: {
1071 res
= g
->gcmajorinc
;
1072 g
->gcmajorinc
= data
;
1075 case LUA_GCSETSTEPMUL
: {
1077 g
->gcstepmul
= data
;
1080 case LUA_GCISRUNNING
: {
1084 case LUA_GCGEN
: { /* change collector to generational mode */
1085 luaC_changemode(L
, KGC_GEN
);
1088 case LUA_GCINC
: { /* change collector to incremental mode */
1089 luaC_changemode(L
, KGC_NORMAL
);
1092 default: res
= -1; /* invalid option */
1101 ** miscellaneous functions
1105 LUA_API
int lua_error (lua_State
*L
) {
1107 api_checknelems(L
, 1);
1109 /* code unreachable; will unlock when control actually leaves the kernel */
1110 return 0; /* to avoid warnings */
1114 LUA_API
int lua_next (lua_State
*L
, int idx
) {
1118 t
= index2addr(L
, idx
);
1119 api_check(L
, ttistable(t
), "table expected");
1120 more
= luaH_next(L
, hvalue(t
), L
->top
- 1);
1124 else /* no more elements */
1125 L
->top
-= 1; /* remove key */
1131 LUA_API
void lua_concat (lua_State
*L
, int n
) {
1133 api_checknelems(L
, n
);
1138 else if (n
== 0) { /* push empty string */
1139 setsvalue2s(L
, L
->top
, luaS_newlstr(L
, "", 0));
1142 /* else n == 1; nothing to do */
1147 LUA_API
void lua_len (lua_State
*L
, int idx
) {
1150 t
= index2addr(L
, idx
);
1151 luaV_objlen(L
, L
->top
, t
);
1157 LUA_API lua_Alloc
lua_getallocf (lua_State
*L
, void **ud
) {
1160 if (ud
) *ud
= G(L
)->ud
;
1167 LUA_API
void lua_setallocf (lua_State
*L
, lua_Alloc f
, void *ud
) {
1175 LUA_API
void *lua_newuserdata (lua_State
*L
, size_t size
) {
1179 u
= luaS_newudata(L
, size
, NULL
);
1180 setuvalue(L
, L
->top
, u
);
1188 static const char *aux_upvalue (StkId fi
, int n
, TValue
**val
,
1190 switch (ttype(fi
)) {
1191 case LUA_TCCL
: { /* C closure */
1192 CClosure
*f
= clCvalue(fi
);
1193 if (!(1 <= n
&& n
<= f
->nupvalues
)) return NULL
;
1194 *val
= &f
->upvalue
[n
-1];
1195 if (owner
) *owner
= obj2gco(f
);
1198 case LUA_TLCL
: { /* Lua closure */
1199 LClosure
*f
= clLvalue(fi
);
1202 if (!(1 <= n
&& n
<= p
->sizeupvalues
)) return NULL
;
1203 *val
= f
->upvals
[n
-1]->v
;
1204 if (owner
) *owner
= obj2gco(f
->upvals
[n
- 1]);
1205 name
= p
->upvalues
[n
-1].name
;
1206 return (name
== NULL
) ? "" : getstr(name
);
1208 default: return NULL
; /* not a closure */
1213 LUA_API
const char *lua_getupvalue (lua_State
*L
, int funcindex
, int n
) {
1215 TValue
*val
= NULL
; /* to avoid warnings */
1217 name
= aux_upvalue(index2addr(L
, funcindex
), n
, &val
, NULL
);
1219 setobj2s(L
, L
->top
, val
);
1227 LUA_API
const char *lua_setupvalue (lua_State
*L
, int funcindex
, int n
) {
1229 TValue
*val
= NULL
; /* to avoid warnings */
1230 GCObject
*owner
= NULL
; /* to avoid warnings */
1233 fi
= index2addr(L
, funcindex
);
1234 api_checknelems(L
, 1);
1235 name
= aux_upvalue(fi
, n
, &val
, &owner
);
1238 setobj(L
, val
, L
->top
);
1239 luaC_barrier(L
, owner
, L
->top
);
1246 static UpVal
**getupvalref (lua_State
*L
, int fidx
, int n
, LClosure
**pf
) {
1248 StkId fi
= index2addr(L
, fidx
);
1249 api_check(L
, ttisLclosure(fi
), "Lua function expected");
1251 api_check(L
, (1 <= n
&& n
<= f
->p
->sizeupvalues
), "invalid upvalue index");
1253 return &f
->upvals
[n
- 1]; /* get its upvalue pointer */
1257 LUA_API
void *lua_upvalueid (lua_State
*L
, int fidx
, int n
) {
1258 StkId fi
= index2addr(L
, fidx
);
1259 switch (ttype(fi
)) {
1260 case LUA_TLCL
: { /* lua closure */
1261 return *getupvalref(L
, fidx
, n
, NULL
);
1263 case LUA_TCCL
: { /* C closure */
1264 CClosure
*f
= clCvalue(fi
);
1265 api_check(L
, 1 <= n
&& n
<= f
->nupvalues
, "invalid upvalue index");
1266 return &f
->upvalue
[n
- 1];
1269 api_check(L
, 0, "closure expected");
1276 LUA_API
void lua_upvaluejoin (lua_State
*L
, int fidx1
, int n1
,
1277 int fidx2
, int n2
) {
1279 UpVal
**up1
= getupvalref(L
, fidx1
, n1
, &f1
);
1280 UpVal
**up2
= getupvalref(L
, fidx2
, n2
, NULL
);
1282 luaC_objbarrier(L
, f1
, *up2
);