?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  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.  
  1088.