lapi.c

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

ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:54 2011 by Doxygen 1.6.1