"Fossies" - the Fresh Open Source Software Archive

Member "memcached-1.6.15/vendor/lua/src/lapi.c" (1 Oct 2021, 35558 Bytes) of package /linux/www/memcached-1.6.15.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    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 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 
   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 
   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 
  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 
  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 
  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 */
  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 
  169 LUA_API int lua_gettop (lua_State *L) {
  170   return cast_int(L->top - (L->ci->func + 1));
  171 }
  172 
  173 
  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 
  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 */
  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 */
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 */
  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 
  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 
  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 
  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 */
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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 */
  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 
  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 
  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 
  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 
  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 
  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 
  903 LUA_API void lua_rawset (lua_State *L, int idx) {
  904   aux_rawset(L, idx, s2v(L->top - 2), 2);
  905 }
  906 
  907 
  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 
  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 
  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 
  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 
  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 
 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 
 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 
 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 
 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 
 1118 LUA_API int lua_status (lua_State *L) {
 1119   return L->status;
 1120 }
 1121 
 1122 
 1123 /*
 1124 ** Garbage-collection function
 1125 */
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 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