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