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