LCOV - code coverage report
Current view: top level - src - lapi.c Coverage Total Hit
Test: Lua 5.3.6 Lines: 88.8 % 607 539
Test Date: 2024-04-28 10:23:15
Legend: Lines: hit not hit

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

Generated by: LCOV version 2.0-1