Imported from ../lua-5.0.3.tar.gz.
[lua.git] / src / lapi.c
blob2ed4c6348213ad540271b98c3978c68d2af237b1
1 /*
2 ** $Id: lapi.c,v 1.235a 2003/04/07 14:36:08 roberto Exp $
3 ** Lua API
4 ** See Copyright Notice in lua.h
5 */
8 #include <assert.h>
9 #include <string.h>
11 #define lapi_c
13 #include "lua.h"
15 #include "lapi.h"
16 #include "ldebug.h"
17 #include "ldo.h"
18 #include "lfunc.h"
19 #include "lgc.h"
20 #include "lmem.h"
21 #include "lobject.h"
22 #include "lstate.h"
23 #include "lstring.h"
24 #include "ltable.h"
25 #include "ltm.h"
26 #include "lundump.h"
27 #include "lvm.h"
30 const char lua_ident[] =
31 "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
32 "$Authors: " LUA_AUTHORS " $\n"
33 "$URL: www.lua.org $\n";
37 #ifndef api_check
38 #define api_check(L, o) /*{ assert(o); }*/
39 #endif
41 #define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
43 #define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
48 static TObject *negindex (lua_State *L, int idx) {
49 if (idx > LUA_REGISTRYINDEX) {
50 api_check(L, idx != 0 && -idx <= L->top - L->base);
51 return L->top+idx;
53 else switch (idx) { /* pseudo-indices */
54 case LUA_REGISTRYINDEX: return registry(L);
55 case LUA_GLOBALSINDEX: return gt(L);
56 default: {
57 TObject *func = (L->base - 1);
58 idx = LUA_GLOBALSINDEX - idx;
59 lua_assert(iscfunction(func));
60 return (idx <= clvalue(func)->c.nupvalues)
61 ? &clvalue(func)->c.upvalue[idx-1]
62 : NULL;
68 static TObject *luaA_index (lua_State *L, int idx) {
69 if (idx > 0) {
70 api_check(L, idx <= L->top - L->base);
71 return L->base + idx - 1;
73 else {
74 TObject *o = negindex(L, idx);
75 api_check(L, o != NULL);
76 return o;
81 static TObject *luaA_indexAcceptable (lua_State *L, int idx) {
82 if (idx > 0) {
83 TObject *o = L->base+(idx-1);
84 api_check(L, idx <= L->stack_last - L->base);
85 if (o >= L->top) return NULL;
86 else return o;
88 else
89 return negindex(L, idx);
93 void luaA_pushobject (lua_State *L, const TObject *o) {
94 setobj2s(L->top, o);
95 incr_top(L);
99 LUA_API int lua_checkstack (lua_State *L, int size) {
100 int res;
101 lua_lock(L);
102 if ((L->top - L->base + size) > LUA_MAXCSTACK)
103 res = 0; /* stack overflow */
104 else {
105 luaD_checkstack(L, size);
106 if (L->ci->top < L->top + size)
107 L->ci->top = L->top + size;
108 res = 1;
110 lua_unlock(L);
111 return res;
115 LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
116 int i;
117 lua_lock(to);
118 api_checknelems(from, n);
119 from->top -= n;
120 for (i = 0; i < n; i++) {
121 setobj2s(to->top, from->top + i);
122 api_incr_top(to);
124 lua_unlock(to);
128 LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
129 lua_CFunction old;
130 lua_lock(L);
131 old = G(L)->panic;
132 G(L)->panic = panicf;
133 lua_unlock(L);
134 return old;
138 LUA_API lua_State *lua_newthread (lua_State *L) {
139 lua_State *L1;
140 lua_lock(L);
141 luaC_checkGC(L);
142 L1 = luaE_newthread(L);
143 setthvalue(L->top, L1);
144 api_incr_top(L);
145 lua_unlock(L);
146 lua_userstateopen(L1);
147 return L1;
153 ** basic stack manipulation
157 LUA_API int lua_gettop (lua_State *L) {
158 return (L->top - L->base);
162 LUA_API void lua_settop (lua_State *L, int idx) {
163 lua_lock(L);
164 if (idx >= 0) {
165 api_check(L, idx <= L->stack_last - L->base);
166 while (L->top < L->base + idx)
167 setnilvalue(L->top++);
168 L->top = L->base + idx;
170 else {
171 api_check(L, -(idx+1) <= (L->top - L->base));
172 L->top += idx+1; /* `subtract' index (index is negative) */
174 lua_unlock(L);
178 LUA_API void lua_remove (lua_State *L, int idx) {
179 StkId p;
180 lua_lock(L);
181 p = luaA_index(L, idx);
182 while (++p < L->top) setobjs2s(p-1, p);
183 L->top--;
184 lua_unlock(L);
188 LUA_API void lua_insert (lua_State *L, int idx) {
189 StkId p;
190 StkId q;
191 lua_lock(L);
192 p = luaA_index(L, idx);
193 for (q = L->top; q>p; q--) setobjs2s(q, q-1);
194 setobjs2s(p, L->top);
195 lua_unlock(L);
199 LUA_API void lua_replace (lua_State *L, int idx) {
200 lua_lock(L);
201 api_checknelems(L, 1);
202 setobj(luaA_index(L, idx), L->top - 1); /* write barrier */
203 L->top--;
204 lua_unlock(L);
208 LUA_API void lua_pushvalue (lua_State *L, int idx) {
209 lua_lock(L);
210 setobj2s(L->top, luaA_index(L, idx));
211 api_incr_top(L);
212 lua_unlock(L);
218 ** access functions (stack -> C)
222 LUA_API int lua_type (lua_State *L, int idx) {
223 StkId o = luaA_indexAcceptable(L, idx);
224 return (o == NULL) ? LUA_TNONE : ttype(o);
228 LUA_API const char *lua_typename (lua_State *L, int t) {
229 UNUSED(L);
230 return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
234 LUA_API int lua_iscfunction (lua_State *L, int idx) {
235 StkId o = luaA_indexAcceptable(L, idx);
236 return (o == NULL) ? 0 : iscfunction(o);
240 LUA_API int lua_isnumber (lua_State *L, int idx) {
241 TObject n;
242 const TObject *o = luaA_indexAcceptable(L, idx);
243 return (o != NULL && tonumber(o, &n));
247 LUA_API int lua_isstring (lua_State *L, int idx) {
248 int t = lua_type(L, idx);
249 return (t == LUA_TSTRING || t == LUA_TNUMBER);
253 LUA_API int lua_isuserdata (lua_State *L, int idx) {
254 const TObject *o = luaA_indexAcceptable(L, idx);
255 return (o != NULL && (ttisuserdata(o) || ttislightuserdata(o)));
259 LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
260 StkId o1 = luaA_indexAcceptable(L, index1);
261 StkId o2 = luaA_indexAcceptable(L, index2);
262 return (o1 == NULL || o2 == NULL) ? 0 /* index out of range */
263 : luaO_rawequalObj(o1, o2);
267 LUA_API int lua_equal (lua_State *L, int index1, int index2) {
268 StkId o1, o2;
269 int i;
270 lua_lock(L); /* may call tag method */
271 o1 = luaA_indexAcceptable(L, index1);
272 o2 = luaA_indexAcceptable(L, index2);
273 i = (o1 == NULL || o2 == NULL) ? 0 /* index out of range */
274 : equalobj(L, o1, o2);
275 lua_unlock(L);
276 return i;
280 LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
281 StkId o1, o2;
282 int i;
283 lua_lock(L); /* may call tag method */
284 o1 = luaA_indexAcceptable(L, index1);
285 o2 = luaA_indexAcceptable(L, index2);
286 i = (o1 == NULL || o2 == NULL) ? 0 /* index out-of-range */
287 : luaV_lessthan(L, o1, o2);
288 lua_unlock(L);
289 return i;
294 LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
295 TObject n;
296 const TObject *o = luaA_indexAcceptable(L, idx);
297 if (o != NULL && tonumber(o, &n))
298 return nvalue(o);
299 else
300 return 0;
304 LUA_API int lua_toboolean (lua_State *L, int idx) {
305 const TObject *o = luaA_indexAcceptable(L, idx);
306 return (o != NULL) && !l_isfalse(o);
310 LUA_API const char *lua_tostring (lua_State *L, int idx) {
311 StkId o = luaA_indexAcceptable(L, idx);
312 if (o == NULL)
313 return NULL;
314 else if (ttisstring(o))
315 return svalue(o);
316 else {
317 const char *s;
318 lua_lock(L); /* `luaV_tostring' may create a new string */
319 s = (luaV_tostring(L, o) ? svalue(o) : NULL);
320 luaC_checkGC(L);
321 lua_unlock(L);
322 return s;
327 LUA_API size_t lua_strlen (lua_State *L, int idx) {
328 StkId o = luaA_indexAcceptable(L, idx);
329 if (o == NULL)
330 return 0;
331 else if (ttisstring(o))
332 return tsvalue(o)->tsv.len;
333 else {
334 size_t l;
335 lua_lock(L); /* `luaV_tostring' may create a new string */
336 l = (luaV_tostring(L, o) ? tsvalue(o)->tsv.len : 0);
337 lua_unlock(L);
338 return l;
343 LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
344 StkId o = luaA_indexAcceptable(L, idx);
345 return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->c.f;
349 LUA_API void *lua_touserdata (lua_State *L, int idx) {
350 StkId o = luaA_indexAcceptable(L, idx);
351 if (o == NULL) return NULL;
352 switch (ttype(o)) {
353 case LUA_TUSERDATA: return (uvalue(o) + 1);
354 case LUA_TLIGHTUSERDATA: return pvalue(o);
355 default: return NULL;
360 LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
361 StkId o = luaA_indexAcceptable(L, idx);
362 return (o == NULL || !ttisthread(o)) ? NULL : thvalue(o);
366 LUA_API const void *lua_topointer (lua_State *L, int idx) {
367 StkId o = luaA_indexAcceptable(L, idx);
368 if (o == NULL) return NULL;
369 else {
370 switch (ttype(o)) {
371 case LUA_TTABLE: return hvalue(o);
372 case LUA_TFUNCTION: return clvalue(o);
373 case LUA_TTHREAD: return thvalue(o);
374 case LUA_TUSERDATA:
375 case LUA_TLIGHTUSERDATA:
376 return lua_touserdata(L, idx);
377 default: return NULL;
385 ** push functions (C -> stack)
389 LUA_API void lua_pushnil (lua_State *L) {
390 lua_lock(L);
391 setnilvalue(L->top);
392 api_incr_top(L);
393 lua_unlock(L);
397 LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
398 lua_lock(L);
399 setnvalue(L->top, n);
400 api_incr_top(L);
401 lua_unlock(L);
405 LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
406 lua_lock(L);
407 luaC_checkGC(L);
408 setsvalue2s(L->top, luaS_newlstr(L, s, len));
409 api_incr_top(L);
410 lua_unlock(L);
414 LUA_API void lua_pushstring (lua_State *L, const char *s) {
415 if (s == NULL)
416 lua_pushnil(L);
417 else
418 lua_pushlstring(L, s, strlen(s));
422 LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
423 va_list argp) {
424 const char *ret;
425 lua_lock(L);
426 luaC_checkGC(L);
427 ret = luaO_pushvfstring(L, fmt, argp);
428 lua_unlock(L);
429 return ret;
433 LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
434 const char *ret;
435 va_list argp;
436 lua_lock(L);
437 luaC_checkGC(L);
438 va_start(argp, fmt);
439 ret = luaO_pushvfstring(L, fmt, argp);
440 va_end(argp);
441 lua_unlock(L);
442 return ret;
446 LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
447 Closure *cl;
448 lua_lock(L);
449 luaC_checkGC(L);
450 api_checknelems(L, n);
451 cl = luaF_newCclosure(L, n);
452 cl->c.f = fn;
453 L->top -= n;
454 while (n--)
455 setobj2n(&cl->c.upvalue[n], L->top+n);
456 setclvalue(L->top, cl);
457 api_incr_top(L);
458 lua_unlock(L);
462 LUA_API void lua_pushboolean (lua_State *L, int b) {
463 lua_lock(L);
464 setbvalue(L->top, (b != 0)); /* ensure that true is 1 */
465 api_incr_top(L);
466 lua_unlock(L);
470 LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
471 lua_lock(L);
472 setpvalue(L->top, p);
473 api_incr_top(L);
474 lua_unlock(L);
480 ** get functions (Lua -> stack)
484 LUA_API void lua_gettable (lua_State *L, int idx) {
485 StkId t;
486 lua_lock(L);
487 t = luaA_index(L, idx);
488 setobj2s(L->top - 1, luaV_gettable(L, t, L->top - 1, 0));
489 lua_unlock(L);
493 LUA_API void lua_rawget (lua_State *L, int idx) {
494 StkId t;
495 lua_lock(L);
496 t = luaA_index(L, idx);
497 api_check(L, ttistable(t));
498 setobj2s(L->top - 1, luaH_get(hvalue(t), L->top - 1));
499 lua_unlock(L);
503 LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
504 StkId o;
505 lua_lock(L);
506 o = luaA_index(L, idx);
507 api_check(L, ttistable(o));
508 setobj2s(L->top, luaH_getnum(hvalue(o), n));
509 api_incr_top(L);
510 lua_unlock(L);
514 LUA_API void lua_newtable (lua_State *L) {
515 lua_lock(L);
516 luaC_checkGC(L);
517 sethvalue(L->top, luaH_new(L, 0, 0));
518 api_incr_top(L);
519 lua_unlock(L);
523 LUA_API int lua_getmetatable (lua_State *L, int objindex) {
524 const TObject *obj;
525 Table *mt = NULL;
526 int res;
527 lua_lock(L);
528 obj = luaA_indexAcceptable(L, objindex);
529 if (obj != NULL) {
530 switch (ttype(obj)) {
531 case LUA_TTABLE:
532 mt = hvalue(obj)->metatable;
533 break;
534 case LUA_TUSERDATA:
535 mt = uvalue(obj)->uv.metatable;
536 break;
539 if (mt == NULL || mt == hvalue(defaultmeta(L)))
540 res = 0;
541 else {
542 sethvalue(L->top, mt);
543 api_incr_top(L);
544 res = 1;
546 lua_unlock(L);
547 return res;
551 LUA_API void lua_getfenv (lua_State *L, int idx) {
552 StkId o;
553 lua_lock(L);
554 o = luaA_index(L, idx);
555 setobj2s(L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L));
556 api_incr_top(L);
557 lua_unlock(L);
562 ** set functions (stack -> Lua)
566 LUA_API void lua_settable (lua_State *L, int idx) {
567 StkId t;
568 lua_lock(L);
569 api_checknelems(L, 2);
570 t = luaA_index(L, idx);
571 luaV_settable(L, t, L->top - 2, L->top - 1);
572 L->top -= 2; /* pop index and value */
573 lua_unlock(L);
577 LUA_API void lua_rawset (lua_State *L, int idx) {
578 StkId t;
579 lua_lock(L);
580 api_checknelems(L, 2);
581 t = luaA_index(L, idx);
582 api_check(L, ttistable(t));
583 setobj2t(luaH_set(L, hvalue(t), L->top-2), L->top-1); /* write barrier */
584 L->top -= 2;
585 lua_unlock(L);
589 LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
590 StkId o;
591 lua_lock(L);
592 api_checknelems(L, 1);
593 o = luaA_index(L, idx);
594 api_check(L, ttistable(o));
595 setobj2t(luaH_setnum(L, hvalue(o), n), L->top-1); /* write barrier */
596 L->top--;
597 lua_unlock(L);
601 LUA_API int lua_setmetatable (lua_State *L, int objindex) {
602 TObject *obj, *mt;
603 int res = 1;
604 lua_lock(L);
605 api_checknelems(L, 1);
606 obj = luaA_index(L, objindex);
607 mt = (!ttisnil(L->top - 1)) ? L->top - 1 : defaultmeta(L);
608 api_check(L, ttistable(mt));
609 switch (ttype(obj)) {
610 case LUA_TTABLE: {
611 hvalue(obj)->metatable = hvalue(mt); /* write barrier */
612 break;
614 case LUA_TUSERDATA: {
615 uvalue(obj)->uv.metatable = hvalue(mt); /* write barrier */
616 break;
618 default: {
619 res = 0; /* cannot set */
620 break;
623 L->top--;
624 lua_unlock(L);
625 return res;
629 LUA_API int lua_setfenv (lua_State *L, int idx) {
630 StkId o;
631 int res = 0;
632 lua_lock(L);
633 api_checknelems(L, 1);
634 o = luaA_index(L, idx);
635 L->top--;
636 api_check(L, ttistable(L->top));
637 if (isLfunction(o)) {
638 res = 1;
639 clvalue(o)->l.g = *(L->top);
641 lua_unlock(L);
642 return res;
647 ** `load' and `call' functions (run Lua code)
650 LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
651 StkId func;
652 lua_lock(L);
653 api_checknelems(L, nargs+1);
654 func = L->top - (nargs+1);
655 luaD_call(L, func, nresults);
656 lua_unlock(L);
662 ** Execute a protected call.
664 struct CallS { /* data to `f_call' */
665 StkId func;
666 int nresults;
670 static void f_call (lua_State *L, void *ud) {
671 struct CallS *c = cast(struct CallS *, ud);
672 luaD_call(L, c->func, c->nresults);
677 LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
678 struct CallS c;
679 int status;
680 ptrdiff_t func;
681 lua_lock(L);
682 func = (errfunc == 0) ? 0 : savestack(L, luaA_index(L, errfunc));
683 c.func = L->top - (nargs+1); /* function to be called */
684 c.nresults = nresults;
685 status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
686 lua_unlock(L);
687 return status;
692 ** Execute a protected C call.
694 struct CCallS { /* data to `f_Ccall' */
695 lua_CFunction func;
696 void *ud;
700 static void f_Ccall (lua_State *L, void *ud) {
701 struct CCallS *c = cast(struct CCallS *, ud);
702 Closure *cl;
703 cl = luaF_newCclosure(L, 0);
704 cl->c.f = c->func;
705 setclvalue(L->top, cl); /* push function */
706 incr_top(L);
707 setpvalue(L->top, c->ud); /* push only argument */
708 incr_top(L);
709 luaD_call(L, L->top - 2, 0);
713 LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
714 struct CCallS c;
715 int status;
716 lua_lock(L);
717 c.func = func;
718 c.ud = ud;
719 status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
720 lua_unlock(L);
721 return status;
725 LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data,
726 const char *chunkname) {
727 ZIO z;
728 int status;
729 int c;
730 lua_lock(L);
731 if (!chunkname) chunkname = "?";
732 luaZ_init(&z, reader, data, chunkname);
733 c = luaZ_lookahead(&z);
734 status = luaD_protectedparser(L, &z, (c == LUA_SIGNATURE[0]));
735 lua_unlock(L);
736 return status;
740 LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data) {
741 int status;
742 TObject *o;
743 lua_lock(L);
744 api_checknelems(L, 1);
745 o = L->top - 1;
746 if (isLfunction(o) && clvalue(o)->l.nupvalues == 0) {
747 luaU_dump(L, clvalue(o)->l.p, writer, data);
748 status = 1;
750 else
751 status = 0;
752 lua_unlock(L);
753 return status;
758 ** Garbage-collection functions
761 /* GC values are expressed in Kbytes: #bytes/2^10 */
762 #define GCscalel(x) ((x)>>10)
763 #define GCscale(x) (cast(int, GCscalel(x)))
764 #define GCunscale(x) (cast(lu_mem, x)<<10)
766 LUA_API int lua_getgcthreshold (lua_State *L) {
767 int threshold;
768 lua_lock(L);
769 threshold = GCscale(G(L)->GCthreshold);
770 lua_unlock(L);
771 return threshold;
774 LUA_API int lua_getgccount (lua_State *L) {
775 int count;
776 lua_lock(L);
777 count = GCscale(G(L)->nblocks);
778 lua_unlock(L);
779 return count;
782 LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
783 lua_lock(L);
784 if (cast(lu_mem, newthreshold) > GCscalel(MAX_LUMEM))
785 G(L)->GCthreshold = MAX_LUMEM;
786 else
787 G(L)->GCthreshold = GCunscale(newthreshold);
788 luaC_checkGC(L);
789 lua_unlock(L);
794 ** miscellaneous functions
798 LUA_API const char *lua_version (void) {
799 return LUA_VERSION;
803 LUA_API int lua_error (lua_State *L) {
804 lua_lock(L);
805 api_checknelems(L, 1);
806 luaG_errormsg(L);
807 lua_unlock(L);
808 return 0; /* to avoid warnings */
812 LUA_API int lua_next (lua_State *L, int idx) {
813 StkId t;
814 int more;
815 lua_lock(L);
816 t = luaA_index(L, idx);
817 api_check(L, ttistable(t));
818 more = luaH_next(L, hvalue(t), L->top - 1);
819 if (more) {
820 api_incr_top(L);
822 else /* no more elements */
823 L->top -= 1; /* remove key */
824 lua_unlock(L);
825 return more;
829 LUA_API void lua_concat (lua_State *L, int n) {
830 lua_lock(L);
831 luaC_checkGC(L);
832 api_checknelems(L, n);
833 if (n >= 2) {
834 luaV_concat(L, n, L->top - L->base - 1);
835 L->top -= (n-1);
837 else if (n == 0) { /* push empty string */
838 setsvalue2s(L->top, luaS_newlstr(L, NULL, 0));
839 api_incr_top(L);
841 /* else n == 1; nothing to do */
842 lua_unlock(L);
846 LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
847 Udata *u;
848 lua_lock(L);
849 luaC_checkGC(L);
850 u = luaS_newudata(L, size);
851 setuvalue(L->top, u);
852 api_incr_top(L);
853 lua_unlock(L);
854 return u + 1;
858 LUA_API int lua_pushupvalues (lua_State *L) {
859 Closure *func;
860 int n, i;
861 lua_lock(L);
862 api_check(L, iscfunction(L->base - 1));
863 func = clvalue(L->base - 1);
864 n = func->c.nupvalues;
865 luaD_checkstack(L, n + LUA_MINSTACK);
866 for (i=0; i<n; i++) {
867 setobj2s(L->top, &func->c.upvalue[i]);
868 L->top++;
870 lua_unlock(L);
871 return n;
875 static const char *aux_upvalue (lua_State *L, int funcindex, int n,
876 TObject **val) {
877 Closure *f;
878 StkId fi = luaA_index(L, funcindex);
879 if (!ttisfunction(fi)) return NULL;
880 f = clvalue(fi);
881 if (f->c.isC) {
882 if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
883 *val = &f->c.upvalue[n-1];
884 return "";
886 else {
887 Proto *p = f->l.p;
888 if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
889 *val = f->l.upvals[n-1]->v;
890 return getstr(p->upvalues[n-1]);
895 LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
896 const char *name;
897 TObject *val;
898 lua_lock(L);
899 name = aux_upvalue(L, funcindex, n, &val);
900 if (name) {
901 setobj2s(L->top, val);
902 api_incr_top(L);
904 lua_unlock(L);
905 return name;
909 LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
910 const char *name;
911 TObject *val;
912 lua_lock(L);
913 api_checknelems(L, 1);
914 name = aux_upvalue(L, funcindex, n, &val);
915 if (name) {
916 L->top--;
917 setobj(val, L->top); /* write barrier */
919 lua_unlock(L);
920 return name;