1/*
2** Public Lua/C API.
3** Copyright (C) 2005-2021 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*/
8
9#define lj_api_c
10#define LUA_CORE
11
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"
28
29/* -- Common helper functions --------------------------------------------- */
30
31#define lj_checkapi_slot(idx) \
32 lj_checkapi((idx) <= (L->top - L->base), "stack slot %d out of range", (idx))
33
34static TValue *index2adr(lua_State *L, int idx)
35{
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);
60 }
61 }
62}
63
64static LJ_AINLINE TValue *index2adr_check(lua_State *L, int idx)
65{
66 TValue *o = index2adr(L, idx);
67 lj_checkapi(o != niltv(L), "invalid stack slot %d", idx);
68 return o;
69}
70
71static TValue *index2adr_stack(lua_State *L, int idx)
72{
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);
80 }
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;
86 }
87}
88
89static GCtab *getcurrenv(lua_State *L)
90{
91 GCfunc *fn = curr_func(L);
92 return fn->c.gct == ~LJ_TFUNC ? tabref(fn->c.env) : tabref(L->env);
93}
94
95/* -- Miscellaneous API functions ----------------------------------------- */
96
97LUA_API int lua_status(lua_State *L)
98{
99 return L->status;
100}
101
102LUA_API int lua_checkstack(lua_State *L, int size)
103{
104 if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) {
105 return 0; /* Stack overflow. */
106 } else if (size > 0) {
107 lj_state_checkstack(L, (MSize)size);
108 }
109 return 1;
110}
111
112LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
113{
114 if (!lua_checkstack(L, size))
115 lj_err_callerv(L, LJ_ERR_STKOVM, msg);
116}
117
118LUA_API void lua_xmove(lua_State *L, lua_State *to, int n)
119{
120 TValue *f, *t;
121 if (L == to) return;
122 lj_checkapi_slot(n);
123 lj_checkapi(G(L) == G(to), "move across global states");
124 lj_state_checkstack(to, (MSize)n);
125 f = L->top;
126 t = to->top = to->top + n;
127 while (--n >= 0) copyTV(to, --t, --f);
128 L->top = f;
129}
130
131LUA_API const lua_Number *lua_version(lua_State *L)
132{
133 static const lua_Number version = LUA_VERSION_NUM;
134 UNUSED(L);
135 return &version;
136}
137
138/* -- Stack manipulation -------------------------------------------------- */
139
140LUA_API int lua_gettop(lua_State *L)
141{
142 return (int)(L->top - L->base);
143}
144
145LUA_API void lua_settop(lua_State *L, int idx)
146{
147 if (idx >= 0) {
148 lj_checkapi(idx <= tvref(L->maxstack) - L->base, "bad stack slot %d", idx);
149 if (L->base + idx > L->top) {
150 if (L->base + idx >= tvref(L->maxstack))
151 lj_state_growstack(L, (MSize)idx - (MSize)(L->top - L->base));
152 do { setnilV(L->top++); } while (L->top < L->base + idx);
153 } else {
154 L->top = L->base + idx;
155 }
156 } else {
157 lj_checkapi(-(idx+1) <= (L->top - L->base), "bad stack slot %d", idx);
158 L->top += idx+1; /* Shrinks top (idx < 0). */
159 }
160}
161
162LUA_API void lua_remove(lua_State *L, int idx)
163{
164 TValue *p = index2adr_stack(L, idx);
165 while (++p < L->top) copyTV(L, p-1, p);
166 L->top--;
167}
168
169LUA_API void lua_insert(lua_State *L, int idx)
170{
171 TValue *q, *p = index2adr_stack(L, idx);
172 for (q = L->top; q > p; q--) copyTV(L, q, q-1);
173 copyTV(L, p, L->top);
174}
175
176static void copy_slot(lua_State *L, TValue *f, int idx)
177{
178 if (idx == LUA_GLOBALSINDEX) {
179 lj_checkapi(tvistab(f), "stack slot %d is not a table", idx);
180 /* NOBARRIER: A thread (i.e. L) is never black. */
181 setgcref(L->env, obj2gco(tabV(f)));
182 } else if (idx == LUA_ENVIRONINDEX) {
183 GCfunc *fn = curr_func(L);
184 if (fn->c.gct != ~LJ_TFUNC)
185 lj_err_msg(L, LJ_ERR_NOENV);
186 lj_checkapi(tvistab(f), "stack slot %d is not a table", idx);
187 setgcref(fn->c.env, obj2gco(tabV(f)));
188 lj_gc_barrier(L, fn, f);
189 } else {
190 TValue *o = index2adr_check(L, idx);
191 copyTV(L, o, f);
192 if (idx < LUA_GLOBALSINDEX) /* Need a barrier for upvalues. */
193 lj_gc_barrier(L, curr_func(L), f);
194 }
195}
196
197LUA_API void lua_replace(lua_State *L, int idx)
198{
199 lj_checkapi_slot(1);
200 copy_slot(L, L->top - 1, idx);
201 L->top--;
202}
203
204LUA_API void lua_copy(lua_State *L, int fromidx, int toidx)
205{
206 copy_slot(L, index2adr(L, fromidx), toidx);
207}
208
209LUA_API void lua_pushvalue(lua_State *L, int idx)
210{
211 copyTV(L, L->top, index2adr(L, idx));
212 incr_top(L);
213}
214
215/* -- Stack getters ------------------------------------------------------- */
216
217LUA_API int lua_type(lua_State *L, int idx)
218{
219 cTValue *o = index2adr(L, idx);
220 if (tvisnumber(o)) {
221 return LUA_TNUMBER;
222#if LJ_64 && !LJ_GC64
223 } else if (tvislightud(o)) {
224 return LUA_TLIGHTUSERDATA;
225#endif
226 } else if (o == niltv(L)) {
227 return LUA_TNONE;
228 } else { /* Magic internal/external tag conversion. ORDER LJ_T */
229 uint32_t t = ~itype(o);
230#if LJ_64
231 int tt = (int)((U64x(75a06,98042110) >> 4*t) & 15u);
232#else
233 int tt = (int)(((t < 8 ? 0x98042110u : 0x75a06u) >> 4*(t&7)) & 15u);
234#endif
235 lj_assertL(tt != LUA_TNIL || tvisnil(o), "bad tag conversion");
236 return tt;
237 }
238}
239
240LUALIB_API void luaL_checktype(lua_State *L, int idx, int tt)
241{
242 if (lua_type(L, idx) != tt)
243 lj_err_argt(L, idx, tt);
244}
245
246LUALIB_API void luaL_checkany(lua_State *L, int idx)
247{
248 if (index2adr(L, idx) == niltv(L))
249 lj_err_arg(L, idx, LJ_ERR_NOVAL);
250}
251
252LUA_API const char *lua_typename(lua_State *L, int t)
253{
254 UNUSED(L);
255 return lj_obj_typename[t+1];
256}
257
258LUA_API int lua_iscfunction(lua_State *L, int idx)
259{
260 cTValue *o = index2adr(L, idx);
261 return tvisfunc(o) && !isluafunc(funcV(o));
262}
263
264LUA_API int lua_isnumber(lua_State *L, int idx)
265{
266 cTValue *o = index2adr(L, idx);
267 TValue tmp;
268 return (tvisnumber(o) || (tvisstr(o) && lj_strscan_number(strV(o), &tmp)));
269}
270
271LUA_API int lua_isstring(lua_State *L, int idx)
272{
273 cTValue *o = index2adr(L, idx);
274 return (tvisstr(o) || tvisnumber(o));
275}
276
277LUA_API int lua_isuserdata(lua_State *L, int idx)
278{
279 cTValue *o = index2adr(L, idx);
280 return (tvisudata(o) || tvislightud(o));
281}
282
283LUA_API int lua_rawequal(lua_State *L, int idx1, int idx2)
284{
285 cTValue *o1 = index2adr(L, idx1);
286 cTValue *o2 = index2adr(L, idx2);
287 return (o1 == niltv(L) || o2 == niltv(L)) ? 0 : lj_obj_equal(o1, o2);
288}
289
290LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
291{
292 cTValue *o1 = index2adr(L, idx1);
293 cTValue *o2 = index2adr(L, idx2);
294 if (tvisint(o1) && tvisint(o2)) {
295 return intV(o1) == intV(o2);
296 } else if (tvisnumber(o1) && tvisnumber(o2)) {
297 return numberVnum(o1) == numberVnum(o2);
298 } else if (itype(o1) != itype(o2)) {
299 return 0;
300 } else if (tvispri(o1)) {
301 return o1 != niltv(L) && o2 != niltv(L);
302#if LJ_64 && !LJ_GC64
303 } else if (tvislightud(o1)) {
304 return o1->u64 == o2->u64;
305#endif
306 } else if (gcrefeq(o1->gcr, o2->gcr)) {
307 return 1;
308 } else if (!tvistabud(o1)) {
309 return 0;
310 } else {
311 TValue *base = lj_meta_equal(L, gcV(o1), gcV(o2), 0);
312 if ((uintptr_t)base <= 1) {
313 return (int)(uintptr_t)base;
314 } else {
315 L->top = base+2;
316 lj_vm_call(L, base, 1+1);
317 L->top -= 2+LJ_FR2;
318 return tvistruecond(L->top+1+LJ_FR2);
319 }
320 }
321}
322
323LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2)
324{
325 cTValue *o1 = index2adr(L, idx1);
326 cTValue *o2 = index2adr(L, idx2);
327 if (o1 == niltv(L) || o2 == niltv(L)) {
328 return 0;
329 } else if (tvisint(o1) && tvisint(o2)) {
330 return intV(o1) < intV(o2);
331 } else if (tvisnumber(o1) && tvisnumber(o2)) {
332 return numberVnum(o1) < numberVnum(o2);
333 } else {
334 TValue *base = lj_meta_comp(L, o1, o2, 0);
335 if ((uintptr_t)base <= 1) {
336 return (int)(uintptr_t)base;
337 } else {
338 L->top = base+2;
339 lj_vm_call(L, base, 1+1);
340 L->top -= 2+LJ_FR2;
341 return tvistruecond(L->top+1+LJ_FR2);
342 }
343 }
344}
345
346LUA_API lua_Number lua_tonumber(lua_State *L, int idx)
347{
348 cTValue *o = index2adr(L, idx);
349 TValue tmp;
350 if (LJ_LIKELY(tvisnumber(o)))
351 return numberVnum(o);
352 else if (tvisstr(o) && lj_strscan_num(strV(o), &tmp))
353 return numV(&tmp);
354 else
355 return 0;
356}
357
358LUA_API lua_Number lua_tonumberx(lua_State *L, int idx, int *ok)
359{
360 cTValue *o = index2adr(L, idx);
361 TValue tmp;
362 if (LJ_LIKELY(tvisnumber(o))) {
363 if (ok) *ok = 1;
364 return numberVnum(o);
365 } else if (tvisstr(o) && lj_strscan_num(strV(o), &tmp)) {
366 if (ok) *ok = 1;
367 return numV(&tmp);
368 } else {
369 if (ok) *ok = 0;
370 return 0;
371 }
372}
373
374LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx)
375{
376 cTValue *o = index2adr(L, idx);
377 TValue tmp;
378 if (LJ_LIKELY(tvisnumber(o)))
379 return numberVnum(o);
380 else if (!(tvisstr(o) && lj_strscan_num(strV(o), &tmp)))
381 lj_err_argt(L, idx, LUA_TNUMBER);
382 return numV(&tmp);
383}
384
385LUALIB_API lua_Number luaL_optnumber(lua_State *L, int idx, lua_Number def)
386{
387 cTValue *o = index2adr(L, idx);
388 TValue tmp;
389 if (LJ_LIKELY(tvisnumber(o)))
390 return numberVnum(o);
391 else if (tvisnil(o))
392 return def;
393 else if (!(tvisstr(o) && lj_strscan_num(strV(o), &tmp)))
394 lj_err_argt(L, idx, LUA_TNUMBER);
395 return numV(&tmp);
396}
397
398LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
399{
400 cTValue *o = index2adr(L, idx);
401 TValue tmp;
402 lua_Number n;
403 if (LJ_LIKELY(tvisint(o))) {
404 return intV(o);
405 } else if (LJ_LIKELY(tvisnum(o))) {
406 n = numV(o);
407 } else {
408 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
409 return 0;
410 if (tvisint(&tmp))
411 return intV(&tmp);
412 n = numV(&tmp);
413 }
414#if LJ_64
415 return (lua_Integer)n;
416#else
417 return lj_num2int(n);
418#endif
419}
420
421LUA_API lua_Integer lua_tointegerx(lua_State *L, int idx, int *ok)
422{
423 cTValue *o = index2adr(L, idx);
424 TValue tmp;
425 lua_Number n;
426 if (LJ_LIKELY(tvisint(o))) {
427 if (ok) *ok = 1;
428 return intV(o);
429 } else if (LJ_LIKELY(tvisnum(o))) {
430 n = numV(o);
431 } else {
432 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp))) {
433 if (ok) *ok = 0;
434 return 0;
435 }
436 if (tvisint(&tmp)) {
437 if (ok) *ok = 1;
438 return intV(&tmp);
439 }
440 n = numV(&tmp);
441 }
442 if (ok) *ok = 1;
443#if LJ_64
444 return (lua_Integer)n;
445#else
446 return lj_num2int(n);
447#endif
448}
449
450LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx)
451{
452 cTValue *o = index2adr(L, idx);
453 TValue tmp;
454 lua_Number n;
455 if (LJ_LIKELY(tvisint(o))) {
456 return intV(o);
457 } else if (LJ_LIKELY(tvisnum(o))) {
458 n = numV(o);
459 } else {
460 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
461 lj_err_argt(L, idx, LUA_TNUMBER);
462 if (tvisint(&tmp))
463 return (lua_Integer)intV(&tmp);
464 n = numV(&tmp);
465 }
466#if LJ_64
467 return (lua_Integer)n;
468#else
469 return lj_num2int(n);
470#endif
471}
472
473LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int idx, lua_Integer def)
474{
475 cTValue *o = index2adr(L, idx);
476 TValue tmp;
477 lua_Number n;
478 if (LJ_LIKELY(tvisint(o))) {
479 return intV(o);
480 } else if (LJ_LIKELY(tvisnum(o))) {
481 n = numV(o);
482 } else if (tvisnil(o)) {
483 return def;
484 } else {
485 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
486 lj_err_argt(L, idx, LUA_TNUMBER);
487 if (tvisint(&tmp))
488 return (lua_Integer)intV(&tmp);
489 n = numV(&tmp);
490 }
491#if LJ_64
492 return (lua_Integer)n;
493#else
494 return lj_num2int(n);
495#endif
496}
497
498LUA_API int lua_toboolean(lua_State *L, int idx)
499{
500 cTValue *o = index2adr(L, idx);
501 return tvistruecond(o);
502}
503
504LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len)
505{
506 TValue *o = index2adr(L, idx);
507 GCstr *s;
508 if (LJ_LIKELY(tvisstr(o))) {
509 s = strV(o);
510 } else if (tvisnumber(o)) {
511 lj_gc_check(L);
512 o = index2adr(L, idx); /* GC may move the stack. */
513 s = lj_strfmt_number(L, o);
514 setstrV(L, o, s);
515 } else {
516 if (len != NULL) *len = 0;
517 return NULL;
518 }
519 if (len != NULL) *len = s->len;
520 return strdata(s);
521}
522
523LUALIB_API const char *luaL_checklstring(lua_State *L, int idx, size_t *len)
524{
525 TValue *o = index2adr(L, idx);
526 GCstr *s;
527 if (LJ_LIKELY(tvisstr(o))) {
528 s = strV(o);
529 } else if (tvisnumber(o)) {
530 lj_gc_check(L);
531 o = index2adr(L, idx); /* GC may move the stack. */
532 s = lj_strfmt_number(L, o);
533 setstrV(L, o, s);
534 } else {
535 lj_err_argt(L, idx, LUA_TSTRING);
536 }
537 if (len != NULL) *len = s->len;
538 return strdata(s);
539}
540
541LUALIB_API const char *luaL_optlstring(lua_State *L, int idx,
542 const char *def, size_t *len)
543{
544 TValue *o = index2adr(L, idx);
545 GCstr *s;
546 if (LJ_LIKELY(tvisstr(o))) {
547 s = strV(o);
548 } else if (tvisnil(o)) {
549 if (len != NULL) *len = def ? strlen(def) : 0;
550 return def;
551 } else if (tvisnumber(o)) {
552 lj_gc_check(L);
553 o = index2adr(L, idx); /* GC may move the stack. */
554 s = lj_strfmt_number(L, o);
555 setstrV(L, o, s);
556 } else {
557 lj_err_argt(L, idx, LUA_TSTRING);
558 }
559 if (len != NULL) *len = s->len;
560 return strdata(s);
561}
562
563LUALIB_API int luaL_checkoption(lua_State *L, int idx, const char *def,
564 const char *const lst[])
565{
566 ptrdiff_t i;
567 const char *s = lua_tolstring(L, idx, NULL);
568 if (s == NULL && (s = def) == NULL)
569 lj_err_argt(L, idx, LUA_TSTRING);
570 for (i = 0; lst[i]; i++)
571 if (strcmp(lst[i], s) == 0)
572 return (int)i;
573 lj_err_argv(L, idx, LJ_ERR_INVOPTM, s);
574}
575
576LUA_API size_t lua_objlen(lua_State *L, int idx)
577{
578 TValue *o = index2adr(L, idx);
579 if (tvisstr(o)) {
580 return strV(o)->len;
581 } else if (tvistab(o)) {
582 return (size_t)lj_tab_len(tabV(o));
583 } else if (tvisudata(o)) {
584 return udataV(o)->len;
585 } else if (tvisnumber(o)) {
586 GCstr *s = lj_strfmt_number(L, o);
587 setstrV(L, o, s);
588 return s->len;
589 } else {
590 return 0;
591 }
592}
593
594LUA_API lua_CFunction lua_tocfunction(lua_State *L, int idx)
595{
596 cTValue *o = index2adr(L, idx);
597 if (tvisfunc(o)) {
598 BCOp op = bc_op(*mref(funcV(o)->c.pc, BCIns));
599 if (op == BC_FUNCC || op == BC_FUNCCW)
600 return funcV(o)->c.f;
601 }
602 return NULL;
603}
604
605LUA_API void *lua_touserdata(lua_State *L, int idx)
606{
607 cTValue *o = index2adr(L, idx);
608 if (tvisudata(o))
609 return uddata(udataV(o));
610 else if (tvislightud(o))
611 return lightudV(G(L), o);
612 else
613 return NULL;
614}
615
616LUA_API lua_State *lua_tothread(lua_State *L, int idx)
617{
618 cTValue *o = index2adr(L, idx);
619 return (!tvisthread(o)) ? NULL : threadV(o);
620}
621
622LUA_API const void *lua_topointer(lua_State *L, int idx)
623{
624 return lj_obj_ptr(G(L), index2adr(L, idx));
625}
626
627/* -- Stack setters (object creation) ------------------------------------- */
628
629LUA_API void lua_pushnil(lua_State *L)
630{
631 setnilV(L->top);
632 incr_top(L);
633}
634
635LUA_API void lua_pushnumber(lua_State *L, lua_Number n)
636{
637 setnumV(L->top, n);
638 if (LJ_UNLIKELY(tvisnan(L->top)))
639 setnanV(L->top); /* Canonicalize injected NaNs. */
640 incr_top(L);
641}
642
643LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
644{
645 setintptrV(L->top, n);
646 incr_top(L);
647}
648
649LUA_API void lua_pushlstring(lua_State *L, const char *str, size_t len)
650{
651 GCstr *s;
652 lj_gc_check(L);
653 s = lj_str_new(L, str, len);
654 setstrV(L, L->top, s);
655 incr_top(L);
656}
657
658LUA_API void lua_pushstring(lua_State *L, const char *str)
659{
660 if (str == NULL) {
661 setnilV(L->top);
662 } else {
663 GCstr *s;
664 lj_gc_check(L);
665 s = lj_str_newz(L, str);
666 setstrV(L, L->top, s);
667 }
668 incr_top(L);
669}
670
671LUA_API const char *lua_pushvfstring(lua_State *L, const char *fmt,
672 va_list argp)
673{
674 lj_gc_check(L);
675 return lj_strfmt_pushvf(L, fmt, argp);
676}
677
678LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...)
679{
680 const char *ret;
681 va_list argp;
682 lj_gc_check(L);
683 va_start(argp, fmt);
684 ret = lj_strfmt_pushvf(L, fmt, argp);
685 va_end(argp);
686 return ret;
687}
688
689LUA_API void lua_pushcclosure(lua_State *L, lua_CFunction f, int n)
690{
691 GCfunc *fn;
692 lj_gc_check(L);
693 lj_checkapi_slot(n);
694 fn = lj_func_newC(L, (MSize)n, getcurrenv(L));
695 fn->c.f = f;
696 L->top -= n;
697 while (n--)
698 copyTV(L, &fn->c.upvalue[n], L->top+n);
699 setfuncV(L, L->top, fn);
700 lj_assertL(iswhite(obj2gco(fn)), "new GC object is not white");
701 incr_top(L);
702}
703
704LUA_API void lua_pushboolean(lua_State *L, int b)
705{
706 setboolV(L->top, (b != 0));
707 incr_top(L);
708}
709
710LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
711{
712#if LJ_64
713 p = lj_lightud_intern(L, p);
714#endif
715 setrawlightudV(L->top, p);
716 incr_top(L);
717}
718
719LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
720{
721 lj_gc_check(L);
722 settabV(L, L->top, lj_tab_new_ah(L, narray, nrec));
723 incr_top(L);
724}
725
726LUALIB_API int luaL_newmetatable(lua_State *L, const char *tname)
727{
728 GCtab *regt = tabV(registry(L));
729 TValue *tv = lj_tab_setstr(L, regt, lj_str_newz(L, tname));
730 if (tvisnil(tv)) {
731 GCtab *mt = lj_tab_new(L, 0, 1);
732 settabV(L, tv, mt);
733 settabV(L, L->top++, mt);
734 lj_gc_anybarriert(L, regt);
735 return 1;
736 } else {
737 copyTV(L, L->top++, tv);
738 return 0;
739 }
740}
741
742LUA_API int lua_pushthread(lua_State *L)
743{
744 setthreadV(L, L->top, L);
745 incr_top(L);
746 return (mainthread(G(L)) == L);
747}
748
749LUA_API lua_State *lua_newthread(lua_State *L)
750{
751 lua_State *L1;
752 lj_gc_check(L);
753 L1 = lj_state_new(L);
754 setthreadV(L, L->top, L1);
755 incr_top(L);
756 return L1;
757}
758
759LUA_API void *lua_newuserdata(lua_State *L, size_t size)
760{
761 GCudata *ud;
762 lj_gc_check(L);
763 if (size > LJ_MAX_UDATA)
764 lj_err_msg(L, LJ_ERR_UDATAOV);
765 ud = lj_udata_new(L, (MSize)size, getcurrenv(L));
766 setudataV(L, L->top, ud);
767 incr_top(L);
768 return uddata(ud);
769}
770
771LUA_API void lua_concat(lua_State *L, int n)
772{
773 lj_checkapi_slot(n);
774 if (n >= 2) {
775 n--;
776 do {
777 TValue *top = lj_meta_cat(L, L->top-1, -n);
778 if (top == NULL) {
779 L->top -= n;
780 break;
781 }
782 n -= (int)(L->top - top);
783 L->top = top+2;
784 lj_vm_call(L, top, 1+1);
785 L->top -= 1+LJ_FR2;
786 copyTV(L, L->top-1, L->top+LJ_FR2);
787 } while (--n > 0);
788 } else if (n == 0) { /* Push empty string. */
789 setstrV(L, L->top, &G(L)->strempty);
790 incr_top(L);
791 }
792 /* else n == 1: nothing to do. */
793}
794
795/* -- Object getters ------------------------------------------------------ */
796
797LUA_API void lua_gettable(lua_State *L, int idx)
798{
799 cTValue *t = index2adr_check(L, idx);
800 cTValue *v = lj_meta_tget(L, t, L->top-1);
801 if (v == NULL) {
802 L->top += 2;
803 lj_vm_call(L, L->top-2, 1+1);
804 L->top -= 2+LJ_FR2;
805 v = L->top+1+LJ_FR2;
806 }
807 copyTV(L, L->top-1, v);
808}
809
810LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
811{
812 cTValue *v, *t = index2adr_check(L, idx);
813 TValue key;
814 setstrV(L, &key, lj_str_newz(L, k));
815 v = lj_meta_tget(L, t, &key);
816 if (v == NULL) {
817 L->top += 2;
818 lj_vm_call(L, L->top-2, 1+1);
819 L->top -= 2+LJ_FR2;
820 v = L->top+1+LJ_FR2;
821 }
822 copyTV(L, L->top, v);
823 incr_top(L);
824}
825
826LUA_API void lua_rawget(lua_State *L, int idx)
827{
828 cTValue *t = index2adr(L, idx);
829 lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
830 copyTV(L, L->top-1, lj_tab_get(L, tabV(t), L->top-1));
831}
832
833LUA_API void lua_rawgeti(lua_State *L, int idx, int n)
834{
835 cTValue *v, *t = index2adr(L, idx);
836 lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
837 v = lj_tab_getint(tabV(t), n);
838 if (v) {
839 copyTV(L, L->top, v);
840 } else {
841 setnilV(L->top);
842 }
843 incr_top(L);
844}
845
846LUA_API int lua_getmetatable(lua_State *L, int idx)
847{
848 cTValue *o = index2adr(L, idx);
849 GCtab *mt = NULL;
850 if (tvistab(o))
851 mt = tabref(tabV(o)->metatable);
852 else if (tvisudata(o))
853 mt = tabref(udataV(o)->metatable);
854 else
855 mt = tabref(basemt_obj(G(L), o));
856 if (mt == NULL)
857 return 0;
858 settabV(L, L->top, mt);
859 incr_top(L);
860 return 1;
861}
862
863LUALIB_API int luaL_getmetafield(lua_State *L, int idx, const char *field)
864{
865 if (lua_getmetatable(L, idx)) {
866 cTValue *tv = lj_tab_getstr(tabV(L->top-1), lj_str_newz(L, field));
867 if (tv && !tvisnil(tv)) {
868 copyTV(L, L->top-1, tv);
869 return 1;
870 }
871 L->top--;
872 }
873 return 0;
874}
875
876LUA_API void lua_getfenv(lua_State *L, int idx)
877{
878 cTValue *o = index2adr_check(L, idx);
879 if (tvisfunc(o)) {
880 settabV(L, L->top, tabref(funcV(o)->c.env));
881 } else if (tvisudata(o)) {
882 settabV(L, L->top, tabref(udataV(o)->env));
883 } else if (tvisthread(o)) {
884 settabV(L, L->top, tabref(threadV(o)->env));
885 } else {
886 setnilV(L->top);
887 }
888 incr_top(L);
889}
890
891LUA_API int lua_next(lua_State *L, int idx)
892{
893 cTValue *t = index2adr(L, idx);
894 int more;
895 lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
896 more = lj_tab_next(L, tabV(t), L->top-1);
897 if (more) {
898 incr_top(L); /* Return new key and value slot. */
899 } else { /* End of traversal. */
900 L->top--; /* Remove key slot. */
901 }
902 return more;
903}
904
905LUA_API const char *lua_getupvalue(lua_State *L, int idx, int n)
906{
907 TValue *val;
908 GCobj *o;
909 const char *name = lj_debug_uvnamev(index2adr(L, idx), (uint32_t)(n-1), &val, &o);
910 if (name) {
911 copyTV(L, L->top, val);
912 incr_top(L);
913 }
914 return name;
915}
916
917LUA_API void *lua_upvalueid(lua_State *L, int idx, int n)
918{
919 GCfunc *fn = funcV(index2adr(L, idx));
920 n--;
921 lj_checkapi((uint32_t)n < fn->l.nupvalues, "bad upvalue %d", n);
922 return isluafunc(fn) ? (void *)gcref(fn->l.uvptr[n]) :
923 (void *)&fn->c.upvalue[n];
924}
925
926LUA_API void lua_upvaluejoin(lua_State *L, int idx1, int n1, int idx2, int n2)
927{
928 GCfunc *fn1 = funcV(index2adr(L, idx1));
929 GCfunc *fn2 = funcV(index2adr(L, idx2));
930 n1--; n2--;
931 lj_checkapi(isluafunc(fn1), "stack slot %d is not a Lua function", idx1);
932 lj_checkapi(isluafunc(fn2), "stack slot %d is not a Lua function", idx2);
933 lj_checkapi((uint32_t)n1 < fn1->l.nupvalues, "bad upvalue %d", n1+1);
934 lj_checkapi((uint32_t)n2 < fn2->l.nupvalues, "bad upvalue %d", n2+1);
935 setgcrefr(fn1->l.uvptr[n1], fn2->l.uvptr[n2]);
936 lj_gc_objbarrier(L, fn1, gcref(fn1->l.uvptr[n1]));
937}
938
939LUALIB_API void *luaL_testudata(lua_State *L, int idx, const char *tname)
940{
941 cTValue *o = index2adr(L, idx);
942 if (tvisudata(o)) {
943 GCudata *ud = udataV(o);
944 cTValue *tv = lj_tab_getstr(tabV(registry(L)), lj_str_newz(L, tname));
945 if (tv && tvistab(tv) && tabV(tv) == tabref(ud->metatable))
946 return uddata(ud);
947 }
948 return NULL; /* value is not a userdata with a metatable */
949}
950
951LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
952{
953 void *p = luaL_testudata(L, idx, tname);
954 if (!p) lj_err_argtype(L, idx, tname);
955 return p;
956}
957
958/* -- Object setters ------------------------------------------------------ */
959
960LUA_API void lua_settable(lua_State *L, int idx)
961{
962 TValue *o;
963 cTValue *t = index2adr_check(L, idx);
964 lj_checkapi_slot(2);
965 o = lj_meta_tset(L, t, L->top-2);
966 if (o) {
967 /* NOBARRIER: lj_meta_tset ensures the table is not black. */
968 L->top -= 2;
969 copyTV(L, o, L->top+1);
970 } else {
971 TValue *base = L->top;
972 copyTV(L, base+2, base-3-2*LJ_FR2);
973 L->top = base+3;
974 lj_vm_call(L, base, 0+1);
975 L->top -= 3+LJ_FR2;
976 }
977}
978
979LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
980{
981 TValue *o;
982 TValue key;
983 cTValue *t = index2adr_check(L, idx);
984 lj_checkapi_slot(1);
985 setstrV(L, &key, lj_str_newz(L, k));
986 o = lj_meta_tset(L, t, &key);
987 if (o) {
988 /* NOBARRIER: lj_meta_tset ensures the table is not black. */
989 copyTV(L, o, --L->top);
990 } else {
991 TValue *base = L->top;
992 copyTV(L, base+2, base-3-2*LJ_FR2);
993 L->top = base+3;
994 lj_vm_call(L, base, 0+1);
995 L->top -= 2+LJ_FR2;
996 }
997}
998
999LUA_API void lua_rawset(lua_State *L, int idx)
1000{
1001 GCtab *t = tabV(index2adr(L, idx));
1002 TValue *dst, *key;
1003 lj_checkapi_slot(2);
1004 key = L->top-2;
1005 dst = lj_tab_set(L, t, key);
1006 copyTV(L, dst, key+1);
1007 lj_gc_anybarriert(L, t);
1008 L->top = key;
1009}
1010
1011LUA_API void lua_rawseti(lua_State *L, int idx, int n)
1012{
1013 GCtab *t = tabV(index2adr(L, idx));
1014 TValue *dst, *src;
1015 lj_checkapi_slot(1);
1016 dst = lj_tab_setint(L, t, n);
1017 src = L->top-1;
1018 copyTV(L, dst, src);
1019 lj_gc_barriert(L, t, dst);
1020 L->top = src;
1021}
1022
1023LUA_API int lua_setmetatable(lua_State *L, int idx)
1024{
1025 global_State *g;
1026 GCtab *mt;
1027 cTValue *o = index2adr_check(L, idx);
1028 lj_checkapi_slot(1);
1029 if (tvisnil(L->top-1)) {
1030 mt = NULL;
1031 } else {
1032 lj_checkapi(tvistab(L->top-1), "top stack slot is not a table");
1033 mt = tabV(L->top-1);
1034 }
1035 g = G(L);
1036 if (tvistab(o)) {
1037 setgcref(tabV(o)->metatable, obj2gco(mt));
1038 if (mt)
1039 lj_gc_objbarriert(L, tabV(o), mt);
1040 } else if (tvisudata(o)) {
1041 setgcref(udataV(o)->metatable, obj2gco(mt));
1042 if (mt)
1043 lj_gc_objbarrier(L, udataV(o), mt);
1044 } else {
1045 /* Flush cache, since traces specialize to basemt. But not during __gc. */
1046 if (lj_trace_flushall(L))
1047 lj_err_caller(L, LJ_ERR_NOGCMM);
1048 if (tvisbool(o)) {
1049 /* NOBARRIER: basemt is a GC root. */
1050 setgcref(basemt_it(g, LJ_TTRUE), obj2gco(mt));
1051 setgcref(basemt_it(g, LJ_TFALSE), obj2gco(mt));
1052 } else {
1053 /* NOBARRIER: basemt is a GC root. */
1054 setgcref(basemt_obj(g, o), obj2gco(mt));
1055 }
1056 }
1057 L->top--;
1058 return 1;
1059}
1060
1061LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
1062{
1063 lua_getfield(L, LUA_REGISTRYINDEX, tname);
1064 lua_setmetatable(L, -2);
1065}
1066
1067LUA_API int lua_setfenv(lua_State *L, int idx)
1068{
1069 cTValue *o = index2adr_check(L, idx);
1070 GCtab *t;
1071 lj_checkapi_slot(1);
1072 lj_checkapi(tvistab(L->top-1), "top stack slot is not a table");
1073 t = tabV(L->top-1);
1074 if (tvisfunc(o)) {
1075 setgcref(funcV(o)->c.env, obj2gco(t));
1076 } else if (tvisudata(o)) {
1077 setgcref(udataV(o)->env, obj2gco(t));
1078 } else if (tvisthread(o)) {
1079 setgcref(threadV(o)->env, obj2gco(t));
1080 } else {
1081 L->top--;
1082 return 0;
1083 }
1084 lj_gc_objbarrier(L, gcV(o), t);
1085 L->top--;
1086 return 1;
1087}
1088
1089LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n)
1090{
1091 cTValue *f = index2adr(L, idx);
1092 TValue *val;
1093 GCobj *o;
1094 const char *name;
1095 lj_checkapi_slot(1);
1096 name = lj_debug_uvnamev(f, (uint32_t)(n-1), &val, &o);
1097 if (name) {
1098 L->top--;
1099 copyTV(L, val, L->top);
1100 lj_gc_barrier(L, o, L->top);
1101 }
1102 return name;
1103}
1104
1105/* -- Calls --------------------------------------------------------------- */
1106
1107#if LJ_FR2
1108static TValue *api_call_base(lua_State *L, int nargs)
1109{
1110 TValue *o = L->top, *base = o - nargs;
1111 L->top = o+1;
1112 for (; o > base; o--) copyTV(L, o, o-1);
1113 setnilV(o);
1114 return o+1;
1115}
1116#else
1117#define api_call_base(L, nargs) (L->top - (nargs))
1118#endif
1119
1120LUA_API void lua_call(lua_State *L, int nargs, int nresults)
1121{
1122 lj_checkapi(L->status == LUA_OK || L->status == LUA_ERRERR,
1123 "thread called in wrong state %d", L->status);
1124 lj_checkapi_slot(nargs+1);
1125 lj_vm_call(L, api_call_base(L, nargs), nresults+1);
1126}
1127
1128LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
1129{
1130 global_State *g = G(L);
1131 uint8_t oldh = hook_save(g);
1132 ptrdiff_t ef;
1133 int status;
1134 lj_checkapi(L->status == LUA_OK || L->status == LUA_ERRERR,
1135 "thread called in wrong state %d", L->status);
1136 lj_checkapi_slot(nargs+1);
1137 if (errfunc == 0) {
1138 ef = 0;
1139 } else {
1140 cTValue *o = index2adr_stack(L, errfunc);
1141 ef = savestack(L, o);
1142 }
1143 status = lj_vm_pcall(L, api_call_base(L, nargs), nresults+1, ef);
1144 if (status) hook_restore(g, oldh);
1145 return status;
1146}
1147
1148static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud)
1149{
1150 GCfunc *fn = lj_func_newC(L, 0, getcurrenv(L));
1151 TValue *top = L->top;
1152 fn->c.f = func;
1153 setfuncV(L, top++, fn);
1154 if (LJ_FR2) setnilV(top++);
1155#if LJ_64
1156 ud = lj_lightud_intern(L, ud);
1157#endif
1158 setrawlightudV(top++, ud);
1159 cframe_nres(L->cframe) = 1+0; /* Zero results. */
1160 L->top = top;
1161 return top-1; /* Now call the newly allocated C function. */
1162}
1163
1164LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
1165{
1166 global_State *g = G(L);
1167 uint8_t oldh = hook_save(g);
1168 int status;
1169 lj_checkapi(L->status == LUA_OK || L->status == LUA_ERRERR,
1170 "thread called in wrong state %d", L->status);
1171 status = lj_vm_cpcall(L, func, ud, cpcall);
1172 if (status) hook_restore(g, oldh);
1173 return status;
1174}
1175
1176LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
1177{
1178 if (luaL_getmetafield(L, idx, field)) {
1179 TValue *top = L->top--;
1180 if (LJ_FR2) setnilV(top++);
1181 copyTV(L, top++, index2adr(L, idx));
1182 L->top = top;
1183 lj_vm_call(L, top-1, 1+1);
1184 return 1;
1185 }
1186 return 0;
1187}
1188
1189/* -- Coroutine yield and resume ------------------------------------------ */
1190
1191LUA_API int lua_isyieldable(lua_State *L)
1192{
1193 return cframe_canyield(L->cframe);
1194}
1195
1196LUA_API int lua_yield(lua_State *L, int nresults)
1197{
1198 void *cf = L->cframe;
1199 global_State *g = G(L);
1200 if (cframe_canyield(cf)) {
1201 cf = cframe_raw(cf);
1202 if (!hook_active(g)) { /* Regular yield: move results down if needed. */
1203 cTValue *f = L->top - nresults;
1204 if (f > L->base) {
1205 TValue *t = L->base;
1206 while (--nresults >= 0) copyTV(L, t++, f++);
1207 L->top = t;
1208 }
1209 L->cframe = NULL;
1210 L->status = LUA_YIELD;
1211 return -1;
1212 } else { /* Yield from hook: add a pseudo-frame. */
1213 TValue *top = L->top;
1214 hook_leave(g);
1215 (top++)->u64 = cframe_multres(cf);
1216 setcont(top, lj_cont_hook);
1217 if (LJ_FR2) top++;
1218 setframe_pc(top, cframe_pc(cf)-1);
1219 top++;
1220 setframe_gc(top, obj2gco(L), LJ_TTHREAD);
1221 if (LJ_FR2) top++;
1222 setframe_ftsz(top, ((char *)(top+1)-(char *)L->base)+FRAME_CONT);
1223 L->top = L->base = top+1;
1224#if ((defined(__GNUC__) || defined(__clang__)) && (LJ_TARGET_X64 || defined(LUAJIT_UNWIND_EXTERNAL)) && !LJ_NO_UNWIND) || LJ_TARGET_WINDOWS
1225 lj_err_throw(L, LUA_YIELD);
1226#else
1227 L->cframe = NULL;
1228 L->status = LUA_YIELD;
1229 lj_vm_unwind_c(cf, LUA_YIELD);
1230#endif
1231 }
1232 }
1233 lj_err_msg(L, LJ_ERR_CYIELD);
1234 return 0; /* unreachable */
1235}
1236
1237LUA_API int lua_resume(lua_State *L, int nargs)
1238{
1239 if (L->cframe == NULL && L->status <= LUA_YIELD)
1240 return lj_vm_resume(L,
1241 L->status == LUA_OK ? api_call_base(L, nargs) : L->top - nargs,
1242 0, 0);
1243 L->top = L->base;
1244 setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP));
1245 incr_top(L);
1246 return LUA_ERRRUN;
1247}
1248
1249/* -- GC and memory management -------------------------------------------- */
1250
1251LUA_API int lua_gc(lua_State *L, int what, int data)
1252{
1253 global_State *g = G(L);
1254 int res = 0;
1255 switch (what) {
1256 case LUA_GCSTOP:
1257 g->gc.threshold = LJ_MAX_MEM;
1258 break;
1259 case LUA_GCRESTART:
1260 g->gc.threshold = data == -1 ? (g->gc.total/100)*g->gc.pause : g->gc.total;
1261 break;
1262 case LUA_GCCOLLECT:
1263 lj_gc_fullgc(L);
1264 break;
1265 case LUA_GCCOUNT:
1266 res = (int)(g->gc.total >> 10);
1267 break;
1268 case LUA_GCCOUNTB:
1269 res = (int)(g->gc.total & 0x3ff);
1270 break;
1271 case LUA_GCSTEP: {
1272 GCSize a = (GCSize)data << 10;
1273 g->gc.threshold = (a <= g->gc.total) ? (g->gc.total - a) : 0;
1274 while (g->gc.total >= g->gc.threshold)
1275 if (lj_gc_step(L) > 0) {
1276 res = 1;
1277 break;
1278 }
1279 break;
1280 }
1281 case LUA_GCSETPAUSE:
1282 res = (int)(g->gc.pause);
1283 g->gc.pause = (MSize)data;
1284 break;
1285 case LUA_GCSETSTEPMUL:
1286 res = (int)(g->gc.stepmul);
1287 g->gc.stepmul = (MSize)data;
1288 break;
1289 case LUA_GCISRUNNING:
1290 res = (g->gc.threshold != LJ_MAX_MEM);
1291 break;
1292 default:
1293 res = -1; /* Invalid option. */
1294 }
1295 return res;
1296}
1297
1298LUA_API lua_Alloc lua_getallocf(lua_State *L, void **ud)
1299{
1300 global_State *g = G(L);
1301 if (ud) *ud = g->allocd;
1302 return g->allocf;
1303}
1304
1305LUA_API void lua_setallocf(lua_State *L, lua_Alloc f, void *ud)
1306{
1307 global_State *g = G(L);
1308 g->allocd = ud;
1309 g->allocf = f;
1310}
1311
1312