3 ** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
5 ** Major portions taken verbatim or adapted from the Lua interpreter.
6 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
26 #include "lj_strscan.h"
27 #include "lj_strfmt.h"
29 /* -- Common helper functions --------------------------------------------- */
31 #define lj_checkapi_slot(idx) \
32 lj_checkapi((idx) <= (L->top - L->base), "stack slot %d out of range", (idx))
34 static TValue
*index2adr(lua_State
*L
, int idx
)
37 TValue
*o
= L
->base
+ (idx
- 1);
38 return o
< L
->top
? o
: niltv(L
);
39 } else if (idx
> LUA_REGISTRYINDEX
) {
40 lj_checkapi(idx
!= 0 && -idx
<= L
->top
- L
->base
,
41 "bad stack slot %d", idx
);
43 } else if (idx
== LUA_GLOBALSINDEX
) {
44 TValue
*o
= &G(L
)->tmptv
;
45 settabV(L
, o
, tabref(L
->env
));
47 } else if (idx
== LUA_REGISTRYINDEX
) {
50 GCfunc
*fn
= curr_func(L
);
51 lj_checkapi(fn
->c
.gct
== ~LJ_TFUNC
&& !isluafunc(fn
),
52 "calling frame is not a C function");
53 if (idx
== LUA_ENVIRONINDEX
) {
54 TValue
*o
= &G(L
)->tmptv
;
55 settabV(L
, o
, tabref(fn
->c
.env
));
58 idx
= LUA_GLOBALSINDEX
- idx
;
59 return idx
<= fn
->c
.nupvalues
? &fn
->c
.upvalue
[idx
-1] : niltv(L
);
64 static LJ_AINLINE TValue
*index2adr_check(lua_State
*L
, int idx
)
66 TValue
*o
= index2adr(L
, idx
);
67 lj_checkapi(o
!= niltv(L
), "invalid stack slot %d", idx
);
71 static TValue
*index2adr_stack(lua_State
*L
, int idx
)
74 TValue
*o
= L
->base
+ (idx
- 1);
78 lj_checkapi(0, "invalid stack slot %d", idx
);
81 return o
< L
->top
? o
: niltv(L
);
83 lj_checkapi(idx
!= 0 && -idx
<= L
->top
- L
->base
,
84 "invalid stack slot %d", idx
);
89 static GCtab
*getcurrenv(lua_State
*L
)
91 GCfunc
*fn
= curr_func(L
);
92 return fn
->c
.gct
== ~LJ_TFUNC
? tabref(fn
->c
.env
) : tabref(L
->env
);
95 /* -- Miscellaneous API functions ----------------------------------------- */
97 LUA_API
int lua_status(lua_State
*L
)
102 LUA_API
int lua_checkstack(lua_State
*L
, int size
)
104 if (size
> LUAI_MAXCSTACK
|| (L
->top
- L
->base
+ size
) > LUAI_MAXCSTACK
) {
105 return 0; /* Stack overflow. */
106 } else if (size
> 0) {
107 int avail
= (int)(mref(L
->maxstack
, TValue
) - L
->top
);
109 lj_state_cpgrowstack(L
, (MSize
)(size
- avail
)) != LUA_OK
) {
111 return 0; /* Out of memory. */
117 LUALIB_API
void luaL_checkstack(lua_State
*L
, int size
, const char *msg
)
119 if (!lua_checkstack(L
, size
))
120 lj_err_callerv(L
, LJ_ERR_STKOVM
, msg
);
123 LUA_API
void lua_xmove(lua_State
*L
, lua_State
*to
, int n
)
128 lj_checkapi(G(L
) == G(to
), "move across global states");
129 lj_state_checkstack(to
, (MSize
)n
);
131 t
= to
->top
= to
->top
+ n
;
132 while (--n
>= 0) copyTV(to
, --t
, --f
);
136 LUA_API
const lua_Number
*lua_version(lua_State
*L
)
138 static const lua_Number version
= LUA_VERSION_NUM
;
143 /* -- Stack manipulation -------------------------------------------------- */
145 LUA_API
int lua_gettop(lua_State
*L
)
147 return (int)(L
->top
- L
->base
);
150 LUA_API
void lua_settop(lua_State
*L
, int idx
)
153 lj_checkapi(idx
<= tvref(L
->maxstack
) - L
->base
, "bad stack slot %d", idx
);
154 if (L
->base
+ idx
> L
->top
) {
155 if (L
->base
+ idx
>= tvref(L
->maxstack
))
156 lj_state_growstack(L
, (MSize
)idx
- (MSize
)(L
->top
- L
->base
));
157 do { setnilV(L
->top
++); } while (L
->top
< L
->base
+ idx
);
159 L
->top
= L
->base
+ idx
;
162 lj_checkapi(-(idx
+1) <= (L
->top
- L
->base
), "bad stack slot %d", idx
);
163 L
->top
+= idx
+1; /* Shrinks top (idx < 0). */
167 LUA_API
void lua_remove(lua_State
*L
, int idx
)
169 TValue
*p
= index2adr_stack(L
, idx
);
170 while (++p
< L
->top
) copyTV(L
, p
-1, p
);
174 LUA_API
void lua_insert(lua_State
*L
, int idx
)
176 TValue
*q
, *p
= index2adr_stack(L
, idx
);
177 for (q
= L
->top
; q
> p
; q
--) copyTV(L
, q
, q
-1);
178 copyTV(L
, p
, L
->top
);
181 static void copy_slot(lua_State
*L
, TValue
*f
, int idx
)
183 if (idx
== LUA_GLOBALSINDEX
) {
184 lj_checkapi(tvistab(f
), "stack slot %d is not a table", idx
);
185 /* NOBARRIER: A thread (i.e. L) is never black. */
186 setgcref(L
->env
, obj2gco(tabV(f
)));
187 } else if (idx
== LUA_ENVIRONINDEX
) {
188 GCfunc
*fn
= curr_func(L
);
189 if (fn
->c
.gct
!= ~LJ_TFUNC
)
190 lj_err_msg(L
, LJ_ERR_NOENV
);
191 lj_checkapi(tvistab(f
), "stack slot %d is not a table", idx
);
192 setgcref(fn
->c
.env
, obj2gco(tabV(f
)));
193 lj_gc_barrier(L
, fn
, f
);
195 TValue
*o
= index2adr_check(L
, idx
);
197 if (idx
< LUA_GLOBALSINDEX
) /* Need a barrier for upvalues. */
198 lj_gc_barrier(L
, curr_func(L
), f
);
202 LUA_API
void lua_replace(lua_State
*L
, int idx
)
205 copy_slot(L
, L
->top
- 1, idx
);
209 LUA_API
void lua_copy(lua_State
*L
, int fromidx
, int toidx
)
211 copy_slot(L
, index2adr(L
, fromidx
), toidx
);
214 LUA_API
void lua_pushvalue(lua_State
*L
, int idx
)
216 copyTV(L
, L
->top
, index2adr(L
, idx
));
220 /* -- Stack getters ------------------------------------------------------- */
222 LUA_API
int lua_type(lua_State
*L
, int idx
)
224 cTValue
*o
= index2adr(L
, idx
);
227 #if LJ_64 && !LJ_GC64
228 } else if (tvislightud(o
)) {
229 return LUA_TLIGHTUSERDATA
;
231 } else if (o
== niltv(L
)) {
233 } else { /* Magic internal/external tag conversion. ORDER LJ_T */
234 uint32_t t
= ~itype(o
);
236 int tt
= (int)((U64x(75a06
,98042110) >> 4*t
) & 15u);
238 int tt
= (int)(((t
< 8 ? 0x98042110u
: 0x75a06u
) >> 4*(t
&7)) & 15u);
240 lj_assertL(tt
!= LUA_TNIL
|| tvisnil(o
), "bad tag conversion");
245 LUALIB_API
void luaL_checktype(lua_State
*L
, int idx
, int tt
)
247 if (lua_type(L
, idx
) != tt
)
248 lj_err_argt(L
, idx
, tt
);
251 LUALIB_API
void luaL_checkany(lua_State
*L
, int idx
)
253 if (index2adr(L
, idx
) == niltv(L
))
254 lj_err_arg(L
, idx
, LJ_ERR_NOVAL
);
257 LUA_API
const char *lua_typename(lua_State
*L
, int t
)
260 return lj_obj_typename
[t
+1];
263 LUA_API
int lua_iscfunction(lua_State
*L
, int idx
)
265 cTValue
*o
= index2adr(L
, idx
);
266 return tvisfunc(o
) && !isluafunc(funcV(o
));
269 LUA_API
int lua_isnumber(lua_State
*L
, int idx
)
271 cTValue
*o
= index2adr(L
, idx
);
273 return (tvisnumber(o
) || (tvisstr(o
) && lj_strscan_number(strV(o
), &tmp
)));
276 LUA_API
int lua_isstring(lua_State
*L
, int idx
)
278 cTValue
*o
= index2adr(L
, idx
);
279 return (tvisstr(o
) || tvisnumber(o
));
282 LUA_API
int lua_isuserdata(lua_State
*L
, int idx
)
284 cTValue
*o
= index2adr(L
, idx
);
285 return (tvisudata(o
) || tvislightud(o
));
288 LUA_API
int lua_rawequal(lua_State
*L
, int idx1
, int idx2
)
290 cTValue
*o1
= index2adr(L
, idx1
);
291 cTValue
*o2
= index2adr(L
, idx2
);
292 return (o1
== niltv(L
) || o2
== niltv(L
)) ? 0 : lj_obj_equal(o1
, o2
);
295 LUA_API
int lua_equal(lua_State
*L
, int idx1
, int idx2
)
297 cTValue
*o1
= index2adr(L
, idx1
);
298 cTValue
*o2
= index2adr(L
, idx2
);
299 if (tvisint(o1
) && tvisint(o2
)) {
300 return intV(o1
) == intV(o2
);
301 } else if (tvisnumber(o1
) && tvisnumber(o2
)) {
302 return numberVnum(o1
) == numberVnum(o2
);
303 } else if (itype(o1
) != itype(o2
)) {
305 } else if (tvispri(o1
)) {
306 return o1
!= niltv(L
) && o2
!= niltv(L
);
307 #if LJ_64 && !LJ_GC64
308 } else if (tvislightud(o1
)) {
309 return o1
->u64
== o2
->u64
;
311 } else if (gcrefeq(o1
->gcr
, o2
->gcr
)) {
313 } else if (!tvistabud(o1
)) {
316 TValue
*base
= lj_meta_equal(L
, gcV(o1
), gcV(o2
), 0);
317 if ((uintptr_t)base
<= 1) {
318 return (int)(uintptr_t)base
;
321 lj_vm_call(L
, base
, 1+1);
323 return tvistruecond(L
->top
+1+LJ_FR2
);
328 LUA_API
int lua_lessthan(lua_State
*L
, int idx1
, int idx2
)
330 cTValue
*o1
= index2adr(L
, idx1
);
331 cTValue
*o2
= index2adr(L
, idx2
);
332 if (o1
== niltv(L
) || o2
== niltv(L
)) {
334 } else if (tvisint(o1
) && tvisint(o2
)) {
335 return intV(o1
) < intV(o2
);
336 } else if (tvisnumber(o1
) && tvisnumber(o2
)) {
337 return numberVnum(o1
) < numberVnum(o2
);
339 TValue
*base
= lj_meta_comp(L
, o1
, o2
, 0);
340 if ((uintptr_t)base
<= 1) {
341 return (int)(uintptr_t)base
;
344 lj_vm_call(L
, base
, 1+1);
346 return tvistruecond(L
->top
+1+LJ_FR2
);
351 LUA_API lua_Number
lua_tonumber(lua_State
*L
, int idx
)
353 cTValue
*o
= index2adr(L
, idx
);
355 if (LJ_LIKELY(tvisnumber(o
)))
356 return numberVnum(o
);
357 else if (tvisstr(o
) && lj_strscan_num(strV(o
), &tmp
))
363 LUA_API lua_Number
lua_tonumberx(lua_State
*L
, int idx
, int *ok
)
365 cTValue
*o
= index2adr(L
, idx
);
367 if (LJ_LIKELY(tvisnumber(o
))) {
369 return numberVnum(o
);
370 } else if (tvisstr(o
) && lj_strscan_num(strV(o
), &tmp
)) {
379 LUALIB_API lua_Number
luaL_checknumber(lua_State
*L
, int idx
)
381 cTValue
*o
= index2adr(L
, idx
);
383 if (LJ_LIKELY(tvisnumber(o
)))
384 return numberVnum(o
);
385 else if (!(tvisstr(o
) && lj_strscan_num(strV(o
), &tmp
)))
386 lj_err_argt(L
, idx
, LUA_TNUMBER
);
390 LUALIB_API lua_Number
luaL_optnumber(lua_State
*L
, int idx
, lua_Number def
)
392 cTValue
*o
= index2adr(L
, idx
);
394 if (LJ_LIKELY(tvisnumber(o
)))
395 return numberVnum(o
);
398 else if (!(tvisstr(o
) && lj_strscan_num(strV(o
), &tmp
)))
399 lj_err_argt(L
, idx
, LUA_TNUMBER
);
403 LUA_API lua_Integer
lua_tointeger(lua_State
*L
, int idx
)
405 cTValue
*o
= index2adr(L
, idx
);
408 if (LJ_LIKELY(tvisint(o
))) {
410 } else if (LJ_LIKELY(tvisnum(o
))) {
413 if (!(tvisstr(o
) && lj_strscan_number(strV(o
), &tmp
)))
420 return (lua_Integer
)n
;
422 return lj_num2int(n
);
426 LUA_API lua_Integer
lua_tointegerx(lua_State
*L
, int idx
, int *ok
)
428 cTValue
*o
= index2adr(L
, idx
);
431 if (LJ_LIKELY(tvisint(o
))) {
434 } else if (LJ_LIKELY(tvisnum(o
))) {
437 if (!(tvisstr(o
) && lj_strscan_number(strV(o
), &tmp
))) {
449 return (lua_Integer
)n
;
451 return lj_num2int(n
);
455 LUALIB_API lua_Integer
luaL_checkinteger(lua_State
*L
, int idx
)
457 cTValue
*o
= index2adr(L
, idx
);
460 if (LJ_LIKELY(tvisint(o
))) {
462 } else if (LJ_LIKELY(tvisnum(o
))) {
465 if (!(tvisstr(o
) && lj_strscan_number(strV(o
), &tmp
)))
466 lj_err_argt(L
, idx
, LUA_TNUMBER
);
468 return (lua_Integer
)intV(&tmp
);
472 return (lua_Integer
)n
;
474 return lj_num2int(n
);
478 LUALIB_API lua_Integer
luaL_optinteger(lua_State
*L
, int idx
, lua_Integer def
)
480 cTValue
*o
= index2adr(L
, idx
);
483 if (LJ_LIKELY(tvisint(o
))) {
485 } else if (LJ_LIKELY(tvisnum(o
))) {
487 } else if (tvisnil(o
)) {
490 if (!(tvisstr(o
) && lj_strscan_number(strV(o
), &tmp
)))
491 lj_err_argt(L
, idx
, LUA_TNUMBER
);
493 return (lua_Integer
)intV(&tmp
);
497 return (lua_Integer
)n
;
499 return lj_num2int(n
);
503 LUA_API
int lua_toboolean(lua_State
*L
, int idx
)
505 cTValue
*o
= index2adr(L
, idx
);
506 return tvistruecond(o
);
509 LUA_API
const char *lua_tolstring(lua_State
*L
, int idx
, size_t *len
)
511 TValue
*o
= index2adr(L
, idx
);
513 if (LJ_LIKELY(tvisstr(o
))) {
515 } else if (tvisnumber(o
)) {
517 o
= index2adr(L
, idx
); /* GC may move the stack. */
518 s
= lj_strfmt_number(L
, o
);
521 if (len
!= NULL
) *len
= 0;
524 if (len
!= NULL
) *len
= s
->len
;
528 LUALIB_API
const char *luaL_checklstring(lua_State
*L
, int idx
, size_t *len
)
530 TValue
*o
= index2adr(L
, idx
);
532 if (LJ_LIKELY(tvisstr(o
))) {
534 } else if (tvisnumber(o
)) {
536 o
= index2adr(L
, idx
); /* GC may move the stack. */
537 s
= lj_strfmt_number(L
, o
);
540 lj_err_argt(L
, idx
, LUA_TSTRING
);
542 if (len
!= NULL
) *len
= s
->len
;
546 LUALIB_API
const char *luaL_optlstring(lua_State
*L
, int idx
,
547 const char *def
, size_t *len
)
549 TValue
*o
= index2adr(L
, idx
);
551 if (LJ_LIKELY(tvisstr(o
))) {
553 } else if (tvisnil(o
)) {
554 if (len
!= NULL
) *len
= def
? strlen(def
) : 0;
556 } else if (tvisnumber(o
)) {
558 o
= index2adr(L
, idx
); /* GC may move the stack. */
559 s
= lj_strfmt_number(L
, o
);
562 lj_err_argt(L
, idx
, LUA_TSTRING
);
564 if (len
!= NULL
) *len
= s
->len
;
568 LUALIB_API
int luaL_checkoption(lua_State
*L
, int idx
, const char *def
,
569 const char *const lst
[])
572 const char *s
= lua_tolstring(L
, idx
, NULL
);
573 if (s
== NULL
&& (s
= def
) == NULL
)
574 lj_err_argt(L
, idx
, LUA_TSTRING
);
575 for (i
= 0; lst
[i
]; i
++)
576 if (strcmp(lst
[i
], s
) == 0)
578 lj_err_argv(L
, idx
, LJ_ERR_INVOPTM
, s
);
581 LUA_API
size_t lua_objlen(lua_State
*L
, int idx
)
583 TValue
*o
= index2adr(L
, idx
);
586 } else if (tvistab(o
)) {
587 return (size_t)lj_tab_len(tabV(o
));
588 } else if (tvisudata(o
)) {
589 return udataV(o
)->len
;
590 } else if (tvisnumber(o
)) {
591 GCstr
*s
= lj_strfmt_number(L
, o
);
599 LUA_API lua_CFunction
lua_tocfunction(lua_State
*L
, int idx
)
601 cTValue
*o
= index2adr(L
, idx
);
603 BCOp op
= bc_op(*mref(funcV(o
)->c
.pc
, BCIns
));
604 if (op
== BC_FUNCC
|| op
== BC_FUNCCW
)
605 return funcV(o
)->c
.f
;
610 LUA_API
void *lua_touserdata(lua_State
*L
, int idx
)
612 cTValue
*o
= index2adr(L
, idx
);
614 return uddata(udataV(o
));
615 else if (tvislightud(o
))
616 return lightudV(G(L
), o
);
621 LUA_API lua_State
*lua_tothread(lua_State
*L
, int idx
)
623 cTValue
*o
= index2adr(L
, idx
);
624 return (!tvisthread(o
)) ? NULL
: threadV(o
);
627 LUA_API
const void *lua_topointer(lua_State
*L
, int idx
)
629 return lj_obj_ptr(G(L
), index2adr(L
, idx
));
632 /* -- Stack setters (object creation) ------------------------------------- */
634 LUA_API
void lua_pushnil(lua_State
*L
)
640 LUA_API
void lua_pushnumber(lua_State
*L
, lua_Number n
)
643 if (LJ_UNLIKELY(tvisnan(L
->top
)))
644 setnanV(L
->top
); /* Canonicalize injected NaNs. */
648 LUA_API
void lua_pushinteger(lua_State
*L
, lua_Integer n
)
650 setintptrV(L
->top
, n
);
654 LUA_API
void lua_pushlstring(lua_State
*L
, const char *str
, size_t len
)
658 s
= lj_str_new(L
, str
, len
);
659 setstrV(L
, L
->top
, s
);
663 LUA_API
void lua_pushstring(lua_State
*L
, const char *str
)
670 s
= lj_str_newz(L
, str
);
671 setstrV(L
, L
->top
, s
);
676 LUA_API
const char *lua_pushvfstring(lua_State
*L
, const char *fmt
,
680 return lj_strfmt_pushvf(L
, fmt
, argp
);
683 LUA_API
const char *lua_pushfstring(lua_State
*L
, const char *fmt
, ...)
689 ret
= lj_strfmt_pushvf(L
, fmt
, argp
);
694 LUA_API
void lua_pushcclosure(lua_State
*L
, lua_CFunction f
, int n
)
699 fn
= lj_func_newC(L
, (MSize
)n
, getcurrenv(L
));
703 copyTV(L
, &fn
->c
.upvalue
[n
], L
->top
+n
);
704 setfuncV(L
, L
->top
, fn
);
705 lj_assertL(iswhite(obj2gco(fn
)), "new GC object is not white");
709 LUA_API
void lua_pushboolean(lua_State
*L
, int b
)
711 setboolV(L
->top
, (b
!= 0));
715 LUA_API
void lua_pushlightuserdata(lua_State
*L
, void *p
)
718 p
= lj_lightud_intern(L
, p
);
720 setrawlightudV(L
->top
, p
);
724 LUA_API
void lua_createtable(lua_State
*L
, int narray
, int nrec
)
727 settabV(L
, L
->top
, lj_tab_new_ah(L
, narray
, nrec
));
731 LUALIB_API
int luaL_newmetatable(lua_State
*L
, const char *tname
)
733 GCtab
*regt
= tabV(registry(L
));
734 TValue
*tv
= lj_tab_setstr(L
, regt
, lj_str_newz(L
, tname
));
736 GCtab
*mt
= lj_tab_new(L
, 0, 1);
738 settabV(L
, L
->top
++, mt
);
739 lj_gc_anybarriert(L
, regt
);
742 copyTV(L
, L
->top
++, tv
);
747 LUA_API
int lua_pushthread(lua_State
*L
)
749 setthreadV(L
, L
->top
, L
);
751 return (mainthread(G(L
)) == L
);
754 LUA_API lua_State
*lua_newthread(lua_State
*L
)
758 L1
= lj_state_new(L
);
759 setthreadV(L
, L
->top
, L1
);
764 LUA_API
void *lua_newuserdata(lua_State
*L
, size_t size
)
768 if (size
> LJ_MAX_UDATA
)
769 lj_err_msg(L
, LJ_ERR_UDATAOV
);
770 ud
= lj_udata_new(L
, (MSize
)size
, getcurrenv(L
));
771 setudataV(L
, L
->top
, ud
);
776 LUA_API
void lua_concat(lua_State
*L
, int n
)
782 TValue
*top
= lj_meta_cat(L
, L
->top
-1, -n
);
787 n
-= (int)(L
->top
- (top
- 2*LJ_FR2
));
789 lj_vm_call(L
, top
, 1+1);
791 copyTV(L
, L
->top
-1, L
->top
+LJ_FR2
);
793 } else if (n
== 0) { /* Push empty string. */
794 setstrV(L
, L
->top
, &G(L
)->strempty
);
797 /* else n == 1: nothing to do. */
800 /* -- Object getters ------------------------------------------------------ */
802 LUA_API
void lua_gettable(lua_State
*L
, int idx
)
804 cTValue
*t
= index2adr_check(L
, idx
);
805 cTValue
*v
= lj_meta_tget(L
, t
, L
->top
-1);
808 lj_vm_call(L
, L
->top
-2, 1+1);
812 copyTV(L
, L
->top
-1, v
);
815 LUA_API
void lua_getfield(lua_State
*L
, int idx
, const char *k
)
817 cTValue
*v
, *t
= index2adr_check(L
, idx
);
819 setstrV(L
, &key
, lj_str_newz(L
, k
));
820 v
= lj_meta_tget(L
, t
, &key
);
823 lj_vm_call(L
, L
->top
-2, 1+1);
827 copyTV(L
, L
->top
, v
);
831 LUA_API
void lua_rawget(lua_State
*L
, int idx
)
833 cTValue
*t
= index2adr(L
, idx
);
834 lj_checkapi(tvistab(t
), "stack slot %d is not a table", idx
);
835 copyTV(L
, L
->top
-1, lj_tab_get(L
, tabV(t
), L
->top
-1));
838 LUA_API
void lua_rawgeti(lua_State
*L
, int idx
, int n
)
840 cTValue
*v
, *t
= index2adr(L
, idx
);
841 lj_checkapi(tvistab(t
), "stack slot %d is not a table", idx
);
842 v
= lj_tab_getint(tabV(t
), n
);
844 copyTV(L
, L
->top
, v
);
851 LUA_API
int lua_getmetatable(lua_State
*L
, int idx
)
853 cTValue
*o
= index2adr(L
, idx
);
856 mt
= tabref(tabV(o
)->metatable
);
857 else if (tvisudata(o
))
858 mt
= tabref(udataV(o
)->metatable
);
860 mt
= tabref(basemt_obj(G(L
), o
));
863 settabV(L
, L
->top
, mt
);
868 LUALIB_API
int luaL_getmetafield(lua_State
*L
, int idx
, const char *field
)
870 if (lua_getmetatable(L
, idx
)) {
871 cTValue
*tv
= lj_tab_getstr(tabV(L
->top
-1), lj_str_newz(L
, field
));
872 if (tv
&& !tvisnil(tv
)) {
873 copyTV(L
, L
->top
-1, tv
);
881 LUA_API
void lua_getfenv(lua_State
*L
, int idx
)
883 cTValue
*o
= index2adr_check(L
, idx
);
885 settabV(L
, L
->top
, tabref(funcV(o
)->c
.env
));
886 } else if (tvisudata(o
)) {
887 settabV(L
, L
->top
, tabref(udataV(o
)->env
));
888 } else if (tvisthread(o
)) {
889 settabV(L
, L
->top
, tabref(threadV(o
)->env
));
896 LUA_API
int lua_next(lua_State
*L
, int idx
)
898 cTValue
*t
= index2adr(L
, idx
);
900 lj_checkapi(tvistab(t
), "stack slot %d is not a table", idx
);
901 more
= lj_tab_next(tabV(t
), L
->top
-1, L
->top
-1);
903 incr_top(L
); /* Return new key and value slot. */
904 } else if (!more
) { /* End of traversal. */
905 L
->top
--; /* Remove key slot. */
907 lj_err_msg(L
, LJ_ERR_NEXTIDX
);
912 LUA_API
const char *lua_getupvalue(lua_State
*L
, int idx
, int n
)
916 const char *name
= lj_debug_uvnamev(index2adr(L
, idx
), (uint32_t)(n
-1), &val
, &o
);
918 copyTV(L
, L
->top
, val
);
924 LUA_API
void *lua_upvalueid(lua_State
*L
, int idx
, int n
)
926 GCfunc
*fn
= funcV(index2adr(L
, idx
));
928 lj_checkapi((uint32_t)n
< fn
->l
.nupvalues
, "bad upvalue %d", n
);
929 return isluafunc(fn
) ? (void *)gcref(fn
->l
.uvptr
[n
]) :
930 (void *)&fn
->c
.upvalue
[n
];
933 LUA_API
void lua_upvaluejoin(lua_State
*L
, int idx1
, int n1
, int idx2
, int n2
)
935 GCfunc
*fn1
= funcV(index2adr(L
, idx1
));
936 GCfunc
*fn2
= funcV(index2adr(L
, idx2
));
938 lj_checkapi(isluafunc(fn1
), "stack slot %d is not a Lua function", idx1
);
939 lj_checkapi(isluafunc(fn2
), "stack slot %d is not a Lua function", idx2
);
940 lj_checkapi((uint32_t)n1
< fn1
->l
.nupvalues
, "bad upvalue %d", n1
+1);
941 lj_checkapi((uint32_t)n2
< fn2
->l
.nupvalues
, "bad upvalue %d", n2
+1);
942 setgcrefr(fn1
->l
.uvptr
[n1
], fn2
->l
.uvptr
[n2
]);
943 lj_gc_objbarrier(L
, fn1
, gcref(fn1
->l
.uvptr
[n1
]));
946 LUALIB_API
void *luaL_testudata(lua_State
*L
, int idx
, const char *tname
)
948 cTValue
*o
= index2adr(L
, idx
);
950 GCudata
*ud
= udataV(o
);
951 cTValue
*tv
= lj_tab_getstr(tabV(registry(L
)), lj_str_newz(L
, tname
));
952 if (tv
&& tvistab(tv
) && tabV(tv
) == tabref(ud
->metatable
))
955 return NULL
; /* value is not a userdata with a metatable */
958 LUALIB_API
void *luaL_checkudata(lua_State
*L
, int idx
, const char *tname
)
960 void *p
= luaL_testudata(L
, idx
, tname
);
961 if (!p
) lj_err_argtype(L
, idx
, tname
);
965 /* -- Object setters ------------------------------------------------------ */
967 LUA_API
void lua_settable(lua_State
*L
, int idx
)
970 cTValue
*t
= index2adr_check(L
, idx
);
972 o
= lj_meta_tset(L
, t
, L
->top
-2);
974 /* NOBARRIER: lj_meta_tset ensures the table is not black. */
976 copyTV(L
, o
, L
->top
+1);
978 TValue
*base
= L
->top
;
979 copyTV(L
, base
+2, base
-3-2*LJ_FR2
);
981 lj_vm_call(L
, base
, 0+1);
986 LUA_API
void lua_setfield(lua_State
*L
, int idx
, const char *k
)
990 cTValue
*t
= index2adr_check(L
, idx
);
992 setstrV(L
, &key
, lj_str_newz(L
, k
));
993 o
= lj_meta_tset(L
, t
, &key
);
995 /* NOBARRIER: lj_meta_tset ensures the table is not black. */
996 copyTV(L
, o
, --L
->top
);
998 TValue
*base
= L
->top
;
999 copyTV(L
, base
+2, base
-3-2*LJ_FR2
);
1001 lj_vm_call(L
, base
, 0+1);
1006 LUA_API
void lua_rawset(lua_State
*L
, int idx
)
1008 GCtab
*t
= tabV(index2adr(L
, idx
));
1010 lj_checkapi_slot(2);
1012 dst
= lj_tab_set(L
, t
, key
);
1013 copyTV(L
, dst
, key
+1);
1014 lj_gc_anybarriert(L
, t
);
1018 LUA_API
void lua_rawseti(lua_State
*L
, int idx
, int n
)
1020 GCtab
*t
= tabV(index2adr(L
, idx
));
1022 lj_checkapi_slot(1);
1023 dst
= lj_tab_setint(L
, t
, n
);
1025 copyTV(L
, dst
, src
);
1026 lj_gc_barriert(L
, t
, dst
);
1030 LUA_API
int lua_setmetatable(lua_State
*L
, int idx
)
1034 cTValue
*o
= index2adr_check(L
, idx
);
1035 lj_checkapi_slot(1);
1036 if (tvisnil(L
->top
-1)) {
1039 lj_checkapi(tvistab(L
->top
-1), "top stack slot is not a table");
1040 mt
= tabV(L
->top
-1);
1044 setgcref(tabV(o
)->metatable
, obj2gco(mt
));
1046 lj_gc_objbarriert(L
, tabV(o
), mt
);
1047 } else if (tvisudata(o
)) {
1048 setgcref(udataV(o
)->metatable
, obj2gco(mt
));
1050 lj_gc_objbarrier(L
, udataV(o
), mt
);
1052 /* Flush cache, since traces specialize to basemt. But not during __gc. */
1053 if (lj_trace_flushall(L
))
1054 lj_err_caller(L
, LJ_ERR_NOGCMM
);
1055 o
= index2adr(L
, idx
); /* Stack may have been reallocated. */
1057 /* NOBARRIER: basemt is a GC root. */
1058 setgcref(basemt_it(g
, LJ_TTRUE
), obj2gco(mt
));
1059 setgcref(basemt_it(g
, LJ_TFALSE
), obj2gco(mt
));
1061 /* NOBARRIER: basemt is a GC root. */
1062 setgcref(basemt_obj(g
, o
), obj2gco(mt
));
1069 LUALIB_API
void luaL_setmetatable(lua_State
*L
, const char *tname
)
1071 lua_getfield(L
, LUA_REGISTRYINDEX
, tname
);
1072 lua_setmetatable(L
, -2);
1075 LUA_API
int lua_setfenv(lua_State
*L
, int idx
)
1077 cTValue
*o
= index2adr_check(L
, idx
);
1079 lj_checkapi_slot(1);
1080 lj_checkapi(tvistab(L
->top
-1), "top stack slot is not a table");
1083 setgcref(funcV(o
)->c
.env
, obj2gco(t
));
1084 } else if (tvisudata(o
)) {
1085 setgcref(udataV(o
)->env
, obj2gco(t
));
1086 } else if (tvisthread(o
)) {
1087 setgcref(threadV(o
)->env
, obj2gco(t
));
1092 lj_gc_objbarrier(L
, gcV(o
), t
);
1097 LUA_API
const char *lua_setupvalue(lua_State
*L
, int idx
, int n
)
1099 cTValue
*f
= index2adr(L
, idx
);
1103 lj_checkapi_slot(1);
1104 name
= lj_debug_uvnamev(f
, (uint32_t)(n
-1), &val
, &o
);
1107 copyTV(L
, val
, L
->top
);
1108 lj_gc_barrier(L
, o
, L
->top
);
1113 /* -- Calls --------------------------------------------------------------- */
1116 static TValue
*api_call_base(lua_State
*L
, int nargs
)
1118 TValue
*o
= L
->top
, *base
= o
- nargs
;
1120 for (; o
> base
; o
--) copyTV(L
, o
, o
-1);
1125 #define api_call_base(L, nargs) (L->top - (nargs))
1128 LUA_API
void lua_call(lua_State
*L
, int nargs
, int nresults
)
1130 lj_checkapi(L
->status
== LUA_OK
|| L
->status
== LUA_ERRERR
,
1131 "thread called in wrong state %d", L
->status
);
1132 lj_checkapi_slot(nargs
+1);
1133 lj_vm_call(L
, api_call_base(L
, nargs
), nresults
+1);
1136 LUA_API
int lua_pcall(lua_State
*L
, int nargs
, int nresults
, int errfunc
)
1138 global_State
*g
= G(L
);
1139 uint8_t oldh
= hook_save(g
);
1142 lj_checkapi(L
->status
== LUA_OK
|| L
->status
== LUA_ERRERR
,
1143 "thread called in wrong state %d", L
->status
);
1144 lj_checkapi_slot(nargs
+1);
1148 cTValue
*o
= index2adr_stack(L
, errfunc
);
1149 ef
= savestack(L
, o
);
1151 status
= lj_vm_pcall(L
, api_call_base(L
, nargs
), nresults
+1, ef
);
1152 if (status
) hook_restore(g
, oldh
);
1156 static TValue
*cpcall(lua_State
*L
, lua_CFunction func
, void *ud
)
1158 GCfunc
*fn
= lj_func_newC(L
, 0, getcurrenv(L
));
1159 TValue
*top
= L
->top
;
1161 setfuncV(L
, top
++, fn
);
1162 if (LJ_FR2
) setnilV(top
++);
1164 ud
= lj_lightud_intern(L
, ud
);
1166 setrawlightudV(top
++, ud
);
1167 cframe_nres(L
->cframe
) = 1+0; /* Zero results. */
1169 return top
-1; /* Now call the newly allocated C function. */
1172 LUA_API
int lua_cpcall(lua_State
*L
, lua_CFunction func
, void *ud
)
1174 global_State
*g
= G(L
);
1175 uint8_t oldh
= hook_save(g
);
1177 lj_checkapi(L
->status
== LUA_OK
|| L
->status
== LUA_ERRERR
,
1178 "thread called in wrong state %d", L
->status
);
1179 status
= lj_vm_cpcall(L
, func
, ud
, cpcall
);
1180 if (status
) hook_restore(g
, oldh
);
1184 LUALIB_API
int luaL_callmeta(lua_State
*L
, int idx
, const char *field
)
1186 if (luaL_getmetafield(L
, idx
, field
)) {
1187 TValue
*top
= L
->top
--;
1188 if (LJ_FR2
) setnilV(top
++);
1189 copyTV(L
, top
++, index2adr(L
, idx
));
1191 lj_vm_call(L
, top
-1, 1+1);
1197 /* -- Coroutine yield and resume ------------------------------------------ */
1199 LUA_API
int lua_isyieldable(lua_State
*L
)
1201 return cframe_canyield(L
->cframe
);
1204 LUA_API
int lua_yield(lua_State
*L
, int nresults
)
1206 void *cf
= L
->cframe
;
1207 global_State
*g
= G(L
);
1208 if (cframe_canyield(cf
)) {
1209 cf
= cframe_raw(cf
);
1210 if (!hook_active(g
)) { /* Regular yield: move results down if needed. */
1211 cTValue
*f
= L
->top
- nresults
;
1213 TValue
*t
= L
->base
;
1214 while (--nresults
>= 0) copyTV(L
, t
++, f
++);
1218 L
->status
= LUA_YIELD
;
1220 } else { /* Yield from hook: add a pseudo-frame. */
1221 TValue
*top
= L
->top
;
1223 (top
++)->u64
= cframe_multres(cf
);
1224 setcont(top
, lj_cont_hook
);
1226 setframe_pc(top
, cframe_pc(cf
)-1);
1228 setframe_gc(top
, obj2gco(L
), LJ_TTHREAD
);
1230 setframe_ftsz(top
, ((char *)(top
+1)-(char *)L
->base
)+FRAME_CONT
);
1231 L
->top
= L
->base
= top
+1;
1232 #if ((defined(__GNUC__) || defined(__clang__)) && (LJ_TARGET_X64 || defined(LUAJIT_UNWIND_EXTERNAL)) && !LJ_NO_UNWIND) || LJ_TARGET_WINDOWS
1233 lj_err_throw(L
, LUA_YIELD
);
1236 L
->status
= LUA_YIELD
;
1237 lj_vm_unwind_c(cf
, LUA_YIELD
);
1241 lj_err_msg(L
, LJ_ERR_CYIELD
);
1242 return 0; /* unreachable */
1245 LUA_API
int lua_resume(lua_State
*L
, int nargs
)
1247 if (L
->cframe
== NULL
&& L
->status
<= LUA_YIELD
)
1248 return lj_vm_resume(L
,
1249 L
->status
== LUA_OK
? api_call_base(L
, nargs
) : L
->top
- nargs
,
1252 setstrV(L
, L
->top
, lj_err_str(L
, LJ_ERR_COSUSP
));
1257 /* -- GC and memory management -------------------------------------------- */
1259 LUA_API
int lua_gc(lua_State
*L
, int what
, int data
)
1261 global_State
*g
= G(L
);
1265 g
->gc
.threshold
= LJ_MAX_MEM
;
1268 g
->gc
.threshold
= data
== -1 ? (g
->gc
.total
/100)*g
->gc
.pause
: g
->gc
.total
;
1274 res
= (int)(g
->gc
.total
>> 10);
1277 res
= (int)(g
->gc
.total
& 0x3ff);
1280 GCSize a
= (GCSize
)data
<< 10;
1281 g
->gc
.threshold
= (a
<= g
->gc
.total
) ? (g
->gc
.total
- a
) : 0;
1282 while (g
->gc
.total
>= g
->gc
.threshold
)
1283 if (lj_gc_step(L
) > 0) {
1289 case LUA_GCSETPAUSE
:
1290 res
= (int)(g
->gc
.pause
);
1291 g
->gc
.pause
= (MSize
)data
;
1293 case LUA_GCSETSTEPMUL
:
1294 res
= (int)(g
->gc
.stepmul
);
1295 g
->gc
.stepmul
= (MSize
)data
;
1297 case LUA_GCISRUNNING
:
1298 res
= (g
->gc
.threshold
!= LJ_MAX_MEM
);
1301 res
= -1; /* Invalid option. */
1306 LUA_API lua_Alloc
lua_getallocf(lua_State
*L
, void **ud
)
1308 global_State
*g
= G(L
);
1309 if (ud
) *ud
= g
->allocd
;
1313 LUA_API
void lua_setallocf(lua_State
*L
, lua_Alloc f
, void *ud
)
1315 global_State
*g
= G(L
);