lapi.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:24k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /*
  2. ** $Id: lapi.c,v 2.53 2006/01/10 12:50:00 roberto Exp $
  3. ** Lua API
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <assert.h>
  7. #include <math.h>
  8. #include <stdarg.h>
  9. #include <string.h>
  10. #define lapi_c
  11. #define LUA_CORE
  12. #include "lua.h"
  13. #include "lapi.h"
  14. #include "ldebug.h"
  15. #include "ldo.h"
  16. #include "lfunc.h"
  17. #include "lgc.h"
  18. #include "lmem.h"
  19. #include "lobject.h"
  20. #include "lstate.h"
  21. #include "lstring.h"
  22. #include "ltable.h"
  23. #include "ltm.h"
  24. #include "lundump.h"
  25. #include "lvm.h"
  26. const char lua_ident[] =
  27.   "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $n"
  28.   "$Authors: " LUA_AUTHORS " $n"
  29.   "$URL: www.lua.org $n";
  30. #define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
  31. #define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject)
  32. #define api_incr_top(L)   {api_check(L, L->top < L->ci->top); L->top++;}
  33. static TValue *index2adr (lua_State *L, int idx) {
  34.   if (idx > 0) {
  35.     TValue *o = L->base + (idx - 1);
  36.     api_check(L, idx <= L->ci->top - L->base);
  37.     if (o >= L->top) return cast(TValue *, luaO_nilobject);
  38.     else return o;
  39.   }
  40.   else if (idx > LUA_REGISTRYINDEX) {
  41.     api_check(L, idx != 0 && -idx <= L->top - L->base);
  42.     return L->top + idx;
  43.   }
  44.   else switch (idx) {  /* pseudo-indices */
  45.     case LUA_REGISTRYINDEX: return registry(L);
  46.     case LUA_ENVIRONINDEX: {
  47.       Closure *func = curr_func(L);
  48.       sethvalue(L, &L->env, func->c.env);
  49.       return &L->env;
  50.     }
  51.     case LUA_GLOBALSINDEX: return gt(L);
  52.     default: {
  53.       Closure *func = curr_func(L);
  54.       idx = LUA_GLOBALSINDEX - idx;
  55.       return (idx <= func->c.nupvalues)
  56.                 ? &func->c.upvalue[idx-1]
  57.                 : cast(TValue *, luaO_nilobject);
  58.     }
  59.   }
  60. }
  61. static Table *getcurrenv (lua_State *L) {
  62.   if (L->ci == L->base_ci)  /* no enclosing function? */
  63.     return hvalue(gt(L));  /* use global table as environment */
  64.   else {
  65.     Closure *func = curr_func(L);
  66.     return func->c.env;
  67.   }
  68. }
  69. void luaA_pushobject (lua_State *L, const TValue *o) {
  70.   setobj2s(L, L->top, o);
  71.   api_incr_top(L);
  72. }
  73. LUA_API int lua_checkstack (lua_State *L, int size) {
  74.   int res;
  75.   lua_lock(L);
  76.   if ((L->top - L->base + size) > LUAI_MAXCSTACK)
  77.     res = 0;  /* stack overflow */
  78.   else {
  79.     luaD_checkstack(L, size);
  80.     if (L->ci->top < L->top + size)
  81.       L->ci->top = L->top + size;
  82.     res = 1;
  83.   }
  84.   lua_unlock(L);
  85.   return res;
  86. }
  87. LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
  88.   int i;
  89.   if (from == to) return;
  90.   lua_lock(to);
  91.   api_checknelems(from, n);
  92.   api_check(from, G(from) == G(to));
  93.   api_check(from, to->ci->top - to->top >= n);
  94.   from->top -= n;
  95.   for (i = 0; i < n; i++) {
  96.     setobj2s(to, to->top++, from->top + i);
  97.   }
  98.   lua_unlock(to);
  99. }
  100. LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
  101.   lua_CFunction old;
  102.   lua_lock(L);
  103.   old = G(L)->panic;
  104.   G(L)->panic = panicf;
  105.   lua_unlock(L);
  106.   return old;
  107. }
  108. LUA_API lua_State *lua_newthread (lua_State *L) {
  109.   lua_State *L1;
  110.   lua_lock(L);
  111.   luaC_checkGC(L);
  112.   L1 = luaE_newthread(L);
  113.   setthvalue(L, L->top, L1);
  114.   api_incr_top(L);
  115.   lua_unlock(L);
  116.   luai_userstatethread(L, L1);
  117.   return L1;
  118. }
  119. /*
  120. ** basic stack manipulation
  121. */
  122. LUA_API int lua_gettop (lua_State *L) {
  123.   return cast_int(L->top - L->base);
  124. }
  125. LUA_API void lua_settop (lua_State *L, int idx) {
  126.   lua_lock(L);
  127.   if (idx >= 0) {
  128.     api_check(L, idx <= L->stack_last - L->base);
  129.     while (L->top < L->base + idx)
  130.       setnilvalue(L->top++);
  131.     L->top = L->base + idx;
  132.   }
  133.   else {
  134.     api_check(L, -(idx+1) <= (L->top - L->base));
  135.     L->top += idx+1;  /* `subtract' index (index is negative) */
  136.   }
  137.   lua_unlock(L);
  138. }
  139. LUA_API void lua_remove (lua_State *L, int idx) {
  140.   StkId p;
  141.   lua_lock(L);
  142.   p = index2adr(L, idx);
  143.   api_checkvalidindex(L, p);
  144.   while (++p < L->top) setobjs2s(L, p-1, p);
  145.   L->top--;
  146.   lua_unlock(L);
  147. }
  148. LUA_API void lua_insert (lua_State *L, int idx) {
  149.   StkId p;
  150.   StkId q;
  151.   lua_lock(L);
  152.   p = index2adr(L, idx);
  153.   api_checkvalidindex(L, p);
  154.   for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
  155.   setobjs2s(L, p, L->top);
  156.   lua_unlock(L);
  157. }
  158. LUA_API void lua_replace (lua_State *L, int idx) {
  159.   StkId o;
  160.   lua_lock(L);
  161.   api_checknelems(L, 1);
  162.   o = index2adr(L, idx);
  163.   api_checkvalidindex(L, o);
  164.   if (idx == LUA_ENVIRONINDEX) {
  165.     Closure *func = curr_func(L);
  166.     api_check(L, ttistable(L->top - 1)); 
  167.     func->c.env = hvalue(L->top - 1);
  168.     luaC_barrier(L, func, L->top - 1);
  169.   }
  170.   else {
  171.     setobj(L, o, L->top - 1);
  172.     if (idx < LUA_GLOBALSINDEX)  /* function upvalue? */
  173.       luaC_barrier(L, curr_func(L), L->top - 1);
  174.   }
  175.   L->top--;
  176.   lua_unlock(L);
  177. }
  178. LUA_API void lua_pushvalue (lua_State *L, int idx) {
  179.   lua_lock(L);
  180.   setobj2s(L, L->top, index2adr(L, idx));
  181.   api_incr_top(L);
  182.   lua_unlock(L);
  183. }
  184. /*
  185. ** access functions (stack -> C)
  186. */
  187. LUA_API int lua_type (lua_State *L, int idx) {
  188.   StkId o = index2adr(L, idx);
  189.   return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
  190. }
  191. LUA_API const char *lua_typename (lua_State *L, int t) {
  192.   UNUSED(L);
  193.   return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
  194. }
  195. LUA_API int lua_iscfunction (lua_State *L, int idx) {
  196.   StkId o = index2adr(L, idx);
  197.   return iscfunction(o);
  198. }
  199. LUA_API int lua_isnumber (lua_State *L, int idx) {
  200.   TValue n;
  201.   const TValue *o = index2adr(L, idx);
  202.   return tonumber(o, &n);
  203. }
  204. LUA_API int lua_isstring (lua_State *L, int idx) {
  205.   int t = lua_type(L, idx);
  206.   return (t == LUA_TSTRING || t == LUA_TNUMBER);
  207. }
  208. LUA_API int lua_isuserdata (lua_State *L, int idx) {
  209.   const TValue *o = index2adr(L, idx);
  210.   return (ttisuserdata(o) || ttislightuserdata(o));
  211. }
  212. LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
  213.   StkId o1 = index2adr(L, index1);
  214.   StkId o2 = index2adr(L, index2);
  215.   return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
  216.          : luaO_rawequalObj(o1, o2);
  217. }
  218. LUA_API int lua_equal (lua_State *L, int index1, int index2) {
  219.   StkId o1, o2;
  220.   int i;
  221.   lua_lock(L);  /* may call tag method */
  222.   o1 = index2adr(L, index1);
  223.   o2 = index2adr(L, index2);
  224.   i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2);
  225.   lua_unlock(L);
  226.   return i;
  227. }
  228. LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
  229.   StkId o1, o2;
  230.   int i;
  231.   lua_lock(L);  /* may call tag method */
  232.   o1 = index2adr(L, index1);
  233.   o2 = index2adr(L, index2);
  234.   i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
  235.        : luaV_lessthan(L, o1, o2);
  236.   lua_unlock(L);
  237.   return i;
  238. }
  239. LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
  240.   TValue n;
  241.   const TValue *o = index2adr(L, idx);
  242.   if (tonumber(o, &n))
  243.     return nvalue(o);
  244.   else
  245.     return 0;
  246. }
  247. LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
  248.   TValue n;
  249.   const TValue *o = index2adr(L, idx);
  250.   if (tonumber(o, &n)) {
  251.     lua_Integer res;
  252.     lua_Number num = nvalue(o);
  253.     lua_number2integer(res, num);
  254.     return res;
  255.   }
  256.   else
  257.     return 0;
  258. }
  259. LUA_API int lua_toboolean (lua_State *L, int idx) {
  260.   const TValue *o = index2adr(L, idx);
  261.   return !l_isfalse(o);
  262. }
  263. LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
  264.   StkId o = index2adr(L, idx);
  265.   if (!ttisstring(o)) {
  266.     lua_lock(L);  /* `luaV_tostring' may create a new string */
  267.     if (!luaV_tostring(L, o)) {  /* conversion failed? */
  268.       if (len != NULL) *len = 0;
  269.       lua_unlock(L);
  270.       return NULL;
  271.     }
  272.     luaC_checkGC(L);
  273.     o = index2adr(L, idx);  /* previous call may reallocate the stack */
  274.     lua_unlock(L);
  275.   }
  276.   if (len != NULL) *len = tsvalue(o)->len;
  277.   return svalue(o);
  278. }
  279. LUA_API size_t lua_objlen (lua_State *L, int idx) {
  280.   StkId o = index2adr(L, idx);
  281.   switch (ttype(o)) {
  282.     case LUA_TSTRING: return tsvalue(o)->len;
  283.     case LUA_TUSERDATA: return uvalue(o)->len;
  284.     case LUA_TTABLE: return luaH_getn(hvalue(o));
  285.     case LUA_TNUMBER: {
  286.       size_t l;
  287.       lua_lock(L);  /* `luaV_tostring' may create a new string */
  288.       l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
  289.       lua_unlock(L);
  290.       return l;
  291.     }
  292.     default: return 0;
  293.   }
  294. }
  295. LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
  296.   StkId o = index2adr(L, idx);
  297.   return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;
  298. }
  299. LUA_API void *lua_touserdata (lua_State *L, int idx) {
  300.   StkId o = index2adr(L, idx);
  301.   switch (ttype(o)) {
  302.     case LUA_TUSERDATA: return (rawuvalue(o) + 1);
  303.     case LUA_TLIGHTUSERDATA: return pvalue(o);
  304.     default: return NULL;
  305.   }
  306. }
  307. LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
  308.   StkId o = index2adr(L, idx);
  309.   return (!ttisthread(o)) ? NULL : thvalue(o);
  310. }
  311. LUA_API const void *lua_topointer (lua_State *L, int idx) {
  312.   StkId o = index2adr(L, idx);
  313.   switch (ttype(o)) {
  314.     case LUA_TTABLE: return hvalue(o);
  315.     case LUA_TFUNCTION: return clvalue(o);
  316.     case LUA_TTHREAD: return thvalue(o);
  317.     case LUA_TUSERDATA:
  318.     case LUA_TLIGHTUSERDATA:
  319.       return lua_touserdata(L, idx);
  320.     default: return NULL;
  321.   }
  322. }
  323. /*
  324. ** push functions (C -> stack)
  325. */
  326. LUA_API void lua_pushnil (lua_State *L) {
  327.   lua_lock(L);
  328.   setnilvalue(L->top);
  329.   api_incr_top(L);
  330.   lua_unlock(L);
  331. }
  332. LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
  333.   lua_lock(L);
  334.   setnvalue(L->top, n);
  335.   api_incr_top(L);
  336.   lua_unlock(L);
  337. }
  338. LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
  339.   lua_lock(L);
  340.   setnvalue(L->top, cast_num(n));
  341.   api_incr_top(L);
  342.   lua_unlock(L);
  343. }
  344. LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
  345.   lua_lock(L);
  346.   luaC_checkGC(L);
  347.   setsvalue2s(L, L->top, luaS_newlstr(L, s, len));
  348.   api_incr_top(L);
  349.   lua_unlock(L);
  350. }
  351. LUA_API void lua_pushstring (lua_State *L, const char *s) {
  352.   if (s == NULL)
  353.     lua_pushnil(L);
  354.   else
  355.     lua_pushlstring(L, s, strlen(s));
  356. }
  357. LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
  358.                                       va_list argp) {
  359.   const char *ret;
  360.   lua_lock(L);
  361.   luaC_checkGC(L);
  362.   ret = luaO_pushvfstring(L, fmt, argp);
  363.   lua_unlock(L);
  364.   return ret;
  365. }
  366. LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
  367.   const char *ret;
  368.   va_list argp;
  369.   lua_lock(L);
  370.   luaC_checkGC(L);
  371.   va_start(argp, fmt);
  372.   ret = luaO_pushvfstring(L, fmt, argp);
  373.   va_end(argp);
  374.   lua_unlock(L);
  375.   return ret;
  376. }
  377. LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
  378.   Closure *cl;
  379.   lua_lock(L);
  380.   luaC_checkGC(L);
  381.   api_checknelems(L, n);
  382.   cl = luaF_newCclosure(L, n, getcurrenv(L));
  383.   cl->c.f = fn;
  384.   L->top -= n;
  385.   while (n--)
  386.     setobj2n(L, &cl->c.upvalue[n], L->top+n);
  387.   setclvalue(L, L->top, cl);
  388.   lua_assert(iswhite(obj2gco(cl)));
  389.   api_incr_top(L);
  390.   lua_unlock(L);
  391. }
  392. LUA_API void lua_pushboolean (lua_State *L, int b) {
  393.   lua_lock(L);
  394.   setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
  395.   api_incr_top(L);
  396.   lua_unlock(L);
  397. }
  398. LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
  399.   lua_lock(L);
  400.   setpvalue(L->top, p);
  401.   api_incr_top(L);
  402.   lua_unlock(L);
  403. }
  404. LUA_API int lua_pushthread (lua_State *L) {
  405.   lua_lock(L);
  406.   setthvalue(L, L->top, L);
  407.   api_incr_top(L);
  408.   lua_unlock(L);
  409.   return (G(L)->mainthread == L);
  410. }
  411. /*
  412. ** get functions (Lua -> stack)
  413. */
  414. LUA_API void lua_gettable (lua_State *L, int idx) {
  415.   StkId t;
  416.   lua_lock(L);
  417.   t = index2adr(L, idx);
  418.   api_checkvalidindex(L, t);
  419.   luaV_gettable(L, t, L->top - 1, L->top - 1);
  420.   lua_unlock(L);
  421. }
  422. LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
  423.   StkId t;
  424.   TValue key;
  425.   lua_lock(L);
  426.   t = index2adr(L, idx);
  427.   api_checkvalidindex(L, t);
  428.   setsvalue(L, &key, luaS_new(L, k));
  429.   luaV_gettable(L, t, &key, L->top);
  430.   api_incr_top(L);
  431.   lua_unlock(L);
  432. }
  433. LUA_API void lua_rawget (lua_State *L, int idx) {
  434.   StkId t;
  435.   lua_lock(L);
  436.   t = index2adr(L, idx);
  437.   api_check(L, ttistable(t));
  438.   setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
  439.   lua_unlock(L);
  440. }
  441. LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
  442.   StkId o;
  443.   lua_lock(L);
  444.   o = index2adr(L, idx);
  445.   api_check(L, ttistable(o));
  446.   setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
  447.   api_incr_top(L);
  448.   lua_unlock(L);
  449. }
  450. LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
  451.   lua_lock(L);
  452.   luaC_checkGC(L);
  453.   sethvalue(L, L->top, luaH_new(L, narray, nrec));
  454.   api_incr_top(L);
  455.   lua_unlock(L);
  456. }
  457. LUA_API int lua_getmetatable (lua_State *L, int objindex) {
  458.   const TValue *obj;
  459.   Table *mt = NULL;
  460.   int res;
  461.   lua_lock(L);
  462.   obj = index2adr(L, objindex);
  463.   switch (ttype(obj)) {
  464.     case LUA_TTABLE:
  465.       mt = hvalue(obj)->metatable;
  466.       break;
  467.     case LUA_TUSERDATA:
  468.       mt = uvalue(obj)->metatable;
  469.       break;
  470.     default:
  471.       mt = G(L)->mt[ttype(obj)];
  472.       break;
  473.   }
  474.   if (mt == NULL)
  475.     res = 0;
  476.   else {
  477.     sethvalue(L, L->top, mt);
  478.     api_incr_top(L);
  479.     res = 1;
  480.   }
  481.   lua_unlock(L);
  482.   return res;
  483. }
  484. LUA_API void lua_getfenv (lua_State *L, int idx) {
  485.   StkId o;
  486.   lua_lock(L);
  487.   o = index2adr(L, idx);
  488.   api_checkvalidindex(L, o);
  489.   switch (ttype(o)) {
  490.     case LUA_TFUNCTION:
  491.       sethvalue(L, L->top, clvalue(o)->c.env);
  492.       break;
  493.     case LUA_TUSERDATA:
  494.       sethvalue(L, L->top, uvalue(o)->env);
  495.       break;
  496.     case LUA_TTHREAD:
  497.       setobj2s(L, L->top,  gt(thvalue(o)));
  498.       break;
  499.     default:
  500.       setnilvalue(L->top);
  501.       break;
  502.   }
  503.   api_incr_top(L);
  504.   lua_unlock(L);
  505. }
  506. /*
  507. ** set functions (stack -> Lua)
  508. */
  509. LUA_API void lua_settable (lua_State *L, int idx) {
  510.   StkId t;
  511.   lua_lock(L);
  512.   api_checknelems(L, 2);
  513.   t = index2adr(L, idx);
  514.   api_checkvalidindex(L, t);
  515.   luaV_settable(L, t, L->top - 2, L->top - 1);
  516.   L->top -= 2;  /* pop index and value */
  517.   lua_unlock(L);
  518. }
  519. LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
  520.   StkId t;
  521.   TValue key;
  522.   lua_lock(L);
  523.   api_checknelems(L, 1);
  524.   t = index2adr(L, idx);
  525.   api_checkvalidindex(L, t);
  526.   setsvalue(L, &key, luaS_new(L, k));
  527.   luaV_settable(L, t, &key, L->top - 1);
  528.   L->top--;  /* pop value */
  529.   lua_unlock(L);
  530. }
  531. LUA_API void lua_rawset (lua_State *L, int idx) {
  532.   StkId t;
  533.   lua_lock(L);
  534.   api_checknelems(L, 2);
  535.   t = index2adr(L, idx);
  536.   api_check(L, ttistable(t));
  537.   setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
  538.   luaC_barriert(L, hvalue(t), L->top-1);
  539.   L->top -= 2;
  540.   lua_unlock(L);
  541. }
  542. LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
  543.   StkId o;
  544.   lua_lock(L);
  545.   api_checknelems(L, 1);
  546.   o = index2adr(L, idx);
  547.   api_check(L, ttistable(o));
  548.   setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
  549.   luaC_barriert(L, hvalue(o), L->top-1);
  550.   L->top--;
  551.   lua_unlock(L);
  552. }
  553. LUA_API int lua_setmetatable (lua_State *L, int objindex) {
  554.   TValue *obj;
  555.   Table *mt;
  556.   lua_lock(L);
  557.   api_checknelems(L, 1);
  558.   obj = index2adr(L, objindex);
  559.   api_checkvalidindex(L, obj);
  560.   if (ttisnil(L->top - 1))
  561.     mt = NULL;
  562.   else {
  563.     api_check(L, ttistable(L->top - 1));
  564.     mt = hvalue(L->top - 1);
  565.   }
  566.   switch (ttype(obj)) {
  567.     case LUA_TTABLE: {
  568.       hvalue(obj)->metatable = mt;
  569.       if (mt)
  570.         luaC_objbarriert(L, hvalue(obj), mt);
  571.       break;
  572.     }
  573.     case LUA_TUSERDATA: {
  574.       uvalue(obj)->metatable = mt;
  575.       if (mt)
  576.         luaC_objbarrier(L, rawuvalue(obj), mt);
  577.       break;
  578.     }
  579.     default: {
  580.       G(L)->mt[ttype(obj)] = mt;
  581.       break;
  582.     }
  583.   }
  584.   L->top--;
  585.   lua_unlock(L);
  586.   return 1;
  587. }
  588. LUA_API int lua_setfenv (lua_State *L, int idx) {
  589.   StkId o;
  590.   int res = 1;
  591.   lua_lock(L);
  592.   api_checknelems(L, 1);
  593.   o = index2adr(L, idx);
  594.   api_checkvalidindex(L, o);
  595.   api_check(L, ttistable(L->top - 1));
  596.   switch (ttype(o)) {
  597.     case LUA_TFUNCTION:
  598.       clvalue(o)->c.env = hvalue(L->top - 1);
  599.       break;
  600.     case LUA_TUSERDATA:
  601.       uvalue(o)->env = hvalue(L->top - 1);
  602.       break;
  603.     case LUA_TTHREAD:
  604.       sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1));
  605.       break;
  606.     default:
  607.       res = 0;
  608.       break;
  609.   }
  610.   luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
  611.   L->top--;
  612.   lua_unlock(L);
  613.   return res;
  614. }
  615. /*
  616. ** `load' and `call' functions (run Lua code)
  617. */
  618. #define adjustresults(L,nres) 
  619.     { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; }
  620. #define checkresults(L,na,nr) 
  621.      api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
  622. LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
  623.   StkId func;
  624.   lua_lock(L);
  625.   api_checknelems(L, nargs+1);
  626.   checkresults(L, nargs, nresults);
  627.   func = L->top - (nargs+1);
  628.   luaD_call(L, func, nresults);
  629.   adjustresults(L, nresults);
  630.   lua_unlock(L);
  631. }
  632. /*
  633. ** Execute a protected call.
  634. */
  635. struct CallS {  /* data to `f_call' */
  636.   StkId func;
  637.   int nresults;
  638. };
  639. static void f_call (lua_State *L, void *ud) {
  640.   struct CallS *c = cast(struct CallS *, ud);
  641.   luaD_call(L, c->func, c->nresults);
  642. }
  643. LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
  644.   struct CallS c;
  645.   int status;
  646.   ptrdiff_t func;
  647.   lua_lock(L);
  648.   api_checknelems(L, nargs+1);
  649.   checkresults(L, nargs, nresults);
  650.   if (errfunc == 0)
  651.     func = 0;
  652.   else {
  653.     StkId o = index2adr(L, errfunc);
  654.     api_checkvalidindex(L, o);
  655.     func = savestack(L, o);
  656.   }
  657.   c.func = L->top - (nargs+1);  /* function to be called */
  658.   c.nresults = nresults;
  659.   status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
  660.   adjustresults(L, nresults);
  661.   lua_unlock(L);
  662.   return status;
  663. }
  664. /*
  665. ** Execute a protected C call.
  666. */
  667. struct CCallS {  /* data to `f_Ccall' */
  668.   lua_CFunction func;
  669.   void *ud;
  670. };
  671. static void f_Ccall (lua_State *L, void *ud) {
  672.   struct CCallS *c = cast(struct CCallS *, ud);
  673.   Closure *cl;
  674.   cl = luaF_newCclosure(L, 0, getcurrenv(L));
  675.   cl->c.f = c->func;
  676.   setclvalue(L, L->top, cl);  /* push function */
  677.   api_incr_top(L);
  678.   setpvalue(L->top, c->ud);  /* push only argument */
  679.   api_incr_top(L);
  680.   luaD_call(L, L->top - 2, 0);
  681. }
  682. LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
  683.   struct CCallS c;
  684.   int status;
  685.   lua_lock(L);
  686.   c.func = func;
  687.   c.ud = ud;
  688.   status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
  689.   lua_unlock(L);
  690.   return status;
  691. }
  692. LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
  693.                       const char *chunkname) {
  694.   ZIO z;
  695.   int status;
  696.   lua_lock(L);
  697.   if (!chunkname) chunkname = "?";
  698.   luaZ_init(L, &z, reader, data);
  699.   status = luaD_protectedparser(L, &z, chunkname);
  700.   lua_unlock(L);
  701.   return status;
  702. }
  703. LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
  704.   int status;
  705.   TValue *o;
  706.   lua_lock(L);
  707.   api_checknelems(L, 1);
  708.   o = L->top - 1;
  709.   if (isLfunction(o))
  710.     status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
  711.   else
  712.     status = 1;
  713.   lua_unlock(L);
  714.   return status;
  715. }
  716. LUA_API int  lua_status (lua_State *L) {
  717.   return L->status;
  718. }
  719. /*
  720. ** Garbage-collection function
  721. */
  722. LUA_API int lua_gc (lua_State *L, int what, int data) {
  723.   int res = 0;
  724.   global_State *g;
  725.   lua_lock(L);
  726.   g = G(L);
  727.   switch (what) {
  728.     case LUA_GCSTOP: {
  729.       g->GCthreshold = MAX_LUMEM;
  730.       break;
  731.     }
  732.     case LUA_GCRESTART: {
  733.       g->GCthreshold = g->totalbytes;
  734.       break;
  735.     }
  736.     case LUA_GCCOLLECT: {
  737.       luaC_fullgc(L);
  738.       break;
  739.     }
  740.     case LUA_GCCOUNT: {
  741.       /* GC values are expressed in Kbytes: #bytes/2^10 */
  742.       res = cast_int(g->totalbytes >> 10);
  743.       break;
  744.     }
  745.     case LUA_GCCOUNTB: {
  746.       res = cast_int(g->totalbytes & 0x3ff);
  747.       break;
  748.     }
  749.     case LUA_GCSTEP: {
  750.       lu_mem a = (cast(lu_mem, data) << 10);
  751.       if (a <= g->totalbytes)
  752.         g->GCthreshold = g->totalbytes - a;
  753.       else
  754.         g->GCthreshold = 0;
  755.       while (g->GCthreshold <= g->totalbytes)
  756.         luaC_step(L);
  757.       if (g->gcstate == GCSpause)  /* end of cycle? */
  758.         res = 1;  /* signal it */
  759.       break;
  760.     }
  761.     case LUA_GCSETPAUSE: {
  762.       res = g->gcpause;
  763.       g->gcpause = data;
  764.       break;
  765.     }
  766.     case LUA_GCSETSTEPMUL: {
  767.       res = g->gcstepmul;
  768.       g->gcstepmul = data;
  769.       break;
  770.     }
  771.     default: res = -1;  /* invalid option */
  772.   }
  773.   lua_unlock(L);
  774.   return res;
  775. }
  776. /*
  777. ** miscellaneous functions
  778. */
  779. LUA_API int lua_error (lua_State *L) {
  780.   lua_lock(L);
  781.   api_checknelems(L, 1);
  782.   luaG_errormsg(L);
  783.   lua_unlock(L);
  784.   return 0;  /* to avoid warnings */
  785. }
  786. LUA_API int lua_next (lua_State *L, int idx) {
  787.   StkId t;
  788.   int more;
  789.   lua_lock(L);
  790.   t = index2adr(L, idx);
  791.   api_check(L, ttistable(t));
  792.   more = luaH_next(L, hvalue(t), L->top - 1);
  793.   if (more) {
  794.     api_incr_top(L);
  795.   }
  796.   else  /* no more elements */
  797.     L->top -= 1;  /* remove key */
  798.   lua_unlock(L);
  799.   return more;
  800. }
  801. LUA_API void lua_concat (lua_State *L, int n) {
  802.   lua_lock(L);
  803.   api_checknelems(L, n);
  804.   if (n >= 2) {
  805.     luaC_checkGC(L);
  806.     luaV_concat(L, n, cast_int(L->top - L->base) - 1);
  807.     L->top -= (n-1);
  808.   }
  809.   else if (n == 0) {  /* push empty string */
  810.     setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
  811.     api_incr_top(L);
  812.   }
  813.   /* else n == 1; nothing to do */
  814.   lua_unlock(L);
  815. }
  816. LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
  817.   lua_Alloc f;
  818.   lua_lock(L);
  819.   if (ud) *ud = G(L)->ud;
  820.   f = G(L)->frealloc;
  821.   lua_unlock(L);
  822.   return f;
  823. }
  824. LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
  825.   lua_lock(L);
  826.   G(L)->ud = ud;
  827.   G(L)->frealloc = f;
  828.   lua_unlock(L);
  829. }
  830. LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
  831.   Udata *u;
  832.   lua_lock(L);
  833.   luaC_checkGC(L);
  834.   u = luaS_newudata(L, size, getcurrenv(L));
  835.   setuvalue(L, L->top, u);
  836.   api_incr_top(L);
  837.   lua_unlock(L);
  838.   return u + 1;
  839. }
  840. static const char *aux_upvalue (StkId fi, int n, TValue **val) {
  841.   Closure *f;
  842.   if (!ttisfunction(fi)) return NULL;
  843.   f = clvalue(fi);
  844.   if (f->c.isC) {
  845.     if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
  846.     *val = &f->c.upvalue[n-1];
  847.     return "";
  848.   }
  849.   else {
  850.     Proto *p = f->l.p;
  851.     if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
  852.     *val = f->l.upvals[n-1]->v;
  853.     return getstr(p->upvalues[n-1]);
  854.   }
  855. }
  856. LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
  857.   const char *name;
  858.   TValue *val;
  859.   lua_lock(L);
  860.   name = aux_upvalue(index2adr(L, funcindex), n, &val);
  861.   if (name) {
  862.     setobj2s(L, L->top, val);
  863.     api_incr_top(L);
  864.   }
  865.   lua_unlock(L);
  866.   return name;
  867. }
  868. LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
  869.   const char *name;
  870.   TValue *val;
  871.   StkId fi;
  872.   lua_lock(L);
  873.   fi = index2adr(L, funcindex);
  874.   api_checknelems(L, 1);
  875.   name = aux_upvalue(fi, n, &val);
  876.   if (name) {
  877.     L->top--;
  878.     setobj(L, val, L->top);
  879.     luaC_barrier(L, clvalue(fi), L->top);
  880.   }
  881.   lua_unlock(L);
  882.   return name;
  883. }
  884. LUA_API void lua_settable_userdata (lua_State *L, int idx, void *userdata) 
  885. {
  886.   StkId t;
  887.   lua_lock(L);
  888.   api_checknelems(L, 2);
  889.   t = index2adr(L, idx);
  890.   api_checkvalidindex(L, t);
  891.    if (ttistable(t)) 
  892.    {
  893.       Table *h = hvalue(t);
  894.   h->userdata = userdata;
  895.    }
  896.   lua_unlock(L);
  897. }
  898. LUA_API void *lua_gettable_userdata (lua_State *L, int idx) 
  899. {
  900.   StkId t;
  901.   void *p = NULL; 
  902.   lua_lock(L);
  903.   api_checknelems(L, 2);
  904.   t = index2adr(L, idx);
  905.   api_checkvalidindex(L, t);
  906.   if (ttistable(t)) 
  907.    {
  908.       Table *h = hvalue(t);
  909.   p = h->userdata;
  910.    }
  911.   lua_unlock(L);
  912.   return p;
  913. }