lua/lapi.c

Go to the documentation of this file.
00001 /*
00002 ** $Id: lapi.c,v 1.2 2004/03/23 05:09:14 jbj Exp $
00003 ** Lua API
00004 ** See Copyright Notice in lua.h
00005 */
00006 
00007 
00008 #include <assert.h>
00009 #include <string.h>
00010 
00011 #define lapi_c
00012 
00013 #include "lua.h"
00014 
00015 #include "lapi.h"
00016 #include "ldebug.h"
00017 #include "ldo.h"
00018 #include "lfunc.h"
00019 #include "lgc.h"
00020 #include "lmem.h"
00021 #include "lobject.h"
00022 #include "lstate.h"
00023 #include "lstring.h"
00024 #include "ltable.h"
00025 #include "ltm.h"
00026 #include "lundump.h"
00027 #include "lvm.h"
00028 
00029 
00030 /*@unused@*/
00031 const char lua_ident[] =
00032   "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
00033   "$Authors: " LUA_AUTHORS " $\n"
00034   "$URL: www.lua.org $\n";
00035 
00036 
00037 
00038 #ifndef api_check
00039 #define api_check(L, o)         /*{ assert(o); }*/
00040 #endif
00041 
00042 #define api_checknelems(L, n)   api_check(L, (n) <= (L->top - L->base))
00043 
00044 #define api_incr_top(L)   {api_check(L, L->top < L->ci->top); L->top++;}
00045 
00046 
00047 
00048 
00049 /*@dependent@*/ /*@null@*/
00050 static TObject *negindex (lua_State *L, int idx)
00051         /*@*/
00052 {
00053   if (idx > LUA_REGISTRYINDEX) {
00054     api_check(L, idx != 0 && -idx <= L->top - L->base);
00055     return L->top+idx;
00056   }
00057   else switch (idx) {  /* pseudo-indices */
00058     case LUA_REGISTRYINDEX: return registry(L);
00059     case LUA_GLOBALSINDEX: return gt(L);
00060     default: {
00061       TObject *func = (L->base - 1);
00062       idx = LUA_GLOBALSINDEX - idx;
00063       lua_assert(iscfunction(func));
00064       return (idx <= clvalue(func)->c.nupvalues)
00065                 ? &clvalue(func)->c.upvalue[idx-1]
00066                 : NULL;
00067     }
00068   }
00069 }
00070 
00071 
00072 /*@dependent@*/ /*@relnull@*/
00073 static TObject *luaA_index (lua_State *L, int idx)
00074         /*@*/
00075 {
00076   if (idx > 0) {
00077     api_check(L, idx <= L->top - L->base);
00078     return L->base + idx - 1;
00079   }
00080   else {
00081     TObject *o = negindex(L, idx);
00082     api_check(L, o != NULL);
00083     return o;
00084   }
00085 }
00086 
00087 
00088 /*@dependent@*/ /*@null@*/
00089 static TObject *luaA_indexAcceptable (lua_State *L, int idx)
00090         /*@*/
00091 {
00092   if (idx > 0) {
00093     TObject *o = L->base+(idx-1);
00094     api_check(L, idx <= L->stack_last - L->base);
00095     if (o >= L->top) return NULL;
00096     else return o;
00097   }
00098   else
00099     return negindex(L, idx);
00100 }
00101 
00102 
00103 void luaA_pushobject (lua_State *L, const TObject *o) {
00104   setobj2s(L->top, o);
00105   incr_top(L);
00106 }
00107 
00108 
00109 LUA_API int lua_checkstack (lua_State *L, int size) {
00110   int res;
00111   lua_lock(L);
00112   if ((L->top - L->base + size) > LUA_MAXCSTACK)
00113     res = 0;  /* stack overflow */
00114   else {
00115     luaD_checkstack(L, size);
00116     if (L->ci->top < L->top + size)
00117       L->ci->top = L->top + size;
00118     res = 1;
00119   }
00120   lua_unlock(L);
00121   return res;
00122 }
00123 
00124 
00125 LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
00126   int i;
00127   lua_lock(to);
00128   api_checknelems(from, n);
00129   from->top -= n;
00130   for (i = 0; i < n; i++) {
00131     setobj2s(to->top, from->top + i);
00132     api_incr_top(to);
00133   }
00134   lua_unlock(to);
00135 }
00136 
00137 
00138 LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
00139   lua_CFunction old;
00140   lua_lock(L);
00141   old = G(L)->panic;
00142   G(L)->panic = panicf;
00143   lua_unlock(L);
00144   return old;
00145 }
00146 
00147 
00148 LUA_API lua_State *lua_newthread (lua_State *L) {
00149   lua_State *L1;
00150   lua_lock(L);
00151   luaC_checkGC(L);
00152   L1 = luaE_newthread(L);
00153   setthvalue(L->top, L1);
00154   api_incr_top(L);
00155   lua_unlock(L);
00156   lua_userstateopen(L1);
00157 /*@-kepttrans@*/
00158   return L1;
00159 /*@=kepttrans@*/
00160 }
00161 
00162 
00163 
00164 /*
00165 ** basic stack manipulation
00166 */
00167 
00168 
00169 LUA_API int lua_gettop (lua_State *L) {
00170   return (L->top - L->base);
00171 }
00172 
00173 
00174 LUA_API void lua_settop (lua_State *L, int idx) {
00175   lua_lock(L);
00176   if (idx >= 0) {
00177     api_check(L, idx <= L->stack_last - L->base);
00178     while (L->top < L->base + idx)
00179       setnilvalue(L->top++);
00180     L->top = L->base + idx;
00181   }
00182   else {
00183     api_check(L, -(idx+1) <= (L->top - L->base));
00184     L->top += idx+1;  /* `subtract' index (index is negative) */
00185   }
00186   lua_unlock(L);
00187 }
00188 
00189 
00190 LUA_API void lua_remove (lua_State *L, int idx) {
00191   StkId p;
00192   lua_lock(L);
00193   p = luaA_index(L, idx);
00194   while (++p < L->top) setobjs2s(p-1, p);
00195   L->top--;
00196   lua_unlock(L);
00197 }
00198 
00199 
00200 LUA_API void lua_insert (lua_State *L, int idx) {
00201   StkId p;
00202   StkId q;
00203   lua_lock(L);
00204   p = luaA_index(L, idx);
00205   for (q = L->top; q>p; q--) setobjs2s(q, q-1);
00206   setobjs2s(p, L->top);
00207   lua_unlock(L);
00208 }
00209 
00210 
00211 LUA_API void lua_replace (lua_State *L, int idx) {
00212   lua_lock(L);
00213   api_checknelems(L, 1);
00214   setobj(luaA_index(L, idx), L->top - 1);  /* write barrier */
00215   L->top--;
00216   lua_unlock(L);
00217 }
00218 
00219 
00220 LUA_API void lua_pushvalue (lua_State *L, int idx) {
00221   lua_lock(L);
00222   setobj2s(L->top, luaA_index(L, idx));
00223   api_incr_top(L);
00224   lua_unlock(L);
00225 }
00226 
00227 
00228 
00229 /*
00230 ** access functions (stack -> C)
00231 */
00232 
00233 
00234 LUA_API int lua_type (lua_State *L, int idx) {
00235   StkId o = luaA_indexAcceptable(L, idx);
00236   return (o == NULL) ? LUA_TNONE : ttype(o);
00237 }
00238 
00239 
00240 LUA_API const char *lua_typename (lua_State *L, int t) {
00241   UNUSED(L);
00242   return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
00243 }
00244 
00245 
00246 LUA_API int lua_iscfunction (lua_State *L, int idx) {
00247   StkId o = luaA_indexAcceptable(L, idx);
00248   return (o == NULL) ? 0 : iscfunction(o);
00249 }
00250 
00251 
00252 LUA_API int lua_isnumber (lua_State *L, int idx) {
00253   TObject n;
00254   const TObject *o = luaA_indexAcceptable(L, idx);
00255   return (o != NULL && tonumber(o, &n));
00256 }
00257 
00258 
00259 LUA_API int lua_isstring (lua_State *L, int idx) {
00260   int t = lua_type(L, idx);
00261   return (t == LUA_TSTRING || t == LUA_TNUMBER);
00262 }
00263 
00264 
00265 LUA_API int lua_isuserdata (lua_State *L, int idx) {
00266   const TObject *o = luaA_indexAcceptable(L, idx);
00267   return (o != NULL && (ttisuserdata(o) || ttislightuserdata(o)));
00268 }
00269 
00270 
00271 LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
00272   StkId o1 = luaA_indexAcceptable(L, index1);
00273   StkId o2 = luaA_indexAcceptable(L, index2);
00274   return (o1 == NULL || o2 == NULL) ? 0  /* index out of range */
00275                                     : luaO_rawequalObj(o1, o2);
00276 }
00277 
00278 
00279 LUA_API int lua_equal (lua_State *L, int index1, int index2) {
00280   StkId o1, o2;
00281   int i;
00282   lua_lock(L);  /* may call tag method */
00283   o1 = luaA_indexAcceptable(L, index1);
00284   o2 = luaA_indexAcceptable(L, index2);
00285   i = (o1 == NULL || o2 == NULL) ? 0  /* index out of range */
00286                                  : equalobj(L, o1, o2);
00287   lua_unlock(L);
00288   return i;
00289 }
00290 
00291 
00292 LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
00293   StkId o1, o2;
00294   int i;
00295   lua_lock(L);  /* may call tag method */
00296   o1 = luaA_indexAcceptable(L, index1);
00297   o2 = luaA_indexAcceptable(L, index2);
00298   i = (o1 == NULL || o2 == NULL) ? 0  /* index out-of-range */
00299                                  : luaV_lessthan(L, o1, o2);
00300   lua_unlock(L);
00301   return i;
00302 }
00303 
00304 
00305 
00306 LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
00307   TObject n;
00308   const TObject *o = luaA_indexAcceptable(L, idx);
00309   if (o != NULL && tonumber(o, &n))
00310     return nvalue(o);
00311   else
00312     return 0;
00313 }
00314 
00315 
00316 LUA_API int lua_toboolean (lua_State *L, int idx) {
00317   const TObject *o = luaA_indexAcceptable(L, idx);
00318   return (o != NULL) && !l_isfalse(o);
00319 }
00320 
00321 
00322 LUA_API const char *lua_tostring (lua_State *L, int idx) {
00323   StkId o = luaA_indexAcceptable(L, idx);
00324   if (o == NULL)
00325     return NULL;
00326   else if (ttisstring(o))
00327     return svalue(o);
00328   else {
00329     const char *s;
00330     lua_lock(L);  /* `luaV_tostring' may create a new string */
00331     s = (luaV_tostring(L, o) ? svalue(o) : NULL);
00332     luaC_checkGC(L);
00333     lua_unlock(L);
00334     return s;
00335   }
00336 }
00337 
00338 
00339 LUA_API size_t lua_strlen (lua_State *L, int idx) {
00340   StkId o = luaA_indexAcceptable(L, idx);
00341   if (o == NULL)
00342     return 0;
00343   else if (ttisstring(o))
00344     return tsvalue(o)->tsv.len;
00345   else {
00346     size_t l;
00347     lua_lock(L);  /* `luaV_tostring' may create a new string */
00348     l = (luaV_tostring(L, o) ? tsvalue(o)->tsv.len : 0);
00349     lua_unlock(L);
00350     return l;
00351   }
00352 }
00353 
00354 
00355 LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
00356   StkId o = luaA_indexAcceptable(L, idx);
00357   return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->c.f;
00358 }
00359 
00360 
00361 LUA_API void *lua_touserdata (lua_State *L, int idx) {
00362   StkId o = luaA_indexAcceptable(L, idx);
00363   if (o == NULL) return NULL;
00364   switch (ttype(o)) {
00365     case LUA_TUSERDATA: return (uvalue(o) + 1);
00366     case LUA_TLIGHTUSERDATA: return pvalue(o);
00367     default: return NULL;
00368   }
00369 }
00370 
00371 
00372 LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
00373   StkId o = luaA_indexAcceptable(L, idx);
00374   return (o == NULL || !ttisthread(o)) ? NULL : thvalue(o);
00375 }
00376 
00377 
00378 LUA_API const void *lua_topointer (lua_State *L, int idx) {
00379   StkId o = luaA_indexAcceptable(L, idx);
00380   if (o == NULL) return NULL;
00381   else {
00382     switch (ttype(o)) {
00383       case LUA_TTABLE: return hvalue(o);
00384       case LUA_TFUNCTION: return clvalue(o);
00385       case LUA_TTHREAD: return thvalue(o);
00386       case LUA_TUSERDATA:
00387       case LUA_TLIGHTUSERDATA:
00388         return lua_touserdata(L, idx);
00389       default: return NULL;
00390     }
00391   }
00392 }
00393 
00394 
00395 
00396 /*
00397 ** push functions (C -> stack)
00398 */
00399 
00400 
00401 LUA_API void lua_pushnil (lua_State *L) {
00402   lua_lock(L);
00403   setnilvalue(L->top);
00404   api_incr_top(L);
00405   lua_unlock(L);
00406 }
00407 
00408 
00409 LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
00410   lua_lock(L);
00411   setnvalue(L->top, n);
00412   api_incr_top(L);
00413   lua_unlock(L);
00414 }
00415 
00416 
00417 LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
00418   lua_lock(L);
00419   luaC_checkGC(L);
00420   setsvalue2s(L->top, luaS_newlstr(L, s, len));
00421   api_incr_top(L);
00422   lua_unlock(L);
00423 }
00424 
00425 
00426 LUA_API void lua_pushstring (lua_State *L, const char *s) {
00427   if (s == NULL)
00428     lua_pushnil(L);
00429   else
00430     lua_pushlstring(L, s, strlen(s));
00431 }
00432 
00433 
00434 LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
00435                                       va_list argp) {
00436   const char *ret;
00437   lua_lock(L);
00438   luaC_checkGC(L);
00439   ret = luaO_pushvfstring(L, fmt, argp);
00440   lua_unlock(L);
00441   return ret;
00442 }
00443 
00444 
00445 LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
00446   const char *ret;
00447   va_list argp;
00448   lua_lock(L);
00449   luaC_checkGC(L);
00450   va_start(argp, fmt);
00451   ret = luaO_pushvfstring(L, fmt, argp);
00452   va_end(argp);
00453   lua_unlock(L);
00454   return ret;
00455 }
00456 
00457 
00458 LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
00459   Closure *cl;
00460   lua_lock(L);
00461   luaC_checkGC(L);
00462   api_checknelems(L, n);
00463   cl = luaF_newCclosure(L, n);
00464   cl->c.f = fn;
00465   L->top -= n;
00466   while (n--)
00467     setobj2n(&cl->c.upvalue[n], L->top+n);
00468   setclvalue(L->top, cl);
00469   api_incr_top(L);
00470   lua_unlock(L);
00471 }
00472 
00473 
00474 LUA_API void lua_pushboolean (lua_State *L, int b) {
00475   lua_lock(L);
00476   setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
00477   api_incr_top(L);
00478   lua_unlock(L);
00479 }
00480 
00481 
00482 LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
00483   lua_lock(L);
00484   setpvalue(L->top, p);
00485   api_incr_top(L);
00486   lua_unlock(L);
00487 }
00488 
00489 
00490 
00491 /*
00492 ** get functions (Lua -> stack)
00493 */
00494 
00495 
00496 LUA_API void lua_gettable (lua_State *L, int idx) {
00497   StkId t;
00498   lua_lock(L);
00499   t = luaA_index(L, idx);
00500   setobj2s(L->top - 1, luaV_gettable(L, t, L->top - 1, 0));
00501   lua_unlock(L);
00502 }
00503 
00504 
00505 LUA_API void lua_rawget (lua_State *L, int idx) {
00506   StkId t;
00507   lua_lock(L);
00508   t = luaA_index(L, idx);
00509   api_check(L, ttistable(t));
00510   setobj2s(L->top - 1, luaH_get(hvalue(t), L->top - 1));
00511   lua_unlock(L);
00512 }
00513 
00514 
00515 LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
00516   StkId o;
00517   lua_lock(L);
00518   o = luaA_index(L, idx);
00519   api_check(L, ttistable(o));
00520   setobj2s(L->top, luaH_getnum(hvalue(o), n));
00521   api_incr_top(L);
00522   lua_unlock(L);
00523 }
00524 
00525 
00526 LUA_API void lua_newtable (lua_State *L) {
00527   lua_lock(L);
00528   luaC_checkGC(L);
00529   sethvalue(L->top, luaH_new(L, 0, 0));
00530   api_incr_top(L);
00531   lua_unlock(L);
00532 }
00533 
00534 
00535 LUA_API int lua_getmetatable (lua_State *L, int objindex) {
00536   const TObject *obj;
00537   Table *mt = NULL;
00538   int res;
00539   lua_lock(L);
00540   obj = luaA_indexAcceptable(L, objindex);
00541   if (obj != NULL) {
00542     switch (ttype(obj)) {
00543       case LUA_TTABLE:
00544         mt = hvalue(obj)->metatable;
00545         break;
00546       case LUA_TUSERDATA:
00547         mt = uvalue(obj)->uv.metatable;
00548         break;
00549     }
00550   }
00551   if (mt == NULL || mt == hvalue(defaultmeta(L)))
00552     res = 0;
00553   else {
00554     sethvalue(L->top, mt);
00555     api_incr_top(L);
00556     res = 1;
00557   }
00558   lua_unlock(L);
00559   return res;
00560 }
00561 
00562 
00563 LUA_API void lua_getfenv (lua_State *L, int idx) {
00564   StkId o;
00565   lua_lock(L);
00566   o = luaA_index(L, idx);
00567   setobj2s(L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L));
00568   api_incr_top(L);
00569   lua_unlock(L);
00570 }
00571 
00572 
00573 /*
00574 ** set functions (stack -> Lua)
00575 */
00576 
00577 
00578 LUA_API void lua_settable (lua_State *L, int idx) {
00579   StkId t;
00580   lua_lock(L);
00581   api_checknelems(L, 2);
00582   t = luaA_index(L, idx);
00583   luaV_settable(L, t, L->top - 2, L->top - 1);
00584   L->top -= 2;  /* pop index and value */
00585   lua_unlock(L);
00586 }
00587 
00588 
00589 LUA_API void lua_rawset (lua_State *L, int idx) {
00590   StkId t;
00591   lua_lock(L);
00592   api_checknelems(L, 2);
00593   t = luaA_index(L, idx);
00594   api_check(L, ttistable(t));
00595   setobj2t(luaH_set(L, hvalue(t), L->top-2), L->top-1);  /* write barrier */
00596   L->top -= 2;
00597   lua_unlock(L);
00598 }
00599 
00600 
00601 LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
00602   StkId o;
00603   lua_lock(L);
00604   api_checknelems(L, 1);
00605   o = luaA_index(L, idx);
00606   api_check(L, ttistable(o));
00607   setobj2t(luaH_setnum(L, hvalue(o), n), L->top-1);  /* write barrier */
00608   L->top--;
00609   lua_unlock(L);
00610 }
00611 
00612 
00613 LUA_API int lua_setmetatable (lua_State *L, int objindex) {
00614   TObject *obj, *mt;
00615   int res = 1;
00616   lua_lock(L);
00617   api_checknelems(L, 1);
00618   obj = luaA_index(L, objindex);
00619   mt = (!ttisnil(L->top - 1)) ? L->top - 1 : defaultmeta(L);
00620   api_check(L, ttistable(mt));
00621   switch (ttype(obj)) {
00622     case LUA_TTABLE: {
00623       hvalue(obj)->metatable = hvalue(mt);  /* write barrier */
00624       break;
00625     }
00626     case LUA_TUSERDATA: {
00627       uvalue(obj)->uv.metatable = hvalue(mt);  /* write barrier */
00628       break;
00629     }
00630     default: {
00631       res = 0;  /* cannot set */
00632       break;
00633     }
00634   }
00635   L->top--;
00636   lua_unlock(L);
00637   return res;
00638 }
00639 
00640 
00641 LUA_API int lua_setfenv (lua_State *L, int idx) {
00642   StkId o;
00643   int res = 0;
00644   lua_lock(L);
00645   api_checknelems(L, 1);
00646   o = luaA_index(L, idx);
00647   L->top--;
00648   api_check(L, ttistable(L->top));
00649   if (isLfunction(o)) {
00650     res = 1;
00651     clvalue(o)->l.g = *(L->top);
00652   }
00653   lua_unlock(L);
00654   return res;
00655 }
00656 
00657 
00658 /*
00659 ** `load' and `call' functions (run Lua code)
00660 */
00661 
00662 LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
00663   StkId func;
00664   lua_lock(L);
00665   api_checknelems(L, nargs+1);
00666   func = L->top - (nargs+1);
00667   luaD_call(L, func, nresults);
00668   lua_unlock(L);
00669 }
00670 
00671 
00672 
00673 /*
00674 ** Execute a protected call.
00675 */
00676 struct CallS {  /* data to `f_call' */
00677 /*@dependent@*/
00678   StkId func;
00679   int nresults;
00680 };
00681 
00682 
00683 static void f_call (lua_State *L, void *ud)
00684         /*@modifies L @*/
00685 {
00686   struct CallS *c = cast(struct CallS *, ud);
00687   luaD_call(L, c->func, c->nresults);
00688 }
00689 
00690 
00691 
00692 LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
00693   struct CallS c;
00694   int status;
00695   ptrdiff_t func;
00696   lua_lock(L);
00697   func = (errfunc == 0) ? 0 : savestack(L, luaA_index(L, errfunc));
00698   c.func = L->top - (nargs+1);  /* function to be called */
00699   c.nresults = nresults;
00700   status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
00701   lua_unlock(L);
00702   return status;
00703 }
00704 
00705 
00706 /*
00707 ** Execute a protected C call.
00708 */
00709 struct CCallS {  /* data to `f_Ccall' */
00710   lua_CFunction func;
00711   void *ud;
00712 };
00713 
00714 
00715 static void f_Ccall (lua_State *L, void *ud)
00716         /*@modifies L @*/
00717 {
00718   struct CCallS *c = cast(struct CCallS *, ud);
00719   Closure *cl;
00720   cl = luaF_newCclosure(L, 0);
00721   cl->c.f = c->func;
00722   setclvalue(L->top, cl);  /* push function */
00723   incr_top(L);
00724   setpvalue(L->top, c->ud);  /* push only argument */
00725   incr_top(L);
00726   luaD_call(L, L->top - 2, 0);
00727 }
00728 
00729 
00730 LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
00731   struct CCallS c;
00732   int status;
00733   lua_lock(L);
00734   c.func = func;
00735   c.ud = ud;
00736   status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
00737   lua_unlock(L);
00738   return status;
00739 }
00740 
00741 
00742 LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data,
00743                       const char *chunkname) {
00744   ZIO z;
00745   int status;
00746   int c;
00747   lua_lock(L);
00748   if (!chunkname) chunkname = "?";
00749   luaZ_init(&z, reader, data, chunkname);
00750   c = luaZ_lookahead(&z);
00751   status = luaD_protectedparser(L, &z, (c == LUA_SIGNATURE[0]));
00752   lua_unlock(L);
00753   return status;
00754 }
00755 
00756 
00757 LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data) {
00758   int status;
00759   TObject *o;
00760   lua_lock(L);
00761   api_checknelems(L, 1);
00762   o = L->top - 1;
00763   if (isLfunction(o) && clvalue(o)->l.nupvalues == 0) {
00764     luaU_dump(L, clvalue(o)->l.p, writer, data);
00765     status = 1;
00766   }
00767   else
00768     status = 0;
00769   lua_unlock(L);
00770   return status;
00771 }
00772 
00773 
00774 /*
00775 ** Garbage-collection functions
00776 */
00777 
00778 /* GC values are expressed in Kbytes: #bytes/2^10 */
00779 #define GCscalel(x)             ((x)>>10)
00780 #define GCscale(x)              (cast(int, GCscalel(x)))
00781 #define GCunscale(x)            (cast(lu_mem, x)<<10)
00782 
00783 LUA_API int lua_getgcthreshold (lua_State *L) {
00784   int threshold;
00785   lua_lock(L);
00786   threshold = GCscale(G(L)->GCthreshold);
00787   lua_unlock(L);
00788   return threshold;
00789 }
00790 
00791 LUA_API int lua_getgccount (lua_State *L) {
00792   int count;
00793   lua_lock(L);
00794   count = GCscale(G(L)->nblocks);
00795   lua_unlock(L);
00796   return count;
00797 }
00798 
00799 LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
00800   lua_lock(L);
00801   if (cast(lu_mem, newthreshold) > GCscalel(MAX_LUMEM))
00802     G(L)->GCthreshold = MAX_LUMEM;
00803   else
00804     G(L)->GCthreshold = GCunscale(newthreshold);
00805   luaC_checkGC(L);
00806   lua_unlock(L);
00807 }
00808 
00809 
00810 /*
00811 ** miscellaneous functions
00812 */
00813 
00814 
00815 LUA_API const char *lua_version (void) {
00816   return LUA_VERSION;
00817 }
00818 
00819 
00820 LUA_API int lua_error (lua_State *L) {
00821   lua_lock(L);
00822   api_checknelems(L, 1);
00823   luaG_errormsg(L);
00824   lua_unlock(L);
00825   return 0;  /* to avoid warnings */
00826 }
00827 
00828 
00829 LUA_API int lua_next (lua_State *L, int idx) {
00830   StkId t;
00831   int more;
00832   lua_lock(L);
00833   t = luaA_index(L, idx);
00834   api_check(L, ttistable(t));
00835   more = luaH_next(L, hvalue(t), L->top - 1);
00836   if (more) {
00837     api_incr_top(L);
00838   }
00839   else  /* no more elements */
00840     L->top -= 1;  /* remove key */
00841   lua_unlock(L);
00842   return more;
00843 }
00844 
00845 
00846 LUA_API void lua_concat (lua_State *L, int n) {
00847   lua_lock(L);
00848   luaC_checkGC(L);
00849   api_checknelems(L, n);
00850   if (n >= 2) {
00851     luaV_concat(L, n, L->top - L->base - 1);
00852     L->top -= (n-1);
00853   }
00854   else if (n == 0) {  /* push empty string */
00855     setsvalue2s(L->top, luaS_newlstr(L, NULL, 0));
00856     api_incr_top(L);
00857   }
00858   /* else n == 1; nothing to do */
00859   lua_unlock(L);
00860 }
00861 
00862 
00863 LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
00864   Udata *u;
00865   lua_lock(L);
00866   luaC_checkGC(L);
00867   u = luaS_newudata(L, size);
00868   setuvalue(L->top, u);
00869   api_incr_top(L);
00870   lua_unlock(L);
00871 /*@-kepttrans@*/
00872   return u + 1;
00873 /*@=kepttrans@*/
00874 }
00875 
00876 
00877 LUA_API int lua_pushupvalues (lua_State *L) {
00878   Closure *func;
00879   int n, i;
00880   lua_lock(L);
00881   api_check(L, iscfunction(L->base - 1));
00882   func = clvalue(L->base - 1);
00883   n = func->c.nupvalues;
00884   luaD_checkstack(L, n + LUA_MINSTACK);
00885   for (i=0; i<n; i++) {
00886     setobj2s(L->top, &func->c.upvalue[i]);
00887     L->top++;
00888   }
00889   lua_unlock(L);
00890   return n;
00891 }
00892 
00893 
00894 /*@observer@*/ /*@null@*/
00895 static const char *aux_upvalue (lua_State *L, int funcindex, int n,
00896                                 TObject **val)
00897         /*@modifies *val @*/
00898 {
00899   Closure *f;
00900   StkId fi = luaA_index(L, funcindex);
00901   if (!ttisfunction(fi)) return NULL;
00902   f = clvalue(fi);
00903   if (f->c.isC) {
00904     if (n > f->c.nupvalues) return NULL;
00905     *val = &f->c.upvalue[n-1];
00906     return "";
00907   }
00908   else {
00909     Proto *p = f->l.p;
00910     if (n > p->sizeupvalues) return NULL;
00911 /*@-onlytrans@*/
00912     *val = f->l.upvals[n-1]->v;
00913 /*@=onlytrans@*/
00914     return getstr(p->upvalues[n-1]);
00915   }
00916 }
00917 
00918 
00919 LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
00920   const char *name;
00921   TObject *val;
00922   lua_lock(L);
00923   name = aux_upvalue(L, funcindex, n, &val);
00924   if (name) {
00925     setobj2s(L->top, val);
00926     api_incr_top(L);
00927   }
00928   lua_unlock(L);
00929   return name;
00930 }
00931 
00932 
00933 LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
00934   const char *name;
00935   TObject *val;
00936   lua_lock(L);
00937   api_checknelems(L, 1);
00938   name = aux_upvalue(L, funcindex, n, &val);
00939   if (name) {
00940     L->top--;
00941     setobj(val, L->top);  /* write barrier */
00942   }
00943   lua_unlock(L);
00944   return name;
00945 }
00946 

Generated on Fri Oct 12 08:44:54 2007 for rpm by  doxygen 1.5.2