LCOV - code coverage report
Current view: top level - src - lapi.c Coverage Total Hit
Test: Lua 5.1.5 Lines: 91.7 % 503 461
Test Date: 2024-04-28 10:23:09
Legend: Lines: hit not hit

            Line data    Source code
       1              : /*
       2              : ** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $
       3              : ** Lua API
       4              : ** See Copyright Notice in lua.h
       5              : */
       6              : 
       7              : 
       8              : #include <assert.h>
       9              : #include <math.h>
      10              : #include <stdarg.h>
      11              : #include <string.h>
      12              : 
      13              : #define lapi_c
      14              : #define LUA_CORE
      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              :   "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n"
      36              :   "$Authors: " LUA_AUTHORS " $\n"
      37              :   "$URL: www.lua.org $\n";
      38              : 
      39              : 
      40              : 
      41              : #define api_checknelems(L, n)   api_check(L, (n) <= (L->top - L->base))
      42              : 
      43              : #define api_checkvalidindex(L, i)       api_check(L, (i) != luaO_nilobject)
      44              : 
      45              : #define api_incr_top(L)   {api_check(L, L->top < L->ci->top); L->top++;}
      46              : 
      47              : 
      48              : 
      49      1210515 : static TValue *index2adr (lua_State *L, int idx) {
      50      1210515 :   if (idx > 0) {
      51       744762 :     TValue *o = L->base + (idx - 1);
      52              :     api_check(L, idx <= L->ci->top - L->base);
      53       744762 :     if (o >= L->top) return cast(TValue *, luaO_nilobject);
      54       713825 :     else return o;
      55              :   }
      56       465753 :   else if (idx > LUA_REGISTRYINDEX) {
      57              :     api_check(L, idx != 0 && -idx <= L->top - L->base);
      58       452903 :     return L->top + idx;
      59              :   }
      60        12850 :   else switch (idx) {  /* pseudo-indices */
      61         2636 :     case LUA_REGISTRYINDEX: return registry(L);
      62          884 :     case LUA_ENVIRONINDEX: {
      63          884 :       Closure *func = curr_func(L);
      64          884 :       sethvalue(L, &L->env, func->c.env);
      65          884 :       return &L->env;
      66              :     }
      67         3150 :     case LUA_GLOBALSINDEX: return gt(L);
      68         6180 :     default: {
      69         6180 :       Closure *func = curr_func(L);
      70         6180 :       idx = LUA_GLOBALSINDEX - idx;
      71         6180 :       return (idx <= func->c.nupvalues)
      72         6180 :                 ? &func->c.upvalue[idx-1]
      73         6180 :                 : cast(TValue *, luaO_nilobject);
      74              :     }
      75              :   }
      76              : }
      77              : 
      78              : 
      79        13305 : static Table *getcurrenv (lua_State *L) {
      80        13305 :   if (L->ci == L->base_ci)  /* no enclosing function? */
      81           95 :     return hvalue(gt(L));  /* use global table as environment */
      82              :   else {
      83        13210 :     Closure *func = curr_func(L);
      84        13210 :     return func->c.env;
      85              :   }
      86              : }
      87              : 
      88              : 
      89            1 : void luaA_pushobject (lua_State *L, const TValue *o) {
      90            1 :   setobj2s(L, L->top, o);
      91            1 :   api_incr_top(L);
      92            1 : }
      93              : 
      94              : 
      95        18526 : LUA_API int lua_checkstack (lua_State *L, int size) {
      96        18526 :   int res = 1;
      97              :   lua_lock(L);
      98        18526 :   if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK)
      99            0 :     res = 0;  /* stack overflow */
     100        18526 :   else if (size > 0) {
     101        12580 :     luaD_checkstack(L, size);
     102        12580 :     if (L->ci->top < L->top + size)
     103         6002 :       L->ci->top = L->top + size;
     104              :   }
     105              :   lua_unlock(L);
     106        18526 :   return res;
     107              : }
     108              : 
     109              : 
     110        11953 : LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
     111              :   int i;
     112        11953 :   if (from == to) return;
     113              :   lua_lock(to);
     114              :   api_checknelems(from, n);
     115              :   api_check(from, G(from) == G(to));
     116              :   api_check(from, to->ci->top - to->top >= n);
     117        11947 :   from->top -= n;
     118        17956 :   for (i = 0; i < n; i++) {
     119         6009 :     setobj2s(to, to->top++, from->top + i);
     120              :   }
     121              :   lua_unlock(to);
     122              : }
     123              : 
     124              : 
     125         5962 : LUA_API void lua_setlevel (lua_State *from, lua_State *to) {
     126         5962 :   to->nCcalls = from->nCcalls;
     127         5962 : }
     128              : 
     129              : 
     130           95 : LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
     131              :   lua_CFunction old;
     132              :   lua_lock(L);
     133           95 :   old = G(L)->panic;
     134           95 :   G(L)->panic = panicf;
     135              :   lua_unlock(L);
     136           95 :   return old;
     137              : }
     138              : 
     139              : 
     140           24 : LUA_API lua_State *lua_newthread (lua_State *L) {
     141              :   lua_State *L1;
     142              :   lua_lock(L);
     143           24 :   luaC_checkGC(L);
     144           24 :   L1 = luaE_newthread(L);
     145           24 :   setthvalue(L, L->top, L1);
     146           24 :   api_incr_top(L);
     147              :   lua_unlock(L);
     148              :   luai_userstatethread(L, L1);
     149           24 :   return L1;
     150              : }
     151              : 
     152              : 
     153              : 
     154              : /*
     155              : ** basic stack manipulation
     156              : */
     157              : 
     158              : 
     159        27366 : LUA_API int lua_gettop (lua_State *L) {
     160        27366 :   return cast_int(L->top - L->base);
     161              : }
     162              : 
     163              : 
     164       150124 : LUA_API void lua_settop (lua_State *L, int idx) {
     165              :   lua_lock(L);
     166       150124 :   if (idx >= 0) {
     167              :     api_check(L, idx <= L->stack_last - L->base);
     168        12192 :     while (L->top < L->base + idx)
     169         5925 :       setnilvalue(L->top++);
     170         6267 :     L->top = L->base + idx;
     171              :   }
     172              :   else {
     173              :     api_check(L, -(idx+1) <= (L->top - L->base));
     174       143857 :     L->top += idx+1;  /* `subtract' index (index is negative) */
     175              :   }
     176              :   lua_unlock(L);
     177       150124 : }
     178              : 
     179              : 
     180         4481 : LUA_API void lua_remove (lua_State *L, int idx) {
     181              :   StkId p;
     182              :   lua_lock(L);
     183         4481 :   p = index2adr(L, idx);
     184              :   api_checkvalidindex(L, p);
     185         8760 :   while (++p < L->top) setobjs2s(L, p-1, p);
     186         4481 :   L->top--;
     187              :   lua_unlock(L);
     188         4481 : }
     189              : 
     190              : 
     191         7514 : LUA_API void lua_insert (lua_State *L, int idx) {
     192              :   StkId p;
     193              :   StkId q;
     194              :   lua_lock(L);
     195         7514 :   p = index2adr(L, idx);
     196              :   api_checkvalidindex(L, p);
     197        21607 :   for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
     198         7514 :   setobjs2s(L, p, L->top);
     199              :   lua_unlock(L);
     200         7514 : }
     201              : 
     202              : 
     203          183 : LUA_API void lua_replace (lua_State *L, int idx) {
     204              :   StkId o;
     205              :   lua_lock(L);
     206              :   /* explicit test for incompatible code */
     207          183 :   if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci)
     208            0 :     luaG_runerror(L, "no calling environment");
     209              :   api_checknelems(L, 1);
     210          183 :   o = index2adr(L, idx);
     211              :   api_checkvalidindex(L, o);
     212          183 :   if (idx == LUA_ENVIRONINDEX) {
     213          166 :     Closure *func = curr_func(L);
     214              :     api_check(L, ttistable(L->top - 1)); 
     215          166 :     func->c.env = hvalue(L->top - 1);
     216          166 :     luaC_barrier(L, func, L->top - 1);
     217              :   }
     218              :   else {
     219           17 :     setobj(L, o, L->top - 1);
     220           17 :     if (idx < LUA_GLOBALSINDEX)  /* function upvalue? */
     221           10 :       luaC_barrier(L, curr_func(L), L->top - 1);
     222              :   }
     223          183 :   L->top--;
     224              :   lua_unlock(L);
     225          183 : }
     226              : 
     227              : 
     228        32371 : LUA_API void lua_pushvalue (lua_State *L, int idx) {
     229              :   lua_lock(L);
     230        32371 :   setobj2s(L, L->top, index2adr(L, idx));
     231        32371 :   api_incr_top(L);
     232              :   lua_unlock(L);
     233        32371 : }
     234              : 
     235              : 
     236              : 
     237              : /*
     238              : ** access functions (stack -> C)
     239              : */
     240              : 
     241              : 
     242       362126 : LUA_API int lua_type (lua_State *L, int idx) {
     243       362126 :   StkId o = index2adr(L, idx);
     244       362126 :   return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
     245              : }
     246              : 
     247              : 
     248          176 : LUA_API const char *lua_typename (lua_State *L, int t) {
     249              :   UNUSED(L);
     250          176 :   return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
     251              : }
     252              : 
     253              : 
     254           49 : LUA_API int lua_iscfunction (lua_State *L, int idx) {
     255           49 :   StkId o = index2adr(L, idx);
     256           49 :   return iscfunction(o);
     257              : }
     258              : 
     259              : 
     260         6124 : LUA_API int lua_isnumber (lua_State *L, int idx) {
     261              :   TValue n;
     262         6124 :   const TValue *o = index2adr(L, idx);
     263         6124 :   return tonumber(o, &n);
     264              : }
     265              : 
     266              : 
     267        81211 : LUA_API int lua_isstring (lua_State *L, int idx) {
     268        81211 :   int t = lua_type(L, idx);
     269        81211 :   return (t == LUA_TSTRING || t == LUA_TNUMBER);
     270              : }
     271              : 
     272              : 
     273            0 : LUA_API int lua_isuserdata (lua_State *L, int idx) {
     274            0 :   const TValue *o = index2adr(L, idx);
     275            0 :   return (ttisuserdata(o) || ttislightuserdata(o));
     276              : }
     277              : 
     278              : 
     279          709 : LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
     280          709 :   StkId o1 = index2adr(L, index1);
     281          709 :   StkId o2 = index2adr(L, index2);
     282          709 :   return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
     283         1418 :          : luaO_rawequalObj(o1, o2);
     284              : }
     285              : 
     286              : 
     287            0 : LUA_API int lua_equal (lua_State *L, int index1, int index2) {
     288              :   StkId o1, o2;
     289              :   int i;
     290              :   lua_lock(L);  /* may call tag method */
     291            0 :   o1 = index2adr(L, index1);
     292            0 :   o2 = index2adr(L, index2);
     293            0 :   i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2);
     294              :   lua_unlock(L);
     295            0 :   return i;
     296              : }
     297              : 
     298              : 
     299        91608 : LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
     300              :   StkId o1, o2;
     301              :   int i;
     302              :   lua_lock(L);  /* may call tag method */
     303        91608 :   o1 = index2adr(L, index1);
     304        91608 :   o2 = index2adr(L, index2);
     305        91608 :   i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
     306       183216 :        : luaV_lessthan(L, o1, o2);
     307              :   lua_unlock(L);
     308        91608 :   return i;
     309              : }
     310              : 
     311              : 
     312              : 
     313          256 : LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
     314              :   TValue n;
     315          256 :   const TValue *o = index2adr(L, idx);
     316          256 :   if (tonumber(o, &n))
     317          253 :     return nvalue(o);
     318              :   else
     319            3 :     return 0;
     320              : }
     321              : 
     322              : 
     323        59127 : LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
     324              :   TValue n;
     325        59127 :   const TValue *o = index2adr(L, idx);
     326        59127 :   if (tonumber(o, &n)) {
     327              :     lua_Integer res;
     328        59125 :     lua_Number num = nvalue(o);
     329        59125 :     lua_number2integer(res, num);
     330        59125 :     return res;
     331              :   }
     332              :   else
     333            2 :     return 0;
     334              : }
     335              : 
     336              : 
     337         6143 : LUA_API int lua_toboolean (lua_State *L, int idx) {
     338         6143 :   const TValue *o = index2adr(L, idx);
     339         6143 :   return !l_isfalse(o);
     340              : }
     341              : 
     342              : 
     343       108270 : LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
     344       108270 :   StkId o = index2adr(L, idx);
     345       108270 :   if (!ttisstring(o)) {
     346              :     lua_lock(L);  /* `luaV_tostring' may create a new string */
     347         1823 :     if (!luaV_tostring(L, o)) {  /* conversion failed? */
     348            9 :       if (len != NULL) *len = 0;
     349              :       lua_unlock(L);
     350            9 :       return NULL;
     351              :     }
     352         1814 :     luaC_checkGC(L);
     353         1814 :     o = index2adr(L, idx);  /* previous call may reallocate the stack */
     354              :     lua_unlock(L);
     355              :   }
     356       108261 :   if (len != NULL) *len = tsvalue(o)->len;
     357       108261 :   return svalue(o);
     358              : }
     359              : 
     360              : 
     361        18008 : LUA_API size_t lua_objlen (lua_State *L, int idx) {
     362        18008 :   StkId o = index2adr(L, idx);
     363        18008 :   switch (ttype(o)) {
     364           36 :     case LUA_TSTRING: return tsvalue(o)->len;
     365            0 :     case LUA_TUSERDATA: return uvalue(o)->len;
     366        17972 :     case LUA_TTABLE: return luaH_getn(hvalue(o));
     367            0 :     case LUA_TNUMBER: {
     368              :       size_t l;
     369              :       lua_lock(L);  /* `luaV_tostring' may create a new string */
     370            0 :       l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
     371              :       lua_unlock(L);
     372            0 :       return l;
     373              :     }
     374            0 :     default: return 0;
     375              :   }
     376              : }
     377              : 
     378              : 
     379          331 : LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
     380          331 :   StkId o = index2adr(L, idx);
     381          331 :   return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;
     382              : }
     383              : 
     384              : 
     385         1090 : LUA_API void *lua_touserdata (lua_State *L, int idx) {
     386         1090 :   StkId o = index2adr(L, idx);
     387         1090 :   switch (ttype(o)) {
     388          873 :     case LUA_TUSERDATA: return (rawuvalue(o) + 1);
     389          141 :     case LUA_TLIGHTUSERDATA: return pvalue(o);
     390           76 :     default: return NULL;
     391              :   }
     392              : }
     393              : 
     394              : 
     395         5970 : LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
     396         5970 :   StkId o = index2adr(L, idx);
     397         5970 :   return (!ttisthread(o)) ? NULL : thvalue(o);
     398              : }
     399              : 
     400              : 
     401            6 : LUA_API const void *lua_topointer (lua_State *L, int idx) {
     402            6 :   StkId o = index2adr(L, idx);
     403            6 :   switch (ttype(o)) {
     404            1 :     case LUA_TTABLE: return hvalue(o);
     405            4 :     case LUA_TFUNCTION: return clvalue(o);
     406            1 :     case LUA_TTHREAD: return thvalue(o);
     407            0 :     case LUA_TUSERDATA:
     408              :     case LUA_TLIGHTUSERDATA:
     409            0 :       return lua_touserdata(L, idx);
     410            0 :     default: return NULL;
     411              :   }
     412              : }
     413              : 
     414              : 
     415              : 
     416              : /*
     417              : ** push functions (C -> stack)
     418              : */
     419              : 
     420              : 
     421          641 : LUA_API void lua_pushnil (lua_State *L) {
     422              :   lua_lock(L);
     423          641 :   setnilvalue(L->top);
     424          641 :   api_incr_top(L);
     425              :   lua_unlock(L);
     426          641 : }
     427              : 
     428              : 
     429          411 : LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
     430              :   lua_lock(L);
     431          411 :   setnvalue(L->top, n);
     432          411 :   api_incr_top(L);
     433              :   lua_unlock(L);
     434          411 : }
     435              : 
     436              : 
     437        52515 : LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
     438              :   lua_lock(L);
     439        52515 :   setnvalue(L->top, cast_num(n));
     440        52515 :   api_incr_top(L);
     441              :   lua_unlock(L);
     442        52515 : }
     443              : 
     444              : 
     445        30866 : LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
     446              :   lua_lock(L);
     447        30866 :   luaC_checkGC(L);
     448        30866 :   setsvalue2s(L, L->top, luaS_newlstr(L, s, len));
     449        30866 :   api_incr_top(L);
     450              :   lua_unlock(L);
     451        30866 : }
     452              : 
     453              : 
     454         6099 : LUA_API void lua_pushstring (lua_State *L, const char *s) {
     455         6099 :   if (s == NULL)
     456            5 :     lua_pushnil(L);
     457              :   else
     458         6094 :     lua_pushlstring(L, s, strlen(s));
     459         6099 : }
     460              : 
     461              : 
     462          131 : LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
     463              :                                       va_list argp) {
     464              :   const char *ret;
     465              :   lua_lock(L);
     466          131 :   luaC_checkGC(L);
     467          131 :   ret = luaO_pushvfstring(L, fmt, argp);
     468              :   lua_unlock(L);
     469          131 :   return ret;
     470              : }
     471              : 
     472              : 
     473         1199 : LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
     474              :   const char *ret;
     475              :   va_list argp;
     476              :   lua_lock(L);
     477         1199 :   luaC_checkGC(L);
     478         1199 :   va_start(argp, fmt);
     479         1199 :   ret = luaO_pushvfstring(L, fmt, argp);
     480         1199 :   va_end(argp);
     481              :   lua_unlock(L);
     482         1199 :   return ret;
     483              : }
     484              : 
     485              : 
     486        12846 : LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
     487              :   Closure *cl;
     488              :   lua_lock(L);
     489        12846 :   luaC_checkGC(L);
     490              :   api_checknelems(L, n);
     491        12846 :   cl = luaF_newCclosure(L, n, getcurrenv(L));
     492        12846 :   cl->c.f = fn;
     493        12846 :   L->top -= n;
     494        13123 :   while (n--)
     495          277 :     setobj2n(L, &cl->c.upvalue[n], L->top+n);
     496        12846 :   setclvalue(L, L->top, cl);
     497              :   lua_assert(iswhite(obj2gco(cl)));
     498        12846 :   api_incr_top(L);
     499              :   lua_unlock(L);
     500        12846 : }
     501              : 
     502              : 
     503         6702 : LUA_API void lua_pushboolean (lua_State *L, int b) {
     504              :   lua_lock(L);
     505         6702 :   setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
     506         6702 :   api_incr_top(L);
     507              :   lua_unlock(L);
     508         6702 : }
     509              : 
     510              : 
     511          596 : LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
     512              :   lua_lock(L);
     513          596 :   setpvalue(L->top, p);
     514          596 :   api_incr_top(L);
     515              :   lua_unlock(L);
     516          596 : }
     517              : 
     518              : 
     519            2 : LUA_API int lua_pushthread (lua_State *L) {
     520              :   lua_lock(L);
     521            2 :   setthvalue(L, L->top, L);
     522            2 :   api_incr_top(L);
     523              :   lua_unlock(L);
     524            2 :   return (G(L)->mainthread == L);
     525              : }
     526              : 
     527              : 
     528              : 
     529              : /*
     530              : ** get functions (Lua -> stack)
     531              : */
     532              : 
     533              : 
     534            9 : LUA_API void lua_gettable (lua_State *L, int idx) {
     535              :   StkId t;
     536              :   lua_lock(L);
     537            9 :   t = index2adr(L, idx);
     538              :   api_checkvalidindex(L, t);
     539            9 :   luaV_gettable(L, t, L->top - 1, L->top - 1);
     540              :   lua_unlock(L);
     541            9 : }
     542              : 
     543              : 
     544         5604 : LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
     545              :   StkId t;
     546              :   TValue key;
     547              :   lua_lock(L);
     548         5604 :   t = index2adr(L, idx);
     549              :   api_checkvalidindex(L, t);
     550         5604 :   setsvalue(L, &key, luaS_new(L, k));
     551         5604 :   luaV_gettable(L, t, &key, L->top);
     552         5604 :   api_incr_top(L);
     553              :   lua_unlock(L);
     554         5604 : }
     555              : 
     556              : 
     557         4529 : LUA_API void lua_rawget (lua_State *L, int idx) {
     558              :   StkId t;
     559              :   lua_lock(L);
     560         4529 :   t = index2adr(L, idx);
     561              :   api_check(L, ttistable(t));
     562         4529 :   setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
     563              :   lua_unlock(L);
     564         4529 : }
     565              : 
     566              : 
     567       293447 : LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
     568              :   StkId o;
     569              :   lua_lock(L);
     570       293447 :   o = index2adr(L, idx);
     571              :   api_check(L, ttistable(o));
     572       293447 :   setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
     573       293447 :   api_incr_top(L);
     574              :   lua_unlock(L);
     575       293447 : }
     576              : 
     577              : 
     578         1562 : LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
     579              :   lua_lock(L);
     580         1562 :   luaC_checkGC(L);
     581         1562 :   sethvalue(L, L->top, luaH_new(L, narray, nrec));
     582         1562 :   api_incr_top(L);
     583              :   lua_unlock(L);
     584         1562 : }
     585              : 
     586              : 
     587         5043 : LUA_API int lua_getmetatable (lua_State *L, int objindex) {
     588              :   const TValue *obj;
     589         5043 :   Table *mt = NULL;
     590              :   int res;
     591              :   lua_lock(L);
     592         5043 :   obj = index2adr(L, objindex);
     593         5043 :   switch (ttype(obj)) {
     594          138 :     case LUA_TTABLE:
     595          138 :       mt = hvalue(obj)->metatable;
     596          138 :       break;
     597          715 :     case LUA_TUSERDATA:
     598          715 :       mt = uvalue(obj)->metatable;
     599          715 :       break;
     600         4190 :     default:
     601         4190 :       mt = G(L)->mt[ttype(obj)];
     602         4190 :       break;
     603              :   }
     604         5043 :   if (mt == NULL)
     605         1883 :     res = 0;
     606              :   else {
     607         3160 :     sethvalue(L, L->top, mt);
     608         3160 :     api_incr_top(L);
     609         3160 :     res = 1;
     610              :   }
     611              :   lua_unlock(L);
     612         5043 :   return res;
     613              : }
     614              : 
     615              : 
     616          353 : LUA_API void lua_getfenv (lua_State *L, int idx) {
     617              :   StkId o;
     618              :   lua_lock(L);
     619          353 :   o = index2adr(L, idx);
     620              :   api_checkvalidindex(L, o);
     621          353 :   switch (ttype(o)) {
     622           17 :     case LUA_TFUNCTION:
     623           17 :       sethvalue(L, L->top, clvalue(o)->c.env);
     624           17 :       break;
     625          331 :     case LUA_TUSERDATA:
     626          331 :       sethvalue(L, L->top, uvalue(o)->env);
     627          331 :       break;
     628            4 :     case LUA_TTHREAD:
     629            4 :       setobj2s(L, L->top,  gt(thvalue(o)));
     630            4 :       break;
     631            1 :     default:
     632            1 :       setnilvalue(L->top);
     633            1 :       break;
     634              :   }
     635          353 :   api_incr_top(L);
     636              :   lua_unlock(L);
     637          353 : }
     638              : 
     639              : 
     640              : /*
     641              : ** set functions (stack -> Lua)
     642              : */
     643              : 
     644              : 
     645          750 : LUA_API void lua_settable (lua_State *L, int idx) {
     646              :   StkId t;
     647              :   lua_lock(L);
     648              :   api_checknelems(L, 2);
     649          750 :   t = index2adr(L, idx);
     650              :   api_checkvalidindex(L, t);
     651          750 :   luaV_settable(L, t, L->top - 2, L->top - 1);
     652          750 :   L->top -= 2;  /* pop index and value */
     653              :   lua_unlock(L);
     654          750 : }
     655              : 
     656              : 
     657        14157 : LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
     658              :   StkId t;
     659              :   TValue key;
     660              :   lua_lock(L);
     661              :   api_checknelems(L, 1);
     662        14157 :   t = index2adr(L, idx);
     663              :   api_checkvalidindex(L, t);
     664        14157 :   setsvalue(L, &key, luaS_new(L, k));
     665        14157 :   luaV_settable(L, t, &key, L->top - 1);
     666        14157 :   L->top--;  /* pop value */
     667              :   lua_unlock(L);
     668        14157 : }
     669              : 
     670              : 
     671            7 : LUA_API void lua_rawset (lua_State *L, int idx) {
     672              :   StkId t;
     673              :   lua_lock(L);
     674              :   api_checknelems(L, 2);
     675            7 :   t = index2adr(L, idx);
     676              :   api_check(L, ttistable(t));
     677            7 :   setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
     678            6 :   luaC_barriert(L, hvalue(t), L->top-1);
     679            6 :   L->top -= 2;
     680              :   lua_unlock(L);
     681            6 : }
     682              : 
     683              : 
     684        86873 : LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
     685              :   StkId o;
     686              :   lua_lock(L);
     687              :   api_checknelems(L, 1);
     688        86873 :   o = index2adr(L, idx);
     689              :   api_check(L, ttistable(o));
     690        86873 :   setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
     691        86873 :   luaC_barriert(L, hvalue(o), L->top-1);
     692        86873 :   L->top--;
     693              :   lua_unlock(L);
     694        86873 : }
     695              : 
     696              : 
     697          619 : LUA_API int lua_setmetatable (lua_State *L, int objindex) {
     698              :   TValue *obj;
     699              :   Table *mt;
     700              :   lua_lock(L);
     701              :   api_checknelems(L, 1);
     702          619 :   obj = index2adr(L, objindex);
     703              :   api_checkvalidindex(L, obj);
     704          619 :   if (ttisnil(L->top - 1))
     705            2 :     mt = NULL;
     706              :   else {
     707              :     api_check(L, ttistable(L->top - 1));
     708          617 :     mt = hvalue(L->top - 1);
     709              :   }
     710          619 :   switch (ttype(obj)) {
     711          172 :     case LUA_TTABLE: {
     712          172 :       hvalue(obj)->metatable = mt;
     713          172 :       if (mt)
     714          170 :         luaC_objbarriert(L, hvalue(obj), mt);
     715          172 :       break;
     716              :     }
     717          362 :     case LUA_TUSERDATA: {
     718          362 :       uvalue(obj)->metatable = mt;
     719          362 :       if (mt)
     720          362 :         luaC_objbarrier(L, rawuvalue(obj), mt);
     721          362 :       break;
     722              :     }
     723           85 :     default: {
     724           85 :       G(L)->mt[ttype(obj)] = mt;
     725           85 :       break;
     726              :     }
     727              :   }
     728          619 :   L->top--;
     729              :   lua_unlock(L);
     730          619 :   return 1;
     731              : }
     732              : 
     733              : 
     734          346 : LUA_API int lua_setfenv (lua_State *L, int idx) {
     735              :   StkId o;
     736          346 :   int res = 1;
     737              :   lua_lock(L);
     738              :   api_checknelems(L, 1);
     739          346 :   o = index2adr(L, idx);
     740              :   api_checkvalidindex(L, o);
     741              :   api_check(L, ttistable(L->top - 1));
     742          346 :   switch (ttype(o)) {
     743           94 :     case LUA_TFUNCTION:
     744           94 :       clvalue(o)->c.env = hvalue(L->top - 1);
     745           94 :       break;
     746          249 :     case LUA_TUSERDATA:
     747          249 :       uvalue(o)->env = hvalue(L->top - 1);
     748          249 :       break;
     749            2 :     case LUA_TTHREAD:
     750            2 :       sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1));
     751            2 :       break;
     752            1 :     default:
     753            1 :       res = 0;
     754            1 :       break;
     755              :   }
     756          346 :   if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
     757          346 :   L->top--;
     758              :   lua_unlock(L);
     759          346 :   return res;
     760              : }
     761              : 
     762              : 
     763              : /*
     764              : ** `load' and `call' functions (run Lua code)
     765              : */
     766              : 
     767              : 
     768              : #define adjustresults(L,nres) \
     769              :     { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; }
     770              : 
     771              : 
     772              : #define checkresults(L,na,nr) \
     773              :      api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
     774              :         
     775              : 
     776         3337 : LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
     777              :   StkId func;
     778              :   lua_lock(L);
     779              :   api_checknelems(L, nargs+1);
     780              :   checkresults(L, nargs, nresults);
     781         3337 :   func = L->top - (nargs+1);
     782         3337 :   luaD_call(L, func, nresults);
     783         3334 :   adjustresults(L, nresults);
     784              :   lua_unlock(L);
     785         3334 : }
     786              : 
     787              : 
     788              : 
     789              : /*
     790              : ** Execute a protected call.
     791              : */
     792              : struct CallS {  /* data to `f_call' */
     793              :   StkId func;
     794              :   int nresults;
     795              : };
     796              : 
     797              : 
     798          725 : static void f_call (lua_State *L, void *ud) {
     799          725 :   struct CallS *c = cast(struct CallS *, ud);
     800          725 :   luaD_call(L, c->func, c->nresults);
     801          381 : }
     802              : 
     803              : 
     804              : 
     805          725 : LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
     806              :   struct CallS c;
     807              :   int status;
     808              :   ptrdiff_t func;
     809              :   lua_lock(L);
     810              :   api_checknelems(L, nargs+1);
     811              :   checkresults(L, nargs, nresults);
     812          725 :   if (errfunc == 0)
     813          504 :     func = 0;
     814              :   else {
     815          221 :     StkId o = index2adr(L, errfunc);
     816              :     api_checkvalidindex(L, o);
     817          221 :     func = savestack(L, o);
     818              :   }
     819          725 :   c.func = L->top - (nargs+1);  /* function to be called */
     820          725 :   c.nresults = nresults;
     821          725 :   status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
     822          716 :   adjustresults(L, nresults);
     823              :   lua_unlock(L);
     824          716 :   return status;
     825              : }
     826              : 
     827              : 
     828              : /*
     829              : ** Execute a protected C call.
     830              : */
     831              : struct CCallS {  /* data to `f_Ccall' */
     832              :   lua_CFunction func;
     833              :   void *ud;
     834              : };
     835              : 
     836              : 
     837           95 : static void f_Ccall (lua_State *L, void *ud) {
     838           95 :   struct CCallS *c = cast(struct CCallS *, ud);
     839              :   Closure *cl;
     840           95 :   cl = luaF_newCclosure(L, 0, getcurrenv(L));
     841           95 :   cl->c.f = c->func;
     842           95 :   setclvalue(L, L->top, cl);  /* push function */
     843           95 :   api_incr_top(L);
     844           95 :   setpvalue(L->top, c->ud);  /* push only argument */
     845           95 :   api_incr_top(L);
     846           95 :   luaD_call(L, L->top - 2, 0);
     847           85 : }
     848              : 
     849              : 
     850           95 : LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
     851              :   struct CCallS c;
     852              :   int status;
     853              :   lua_lock(L);
     854           95 :   c.func = func;
     855           95 :   c.ud = ud;
     856           95 :   status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
     857              :   lua_unlock(L);
     858           85 :   return status;
     859              : }
     860              : 
     861              : 
     862          488 : LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
     863              :                       const char *chunkname) {
     864              :   ZIO z;
     865              :   int status;
     866              :   lua_lock(L);
     867          488 :   if (!chunkname) chunkname = "?";
     868          488 :   luaZ_init(L, &z, reader, data);
     869          488 :   status = luaD_protectedparser(L, &z, chunkname);
     870              :   lua_unlock(L);
     871          488 :   return status;
     872              : }
     873              : 
     874              : 
     875            2 : LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
     876              :   int status;
     877              :   TValue *o;
     878              :   lua_lock(L);
     879              :   api_checknelems(L, 1);
     880            2 :   o = L->top - 1;
     881            2 :   if (isLfunction(o))
     882            1 :     status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
     883              :   else
     884            1 :     status = 1;
     885              :   lua_unlock(L);
     886            2 :   return status;
     887              : }
     888              : 
     889              : 
     890         5967 : LUA_API int  lua_status (lua_State *L) {
     891         5967 :   return L->status;
     892              : }
     893              : 
     894              : 
     895              : /*
     896              : ** Garbage-collection function
     897              : */
     898              : 
     899          177 : LUA_API int lua_gc (lua_State *L, int what, int data) {
     900          177 :   int res = 0;
     901              :   global_State *g;
     902              :   lua_lock(L);
     903          177 :   g = G(L);
     904          177 :   switch (what) {
     905           84 :     case LUA_GCSTOP: {
     906           84 :       g->GCthreshold = MAX_LUMEM;
     907           84 :       break;
     908              :     }
     909           84 :     case LUA_GCRESTART: {
     910           84 :       g->GCthreshold = g->totalbytes;
     911           84 :       break;
     912              :     }
     913            5 :     case LUA_GCCOLLECT: {
     914            5 :       luaC_fullgc(L);
     915            5 :       break;
     916              :     }
     917            2 :     case LUA_GCCOUNT: {
     918              :       /* GC values are expressed in Kbytes: #bytes/2^10 */
     919            2 :       res = cast_int(g->totalbytes >> 10);
     920            2 :       break;
     921              :     }
     922            1 :     case LUA_GCCOUNTB: {
     923            1 :       res = cast_int(g->totalbytes & 0x3ff);
     924            1 :       break;
     925              :     }
     926            1 :     case LUA_GCSTEP: {
     927            1 :       lu_mem a = (cast(lu_mem, data) << 10);
     928            1 :       if (a <= g->totalbytes)
     929            1 :         g->GCthreshold = g->totalbytes - a;
     930              :       else
     931            0 :         g->GCthreshold = 0;
     932            2 :       while (g->GCthreshold <= g->totalbytes) {
     933            1 :         luaC_step(L);
     934            1 :         if (g->gcstate == GCSpause) {  /* end of cycle? */
     935            0 :           res = 1;  /* signal it */
     936            0 :           break;
     937              :         }
     938              :       }
     939            1 :       break;
     940              :     }
     941            0 :     case LUA_GCSETPAUSE: {
     942            0 :       res = g->gcpause;
     943            0 :       g->gcpause = data;
     944            0 :       break;
     945              :     }
     946            0 :     case LUA_GCSETSTEPMUL: {
     947            0 :       res = g->gcstepmul;
     948            0 :       g->gcstepmul = data;
     949            0 :       break;
     950              :     }
     951            0 :     default: res = -1;  /* invalid option */
     952              :   }
     953              :   lua_unlock(L);
     954          177 :   return res;
     955              : }
     956              : 
     957              : 
     958              : 
     959              : /*
     960              : ** miscellaneous functions
     961              : */
     962              : 
     963              : 
     964          145 : LUA_API int lua_error (lua_State *L) {
     965              :   lua_lock(L);
     966              :   api_checknelems(L, 1);
     967          145 :   luaG_errormsg(L);
     968              :   lua_unlock(L);
     969            0 :   return 0;  /* to avoid warnings */
     970              : }
     971              : 
     972              : 
     973           57 : LUA_API int lua_next (lua_State *L, int idx) {
     974              :   StkId t;
     975              :   int more;
     976              :   lua_lock(L);
     977           57 :   t = index2adr(L, idx);
     978              :   api_check(L, ttistable(t));
     979           57 :   more = luaH_next(L, hvalue(t), L->top - 1);
     980           56 :   if (more) {
     981           39 :     api_incr_top(L);
     982              :   }
     983              :   else  /* no more elements */
     984           17 :     L->top -= 1;  /* remove key */
     985              :   lua_unlock(L);
     986           56 :   return more;
     987              : }
     988              : 
     989              : 
     990        14851 : LUA_API void lua_concat (lua_State *L, int n) {
     991              :   lua_lock(L);
     992              :   api_checknelems(L, n);
     993        14851 :   if (n >= 2) {
     994         1154 :     luaC_checkGC(L);
     995         1154 :     luaV_concat(L, n, cast_int(L->top - L->base) - 1);
     996         1154 :     L->top -= (n-1);
     997              :   }
     998        13697 :   else if (n == 0) {  /* push empty string */
     999           34 :     setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
    1000           34 :     api_incr_top(L);
    1001              :   }
    1002              :   /* else n == 1; nothing to do */
    1003              :   lua_unlock(L);
    1004        14851 : }
    1005              : 
    1006              : 
    1007            0 : LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
    1008              :   lua_Alloc f;
    1009              :   lua_lock(L);
    1010            0 :   if (ud) *ud = G(L)->ud;
    1011            0 :   f = G(L)->frealloc;
    1012              :   lua_unlock(L);
    1013            0 :   return f;
    1014              : }
    1015              : 
    1016              : 
    1017            0 : LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
    1018              :   lua_lock(L);
    1019            0 :   G(L)->ud = ud;
    1020            0 :   G(L)->frealloc = f;
    1021              :   lua_unlock(L);
    1022            0 : }
    1023              : 
    1024              : 
    1025          364 : LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
    1026              :   Udata *u;
    1027              :   lua_lock(L);
    1028          364 :   luaC_checkGC(L);
    1029          364 :   u = luaS_newudata(L, size, getcurrenv(L));
    1030          364 :   setuvalue(L, L->top, u);
    1031          364 :   api_incr_top(L);
    1032              :   lua_unlock(L);
    1033          364 :   return u + 1;
    1034              : }
    1035              : 
    1036              : 
    1037              : 
    1038              : 
    1039            3 : static const char *aux_upvalue (StkId fi, int n, TValue **val) {
    1040              :   Closure *f;
    1041            3 :   if (!ttisfunction(fi)) return NULL;
    1042            3 :   f = clvalue(fi);
    1043            3 :   if (f->c.isC) {
    1044            0 :     if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
    1045            0 :     *val = &f->c.upvalue[n-1];
    1046            0 :     return "";
    1047              :   }
    1048              :   else {
    1049            3 :     Proto *p = f->l.p;
    1050            3 :     if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
    1051            2 :     *val = f->l.upvals[n-1]->v;
    1052            2 :     return getstr(p->upvalues[n-1]);
    1053              :   }
    1054              : }
    1055              : 
    1056              : 
    1057            1 : LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
    1058              :   const char *name;
    1059              :   TValue *val;
    1060              :   lua_lock(L);
    1061            1 :   name = aux_upvalue(index2adr(L, funcindex), n, &val);
    1062            1 :   if (name) {
    1063            1 :     setobj2s(L, L->top, val);
    1064            1 :     api_incr_top(L);
    1065              :   }
    1066              :   lua_unlock(L);
    1067            1 :   return name;
    1068              : }
    1069              : 
    1070              : 
    1071            2 : LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
    1072              :   const char *name;
    1073              :   TValue *val;
    1074              :   StkId fi;
    1075              :   lua_lock(L);
    1076            2 :   fi = index2adr(L, funcindex);
    1077              :   api_checknelems(L, 1);
    1078            2 :   name = aux_upvalue(fi, n, &val);
    1079            2 :   if (name) {
    1080            1 :     L->top--;
    1081            1 :     setobj(L, val, L->top);
    1082            1 :     luaC_barrier(L, clvalue(fi), L->top);
    1083              :   }
    1084              :   lua_unlock(L);
    1085            2 :   return name;
    1086              : }
    1087              : 
        

Generated by: LCOV version 2.0-1