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