xref: /minix/external/mit/lua/dist/src/lapi.c (revision 0a6a1f1d)
1 /*	$NetBSD: lapi.c,v 1.5 2015/10/08 13:21:00 mbalmer Exp $	*/
2 
3 /*
4 ** Id: lapi.c,v 2.249 2015/04/06 12:23:48 roberto Exp
5 ** Lua API
6 ** See Copyright Notice in lua.h
7 */
8 
9 #define lapi_c
10 #define LUA_CORE
11 
12 #include "lprefix.h"
13 
14 
15 #include <stdarg.h>
16 #ifndef _KERNEL
17 #include <string.h>
18 #endif
19 
20 #include "lua.h"
21 
22 #include "lapi.h"
23 #include "ldebug.h"
24 #include "ldo.h"
25 #include "lfunc.h"
26 #include "lgc.h"
27 #include "lmem.h"
28 #include "lobject.h"
29 #include "lstate.h"
30 #include "lstring.h"
31 #include "ltable.h"
32 #include "ltm.h"
33 #include "lundump.h"
34 #include "lvm.h"
35 
36 
37 
38 const char lua_ident[] =
39   "$LuaVersion: " LUA_COPYRIGHT " $"
40   "$LuaAuthors: " LUA_AUTHORS " $";
41 
42 
43 /* value at a non-valid index */
44 #define NONVALIDVALUE		cast(TValue *, luaO_nilobject)
45 
46 /* corresponding test */
47 #define isvalid(o)	((o) != luaO_nilobject)
48 
49 /* test for pseudo index */
50 #define ispseudo(i)		((i) <= LUA_REGISTRYINDEX)
51 
52 /* test for upvalue */
53 #define isupvalue(i)		((i) < LUA_REGISTRYINDEX)
54 
55 /* test for valid but not pseudo index */
56 #define isstackindex(i, o)	(isvalid(o) && !ispseudo(i))
57 
58 #define api_checkvalidindex(l,o)  api_check(l, isvalid(o), "invalid index")
59 
60 #define api_checkstackindex(l, i, o)  \
61 	api_check(l, isstackindex(i, o), "index not in the stack")
62 
63 
index2addr(lua_State * L,int idx)64 static TValue *index2addr (lua_State *L, int idx) {
65   CallInfo *ci = L->ci;
66   if (idx > 0) {
67     TValue *o = ci->func + idx;
68     api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
69     if (o >= L->top) return NONVALIDVALUE;
70     else return o;
71   }
72   else if (!ispseudo(idx)) {  /* negative index */
73     api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
74     return L->top + idx;
75   }
76   else if (idx == LUA_REGISTRYINDEX)
77     return &G(L)->l_registry;
78   else {  /* upvalues */
79     idx = LUA_REGISTRYINDEX - idx;
80     api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
81     if (ttislcf(ci->func))  /* light C function? */
82       return NONVALIDVALUE;  /* it has no upvalues */
83     else {
84       CClosure *func = clCvalue(ci->func);
85       return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE;
86     }
87   }
88 }
89 
90 
91 /*
92 ** to be called by 'lua_checkstack' in protected mode, to grow stack
93 ** capturing memory errors
94 */
growstack(lua_State * L,void * ud)95 static void growstack (lua_State *L, void *ud) {
96   int size = *(int *)ud;
97   luaD_growstack(L, size);
98 }
99 
100 
lua_checkstack(lua_State * L,int n)101 LUA_API int lua_checkstack (lua_State *L, int n) {
102   int res;
103   CallInfo *ci = L->ci;
104   lua_lock(L);
105   api_check(L, n >= 0, "negative 'n'");
106   if (L->stack_last - L->top > n)  /* stack large enough? */
107     res = 1;  /* yes; check is OK */
108   else {  /* no; need to grow stack */
109     int inuse = cast_int(L->top - L->stack) + EXTRA_STACK;
110     if (inuse > LUAI_MAXSTACK - n)  /* can grow without overflow? */
111       res = 0;  /* no */
112     else  /* try to grow stack */
113       res = (luaD_rawrunprotected(L, &growstack, &n) == LUA_OK);
114   }
115   if (res && ci->top < L->top + n)
116     ci->top = L->top + n;  /* adjust frame top */
117   lua_unlock(L);
118   return res;
119 }
120 
121 
lua_xmove(lua_State * from,lua_State * to,int n)122 LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
123   int i;
124   if (from == to) return;
125   lua_lock(to);
126   api_checknelems(from, n);
127   api_check(from, G(from) == G(to), "moving among independent states");
128   api_check(from, to->ci->top - to->top >= n, "not enough elements to move");
129   from->top -= n;
130   for (i = 0; i < n; i++) {
131     setobj2s(to, to->top, from->top + i);
132     api_incr_top(to);
133   }
134   lua_unlock(to);
135 }
136 
137 
lua_atpanic(lua_State * L,lua_CFunction panicf)138 LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
139   lua_CFunction old;
140   lua_lock(L);
141   old = G(L)->panic;
142   G(L)->panic = panicf;
143   lua_unlock(L);
144   return old;
145 }
146 
147 
lua_version(lua_State * L)148 LUA_API const lua_Number *lua_version (lua_State *L) {
149   static const lua_Number version = LUA_VERSION_NUM;
150   if (L == NULL) return &version;
151   else return G(L)->version;
152 }
153 
154 
155 
156 /*
157 ** basic stack manipulation
158 */
159 
160 
161 /*
162 ** convert an acceptable stack index into an absolute index
163 */
lua_absindex(lua_State * L,int idx)164 LUA_API int lua_absindex (lua_State *L, int idx) {
165   return (idx > 0 || ispseudo(idx))
166          ? idx
167          : cast_int(L->top - L->ci->func) + idx;
168 }
169 
170 
lua_gettop(lua_State * L)171 LUA_API int lua_gettop (lua_State *L) {
172   return cast_int(L->top - (L->ci->func + 1));
173 }
174 
175 
lua_settop(lua_State * L,int idx)176 LUA_API void lua_settop (lua_State *L, int idx) {
177   StkId func = L->ci->func;
178   lua_lock(L);
179   if (idx >= 0) {
180     api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
181     while (L->top < (func + 1) + idx)
182       setnilvalue(L->top++);
183     L->top = (func + 1) + idx;
184   }
185   else {
186     api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
187     L->top += idx+1;  /* 'subtract' index (index is negative) */
188   }
189   lua_unlock(L);
190 }
191 
192 
193 /*
194 ** Reverse the stack segment from 'from' to 'to'
195 ** (auxiliary to 'lua_rotate')
196 */
reverse(lua_State * L,StkId from,StkId to)197 static void reverse (lua_State *L, StkId from, StkId to) {
198   for (; from < to; from++, to--) {
199     TValue temp;
200     setobj(L, &temp, from);
201     setobjs2s(L, from, to);
202     setobj2s(L, to, &temp);
203   }
204 }
205 
206 
207 /*
208 ** Let x = AB, where A is a prefix of length 'n'. Then,
209 ** rotate x n == BA. But BA == (A^r . B^r)^r.
210 */
lua_rotate(lua_State * L,int idx,int n)211 LUA_API void lua_rotate (lua_State *L, int idx, int n) {
212   StkId p, t, m;
213   lua_lock(L);
214   t = L->top - 1;  /* end of stack segment being rotated */
215   p = index2addr(L, idx);  /* start of segment */
216   api_checkstackindex(L, idx, p);
217   api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
218   m = (n >= 0 ? t - n : p - n - 1);  /* end of prefix */
219   reverse(L, p, m);  /* reverse the prefix with length 'n' */
220   reverse(L, m + 1, t);  /* reverse the suffix */
221   reverse(L, p, t);  /* reverse the entire segment */
222   lua_unlock(L);
223 }
224 
225 
lua_copy(lua_State * L,int fromidx,int toidx)226 LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
227   TValue *fr, *to;
228   lua_lock(L);
229   fr = index2addr(L, fromidx);
230   to = index2addr(L, toidx);
231   api_checkvalidindex(L, to);
232   setobj(L, to, fr);
233   if (isupvalue(toidx))  /* function upvalue? */
234     luaC_barrier(L, clCvalue(L->ci->func), fr);
235   /* LUA_REGISTRYINDEX does not need gc barrier
236      (collector revisits it before finishing collection) */
237   lua_unlock(L);
238 }
239 
240 
lua_pushvalue(lua_State * L,int idx)241 LUA_API void lua_pushvalue (lua_State *L, int idx) {
242   lua_lock(L);
243   setobj2s(L, L->top, index2addr(L, idx));
244   api_incr_top(L);
245   lua_unlock(L);
246 }
247 
248 
249 
250 /*
251 ** access functions (stack -> C)
252 */
253 
254 
lua_type(lua_State * L,int idx)255 LUA_API int lua_type (lua_State *L, int idx) {
256   StkId o = index2addr(L, idx);
257   return (isvalid(o) ? ttnov(o) : LUA_TNONE);
258 }
259 
260 
lua_typename(lua_State * L,int t)261 LUA_API const char *lua_typename (lua_State *L, int t) {
262   UNUSED(L);
263   api_check(L, LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag");
264   return ttypename(t);
265 }
266 
267 
lua_iscfunction(lua_State * L,int idx)268 LUA_API int lua_iscfunction (lua_State *L, int idx) {
269   StkId o = index2addr(L, idx);
270   return (ttislcf(o) || (ttisCclosure(o)));
271 }
272 
273 
lua_isinteger(lua_State * L,int idx)274 LUA_API int lua_isinteger (lua_State *L, int idx) {
275   StkId o = index2addr(L, idx);
276   return ttisinteger(o);
277 }
278 
279 
lua_isnumber(lua_State * L,int idx)280 LUA_API int lua_isnumber (lua_State *L, int idx) {
281   lua_Number n;
282   const TValue *o = index2addr(L, idx);
283   return tonumber(o, &n);
284 }
285 
286 
lua_isstring(lua_State * L,int idx)287 LUA_API int lua_isstring (lua_State *L, int idx) {
288   const TValue *o = index2addr(L, idx);
289   return (ttisstring(o) || cvt2str(o));
290 }
291 
292 
lua_isuserdata(lua_State * L,int idx)293 LUA_API int lua_isuserdata (lua_State *L, int idx) {
294   const TValue *o = index2addr(L, idx);
295   return (ttisfulluserdata(o) || ttislightuserdata(o));
296 }
297 
298 
lua_rawequal(lua_State * L,int index1,int index2)299 LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
300   StkId o1 = index2addr(L, index1);
301   StkId o2 = index2addr(L, index2);
302   return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0;
303 }
304 
305 
lua_arith(lua_State * L,int op)306 LUA_API void lua_arith (lua_State *L, int op) {
307   lua_lock(L);
308   if (op != LUA_OPUNM && op != LUA_OPBNOT)
309     api_checknelems(L, 2);  /* all other operations expect two operands */
310   else {  /* for unary operations, add fake 2nd operand */
311     api_checknelems(L, 1);
312     setobjs2s(L, L->top, L->top - 1);
313     api_incr_top(L);
314   }
315   /* first operand at top - 2, second at top - 1; result go to top - 2 */
316   luaO_arith(L, op, L->top - 2, L->top - 1, L->top - 2);
317   L->top--;  /* remove second operand */
318   lua_unlock(L);
319 }
320 
321 
lua_compare(lua_State * L,int index1,int index2,int op)322 LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
323   StkId o1, o2;
324   int i = 0;
325   lua_lock(L);  /* may call tag method */
326   o1 = index2addr(L, index1);
327   o2 = index2addr(L, index2);
328   if (isvalid(o1) && isvalid(o2)) {
329     switch (op) {
330       case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break;
331       case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
332       case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
333       default: api_check(L, 0, "invalid option");
334     }
335   }
336   lua_unlock(L);
337   return i;
338 }
339 
340 
lua_stringtonumber(lua_State * L,const char * s)341 LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
342   size_t sz = luaO_str2num(s, L->top);
343   if (sz != 0)
344     api_incr_top(L);
345   return sz;
346 }
347 
348 
349 #ifndef _KERNEL
lua_tonumberx(lua_State * L,int idx,int * pisnum)350 LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) {
351   lua_Number n;
352   const TValue *o = index2addr(L, idx);
353   int isnum = tonumber(o, &n);
354   if (!isnum)
355     n = 0;  /* call to 'tonumber' may change 'n' even if it fails */
356   if (pisnum) *pisnum = isnum;
357   return n;
358 }
359 #endif
360 
361 
lua_tointegerx(lua_State * L,int idx,int * pisnum)362 LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) {
363   lua_Integer res;
364   const TValue *o = index2addr(L, idx);
365   int isnum = tointeger(o, &res);
366   if (!isnum)
367     res = 0;  /* call to 'tointeger' may change 'n' even if it fails */
368   if (pisnum) *pisnum = isnum;
369   return res;
370 }
371 
372 
lua_toboolean(lua_State * L,int idx)373 LUA_API int lua_toboolean (lua_State *L, int idx) {
374   const TValue *o = index2addr(L, idx);
375   return !l_isfalse(o);
376 }
377 
378 
lua_tolstring(lua_State * L,int idx,size_t * len)379 LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
380   StkId o = index2addr(L, idx);
381   if (!ttisstring(o)) {
382     if (!cvt2str(o)) {  /* not convertible? */
383       if (len != NULL) *len = 0;
384       return NULL;
385     }
386     lua_lock(L);  /* 'luaO_tostring' may create a new string */
387     luaC_checkGC(L);
388     o = index2addr(L, idx);  /* previous call may reallocate the stack */
389     luaO_tostring(L, o);
390     lua_unlock(L);
391   }
392   if (len != NULL)
393     *len = vslen(o);
394   return svalue(o);
395 }
396 
397 
lua_rawlen(lua_State * L,int idx)398 LUA_API size_t lua_rawlen (lua_State *L, int idx) {
399   StkId o = index2addr(L, idx);
400   switch (ttype(o)) {
401     case LUA_TSHRSTR: return tsvalue(o)->shrlen;
402     case LUA_TLNGSTR: return tsvalue(o)->u.lnglen;
403     case LUA_TUSERDATA: return uvalue(o)->len;
404     case LUA_TTABLE: return luaH_getn(hvalue(o));
405     default: return 0;
406   }
407 }
408 
409 
lua_tocfunction(lua_State * L,int idx)410 LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
411   StkId o = index2addr(L, idx);
412   if (ttislcf(o)) return fvalue(o);
413   else if (ttisCclosure(o))
414     return clCvalue(o)->f;
415   else return NULL;  /* not a C function */
416 }
417 
418 
lua_touserdata(lua_State * L,int idx)419 LUA_API void *lua_touserdata (lua_State *L, int idx) {
420   StkId o = index2addr(L, idx);
421   switch (ttnov(o)) {
422     case LUA_TUSERDATA: return getudatamem(uvalue(o));
423     case LUA_TLIGHTUSERDATA: return pvalue(o);
424     default: return NULL;
425   }
426 }
427 
428 
lua_tothread(lua_State * L,int idx)429 LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
430   StkId o = index2addr(L, idx);
431   return (!ttisthread(o)) ? NULL : thvalue(o);
432 }
433 
434 
lua_topointer(lua_State * L,int idx)435 LUA_API const void *lua_topointer (lua_State *L, int idx) {
436   StkId o = index2addr(L, idx);
437   switch (ttype(o)) {
438     case LUA_TTABLE: return hvalue(o);
439     case LUA_TLCL: return clLvalue(o);
440     case LUA_TCCL: return clCvalue(o);
441     case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
442     case LUA_TTHREAD: return thvalue(o);
443     case LUA_TUSERDATA: return getudatamem(uvalue(o));
444     case LUA_TLIGHTUSERDATA: return pvalue(o);
445     default: return NULL;
446   }
447 }
448 
449 
450 
451 /*
452 ** push functions (C -> stack)
453 */
454 
455 
lua_pushnil(lua_State * L)456 LUA_API void lua_pushnil (lua_State *L) {
457   lua_lock(L);
458   setnilvalue(L->top);
459   api_incr_top(L);
460   lua_unlock(L);
461 }
462 
463 
464 #ifndef _KERNEL
lua_pushnumber(lua_State * L,lua_Number n)465 LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
466   lua_lock(L);
467   setfltvalue(L->top, n);
468   api_incr_top(L);
469   lua_unlock(L);
470 }
471 #endif
472 
473 
lua_pushinteger(lua_State * L,lua_Integer n)474 LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
475   lua_lock(L);
476   setivalue(L->top, n);
477   api_incr_top(L);
478   lua_unlock(L);
479 }
480 
481 
lua_pushlstring(lua_State * L,const char * s,size_t len)482 LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
483   TString *ts;
484   lua_lock(L);
485   luaC_checkGC(L);
486   ts = luaS_newlstr(L, s, len);
487   setsvalue2s(L, L->top, ts);
488   api_incr_top(L);
489   lua_unlock(L);
490   return getstr(ts);
491 }
492 
493 
lua_pushstring(lua_State * L,const char * s)494 LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
495   lua_lock(L);
496   if (s == NULL)
497     setnilvalue(L->top);
498   else {
499     TString *ts;
500     luaC_checkGC(L);
501     ts = luaS_new(L, s);
502     setsvalue2s(L, L->top, ts);
503     s = getstr(ts);  /* internal copy's address */
504   }
505   api_incr_top(L);
506   lua_unlock(L);
507   return s;
508 }
509 
510 
lua_pushvfstring(lua_State * L,const char * fmt,va_list argp)511 LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
512                                       va_list argp) {
513   const char *ret;
514   lua_lock(L);
515   luaC_checkGC(L);
516   ret = luaO_pushvfstring(L, fmt, argp);
517   lua_unlock(L);
518   return ret;
519 }
520 
521 
lua_pushfstring(lua_State * L,const char * fmt,...)522 LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
523   const char *ret;
524   va_list argp;
525   lua_lock(L);
526   luaC_checkGC(L);
527   va_start(argp, fmt);
528   ret = luaO_pushvfstring(L, fmt, argp);
529   va_end(argp);
530   lua_unlock(L);
531   return ret;
532 }
533 
534 
lua_pushcclosure(lua_State * L,lua_CFunction fn,int n)535 LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
536   lua_lock(L);
537   if (n == 0) {
538     setfvalue(L->top, fn);
539   }
540   else {
541     CClosure *cl;
542     api_checknelems(L, n);
543     api_check(L, n <= MAXUPVAL, "upvalue index too large");
544     luaC_checkGC(L);
545     cl = luaF_newCclosure(L, n);
546     cl->f = fn;
547     L->top -= n;
548     while (n--) {
549       setobj2n(L, &cl->upvalue[n], L->top + n);
550       /* does not need barrier because closure is white */
551     }
552     setclCvalue(L, L->top, cl);
553   }
554   api_incr_top(L);
555   lua_unlock(L);
556 }
557 
558 
lua_pushboolean(lua_State * L,int b)559 LUA_API void lua_pushboolean (lua_State *L, int b) {
560   lua_lock(L);
561   setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
562   api_incr_top(L);
563   lua_unlock(L);
564 }
565 
566 
lua_pushlightuserdata(lua_State * L,void * p)567 LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
568   lua_lock(L);
569   setpvalue(L->top, p);
570   api_incr_top(L);
571   lua_unlock(L);
572 }
573 
574 
lua_pushthread(lua_State * L)575 LUA_API int lua_pushthread (lua_State *L) {
576   lua_lock(L);
577   setthvalue(L, L->top, L);
578   api_incr_top(L);
579   lua_unlock(L);
580   return (G(L)->mainthread == L);
581 }
582 
583 
584 
585 /*
586 ** get functions (Lua -> stack)
587 */
588 
589 
lua_getglobal(lua_State * L,const char * name)590 LUA_API int lua_getglobal (lua_State *L, const char *name) {
591   Table *reg = hvalue(&G(L)->l_registry);
592   const TValue *gt;  /* global table */
593   lua_lock(L);
594   gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
595   setsvalue2s(L, L->top, luaS_new(L, name));
596   api_incr_top(L);
597   luaV_gettable(L, gt, L->top - 1, L->top - 1);
598   lua_unlock(L);
599   return ttnov(L->top - 1);
600 }
601 
602 
lua_gettable(lua_State * L,int idx)603 LUA_API int lua_gettable (lua_State *L, int idx) {
604   StkId t;
605   lua_lock(L);
606   t = index2addr(L, idx);
607   luaV_gettable(L, t, L->top - 1, L->top - 1);
608   lua_unlock(L);
609   return ttnov(L->top - 1);
610 }
611 
612 
lua_getfield(lua_State * L,int idx,const char * k)613 LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
614   StkId t;
615   lua_lock(L);
616   t = index2addr(L, idx);
617   setsvalue2s(L, L->top, luaS_new(L, k));
618   api_incr_top(L);
619   luaV_gettable(L, t, L->top - 1, L->top - 1);
620   lua_unlock(L);
621   return ttnov(L->top - 1);
622 }
623 
624 
lua_geti(lua_State * L,int idx,lua_Integer n)625 LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
626   StkId t;
627   lua_lock(L);
628   t = index2addr(L, idx);
629   setivalue(L->top, n);
630   api_incr_top(L);
631   luaV_gettable(L, t, L->top - 1, L->top - 1);
632   lua_unlock(L);
633   return ttnov(L->top - 1);
634 }
635 
636 
lua_rawget(lua_State * L,int idx)637 LUA_API int lua_rawget (lua_State *L, int idx) {
638   StkId t;
639   lua_lock(L);
640   t = index2addr(L, idx);
641   api_check(L, ttistable(t), "table expected");
642   setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
643   lua_unlock(L);
644   return ttnov(L->top - 1);
645 }
646 
647 
lua_rawgeti(lua_State * L,int idx,lua_Integer n)648 LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
649   StkId t;
650   lua_lock(L);
651   t = index2addr(L, idx);
652   api_check(L, ttistable(t), "table expected");
653   setobj2s(L, L->top, luaH_getint(hvalue(t), n));
654   api_incr_top(L);
655   lua_unlock(L);
656   return ttnov(L->top - 1);
657 }
658 
659 
lua_rawgetp(lua_State * L,int idx,const void * p)660 LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
661   StkId t;
662   TValue k;
663   lua_lock(L);
664   t = index2addr(L, idx);
665   api_check(L, ttistable(t), "table expected");
666   setpvalue(&k, cast(void *, p));
667   setobj2s(L, L->top, luaH_get(hvalue(t), &k));
668   api_incr_top(L);
669   lua_unlock(L);
670   return ttnov(L->top - 1);
671 }
672 
673 
lua_createtable(lua_State * L,int narray,int nrec)674 LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
675   Table *t;
676   lua_lock(L);
677   luaC_checkGC(L);
678   t = luaH_new(L);
679   sethvalue(L, L->top, t);
680   api_incr_top(L);
681   if (narray > 0 || nrec > 0)
682     luaH_resize(L, t, narray, nrec);
683   lua_unlock(L);
684 }
685 
686 
lua_getmetatable(lua_State * L,int objindex)687 LUA_API int lua_getmetatable (lua_State *L, int objindex) {
688   const TValue *obj;
689   Table *mt;
690   int res = 0;
691   lua_lock(L);
692   obj = index2addr(L, objindex);
693   switch (ttnov(obj)) {
694     case LUA_TTABLE:
695       mt = hvalue(obj)->metatable;
696       break;
697     case LUA_TUSERDATA:
698       mt = uvalue(obj)->metatable;
699       break;
700     default:
701       mt = G(L)->mt[ttnov(obj)];
702       break;
703   }
704   if (mt != NULL) {
705     sethvalue(L, L->top, mt);
706     api_incr_top(L);
707     res = 1;
708   }
709   lua_unlock(L);
710   return res;
711 }
712 
713 
lua_getuservalue(lua_State * L,int idx)714 LUA_API int lua_getuservalue (lua_State *L, int idx) {
715   StkId o;
716   lua_lock(L);
717   o = index2addr(L, idx);
718   api_check(L, ttisfulluserdata(o), "full userdata expected");
719   getuservalue(L, uvalue(o), L->top);
720   api_incr_top(L);
721   lua_unlock(L);
722   return ttnov(L->top - 1);
723 }
724 
725 
726 /*
727 ** set functions (stack -> Lua)
728 */
729 
730 
lua_setglobal(lua_State * L,const char * name)731 LUA_API void lua_setglobal (lua_State *L, const char *name) {
732   Table *reg = hvalue(&G(L)->l_registry);
733   const TValue *gt;  /* global table */
734   lua_lock(L);
735   api_checknelems(L, 1);
736   gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
737   setsvalue2s(L, L->top, luaS_new(L, name));
738   api_incr_top(L);
739   luaV_settable(L, gt, L->top - 1, L->top - 2);
740   L->top -= 2;  /* pop value and key */
741   lua_unlock(L);
742 }
743 
744 
lua_settable(lua_State * L,int idx)745 LUA_API void lua_settable (lua_State *L, int idx) {
746   StkId t;
747   lua_lock(L);
748   api_checknelems(L, 2);
749   t = index2addr(L, idx);
750   luaV_settable(L, t, L->top - 2, L->top - 1);
751   L->top -= 2;  /* pop index and value */
752   lua_unlock(L);
753 }
754 
755 
lua_setfield(lua_State * L,int idx,const char * k)756 LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
757   StkId t;
758   lua_lock(L);
759   api_checknelems(L, 1);
760   t = index2addr(L, idx);
761   setsvalue2s(L, L->top, luaS_new(L, k));
762   api_incr_top(L);
763   luaV_settable(L, t, L->top - 1, L->top - 2);
764   L->top -= 2;  /* pop value and key */
765   lua_unlock(L);
766 }
767 
768 
lua_seti(lua_State * L,int idx,lua_Integer n)769 LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
770   StkId t;
771   lua_lock(L);
772   api_checknelems(L, 1);
773   t = index2addr(L, idx);
774   setivalue(L->top, n);
775   api_incr_top(L);
776   luaV_settable(L, t, L->top - 1, L->top - 2);
777   L->top -= 2;  /* pop value and key */
778   lua_unlock(L);
779 }
780 
781 
lua_rawset(lua_State * L,int idx)782 LUA_API void lua_rawset (lua_State *L, int idx) {
783   StkId o;
784   Table *t;
785   lua_lock(L);
786   api_checknelems(L, 2);
787   o = index2addr(L, idx);
788   api_check(L, ttistable(o), "table expected");
789   t = hvalue(o);
790   setobj2t(L, luaH_set(L, t, L->top-2), L->top-1);
791   invalidateTMcache(t);
792   luaC_barrierback(L, t, L->top-1);
793   L->top -= 2;
794   lua_unlock(L);
795 }
796 
797 
lua_rawseti(lua_State * L,int idx,lua_Integer n)798 LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
799   StkId o;
800   Table *t;
801   lua_lock(L);
802   api_checknelems(L, 1);
803   o = index2addr(L, idx);
804   api_check(L, ttistable(o), "table expected");
805   t = hvalue(o);
806   luaH_setint(L, t, n, L->top - 1);
807   luaC_barrierback(L, t, L->top-1);
808   L->top--;
809   lua_unlock(L);
810 }
811 
812 
lua_rawsetp(lua_State * L,int idx,const void * p)813 LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
814   StkId o;
815   Table *t;
816   TValue k;
817   lua_lock(L);
818   api_checknelems(L, 1);
819   o = index2addr(L, idx);
820   api_check(L, ttistable(o), "table expected");
821   t = hvalue(o);
822   setpvalue(&k, cast(void *, p));
823   setobj2t(L, luaH_set(L, t, &k), L->top - 1);
824   luaC_barrierback(L, t, L->top - 1);
825   L->top--;
826   lua_unlock(L);
827 }
828 
829 
lua_setmetatable(lua_State * L,int objindex)830 LUA_API int lua_setmetatable (lua_State *L, int objindex) {
831   TValue *obj;
832   Table *mt;
833   lua_lock(L);
834   api_checknelems(L, 1);
835   obj = index2addr(L, objindex);
836   if (ttisnil(L->top - 1))
837     mt = NULL;
838   else {
839     api_check(L, ttistable(L->top - 1), "table expected");
840     mt = hvalue(L->top - 1);
841   }
842   switch (ttnov(obj)) {
843     case LUA_TTABLE: {
844       hvalue(obj)->metatable = mt;
845       if (mt) {
846         luaC_objbarrier(L, gcvalue(obj), mt);
847         luaC_checkfinalizer(L, gcvalue(obj), mt);
848       }
849       break;
850     }
851     case LUA_TUSERDATA: {
852       uvalue(obj)->metatable = mt;
853       if (mt) {
854         luaC_objbarrier(L, uvalue(obj), mt);
855         luaC_checkfinalizer(L, gcvalue(obj), mt);
856       }
857       break;
858     }
859     default: {
860       G(L)->mt[ttnov(obj)] = mt;
861       break;
862     }
863   }
864   L->top--;
865   lua_unlock(L);
866   return 1;
867 }
868 
869 
lua_setuservalue(lua_State * L,int idx)870 LUA_API void lua_setuservalue (lua_State *L, int idx) {
871   StkId o;
872   lua_lock(L);
873   api_checknelems(L, 1);
874   o = index2addr(L, idx);
875   api_check(L, ttisfulluserdata(o), "full userdata expected");
876   setuservalue(L, uvalue(o), L->top - 1);
877   luaC_barrier(L, gcvalue(o), L->top - 1);
878   L->top--;
879   lua_unlock(L);
880 }
881 
882 
883 /*
884 ** 'load' and 'call' functions (run Lua code)
885 */
886 
887 
888 #define checkresults(L,na,nr) \
889      api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
890 	"results from function overflow current stack size")
891 
892 
lua_callk(lua_State * L,int nargs,int nresults,lua_KContext ctx,lua_KFunction k)893 LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
894                         lua_KContext ctx, lua_KFunction k) {
895   StkId func;
896   lua_lock(L);
897   api_check(L, k == NULL || !isLua(L->ci),
898     "cannot use continuations inside hooks");
899   api_checknelems(L, nargs+1);
900   api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
901   checkresults(L, nargs, nresults);
902   func = L->top - (nargs+1);
903   if (k != NULL && L->nny == 0) {  /* need to prepare continuation? */
904     L->ci->u.c.k = k;  /* save continuation */
905     L->ci->u.c.ctx = ctx;  /* save context */
906     luaD_call(L, func, nresults, 1);  /* do the call */
907   }
908   else  /* no continuation or no yieldable */
909     luaD_call(L, func, nresults, 0);  /* just do the call */
910   adjustresults(L, nresults);
911   lua_unlock(L);
912 }
913 
914 
915 
916 /*
917 ** Execute a protected call.
918 */
919 struct CallS {  /* data to 'f_call' */
920   StkId func;
921   int nresults;
922 };
923 
924 
f_call(lua_State * L,void * ud)925 static void f_call (lua_State *L, void *ud) {
926   struct CallS *c = cast(struct CallS *, ud);
927   luaD_call(L, c->func, c->nresults, 0);
928 }
929 
930 
931 
lua_pcallk(lua_State * L,int nargs,int nresults,int errfunc,lua_KContext ctx,lua_KFunction k)932 LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
933                         lua_KContext ctx, lua_KFunction k) {
934   struct CallS c;
935   int status;
936   ptrdiff_t func;
937   lua_lock(L);
938   api_check(L, k == NULL || !isLua(L->ci),
939     "cannot use continuations inside hooks");
940   api_checknelems(L, nargs+1);
941   api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
942   checkresults(L, nargs, nresults);
943   if (errfunc == 0)
944     func = 0;
945   else {
946     StkId o = index2addr(L, errfunc);
947     api_checkstackindex(L, errfunc, o);
948     func = savestack(L, o);
949   }
950   c.func = L->top - (nargs+1);  /* function to be called */
951   if (k == NULL || L->nny > 0) {  /* no continuation or no yieldable? */
952     c.nresults = nresults;  /* do a 'conventional' protected call */
953     status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
954   }
955   else {  /* prepare continuation (call is already protected by 'resume') */
956     CallInfo *ci = L->ci;
957     ci->u.c.k = k;  /* save continuation */
958     ci->u.c.ctx = ctx;  /* save context */
959     /* save information for error recovery */
960     ci->extra = savestack(L, c.func);
961     ci->u.c.old_errfunc = L->errfunc;
962     L->errfunc = func;
963     setoah(ci->callstatus, L->allowhook);  /* save value of 'allowhook' */
964     ci->callstatus |= CIST_YPCALL;  /* function can do error recovery */
965     luaD_call(L, c.func, nresults, 1);  /* do the call */
966     ci->callstatus &= ~CIST_YPCALL;
967     L->errfunc = ci->u.c.old_errfunc;
968     status = LUA_OK;  /* if it is here, there were no errors */
969   }
970   adjustresults(L, nresults);
971   lua_unlock(L);
972   return status;
973 }
974 
975 
lua_load(lua_State * L,lua_Reader reader,void * data,const char * chunkname,const char * mode)976 LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
977                       const char *chunkname, const char *mode) {
978   ZIO z;
979   int status;
980   lua_lock(L);
981   if (!chunkname) chunkname = "?";
982   luaZ_init(L, &z, reader, data);
983   status = luaD_protectedparser(L, &z, chunkname, mode);
984   if (status == LUA_OK) {  /* no errors? */
985     LClosure *f = clLvalue(L->top - 1);  /* get newly created function */
986     if (f->nupvalues >= 1) {  /* does it have an upvalue? */
987       /* get global table from registry */
988       Table *reg = hvalue(&G(L)->l_registry);
989       const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
990       /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
991       setobj(L, f->upvals[0]->v, gt);
992       luaC_upvalbarrier(L, f->upvals[0]);
993     }
994   }
995   lua_unlock(L);
996   return status;
997 }
998 
999 
lua_dump(lua_State * L,lua_Writer writer,void * data,int strip)1000 LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
1001   int status;
1002   TValue *o;
1003   lua_lock(L);
1004   api_checknelems(L, 1);
1005   o = L->top - 1;
1006   if (isLfunction(o))
1007     status = luaU_dump(L, getproto(o), writer, data, strip);
1008   else
1009     status = 1;
1010   lua_unlock(L);
1011   return status;
1012 }
1013 
1014 
lua_status(lua_State * L)1015 LUA_API int lua_status (lua_State *L) {
1016   return L->status;
1017 }
1018 
1019 
1020 /*
1021 ** Garbage-collection function
1022 */
1023 
lua_gc(lua_State * L,int what,int data)1024 LUA_API int lua_gc (lua_State *L, int what, int data) {
1025   int res = 0;
1026   global_State *g;
1027   lua_lock(L);
1028   g = G(L);
1029   switch (what) {
1030     case LUA_GCSTOP: {
1031       g->gcrunning = 0;
1032       break;
1033     }
1034     case LUA_GCRESTART: {
1035       luaE_setdebt(g, 0);
1036       g->gcrunning = 1;
1037       break;
1038     }
1039     case LUA_GCCOLLECT: {
1040       luaC_fullgc(L, 0);
1041       break;
1042     }
1043     case LUA_GCCOUNT: {
1044       /* GC values are expressed in Kbytes: #bytes/2^10 */
1045       res = cast_int(gettotalbytes(g) >> 10);
1046       break;
1047     }
1048     case LUA_GCCOUNTB: {
1049       res = cast_int(gettotalbytes(g) & 0x3ff);
1050       break;
1051     }
1052     case LUA_GCSTEP: {
1053       l_mem debt = 1;  /* =1 to signal that it did an actual step */
1054       int oldrunning = g->gcrunning;
1055       g->gcrunning = 1;  /* allow GC to run */
1056       if (data == 0) {
1057         luaE_setdebt(g, -GCSTEPSIZE);  /* to do a "small" step */
1058         luaC_step(L);
1059       }
1060       else {  /* add 'data' to total debt */
1061         debt = cast(l_mem, data) * 1024 + g->GCdebt;
1062         luaE_setdebt(g, debt);
1063         luaC_checkGC(L);
1064       }
1065       g->gcrunning = oldrunning;  /* restore previous state */
1066       if (debt > 0 && g->gcstate == GCSpause)  /* end of cycle? */
1067         res = 1;  /* signal it */
1068       break;
1069     }
1070     case LUA_GCSETPAUSE: {
1071       res = g->gcpause;
1072       g->gcpause = data;
1073       break;
1074     }
1075     case LUA_GCSETSTEPMUL: {
1076       res = g->gcstepmul;
1077       if (data < 40) data = 40;  /* avoid ridiculous low values (and 0) */
1078       g->gcstepmul = data;
1079       break;
1080     }
1081     case LUA_GCISRUNNING: {
1082       res = g->gcrunning;
1083       break;
1084     }
1085     default: res = -1;  /* invalid option */
1086   }
1087   lua_unlock(L);
1088   return res;
1089 }
1090 
1091 
1092 
1093 /*
1094 ** miscellaneous functions
1095 */
1096 
1097 
lua_error(lua_State * L)1098 LUA_API int lua_error (lua_State *L) {
1099   lua_lock(L);
1100   api_checknelems(L, 1);
1101   luaG_errormsg(L);
1102   /* code unreachable; will unlock when control actually leaves the kernel */
1103   return 0;  /* to avoid warnings */
1104 }
1105 
1106 
lua_next(lua_State * L,int idx)1107 LUA_API int lua_next (lua_State *L, int idx) {
1108   StkId t;
1109   int more;
1110   lua_lock(L);
1111   t = index2addr(L, idx);
1112   api_check(L, ttistable(t), "table expected");
1113   more = luaH_next(L, hvalue(t), L->top - 1);
1114   if (more) {
1115     api_incr_top(L);
1116   }
1117   else  /* no more elements */
1118     L->top -= 1;  /* remove key */
1119   lua_unlock(L);
1120   return more;
1121 }
1122 
1123 
lua_concat(lua_State * L,int n)1124 LUA_API void lua_concat (lua_State *L, int n) {
1125   lua_lock(L);
1126   api_checknelems(L, n);
1127   if (n >= 2) {
1128     luaC_checkGC(L);
1129     luaV_concat(L, n);
1130   }
1131   else if (n == 0) {  /* push empty string */
1132     setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
1133     api_incr_top(L);
1134   }
1135   /* else n == 1; nothing to do */
1136   lua_unlock(L);
1137 }
1138 
1139 
lua_len(lua_State * L,int idx)1140 LUA_API void lua_len (lua_State *L, int idx) {
1141   StkId t;
1142   lua_lock(L);
1143   t = index2addr(L, idx);
1144   luaV_objlen(L, L->top, t);
1145   api_incr_top(L);
1146   lua_unlock(L);
1147 }
1148 
1149 
lua_getallocf(lua_State * L,void ** ud)1150 LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
1151   lua_Alloc f;
1152   lua_lock(L);
1153   if (ud) *ud = G(L)->ud;
1154   f = G(L)->frealloc;
1155   lua_unlock(L);
1156   return f;
1157 }
1158 
1159 
lua_setallocf(lua_State * L,lua_Alloc f,void * ud)1160 LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
1161   lua_lock(L);
1162   G(L)->ud = ud;
1163   G(L)->frealloc = f;
1164   lua_unlock(L);
1165 }
1166 
1167 
lua_newuserdata(lua_State * L,size_t size)1168 LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
1169   Udata *u;
1170   lua_lock(L);
1171   luaC_checkGC(L);
1172   u = luaS_newudata(L, size);
1173   setuvalue(L, L->top, u);
1174   api_incr_top(L);
1175   lua_unlock(L);
1176   return getudatamem(u);
1177 }
1178 
1179 
1180 
aux_upvalue(StkId fi,int n,TValue ** val,CClosure ** owner,UpVal ** uv)1181 static const char *aux_upvalue (StkId fi, int n, TValue **val,
1182                                 CClosure **owner, UpVal **uv) {
1183   switch (ttype(fi)) {
1184     case LUA_TCCL: {  /* C closure */
1185       CClosure *f = clCvalue(fi);
1186       if (!(1 <= n && n <= f->nupvalues)) return NULL;
1187       *val = &f->upvalue[n-1];
1188       if (owner) *owner = f;
1189       return "";
1190     }
1191     case LUA_TLCL: {  /* Lua closure */
1192       LClosure *f = clLvalue(fi);
1193       TString *name;
1194       Proto *p = f->p;
1195       if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
1196       *val = f->upvals[n-1]->v;
1197       if (uv) *uv = f->upvals[n - 1];
1198       name = p->upvalues[n-1].name;
1199       return (name == NULL) ? "(*no name)" : getstr(name);
1200     }
1201     default: return NULL;  /* not a closure */
1202   }
1203 }
1204 
1205 
lua_getupvalue(lua_State * L,int funcindex,int n)1206 LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
1207   const char *name;
1208   TValue *val = NULL;  /* to avoid warnings */
1209   lua_lock(L);
1210   name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL, NULL);
1211   if (name) {
1212     setobj2s(L, L->top, val);
1213     api_incr_top(L);
1214   }
1215   lua_unlock(L);
1216   return name;
1217 }
1218 
1219 
lua_setupvalue(lua_State * L,int funcindex,int n)1220 LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
1221   const char *name;
1222   TValue *val = NULL;  /* to avoid warnings */
1223   CClosure *owner = NULL;
1224   UpVal *uv = NULL;
1225   StkId fi;
1226   lua_lock(L);
1227   fi = index2addr(L, funcindex);
1228   api_checknelems(L, 1);
1229   name = aux_upvalue(fi, n, &val, &owner, &uv);
1230   if (name) {
1231     L->top--;
1232     setobj(L, val, L->top);
1233     if (owner) { luaC_barrier(L, owner, L->top); }
1234     else if (uv) { luaC_upvalbarrier(L, uv); }
1235   }
1236   lua_unlock(L);
1237   return name;
1238 }
1239 
1240 
getupvalref(lua_State * L,int fidx,int n,LClosure ** pf)1241 static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
1242   LClosure *f;
1243   StkId fi = index2addr(L, fidx);
1244   api_check(L, ttisLclosure(fi), "Lua function expected");
1245   f = clLvalue(fi);
1246   api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
1247   if (pf) *pf = f;
1248   return &f->upvals[n - 1];  /* get its upvalue pointer */
1249 }
1250 
1251 
lua_upvalueid(lua_State * L,int fidx,int n)1252 LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
1253   StkId fi = index2addr(L, fidx);
1254   switch (ttype(fi)) {
1255     case LUA_TLCL: {  /* lua closure */
1256       return *getupvalref(L, fidx, n, NULL);
1257     }
1258     case LUA_TCCL: {  /* C closure */
1259       CClosure *f = clCvalue(fi);
1260       api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index");
1261       return &f->upvalue[n - 1];
1262     }
1263     default: {
1264       api_check(L, 0, "closure expected");
1265       return NULL;
1266     }
1267   }
1268 }
1269 
1270 
lua_upvaluejoin(lua_State * L,int fidx1,int n1,int fidx2,int n2)1271 LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
1272                                             int fidx2, int n2) {
1273   LClosure *f1;
1274   UpVal **up1 = getupvalref(L, fidx1, n1, &f1);
1275   UpVal **up2 = getupvalref(L, fidx2, n2, NULL);
1276   luaC_upvdeccount(L, *up1);
1277   *up1 = *up2;
1278   (*up1)->refcount++;
1279   if (upisopen(*up1)) (*up1)->u.open.touched = 1;
1280   luaC_upvalbarrier(L, *up1);
1281 }
1282 
1283 
1284