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