OSX/iOS: Fix SDK incompatibility.
[luajit-2.0.git] / src / lj_api.c
blob1ad71678ef853efe1091bc4dda3ede0165c41ada
1 /*
2 ** Public Lua/C API.
3 ** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
4 **
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
7 */
9 #define lj_api_c
10 #define LUA_CORE
12 #include "lj_obj.h"
13 #include "lj_gc.h"
14 #include "lj_err.h"
15 #include "lj_debug.h"
16 #include "lj_str.h"
17 #include "lj_tab.h"
18 #include "lj_func.h"
19 #include "lj_udata.h"
20 #include "lj_meta.h"
21 #include "lj_state.h"
22 #include "lj_bc.h"
23 #include "lj_frame.h"
24 #include "lj_trace.h"
25 #include "lj_vm.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)
36 if (idx > 0) {
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);
42 return L->top + idx;
43 } else if (idx == LUA_GLOBALSINDEX) {
44 TValue *o = &G(L)->tmptv;
45 settabV(L, o, tabref(L->env));
46 return o;
47 } else if (idx == LUA_REGISTRYINDEX) {
48 return registry(L);
49 } else {
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));
56 return o;
57 } else {
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);
68 return o;
71 static TValue *index2adr_stack(lua_State *L, int idx)
73 if (idx > 0) {
74 TValue *o = L->base + (idx - 1);
75 if (o < L->top) {
76 return o;
77 } else {
78 lj_checkapi(0, "invalid stack slot %d", idx);
79 return niltv(L);
81 return o < L->top ? o : niltv(L);
82 } else {
83 lj_checkapi(idx != 0 && -idx <= L->top - L->base,
84 "invalid stack slot %d", idx);
85 return L->top + 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)
99 return L->status;
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);
108 if (size > avail &&
109 lj_state_cpgrowstack(L, (MSize)(size - avail)) != LUA_OK) {
110 L->top--;
111 return 0; /* Out of memory. */
114 return 1;
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)
125 TValue *f, *t;
126 if (L == to) return;
127 lj_checkapi_slot(n);
128 lj_checkapi(G(L) == G(to), "move across global states");
129 lj_state_checkstack(to, (MSize)n);
130 f = L->top;
131 t = to->top = to->top + n;
132 while (--n >= 0) copyTV(to, --t, --f);
133 L->top = f;
136 LUA_API const lua_Number *lua_version(lua_State *L)
138 static const lua_Number version = LUA_VERSION_NUM;
139 UNUSED(L);
140 return &version;
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)
152 if (idx >= 0) {
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);
158 } else {
159 L->top = L->base + idx;
161 } else {
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);
171 L->top--;
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);
194 } else {
195 TValue *o = index2adr_check(L, idx);
196 copyTV(L, o, f);
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)
204 lj_checkapi_slot(1);
205 copy_slot(L, L->top - 1, idx);
206 L->top--;
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));
217 incr_top(L);
220 /* -- Stack getters ------------------------------------------------------- */
222 LUA_API int lua_type(lua_State *L, int idx)
224 cTValue *o = index2adr(L, idx);
225 if (tvisnumber(o)) {
226 return LUA_TNUMBER;
227 #if LJ_64 && !LJ_GC64
228 } else if (tvislightud(o)) {
229 return LUA_TLIGHTUSERDATA;
230 #endif
231 } else if (o == niltv(L)) {
232 return LUA_TNONE;
233 } else { /* Magic internal/external tag conversion. ORDER LJ_T */
234 uint32_t t = ~itype(o);
235 #if LJ_64
236 int tt = (int)((U64x(75a06,98042110) >> 4*t) & 15u);
237 #else
238 int tt = (int)(((t < 8 ? 0x98042110u : 0x75a06u) >> 4*(t&7)) & 15u);
239 #endif
240 lj_assertL(tt != LUA_TNIL || tvisnil(o), "bad tag conversion");
241 return tt;
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)
259 UNUSED(L);
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);
272 TValue tmp;
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)) {
304 return 0;
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;
310 #endif
311 } else if (gcrefeq(o1->gcr, o2->gcr)) {
312 return 1;
313 } else if (!tvistabud(o1)) {
314 return 0;
315 } else {
316 TValue *base = lj_meta_equal(L, gcV(o1), gcV(o2), 0);
317 if ((uintptr_t)base <= 1) {
318 return (int)(uintptr_t)base;
319 } else {
320 L->top = base+2;
321 lj_vm_call(L, base, 1+1);
322 L->top -= 2+LJ_FR2;
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)) {
333 return 0;
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);
338 } else {
339 TValue *base = lj_meta_comp(L, o1, o2, 0);
340 if ((uintptr_t)base <= 1) {
341 return (int)(uintptr_t)base;
342 } else {
343 L->top = base+2;
344 lj_vm_call(L, base, 1+1);
345 L->top -= 2+LJ_FR2;
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);
354 TValue tmp;
355 if (LJ_LIKELY(tvisnumber(o)))
356 return numberVnum(o);
357 else if (tvisstr(o) && lj_strscan_num(strV(o), &tmp))
358 return numV(&tmp);
359 else
360 return 0;
363 LUA_API lua_Number lua_tonumberx(lua_State *L, int idx, int *ok)
365 cTValue *o = index2adr(L, idx);
366 TValue tmp;
367 if (LJ_LIKELY(tvisnumber(o))) {
368 if (ok) *ok = 1;
369 return numberVnum(o);
370 } else if (tvisstr(o) && lj_strscan_num(strV(o), &tmp)) {
371 if (ok) *ok = 1;
372 return numV(&tmp);
373 } else {
374 if (ok) *ok = 0;
375 return 0;
379 LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx)
381 cTValue *o = index2adr(L, idx);
382 TValue tmp;
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);
387 return numV(&tmp);
390 LUALIB_API lua_Number luaL_optnumber(lua_State *L, int idx, lua_Number def)
392 cTValue *o = index2adr(L, idx);
393 TValue tmp;
394 if (LJ_LIKELY(tvisnumber(o)))
395 return numberVnum(o);
396 else if (tvisnil(o))
397 return def;
398 else if (!(tvisstr(o) && lj_strscan_num(strV(o), &tmp)))
399 lj_err_argt(L, idx, LUA_TNUMBER);
400 return numV(&tmp);
403 LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
405 cTValue *o = index2adr(L, idx);
406 TValue tmp;
407 lua_Number n;
408 if (LJ_LIKELY(tvisint(o))) {
409 return intV(o);
410 } else if (LJ_LIKELY(tvisnum(o))) {
411 n = numV(o);
412 } else {
413 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
414 return 0;
415 if (tvisint(&tmp))
416 return intV(&tmp);
417 n = numV(&tmp);
419 #if LJ_64
420 return (lua_Integer)n;
421 #else
422 return lj_num2int(n);
423 #endif
426 LUA_API lua_Integer lua_tointegerx(lua_State *L, int idx, int *ok)
428 cTValue *o = index2adr(L, idx);
429 TValue tmp;
430 lua_Number n;
431 if (LJ_LIKELY(tvisint(o))) {
432 if (ok) *ok = 1;
433 return intV(o);
434 } else if (LJ_LIKELY(tvisnum(o))) {
435 n = numV(o);
436 } else {
437 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp))) {
438 if (ok) *ok = 0;
439 return 0;
441 if (tvisint(&tmp)) {
442 if (ok) *ok = 1;
443 return intV(&tmp);
445 n = numV(&tmp);
447 if (ok) *ok = 1;
448 #if LJ_64
449 return (lua_Integer)n;
450 #else
451 return lj_num2int(n);
452 #endif
455 LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx)
457 cTValue *o = index2adr(L, idx);
458 TValue tmp;
459 lua_Number n;
460 if (LJ_LIKELY(tvisint(o))) {
461 return intV(o);
462 } else if (LJ_LIKELY(tvisnum(o))) {
463 n = numV(o);
464 } else {
465 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
466 lj_err_argt(L, idx, LUA_TNUMBER);
467 if (tvisint(&tmp))
468 return (lua_Integer)intV(&tmp);
469 n = numV(&tmp);
471 #if LJ_64
472 return (lua_Integer)n;
473 #else
474 return lj_num2int(n);
475 #endif
478 LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int idx, lua_Integer def)
480 cTValue *o = index2adr(L, idx);
481 TValue tmp;
482 lua_Number n;
483 if (LJ_LIKELY(tvisint(o))) {
484 return intV(o);
485 } else if (LJ_LIKELY(tvisnum(o))) {
486 n = numV(o);
487 } else if (tvisnil(o)) {
488 return def;
489 } else {
490 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
491 lj_err_argt(L, idx, LUA_TNUMBER);
492 if (tvisint(&tmp))
493 return (lua_Integer)intV(&tmp);
494 n = numV(&tmp);
496 #if LJ_64
497 return (lua_Integer)n;
498 #else
499 return lj_num2int(n);
500 #endif
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);
512 GCstr *s;
513 if (LJ_LIKELY(tvisstr(o))) {
514 s = strV(o);
515 } else if (tvisnumber(o)) {
516 lj_gc_check(L);
517 o = index2adr(L, idx); /* GC may move the stack. */
518 s = lj_strfmt_number(L, o);
519 setstrV(L, o, s);
520 } else {
521 if (len != NULL) *len = 0;
522 return NULL;
524 if (len != NULL) *len = s->len;
525 return strdata(s);
528 LUALIB_API const char *luaL_checklstring(lua_State *L, int idx, size_t *len)
530 TValue *o = index2adr(L, idx);
531 GCstr *s;
532 if (LJ_LIKELY(tvisstr(o))) {
533 s = strV(o);
534 } else if (tvisnumber(o)) {
535 lj_gc_check(L);
536 o = index2adr(L, idx); /* GC may move the stack. */
537 s = lj_strfmt_number(L, o);
538 setstrV(L, o, s);
539 } else {
540 lj_err_argt(L, idx, LUA_TSTRING);
542 if (len != NULL) *len = s->len;
543 return strdata(s);
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);
550 GCstr *s;
551 if (LJ_LIKELY(tvisstr(o))) {
552 s = strV(o);
553 } else if (tvisnil(o)) {
554 if (len != NULL) *len = def ? strlen(def) : 0;
555 return def;
556 } else if (tvisnumber(o)) {
557 lj_gc_check(L);
558 o = index2adr(L, idx); /* GC may move the stack. */
559 s = lj_strfmt_number(L, o);
560 setstrV(L, o, s);
561 } else {
562 lj_err_argt(L, idx, LUA_TSTRING);
564 if (len != NULL) *len = s->len;
565 return strdata(s);
568 LUALIB_API int luaL_checkoption(lua_State *L, int idx, const char *def,
569 const char *const lst[])
571 ptrdiff_t i;
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)
577 return (int)i;
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);
584 if (tvisstr(o)) {
585 return strV(o)->len;
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);
592 setstrV(L, o, s);
593 return s->len;
594 } else {
595 return 0;
599 LUA_API lua_CFunction lua_tocfunction(lua_State *L, int idx)
601 cTValue *o = index2adr(L, idx);
602 if (tvisfunc(o)) {
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;
607 return NULL;
610 LUA_API void *lua_touserdata(lua_State *L, int idx)
612 cTValue *o = index2adr(L, idx);
613 if (tvisudata(o))
614 return uddata(udataV(o));
615 else if (tvislightud(o))
616 return lightudV(G(L), o);
617 else
618 return NULL;
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)
636 setnilV(L->top);
637 incr_top(L);
640 LUA_API void lua_pushnumber(lua_State *L, lua_Number n)
642 setnumV(L->top, n);
643 if (LJ_UNLIKELY(tvisnan(L->top)))
644 setnanV(L->top); /* Canonicalize injected NaNs. */
645 incr_top(L);
648 LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
650 setintptrV(L->top, n);
651 incr_top(L);
654 LUA_API void lua_pushlstring(lua_State *L, const char *str, size_t len)
656 GCstr *s;
657 lj_gc_check(L);
658 s = lj_str_new(L, str, len);
659 setstrV(L, L->top, s);
660 incr_top(L);
663 LUA_API void lua_pushstring(lua_State *L, const char *str)
665 if (str == NULL) {
666 setnilV(L->top);
667 } else {
668 GCstr *s;
669 lj_gc_check(L);
670 s = lj_str_newz(L, str);
671 setstrV(L, L->top, s);
673 incr_top(L);
676 LUA_API const char *lua_pushvfstring(lua_State *L, const char *fmt,
677 va_list argp)
679 lj_gc_check(L);
680 return lj_strfmt_pushvf(L, fmt, argp);
683 LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...)
685 const char *ret;
686 va_list argp;
687 lj_gc_check(L);
688 va_start(argp, fmt);
689 ret = lj_strfmt_pushvf(L, fmt, argp);
690 va_end(argp);
691 return ret;
694 LUA_API void lua_pushcclosure(lua_State *L, lua_CFunction f, int n)
696 GCfunc *fn;
697 lj_gc_check(L);
698 lj_checkapi_slot(n);
699 fn = lj_func_newC(L, (MSize)n, getcurrenv(L));
700 fn->c.f = f;
701 L->top -= n;
702 while (n--)
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");
706 incr_top(L);
709 LUA_API void lua_pushboolean(lua_State *L, int b)
711 setboolV(L->top, (b != 0));
712 incr_top(L);
715 LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
717 #if LJ_64
718 p = lj_lightud_intern(L, p);
719 #endif
720 setrawlightudV(L->top, p);
721 incr_top(L);
724 LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
726 lj_gc_check(L);
727 settabV(L, L->top, lj_tab_new_ah(L, narray, nrec));
728 incr_top(L);
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));
735 if (tvisnil(tv)) {
736 GCtab *mt = lj_tab_new(L, 0, 1);
737 settabV(L, tv, mt);
738 settabV(L, L->top++, mt);
739 lj_gc_anybarriert(L, regt);
740 return 1;
741 } else {
742 copyTV(L, L->top++, tv);
743 return 0;
747 LUA_API int lua_pushthread(lua_State *L)
749 setthreadV(L, L->top, L);
750 incr_top(L);
751 return (mainthread(G(L)) == L);
754 LUA_API lua_State *lua_newthread(lua_State *L)
756 lua_State *L1;
757 lj_gc_check(L);
758 L1 = lj_state_new(L);
759 setthreadV(L, L->top, L1);
760 incr_top(L);
761 return L1;
764 LUA_API void *lua_newuserdata(lua_State *L, size_t size)
766 GCudata *ud;
767 lj_gc_check(L);
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);
772 incr_top(L);
773 return uddata(ud);
776 LUA_API void lua_concat(lua_State *L, int n)
778 lj_checkapi_slot(n);
779 if (n >= 2) {
780 n--;
781 do {
782 TValue *top = lj_meta_cat(L, L->top-1, -n);
783 if (top == NULL) {
784 L->top -= n;
785 break;
787 n -= (int)(L->top - (top - 2*LJ_FR2));
788 L->top = top+2;
789 lj_vm_call(L, top, 1+1);
790 L->top -= 1+LJ_FR2;
791 copyTV(L, L->top-1, L->top+LJ_FR2);
792 } while (--n > 0);
793 } else if (n == 0) { /* Push empty string. */
794 setstrV(L, L->top, &G(L)->strempty);
795 incr_top(L);
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);
806 if (v == NULL) {
807 L->top += 2;
808 lj_vm_call(L, L->top-2, 1+1);
809 L->top -= 2+LJ_FR2;
810 v = L->top+1+LJ_FR2;
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);
818 TValue key;
819 setstrV(L, &key, lj_str_newz(L, k));
820 v = lj_meta_tget(L, t, &key);
821 if (v == NULL) {
822 L->top += 2;
823 lj_vm_call(L, L->top-2, 1+1);
824 L->top -= 2+LJ_FR2;
825 v = L->top+1+LJ_FR2;
827 copyTV(L, L->top, v);
828 incr_top(L);
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);
843 if (v) {
844 copyTV(L, L->top, v);
845 } else {
846 setnilV(L->top);
848 incr_top(L);
851 LUA_API int lua_getmetatable(lua_State *L, int idx)
853 cTValue *o = index2adr(L, idx);
854 GCtab *mt = NULL;
855 if (tvistab(o))
856 mt = tabref(tabV(o)->metatable);
857 else if (tvisudata(o))
858 mt = tabref(udataV(o)->metatable);
859 else
860 mt = tabref(basemt_obj(G(L), o));
861 if (mt == NULL)
862 return 0;
863 settabV(L, L->top, mt);
864 incr_top(L);
865 return 1;
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);
874 return 1;
876 L->top--;
878 return 0;
881 LUA_API void lua_getfenv(lua_State *L, int idx)
883 cTValue *o = index2adr_check(L, idx);
884 if (tvisfunc(o)) {
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));
890 } else {
891 setnilV(L->top);
893 incr_top(L);
896 LUA_API int lua_next(lua_State *L, int idx)
898 cTValue *t = index2adr(L, idx);
899 int more;
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);
902 if (more > 0) {
903 incr_top(L); /* Return new key and value slot. */
904 } else if (!more) { /* End of traversal. */
905 L->top--; /* Remove key slot. */
906 } else {
907 lj_err_msg(L, LJ_ERR_NEXTIDX);
909 return more;
912 LUA_API const char *lua_getupvalue(lua_State *L, int idx, int n)
914 TValue *val;
915 GCobj *o;
916 const char *name = lj_debug_uvnamev(index2adr(L, idx), (uint32_t)(n-1), &val, &o);
917 if (name) {
918 copyTV(L, L->top, val);
919 incr_top(L);
921 return name;
924 LUA_API void *lua_upvalueid(lua_State *L, int idx, int n)
926 GCfunc *fn = funcV(index2adr(L, idx));
927 n--;
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));
937 n1--; n2--;
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);
949 if (tvisudata(o)) {
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))
953 return uddata(ud);
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);
962 return p;
965 /* -- Object setters ------------------------------------------------------ */
967 LUA_API void lua_settable(lua_State *L, int idx)
969 TValue *o;
970 cTValue *t = index2adr_check(L, idx);
971 lj_checkapi_slot(2);
972 o = lj_meta_tset(L, t, L->top-2);
973 if (o) {
974 /* NOBARRIER: lj_meta_tset ensures the table is not black. */
975 L->top -= 2;
976 copyTV(L, o, L->top+1);
977 } else {
978 TValue *base = L->top;
979 copyTV(L, base+2, base-3-2*LJ_FR2);
980 L->top = base+3;
981 lj_vm_call(L, base, 0+1);
982 L->top -= 3+LJ_FR2;
986 LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
988 TValue *o;
989 TValue key;
990 cTValue *t = index2adr_check(L, idx);
991 lj_checkapi_slot(1);
992 setstrV(L, &key, lj_str_newz(L, k));
993 o = lj_meta_tset(L, t, &key);
994 if (o) {
995 /* NOBARRIER: lj_meta_tset ensures the table is not black. */
996 copyTV(L, o, --L->top);
997 } else {
998 TValue *base = L->top;
999 copyTV(L, base+2, base-3-2*LJ_FR2);
1000 L->top = base+3;
1001 lj_vm_call(L, base, 0+1);
1002 L->top -= 2+LJ_FR2;
1006 LUA_API void lua_rawset(lua_State *L, int idx)
1008 GCtab *t = tabV(index2adr(L, idx));
1009 TValue *dst, *key;
1010 lj_checkapi_slot(2);
1011 key = L->top-2;
1012 dst = lj_tab_set(L, t, key);
1013 copyTV(L, dst, key+1);
1014 lj_gc_anybarriert(L, t);
1015 L->top = key;
1018 LUA_API void lua_rawseti(lua_State *L, int idx, int n)
1020 GCtab *t = tabV(index2adr(L, idx));
1021 TValue *dst, *src;
1022 lj_checkapi_slot(1);
1023 dst = lj_tab_setint(L, t, n);
1024 src = L->top-1;
1025 copyTV(L, dst, src);
1026 lj_gc_barriert(L, t, dst);
1027 L->top = src;
1030 LUA_API int lua_setmetatable(lua_State *L, int idx)
1032 global_State *g;
1033 GCtab *mt;
1034 cTValue *o = index2adr_check(L, idx);
1035 lj_checkapi_slot(1);
1036 if (tvisnil(L->top-1)) {
1037 mt = NULL;
1038 } else {
1039 lj_checkapi(tvistab(L->top-1), "top stack slot is not a table");
1040 mt = tabV(L->top-1);
1042 g = G(L);
1043 if (tvistab(o)) {
1044 setgcref(tabV(o)->metatable, obj2gco(mt));
1045 if (mt)
1046 lj_gc_objbarriert(L, tabV(o), mt);
1047 } else if (tvisudata(o)) {
1048 setgcref(udataV(o)->metatable, obj2gco(mt));
1049 if (mt)
1050 lj_gc_objbarrier(L, udataV(o), mt);
1051 } else {
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. */
1056 if (tvisbool(o)) {
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));
1060 } else {
1061 /* NOBARRIER: basemt is a GC root. */
1062 setgcref(basemt_obj(g, o), obj2gco(mt));
1065 L->top--;
1066 return 1;
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);
1078 GCtab *t;
1079 lj_checkapi_slot(1);
1080 lj_checkapi(tvistab(L->top-1), "top stack slot is not a table");
1081 t = tabV(L->top-1);
1082 if (tvisfunc(o)) {
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));
1088 } else {
1089 L->top--;
1090 return 0;
1092 lj_gc_objbarrier(L, gcV(o), t);
1093 L->top--;
1094 return 1;
1097 LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n)
1099 cTValue *f = index2adr(L, idx);
1100 TValue *val;
1101 GCobj *o;
1102 const char *name;
1103 lj_checkapi_slot(1);
1104 name = lj_debug_uvnamev(f, (uint32_t)(n-1), &val, &o);
1105 if (name) {
1106 L->top--;
1107 copyTV(L, val, L->top);
1108 lj_gc_barrier(L, o, L->top);
1110 return name;
1113 /* -- Calls --------------------------------------------------------------- */
1115 #if LJ_FR2
1116 static TValue *api_call_base(lua_State *L, int nargs)
1118 TValue *o = L->top, *base = o - nargs;
1119 L->top = o+1;
1120 for (; o > base; o--) copyTV(L, o, o-1);
1121 setnilV(o);
1122 return o+1;
1124 #else
1125 #define api_call_base(L, nargs) (L->top - (nargs))
1126 #endif
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);
1140 ptrdiff_t ef;
1141 int status;
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);
1145 if (errfunc == 0) {
1146 ef = 0;
1147 } else {
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);
1153 return status;
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;
1160 fn->c.f = func;
1161 setfuncV(L, top++, fn);
1162 if (LJ_FR2) setnilV(top++);
1163 #if LJ_64
1164 ud = lj_lightud_intern(L, ud);
1165 #endif
1166 setrawlightudV(top++, ud);
1167 cframe_nres(L->cframe) = 1+0; /* Zero results. */
1168 L->top = top;
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);
1176 int status;
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);
1181 return status;
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));
1190 L->top = top;
1191 lj_vm_call(L, top-1, 1+1);
1192 return 1;
1194 return 0;
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;
1212 if (f > L->base) {
1213 TValue *t = L->base;
1214 while (--nresults >= 0) copyTV(L, t++, f++);
1215 L->top = t;
1217 L->cframe = NULL;
1218 L->status = LUA_YIELD;
1219 return -1;
1220 } else { /* Yield from hook: add a pseudo-frame. */
1221 TValue *top = L->top;
1222 hook_leave(g);
1223 (top++)->u64 = cframe_multres(cf);
1224 setcont(top, lj_cont_hook);
1225 if (LJ_FR2) top++;
1226 setframe_pc(top, cframe_pc(cf)-1);
1227 top++;
1228 setframe_gc(top, obj2gco(L), LJ_TTHREAD);
1229 if (LJ_FR2) top++;
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);
1234 #else
1235 L->cframe = NULL;
1236 L->status = LUA_YIELD;
1237 lj_vm_unwind_c(cf, LUA_YIELD);
1238 #endif
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,
1250 0, 0);
1251 L->top = L->base;
1252 setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP));
1253 incr_top(L);
1254 return LUA_ERRRUN;
1257 /* -- GC and memory management -------------------------------------------- */
1259 LUA_API int lua_gc(lua_State *L, int what, int data)
1261 global_State *g = G(L);
1262 int res = 0;
1263 switch (what) {
1264 case LUA_GCSTOP:
1265 g->gc.threshold = LJ_MAX_MEM;
1266 break;
1267 case LUA_GCRESTART:
1268 g->gc.threshold = data == -1 ? (g->gc.total/100)*g->gc.pause : g->gc.total;
1269 break;
1270 case LUA_GCCOLLECT:
1271 lj_gc_fullgc(L);
1272 break;
1273 case LUA_GCCOUNT:
1274 res = (int)(g->gc.total >> 10);
1275 break;
1276 case LUA_GCCOUNTB:
1277 res = (int)(g->gc.total & 0x3ff);
1278 break;
1279 case LUA_GCSTEP: {
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) {
1284 res = 1;
1285 break;
1287 break;
1289 case LUA_GCSETPAUSE:
1290 res = (int)(g->gc.pause);
1291 g->gc.pause = (MSize)data;
1292 break;
1293 case LUA_GCSETSTEPMUL:
1294 res = (int)(g->gc.stepmul);
1295 g->gc.stepmul = (MSize)data;
1296 break;
1297 case LUA_GCISRUNNING:
1298 res = (g->gc.threshold != LJ_MAX_MEM);
1299 break;
1300 default:
1301 res = -1; /* Invalid option. */
1303 return res;
1306 LUA_API lua_Alloc lua_getallocf(lua_State *L, void **ud)
1308 global_State *g = G(L);
1309 if (ud) *ud = g->allocd;
1310 return g->allocf;
1313 LUA_API void lua_setallocf(lua_State *L, lua_Alloc f, void *ud)
1315 global_State *g = G(L);
1316 g->allocd = ud;
1317 g->allocf = f;