Mercurial > vba-clojure
view src/lua/lapi.c @ 104:d2e00ea31508
checking in continue!, which let's the GB run for an unlimited time.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Tue, 13 Mar 2012 00:03:02 -0500 |
parents | 27763b933818 |
children |
line wrap: on
line source
1 /*2 ** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $3 ** Lua API4 ** See Copyright Notice in lua.h5 */8 #include <assert.h>9 #include <math.h>10 #include <stdarg.h>11 #include <string.h>13 #define lapi_c14 #define LUA_CORE16 #include "lua.h"18 #include "lapi.h"19 #include "ldebug.h"20 #include "ldo.h"21 #include "lfunc.h"22 #include "lgc.h"23 #include "lmem.h"24 #include "lobject.h"25 #include "lstate.h"26 #include "lstring.h"27 #include "ltable.h"28 #include "ltm.h"29 #include "lundump.h"30 #include "lvm.h"34 const char lua_ident[] =35 "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n"36 "$Authors: " LUA_AUTHORS " $\n"37 "$URL: www.lua.org $\n";41 #define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))43 #define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject)45 #define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}49 static TValue *index2adr (lua_State *L, int idx) {50 if (idx > 0) {51 TValue *o = L->base + (idx - 1);52 api_check(L, idx <= L->ci->top - L->base);53 if (o >= L->top) return cast(TValue *, luaO_nilobject);54 else return o;55 }56 else if (idx > LUA_REGISTRYINDEX) {57 api_check(L, idx != 0 && -idx <= L->top - L->base);58 return L->top + idx;59 }60 else switch (idx) { /* pseudo-indices */61 case LUA_REGISTRYINDEX: return registry(L);62 case LUA_ENVIRONINDEX: {63 Closure *func = curr_func(L);64 sethvalue(L, &L->env, func->c.env);65 return &L->env;66 }67 case LUA_GLOBALSINDEX: return gt(L);68 default: {69 Closure *func = curr_func(L);70 idx = LUA_GLOBALSINDEX - idx;71 return (idx <= func->c.nupvalues)72 ? &func->c.upvalue[idx-1]73 : cast(TValue *, luaO_nilobject);74 }75 }76 }79 static Table *getcurrenv (lua_State *L) {80 if (L->ci == L->base_ci) /* no enclosing function? */81 return hvalue(gt(L)); /* use global table as environment */82 else {83 Closure *func = curr_func(L);84 return func->c.env;85 }86 }89 void luaA_pushobject (lua_State *L, const TValue *o) {90 setobj2s(L, L->top, o);91 api_incr_top(L);92 }95 LUA_API int lua_checkstack (lua_State *L, int size) {96 int res = 1;97 lua_lock(L);98 if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK)99 res = 0; /* stack overflow */100 else if (size > 0) {101 luaD_checkstack(L, size);102 if (L->ci->top < L->top + size)103 L->ci->top = L->top + size;104 }105 lua_unlock(L);106 return res;107 }110 LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {111 int i;112 if (from == to) return;113 lua_lock(to);114 api_checknelems(from, n);115 api_check(from, G(from) == G(to));116 api_check(from, to->ci->top - to->top >= n);117 from->top -= n;118 for (i = 0; i < n; i++) {119 setobj2s(to, to->top++, from->top + i);120 }121 lua_unlock(to);122 }125 LUA_API void lua_setlevel (lua_State *from, lua_State *to) {126 to->nCcalls = from->nCcalls;127 }130 LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {131 lua_CFunction old;132 lua_lock(L);133 old = G(L)->panic;134 G(L)->panic = panicf;135 lua_unlock(L);136 return old;137 }140 LUA_API lua_State *lua_newthread (lua_State *L) {141 lua_State *L1;142 lua_lock(L);143 luaC_checkGC(L);144 L1 = luaE_newthread(L);145 setthvalue(L, L->top, L1);146 api_incr_top(L);147 lua_unlock(L);148 luai_userstatethread(L, L1);149 return L1;150 }154 /*155 ** basic stack manipulation156 */159 LUA_API int lua_gettop (lua_State *L) {160 return cast_int(L->top - L->base);161 }164 LUA_API void lua_settop (lua_State *L, int idx) {165 lua_lock(L);166 if (idx >= 0) {167 api_check(L, idx <= L->stack_last - L->base);168 while (L->top < L->base + idx)169 setnilvalue(L->top++);170 L->top = L->base + idx;171 }172 else {173 api_check(L, -(idx+1) <= (L->top - L->base));174 L->top += idx+1; /* `subtract' index (index is negative) */175 }176 lua_unlock(L);177 }180 LUA_API void lua_remove (lua_State *L, int idx) {181 StkId p;182 lua_lock(L);183 p = index2adr(L, idx);184 api_checkvalidindex(L, p);185 while (++p < L->top) setobjs2s(L, p-1, p);186 L->top--;187 lua_unlock(L);188 }191 LUA_API void lua_insert (lua_State *L, int idx) {192 StkId p;193 StkId q;194 lua_lock(L);195 p = index2adr(L, idx);196 api_checkvalidindex(L, p);197 for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);198 setobjs2s(L, p, L->top);199 lua_unlock(L);200 }203 LUA_API void lua_replace (lua_State *L, int idx) {204 StkId o;205 lua_lock(L);206 /* explicit test for incompatible code */207 if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci)208 luaG_runerror(L, "no calling environment");209 api_checknelems(L, 1);210 o = index2adr(L, idx);211 api_checkvalidindex(L, o);212 if (idx == LUA_ENVIRONINDEX) {213 Closure *func = curr_func(L);214 api_check(L, ttistable(L->top - 1));215 func->c.env = hvalue(L->top - 1);216 luaC_barrier(L, func, L->top - 1);217 }218 else {219 setobj(L, o, L->top - 1);220 if (idx < LUA_GLOBALSINDEX) /* function upvalue? */221 luaC_barrier(L, curr_func(L), L->top - 1);222 }223 L->top--;224 lua_unlock(L);225 }228 LUA_API void lua_pushvalue (lua_State *L, int idx) {229 lua_lock(L);230 setobj2s(L, L->top, index2adr(L, idx));231 api_incr_top(L);232 lua_unlock(L);233 }237 /*238 ** access functions (stack -> C)239 */242 LUA_API int lua_type (lua_State *L, int idx) {243 StkId o = index2adr(L, idx);244 return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);245 }248 LUA_API const char *lua_typename (lua_State *L, int t) {249 UNUSED(L);250 return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];251 }254 LUA_API int lua_iscfunction (lua_State *L, int idx) {255 StkId o = index2adr(L, idx);256 return iscfunction(o);257 }260 LUA_API int lua_isnumber (lua_State *L, int idx) {261 TValue n;262 const TValue *o = index2adr(L, idx);263 return tonumber(o, &n);264 }267 LUA_API int lua_isstring (lua_State *L, int idx) {268 int t = lua_type(L, idx);269 return (t == LUA_TSTRING || t == LUA_TNUMBER);270 }273 LUA_API int lua_isuserdata (lua_State *L, int idx) {274 const TValue *o = index2adr(L, idx);275 return (ttisuserdata(o) || ttislightuserdata(o));276 }279 LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {280 StkId o1 = index2adr(L, index1);281 StkId o2 = index2adr(L, index2);282 return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0283 : luaO_rawequalObj(o1, o2);284 }287 LUA_API int lua_equal (lua_State *L, int index1, int index2) {288 StkId o1, o2;289 int i;290 lua_lock(L); /* may call tag method */291 o1 = index2adr(L, index1);292 o2 = index2adr(L, index2);293 i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2);294 lua_unlock(L);295 return i;296 }299 LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {300 StkId o1, o2;301 int i;302 lua_lock(L); /* may call tag method */303 o1 = index2adr(L, index1);304 o2 = index2adr(L, index2);305 i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0306 : luaV_lessthan(L, o1, o2);307 lua_unlock(L);308 return i;309 }313 LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {314 TValue n;315 const TValue *o = index2adr(L, idx);316 if (tonumber(o, &n))317 return nvalue(o);318 else319 return 0;320 }323 LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {324 TValue n;325 const TValue *o = index2adr(L, idx);326 if (tonumber(o, &n)) {327 lua_Integer res;328 lua_Number num = nvalue(o);329 lua_number2integer(res, num);330 return res;331 }332 else333 return 0;334 }337 LUA_API int lua_toboolean (lua_State *L, int idx) {338 const TValue *o = index2adr(L, idx);339 return !l_isfalse(o);340 }343 LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {344 StkId o = index2adr(L, idx);345 if (!ttisstring(o)) {346 lua_lock(L); /* `luaV_tostring' may create a new string */347 if (!luaV_tostring(L, o)) { /* conversion failed? */348 if (len != NULL) *len = 0;349 lua_unlock(L);350 return NULL;351 }352 luaC_checkGC(L);353 o = index2adr(L, idx); /* previous call may reallocate the stack */354 lua_unlock(L);355 }356 if (len != NULL) *len = tsvalue(o)->len;357 return svalue(o);358 }361 LUA_API size_t lua_objlen (lua_State *L, int idx) {362 StkId o = index2adr(L, idx);363 switch (ttype(o)) {364 case LUA_TSTRING: return tsvalue(o)->len;365 case LUA_TUSERDATA: return uvalue(o)->len;366 case LUA_TTABLE: return luaH_getn(hvalue(o));367 case LUA_TNUMBER: {368 size_t l;369 lua_lock(L); /* `luaV_tostring' may create a new string */370 l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);371 lua_unlock(L);372 return l;373 }374 default: return 0;375 }376 }379 LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {380 StkId o = index2adr(L, idx);381 return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;382 }385 LUA_API void *lua_touserdata (lua_State *L, int idx) {386 StkId o = index2adr(L, idx);387 switch (ttype(o)) {388 case LUA_TUSERDATA: return (rawuvalue(o) + 1);389 case LUA_TLIGHTUSERDATA: return pvalue(o);390 default: return NULL;391 }392 }395 LUA_API lua_State *lua_tothread (lua_State *L, int idx) {396 StkId o = index2adr(L, idx);397 return (!ttisthread(o)) ? NULL : thvalue(o);398 }401 LUA_API const void *lua_topointer (lua_State *L, int idx) {402 StkId o = index2adr(L, idx);403 switch (ttype(o)) {404 case LUA_TTABLE: return hvalue(o);405 case LUA_TFUNCTION: return clvalue(o);406 case LUA_TTHREAD: return thvalue(o);407 case LUA_TUSERDATA:408 case LUA_TLIGHTUSERDATA:409 return lua_touserdata(L, idx);410 default: return NULL;411 }412 }416 /*417 ** push functions (C -> stack)418 */421 LUA_API void lua_pushnil (lua_State *L) {422 lua_lock(L);423 setnilvalue(L->top);424 api_incr_top(L);425 lua_unlock(L);426 }429 LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {430 lua_lock(L);431 setnvalue(L->top, n);432 api_incr_top(L);433 lua_unlock(L);434 }437 LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {438 lua_lock(L);439 setnvalue(L->top, cast_num(n));440 api_incr_top(L);441 lua_unlock(L);442 }445 LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {446 lua_lock(L);447 luaC_checkGC(L);448 setsvalue2s(L, L->top, luaS_newlstr(L, s, len));449 api_incr_top(L);450 lua_unlock(L);451 }454 LUA_API void lua_pushstring (lua_State *L, const char *s) {455 if (s == NULL)456 lua_pushnil(L);457 else458 lua_pushlstring(L, s, strlen(s));459 }462 LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,463 va_list argp) {464 const char *ret;465 lua_lock(L);466 luaC_checkGC(L);467 ret = luaO_pushvfstring(L, fmt, argp);468 lua_unlock(L);469 return ret;470 }473 LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {474 const char *ret;475 va_list argp;476 lua_lock(L);477 luaC_checkGC(L);478 va_start(argp, fmt);479 ret = luaO_pushvfstring(L, fmt, argp);480 va_end(argp);481 lua_unlock(L);482 return ret;483 }486 LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {487 Closure *cl;488 lua_lock(L);489 luaC_checkGC(L);490 api_checknelems(L, n);491 cl = luaF_newCclosure(L, n, getcurrenv(L));492 cl->c.f = fn;493 L->top -= n;494 while (n--)495 setobj2n(L, &cl->c.upvalue[n], L->top+n);496 setclvalue(L, L->top, cl);497 lua_assert(iswhite(obj2gco(cl)));498 api_incr_top(L);499 lua_unlock(L);500 }503 LUA_API void lua_pushboolean (lua_State *L, int b) {504 lua_lock(L);505 setbvalue(L->top, (b != 0)); /* ensure that true is 1 */506 api_incr_top(L);507 lua_unlock(L);508 }511 LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {512 lua_lock(L);513 setpvalue(L->top, p);514 api_incr_top(L);515 lua_unlock(L);516 }519 LUA_API int lua_pushthread (lua_State *L) {520 lua_lock(L);521 setthvalue(L, L->top, L);522 api_incr_top(L);523 lua_unlock(L);524 return (G(L)->mainthread == L);525 }529 /*530 ** get functions (Lua -> stack)531 */534 LUA_API void lua_gettable (lua_State *L, int idx) {535 StkId t;536 lua_lock(L);537 t = index2adr(L, idx);538 api_checkvalidindex(L, t);539 luaV_gettable(L, t, L->top - 1, L->top - 1);540 lua_unlock(L);541 }544 LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {545 StkId t;546 TValue key;547 lua_lock(L);548 t = index2adr(L, idx);549 api_checkvalidindex(L, t);550 setsvalue(L, &key, luaS_new(L, k));551 luaV_gettable(L, t, &key, L->top);552 api_incr_top(L);553 lua_unlock(L);554 }557 LUA_API void lua_rawget (lua_State *L, int idx) {558 StkId t;559 lua_lock(L);560 t = index2adr(L, idx);561 api_check(L, ttistable(t));562 setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));563 lua_unlock(L);564 }567 LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {568 StkId o;569 lua_lock(L);570 o = index2adr(L, idx);571 api_check(L, ttistable(o));572 setobj2s(L, L->top, luaH_getnum(hvalue(o), n));573 api_incr_top(L);574 lua_unlock(L);575 }578 LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {579 lua_lock(L);580 luaC_checkGC(L);581 sethvalue(L, L->top, luaH_new(L, narray, nrec));582 api_incr_top(L);583 lua_unlock(L);584 }587 LUA_API int lua_getmetatable (lua_State *L, int objindex) {588 const TValue *obj;589 Table *mt = NULL;590 int res;591 lua_lock(L);592 obj = index2adr(L, objindex);593 switch (ttype(obj)) {594 case LUA_TTABLE:595 mt = hvalue(obj)->metatable;596 break;597 case LUA_TUSERDATA:598 mt = uvalue(obj)->metatable;599 break;600 default:601 mt = G(L)->mt[ttype(obj)];602 break;603 }604 if (mt == NULL)605 res = 0;606 else {607 sethvalue(L, L->top, mt);608 api_incr_top(L);609 res = 1;610 }611 lua_unlock(L);612 return res;613 }616 LUA_API void lua_getfenv (lua_State *L, int idx) {617 StkId o;618 lua_lock(L);619 o = index2adr(L, idx);620 api_checkvalidindex(L, o);621 switch (ttype(o)) {622 case LUA_TFUNCTION:623 sethvalue(L, L->top, clvalue(o)->c.env);624 break;625 case LUA_TUSERDATA:626 sethvalue(L, L->top, uvalue(o)->env);627 break;628 case LUA_TTHREAD:629 setobj2s(L, L->top, gt(thvalue(o)));630 break;631 default:632 setnilvalue(L->top);633 break;634 }635 api_incr_top(L);636 lua_unlock(L);637 }640 /*641 ** set functions (stack -> Lua)642 */645 LUA_API void lua_settable (lua_State *L, int idx) {646 StkId t;647 lua_lock(L);648 api_checknelems(L, 2);649 t = index2adr(L, idx);650 api_checkvalidindex(L, t);651 luaV_settable(L, t, L->top - 2, L->top - 1);652 L->top -= 2; /* pop index and value */653 lua_unlock(L);654 }657 LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {658 StkId t;659 TValue key;660 lua_lock(L);661 api_checknelems(L, 1);662 t = index2adr(L, idx);663 api_checkvalidindex(L, t);664 setsvalue(L, &key, luaS_new(L, k));665 luaV_settable(L, t, &key, L->top - 1);666 L->top--; /* pop value */667 lua_unlock(L);668 }671 LUA_API void lua_rawset (lua_State *L, int idx) {672 StkId t;673 lua_lock(L);674 api_checknelems(L, 2);675 t = index2adr(L, idx);676 api_check(L, ttistable(t));677 setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);678 luaC_barriert(L, hvalue(t), L->top-1);679 L->top -= 2;680 lua_unlock(L);681 }684 LUA_API void lua_rawseti (lua_State *L, int idx, int n) {685 StkId o;686 lua_lock(L);687 api_checknelems(L, 1);688 o = index2adr(L, idx);689 api_check(L, ttistable(o));690 setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);691 luaC_barriert(L, hvalue(o), L->top-1);692 L->top--;693 lua_unlock(L);694 }697 LUA_API int lua_setmetatable (lua_State *L, int objindex) {698 TValue *obj;699 Table *mt;700 lua_lock(L);701 api_checknelems(L, 1);702 obj = index2adr(L, objindex);703 api_checkvalidindex(L, obj);704 if (ttisnil(L->top - 1))705 mt = NULL;706 else {707 api_check(L, ttistable(L->top - 1));708 mt = hvalue(L->top - 1);709 }710 switch (ttype(obj)) {711 case LUA_TTABLE: {712 hvalue(obj)->metatable = mt;713 if (mt)714 luaC_objbarriert(L, hvalue(obj), mt);715 break;716 }717 case LUA_TUSERDATA: {718 uvalue(obj)->metatable = mt;719 if (mt)720 luaC_objbarrier(L, rawuvalue(obj), mt);721 break;722 }723 default: {724 G(L)->mt[ttype(obj)] = mt;725 break;726 }727 }728 L->top--;729 lua_unlock(L);730 return 1;731 }734 LUA_API int lua_setfenv (lua_State *L, int idx) {735 StkId o;736 int res = 1;737 lua_lock(L);738 api_checknelems(L, 1);739 o = index2adr(L, idx);740 api_checkvalidindex(L, o);741 api_check(L, ttistable(L->top - 1));742 switch (ttype(o)) {743 case LUA_TFUNCTION:744 clvalue(o)->c.env = hvalue(L->top - 1);745 break;746 case LUA_TUSERDATA:747 uvalue(o)->env = hvalue(L->top - 1);748 break;749 case LUA_TTHREAD:750 sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1));751 break;752 default:753 res = 0;754 break;755 }756 if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));757 L->top--;758 lua_unlock(L);759 return res;760 }763 /*764 ** `load' and `call' functions (run Lua code)765 */768 #define adjustresults(L,nres) \769 { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; }772 #define checkresults(L,na,nr) \773 api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))776 LUA_API void lua_call (lua_State *L, int nargs, int nresults) {777 StkId func;778 lua_lock(L);779 api_checknelems(L, nargs+1);780 checkresults(L, nargs, nresults);781 func = L->top - (nargs+1);782 luaD_call(L, func, nresults);783 adjustresults(L, nresults);784 lua_unlock(L);785 }789 /*790 ** Execute a protected call.791 */792 struct CallS { /* data to `f_call' */793 StkId func;794 int nresults;795 };798 static void f_call (lua_State *L, void *ud) {799 struct CallS *c = cast(struct CallS *, ud);800 luaD_call(L, c->func, c->nresults);801 }805 LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {806 struct CallS c;807 int status;808 ptrdiff_t func;809 lua_lock(L);810 api_checknelems(L, nargs+1);811 checkresults(L, nargs, nresults);812 if (errfunc == 0)813 func = 0;814 else {815 StkId o = index2adr(L, errfunc);816 api_checkvalidindex(L, o);817 func = savestack(L, o);818 }819 c.func = L->top - (nargs+1); /* function to be called */820 c.nresults = nresults;821 status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);822 adjustresults(L, nresults);823 lua_unlock(L);824 return status;825 }828 /*829 ** Execute a protected C call.830 */831 struct CCallS { /* data to `f_Ccall' */832 lua_CFunction func;833 void *ud;834 };837 static void f_Ccall (lua_State *L, void *ud) {838 struct CCallS *c = cast(struct CCallS *, ud);839 Closure *cl;840 cl = luaF_newCclosure(L, 0, getcurrenv(L));841 cl->c.f = c->func;842 setclvalue(L, L->top, cl); /* push function */843 api_incr_top(L);844 setpvalue(L->top, c->ud); /* push only argument */845 api_incr_top(L);846 luaD_call(L, L->top - 2, 0);847 }850 LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {851 struct CCallS c;852 int status;853 lua_lock(L);854 c.func = func;855 c.ud = ud;856 status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);857 lua_unlock(L);858 return status;859 }862 LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,863 const char *chunkname) {864 ZIO z;865 int status;866 lua_lock(L);867 if (!chunkname) chunkname = "?";868 luaZ_init(L, &z, reader, data);869 status = luaD_protectedparser(L, &z, chunkname);870 lua_unlock(L);871 return status;872 }875 LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {876 int status;877 TValue *o;878 lua_lock(L);879 api_checknelems(L, 1);880 o = L->top - 1;881 if (isLfunction(o))882 status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);883 else884 status = 1;885 lua_unlock(L);886 return status;887 }890 LUA_API int lua_status (lua_State *L) {891 return L->status;892 }895 /*896 ** Garbage-collection function897 */899 LUA_API int lua_gc (lua_State *L, int what, int data) {900 int res = 0;901 global_State *g;902 lua_lock(L);903 g = G(L);904 switch (what) {905 case LUA_GCSTOP: {906 g->GCthreshold = MAX_LUMEM;907 break;908 }909 case LUA_GCRESTART: {910 g->GCthreshold = g->totalbytes;911 break;912 }913 case LUA_GCCOLLECT: {914 luaC_fullgc(L);915 break;916 }917 case LUA_GCCOUNT: {918 /* GC values are expressed in Kbytes: #bytes/2^10 */919 res = cast_int(g->totalbytes >> 10);920 break;921 }922 case LUA_GCCOUNTB: {923 res = cast_int(g->totalbytes & 0x3ff);924 break;925 }926 case LUA_GCSTEP: {927 lu_mem a = (cast(lu_mem, data) << 10);928 if (a <= g->totalbytes)929 g->GCthreshold = g->totalbytes - a;930 else931 g->GCthreshold = 0;932 while (g->GCthreshold <= g->totalbytes) {933 luaC_step(L);934 if (g->gcstate == GCSpause) { /* end of cycle? */935 res = 1; /* signal it */936 break;937 }938 }939 break;940 }941 case LUA_GCSETPAUSE: {942 res = g->gcpause;943 g->gcpause = data;944 break;945 }946 case LUA_GCSETSTEPMUL: {947 res = g->gcstepmul;948 g->gcstepmul = data;949 break;950 }951 default: res = -1; /* invalid option */952 }953 lua_unlock(L);954 return res;955 }959 /*960 ** miscellaneous functions961 */964 LUA_API int lua_error (lua_State *L) {965 lua_lock(L);966 api_checknelems(L, 1);967 luaG_errormsg(L);968 lua_unlock(L);969 return 0; /* to avoid warnings */970 }973 LUA_API int lua_next (lua_State *L, int idx) {974 StkId t;975 int more;976 lua_lock(L);977 t = index2adr(L, idx);978 api_check(L, ttistable(t));979 more = luaH_next(L, hvalue(t), L->top - 1);980 if (more) {981 api_incr_top(L);982 }983 else /* no more elements */984 L->top -= 1; /* remove key */985 lua_unlock(L);986 return more;987 }990 LUA_API void lua_concat (lua_State *L, int n) {991 lua_lock(L);992 api_checknelems(L, n);993 if (n >= 2) {994 luaC_checkGC(L);995 luaV_concat(L, n, cast_int(L->top - L->base) - 1);996 L->top -= (n-1);997 }998 else if (n == 0) { /* push empty string */999 setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));1000 api_incr_top(L);1001 }1002 /* else n == 1; nothing to do */1003 lua_unlock(L);1004 }1007 LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {1008 lua_Alloc f;1009 lua_lock(L);1010 if (ud) *ud = G(L)->ud;1011 f = G(L)->frealloc;1012 lua_unlock(L);1013 return f;1014 }1017 LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {1018 lua_lock(L);1019 G(L)->ud = ud;1020 G(L)->frealloc = f;1021 lua_unlock(L);1022 }1025 LUA_API void *lua_newuserdata (lua_State *L, size_t size) {1026 Udata *u;1027 lua_lock(L);1028 luaC_checkGC(L);1029 u = luaS_newudata(L, size, getcurrenv(L));1030 setuvalue(L, L->top, u);1031 api_incr_top(L);1032 lua_unlock(L);1033 return u + 1;1034 }1039 static const char *aux_upvalue (StkId fi, int n, TValue **val) {1040 Closure *f;1041 if (!ttisfunction(fi)) return NULL;1042 f = clvalue(fi);1043 if (f->c.isC) {1044 if (!(1 <= n && n <= f->c.nupvalues)) return NULL;1045 *val = &f->c.upvalue[n-1];1046 return "";1047 }1048 else {1049 Proto *p = f->l.p;1050 if (!(1 <= n && n <= p->sizeupvalues)) return NULL;1051 *val = f->l.upvals[n-1]->v;1052 return getstr(p->upvalues[n-1]);1053 }1054 }1057 LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {1058 const char *name;1059 TValue *val;1060 lua_lock(L);1061 name = aux_upvalue(index2adr(L, funcindex), n, &val);1062 if (name) {1063 setobj2s(L, L->top, val);1064 api_incr_top(L);1065 }1066 lua_unlock(L);1067 return name;1068 }1071 LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {1072 const char *name;1073 TValue *val;1074 StkId fi;1075 lua_lock(L);1076 fi = index2adr(L, funcindex);1077 api_checknelems(L, 1);1078 name = aux_upvalue(fi, n, &val);1079 if (name) {1080 L->top--;1081 setobj(L, val, L->top);1082 luaC_barrier(L, clvalue(fi), L->top);1083 }1084 lua_unlock(L);1085 return name;1086 }