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