beta-0.89.2
[luatex.git] / source / libs / luajit / LuaJIT-src / src / lj_api.c
blob1f09284f991471f6e00b7ddbc7572f8e86a8f02c
1 /*
2 ** Public Lua/C API.
3 ** Copyright (C) 2005-2015 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 api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
32 #define api_checkvalidindex(L, i) api_check(L, (i) != niltv(L))
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 api_check(L, idx != 0 && -idx <= L->top - L->base);
41 return L->top + idx;
42 } else if (idx == LUA_GLOBALSINDEX) {
43 TValue *o = &G(L)->tmptv;
44 settabV(L, o, tabref(L->env));
45 return o;
46 } else if (idx == LUA_REGISTRYINDEX) {
47 return registry(L);
48 } else {
49 GCfunc *fn = curr_func(L);
50 api_check(L, fn->c.gct == ~LJ_TFUNC && !isluafunc(fn));
51 if (idx == LUA_ENVIRONINDEX) {
52 TValue *o = &G(L)->tmptv;
53 settabV(L, o, tabref(fn->c.env));
54 return o;
55 } else {
56 idx = LUA_GLOBALSINDEX - idx;
57 return idx <= fn->c.nupvalues ? &fn->c.upvalue[idx-1] : niltv(L);
62 static TValue *stkindex2adr(lua_State *L, int idx)
64 if (idx > 0) {
65 TValue *o = L->base + (idx - 1);
66 return o < L->top ? o : niltv(L);
67 } else {
68 api_check(L, idx != 0 && -idx <= L->top - L->base);
69 return L->top + idx;
73 static GCtab *getcurrenv(lua_State *L)
75 GCfunc *fn = curr_func(L);
76 return fn->c.gct == ~LJ_TFUNC ? tabref(fn->c.env) : tabref(L->env);
79 /* -- Miscellaneous API functions ----------------------------------------- */
81 LUA_API int lua_status(lua_State *L)
83 return L->status;
86 LUA_API int lua_checkstack(lua_State *L, int size)
88 if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) {
89 return 0; /* Stack overflow. */
90 } else if (size > 0) {
91 lj_state_checkstack(L, (MSize)size);
93 return 1;
96 LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
98 if (!lua_checkstack(L, size))
99 lj_err_callerv(L, LJ_ERR_STKOVM, msg);
102 LUA_API void lua_xmove(lua_State *from, lua_State *to, int n)
104 TValue *f, *t;
105 if (from == to) return;
106 api_checknelems(from, n);
107 api_check(from, G(from) == G(to));
108 lj_state_checkstack(to, (MSize)n);
109 f = from->top;
110 t = to->top = to->top + n;
111 while (--n >= 0) copyTV(to, --t, --f);
112 from->top = f;
115 /* -- Stack manipulation -------------------------------------------------- */
117 LUA_API int lua_gettop(lua_State *L)
119 return (int)(L->top - L->base);
122 LUA_API void lua_settop(lua_State *L, int idx)
124 if (idx >= 0) {
125 api_check(L, idx <= tvref(L->maxstack) - L->base);
126 if (L->base + idx > L->top) {
127 if (L->base + idx >= tvref(L->maxstack))
128 lj_state_growstack(L, (MSize)idx - (MSize)(L->top - L->base));
129 do { setnilV(L->top++); } while (L->top < L->base + idx);
130 } else {
131 L->top = L->base + idx;
133 } else {
134 api_check(L, -(idx+1) <= (L->top - L->base));
135 L->top += idx+1; /* Shrinks top (idx < 0). */
139 LUA_API void lua_remove(lua_State *L, int idx)
141 TValue *p = stkindex2adr(L, idx);
142 api_checkvalidindex(L, p);
143 while (++p < L->top) copyTV(L, p-1, p);
144 L->top--;
147 LUA_API void lua_insert(lua_State *L, int idx)
149 TValue *q, *p = stkindex2adr(L, idx);
150 api_checkvalidindex(L, p);
151 for (q = L->top; q > p; q--) copyTV(L, q, q-1);
152 copyTV(L, p, L->top);
155 LUA_API void lua_replace(lua_State *L, int idx)
157 api_checknelems(L, 1);
158 if (idx == LUA_GLOBALSINDEX) {
159 api_check(L, tvistab(L->top-1));
160 /* NOBARRIER: A thread (i.e. L) is never black. */
161 setgcref(L->env, obj2gco(tabV(L->top-1)));
162 } else if (idx == LUA_ENVIRONINDEX) {
163 GCfunc *fn = curr_func(L);
164 if (fn->c.gct != ~LJ_TFUNC)
165 lj_err_msg(L, LJ_ERR_NOENV);
166 api_check(L, tvistab(L->top-1));
167 setgcref(fn->c.env, obj2gco(tabV(L->top-1)));
168 lj_gc_barrier(L, fn, L->top-1);
169 } else {
170 TValue *o = index2adr(L, idx);
171 api_checkvalidindex(L, o);
172 copyTV(L, o, L->top-1);
173 if (idx < LUA_GLOBALSINDEX) /* Need a barrier for upvalues. */
174 lj_gc_barrier(L, curr_func(L), L->top-1);
176 L->top--;
179 LUA_API void lua_pushvalue(lua_State *L, int idx)
181 copyTV(L, L->top, index2adr(L, idx));
182 incr_top(L);
185 /* -- Stack getters ------------------------------------------------------- */
187 LUA_API int lua_type(lua_State *L, int idx)
189 cTValue *o = index2adr(L, idx);
190 if (tvisnumber(o)) {
191 return LUA_TNUMBER;
192 #if LJ_64 && !LJ_GC64
193 } else if (tvislightud(o)) {
194 return LUA_TLIGHTUSERDATA;
195 #endif
196 } else if (o == niltv(L)) {
197 return LUA_TNONE;
198 } else { /* Magic internal/external tag conversion. ORDER LJ_T */
199 uint32_t t = ~itype(o);
200 #if LJ_64
201 int tt = (int)((U64x(75a06,98042110) >> 4*t) & 15u);
202 #else
203 int tt = (int)(((t < 8 ? 0x98042110u : 0x75a06u) >> 4*(t&7)) & 15u);
204 #endif
205 lua_assert(tt != LUA_TNIL || tvisnil(o));
206 return tt;
210 LUALIB_API void luaL_checktype(lua_State *L, int idx, int tt)
212 if (lua_type(L, idx) != tt)
213 lj_err_argt(L, idx, tt);
216 LUALIB_API void luaL_checkany(lua_State *L, int idx)
218 if (index2adr(L, idx) == niltv(L))
219 lj_err_arg(L, idx, LJ_ERR_NOVAL);
222 LUA_API const char *lua_typename(lua_State *L, int t)
224 UNUSED(L);
225 return lj_obj_typename[t+1];
228 LUA_API int lua_iscfunction(lua_State *L, int idx)
230 cTValue *o = index2adr(L, idx);
231 return tvisfunc(o) && !isluafunc(funcV(o));
234 LUA_API int lua_isnumber(lua_State *L, int idx)
236 cTValue *o = index2adr(L, idx);
237 TValue tmp;
238 return (tvisnumber(o) || (tvisstr(o) && lj_strscan_number(strV(o), &tmp)));
241 LUA_API int lua_isstring(lua_State *L, int idx)
243 cTValue *o = index2adr(L, idx);
244 return (tvisstr(o) || tvisnumber(o));
247 LUA_API int lua_isuserdata(lua_State *L, int idx)
249 cTValue *o = index2adr(L, idx);
250 return (tvisudata(o) || tvislightud(o));
253 LUA_API int lua_rawequal(lua_State *L, int idx1, int idx2)
255 cTValue *o1 = index2adr(L, idx1);
256 cTValue *o2 = index2adr(L, idx2);
257 return (o1 == niltv(L) || o2 == niltv(L)) ? 0 : lj_obj_equal(o1, o2);
260 LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
262 cTValue *o1 = index2adr(L, idx1);
263 cTValue *o2 = index2adr(L, idx2);
264 if (tvisint(o1) && tvisint(o2)) {
265 return intV(o1) == intV(o2);
266 } else if (tvisnumber(o1) && tvisnumber(o2)) {
267 return numberVnum(o1) == numberVnum(o2);
268 } else if (itype(o1) != itype(o2)) {
269 return 0;
270 } else if (tvispri(o1)) {
271 return o1 != niltv(L) && o2 != niltv(L);
272 #if LJ_64 && !LJ_GC64
273 } else if (tvislightud(o1)) {
274 return o1->u64 == o2->u64;
275 #endif
276 } else if (gcrefeq(o1->gcr, o2->gcr)) {
277 return 1;
278 } else if (!tvistabud(o1)) {
279 return 0;
280 } else {
281 TValue *base = lj_meta_equal(L, gcV(o1), gcV(o2), 0);
282 if ((uintptr_t)base <= 1) {
283 return (int)(uintptr_t)base;
284 } else {
285 L->top = base+2;
286 lj_vm_call(L, base, 1+1);
287 L->top -= 2+LJ_FR2;
288 return tvistruecond(L->top+1+LJ_FR2);
293 LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2)
295 cTValue *o1 = index2adr(L, idx1);
296 cTValue *o2 = index2adr(L, idx2);
297 if (o1 == niltv(L) || o2 == niltv(L)) {
298 return 0;
299 } else 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 {
304 TValue *base = lj_meta_comp(L, o1, o2, 0);
305 if ((uintptr_t)base <= 1) {
306 return (int)(uintptr_t)base;
307 } else {
308 L->top = base+2;
309 lj_vm_call(L, base, 1+1);
310 L->top -= 2+LJ_FR2;
311 return tvistruecond(L->top+1+LJ_FR2);
316 LUA_API lua_Number lua_tonumber(lua_State *L, int idx)
318 cTValue *o = index2adr(L, idx);
319 TValue tmp;
320 if (LJ_LIKELY(tvisnumber(o)))
321 return numberVnum(o);
322 else if (tvisstr(o) && lj_strscan_num(strV(o), &tmp))
323 return numV(&tmp);
324 else
325 return 0;
328 LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx)
330 cTValue *o = index2adr(L, idx);
331 TValue tmp;
332 if (LJ_LIKELY(tvisnumber(o)))
333 return numberVnum(o);
334 else if (!(tvisstr(o) && lj_strscan_num(strV(o), &tmp)))
335 lj_err_argt(L, idx, LUA_TNUMBER);
336 return numV(&tmp);
339 LUALIB_API lua_Number luaL_optnumber(lua_State *L, int idx, lua_Number def)
341 cTValue *o = index2adr(L, idx);
342 TValue tmp;
343 if (LJ_LIKELY(tvisnumber(o)))
344 return numberVnum(o);
345 else if (tvisnil(o))
346 return def;
347 else if (!(tvisstr(o) && lj_strscan_num(strV(o), &tmp)))
348 lj_err_argt(L, idx, LUA_TNUMBER);
349 return numV(&tmp);
352 LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
354 cTValue *o = index2adr(L, idx);
355 TValue tmp;
356 lua_Number n;
357 if (LJ_LIKELY(tvisint(o))) {
358 return intV(o);
359 } else if (LJ_LIKELY(tvisnum(o))) {
360 n = numV(o);
361 } else {
362 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
363 return 0;
364 if (tvisint(&tmp))
365 return (lua_Integer)intV(&tmp);
366 n = numV(&tmp);
368 #if LJ_64
369 return (lua_Integer)n;
370 #else
371 return lj_num2int(n);
372 #endif
375 LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx)
377 cTValue *o = index2adr(L, idx);
378 TValue tmp;
379 lua_Number n;
380 if (LJ_LIKELY(tvisint(o))) {
381 return intV(o);
382 } else if (LJ_LIKELY(tvisnum(o))) {
383 n = numV(o);
384 } else {
385 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
386 lj_err_argt(L, idx, LUA_TNUMBER);
387 if (tvisint(&tmp))
388 return (lua_Integer)intV(&tmp);
389 n = numV(&tmp);
391 #if LJ_64
392 return (lua_Integer)n;
393 #else
394 return lj_num2int(n);
395 #endif
398 LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int idx, lua_Integer def)
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 if (tvisnil(o)) {
408 return def;
409 } else {
410 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
411 lj_err_argt(L, idx, LUA_TNUMBER);
412 if (tvisint(&tmp))
413 return (lua_Integer)intV(&tmp);
414 n = numV(&tmp);
416 #if LJ_64
417 return (lua_Integer)n;
418 #else
419 return lj_num2int(n);
420 #endif
423 LUA_API int lua_toboolean(lua_State *L, int idx)
425 cTValue *o = index2adr(L, idx);
426 return tvistruecond(o);
429 LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len)
431 TValue *o = index2adr(L, idx);
432 GCstr *s;
433 if (LJ_LIKELY(tvisstr(o))) {
434 s = strV(o);
435 } else if (tvisnumber(o)) {
436 lj_gc_check(L);
437 o = index2adr(L, idx); /* GC may move the stack. */
438 s = lj_strfmt_number(L, o);
439 setstrV(L, o, s);
440 } else {
441 if (len != NULL) *len = 0;
442 return NULL;
444 if (len != NULL) *len = s->len;
445 return strdata(s);
448 LUALIB_API const char *luaL_checklstring(lua_State *L, int idx, size_t *len)
450 TValue *o = index2adr(L, idx);
451 GCstr *s;
452 if (LJ_LIKELY(tvisstr(o))) {
453 s = strV(o);
454 } else if (tvisnumber(o)) {
455 lj_gc_check(L);
456 o = index2adr(L, idx); /* GC may move the stack. */
457 s = lj_strfmt_number(L, o);
458 setstrV(L, o, s);
459 } else {
460 lj_err_argt(L, idx, LUA_TSTRING);
462 if (len != NULL) *len = s->len;
463 return strdata(s);
466 LUALIB_API const char *luaL_optlstring(lua_State *L, int idx,
467 const char *def, size_t *len)
469 TValue *o = index2adr(L, idx);
470 GCstr *s;
471 if (LJ_LIKELY(tvisstr(o))) {
472 s = strV(o);
473 } else if (tvisnil(o)) {
474 if (len != NULL) *len = def ? strlen(def) : 0;
475 return def;
476 } else if (tvisnumber(o)) {
477 lj_gc_check(L);
478 o = index2adr(L, idx); /* GC may move the stack. */
479 s = lj_strfmt_number(L, o);
480 setstrV(L, o, s);
481 } else {
482 lj_err_argt(L, idx, LUA_TSTRING);
484 if (len != NULL) *len = s->len;
485 return strdata(s);
488 LUALIB_API int luaL_checkoption(lua_State *L, int idx, const char *def,
489 const char *const lst[])
491 ptrdiff_t i;
492 const char *s = lua_tolstring(L, idx, NULL);
493 if (s == NULL && (s = def) == NULL)
494 lj_err_argt(L, idx, LUA_TSTRING);
495 for (i = 0; lst[i]; i++)
496 if (strcmp(lst[i], s) == 0)
497 return (int)i;
498 lj_err_argv(L, idx, LJ_ERR_INVOPTM, s);
501 LUA_API size_t lua_objlen(lua_State *L, int idx)
503 TValue *o = index2adr(L, idx);
504 if (tvisstr(o)) {
505 return strV(o)->len;
506 } else if (tvistab(o)) {
507 return (size_t)lj_tab_len(tabV(o));
508 } else if (tvisudata(o)) {
509 return udataV(o)->len;
510 } else if (tvisnumber(o)) {
511 GCstr *s = lj_strfmt_number(L, o);
512 setstrV(L, o, s);
513 return s->len;
514 } else {
515 return 0;
519 LUA_API lua_CFunction lua_tocfunction(lua_State *L, int idx)
521 cTValue *o = index2adr(L, idx);
522 if (tvisfunc(o)) {
523 BCOp op = bc_op(*mref(funcV(o)->c.pc, BCIns));
524 if (op == BC_FUNCC || op == BC_FUNCCW)
525 return funcV(o)->c.f;
527 return NULL;
530 LUA_API void *lua_touserdata(lua_State *L, int idx)
532 cTValue *o = index2adr(L, idx);
533 if (tvisudata(o))
534 return uddata(udataV(o));
535 else if (tvislightud(o))
536 return lightudV(o);
537 else
538 return NULL;
541 LUA_API lua_State *lua_tothread(lua_State *L, int idx)
543 cTValue *o = index2adr(L, idx);
544 return (!tvisthread(o)) ? NULL : threadV(o);
547 LUA_API const void *lua_topointer(lua_State *L, int idx)
549 return lj_obj_ptr(index2adr(L, idx));
552 /* -- Stack setters (object creation) ------------------------------------- */
554 LUA_API void lua_pushnil(lua_State *L)
556 setnilV(L->top);
557 incr_top(L);
560 LUA_API void lua_pushnumber(lua_State *L, lua_Number n)
562 setnumV(L->top, n);
563 if (LJ_UNLIKELY(tvisnan(L->top)))
564 setnanV(L->top); /* Canonicalize injected NaNs. */
565 incr_top(L);
568 LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
570 setintptrV(L->top, n);
571 incr_top(L);
574 LUA_API void lua_pushlstring(lua_State *L, const char *str, size_t len)
576 GCstr *s;
577 lj_gc_check(L);
578 s = lj_str_new(L, str, len);
579 setstrV(L, L->top, s);
580 incr_top(L);
583 LUA_API void lua_pushstring(lua_State *L, const char *str)
585 if (str == NULL) {
586 setnilV(L->top);
587 } else {
588 GCstr *s;
589 lj_gc_check(L);
590 s = lj_str_newz(L, str);
591 setstrV(L, L->top, s);
593 incr_top(L);
596 LUA_API const char *lua_pushvfstring(lua_State *L, const char *fmt,
597 va_list argp)
599 lj_gc_check(L);
600 return lj_strfmt_pushvf(L, fmt, argp);
603 LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...)
605 const char *ret;
606 va_list argp;
607 lj_gc_check(L);
608 va_start(argp, fmt);
609 ret = lj_strfmt_pushvf(L, fmt, argp);
610 va_end(argp);
611 return ret;
614 LUA_API void lua_pushcclosure(lua_State *L, lua_CFunction f, int n)
616 GCfunc *fn;
617 lj_gc_check(L);
618 api_checknelems(L, n);
619 fn = lj_func_newC(L, (MSize)n, getcurrenv(L));
620 fn->c.f = f;
621 L->top -= n;
622 while (n--)
623 copyTV(L, &fn->c.upvalue[n], L->top+n);
624 setfuncV(L, L->top, fn);
625 lua_assert(iswhite(obj2gco(fn)));
626 incr_top(L);
629 LUA_API void lua_pushboolean(lua_State *L, int b)
631 setboolV(L->top, (b != 0));
632 incr_top(L);
635 LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
637 setlightudV(L->top, checklightudptr(L, p));
638 incr_top(L);
641 LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
643 lj_gc_check(L);
644 settabV(L, L->top, lj_tab_new_ah(L, narray, nrec));
645 incr_top(L);
648 LUALIB_API int luaL_newmetatable(lua_State *L, const char *tname)
650 GCtab *regt = tabV(registry(L));
651 TValue *tv = lj_tab_setstr(L, regt, lj_str_newz(L, tname));
652 if (tvisnil(tv)) {
653 GCtab *mt = lj_tab_new(L, 0, 1);
654 settabV(L, tv, mt);
655 settabV(L, L->top++, mt);
656 lj_gc_anybarriert(L, regt);
657 return 1;
658 } else {
659 copyTV(L, L->top++, tv);
660 return 0;
664 LUA_API int lua_pushthread(lua_State *L)
666 setthreadV(L, L->top, L);
667 incr_top(L);
668 return (mainthread(G(L)) == L);
671 LUA_API lua_State *lua_newthread(lua_State *L)
673 lua_State *L1;
674 lj_gc_check(L);
675 L1 = lj_state_new(L);
676 setthreadV(L, L->top, L1);
677 incr_top(L);
678 return L1;
681 LUA_API void *lua_newuserdata(lua_State *L, size_t size)
683 GCudata *ud;
684 lj_gc_check(L);
685 if (size > LJ_MAX_UDATA)
686 lj_err_msg(L, LJ_ERR_UDATAOV);
687 ud = lj_udata_new(L, (MSize)size, getcurrenv(L));
688 setudataV(L, L->top, ud);
689 incr_top(L);
690 return uddata(ud);
693 LUA_API void lua_concat(lua_State *L, int n)
695 api_checknelems(L, n);
696 if (n >= 2) {
697 n--;
698 do {
699 TValue *top = lj_meta_cat(L, L->top-1, -n);
700 if (top == NULL) {
701 L->top -= n;
702 break;
704 n -= (int)(L->top - top);
705 L->top = top+2;
706 lj_vm_call(L, top, 1+1);
707 L->top -= 1+LJ_FR2;
708 copyTV(L, L->top-1, L->top+LJ_FR2);
709 } while (--n > 0);
710 } else if (n == 0) { /* Push empty string. */
711 setstrV(L, L->top, &G(L)->strempty);
712 incr_top(L);
714 /* else n == 1: nothing to do. */
717 /* -- Object getters ------------------------------------------------------ */
719 LUA_API void lua_gettable(lua_State *L, int idx)
721 cTValue *v, *t = index2adr(L, idx);
722 api_checkvalidindex(L, t);
723 v = lj_meta_tget(L, t, L->top-1);
724 if (v == NULL) {
725 L->top += 2;
726 lj_vm_call(L, L->top-2, 1+1);
727 L->top -= 2+LJ_FR2;
728 v = L->top+1+LJ_FR2;
730 copyTV(L, L->top-1, v);
733 LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
735 cTValue *v, *t = index2adr(L, idx);
736 TValue key;
737 api_checkvalidindex(L, t);
738 setstrV(L, &key, lj_str_newz(L, k));
739 v = lj_meta_tget(L, t, &key);
740 if (v == NULL) {
741 L->top += 2;
742 lj_vm_call(L, L->top-2, 1+1);
743 L->top -= 2+LJ_FR2;
744 v = L->top+1+LJ_FR2;
746 copyTV(L, L->top, v);
747 incr_top(L);
750 LUA_API void lua_rawget(lua_State *L, int idx)
752 cTValue *t = index2adr(L, idx);
753 api_check(L, tvistab(t));
754 copyTV(L, L->top-1, lj_tab_get(L, tabV(t), L->top-1));
757 LUA_API void lua_rawgeti(lua_State *L, int idx, int n)
759 cTValue *v, *t = index2adr(L, idx);
760 api_check(L, tvistab(t));
761 v = lj_tab_getint(tabV(t), n);
762 if (v) {
763 copyTV(L, L->top, v);
764 } else {
765 setnilV(L->top);
767 incr_top(L);
770 LUA_API int lua_getmetatable(lua_State *L, int idx)
772 cTValue *o = index2adr(L, idx);
773 GCtab *mt = NULL;
774 if (tvistab(o))
775 mt = tabref(tabV(o)->metatable);
776 else if (tvisudata(o))
777 mt = tabref(udataV(o)->metatable);
778 else
779 mt = tabref(basemt_obj(G(L), o));
780 if (mt == NULL)
781 return 0;
782 settabV(L, L->top, mt);
783 incr_top(L);
784 return 1;
787 LUALIB_API int luaL_getmetafield(lua_State *L, int idx, const char *field)
789 if (lua_getmetatable(L, idx)) {
790 cTValue *tv = lj_tab_getstr(tabV(L->top-1), lj_str_newz(L, field));
791 if (tv && !tvisnil(tv)) {
792 copyTV(L, L->top-1, tv);
793 return 1;
795 L->top--;
797 return 0;
800 LUA_API void lua_getfenv(lua_State *L, int idx)
802 cTValue *o = index2adr(L, idx);
803 api_checkvalidindex(L, o);
804 if (tvisfunc(o)) {
805 settabV(L, L->top, tabref(funcV(o)->c.env));
806 } else if (tvisudata(o)) {
807 settabV(L, L->top, tabref(udataV(o)->env));
808 } else if (tvisthread(o)) {
809 settabV(L, L->top, tabref(threadV(o)->env));
810 } else {
811 setnilV(L->top);
813 incr_top(L);
816 LUA_API int lua_next(lua_State *L, int idx)
818 cTValue *t = index2adr(L, idx);
819 int more;
820 api_check(L, tvistab(t));
821 more = lj_tab_next(L, tabV(t), L->top-1);
822 if (more) {
823 incr_top(L); /* Return new key and value slot. */
824 } else { /* End of traversal. */
825 L->top--; /* Remove key slot. */
827 return more;
830 LUA_API const char *lua_getupvalue(lua_State *L, int idx, int n)
832 TValue *val;
833 const char *name = lj_debug_uvnamev(index2adr(L, idx), (uint32_t)(n-1), &val);
834 if (name) {
835 copyTV(L, L->top, val);
836 incr_top(L);
838 return name;
841 LUA_API void *lua_upvalueid(lua_State *L, int idx, int n)
843 GCfunc *fn = funcV(index2adr(L, idx));
844 n--;
845 api_check(L, (uint32_t)n < fn->l.nupvalues);
846 return isluafunc(fn) ? (void *)gcref(fn->l.uvptr[n]) :
847 (void *)&fn->c.upvalue[n];
850 LUA_API void lua_upvaluejoin(lua_State *L, int idx1, int n1, int idx2, int n2)
852 GCfunc *fn1 = funcV(index2adr(L, idx1));
853 GCfunc *fn2 = funcV(index2adr(L, idx2));
854 n1--; n2--;
855 api_check(L, isluafunc(fn1) && (uint32_t)n1 < fn1->l.nupvalues);
856 api_check(L, isluafunc(fn2) && (uint32_t)n2 < fn2->l.nupvalues);
857 setgcrefr(fn1->l.uvptr[n1], fn2->l.uvptr[n2]);
858 lj_gc_objbarrier(L, fn1, gcref(fn1->l.uvptr[n1]));
861 LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
863 cTValue *o = index2adr(L, idx);
864 if (tvisudata(o)) {
865 GCudata *ud = udataV(o);
866 cTValue *tv = lj_tab_getstr(tabV(registry(L)), lj_str_newz(L, tname));
867 if (tv && tvistab(tv) && tabV(tv) == tabref(ud->metatable))
868 return uddata(ud);
870 lj_err_argtype(L, idx, tname);
871 return NULL; /* unreachable */
874 /* -- Object setters ------------------------------------------------------ */
876 LUA_API void lua_settable(lua_State *L, int idx)
878 TValue *o;
879 cTValue *t = index2adr(L, idx);
880 api_checknelems(L, 2);
881 api_checkvalidindex(L, t);
882 o = lj_meta_tset(L, t, L->top-2);
883 if (o) {
884 /* NOBARRIER: lj_meta_tset ensures the table is not black. */
885 L->top -= 2;
886 copyTV(L, o, L->top+1);
887 } else {
888 TValue *base = L->top;
889 copyTV(L, base+2, base-3-2*LJ_FR2);
890 L->top = base+3;
891 lj_vm_call(L, base, 0+1);
892 L->top -= 3+LJ_FR2;
896 LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
898 TValue *o;
899 TValue key;
900 cTValue *t = index2adr(L, idx);
901 api_checknelems(L, 1);
902 api_checkvalidindex(L, t);
903 setstrV(L, &key, lj_str_newz(L, k));
904 o = lj_meta_tset(L, t, &key);
905 if (o) {
906 /* NOBARRIER: lj_meta_tset ensures the table is not black. */
907 copyTV(L, o, --L->top);
908 } else {
909 TValue *base = L->top;
910 copyTV(L, base+2, base-3-2*LJ_FR2);
911 L->top = base+3;
912 lj_vm_call(L, base, 0+1);
913 L->top -= 2+LJ_FR2;
917 LUA_API void lua_rawset(lua_State *L, int idx)
919 GCtab *t = tabV(index2adr(L, idx));
920 TValue *dst, *key;
921 api_checknelems(L, 2);
922 key = L->top-2;
923 dst = lj_tab_set(L, t, key);
924 copyTV(L, dst, key+1);
925 lj_gc_anybarriert(L, t);
926 L->top = key;
929 LUA_API void lua_rawseti(lua_State *L, int idx, int n)
931 GCtab *t = tabV(index2adr(L, idx));
932 TValue *dst, *src;
933 api_checknelems(L, 1);
934 dst = lj_tab_setint(L, t, n);
935 src = L->top-1;
936 copyTV(L, dst, src);
937 lj_gc_barriert(L, t, dst);
938 L->top = src;
941 LUA_API int lua_setmetatable(lua_State *L, int idx)
943 global_State *g;
944 GCtab *mt;
945 cTValue *o = index2adr(L, idx);
946 api_checknelems(L, 1);
947 api_checkvalidindex(L, o);
948 if (tvisnil(L->top-1)) {
949 mt = NULL;
950 } else {
951 api_check(L, tvistab(L->top-1));
952 mt = tabV(L->top-1);
954 g = G(L);
955 if (tvistab(o)) {
956 setgcref(tabV(o)->metatable, obj2gco(mt));
957 if (mt)
958 lj_gc_objbarriert(L, tabV(o), mt);
959 } else if (tvisudata(o)) {
960 setgcref(udataV(o)->metatable, obj2gco(mt));
961 if (mt)
962 lj_gc_objbarrier(L, udataV(o), mt);
963 } else {
964 /* Flush cache, since traces specialize to basemt. But not during __gc. */
965 if (lj_trace_flushall(L))
966 lj_err_caller(L, LJ_ERR_NOGCMM);
967 if (tvisbool(o)) {
968 /* NOBARRIER: basemt is a GC root. */
969 setgcref(basemt_it(g, LJ_TTRUE), obj2gco(mt));
970 setgcref(basemt_it(g, LJ_TFALSE), obj2gco(mt));
971 } else {
972 /* NOBARRIER: basemt is a GC root. */
973 setgcref(basemt_obj(g, o), obj2gco(mt));
976 L->top--;
977 return 1;
980 LUA_API int lua_setfenv(lua_State *L, int idx)
982 cTValue *o = index2adr(L, idx);
983 GCtab *t;
984 api_checknelems(L, 1);
985 api_checkvalidindex(L, o);
986 api_check(L, tvistab(L->top-1));
987 t = tabV(L->top-1);
988 if (tvisfunc(o)) {
989 setgcref(funcV(o)->c.env, obj2gco(t));
990 } else if (tvisudata(o)) {
991 setgcref(udataV(o)->env, obj2gco(t));
992 } else if (tvisthread(o)) {
993 setgcref(threadV(o)->env, obj2gco(t));
994 } else {
995 L->top--;
996 return 0;
998 lj_gc_objbarrier(L, gcV(o), t);
999 L->top--;
1000 return 1;
1003 LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n)
1005 cTValue *f = index2adr(L, idx);
1006 TValue *val;
1007 const char *name;
1008 api_checknelems(L, 1);
1009 name = lj_debug_uvnamev(f, (uint32_t)(n-1), &val);
1010 if (name) {
1011 L->top--;
1012 copyTV(L, val, L->top);
1013 lj_gc_barrier(L, funcV(f), L->top);
1015 return name;
1018 /* -- Calls --------------------------------------------------------------- */
1020 #if LJ_FR2
1021 static TValue *api_call_base(lua_State *L, int nargs)
1023 TValue *o = L->top, *base = o - nargs;
1024 L->top = o+1;
1025 for (; o > base; o--) copyTV(L, o, o-1);
1026 setnilV(o);
1027 return o+1;
1029 #else
1030 #define api_call_base(L, nargs) (L->top - (nargs))
1031 #endif
1033 LUA_API void lua_call(lua_State *L, int nargs, int nresults)
1035 api_check(L, L->status == 0 || L->status == LUA_ERRERR);
1036 api_checknelems(L, nargs+1);
1037 lj_vm_call(L, api_call_base(L, nargs), nresults+1);
1040 LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
1042 global_State *g = G(L);
1043 uint8_t oldh = hook_save(g);
1044 ptrdiff_t ef;
1045 int status;
1046 api_check(L, L->status == 0 || L->status == LUA_ERRERR);
1047 api_checknelems(L, nargs+1);
1048 if (errfunc == 0) {
1049 ef = 0;
1050 } else {
1051 cTValue *o = stkindex2adr(L, errfunc);
1052 api_checkvalidindex(L, o);
1053 ef = savestack(L, o);
1055 status = lj_vm_pcall(L, api_call_base(L, nargs), nresults+1, ef);
1056 if (status) hook_restore(g, oldh);
1057 return status;
1060 static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud)
1062 GCfunc *fn = lj_func_newC(L, 0, getcurrenv(L));
1063 TValue *top = L->top;
1064 fn->c.f = func;
1065 setfuncV(L, top++, fn);
1066 if (LJ_FR2) setnilV(top++);
1067 setlightudV(top++, checklightudptr(L, ud));
1068 cframe_nres(L->cframe) = 1+0; /* Zero results. */
1069 L->top = top;
1070 return top-1; /* Now call the newly allocated C function. */
1073 LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
1075 global_State *g = G(L);
1076 uint8_t oldh = hook_save(g);
1077 int status;
1078 api_check(L, L->status == 0 || L->status == LUA_ERRERR);
1079 status = lj_vm_cpcall(L, func, ud, cpcall);
1080 if (status) hook_restore(g, oldh);
1081 return status;
1084 LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
1086 if (luaL_getmetafield(L, idx, field)) {
1087 TValue *top = L->top--;
1088 if (LJ_FR2) setnilV(top++);
1089 copyTV(L, top++, index2adr(L, idx));
1090 L->top = top;
1091 lj_vm_call(L, top-1, 1+1);
1092 return 1;
1094 return 0;
1097 /* -- Coroutine yield and resume ------------------------------------------ */
1099 LUA_API int lua_yield(lua_State *L, int nresults)
1101 void *cf = L->cframe;
1102 global_State *g = G(L);
1103 if (cframe_canyield(cf)) {
1104 cf = cframe_raw(cf);
1105 if (!hook_active(g)) { /* Regular yield: move results down if needed. */
1106 cTValue *f = L->top - nresults;
1107 if (f > L->base) {
1108 TValue *t = L->base;
1109 while (--nresults >= 0) copyTV(L, t++, f++);
1110 L->top = t;
1112 L->cframe = NULL;
1113 L->status = LUA_YIELD;
1114 return -1;
1115 } else { /* Yield from hook: add a pseudo-frame. */
1116 TValue *top = L->top;
1117 hook_leave(g);
1118 (top++)->u64 = cframe_multres(cf);
1119 setcont(top, lj_cont_hook);
1120 if (LJ_FR2) top++;
1121 setframe_pc(top, cframe_pc(cf)-1);
1122 if (LJ_FR2) top++;
1123 setframe_gc(top, obj2gco(L), LJ_TTHREAD);
1124 setframe_ftsz(top, ((char *)(top+1)-(char *)L->base)+FRAME_CONT);
1125 L->top = L->base = top+1;
1126 #if LJ_TARGET_X64
1127 lj_err_throw(L, LUA_YIELD);
1128 #else
1129 L->cframe = NULL;
1130 L->status = LUA_YIELD;
1131 lj_vm_unwind_c(cf, LUA_YIELD);
1132 #endif
1135 lj_err_msg(L, LJ_ERR_CYIELD);
1136 return 0; /* unreachable */
1139 LUA_API int lua_resume(lua_State *L, int nargs)
1141 if (L->cframe == NULL && L->status <= LUA_YIELD)
1142 return lj_vm_resume(L,
1143 L->status == 0 ? api_call_base(L, nargs) : L->top - nargs,
1144 0, 0);
1145 L->top = L->base;
1146 setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP));
1147 incr_top(L);
1148 return LUA_ERRRUN;
1151 /* -- GC and memory management -------------------------------------------- */
1153 LUA_API int lua_gc(lua_State *L, int what, int data)
1155 global_State *g = G(L);
1156 int res = 0;
1157 switch (what) {
1158 case LUA_GCSTOP:
1159 g->gc.threshold = LJ_MAX_MEM;
1160 break;
1161 case LUA_GCRESTART:
1162 g->gc.threshold = data == -1 ? (g->gc.total/100)*g->gc.pause : g->gc.total;
1163 break;
1164 case LUA_GCCOLLECT:
1165 lj_gc_fullgc(L);
1166 break;
1167 case LUA_GCCOUNT:
1168 res = (int)(g->gc.total >> 10);
1169 break;
1170 case LUA_GCCOUNTB:
1171 res = (int)(g->gc.total & 0x3ff);
1172 break;
1173 case LUA_GCSTEP: {
1174 GCSize a = (GCSize)data << 10;
1175 g->gc.threshold = (a <= g->gc.total) ? (g->gc.total - a) : 0;
1176 while (g->gc.total >= g->gc.threshold)
1177 if (lj_gc_step(L) > 0) {
1178 res = 1;
1179 break;
1181 break;
1183 case LUA_GCSETPAUSE:
1184 res = (int)(g->gc.pause);
1185 g->gc.pause = (MSize)data;
1186 break;
1187 case LUA_GCSETSTEPMUL:
1188 res = (int)(g->gc.stepmul);
1189 g->gc.stepmul = (MSize)data;
1190 break;
1191 default:
1192 res = -1; /* Invalid option. */
1194 return res;
1197 LUA_API lua_Alloc lua_getallocf(lua_State *L, void **ud)
1199 global_State *g = G(L);
1200 if (ud) *ud = g->allocd;
1201 return g->allocf;
1204 LUA_API void lua_setallocf(lua_State *L, lua_Alloc f, void *ud)
1206 global_State *g = G(L);
1207 g->allocd = ud;
1208 g->allocf = f;