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