00001
00002
00003
00004
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) {
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)
00081 return hvalue(gt(L));
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;
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
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;
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
00207 if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci)
00208 luaG_runerror(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)
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
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);
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);
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);
00347 if (!luaV_tostring(L, o)) {
00348 if (len != NULL) *len = 0;
00349 lua_unlock(L);
00350 return NULL;
00351 }
00352 luaC_checkGC(L);
00353 o = index2adr(L, idx);
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);
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
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));
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
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
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;
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--;
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
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
00791
00792 struct CallS {
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);
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
00830
00831 struct CCallS {
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);
00843 api_incr_top(L);
00844 setpvalue(L->top, c->ud);
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
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
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) {
00935 res = 1;
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;
00952 }
00953 lua_unlock(L);
00954 return res;
00955 }
00956
00957
00958
00959
00960
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;
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
00984 L->top -= 1;
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) {
00999 setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
01000 api_incr_top(L);
01001 }
01002
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 }