LCOV - code coverage report
Current view: top level - AP_Scripting/lua/src - lapi.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 388 609 63.7 %
Date: 2026-09-09 11:02:08 Functions: 60 85 70.6 %

          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    26037660 : static TValue *index2addr (lua_State *L, int idx) {
      61    26037660 :   CallInfo *ci = L->ci;
      62    26037660 :   if (idx > 0) {
      63    13430709 :     TValue *o = ci->func + idx;
      64             :     api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
      65    13430709 :     if (o >= L->top) return NONVALIDVALUE;
      66    13270563 :     else return o;
      67             :   }
      68    12606951 :   else if (!ispseudo(idx)) {  /* negative index */
      69             :     api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
      70     7792215 :     return L->top + idx;
      71             :   }
      72     4814736 :   else if (idx == LUA_REGISTRYINDEX)
      73     4814697 :     return &G(L)->l_registry;
      74             :   else {  /* upvalues */
      75          39 :     idx = LUA_REGISTRYINDEX - idx;
      76             :     api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
      77          39 :     if (ttislcf(ci->func))  /* light C function? */
      78           0 :       return NONVALIDVALUE;  /* it has no upvalues */
      79             :     else {
      80          39 :       CClosure *func = clCvalue(ci->func);
      81          39 :       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           0 : static void growstack (lua_State *L, void *ud) {
      92           0 :   int size = *(int *)ud;
      93           0 :   luaD_growstack(L, size);
      94           0 : }
      95             : 
      96             : 
      97        1414 : LUA_API int lua_checkstack (lua_State *L, int n) {
      98             :   int res;
      99        1414 :   CallInfo *ci = L->ci;
     100             :   lua_lock(L);
     101             :   api_check(L, n >= 0, "negative 'n'");
     102        1414 :   if (L->stack_last - L->top > n)  /* stack large enough? */
     103        1414 :     res = 1;  /* yes; check is OK */
     104             :   else {  /* no; need to grow stack */
     105           0 :     int inuse = cast_int(L->top - L->stack) + EXTRA_STACK;
     106           0 :     if (inuse > LUAI_MAXSTACK - n)  /* can grow without overflow? */
     107           0 :       res = 0;  /* no */
     108             :     else  /* try to grow stack */
     109           0 :       res = (luaD_rawrunprotected(L, &growstack, &n) == LUA_OK);
     110             :   }
     111        1414 :   if (res && ci->top < L->top + n)
     112           0 :     ci->top = L->top + n;  /* adjust frame top */
     113             :   lua_unlock(L);
     114        1414 :   return res;
     115             : }
     116             : 
     117             : 
     118           0 : LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
     119             :   int i;
     120           0 :   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           0 :   from->top -= n;
     126           0 :   for (i = 0; i < n; i++) {
     127           0 :     setobj2s(to, to->top, from->top + i);
     128           0 :     to->top++;  /* stack already checked by previous 'api_check' */
     129             :   }
     130             :   lua_unlock(to);
     131             : }
     132             : 
     133             : 
     134           0 : LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
     135             :   lua_CFunction old;
     136             :   lua_lock(L);
     137           0 :   old = G(L)->panic;
     138           0 :   G(L)->panic = panicf;
     139             :   lua_unlock(L);
     140           0 :   return old;
     141             : }
     142             : 
     143             : 
     144        1211 : LUA_API const lua_Number *lua_version (lua_State *L) {
     145             :   static const lua_Number version = LUA_VERSION_NUM;
     146        1211 :   if (L == NULL) return &version;
     147         557 :   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      191843 : LUA_API int lua_absindex (lua_State *L, int idx) {
     161      181209 :   return (idx > 0 || ispseudo(idx))
     162             :          ? idx
     163      373052 :          : cast_int(L->top - L->ci->func) + idx;
     164             : }
     165             : 
     166             : 
     167     3986435 : LUA_API int lua_gettop (lua_State *L) {
     168     3986435 :   return cast_int(L->top - (L->ci->func + 1));
     169             : }
     170             : 
     171             : 
     172     3630626 : LUA_API void lua_settop (lua_State *L, int idx) {
     173     3630626 :   StkId func = L->ci->func;
     174             :   lua_lock(L);
     175     3630626 :   if (idx >= 0) {
     176             :     api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
     177      237491 :     while (L->top < (func + 1) + idx)
     178           0 :       setnilvalue(L->top++);
     179      237491 :     L->top = (func + 1) + idx;
     180             :   }
     181             :   else {
     182             :     api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
     183     3393135 :     L->top += idx+1;  /* 'subtract' index (index is negative) */
     184             :   }
     185             :   lua_unlock(L);
     186     3630626 : }
     187             : 
     188             : 
     189             : /*
     190             : ** Reverse the stack segment from 'from' to 'to'
     191             : ** (auxiliary to 'lua_rotate')
     192             : */
     193      217077 : static void reverse (lua_State *L, StkId from, StkId to) {
     194      616611 :   for (; from < to; from++, to--) {
     195             :     TValue temp;
     196      399534 :     setobj(L, &temp, from);
     197      399534 :     setobjs2s(L, from, to);
     198      399534 :     setobj2s(L, to, &temp);
     199             :   }
     200      217077 : }
     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       72359 : LUA_API void lua_rotate (lua_State *L, int idx, int n) {
     208             :   StkId p, t, m;
     209             :   lua_lock(L);
     210       72359 :   t = L->top - 1;  /* end of stack segment being rotated */
     211       72359 :   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       72359 :   m = (n >= 0 ? t - n : p - n - 1);  /* end of prefix */
     215       72359 :   reverse(L, p, m);  /* reverse the prefix with length 'n' */
     216       72359 :   reverse(L, m + 1, t);  /* reverse the suffix */
     217       72359 :   reverse(L, p, t);  /* reverse the entire segment */
     218             :   lua_unlock(L);
     219       72359 : }
     220             : 
     221             : 
     222           0 : LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
     223             :   TValue *fr, *to;
     224             :   lua_lock(L);
     225           0 :   fr = index2addr(L, fromidx);
     226           0 :   to = index2addr(L, toidx);
     227             :   api_checkvalidindex(L, to);
     228           0 :   setobj(L, to, fr);
     229           0 :   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           0 : }
     235             : 
     236             : 
     237      112027 : LUA_API void lua_pushvalue (lua_State *L, int idx) {
     238             :   lua_lock(L);
     239      112027 :   setobj2s(L, L->top, index2addr(L, idx));
     240      112027 :   api_incr_top(L);
     241             :   lua_unlock(L);
     242      112027 : }
     243             : 
     244             : 
     245             : 
     246             : /*
     247             : ** access functions (stack -> C)
     248             : */
     249             : 
     250             : 
     251      633429 : LUA_API int lua_type (lua_State *L, int idx) {
     252      633429 :   StkId o = index2addr(L, idx);
     253      633429 :   return (isvalid(o) ? ttnov(o) : LUA_TNONE);
     254             : }
     255             : 
     256             : 
     257          35 : 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          35 :   return ttypename(t);
     261             : }
     262             : 
     263             : 
     264           0 : LUA_API int lua_iscfunction (lua_State *L, int idx) {
     265           0 :   StkId o = index2addr(L, idx);
     266           0 :   return (ttislcf(o) || (ttisCclosure(o)));
     267             : }
     268             : 
     269             : 
     270      276254 : LUA_API int lua_isinteger (lua_State *L, int idx) {
     271      276254 :   StkId o = index2addr(L, idx);
     272      276254 :   return ttisinteger(o);
     273             : }
     274             : 
     275             : 
     276          80 : LUA_API int lua_isnumber (lua_State *L, int idx) {
     277             :   lua_Number n;
     278          80 :   const TValue *o = index2addr(L, idx);
     279          80 :   return tonumber(o, &n);
     280             : }
     281             : 
     282             : 
     283         675 : LUA_API int lua_isstring (lua_State *L, int idx) {
     284         675 :   const TValue *o = index2addr(L, idx);
     285         675 :   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     3187815 : LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
     296     3187815 :   StkId o1 = index2addr(L, index1);
     297     3187815 :   StkId o2 = index2addr(L, index2);
     298     3187815 :   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       55123 : LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
     319             :   StkId o1, o2;
     320       55123 :   int i = 0;
     321             :   lua_lock(L);  /* may call tag method */
     322       55123 :   o1 = index2addr(L, index1);
     323       55123 :   o2 = index2addr(L, index2);
     324       55123 :   if (isvalid(o1) && isvalid(o2)) {
     325       55123 :     switch (op) {
     326           0 :       case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break;
     327       55123 :       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       55123 :   return i;
     334             : }
     335             : 
     336             : 
     337         261 : LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
     338         261 :   size_t sz = luaO_str2num(s, L->top);
     339         261 :   if (sz != 0)
     340         156 :     api_incr_top(L);
     341         261 :   return sz;
     342             : }
     343             : 
     344             : 
     345     1746648 : LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) {
     346             :   lua_Number n;
     347     1746648 :   const TValue *o = index2addr(L, idx);
     348     1746648 :   int isnum = tonumber(o, &n);
     349     1746648 :   if (!isnum)
     350           2 :     n = 0;  /* call to 'tonumber' may change 'n' even if it fails */
     351     1746648 :   if (pisnum) *pisnum = isnum;
     352     1746648 :   return n;
     353             : }
     354             : 
     355             : 
     356      588032 : LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) {
     357             :   lua_Integer res;
     358      588032 :   const TValue *o = index2addr(L, idx);
     359      588032 :   int isnum = tointeger(o, &res);
     360      588032 :   if (!isnum)
     361         230 :     res = 0;  /* call to 'tointeger' may change 'n' even if it fails */
     362      588032 :   if (pisnum) *pisnum = isnum;
     363      588032 :   return res;
     364             : }
     365             : 
     366             : 
     367      160701 : LUA_API int lua_toboolean (lua_State *L, int idx) {
     368      160701 :   const TValue *o = index2addr(L, idx);
     369      160701 :   return !l_isfalse(o);
     370             : }
     371             : 
     372             : 
     373     3374123 : LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
     374     3374123 :   StkId o = index2addr(L, idx);
     375     3374123 :   if (!ttisstring(o)) {
     376           2 :     if (!cvt2str(o)) {  /* not convertible? */
     377           2 :       if (len != NULL) *len = 0;
     378           2 :       return NULL;
     379             :     }
     380             :     lua_lock(L);  /* 'luaO_tostring' may create a new string */
     381           0 :     luaO_tostring(L, o);
     382           0 :     luaC_checkGC(L);
     383           0 :     o = index2addr(L, idx);  /* previous call may reallocate the stack */
     384             :     lua_unlock(L);
     385             :   }
     386     3374121 :   if (len != NULL)
     387       61474 :     *len = vslen(o);
     388     3374121 :   return svalue(o);
     389             : }
     390             : 
     391             : 
     392         185 : LUA_API size_t lua_rawlen (lua_State *L, int idx) {
     393         185 :   StkId o = index2addr(L, idx);
     394         185 :   switch (ttype(o)) {
     395           1 :     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         184 :     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     3256433 : LUA_API void *lua_touserdata (lua_State *L, int idx) {
     414     3256433 :   StkId o = index2addr(L, idx);
     415     3256433 :   switch (ttnov(o)) {
     416     3187885 :     case LUA_TUSERDATA: return getudatamem(uvalue(o));
     417           0 :     case LUA_TLIGHTUSERDATA: return pvalue(o);
     418       68548 :     default: return NULL;
     419             :   }
     420             : }
     421             : 
     422             : 
     423           0 : LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
     424           0 :   StkId o = index2addr(L, idx);
     425           0 :   return (!ttisthread(o)) ? NULL : thvalue(o);
     426             : }
     427             : 
     428             : 
     429           2 : LUA_API const void *lua_topointer (lua_State *L, int idx) {
     430           2 :   StkId o = index2addr(L, idx);
     431           2 :   switch (ttype(o)) {
     432           2 :     case LUA_TTABLE: return hvalue(o);
     433           0 :     case LUA_TLCL: return clLvalue(o);
     434           0 :     case LUA_TCCL: return clCvalue(o);
     435           0 :     case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
     436           0 :     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       80581 : LUA_API void lua_pushnil (lua_State *L) {
     451             :   lua_lock(L);
     452       80581 :   setnilvalue(L->top);
     453       80581 :   api_incr_top(L);
     454             :   lua_unlock(L);
     455       80581 : }
     456             : 
     457             : 
     458     1788162 : LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
     459             :   lua_lock(L);
     460     1788162 :   setfltvalue(L->top, n);
     461     1788162 :   api_incr_top(L);
     462             :   lua_unlock(L);
     463     1788162 : }
     464             : 
     465             : 
     466      616570 : LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
     467             :   lua_lock(L);
     468      616570 :   setivalue(L->top, n);
     469      616570 :   api_incr_top(L);
     470             :   lua_unlock(L);
     471      616570 : }
     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       32819 : LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
     480             :   TString *ts;
     481             :   lua_lock(L);
     482       32819 :   ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len);
     483       32819 :   setsvalue2s(L, L->top, ts);
     484       32819 :   api_incr_top(L);
     485       32819 :   luaC_checkGC(L);
     486             :   lua_unlock(L);
     487       32819 :   return getstr(ts);
     488             : }
     489             : 
     490             : 
     491       12907 : LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
     492             :   lua_lock(L);
     493       12907 :   if (s == NULL)
     494           0 :     setnilvalue(L->top);
     495             :   else {
     496             :     TString *ts;
     497       12907 :     ts = luaS_new(L, s);
     498       12907 :     setsvalue2s(L, L->top, ts);
     499       12907 :     s = getstr(ts);  /* internal copy's address */
     500             :   }
     501       12907 :   api_incr_top(L);
     502       12907 :   luaC_checkGC(L);
     503             :   lua_unlock(L);
     504       12907 :   return s;
     505             : }
     506             : 
     507             : 
     508          48 : 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          48 :   ret = luaO_pushvfstring(L, fmt, argp);
     513          48 :   luaC_checkGC(L);
     514             :   lua_unlock(L);
     515          48 :   return ret;
     516             : }
     517             : 
     518             : 
     519         590 : 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         590 :   va_start(argp, fmt);
     524         590 :   ret = luaO_pushvfstring(L, fmt, argp);
     525         590 :   va_end(argp);
     526         590 :   luaC_checkGC(L);
     527             :   lua_unlock(L);
     528         590 :   return ret;
     529             : }
     530             : 
     531             : 
     532     3165983 : LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
     533             :   lua_lock(L);
     534     3165983 :   if (n == 0) {
     535     3165887 :     setfvalue(L->top, fn);
     536     3165887 :     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          96 :     cl = luaF_newCclosure(L, n);
     543          96 :     cl->f = fn;
     544          96 :     L->top -= n;
     545         200 :     while (n--) {
     546         104 :       setobj2n(L, &cl->upvalue[n], L->top + n);
     547             :       /* does not need barrier because closure is white */
     548             :     }
     549          96 :     setclCvalue(L, L->top, cl);
     550          96 :     api_incr_top(L);
     551          96 :     luaC_checkGC(L);
     552             :   }
     553             :   lua_unlock(L);
     554     3165983 : }
     555             : 
     556             : 
     557      217439 : LUA_API void lua_pushboolean (lua_State *L, int b) {
     558             :   lua_lock(L);
     559      217439 :   setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
     560      217439 :   api_incr_top(L);
     561             :   lua_unlock(L);
     562      217439 : }
     563             : 
     564             : 
     565           0 : LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
     566             :   lua_lock(L);
     567           0 :   setpvalue(L->top, p);
     568           0 :   api_incr_top(L);
     569             :   lua_unlock(L);
     570           0 : }
     571             : 
     572             : 
     573           0 : LUA_API int lua_pushthread (lua_State *L) {
     574             :   lua_lock(L);
     575           0 :   setthvalue(L, L->top, L);
     576           0 :   api_incr_top(L);
     577             :   lua_unlock(L);
     578           0 :   return (G(L)->mainthread == L);
     579             : }
     580             : 
     581             : 
     582             : 
     583             : /*
     584             : ** get functions (Lua -> stack)
     585             : */
     586             : 
     587             : 
     588     4090477 : static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
     589             :   const TValue *slot;
     590     4090477 :   TString *str = luaS_new(L, k);
     591     4090477 :   if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
     592     4089602 :     setobj2s(L, L->top, slot);
     593     4089602 :     api_incr_top(L);
     594             :   }
     595             :   else {
     596         875 :     setsvalue2s(L, L->top, str);
     597         875 :     api_incr_top(L);
     598         875 :     luaV_finishget(L, t, L->top - 1, L->top - 1, slot);
     599             :   }
     600             :   lua_unlock(L);
     601     4090477 :   return ttnov(L->top - 1);
     602             : }
     603             : 
     604             : 
     605           0 : LUA_API int lua_getglobal (lua_State *L, const char *name) {
     606           0 :   Table *reg = hvalue(&G(L)->l_registry);
     607             :   lua_lock(L);
     608           0 :   return auxgetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name);
     609             : }
     610             : 
     611             : 
     612         128 : LUA_API int lua_gettable (lua_State *L, int idx) {
     613             :   StkId t;
     614             :   lua_lock(L);
     615         128 :   t = index2addr(L, idx);
     616         128 :   luaV_gettable(L, t, L->top - 1, L->top - 1);
     617             :   lua_unlock(L);
     618         128 :   return ttnov(L->top - 1);
     619             : }
     620             : 
     621             : 
     622     4090477 : LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
     623             :   lua_lock(L);
     624     4090477 :   return auxgetstr(L, index2addr(L, idx), k);
     625             : }
     626             : 
     627             : 
     628      122620 : 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      122620 :   t = index2addr(L, idx);
     633      122620 :   if (luaV_fastget(L, t, n, slot, luaH_getint)) {
     634      102204 :     setobj2s(L, L->top, slot);
     635      102204 :     api_incr_top(L);
     636             :   }
     637             :   else {
     638       20416 :     setivalue(L->top, n);
     639       20416 :     api_incr_top(L);
     640       20416 :     luaV_finishget(L, t, L->top - 1, L->top - 1, slot);
     641             :   }
     642             :   lua_unlock(L);
     643      122620 :   return ttnov(L->top - 1);
     644             : }
     645             : 
     646             : 
     647       10383 : LUA_API int lua_rawget (lua_State *L, int idx) {
     648             :   StkId t;
     649             :   lua_lock(L);
     650       10383 :   t = index2addr(L, idx);
     651             :   api_check(L, ttistable(t), "table expected");
     652       10383 :   setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
     653             :   lua_unlock(L);
     654       10383 :   return ttnov(L->top - 1);
     655             : }
     656             : 
     657             : 
     658      361785 : LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
     659             :   StkId t;
     660             :   lua_lock(L);
     661      361785 :   t = index2addr(L, idx);
     662             :   api_check(L, ttistable(t), "table expected");
     663      361785 :   setobj2s(L, L->top, luaH_getint(hvalue(t), n));
     664      361785 :   api_incr_top(L);
     665             :   lua_unlock(L);
     666      361785 :   return ttnov(L->top - 1);
     667             : }
     668             : 
     669             : 
     670           0 : LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
     671             :   StkId t;
     672             :   TValue k;
     673             :   lua_lock(L);
     674           0 :   t = index2addr(L, idx);
     675             :   api_check(L, ttistable(t), "table expected");
     676           0 :   setpvalue(&k, cast(void *, p));
     677           0 :   setobj2s(L, L->top, luaH_get(hvalue(t), &k));
     678           0 :   api_incr_top(L);
     679             :   lua_unlock(L);
     680           0 :   return ttnov(L->top - 1);
     681             : }
     682             : 
     683             : 
     684        1677 : LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
     685             :   Table *t;
     686             :   lua_lock(L);
     687        1677 :   t = luaH_new(L);
     688        1677 :   sethvalue(L, L->top, t);
     689        1677 :   api_incr_top(L);
     690        1677 :   if (narray > 0 || nrec > 0)
     691        1401 :     luaH_resize(L, t, narray, nrec);
     692        1677 :   luaC_checkGC(L);
     693             :   lua_unlock(L);
     694        1677 : }
     695             : 
     696             : 
     697     3228751 : LUA_API int lua_getmetatable (lua_State *L, int objindex) {
     698             :   const TValue *obj;
     699             :   Table *mt;
     700     3228751 :   int res = 0;
     701             :   lua_lock(L);
     702     3228751 :   obj = index2addr(L, objindex);
     703     3228751 :   switch (ttnov(obj)) {
     704       30236 :     case LUA_TTABLE:
     705       30236 :       mt = hvalue(obj)->metatable;
     706       30236 :       break;
     707     3187836 :     case LUA_TUSERDATA:
     708     3187836 :       mt = uvalue(obj)->metatable;
     709     3187836 :       break;
     710       10679 :     default:
     711       10679 :       mt = G(L)->mt[ttnov(obj)];
     712       10679 :       break;
     713             :   }
     714     3228751 :   if (mt != NULL) {
     715     3198198 :     sethvalue(L, L->top, mt);
     716     3198198 :     api_incr_top(L);
     717     3198198 :     res = 1;
     718             :   }
     719             :   lua_unlock(L);
     720     3228751 :   return res;
     721             : }
     722             : 
     723             : 
     724           0 : LUA_API int lua_getuservalue (lua_State *L, int idx) {
     725             :   StkId o;
     726             :   lua_lock(L);
     727           0 :   o = index2addr(L, idx);
     728             :   api_check(L, ttisfulluserdata(o), "full userdata expected");
     729           0 :   getuservalue(L, uvalue(o), L->top);
     730           0 :   api_incr_top(L);
     731             :   lua_unlock(L);
     732           0 :   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       13518 : static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
     744             :   const TValue *slot;
     745       13518 :   TString *str = luaS_new(L, k);
     746             :   api_checknelems(L, 1);
     747       13518 :   if (luaV_fastset(L, t, str, slot, luaH_getstr, L->top - 1))
     748         721 :     L->top--;  /* pop value */
     749             :   else {
     750       12797 :     setsvalue2s(L, L->top, str);  /* push 'str' (to make it a TValue) */
     751       12797 :     api_incr_top(L);
     752       12797 :     luaV_finishset(L, t, L->top - 1, L->top - 2, slot);
     753       12797 :     L->top -= 2;  /* pop value and key */
     754             :   }
     755             :   lua_unlock(L);  /* lock done by caller */
     756       13518 : }
     757             : 
     758             : 
     759           0 : LUA_API void lua_setglobal (lua_State *L, const char *name) {
     760           0 :   Table *reg = hvalue(&G(L)->l_registry);
     761             :   lua_lock(L);  /* unlock done in 'auxsetstr' */
     762           0 :   auxsetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name);
     763           0 : }
     764             : 
     765             : 
     766         983 : LUA_API void lua_settable (lua_State *L, int idx) {
     767             :   StkId t;
     768             :   lua_lock(L);
     769             :   api_checknelems(L, 2);
     770         983 :   t = index2addr(L, idx);
     771         983 :   luaV_settable(L, t, L->top - 2, L->top - 1);
     772         983 :   L->top -= 2;  /* pop index and value */
     773             :   lua_unlock(L);
     774         983 : }
     775             : 
     776             : 
     777       13518 : LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
     778             :   lua_lock(L);  /* unlock done in 'auxsetstr' */
     779       13518 :   auxsetstr(L, index2addr(L, idx), k);
     780       13518 : }
     781             : 
     782             : 
     783         170 : 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         170 :   t = index2addr(L, idx);
     789         170 :   if (luaV_fastset(L, t, n, slot, luaH_getint, L->top - 1))
     790           2 :     L->top--;  /* pop value */
     791             :   else {
     792         168 :     setivalue(L->top, n);
     793         168 :     api_incr_top(L);
     794         168 :     luaV_finishset(L, t, L->top - 1, L->top - 2, slot);
     795         168 :     L->top -= 2;  /* pop value and key */
     796             :   }
     797             :   lua_unlock(L);
     798         170 : }
     799             : 
     800             : 
     801           0 : 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           0 :   o = index2addr(L, idx);
     807             :   api_check(L, ttistable(o), "table expected");
     808           0 :   slot = luaH_set(L, hvalue(o), L->top - 2);
     809           0 :   setobj2t(L, slot, L->top - 1);
     810           0 :   invalidateTMcache(hvalue(o));
     811           0 :   luaC_barrierback(L, hvalue(o), L->top-1);
     812           0 :   L->top -= 2;
     813             :   lua_unlock(L);
     814           0 : }
     815             : 
     816             : 
     817      361740 : 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      361740 :   o = index2addr(L, idx);
     822             :   api_check(L, ttistable(o), "table expected");
     823      361740 :   luaH_setint(L, hvalue(o), n, L->top - 1);
     824      361740 :   luaC_barrierback(L, hvalue(o), L->top-1);
     825      361740 :   L->top--;
     826             :   lua_unlock(L);
     827      361740 : }
     828             : 
     829             : 
     830           0 : 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           0 :   o = index2addr(L, idx);
     836             :   api_check(L, ttistable(o), "table expected");
     837           0 :   setpvalue(&k, cast(void *, p));
     838           0 :   slot = luaH_set(L, hvalue(o), &k);
     839           0 :   setobj2t(L, slot, L->top - 1);
     840           0 :   luaC_barrierback(L, hvalue(o), L->top - 1);
     841           0 :   L->top--;
     842             :   lua_unlock(L);
     843           0 : }
     844             : 
     845             : 
     846      909162 : 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      909162 :   obj = index2addr(L, objindex);
     852      909162 :   if (ttisnil(L->top - 1))
     853           0 :     mt = NULL;
     854             :   else {
     855             :     api_check(L, ttistable(L->top - 1), "table expected");
     856      909162 :     mt = hvalue(L->top - 1);
     857             :   }
     858      909162 :   switch (ttnov(obj)) {
     859        6840 :     case LUA_TTABLE: {
     860        6840 :       hvalue(obj)->metatable = mt;
     861        6840 :       if (mt) {
     862        6840 :         luaC_objbarrier(L, gcvalue(obj), mt);
     863        6840 :         luaC_checkfinalizer(L, gcvalue(obj), mt);
     864             :       }
     865        6840 :       break;
     866             :     }
     867      902225 :     case LUA_TUSERDATA: {
     868      902225 :       uvalue(obj)->metatable = mt;
     869      902225 :       if (mt) {
     870      902225 :         luaC_objbarrier(L, uvalue(obj), mt);
     871      902225 :         luaC_checkfinalizer(L, gcvalue(obj), mt);
     872             :       }
     873      902225 :       break;
     874             :     }
     875          97 :     default: {
     876          97 :       G(L)->mt[ttnov(obj)] = mt;
     877          97 :       break;
     878             :     }
     879             :   }
     880      909162 :   L->top--;
     881             :   lua_unlock(L);
     882      909162 :   return 1;
     883             : }
     884             : 
     885             : 
     886           0 : LUA_API void lua_setuservalue (lua_State *L, int idx) {
     887             :   StkId o;
     888             :   lua_lock(L);
     889             :   api_checknelems(L, 1);
     890           0 :   o = index2addr(L, idx);
     891             :   api_check(L, ttisfulluserdata(o), "full userdata expected");
     892           0 :   setuservalue(L, uvalue(o), L->top - 1);
     893           0 :   luaC_barrier(L, gcvalue(o), L->top - 1);
     894           0 :   L->top--;
     895             :   lua_unlock(L);
     896           0 : }
     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          54 : 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          54 :   func = L->top - (nargs+1);
     919          54 :   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          54 :     luaD_callnoyield(L, func, nresults);  /* just do the call */
     926          54 :   adjustresults(L, nresults);
     927             :   lua_unlock(L);
     928          54 : }
     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      117827 : static void f_call (lua_State *L, void *ud) {
     942      117827 :   struct CallS *c = cast(struct CallS *, ud);
     943      117827 :   luaD_callnoyield(L, c->func, c->nresults);
     944      117722 : }
     945             : 
     946             : 
     947             : 
     948      117827 : 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      117827 :   if (errfunc == 0)
     960      117827 :     func = 0;
     961             :   else {
     962           0 :     StkId o = index2addr(L, errfunc);
     963             :     api_checkstackindex(L, errfunc, o);
     964           0 :     func = savestack(L, o);
     965             :   }
     966      117827 :   c.func = L->top - (nargs+1);  /* function to be called */
     967      117827 :   if (k == NULL || L->nny > 0) {  /* no continuation or no yieldable? */
     968      117827 :     c.nresults = nresults;  /* do a 'conventional' protected call */
     969      117827 :     status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
     970             :   }
     971             :   else {  /* prepare continuation (call is already protected by 'resume') */
     972           0 :     CallInfo *ci = L->ci;
     973           0 :     ci->u.c.k = k;  /* save continuation */
     974           0 :     ci->u.c.ctx = ctx;  /* save context */
     975             :     /* save information for error recovery */
     976           0 :     ci->extra = savestack(L, c.func);
     977           0 :     ci->u.c.old_errfunc = L->errfunc;
     978           0 :     L->errfunc = func;
     979           0 :     setoah(ci->callstatus, L->allowhook);  /* save value of 'allowhook' */
     980           0 :     ci->callstatus |= CIST_YPCALL;  /* function can do error recovery */
     981           0 :     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      117780 :   adjustresults(L, nresults);
     987             :   lua_unlock(L);
     988      117780 :   return status;
     989             : }
     990             : 
     991             : 
     992         120 : 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         120 :   if (!chunkname) chunkname = "?";
     998         120 :   luaZ_init(L, &z, reader, data);
     999         120 :   status = luaD_protectedparser(L, &z, chunkname, mode);
    1000         120 :   if (status == LUA_OK) {  /* no errors? */
    1001         120 :     LClosure *f = clLvalue(L->top - 1);  /* get newly created function */
    1002         120 :     if (f->nupvalues >= 1) {  /* does it have an upvalue? */
    1003             :       /* get global table from registry */
    1004         120 :       Table *reg = hvalue(&G(L)->l_registry);
    1005         120 :       const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
    1006             :       /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
    1007         120 :       setobj(L, f->upvals[0]->v, gt);
    1008         120 :       luaC_upvalbarrier(L, f->upvals[0]);
    1009             :     }
    1010             :   }
    1011             :   lua_unlock(L);
    1012         120 :   return status;
    1013             : }
    1014             : 
    1015             : 
    1016           0 : 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           0 :   o = L->top - 1;
    1022           0 :   if (isLfunction(o))
    1023           0 :     status = luaU_dump(L, getproto(o), writer, data, strip);
    1024             :   else
    1025           0 :     status = 1;
    1026             :   lua_unlock(L);
    1027           0 :   return status;
    1028             : }
    1029             : 
    1030             : 
    1031           0 : LUA_API int lua_status (lua_State *L) {
    1032           0 :   return L->status;
    1033             : }
    1034             : 
    1035             : 
    1036             : /*
    1037             : ** Garbage-collection function
    1038             : */
    1039             : 
    1040      452321 : LUA_API int lua_gc (lua_State *L, int what, int data) {
    1041      452321 :   int res = 0;
    1042             :   global_State *g;
    1043             :   lua_lock(L);
    1044      452321 :   g = G(L);
    1045      452321 :   switch (what) {
    1046           0 :     case LUA_GCSTOP: {
    1047           0 :       g->gcrunning = 0;
    1048           0 :       break;
    1049             :     }
    1050           0 :     case LUA_GCRESTART: {
    1051           0 :       luaE_setdebt(g, 0);
    1052           0 :       g->gcrunning = 1;
    1053           0 :       break;
    1054             :     }
    1055       90389 :     case LUA_GCCOLLECT: {
    1056       90389 :       luaC_fullgc(L, 0);
    1057       90389 :       break;
    1058             :     }
    1059      180966 :     case LUA_GCCOUNT: {
    1060             :       /* GC values are expressed in Kbytes: #bytes/2^10 */
    1061      180966 :       res = cast_int(gettotalbytes(g) >> 10);
    1062      180966 :       break;
    1063             :     }
    1064      180966 :     case LUA_GCCOUNTB: {
    1065      180966 :       res = cast_int(gettotalbytes(g) & 0x3ff);
    1066      180966 :       break;
    1067             :     }
    1068           0 :     case LUA_GCSTEP: {
    1069           0 :       l_mem debt = 1;  /* =1 to signal that it did an actual step */
    1070           0 :       lu_byte oldrunning = g->gcrunning;
    1071           0 :       g->gcrunning = 1;  /* allow GC to run */
    1072           0 :       if (data == 0) {
    1073           0 :         luaE_setdebt(g, -GCSTEPSIZE);  /* to do a "small" step */
    1074           0 :         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           0 :       g->gcrunning = oldrunning;  /* restore previous state */
    1082           0 :       if (debt > 0 && g->gcstate == GCSpause)  /* end of cycle? */
    1083           0 :         res = 1;  /* signal it */
    1084           0 :       break;
    1085             :     }
    1086           0 :     case LUA_GCSETPAUSE: {
    1087           0 :       res = g->gcpause;
    1088           0 :       g->gcpause = data;
    1089           0 :       break;
    1090             :     }
    1091           0 :     case LUA_GCSETSTEPMUL: {
    1092           0 :       res = g->gcstepmul;
    1093           0 :       if (data < 40) data = 40;  /* avoid ridiculous low values (and 0) */
    1094           0 :       g->gcstepmul = data;
    1095           0 :       break;
    1096             :     }
    1097           0 :     case LUA_GCISRUNNING: {
    1098           0 :       res = g->gcrunning;
    1099           0 :       break;
    1100             :     }
    1101           0 :     default: res = -1;  /* invalid option */
    1102             :   }
    1103             :   lua_unlock(L);
    1104      452321 :   return res;
    1105             : }
    1106             : 
    1107             : 
    1108             : 
    1109             : /*
    1110             : ** miscellaneous functions
    1111             : */
    1112             : 
    1113             : 
    1114          48 : LUA_API int lua_error (lua_State *L) {
    1115             :   lua_lock(L);
    1116             :   api_checknelems(L, 1);
    1117          48 :   luaG_errormsg(L);
    1118             :   /* code unreachable; will unlock when control actually leaves the kernel */
    1119             :   return 0;  /* to avoid warnings */
    1120             : }
    1121             : 
    1122             : 
    1123      230651 : LUA_API int lua_next (lua_State *L, int idx) {
    1124             :   StkId t;
    1125             :   int more;
    1126             :   lua_lock(L);
    1127      230651 :   t = index2addr(L, idx);
    1128             :   api_check(L, ttistable(t), "table expected");
    1129      230651 :   more = luaH_next(L, hvalue(t), L->top - 1);
    1130      230651 :   if (more) {
    1131      207210 :     api_incr_top(L);
    1132             :   }
    1133             :   else  /* no more elements */
    1134       23441 :     L->top -= 1;  /* remove key */
    1135             :   lua_unlock(L);
    1136      230651 :   return more;
    1137             : }
    1138             : 
    1139             : 
    1140          48 : LUA_API void lua_concat (lua_State *L, int n) {
    1141             :   lua_lock(L);
    1142             :   api_checknelems(L, n);
    1143          48 :   if (n >= 2) {
    1144          48 :     luaV_concat(L, n);
    1145             :   }
    1146           0 :   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          48 :   luaC_checkGC(L);
    1152             :   lua_unlock(L);
    1153          48 : }
    1154             : 
    1155             : 
    1156         348 : LUA_API void lua_len (lua_State *L, int idx) {
    1157             :   StkId t;
    1158             :   lua_lock(L);
    1159         348 :   t = index2addr(L, idx);
    1160         348 :   luaV_objlen(L, L->top, t);
    1161         348 :   api_incr_top(L);
    1162             :   lua_unlock(L);
    1163         348 : }
    1164             : 
    1165             : 
    1166          50 : LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
    1167             :   lua_Alloc f;
    1168             :   lua_lock(L);
    1169          50 :   if (ud) *ud = G(L)->ud;
    1170          50 :   f = G(L)->frealloc;
    1171             :   lua_unlock(L);
    1172          50 :   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      902229 : LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
    1185             :   Udata *u;
    1186             :   lua_lock(L);
    1187      902229 :   u = luaS_newudata(L, size);
    1188      902229 :   setuvalue(L, L->top, u);
    1189      902229 :   api_incr_top(L);
    1190      902229 :   luaC_checkGC(L);
    1191             :   lua_unlock(L);
    1192      902229 :   void *udata = getudatamem(u);
    1193      902229 :   memset(udata, 0, size);
    1194      902229 :   return udata;
    1195             : }
    1196             : 
    1197             : 
    1198             : 
    1199         120 : static const char *aux_upvalue (StkId fi, int n, TValue **val,
    1200             :                                 CClosure **owner, UpVal **uv) {
    1201         120 :   switch (ttype(fi)) {
    1202           0 :     case LUA_TCCL: {  /* C closure */
    1203           0 :       CClosure *f = clCvalue(fi);
    1204           0 :       if (!(1 <= n && n <= f->nupvalues)) return NULL;
    1205           0 :       *val = &f->upvalue[n-1];
    1206           0 :       if (owner) *owner = f;
    1207           0 :       return "";
    1208             :     }
    1209         120 :     case LUA_TLCL: {  /* Lua closure */
    1210         120 :       LClosure *f = clLvalue(fi);
    1211             :       TString *name;
    1212         120 :       Proto *p = f->p;
    1213         120 :       if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
    1214         120 :       *val = f->upvals[n-1]->v;
    1215         120 :       if (uv) *uv = f->upvals[n - 1];
    1216         120 :       name = p->upvalues[n-1].name;
    1217         120 :       return (name == NULL) ? "(*no name)" : getstr(name);
    1218             :     }
    1219           0 :     default: return NULL;  /* not a closure */
    1220             :   }
    1221             : }
    1222             : 
    1223             : 
    1224           0 : LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
    1225             :   const char *name;
    1226           0 :   TValue *val = NULL;  /* to avoid warnings */
    1227             :   lua_lock(L);
    1228           0 :   name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL, NULL);
    1229           0 :   if (name) {
    1230           0 :     setobj2s(L, L->top, val);
    1231           0 :     api_incr_top(L);
    1232             :   }
    1233             :   lua_unlock(L);
    1234           0 :   return name;
    1235             : }
    1236             : 
    1237             : 
    1238         120 : LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
    1239             :   const char *name;
    1240         120 :   TValue *val = NULL;  /* to avoid warnings */
    1241         120 :   CClosure *owner = NULL;
    1242         120 :   UpVal *uv = NULL;
    1243             :   StkId fi;
    1244             :   lua_lock(L);
    1245         120 :   fi = index2addr(L, funcindex);
    1246             :   api_checknelems(L, 1);
    1247         120 :   name = aux_upvalue(fi, n, &val, &owner, &uv);
    1248         120 :   if (name) {
    1249         120 :     L->top--;
    1250         120 :     setobj(L, val, L->top);
    1251         120 :     if (owner) { luaC_barrier(L, owner, L->top); }
    1252         120 :     else if (uv) { luaC_upvalbarrier(L, uv); }
    1253             :   }
    1254             :   lua_unlock(L);
    1255         120 :   return name;
    1256             : }
    1257             : 
    1258             : 
    1259           0 : static UpVal **getupvalref (lua_State *L, int fidx, int n) {
    1260             :   LClosure *f;
    1261           0 :   StkId fi = index2addr(L, fidx);
    1262             :   api_check(L, ttisLclosure(fi), "Lua function expected");
    1263           0 :   f = clLvalue(fi);
    1264             :   api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
    1265           0 :   return &f->upvals[n - 1];  /* get its upvalue pointer */
    1266             : }
    1267             : 
    1268             : 
    1269           0 : LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
    1270           0 :   StkId fi = index2addr(L, fidx);
    1271           0 :   switch (ttype(fi)) {
    1272           0 :     case LUA_TLCL: {  /* lua closure */
    1273           0 :       return *getupvalref(L, fidx, n);
    1274             :     }
    1275           0 :     case LUA_TCCL: {  /* C closure */
    1276           0 :       CClosure *f = clCvalue(fi);
    1277             :       api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index");
    1278           0 :       return &f->upvalue[n - 1];
    1279             :     }
    1280           0 :     default: {
    1281             :       api_check(L, 0, "closure expected");
    1282           0 :       return NULL;
    1283             :     }
    1284             :   }
    1285             : }
    1286             : 
    1287             : 
    1288           0 : LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
    1289             :                                             int fidx2, int n2) {
    1290           0 :   UpVal **up1 = getupvalref(L, fidx1, n1);
    1291           0 :   UpVal **up2 = getupvalref(L, fidx2, n2);
    1292           0 :   if (*up1 == *up2)
    1293           0 :     return;
    1294           0 :   luaC_upvdeccount(L, *up1);
    1295           0 :   *up1 = *up2;
    1296           0 :   (*up1)->refcount++;
    1297           0 :   if (upisopen(*up1)) (*up1)->u.open.touched = 1;
    1298           0 :   luaC_upvalbarrier(L, *up1);
    1299             : }
    1300             : 
    1301             : 

Generated by: LCOV version 1.14