LCOV - code coverage report
Current view: top level - src - lapi.c Hit Total Coverage
Test: Lua 5.1.5 Lines: 395 477 82.8 %
Date: 2017-04-16 16:03:13
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     1278471 : static TValue *index2adr (lua_State *L, int idx) {
      50     1278471 :   if (idx > 0) {
      51      825563 :     TValue *o = L->base + (idx - 1);
      52             :     api_check(L, idx <= L->ci->top - L->base);
      53      825563 :     if (o >= L->top) return cast(TValue *, luaO_nilobject);
      54      786366 :     else return o;
      55             :   }
      56      452908 :   else if (idx > LUA_REGISTRYINDEX) {
      57             :     api_check(L, idx != 0 && -idx <= L->top - L->base);
      58      441907 :     return L->top + idx;
      59             :   }
      60       11001 :   else switch (idx) {  /* pseudo-indices */
      61        3254 :     case LUA_REGISTRYINDEX: return registry(L);
      62             :     case LUA_ENVIRONINDEX: {
      63         496 :       Closure *func = curr_func(L);
      64         496 :       sethvalue(L, &L->env, func->c.env);
      65         496 :       return &L->env;
      66             :     }
      67        1051 :     case LUA_GLOBALSINDEX: return gt(L);
      68             :     default: {
      69        6200 :       Closure *func = curr_func(L);
      70        6200 :       idx = LUA_GLOBALSINDEX - idx;
      71        6200 :       return (idx <= func->c.nupvalues)
      72        6200 :                 ? &func->c.upvalue[idx-1]
      73       12400 :                 : cast(TValue *, luaO_nilobject);
      74             :     }
      75             :   }
      76             : }
      77             : 
      78             : 
      79        9873 : static Table *getcurrenv (lua_State *L) {
      80        9873 :   if (L->ci == L->base_ci)  /* no enclosing function? */
      81          63 :     return hvalue(gt(L));  /* use global table as environment */
      82             :   else {
      83        9810 :     Closure *func = curr_func(L);
      84        9810 :     return func->c.env;
      85             :   }
      86             : }
      87             : 
      88             : 
      89           0 : void luaA_pushobject (lua_State *L, const TValue *o) {
      90           0 :   setobj2s(L, L->top, o);
      91           0 :   api_incr_top(L);
      92           0 : }
      93             : 
      94             : 
      95       18368 : LUA_API int lua_checkstack (lua_State *L, int size) {
      96       18368 :   int res = 1;
      97             :   lua_lock(L);
      98       18368 :   if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK)
      99           0 :     res = 0;  /* stack overflow */
     100       18368 :   else if (size > 0) {
     101       12424 :     luaD_checkstack(L, size);
     102       12424 :     if (L->ci->top < L->top + size)
     103        5954 :       L->ci->top = L->top + size;
     104             :   }
     105             :   lua_unlock(L);
     106       18368 :   return res;
     107             : }
     108             : 
     109             : 
     110       11943 : LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
     111             :   int i;
     112       11943 :   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       11942 :   from->top -= n;
     118       17947 :   for (i = 0; i < n; i++) {
     119        6005 :     setobj2s(to, to->top++, from->top + i);
     120             :   }
     121             :   lua_unlock(to);
     122             : }
     123             : 
     124             : 
     125        5961 : LUA_API void lua_setlevel (lua_State *from, lua_State *to) {
     126        5961 :   to->nCcalls = from->nCcalls;
     127        5961 : }
     128             : 
     129             : 
     130          63 : LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
     131             :   lua_CFunction old;
     132             :   lua_lock(L);
     133          63 :   old = G(L)->panic;
     134          63 :   G(L)->panic = panicf;
     135             :   lua_unlock(L);
     136          63 :   return old;
     137             : }
     138             : 
     139             : 
     140          20 : LUA_API lua_State *lua_newthread (lua_State *L) {
     141             :   lua_State *L1;
     142             :   lua_lock(L);
     143          20 :   luaC_checkGC(L);
     144          20 :   L1 = luaE_newthread(L);
     145          20 :   setthvalue(L, L->top, L1);
     146          20 :   api_incr_top(L);
     147             :   lua_unlock(L);
     148             :   luai_userstatethread(L, L1);
     149          20 :   return L1;
     150             : }
     151             : 
     152             : 
     153             : 
     154             : /*
     155             : ** basic stack manipulation
     156             : */
     157             : 
     158             : 
     159       26280 : LUA_API int lua_gettop (lua_State *L) {
     160       26280 :   return cast_int(L->top - L->base);
     161             : }
     162             : 
     163             : 
     164      169958 : LUA_API void lua_settop (lua_State *L, int idx) {
     165             :   lua_lock(L);
     166      169958 :   if (idx >= 0) {
     167             :     api_check(L, idx <= L->stack_last - L->base);
     168       59690 :     while (L->top < L->base + idx)
     169        5914 :       setnilvalue(L->top++);
     170       26888 :     L->top = L->base + idx;
     171             :   }
     172             :   else {
     173             :     api_check(L, -(idx+1) <= (L->top - L->base));
     174      143070 :     L->top += idx+1;  /* `subtract' index (index is negative) */
     175             :   }
     176             :   lua_unlock(L);
     177      169958 : }
     178             : 
     179             : 
     180        2877 : LUA_API void lua_remove (lua_State *L, int idx) {
     181             :   StkId p;
     182             :   lua_lock(L);
     183        2877 :   p = index2adr(L, idx);
     184             :   api_checkvalidindex(L, p);
     185        2877 :   while (++p < L->top) setobjs2s(L, p-1, p);
     186        2877 :   L->top--;
     187             :   lua_unlock(L);
     188        2877 : }
     189             : 
     190             : 
     191        6933 : LUA_API void lua_insert (lua_State *L, int idx) {
     192             :   StkId p;
     193             :   StkId q;
     194             :   lua_lock(L);
     195        6933 :   p = index2adr(L, idx);
     196             :   api_checkvalidindex(L, p);
     197        6933 :   for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
     198        6933 :   setobjs2s(L, p, L->top);
     199             :   lua_unlock(L);
     200        6933 : }
     201             : 
     202             : 
     203         136 : LUA_API void lua_replace (lua_State *L, int idx) {
     204             :   StkId o;
     205             :   lua_lock(L);
     206             :   /* explicit test for incompatible code */
     207         136 :   if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci)
     208           0 :     luaG_runerror(L, "no calling environment");
     209             :   api_checknelems(L, 1);
     210         136 :   o = index2adr(L, idx);
     211             :   api_checkvalidindex(L, o);
     212         136 :   if (idx == LUA_ENVIRONINDEX) {
     213         124 :     Closure *func = curr_func(L);
     214             :     api_check(L, ttistable(L->top - 1)); 
     215         124 :     func->c.env = hvalue(L->top - 1);
     216         124 :     luaC_barrier(L, func, L->top - 1);
     217             :   }
     218             :   else {
     219          12 :     setobj(L, o, L->top - 1);
     220          12 :     if (idx < LUA_GLOBALSINDEX)  /* function upvalue? */
     221          10 :       luaC_barrier(L, curr_func(L), L->top - 1);
     222             :   }
     223         136 :   L->top--;
     224             :   lua_unlock(L);
     225         136 : }
     226             : 
     227             : 
     228       27157 : LUA_API void lua_pushvalue (lua_State *L, int idx) {
     229             :   lua_lock(L);
     230       27157 :   setobj2s(L, L->top, index2adr(L, idx));
     231       27157 :   api_incr_top(L);
     232             :   lua_unlock(L);
     233       27157 : }
     234             : 
     235             : 
     236             : 
     237             : /*
     238             : ** access functions (stack -> C)
     239             : */
     240             : 
     241             : 
     242      413446 : LUA_API int lua_type (lua_State *L, int idx) {
     243      413446 :   StkId o = index2adr(L, idx);
     244      413446 :   return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
     245             : }
     246             : 
     247             : 
     248        1134 : LUA_API const char *lua_typename (lua_State *L, int t) {
     249             :   UNUSED(L);
     250        1134 :   return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
     251             : }
     252             : 
     253             : 
     254          45 : LUA_API int lua_iscfunction (lua_State *L, int idx) {
     255          45 :   StkId o = index2adr(L, idx);
     256          45 :   return iscfunction(o);
     257             : }
     258             : 
     259             : 
     260        7392 : LUA_API int lua_isnumber (lua_State *L, int idx) {
     261             :   TValue n;
     262        7392 :   const TValue *o = index2adr(L, idx);
     263        7392 :   return tonumber(o, &n);
     264             : }
     265             : 
     266             : 
     267       82327 : LUA_API int lua_isstring (lua_State *L, int idx) {
     268       82327 :   int t = lua_type(L, idx);
     269       82327 :   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        1803 : LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
     280        1803 :   StkId o1 = index2adr(L, index1);
     281        1803 :   StkId o2 = index2adr(L, index2);
     282        1803 :   return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
     283        3606 :          : 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      183216 :   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        1494 : LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
     314             :   TValue n;
     315        1494 :   const TValue *o = index2adr(L, idx);
     316        1494 :   if (tonumber(o, &n))
     317        1491 :     return nvalue(o);
     318             :   else
     319           3 :     return 0;
     320             : }
     321             : 
     322             : 
     323       58187 : LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
     324             :   TValue n;
     325       58187 :   const TValue *o = index2adr(L, idx);
     326       58187 :   if (tonumber(o, &n)) {
     327             :     lua_Integer res;
     328       58186 :     lua_Number num = nvalue(o);
     329       58186 :     lua_number2integer(res, num);
     330       58186 :     return res;
     331             :   }
     332             :   else
     333           1 :     return 0;
     334             : }
     335             : 
     336             : 
     337        6313 : LUA_API int lua_toboolean (lua_State *L, int idx) {
     338        6313 :   const TValue *o = index2adr(L, idx);
     339        6313 :   return !l_isfalse(o);
     340             : }
     341             : 
     342             : 
     343      111708 : LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
     344      111708 :   StkId o = index2adr(L, idx);
     345      111708 :   if (!ttisstring(o)) {
     346             :     lua_lock(L);  /* `luaV_tostring' may create a new string */
     347        1393 :     if (!luaV_tostring(L, o)) {  /* conversion failed? */
     348           2 :       if (len != NULL) *len = 0;
     349             :       lua_unlock(L);
     350           2 :       return NULL;
     351             :     }
     352        1391 :     luaC_checkGC(L);
     353        1391 :     o = index2adr(L, idx);  /* previous call may reallocate the stack */
     354             :     lua_unlock(L);
     355             :   }
     356      111706 :   if (len != NULL) *len = tsvalue(o)->len;
     357      111706 :   return svalue(o);
     358             : }
     359             : 
     360             : 
     361       19626 : LUA_API size_t lua_objlen (lua_State *L, int idx) {
     362       19626 :   StkId o = index2adr(L, idx);
     363       19626 :   switch (ttype(o)) {
     364          11 :     case LUA_TSTRING: return tsvalue(o)->len;
     365           0 :     case LUA_TUSERDATA: return uvalue(o)->len;
     366       19615 :     case LUA_TTABLE: return luaH_getn(hvalue(o));
     367             :     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         242 : LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
     380         242 :   StkId o = index2adr(L, idx);
     381         242 :   return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;
     382             : }
     383             : 
     384             : 
     385        2364 : LUA_API void *lua_touserdata (lua_State *L, int idx) {
     386        2364 :   StkId o = index2adr(L, idx);
     387        2364 :   switch (ttype(o)) {
     388        1955 :     case LUA_TUSERDATA: return (rawuvalue(o) + 1);
     389          64 :     case LUA_TLIGHTUSERDATA: return pvalue(o);
     390         345 :     default: return NULL;
     391             :   }
     392             : }
     393             : 
     394             : 
     395        5966 : LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
     396        5966 :   StkId o = index2adr(L, idx);
     397        5966 :   return (!ttisthread(o)) ? NULL : thvalue(o);
     398             : }
     399             : 
     400             : 
     401           5 : LUA_API const void *lua_topointer (lua_State *L, int idx) {
     402           5 :   StkId o = index2adr(L, idx);
     403           5 :   switch (ttype(o)) {
     404           1 :     case LUA_TTABLE: return hvalue(o);
     405           3 :     case LUA_TFUNCTION: return clvalue(o);
     406           1 :     case LUA_TTHREAD: return thvalue(o);
     407             :     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        1681 : LUA_API void lua_pushnil (lua_State *L) {
     422             :   lua_lock(L);
     423        1681 :   setnilvalue(L->top);
     424        1681 :   api_incr_top(L);
     425             :   lua_unlock(L);
     426        1681 : }
     427             : 
     428             : 
     429        1609 : LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
     430             :   lua_lock(L);
     431        1609 :   setnvalue(L->top, n);
     432        1609 :   api_incr_top(L);
     433             :   lua_unlock(L);
     434        1609 : }
     435             : 
     436             : 
     437       53829 : LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
     438             :   lua_lock(L);
     439       53829 :   setnvalue(L->top, cast_num(n));
     440       53829 :   api_incr_top(L);
     441             :   lua_unlock(L);
     442       53829 : }
     443             : 
     444             : 
     445       29798 : LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
     446             :   lua_lock(L);
     447       29798 :   luaC_checkGC(L);
     448       29798 :   setsvalue2s(L, L->top, luaS_newlstr(L, s, len));
     449       29798 :   api_incr_top(L);
     450             :   lua_unlock(L);
     451       29798 : }
     452             : 
     453             : 
     454        5140 : LUA_API void lua_pushstring (lua_State *L, const char *s) {
     455        5140 :   if (s == NULL)
     456           4 :     lua_pushnil(L);
     457             :   else
     458        5136 :     lua_pushlstring(L, s, strlen(s));
     459        5140 : }
     460             : 
     461             : 
     462          53 : 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          53 :   luaC_checkGC(L);
     467          53 :   ret = luaO_pushvfstring(L, fmt, argp);
     468             :   lua_unlock(L);
     469          53 :   return ret;
     470             : }
     471             : 
     472             : 
     473         641 : 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         641 :   luaC_checkGC(L);
     478         641 :   va_start(argp, fmt);
     479         641 :   ret = luaO_pushvfstring(L, fmt, argp);
     480         641 :   va_end(argp);
     481             :   lua_unlock(L);
     482         641 :   return ret;
     483             : }
     484             : 
     485             : 
     486        9563 : LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
     487             :   Closure *cl;
     488             :   lua_lock(L);
     489        9563 :   luaC_checkGC(L);
     490             :   api_checknelems(L, n);
     491        9563 :   cl = luaF_newCclosure(L, n, getcurrenv(L));
     492        9563 :   cl->c.f = fn;
     493        9563 :   L->top -= n;
     494       19340 :   while (n--)
     495         214 :     setobj2n(L, &cl->c.upvalue[n], L->top+n);
     496        9563 :   setclvalue(L, L->top, cl);
     497             :   lua_assert(iswhite(obj2gco(cl)));
     498        9563 :   api_incr_top(L);
     499             :   lua_unlock(L);
     500        9563 : }
     501             : 
     502             : 
     503        7667 : LUA_API void lua_pushboolean (lua_State *L, int b) {
     504             :   lua_lock(L);
     505        7667 :   setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
     506        7667 :   api_incr_top(L);
     507             :   lua_unlock(L);
     508        7667 : }
     509             : 
     510             : 
     511          72 : LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
     512             :   lua_lock(L);
     513          72 :   setpvalue(L->top, p);
     514          72 :   api_incr_top(L);
     515             :   lua_unlock(L);
     516          72 : }
     517             : 
     518             : 
     519           0 : LUA_API int lua_pushthread (lua_State *L) {
     520             :   lua_lock(L);
     521           0 :   setthvalue(L, L->top, L);
     522           0 :   api_incr_top(L);
     523             :   lua_unlock(L);
     524           0 :   return (G(L)->mainthread == L);
     525             : }
     526             : 
     527             : 
     528             : 
     529             : /*
     530             : ** get functions (Lua -> stack)
     531             : */
     532             : 
     533             : 
     534           8 : LUA_API void lua_gettable (lua_State *L, int idx) {
     535             :   StkId t;
     536             :   lua_lock(L);
     537           8 :   t = index2adr(L, idx);
     538             :   api_checkvalidindex(L, t);
     539           8 :   luaV_gettable(L, t, L->top - 1, L->top - 1);
     540             :   lua_unlock(L);
     541           8 : }
     542             : 
     543             : 
     544        4371 : LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
     545             :   StkId t;
     546             :   TValue key;
     547             :   lua_lock(L);
     548        4371 :   t = index2adr(L, idx);
     549             :   api_checkvalidindex(L, t);
     550        4371 :   setsvalue(L, &key, luaS_new(L, k));
     551        4371 :   luaV_gettable(L, t, &key, L->top);
     552        4371 :   api_incr_top(L);
     553             :   lua_unlock(L);
     554        4371 : }
     555             : 
     556             : 
     557       22392 : LUA_API void lua_rawget (lua_State *L, int idx) {
     558             :   StkId t;
     559             :   lua_lock(L);
     560       22392 :   t = index2adr(L, idx);
     561             :   api_check(L, ttistable(t));
     562       22392 :   setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
     563             :   lua_unlock(L);
     564       22392 : }
     565             : 
     566             : 
     567      294506 : LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
     568             :   StkId o;
     569             :   lua_lock(L);
     570      294506 :   o = index2adr(L, idx);
     571             :   api_check(L, ttistable(o));
     572      294506 :   setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
     573      294506 :   api_incr_top(L);
     574             :   lua_unlock(L);
     575      294506 : }
     576             : 
     577             : 
     578        1167 : LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
     579             :   lua_lock(L);
     580        1167 :   luaC_checkGC(L);
     581        1167 :   sethvalue(L, L->top, luaH_new(L, narray, nrec));
     582        1167 :   api_incr_top(L);
     583             :   lua_unlock(L);
     584        1167 : }
     585             : 
     586             : 
     587        5077 : LUA_API int lua_getmetatable (lua_State *L, int objindex) {
     588             :   const TValue *obj;
     589        5077 :   Table *mt = NULL;
     590             :   int res;
     591             :   lua_lock(L);
     592        5077 :   obj = index2adr(L, objindex);
     593        5077 :   switch (ttype(obj)) {
     594             :     case LUA_TTABLE:
     595         188 :       mt = hvalue(obj)->metatable;
     596         188 :       break;
     597             :     case LUA_TUSERDATA:
     598        1792 :       mt = uvalue(obj)->metatable;
     599        1792 :       break;
     600             :     default:
     601        3097 :       mt = G(L)->mt[ttype(obj)];
     602        3097 :       break;
     603             :   }
     604        5077 :   if (mt == NULL)
     605        1541 :     res = 0;
     606             :   else {
     607        3536 :     sethvalue(L, L->top, mt);
     608        3536 :     api_incr_top(L);
     609        3536 :     res = 1;
     610             :   }
     611             :   lua_unlock(L);
     612        5077 :   return res;
     613             : }
     614             : 
     615             : 
     616         265 : LUA_API void lua_getfenv (lua_State *L, int idx) {
     617             :   StkId o;
     618             :   lua_lock(L);
     619         265 :   o = index2adr(L, idx);
     620             :   api_checkvalidindex(L, o);
     621         265 :   switch (ttype(o)) {
     622             :     case LUA_TFUNCTION:
     623          18 :       sethvalue(L, L->top, clvalue(o)->c.env);
     624          18 :       break;
     625             :     case LUA_TUSERDATA:
     626         242 :       sethvalue(L, L->top, uvalue(o)->env);
     627         242 :       break;
     628             :     case LUA_TTHREAD:
     629           4 :       setobj2s(L, L->top,  gt(thvalue(o)));
     630           4 :       break;
     631             :     default:
     632           1 :       setnilvalue(L->top);
     633           1 :       break;
     634             :   }
     635         265 :   api_incr_top(L);
     636             :   lua_unlock(L);
     637         265 : }
     638             : 
     639             : 
     640             : /*
     641             : ** set functions (stack -> Lua)
     642             : */
     643             : 
     644             : 
     645         561 : LUA_API void lua_settable (lua_State *L, int idx) {
     646             :   StkId t;
     647             :   lua_lock(L);
     648             :   api_checknelems(L, 2);
     649         561 :   t = index2adr(L, idx);
     650             :   api_checkvalidindex(L, t);
     651         561 :   luaV_settable(L, t, L->top - 2, L->top - 1);
     652         561 :   L->top -= 2;  /* pop index and value */
     653             :   lua_unlock(L);
     654         561 : }
     655             : 
     656             : 
     657       10583 : 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       10583 :   t = index2adr(L, idx);
     663             :   api_checkvalidindex(L, t);
     664       10583 :   setsvalue(L, &key, luaS_new(L, k));
     665       10583 :   luaV_settable(L, t, &key, L->top - 1);
     666       10583 :   L->top--;  /* pop value */
     667             :   lua_unlock(L);
     668       10583 : }
     669             : 
     670             : 
     671           2 : LUA_API void lua_rawset (lua_State *L, int idx) {
     672             :   StkId t;
     673             :   lua_lock(L);
     674             :   api_checknelems(L, 2);
     675           2 :   t = index2adr(L, idx);
     676             :   api_check(L, ttistable(t));
     677           2 :   setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
     678           2 :   luaC_barriert(L, hvalue(t), L->top-1);
     679           2 :   L->top -= 2;
     680             :   lua_unlock(L);
     681           2 : }
     682             : 
     683             : 
     684       86684 : 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       86684 :   o = index2adr(L, idx);
     689             :   api_check(L, ttistable(o));
     690       86684 :   setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
     691       86684 :   luaC_barriert(L, hvalue(o), L->top-1);
     692       86684 :   L->top--;
     693             :   lua_unlock(L);
     694       86684 : }
     695             : 
     696             : 
     697         520 : 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         520 :   obj = index2adr(L, objindex);
     703             :   api_checkvalidindex(L, obj);
     704         520 :   if (ttisnil(L->top - 1))
     705           0 :     mt = NULL;
     706             :   else {
     707             :     api_check(L, ttistable(L->top - 1));
     708         520 :     mt = hvalue(L->top - 1);
     709             :   }
     710         520 :   switch (ttype(obj)) {
     711             :     case LUA_TTABLE: {
     712         211 :       hvalue(obj)->metatable = mt;
     713         211 :       if (mt)
     714         211 :         luaC_objbarriert(L, hvalue(obj), mt);
     715         211 :       break;
     716             :     }
     717             :     case LUA_TUSERDATA: {
     718         247 :       uvalue(obj)->metatable = mt;
     719         247 :       if (mt)
     720         247 :         luaC_objbarrier(L, rawuvalue(obj), mt);
     721         247 :       break;
     722             :     }
     723             :     default: {
     724          62 :       G(L)->mt[ttype(obj)] = mt;
     725          62 :       break;
     726             :     }
     727             :   }
     728         520 :   L->top--;
     729             :   lua_unlock(L);
     730         520 :   return 1;
     731             : }
     732             : 
     733             : 
     734         262 : LUA_API int lua_setfenv (lua_State *L, int idx) {
     735             :   StkId o;
     736         262 :   int res = 1;
     737             :   lua_lock(L);
     738             :   api_checknelems(L, 1);
     739         262 :   o = index2adr(L, idx);
     740             :   api_checkvalidindex(L, o);
     741             :   api_check(L, ttistable(L->top - 1));
     742         262 :   switch (ttype(o)) {
     743             :     case LUA_TFUNCTION:
     744          74 :       clvalue(o)->c.env = hvalue(L->top - 1);
     745          74 :       break;
     746             :     case LUA_TUSERDATA:
     747         186 :       uvalue(o)->env = hvalue(L->top - 1);
     748         186 :       break;
     749             :     case LUA_TTHREAD:
     750           1 :       sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1));
     751           1 :       break;
     752             :     default:
     753           1 :       res = 0;
     754           1 :       break;
     755             :   }
     756         262 :   if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
     757         262 :   L->top--;
     758             :   lua_unlock(L);
     759         262 :   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         911 : 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         911 :   func = L->top - (nargs+1);
     782         911 :   luaD_call(L, func, nresults);
     783         908 :   adjustresults(L, nresults);
     784             :   lua_unlock(L);
     785         908 : }
     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         372 : static void f_call (lua_State *L, void *ud) {
     799         372 :   struct CallS *c = cast(struct CallS *, ud);
     800         372 :   luaD_call(L, c->func, c->nresults);
     801         129 : }
     802             : 
     803             : 
     804             : 
     805         372 : 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         372 :   if (errfunc == 0)
     813         244 :     func = 0;
     814             :   else {
     815         128 :     StkId o = index2adr(L, errfunc);
     816             :     api_checkvalidindex(L, o);
     817         128 :     func = savestack(L, o);
     818             :   }
     819         372 :   c.func = L->top - (nargs+1);  /* function to be called */
     820         372 :   c.nresults = nresults;
     821         372 :   status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
     822         370 :   adjustresults(L, nresults);
     823             :   lua_unlock(L);
     824         370 :   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          63 : static void f_Ccall (lua_State *L, void *ud) {
     838          63 :   struct CCallS *c = cast(struct CCallS *, ud);
     839             :   Closure *cl;
     840          63 :   cl = luaF_newCclosure(L, 0, getcurrenv(L));
     841          63 :   cl->c.f = c->func;
     842          63 :   setclvalue(L, L->top, cl);  /* push function */
     843          63 :   api_incr_top(L);
     844          63 :   setpvalue(L->top, c->ud);  /* push only argument */
     845          63 :   api_incr_top(L);
     846          63 :   luaD_call(L, L->top - 2, 0);
     847          61 : }
     848             : 
     849             : 
     850          63 : 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          63 :   c.func = func;
     855          63 :   c.ud = ud;
     856          63 :   status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
     857             :   lua_unlock(L);
     858          61 :   return status;
     859             : }
     860             : 
     861             : 
     862         368 : 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         368 :   if (!chunkname) chunkname = "?";
     868         368 :   luaZ_init(L, &z, reader, data);
     869         368 :   status = luaD_protectedparser(L, &z, chunkname);
     870             :   lua_unlock(L);
     871         368 :   return status;
     872             : }
     873             : 
     874             : 
     875           0 : 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           0 :   o = L->top - 1;
     881           0 :   if (isLfunction(o))
     882           0 :     status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
     883             :   else
     884           0 :     status = 1;
     885             :   lua_unlock(L);
     886           0 :   return status;
     887             : }
     888             : 
     889             : 
     890        5966 : LUA_API int  lua_status (lua_State *L) {
     891        5966 :   return L->status;
     892             : }
     893             : 
     894             : 
     895             : /*
     896             : ** Garbage-collection function
     897             : */
     898             : 
     899         131 : LUA_API int lua_gc (lua_State *L, int what, int data) {
     900         131 :   int res = 0;
     901             :   global_State *g;
     902             :   lua_lock(L);
     903         131 :   g = G(L);
     904         131 :   switch (what) {
     905             :     case LUA_GCSTOP: {
     906          63 :       g->GCthreshold = MAX_LUMEM;
     907          63 :       break;
     908             :     }
     909             :     case LUA_GCRESTART: {
     910          63 :       g->GCthreshold = g->totalbytes;
     911          63 :       break;
     912             :     }
     913             :     case LUA_GCCOLLECT: {
     914           3 :       luaC_fullgc(L);
     915           3 :       break;
     916             :     }
     917             :     case LUA_GCCOUNT: {
     918             :       /* GC values are expressed in Kbytes: #bytes/2^10 */
     919           1 :       res = cast_int(g->totalbytes >> 10);
     920           1 :       break;
     921             :     }
     922             :     case LUA_GCCOUNTB: {
     923           1 :       res = cast_int(g->totalbytes & 0x3ff);
     924           1 :       break;
     925             :     }
     926             :     case LUA_GCSTEP: {
     927           0 :       lu_mem a = (cast(lu_mem, data) << 10);
     928           0 :       if (a <= g->totalbytes)
     929           0 :         g->GCthreshold = g->totalbytes - a;
     930             :       else
     931           0 :         g->GCthreshold = 0;
     932           0 :       while (g->GCthreshold <= g->totalbytes) {
     933           0 :         luaC_step(L);
     934           0 :         if (g->gcstate == GCSpause) {  /* end of cycle? */
     935           0 :           res = 1;  /* signal it */
     936           0 :           break;
     937             :         }
     938             :       }
     939           0 :       break;
     940             :     }
     941             :     case LUA_GCSETPAUSE: {
     942           0 :       res = g->gcpause;
     943           0 :       g->gcpause = data;
     944           0 :       break;
     945             :     }
     946             :     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         131 :   return res;
     955             : }
     956             : 
     957             : 
     958             : 
     959             : /*
     960             : ** miscellaneous functions
     961             : */
     962             : 
     963             : 
     964          57 : LUA_API int lua_error (lua_State *L) {
     965             :   lua_lock(L);
     966             :   api_checknelems(L, 1);
     967          57 :   luaG_errormsg(L);
     968             :   lua_unlock(L);
     969           0 :   return 0;  /* to avoid warnings */
     970             : }
     971             : 
     972             : 
     973        1008 : LUA_API int lua_next (lua_State *L, int idx) {
     974             :   StkId t;
     975             :   int more;
     976             :   lua_lock(L);
     977        1008 :   t = index2adr(L, idx);
     978             :   api_check(L, ttistable(t));
     979        1008 :   more = luaH_next(L, hvalue(t), L->top - 1);
     980        1007 :   if (more) {
     981         957 :     api_incr_top(L);
     982             :   }
     983             :   else  /* no more elements */
     984          50 :     L->top -= 1;  /* remove key */
     985             :   lua_unlock(L);
     986        1007 :   return more;
     987             : }
     988             : 
     989             : 
     990       16026 : LUA_API void lua_concat (lua_State *L, int n) {
     991             :   lua_lock(L);
     992             :   api_checknelems(L, n);
     993       16026 :   if (n >= 2) {
     994         497 :     luaC_checkGC(L);
     995         497 :     luaV_concat(L, n, cast_int(L->top - L->base) - 1);
     996         497 :     L->top -= (n-1);
     997             :   }
     998       15529 :   else if (n == 0) {  /* push empty string */
     999          20 :     setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
    1000          20 :     api_incr_top(L);
    1001             :   }
    1002             :   /* else n == 1; nothing to do */
    1003             :   lua_unlock(L);
    1004       16026 : }
    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         247 : LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
    1026             :   Udata *u;
    1027             :   lua_lock(L);
    1028         247 :   luaC_checkGC(L);
    1029         247 :   u = luaS_newudata(L, size, getcurrenv(L));
    1030         247 :   setuvalue(L, L->top, u);
    1031         247 :   api_incr_top(L);
    1032             :   lua_unlock(L);
    1033         247 :   return u + 1;
    1034             : }
    1035             : 
    1036             : 
    1037             : 
    1038             : 
    1039           0 : static const char *aux_upvalue (StkId fi, int n, TValue **val) {
    1040             :   Closure *f;
    1041           0 :   if (!ttisfunction(fi)) return NULL;
    1042           0 :   f = clvalue(fi);
    1043           0 :   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           0 :     Proto *p = f->l.p;
    1050           0 :     if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
    1051           0 :     *val = f->l.upvals[n-1]->v;
    1052           0 :     return getstr(p->upvalues[n-1]);
    1053             :   }
    1054             : }
    1055             : 
    1056             : 
    1057           0 : 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           0 :   name = aux_upvalue(index2adr(L, funcindex), n, &val);
    1062           0 :   if (name) {
    1063           0 :     setobj2s(L, L->top, val);
    1064           0 :     api_incr_top(L);
    1065             :   }
    1066             :   lua_unlock(L);
    1067           0 :   return name;
    1068             : }
    1069             : 
    1070             : 
    1071           0 : 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           0 :   fi = index2adr(L, funcindex);
    1077             :   api_checknelems(L, 1);
    1078           0 :   name = aux_upvalue(fi, n, &val);
    1079           0 :   if (name) {
    1080           0 :     L->top--;
    1081           0 :     setobj(L, val, L->top);
    1082           0 :     luaC_barrier(L, clvalue(fi), L->top);
    1083             :   }
    1084             :   lua_unlock(L);
    1085           0 :   return name;
    1086             : }
    1087             : 

Generated by: LCOV version 1.13