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