1 /*
2 ** Public Lua/C API.
3 ** Copyright (C) 2005-2017 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 api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
32 #define api_checkvalidindex(L, i) api_check(L, (i) != niltv(L))
33
index2adr(lua_State * L,int idx)34 static 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 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);
58 }
59 }
60 }
61
stkindex2adr(lua_State * L,int idx)62 static TValue *stkindex2adr(lua_State *L, int idx)
63 {
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;
70 }
71 }
72
getcurrenv(lua_State * L)73 static GCtab *getcurrenv(lua_State *L)
74 {
75 GCfunc *fn = curr_func(L);
76 return fn->c.gct == ~LJ_TFUNC ? tabref(fn->c.env) : tabref(L->env);
77 }
78
79 /* -- Miscellaneous API functions ----------------------------------------- */
80
lua_status(lua_State * L)81 LUA_API int lua_status(lua_State *L)
82 {
83 return L->status;
84 }
85
lua_checkstack(lua_State * L,int size)86 LUA_API int lua_checkstack(lua_State *L, int size)
87 {
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);
92 }
93 return 1;
94 }
95
luaL_checkstack(lua_State * L,int size,const char * msg)96 LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
97 {
98 if (!lua_checkstack(L, size))
99 lj_err_callerv(L, LJ_ERR_STKOVM, msg);
100 }
101
lua_xmove(lua_State * from,lua_State * to,int n)102 LUA_API void lua_xmove(lua_State *from, lua_State *to, int n)
103 {
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;
113 }
114
115 /* -- Stack manipulation -------------------------------------------------- */
116
lua_gettop(lua_State * L)117 LUA_API int lua_gettop(lua_State *L)
118 {
119 return (int)(L->top - L->base);
120 }
121
lua_settop(lua_State * L,int idx)122 LUA_API void lua_settop(lua_State *L, int idx)
123 {
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;
132 }
133 } else {
134 api_check(L, -(idx+1) <= (L->top - L->base));
135 L->top += idx+1; /* Shrinks top (idx < 0). */
136 }
137 }
138
lua_remove(lua_State * L,int idx)139 LUA_API void lua_remove(lua_State *L, int idx)
140 {
141 TValue *p = stkindex2adr(L, idx);
142 api_checkvalidindex(L, p);
143 while (++p < L->top) copyTV(L, p-1, p);
144 L->top--;
145 }
146
lua_insert(lua_State * L,int idx)147 LUA_API void lua_insert(lua_State *L, int idx)
148 {
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);
153 }
154
lua_replace(lua_State * L,int idx)155 LUA_API void lua_replace(lua_State *L, int idx)
156 {
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);
175 }
176 L->top--;
177 }
178
lua_pushvalue(lua_State * L,int idx)179 LUA_API void lua_pushvalue(lua_State *L, int idx)
180 {
181 copyTV(L, L->top, index2adr(L, idx));
182 incr_top(L);
183 }
184
185 /* -- Stack getters ------------------------------------------------------- */
186
lua_type(lua_State * L,int idx)187 LUA_API int lua_type(lua_State *L, int idx)
188 {
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;
207 }
208 }
209
luaL_checktype(lua_State * L,int idx,int tt)210 LUALIB_API void luaL_checktype(lua_State *L, int idx, int tt)
211 {
212 if (lua_type(L, idx) != tt)
213 lj_err_argt(L, idx, tt);
214 }
215
luaL_checkany(lua_State * L,int idx)216 LUALIB_API void luaL_checkany(lua_State *L, int idx)
217 {
218 if (index2adr(L, idx) == niltv(L))
219 lj_err_arg(L, idx, LJ_ERR_NOVAL);
220 }
221
lua_typename(lua_State * L,int t)222 LUA_API const char *lua_typename(lua_State *L, int t)
223 {
224 UNUSED(L);
225 return lj_obj_typename[t+1];
226 }
227
lua_iscfunction(lua_State * L,int idx)228 LUA_API int lua_iscfunction(lua_State *L, int idx)
229 {
230 cTValue *o = index2adr(L, idx);
231 return tvisfunc(o) && !isluafunc(funcV(o));
232 }
233
lua_isnumber(lua_State * L,int idx)234 LUA_API int lua_isnumber(lua_State *L, int idx)
235 {
236 cTValue *o = index2adr(L, idx);
237 TValue tmp;
238 return (tvisnumber(o) || (tvisstr(o) && lj_strscan_number(strV(o), &tmp)));
239 }
240
lua_isstring(lua_State * L,int idx)241 LUA_API int lua_isstring(lua_State *L, int idx)
242 {
243 cTValue *o = index2adr(L, idx);
244 return (tvisstr(o) || tvisnumber(o));
245 }
246
lua_isuserdata(lua_State * L,int idx)247 LUA_API int lua_isuserdata(lua_State *L, int idx)
248 {
249 cTValue *o = index2adr(L, idx);
250 return (tvisudata(o) || tvislightud(o));
251 }
252
lua_rawequal(lua_State * L,int idx1,int idx2)253 LUA_API int lua_rawequal(lua_State *L, int idx1, int idx2)
254 {
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);
258 }
259
lua_equal(lua_State * L,int idx1,int idx2)260 LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
261 {
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);
289 }
290 }
291 }
292
lua_lessthan(lua_State * L,int idx1,int idx2)293 LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2)
294 {
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);
312 }
313 }
314 }
315
lua_tonumber(lua_State * L,int idx)316 LUA_API lua_Number lua_tonumber(lua_State *L, int idx)
317 {
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;
326 }
327
luaL_checknumber(lua_State * L,int idx)328 LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx)
329 {
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);
337 }
338
luaL_optnumber(lua_State * L,int idx,lua_Number def)339 LUALIB_API lua_Number luaL_optnumber(lua_State *L, int idx, lua_Number def)
340 {
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);
350 }
351
lua_tointeger(lua_State * L,int idx)352 LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
353 {
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);
367 }
368 #if LJ_64
369 return (lua_Integer)n;
370 #else
371 return lj_num2int(n);
372 #endif
373 }
374
luaL_checkinteger(lua_State * L,int idx)375 LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx)
376 {
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);
390 }
391 #if LJ_64
392 return (lua_Integer)n;
393 #else
394 return lj_num2int(n);
395 #endif
396 }
397
luaL_optinteger(lua_State * L,int idx,lua_Integer def)398 LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int idx, lua_Integer def)
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 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);
415 }
416 #if LJ_64
417 return (lua_Integer)n;
418 #else
419 return lj_num2int(n);
420 #endif
421 }
422
lua_toboolean(lua_State * L,int idx)423 LUA_API int lua_toboolean(lua_State *L, int idx)
424 {
425 cTValue *o = index2adr(L, idx);
426 return tvistruecond(o);
427 }
428
lua_tolstring(lua_State * L,int idx,size_t * len)429 LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len)
430 {
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;
443 }
444 if (len != NULL) *len = s->len;
445 return strdata(s);
446 }
447
luaL_checklstring(lua_State * L,int idx,size_t * len)448 LUALIB_API const char *luaL_checklstring(lua_State *L, int idx, size_t *len)
449 {
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);
461 }
462 if (len != NULL) *len = s->len;
463 return strdata(s);
464 }
465
luaL_optlstring(lua_State * L,int idx,const char * def,size_t * len)466 LUALIB_API const char *luaL_optlstring(lua_State *L, int idx,
467 const char *def, size_t *len)
468 {
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);
483 }
484 if (len != NULL) *len = s->len;
485 return strdata(s);
486 }
487
luaL_checkoption(lua_State * L,int idx,const char * def,const char * const lst[])488 LUALIB_API int luaL_checkoption(lua_State *L, int idx, const char *def,
489 const char *const lst[])
490 {
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);
499 }
500
lua_objlen(lua_State * L,int idx)501 LUA_API size_t lua_objlen(lua_State *L, int idx)
502 {
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;
516 }
517 }
518
lua_tocfunction(lua_State * L,int idx)519 LUA_API lua_CFunction lua_tocfunction(lua_State *L, int idx)
520 {
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;
526 }
527 return NULL;
528 }
529
lua_touserdata(lua_State * L,int idx)530 LUA_API void *lua_touserdata(lua_State *L, int idx)
531 {
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;
539 }
540
lua_tothread(lua_State * L,int idx)541 LUA_API lua_State *lua_tothread(lua_State *L, int idx)
542 {
543 cTValue *o = index2adr(L, idx);
544 return (!tvisthread(o)) ? NULL : threadV(o);
545 }
546
lua_topointer(lua_State * L,int idx)547 LUA_API const void *lua_topointer(lua_State *L, int idx)
548 {
549 return lj_obj_ptr(index2adr(L, idx));
550 }
551
552 /* -- Stack setters (object creation) ------------------------------------- */
553
lua_pushnil(lua_State * L)554 LUA_API void lua_pushnil(lua_State *L)
555 {
556 setnilV(L->top);
557 incr_top(L);
558 }
559
lua_pushnumber(lua_State * L,lua_Number n)560 LUA_API void lua_pushnumber(lua_State *L, lua_Number n)
561 {
562 setnumV(L->top, n);
563 if (LJ_UNLIKELY(tvisnan(L->top)))
564 setnanV(L->top); /* Canonicalize injected NaNs. */
565 incr_top(L);
566 }
567
lua_pushinteger(lua_State * L,lua_Integer n)568 LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
569 {
570 setintptrV(L->top, n);
571 incr_top(L);
572 }
573
lua_pushlstring(lua_State * L,const char * str,size_t len)574 LUA_API void lua_pushlstring(lua_State *L, const char *str, size_t len)
575 {
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);
581 }
582
lua_pushstring(lua_State * L,const char * str)583 LUA_API void lua_pushstring(lua_State *L, const char *str)
584 {
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);
592 }
593 incr_top(L);
594 }
595
lua_pushvfstring(lua_State * L,const char * fmt,va_list argp)596 LUA_API const char *lua_pushvfstring(lua_State *L, const char *fmt,
597 va_list argp)
598 {
599 lj_gc_check(L);
600 return lj_strfmt_pushvf(L, fmt, argp);
601 }
602
lua_pushfstring(lua_State * L,const char * fmt,...)603 LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...)
604 {
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;
612 }
613
lua_pushcclosure(lua_State * L,lua_CFunction f,int n)614 LUA_API void lua_pushcclosure(lua_State *L, lua_CFunction f, int n)
615 {
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);
627 }
628
lua_pushboolean(lua_State * L,int b)629 LUA_API void lua_pushboolean(lua_State *L, int b)
630 {
631 setboolV(L->top, (b != 0));
632 incr_top(L);
633 }
634
lua_pushlightuserdata(lua_State * L,void * p)635 LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
636 {
637 setlightudV(L->top, checklightudptr(L, p));
638 incr_top(L);
639 }
640
lua_createtable(lua_State * L,int narray,int nrec)641 LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
642 {
643 lj_gc_check(L);
644 settabV(L, L->top, lj_tab_new_ah(L, narray, nrec));
645 incr_top(L);
646 }
647
luaL_newmetatable(lua_State * L,const char * tname)648 LUALIB_API int luaL_newmetatable(lua_State *L, const char *tname)
649 {
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;
661 }
662 }
663
lua_pushthread(lua_State * L)664 LUA_API int lua_pushthread(lua_State *L)
665 {
666 setthreadV(L, L->top, L);
667 incr_top(L);
668 return (mainthread(G(L)) == L);
669 }
670
lua_newthread(lua_State * L)671 LUA_API lua_State *lua_newthread(lua_State *L)
672 {
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;
679 }
680
lua_newuserdata(lua_State * L,size_t size)681 LUA_API void *lua_newuserdata(lua_State *L, size_t size)
682 {
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);
691 }
692
lua_concat(lua_State * L,int n)693 LUA_API void lua_concat(lua_State *L, int n)
694 {
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;
703 }
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);
713 }
714 /* else n == 1: nothing to do. */
715 }
716
717 /* -- Object getters ------------------------------------------------------ */
718
lua_gettable(lua_State * L,int idx)719 LUA_API void lua_gettable(lua_State *L, int idx)
720 {
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;
729 }
730 copyTV(L, L->top-1, v);
731 }
732
lua_getfield(lua_State * L,int idx,const char * k)733 LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
734 {
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;
745 }
746 copyTV(L, L->top, v);
747 incr_top(L);
748 }
749
lua_rawget(lua_State * L,int idx)750 LUA_API void lua_rawget(lua_State *L, int idx)
751 {
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));
755 }
756
lua_rawgeti(lua_State * L,int idx,int n)757 LUA_API void lua_rawgeti(lua_State *L, int idx, int n)
758 {
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);
766 }
767 incr_top(L);
768 }
769
lua_getmetatable(lua_State * L,int idx)770 LUA_API int lua_getmetatable(lua_State *L, int idx)
771 {
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;
785 }
786
luaL_getmetafield(lua_State * L,int idx,const char * field)787 LUALIB_API int luaL_getmetafield(lua_State *L, int idx, const char *field)
788 {
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;
794 }
795 L->top--;
796 }
797 return 0;
798 }
799
lua_getfenv(lua_State * L,int idx)800 LUA_API void lua_getfenv(lua_State *L, int idx)
801 {
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);
812 }
813 incr_top(L);
814 }
815
lua_next(lua_State * L,int idx)816 LUA_API int lua_next(lua_State *L, int idx)
817 {
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. */
826 }
827 return more;
828 }
829
lua_getupvalue(lua_State * L,int idx,int n)830 LUA_API const char *lua_getupvalue(lua_State *L, int idx, int n)
831 {
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);
837 }
838 return name;
839 }
840
lua_upvalueid(lua_State * L,int idx,int n)841 LUA_API void *lua_upvalueid(lua_State *L, int idx, int n)
842 {
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];
848 }
849
lua_upvaluejoin(lua_State * L,int idx1,int n1,int idx2,int n2)850 LUA_API void lua_upvaluejoin(lua_State *L, int idx1, int n1, int idx2, int n2)
851 {
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]));
859 }
860
luaL_checkudata(lua_State * L,int idx,const char * tname)861 LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
862 {
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);
869 }
870 lj_err_argtype(L, idx, tname);
871 return NULL; /* unreachable */
872 }
873
874 /* -- Object setters ------------------------------------------------------ */
875
lua_settable(lua_State * L,int idx)876 LUA_API void lua_settable(lua_State *L, int idx)
877 {
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;
893 }
894 }
895
lua_setfield(lua_State * L,int idx,const char * k)896 LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
897 {
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;
914 }
915 }
916
lua_rawset(lua_State * L,int idx)917 LUA_API void lua_rawset(lua_State *L, int idx)
918 {
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;
927 }
928
lua_rawseti(lua_State * L,int idx,int n)929 LUA_API void lua_rawseti(lua_State *L, int idx, int n)
930 {
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;
939 }
940
lua_setmetatable(lua_State * L,int idx)941 LUA_API int lua_setmetatable(lua_State *L, int idx)
942 {
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);
953 }
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));
974 }
975 }
976 L->top--;
977 return 1;
978 }
979
lua_setfenv(lua_State * L,int idx)980 LUA_API int lua_setfenv(lua_State *L, int idx)
981 {
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;
997 }
998 lj_gc_objbarrier(L, gcV(o), t);
999 L->top--;
1000 return 1;
1001 }
1002
lua_setupvalue(lua_State * L,int idx,int n)1003 LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n)
1004 {
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);
1014 }
1015 return name;
1016 }
1017
1018 /* -- Calls --------------------------------------------------------------- */
1019
1020 #if LJ_FR2
api_call_base(lua_State * L,int nargs)1021 static TValue *api_call_base(lua_State *L, int nargs)
1022 {
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;
1028 }
1029 #else
1030 #define api_call_base(L, nargs) (L->top - (nargs))
1031 #endif
1032
lua_call(lua_State * L,int nargs,int nresults)1033 LUA_API void lua_call(lua_State *L, int nargs, int nresults)
1034 {
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);
1038 }
1039
lua_pcall(lua_State * L,int nargs,int nresults,int errfunc)1040 LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
1041 {
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);
1054 }
1055 status = lj_vm_pcall(L, api_call_base(L, nargs), nresults+1, ef);
1056 if (status) hook_restore(g, oldh);
1057 return status;
1058 }
1059
cpcall(lua_State * L,lua_CFunction func,void * ud)1060 static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud)
1061 {
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. */
1071 }
1072
lua_cpcall(lua_State * L,lua_CFunction func,void * ud)1073 LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
1074 {
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;
1082 }
1083
luaL_callmeta(lua_State * L,int idx,const char * field)1084 LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
1085 {
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;
1093 }
1094 return 0;
1095 }
1096
1097 /* -- Coroutine yield and resume ------------------------------------------ */
1098
lua_yield(lua_State * L,int nresults)1099 LUA_API int lua_yield(lua_State *L, int nresults)
1100 {
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;
1111 }
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
1133 }
1134 }
1135 lj_err_msg(L, LJ_ERR_CYIELD);
1136 return 0; /* unreachable */
1137 }
1138
lua_resume(lua_State * L,int nargs)1139 LUA_API int lua_resume(lua_State *L, int nargs)
1140 {
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;
1149 }
1150
1151 /* -- GC and memory management -------------------------------------------- */
1152
lua_gc(lua_State * L,int what,int data)1153 LUA_API int lua_gc(lua_State *L, int what, int data)
1154 {
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;
1180 }
1181 break;
1182 }
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 case LUA_GCISRUNNING:
1192 res = (g->gc.threshold != LJ_MAX_MEM);
1193 break;
1194 default:
1195 res = -1; /* Invalid option. */
1196 }
1197 return res;
1198 }
1199
lua_getallocf(lua_State * L,void ** ud)1200 LUA_API lua_Alloc lua_getallocf(lua_State *L, void **ud)
1201 {
1202 global_State *g = G(L);
1203 if (ud) *ud = g->allocd;
1204 return g->allocf;
1205 }
1206
lua_setallocf(lua_State * L,lua_Alloc f,void * ud)1207 LUA_API void lua_setallocf(lua_State *L, lua_Alloc f, void *ud)
1208 {
1209 global_State *g = G(L);
1210 g->allocd = ud;
1211 g->allocf = f;
1212 }
1213
1214