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