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