"SfR Fresh" - the SfR Freeware/Shareware Archive

Member "lua-5.1.4/src/lapi.c" of archive lua-5.1.4.tar.gz:


As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
    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<