LCOV - code coverage report
Current view: directory - src - lapi.c Found Hit Coverage
Test: Lua 5.1.4 Lines: 469 387 82.5 %
Date: 2009-09-13
Colors: not hit hit

       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         1171568 : static TValue *index2adr (lua_State *L, int idx) {
      50         1171568 :   if (idx > 0) {
      51          732285 :     TValue *o = L->base + (idx - 1);
      52                 :     api_check(L, idx <= L->ci->top - L->base);
      53          732285 :     if (o >= L->top) return cast(TValue *, luaO_nilobject);
      54          701631 :     else return o;
      55                 :   }
      56          439283 :   else if (idx > LUA_REGISTRYINDEX) {
      57                 :     api_check(L, idx != 0 && -idx <= L->top - L->base);
      58          429724 :     return L->top + idx;
      59                 :   }
      60            9559 :   else switch (idx) {  /* pseudo-indices */
      61            1017 :     case LUA_REGISTRYINDEX: return registry(L);
      62                 :     case LUA_ENVIRONINDEX: {
      63             342 :       Closure *func = curr_func(L);
      64             342 :       sethvalue(L, &L->env, func->c.env);
      65             342 :       return &L->env;
      66                 :     }
      67            1940 :     case LUA_GLOBALSINDEX: return gt(L);
      68                 :     default: {
      69            6260 :       Closure *func = curr_func(L);
      70            6260 :       idx = LUA_GLOBALSINDEX - idx;
      71            6260 :       return (idx <= func->c.nupvalues)
      72                 :                 ? &func->c.upvalue[idx-1]
      73                 :                 : cast(TValue *, luaO_nilobject);
      74                 :     }
      75                 :   }
      76                 : }
      77                 : 
      78                 : 
      79            5577 : static Table *getcurrenv (lua_State *L) {
      80            5577 :   if (L->ci == L->base_ci)  /* no enclosing function? */
      81              35 :     return hvalue(gt(L));  /* use global table as environment */
      82                 :   else {
      83            5542 :     Closure *func = curr_func(L);
      84            5542 :     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           18283 : LUA_API int lua_checkstack (lua_State *L, int size) {
      96           18283 :   int res = 1;
      97                 :   lua_lock(L);
      98           18283 :   if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK)
      99               0 :     res = 0;  /* stack overflow */
     100           18283 :   else if (size > 0) {
     101           12339 :     luaD_checkstack(L, size);
     102           12339 :     if (L->ci->top < L->top + size)
     103            5923 :       L->ci->top = L->top + size;
     104                 :   }
     105                 :   lua_unlock(L);
     106           18283 :   return res;
     107                 : }
     108                 : 
     109                 : 
     110           11942 : LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
     111                 :   int i;
     112           11942 :   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              35 : LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
     131                 :   lua_CFunction old;
     132                 :   lua_lock(L);
     133              35 :   old = G(L)->panic;
     134              35 :   G(L)->panic = panicf;
     135                 :   lua_unlock(L);
     136              35 :   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           26037 : LUA_API int lua_gettop (lua_State *L) {
     160           26037 :   return cast_int(L->top - L->base);
     161                 : }
     162                 : 
     163                 : 
     164          147442 : LUA_API void lua_settop (lua_State *L, int idx) {
     165                 :   lua_lock(L);
     166          147442 :   if (idx >= 0) {
     167                 :     api_check(L, idx <= L->stack_last - L->base);
     168           19620 :     while (L->top < L->base + idx)
     169            5914 :       setnilvalue(L->top++);
     170            6853 :     L->top = L->base + idx;
     171                 :   }
     172                 :   else {
     173                 :     api_check(L, -(idx+1) <= (L->top - L->base));
     174          140589 :     L->top += idx+1;  /* `subtract' index (index is negative) */
     175                 :   }
     176                 :   lua_unlock(L);
     177          147442 : }
     178                 : 
     179                 : 
     180            1976 : LUA_API void lua_remove (lua_State *L, int idx) {
     181                 :   StkId p;
     182                 :   lua_lock(L);
     183            1976 :   p = index2adr(L, idx);
     184                 :   api_checkvalidindex(L, p);
     185            1976 :   while (++p < L->top) setobjs2s(L, p-1, p);
     186            1976 :   L->top--;
     187                 :   lua_unlock(L);
     188            1976 : }
     189                 : 
     190                 : 
     191            6596 : LUA_API void lua_insert (lua_State *L, int idx) {
     192                 :   StkId p;
     193                 :   StkId q;
     194                 :   lua_lock(L);
     195            6596 :   p = index2adr(L, idx);
     196                 :   api_checkvalidindex(L, p);
     197            6596 :   for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
     198            6596 :   setobjs2s(L, p, L->top);
     199                 :   lua_unlock(L);
     200            6596 : }
     201                 : 
     202                 : 
     203              82 : LUA_API void lua_replace (lua_State *L, int idx) {
     204                 :   StkId o;
     205                 :   lua_lock(L);
     206                 :   /* explicit test for incompatible code */
     207              82 :   if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci)
     208               0 :     luaG_runerror(L, "no calling environment");
     209                 :   api_checknelems(L, 1);
     210              82 :   o = index2adr(L, idx);
     211                 :   api_checkvalidindex(L, o);
     212              82 :   if (idx == LUA_ENVIRONINDEX) {
     213              70 :     Closure *func = curr_func(L);
     214                 :     api_check(L, ttistable(L->top - 1)); 
     215              70 :     func->c.env = hvalue(L->top - 1);
     216              70 :     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              82 :   L->top--;
     224                 :   lua_unlock(L);
     225              82 : }
     226                 : 
     227                 : 
     228           28604 : LUA_API void lua_pushvalue (lua_State *L, int idx) {
     229                 :   lua_lock(L);
     230           28604 :   setobj2s(L, L->top, index2adr(L, idx));
     231           28604 :   api_incr_top(L);
     232                 :   lua_unlock(L);
     233           28604 : }
     234                 : 
     235                 : 
     236                 : 
     237                 : /*
     238                 : ** access functions (stack -> C)
     239                 : */
     240                 : 
     241                 : 
     242          354368 : LUA_API int lua_type (lua_State *L, int idx) {
     243          354368 :   StkId o = index2adr(L, idx);
     244          354368 :   return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
     245                 : }
     246                 : 
     247                 : 
     248             336 : LUA_API const char *lua_typename (lua_State *L, int t) {
     249                 :   UNUSED(L);
     250             336 :   return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
     251                 : }
     252                 : 
     253                 : 
     254             101 : LUA_API int lua_iscfunction (lua_State *L, int idx) {
     255             101 :   StkId o = index2adr(L, idx);
     256             101 :   return iscfunction(o);
     257                 : }
     258                 : 
     259                 : 
     260            6148 : LUA_API int lua_isnumber (lua_State *L, int idx) {
     261                 :   TValue n;
     262            6148 :   const TValue *o = index2adr(L, idx);
     263            6148 :   return tonumber(o, &n);
     264                 : }
     265                 : 
     266                 : 
     267           80968 : LUA_API int lua_isstring (lua_State *L, int idx) {
     268           80968 :   int t = lua_type(L, idx);
     269           80968 :   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             279 : LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
     280             279 :   StkId o1 = index2adr(L, index1);
     281             279 :   StkId o2 = index2adr(L, index2);
     282             279 :   return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
     283                 :          : 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                 :        : luaV_lessthan(L, o1, o2);
     307                 :   lua_unlock(L);
     308           91608 :   return i;
     309                 : }
     310                 : 
     311                 : 
     312                 : 
     313             179 : LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
     314                 :   TValue n;
     315             179 :   const TValue *o = index2adr(L, idx);
     316             179 :   if (tonumber(o, &n))
     317             176 :     return nvalue(o);
     318                 :   else
     319               3 :     return 0;
     320                 : }
     321                 : 
     322                 : 
     323           59878 : LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
     324                 :   TValue n;
     325           59878 :   const TValue *o = index2adr(L, idx);
     326           59878 :   if (tonumber(o, &n)) {
     327                 :     lua_Integer res;
     328           59877 :     lua_Number num = nvalue(o);
     329           59877 :     lua_number2integer(res, num);
     330           59877 :     return res;
     331                 :   }
     332                 :   else
     333               1 :     return 0;
     334                 : }
     335                 : 
     336                 : 
     337            6025 : LUA_API int lua_toboolean (lua_State *L, int idx) {
     338            6025 :   const TValue *o = index2adr(L, idx);
     339            6025 :   return !l_isfalse(o);
     340                 : }
     341                 : 
     342                 : 
     343          103599 : LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
     344          103599 :   StkId o = index2adr(L, idx);
     345          103599 :   if (!ttisstring(o)) {
     346                 :     lua_lock(L);  /* `luaV_tostring' may create a new string */
     347              49 :     if (!luaV_tostring(L, o)) {  /* conversion failed? */
     348               3 :       if (len != NULL) *len = 0;
     349                 :       lua_unlock(L);
     350               3 :       return NULL;
     351                 :     }
     352              46 :     luaC_checkGC(L);
     353              46 :     o = index2adr(L, idx);  /* previous call may reallocate the stack */
     354                 :     lua_unlock(L);
     355                 :   }
     356          103596 :   if (len != NULL) *len = tsvalue(o)->len;
     357          103596 :   return svalue(o);
     358                 : }
     359                 : 
     360                 : 
     361           18046 : LUA_API size_t lua_objlen (lua_State *L, int idx) {
     362           18046 :   StkId o = index2adr(L, idx);
     363           18046 :   switch (ttype(o)) {
     364               7 :     case LUA_TSTRING: return tsvalue(o)->len;
     365               0 :     case LUA_TUSERDATA: return uvalue(o)->len;
     366           18039 :     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             142 : LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
     380             142 :   StkId o = index2adr(L, idx);
     381             142 :   return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;
     382                 : }
     383                 : 
     384                 : 
     385             520 : LUA_API void *lua_touserdata (lua_State *L, int idx) {
     386             520 :   StkId o = index2adr(L, idx);
     387             520 :   switch (ttype(o)) {
     388             423 :     case LUA_TUSERDATA: return (rawuvalue(o) + 1);
     389              36 :     case LUA_TLIGHTUSERDATA: return pvalue(o);
     390              61 :     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               4 : LUA_API const void *lua_topointer (lua_State *L, int idx) {
     402               4 :   StkId o = index2adr(L, idx);
     403               4 :   switch (ttype(o)) {
     404               1 :     case LUA_TTABLE: return hvalue(o);
     405               2 :     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             270 : LUA_API void lua_pushnil (lua_State *L) {
     422                 :   lua_lock(L);
     423             270 :   setnilvalue(L->top);
     424             270 :   api_incr_top(L);
     425                 :   lua_unlock(L);
     426             270 : }
     427                 : 
     428                 : 
     429             238 : LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
     430                 :   lua_lock(L);
     431             238 :   setnvalue(L->top, n);
     432             238 :   api_incr_top(L);
     433                 :   lua_unlock(L);
     434             238 : }
     435                 : 
     436                 : 
     437           52834 : LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
     438                 :   lua_lock(L);
     439           52834 :   setnvalue(L->top, cast_num(n));
     440           52834 :   api_incr_top(L);
     441                 :   lua_unlock(L);
     442           52834 : }
     443                 : 
     444                 : 
     445           24278 : LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
     446                 :   lua_lock(L);
     447           24278 :   luaC_checkGC(L);
     448           24278 :   setsvalue2s(L, L->top, luaS_newlstr(L, s, len));
     449           24278 :   api_incr_top(L);
     450                 :   lua_unlock(L);
     451           24278 : }
     452                 : 
     453                 : 
     454            2624 : LUA_API void lua_pushstring (lua_State *L, const char *s) {
     455            2624 :   if (s == NULL)
     456               2 :     lua_pushnil(L);
     457                 :   else
     458            2622 :     lua_pushlstring(L, s, strlen(s));
     459            2624 : }
     460                 : 
     461                 : 
     462                 : LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
     463              51 :                                       va_list argp) {
     464                 :   const char *ret;
     465                 :   lua_lock(L);
     466              51 :   luaC_checkGC(L);
     467              51 :   ret = luaO_pushvfstring(L, fmt, argp);
     468                 :   lua_unlock(L);
     469              51 :   return ret;
     470                 : }
     471                 : 
     472                 : 
     473             534 : 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             534 :   luaC_checkGC(L);
     478             534 :   va_start(argp, fmt);
     479             534 :   ret = luaO_pushvfstring(L, fmt, argp);
     480             534 :   va_end(argp);
     481                 :   lua_unlock(L);
     482             534 :   return ret;
     483                 : }
     484                 : 
     485                 : 
     486            5401 : LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
     487                 :   Closure *cl;
     488                 :   lua_lock(L);
     489            5401 :   luaC_checkGC(L);
     490                 :   api_checknelems(L, n);
     491            5401 :   cl = luaF_newCclosure(L, n, getcurrenv(L));
     492            5401 :   cl->c.f = fn;
     493            5401 :   L->top -= n;
     494           10931 :   while (n--)
     495             129 :     setobj2n(L, &cl->c.upvalue[n], L->top+n);
     496            5401 :   setclvalue(L, L->top, cl);
     497                 :   lua_assert(iswhite(obj2gco(cl)));
     498            5401 :   api_incr_top(L);
     499                 :   lua_unlock(L);
     500            5401 : }
     501                 : 
     502                 : 
     503            6266 : LUA_API void lua_pushboolean (lua_State *L, int b) {
     504                 :   lua_lock(L);
     505            6266 :   setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
     506            6266 :   api_incr_top(L);
     507                 :   lua_unlock(L);
     508            6266 : }
     509                 : 
     510                 : 
     511              60 : LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
     512                 :   lua_lock(L);
     513              60 :   setpvalue(L->top, p);
     514              60 :   api_incr_top(L);
     515                 :   lua_unlock(L);
     516              60 : }
     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            3014 : LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
     545                 :   StkId t;
     546                 :   TValue key;
     547                 :   lua_lock(L);
     548            3014 :   t = index2adr(L, idx);
     549                 :   api_checkvalidindex(L, t);
     550            3014 :   setsvalue(L, &key, luaS_new(L, k));
     551            3014 :   luaV_gettable(L, t, &key, L->top);
     552            3014 :   api_incr_top(L);
     553                 :   lua_unlock(L);
     554            3014 : }
     555                 : 
     556                 : 
     557            2417 : LUA_API void lua_rawget (lua_State *L, int idx) {
     558                 :   StkId t;
     559                 :   lua_lock(L);
     560            2417 :   t = index2adr(L, idx);
     561                 :   api_check(L, ttistable(t));
     562            2417 :   setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
     563                 :   lua_unlock(L);
     564            2417 : }
     565                 : 
     566                 : 
     567          293427 : LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
     568                 :   StkId o;
     569                 :   lua_lock(L);
     570          293427 :   o = index2adr(L, idx);
     571                 :   api_check(L, ttistable(o));
     572          293427 :   setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
     573          293427 :   api_incr_top(L);
     574                 :   lua_unlock(L);
     575          293427 : }
     576                 : 
     577                 : 
     578             755 : LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
     579                 :   lua_lock(L);
     580             755 :   luaC_checkGC(L);
     581             755 :   sethvalue(L, L->top, luaH_new(L, narray, nrec));
     582             755 :   api_incr_top(L);
     583                 :   lua_unlock(L);
     584             755 : }
     585                 : 
     586                 : 
     587            2025 : LUA_API int lua_getmetatable (lua_State *L, int objindex) {
     588                 :   const TValue *obj;
     589            2025 :   Table *mt = NULL;
     590                 :   int res;
     591                 :   lua_lock(L);
     592            2025 :   obj = index2adr(L, objindex);
     593            2025 :   switch (ttype(obj)) {
     594                 :     case LUA_TTABLE:
     595             120 :       mt = hvalue(obj)->metatable;
     596             120 :       break;
     597                 :     case LUA_TUSERDATA:
     598             268 :       mt = uvalue(obj)->metatable;
     599             268 :       break;
     600                 :     default:
     601            1637 :       mt = G(L)->mt[ttype(obj)];
     602                 :       break;
     603                 :   }
     604            2025 :   if (mt == NULL)
     605             125 :     res = 0;
     606                 :   else {
     607            1900 :     sethvalue(L, L->top, mt);
     608            1900 :     api_incr_top(L);
     609            1900 :     res = 1;
     610                 :   }
     611                 :   lua_unlock(L);
     612            2025 :   return res;
     613                 : }
     614                 : 
     615                 : 
     616             165 : LUA_API void lua_getfenv (lua_State *L, int idx) {
     617                 :   StkId o;
     618                 :   lua_lock(L);
     619             165 :   o = index2adr(L, idx);
     620                 :   api_checkvalidindex(L, o);
     621             165 :   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             142 :       sethvalue(L, L->top, uvalue(o)->env);
     627             142 :       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                 :       break;
     634                 :   }
     635             165 :   api_incr_top(L);
     636                 :   lua_unlock(L);
     637             165 : }
     638                 : 
     639                 : 
     640                 : /*
     641                 : ** set functions (stack -> Lua)
     642                 : */
     643                 : 
     644                 : 
     645             402 : LUA_API void lua_settable (lua_State *L, int idx) {
     646                 :   StkId t;
     647                 :   lua_lock(L);
     648                 :   api_checknelems(L, 2);
     649             402 :   t = index2adr(L, idx);
     650                 :   api_checkvalidindex(L, t);
     651             402 :   luaV_settable(L, t, L->top - 2, L->top - 1);
     652             402 :   L->top -= 2;  /* pop index and value */
     653                 :   lua_unlock(L);
     654             402 : }
     655                 : 
     656                 : 
     657            6190 : 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            6190 :   t = index2adr(L, idx);
     663                 :   api_checkvalidindex(L, t);
     664            6190 :   setsvalue(L, &key, luaS_new(L, k));
     665            6190 :   luaV_settable(L, t, &key, L->top - 1);
     666            6190 :   L->top--;  /* pop value */
     667                 :   lua_unlock(L);
     668            6190 : }
     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           86502 : 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           86502 :   o = index2adr(L, idx);
     689                 :   api_check(L, ttistable(o));
     690           86502 :   setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
     691           86502 :   luaC_barriert(L, hvalue(o), L->top-1);
     692           86502 :   L->top--;
     693                 :   lua_unlock(L);
     694           86502 : }
     695                 : 
     696                 : 
     697             292 : 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             292 :   obj = index2adr(L, objindex);
     703                 :   api_checkvalidindex(L, obj);
     704             292 :   if (ttisnil(L->top - 1))
     705               0 :     mt = NULL;
     706                 :   else {
     707                 :     api_check(L, ttistable(L->top - 1));
     708             292 :     mt = hvalue(L->top - 1);
     709                 :   }
     710             292 :   switch (ttype(obj)) {
     711                 :     case LUA_TTABLE: {
     712             116 :       hvalue(obj)->metatable = mt;
     713             116 :       if (mt)
     714             116 :         luaC_objbarriert(L, hvalue(obj), mt);
     715             116 :       break;
     716                 :     }
     717                 :     case LUA_TUSERDATA: {
     718             141 :       uvalue(obj)->metatable = mt;
     719             141 :       if (mt)
     720             141 :         luaC_objbarrier(L, rawuvalue(obj), mt);
     721             141 :       break;
     722                 :     }
     723                 :     default: {
     724              35 :       G(L)->mt[ttype(obj)] = mt;
     725                 :       break;
     726                 :     }
     727                 :   }
     728             292 :   L->top--;
     729                 :   lua_unlock(L);
     730             292 :   return 1;
     731                 : }
     732                 : 
     733                 : 
     734             210 : LUA_API int lua_setfenv (lua_State *L, int idx) {
     735                 :   StkId o;
     736             210 :   int res = 1;
     737                 :   lua_lock(L);
     738                 :   api_checknelems(L, 1);
     739             210 :   o = index2adr(L, idx);
     740                 :   api_checkvalidindex(L, o);
     741                 :   api_check(L, ttistable(L->top - 1));
     742             210 :   switch (ttype(o)) {
     743                 :     case LUA_TFUNCTION:
     744             103 :       clvalue(o)->c.env = hvalue(L->top - 1);
     745             103 :       break;
     746                 :     case LUA_TUSERDATA:
     747             105 :       uvalue(o)->env = hvalue(L->top - 1);
     748             105 :       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                 :       break;
     755                 :   }
     756             210 :   if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
     757             210 :   L->top--;
     758                 :   lua_unlock(L);
     759             210 :   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            1876 : 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            1876 :   func = L->top - (nargs+1);
     782            1876 :   luaD_call(L, func, nresults);
     783            1873 :   adjustresults(L, nresults);
     784                 :   lua_unlock(L);
     785            1873 : }
     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             294 : static void f_call (lua_State *L, void *ud) {
     799             294 :   struct CallS *c = cast(struct CallS *, ud);
     800             294 :   luaD_call(L, c->func, c->nresults);
     801              72 : }
     802                 : 
     803                 : 
     804                 : 
     805             294 : 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             294 :   if (errfunc == 0)
     813             222 :     func = 0;
     814                 :   else {
     815              72 :     StkId o = index2adr(L, errfunc);
     816                 :     api_checkvalidindex(L, o);
     817              72 :     func = savestack(L, o);
     818                 :   }
     819             294 :   c.func = L->top - (nargs+1);  /* function to be called */
     820             294 :   c.nresults = nresults;
     821             294 :   status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
     822             294 :   adjustresults(L, nresults);
     823                 :   lua_unlock(L);
     824             294 :   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              35 : static void f_Ccall (lua_State *L, void *ud) {
     838              35 :   struct CCallS *c = cast(struct CCallS *, ud);
     839                 :   Closure *cl;
     840              35 :   cl = luaF_newCclosure(L, 0, getcurrenv(L));
     841              35 :   cl->c.f = c->func;
     842              35 :   setclvalue(L, L->top, cl);  /* push function */
     843              35 :   api_incr_top(L);
     844              35 :   setpvalue(L->top, c->ud);  /* push only argument */
     845              35 :   api_incr_top(L);
     846              35 :   luaD_call(L, L->top - 2, 0);
     847              35 : }
     848                 : 
     849                 : 
     850              35 : 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              35 :   c.func = func;
     855              35 :   c.ud = ud;
     856              35 :   status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
     857                 :   lua_unlock(L);
     858              35 :   return status;
     859                 : }
     860                 : 
     861                 : 
     862                 : LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
     863             291 :                       const char *chunkname) {
     864                 :   ZIO z;
     865                 :   int status;
     866                 :   lua_lock(L);
     867             291 :   if (!chunkname) chunkname = "?";
     868             291 :   luaZ_init(L, &z, reader, data);
     869             291 :   status = luaD_protectedparser(L, &z, chunkname);
     870                 :   lua_unlock(L);
     871             291 :   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              76 : LUA_API int lua_gc (lua_State *L, int what, int data) {
     900              76 :   int res = 0;
     901                 :   global_State *g;
     902                 :   lua_lock(L);
     903              76 :   g = G(L);
     904              76 :   switch (what) {
     905                 :     case LUA_GCSTOP: {
     906              36 :       g->GCthreshold = MAX_LUMEM;
     907              36 :       break;
     908                 :     }
     909                 :     case LUA_GCRESTART: {
     910              36 :       g->GCthreshold = g->totalbytes;
     911              36 :       break;
     912                 :     }
     913                 :     case LUA_GCCOLLECT: {
     914               2 :       luaC_fullgc(L);
     915               2 :       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              76 :   return res;
     955                 : }
     956                 : 
     957                 : 
     958                 : 
     959                 : /*
     960                 : ** miscellaneous functions
     961                 : */
     962                 : 
     963                 : 
     964              55 : LUA_API int lua_error (lua_State *L) {
     965                 :   lua_lock(L);
     966                 :   api_checknelems(L, 1);
     967              55 :   luaG_errormsg(L);
     968                 :   lua_unlock(L);
     969               0 :   return 0;  /* to avoid warnings */
     970                 : }
     971                 : 
     972                 : 
     973             788 : LUA_API int lua_next (lua_State *L, int idx) {
     974                 :   StkId t;
     975                 :   int more;
     976                 :   lua_lock(L);
     977             788 :   t = index2adr(L, idx);
     978                 :   api_check(L, ttistable(t));
     979             788 :   more = luaH_next(L, hvalue(t), L->top - 1);
     980             787 :   if (more) {
     981             742 :     api_incr_top(L);
     982                 :   }
     983                 :   else  /* no more elements */
     984              45 :     L->top -= 1;  /* remove key */
     985                 :   lua_unlock(L);
     986             787 :   return more;
     987                 : }
     988                 : 
     989                 : 
     990           13072 : LUA_API void lua_concat (lua_State *L, int n) {
     991                 :   lua_lock(L);
     992                 :   api_checknelems(L, n);
     993           13072 :   if (n >= 2) {
     994             409 :     luaC_checkGC(L);
     995             409 :     luaV_concat(L, n, cast_int(L->top - L->base) - 1);
     996             409 :     L->top -= (n-1);
     997                 :   }
     998           12663 :   else if (n == 0) {  /* push empty string */
     999              15 :     setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
    1000              15 :     api_incr_top(L);
    1001                 :   }
    1002                 :   /* else n == 1; nothing to do */
    1003                 :   lua_unlock(L);
    1004           13072 : }
    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             141 : LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
    1026                 :   Udata *u;
    1027                 :   lua_lock(L);
    1028             141 :   luaC_checkGC(L);
    1029             141 :   u = luaS_newudata(L, size, getcurrenv(L));
    1030             141 :   setuvalue(L, L->top, u);
    1031             141 :   api_incr_top(L);
    1032                 :   lua_unlock(L);
    1033             141 :   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.7