1dc2bddecbca68e2e682ce46d38fe9c96943bd51
[olsrd.git] / lib / tas / src / lua / lapi.c
1
2 /*
3 ** $Id: lapi.c,v 1.235 2003/04/07 14:36:08 roberto Exp $
4 ** Lua API
5 ** See Copyright Notice in lua.h
6 */
7
8
9 #include <assert.h>
10 #include <string.h>
11
12 #define lapi_c
13
14 #include "lua.h"
15
16 #include "lapi.h"
17 #include "ldebug.h"
18 #include "ldo.h"
19 #include "lfunc.h"
20 #include "lgc.h"
21 #include "lmem.h"
22 #include "lobject.h"
23 #include "lstate.h"
24 #include "lstring.h"
25 #include "ltable.h"
26 #include "ltm.h"
27 #include "lundump.h"
28 #include "lvm.h"
29
30
31 const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n" "$Authors: " LUA_AUTHORS " $\n" "$URL: www.lua.org $\n";
32
33
34
35 #ifndef api_check
36 #define api_check(L, o)         /*{ assert(o); } */
37 #endif
38
39 #define api_checknelems(L, n)   api_check(L, (n) <= (L->top - L->base))
40
41 #define api_incr_top(L)   {api_check(L, L->top < L->ci->top); L->top++;}
42
43
44
45
46 static TObject *
47 negindex(lua_State * L, int idx)
48 {
49   if (idx > LUA_REGISTRYINDEX) {
50     api_check(L, idx != 0 && -idx <= L->top - L->base);
51     return L->top + idx;
52   } else
53     switch (idx) {              /* pseudo-indices */
54     case LUA_REGISTRYINDEX:
55       return registry(L);
56     case LUA_GLOBALSINDEX:
57       return gt(L);
58     default:{
59         TObject *func = (L->base - 1);
60         idx = LUA_GLOBALSINDEX - idx;
61         lua_assert(iscfunction(func));
62         return (idx <= clvalue(func)->c.nupvalues)
63           ? &clvalue(func)->c.upvalue[idx - 1]
64           : NULL;
65       }
66     }
67 }
68
69
70 static TObject *
71 luaA_index(lua_State * L, int idx)
72 {
73   if (idx > 0) {
74     api_check(L, idx <= L->top - L->base);
75     return L->base + idx - 1;
76   } else {
77     TObject *o = negindex(L, idx);
78     api_check(L, o != NULL);
79     return o;
80   }
81 }
82
83
84 static TObject *
85 luaA_indexAcceptable(lua_State * L, int idx)
86 {
87   if (idx > 0) {
88     TObject *o = L->base + (idx - 1);
89     api_check(L, idx <= L->stack_last - L->base);
90     if (o >= L->top)
91       return NULL;
92     else
93       return o;
94   } else
95     return negindex(L, idx);
96 }
97
98
99 void
100 luaA_pushobject(lua_State * L, const TObject * o)
101 {
102   setobj2s(L->top, o);
103   incr_top(L);
104 }
105
106
107 LUA_API int
108 lua_checkstack(lua_State * L, int size)
109 {
110   int res;
111   lua_lock(L);
112   if ((L->top - L->base + size) > LUA_MAXCSTACK)
113     res = 0;                    /* stack overflow */
114   else {
115     luaD_checkstack(L, size);
116     if (L->ci->top < L->top + size)
117       L->ci->top = L->top + size;
118     res = 1;
119   }
120   lua_unlock(L);
121   return res;
122 }
123
124
125 LUA_API void
126 lua_xmove(lua_State * from, lua_State * to, int n)
127 {
128   int i;
129   lua_lock(to);
130   api_checknelems(from, n);
131   from->top -= n;
132   for (i = 0; i < n; i++) {
133     setobj2s(to->top, from->top + i);
134     api_incr_top(to);
135   }
136   lua_unlock(to);
137 }
138
139
140 LUA_API lua_CFunction
141 lua_atpanic(lua_State * L, lua_CFunction panicf)
142 {
143   lua_CFunction old;
144   lua_lock(L);
145   old = G(L)->panic;
146   G(L)->panic = panicf;
147   lua_unlock(L);
148   return old;
149 }
150
151
152 LUA_API lua_State *
153 lua_newthread(lua_State * L)
154 {
155   lua_State *L1;
156   lua_lock(L);
157   luaC_checkGC(L);
158   L1 = luaE_newthread(L);
159   setthvalue(L->top, L1);
160   api_incr_top(L);
161   lua_unlock(L);
162   lua_userstateopen(L1);
163   return L1;
164 }
165
166
167
168 /*
169 ** basic stack manipulation
170 */
171
172
173 LUA_API int
174 lua_gettop(lua_State * L)
175 {
176   return (L->top - L->base);
177 }
178
179
180 LUA_API void
181 lua_settop(lua_State * L, int idx)
182 {
183   lua_lock(L);
184   if (idx >= 0) {
185     api_check(L, idx <= L->stack_last - L->base);
186     while (L->top < L->base + idx)
187       setnilvalue(L->top++);
188     L->top = L->base + idx;
189   } else {
190     api_check(L, -(idx + 1) <= (L->top - L->base));
191     L->top += idx + 1;          /* `subtract' index (index is negative) */
192   }
193   lua_unlock(L);
194 }
195
196
197 LUA_API void
198 lua_remove(lua_State * L, int idx)
199 {
200   StkId p;
201   lua_lock(L);
202   p = luaA_index(L, idx);
203   while (++p < L->top)
204     setobjs2s(p - 1, p);
205   L->top--;
206   lua_unlock(L);
207 }
208
209
210 LUA_API void
211 lua_insert(lua_State * L, int idx)
212 {
213   StkId p;
214   StkId q;
215   lua_lock(L);
216   p = luaA_index(L, idx);
217   for (q = L->top; q > p; q--)
218     setobjs2s(q, q - 1);
219   setobjs2s(p, L->top);
220   lua_unlock(L);
221 }
222
223
224 LUA_API void
225 lua_replace(lua_State * L, int idx)
226 {
227   lua_lock(L);
228   api_checknelems(L, 1);
229   setobj(luaA_index(L, idx), L->top - 1);       /* write barrier */
230   L->top--;
231   lua_unlock(L);
232 }
233
234
235 LUA_API void
236 lua_pushvalue(lua_State * L, int idx)
237 {
238   lua_lock(L);
239   setobj2s(L->top, luaA_index(L, idx));
240   api_incr_top(L);
241   lua_unlock(L);
242 }
243
244
245
246 /*
247 ** access functions (stack -> C)
248 */
249
250
251 LUA_API int
252 lua_type(lua_State * L, int idx)
253 {
254   StkId o = luaA_indexAcceptable(L, idx);
255   return (o == NULL) ? LUA_TNONE : ttype(o);
256 }
257
258
259 LUA_API const char *
260 lua_typename(lua_State * L, int t)
261 {
262   UNUSED(L);
263   return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
264 }
265
266
267 LUA_API int
268 lua_iscfunction(lua_State * L, int idx)
269 {
270   StkId o = luaA_indexAcceptable(L, idx);
271   return (o == NULL) ? 0 : iscfunction(o);
272 }
273
274
275 LUA_API int
276 lua_isnumber(lua_State * L, int idx)
277 {
278   TObject n;
279   const TObject *o = luaA_indexAcceptable(L, idx);
280   return (o != NULL && tonumber(o, &n));
281 }
282
283
284 LUA_API int
285 lua_isstring(lua_State * L, int idx)
286 {
287   int t = lua_type(L, idx);
288   return (t == LUA_TSTRING || t == LUA_TNUMBER);
289 }
290
291
292 LUA_API int
293 lua_isuserdata(lua_State * L, int idx)
294 {
295   const TObject *o = luaA_indexAcceptable(L, idx);
296   return (o != NULL && (ttisuserdata(o) || ttislightuserdata(o)));
297 }
298
299
300 LUA_API int
301 lua_rawequal(lua_State * L, int index1, int index2)
302 {
303   StkId o1 = luaA_indexAcceptable(L, index1);
304   StkId o2 = luaA_indexAcceptable(L, index2);
305   return (o1 == NULL || o2 == NULL) ? 0 /* index out of range */
306     : luaO_rawequalObj(o1, o2);
307 }
308
309
310 LUA_API int
311 lua_equal(lua_State * L, int index1, int index2)
312 {
313   StkId o1, o2;
314   int i;
315   lua_lock(L);                  /* may call tag method */
316   o1 = luaA_indexAcceptable(L, index1);
317   o2 = luaA_indexAcceptable(L, index2);
318   i = (o1 == NULL || o2 == NULL) ? 0    /* index out of range */
319     : equalobj(L, o1, o2);
320   lua_unlock(L);
321   return i;
322 }
323
324
325 LUA_API int
326 lua_lessthan(lua_State * L, int index1, int index2)
327 {
328   StkId o1, o2;
329   int i;
330   lua_lock(L);                  /* may call tag method */
331   o1 = luaA_indexAcceptable(L, index1);
332   o2 = luaA_indexAcceptable(L, index2);
333   i = (o1 == NULL || o2 == NULL) ? 0    /* index out-of-range */
334     : luaV_lessthan(L, o1, o2);
335   lua_unlock(L);
336   return i;
337 }
338
339
340
341 LUA_API lua_Number
342 lua_tonumber(lua_State * L, int idx)
343 {
344   TObject n;
345   const TObject *o = luaA_indexAcceptable(L, idx);
346   if (o != NULL && tonumber(o, &n))
347     return nvalue(o);
348   else
349     return 0;
350 }
351
352
353 LUA_API int
354 lua_toboolean(lua_State * L, int idx)
355 {
356   const TObject *o = luaA_indexAcceptable(L, idx);
357   return (o != NULL) && !l_isfalse(o);
358 }
359
360
361 LUA_API const char *
362 lua_tostring(lua_State * L, int idx)
363 {
364   StkId o = luaA_indexAcceptable(L, idx);
365   if (o == NULL)
366     return NULL;
367   else if (ttisstring(o))
368     return svalue(o);
369   else {
370     const char *s;
371     lua_lock(L);                /* `luaV_tostring' may create a new string */
372     s = (luaV_tostring(L, o) ? svalue(o) : NULL);
373     luaC_checkGC(L);
374     lua_unlock(L);
375     return s;
376   }
377 }
378
379
380 LUA_API size_t
381 lua_strlen(lua_State * L, int idx)
382 {
383   StkId o = luaA_indexAcceptable(L, idx);
384   if (o == NULL)
385     return 0;
386   else if (ttisstring(o))
387     return tsvalue(o)->tsv.len;
388   else {
389     size_t l;
390     lua_lock(L);                /* `luaV_tostring' may create a new string */
391     l = (luaV_tostring(L, o) ? tsvalue(o)->tsv.len : 0);
392     lua_unlock(L);
393     return l;
394   }
395 }
396
397
398 LUA_API lua_CFunction
399 lua_tocfunction(lua_State * L, int idx)
400 {
401   StkId o = luaA_indexAcceptable(L, idx);
402   return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->c.f;
403 }
404
405
406 LUA_API void *
407 lua_touserdata(lua_State * L, int idx)
408 {
409   StkId o = luaA_indexAcceptable(L, idx);
410   if (o == NULL)
411     return NULL;
412   switch (ttype(o)) {
413   case LUA_TUSERDATA:
414     return (uvalue(o) + 1);
415   case LUA_TLIGHTUSERDATA:
416     return pvalue(o);
417   default:
418     return NULL;
419   }
420 }
421
422
423 LUA_API lua_State *
424 lua_tothread(lua_State * L, int idx)
425 {
426   StkId o = luaA_indexAcceptable(L, idx);
427   return (o == NULL || !ttisthread(o)) ? NULL : thvalue(o);
428 }
429
430
431 LUA_API const void *
432 lua_topointer(lua_State * L, int idx)
433 {
434   StkId o = luaA_indexAcceptable(L, idx);
435   if (o == NULL)
436     return NULL;
437   else {
438     switch (ttype(o)) {
439     case LUA_TTABLE:
440       return hvalue(o);
441     case LUA_TFUNCTION:
442       return clvalue(o);
443     case LUA_TTHREAD:
444       return thvalue(o);
445     case LUA_TUSERDATA:
446     case LUA_TLIGHTUSERDATA:
447       return lua_touserdata(L, idx);
448     default:
449       return NULL;
450     }
451   }
452 }
453
454
455
456 /*
457 ** push functions (C -> stack)
458 */
459
460
461 LUA_API void
462 lua_pushnil(lua_State * L)
463 {
464   lua_lock(L);
465   setnilvalue(L->top);
466   api_incr_top(L);
467   lua_unlock(L);
468 }
469
470
471 LUA_API void
472 lua_pushnumber(lua_State * L, lua_Number n)
473 {
474   lua_lock(L);
475   setnvalue(L->top, n);
476   api_incr_top(L);
477   lua_unlock(L);
478 }
479
480
481 LUA_API void
482 lua_pushlstring(lua_State * L, const char *s, size_t len)
483 {
484   lua_lock(L);
485   luaC_checkGC(L);
486   setsvalue2s(L->top, luaS_newlstr(L, s, len));
487   api_incr_top(L);
488   lua_unlock(L);
489 }
490
491
492 LUA_API void
493 lua_pushstring(lua_State * L, const char *s)
494 {
495   if (s == NULL)
496     lua_pushnil(L);
497   else
498     lua_pushlstring(L, s, strlen(s));
499 }
500
501
502 LUA_API const char *
503 lua_pushvfstring(lua_State * L, const char *fmt, va_list argp)
504 {
505   const char *ret;
506   lua_lock(L);
507   luaC_checkGC(L);
508   ret = luaO_pushvfstring(L, fmt, argp);
509   lua_unlock(L);
510   return ret;
511 }
512
513
514 LUA_API const char *
515 lua_pushfstring(lua_State * L, const char *fmt, ...)
516 {
517   const char *ret;
518   va_list argp;
519   lua_lock(L);
520   luaC_checkGC(L);
521   va_start(argp, fmt);
522   ret = luaO_pushvfstring(L, fmt, argp);
523   va_end(argp);
524   lua_unlock(L);
525   return ret;
526 }
527
528
529 LUA_API void
530 lua_pushcclosure(lua_State * L, lua_CFunction fn, int n)
531 {
532   Closure *cl;
533   lua_lock(L);
534   luaC_checkGC(L);
535   api_checknelems(L, n);
536   cl = luaF_newCclosure(L, n);
537   cl->c.f = fn;
538   L->top -= n;
539   while (n--)
540     setobj2n(&cl->c.upvalue[n], L->top + n);
541   setclvalue(L->top, cl);
542   api_incr_top(L);
543   lua_unlock(L);
544 }
545
546
547 LUA_API void
548 lua_pushboolean(lua_State * L, int b)
549 {
550   lua_lock(L);
551   setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
552   api_incr_top(L);
553   lua_unlock(L);
554 }
555
556
557 LUA_API void
558 lua_pushlightuserdata(lua_State * L, const void *p)
559 {
560   lua_lock(L);
561   setpvalue(L->top, (void *)p);
562   api_incr_top(L);
563   lua_unlock(L);
564 }
565
566
567
568 /*
569 ** get functions (Lua -> stack)
570 */
571
572
573 LUA_API void
574 lua_gettable(lua_State * L, int idx)
575 {
576   StkId t;
577   lua_lock(L);
578   t = luaA_index(L, idx);
579   setobj2s(L->top - 1, luaV_gettable(L, t, L->top - 1, 0));
580   lua_unlock(L);
581 }
582
583
584 LUA_API void
585 lua_rawget(lua_State * L, int idx)
586 {
587   StkId t;
588   lua_lock(L);
589   t = luaA_index(L, idx);
590   api_check(L, ttistable(t));
591   setobj2s(L->top - 1, luaH_get(hvalue(t), L->top - 1));
592   lua_unlock(L);
593 }
594
595
596 LUA_API void
597 lua_rawgeti(lua_State * L, int idx, int n)
598 {
599   StkId o;
600   lua_lock(L);
601   o = luaA_index(L, idx);
602   api_check(L, ttistable(o));
603   setobj2s(L->top, luaH_getnum(hvalue(o), n));
604   api_incr_top(L);
605   lua_unlock(L);
606 }
607
608
609 LUA_API void
610 lua_newtable(lua_State * L)
611 {
612   lua_lock(L);
613   luaC_checkGC(L);
614   sethvalue(L->top, luaH_new(L, 0, 0));
615   api_incr_top(L);
616   lua_unlock(L);
617 }
618
619
620 LUA_API int
621 lua_getmetatable(lua_State * L, int objindex)
622 {
623   const TObject *obj;
624   Table *mt = NULL;
625   int res;
626   lua_lock(L);
627   obj = luaA_indexAcceptable(L, objindex);
628   if (obj != NULL) {
629     switch (ttype(obj)) {
630     case LUA_TTABLE:
631       mt = hvalue(obj)->metatable;
632       break;
633     case LUA_TUSERDATA:
634       mt = uvalue(obj)->uv.metatable;
635       break;
636     }
637   }
638   if (mt == NULL || mt == hvalue(defaultmeta(L)))
639     res = 0;
640   else {
641     sethvalue(L->top, mt);
642     api_incr_top(L);
643     res = 1;
644   }
645   lua_unlock(L);
646   return res;
647 }
648
649
650 LUA_API void
651 lua_getfenv(lua_State * L, int idx)
652 {
653   StkId o;
654   lua_lock(L);
655   o = luaA_index(L, idx);
656   setobj2s(L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L));
657   api_incr_top(L);
658   lua_unlock(L);
659 }
660
661
662 /*
663 ** set functions (stack -> Lua)
664 */
665
666
667 LUA_API void
668 lua_settable(lua_State * L, int idx)
669 {
670   StkId t;
671   lua_lock(L);
672   api_checknelems(L, 2);
673   t = luaA_index(L, idx);
674   luaV_settable(L, t, L->top - 2, L->top - 1);
675   L->top -= 2;                  /* pop index and value */
676   lua_unlock(L);
677 }
678
679
680 LUA_API void
681 lua_rawset(lua_State * L, int idx)
682 {
683   StkId t;
684   lua_lock(L);
685   api_checknelems(L, 2);
686   t = luaA_index(L, idx);
687   api_check(L, ttistable(t));
688   setobj2t(luaH_set(L, hvalue(t), L->top - 2), L->top - 1);     /* write barrier */
689   L->top -= 2;
690   lua_unlock(L);
691 }
692
693
694 LUA_API void
695 lua_rawseti(lua_State * L, int idx, int n)
696 {
697   StkId o;
698   lua_lock(L);
699   api_checknelems(L, 1);
700   o = luaA_index(L, idx);
701   api_check(L, ttistable(o));
702   setobj2t(luaH_setnum(L, hvalue(o), n), L->top - 1);   /* write barrier */
703   L->top--;
704   lua_unlock(L);
705 }
706
707
708 LUA_API int
709 lua_setmetatable(lua_State * L, int objindex)
710 {
711   TObject *obj, *mt;
712   int res = 1;
713   lua_lock(L);
714   api_checknelems(L, 1);
715   obj = luaA_index(L, objindex);
716   mt = (!ttisnil(L->top - 1)) ? L->top - 1 : defaultmeta(L);
717   api_check(L, ttistable(mt));
718   switch (ttype(obj)) {
719   case LUA_TTABLE:{
720       hvalue(obj)->metatable = hvalue(mt);      /* write barrier */
721       break;
722     }
723   case LUA_TUSERDATA:{
724       uvalue(obj)->uv.metatable = hvalue(mt);   /* write barrier */
725       break;
726     }
727   default:{
728       res = 0;                  /* cannot set */
729       break;
730     }
731   }
732   L->top--;
733   lua_unlock(L);
734   return res;
735 }
736
737
738 LUA_API int
739 lua_setfenv(lua_State * L, int idx)
740 {
741   StkId o;
742   int res = 0;
743   lua_lock(L);
744   api_checknelems(L, 1);
745   o = luaA_index(L, idx);
746   L->top--;
747   api_check(L, ttistable(L->top));
748   if (isLfunction(o)) {
749     res = 1;
750     clvalue(o)->l.g = *(L->top);
751   }
752   lua_unlock(L);
753   return res;
754 }
755
756
757 /*
758 ** `load' and `call' functions (run Lua code)
759 */
760
761 LUA_API void
762 lua_call(lua_State * L, int nargs, int nresults)
763 {
764   StkId func;
765   lua_lock(L);
766   api_checknelems(L, nargs + 1);
767   func = L->top - (nargs + 1);
768   luaD_call(L, func, nresults);
769   lua_unlock(L);
770 }
771
772
773
774 /*
775 ** Execute a protected call.
776 */
777 struct CallS {                         /* data to `f_call' */
778   StkId func;
779   int nresults;
780 };
781
782
783 static void
784 f_call(lua_State * L, void *ud)
785 {
786   struct CallS *c = cast(struct CallS *, ud);
787   luaD_call(L, c->func, c->nresults);
788 }
789
790
791
792 LUA_API int
793 lua_pcall(lua_State * L, int nargs, int nresults, int errfunc)
794 {
795   struct CallS c;
796   int status;
797   ptrdiff_t func;
798   lua_lock(L);
799   func = (errfunc == 0) ? 0 : savestack(L, luaA_index(L, errfunc));
800   c.func = L->top - (nargs + 1);        /* function to be called */
801   c.nresults = nresults;
802   status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
803   lua_unlock(L);
804   return status;
805 }
806
807
808 /*
809 ** Execute a protected C call.
810 */
811 struct CCallS {                        /* data to `f_Ccall' */
812   lua_CFunction func;
813   void *ud;
814 };
815
816
817 static void
818 f_Ccall(lua_State * L, void *ud)
819 {
820   struct CCallS *c = cast(struct CCallS *, ud);
821   Closure *cl;
822   cl = luaF_newCclosure(L, 0);
823   cl->c.f = c->func;
824   setclvalue(L->top, cl);       /* push function */
825   incr_top(L);
826   setpvalue(L->top, c->ud);     /* push only argument */
827   incr_top(L);
828   luaD_call(L, L->top - 2, 0);
829 }
830
831
832 LUA_API int
833 lua_cpcall(lua_State * L, lua_CFunction func, void *ud)
834 {
835   struct CCallS c;
836   int status;
837   lua_lock(L);
838   c.func = func;
839   c.ud = ud;
840   status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
841   lua_unlock(L);
842   return status;
843 }
844
845
846 LUA_API int
847 lua_load(lua_State * L, lua_Chunkreader reader, void *data, const char *chunkname)
848 {
849   ZIO z;
850   int status;
851   int c;
852   lua_lock(L);
853   if (!chunkname)
854     chunkname = "?";
855   luaZ_init(&z, reader, data, chunkname);
856   c = luaZ_lookahead(&z);
857   status = luaD_protectedparser(L, &z, (c == LUA_SIGNATURE[0]));
858   lua_unlock(L);
859   return status;
860 }
861
862
863 LUA_API int
864 lua_dump(lua_State * L, lua_Chunkwriter writer, void *data)
865 {
866   int status;
867   TObject *o;
868   lua_lock(L);
869   api_checknelems(L, 1);
870   o = L->top - 1;
871   if (isLfunction(o) && clvalue(o)->l.nupvalues == 0) {
872     luaU_dump(L, clvalue(o)->l.p, writer, data);
873     status = 1;
874   } else
875     status = 0;
876   lua_unlock(L);
877   return status;
878 }
879
880
881 /*
882 ** Garbage-collection functions
883 */
884
885 /* GC values are expressed in Kbytes: #bytes/2^10 */
886 #define GCscalel(x)             ((x)>>10)
887 #define GCscale(x)              (cast(int, GCscalel(x)))
888 #define GCunscale(x)            (cast(lu_mem, x)<<10)
889
890 LUA_API int
891 lua_getgcthreshold(lua_State * L)
892 {
893   int threshold;
894   lua_lock(L);
895   threshold = GCscale(G(L)->GCthreshold);
896   lua_unlock(L);
897   return threshold;
898 }
899
900 LUA_API int
901 lua_getgccount(lua_State * L)
902 {
903   int count;
904   lua_lock(L);
905   count = GCscale(G(L)->nblocks);
906   lua_unlock(L);
907   return count;
908 }
909
910 LUA_API void
911 lua_setgcthreshold(lua_State * L, int newthreshold)
912 {
913   lua_lock(L);
914   if (cast(lu_mem, newthreshold) > GCscalel(MAX_LUMEM))
915     G(L)->GCthreshold = MAX_LUMEM;
916   else
917     G(L)->GCthreshold = GCunscale(newthreshold);
918   luaC_checkGC(L);
919   lua_unlock(L);
920 }
921
922
923 /*
924 ** miscellaneous functions
925 */
926
927
928 LUA_API const char *
929 lua_version(void)
930 {
931   return LUA_VERSION;
932 }
933
934
935 LUA_API int
936 lua_error(lua_State * L)
937 {
938   lua_lock(L);
939   api_checknelems(L, 1);
940   luaG_errormsg(L);
941   lua_unlock(L);
942 }
943
944
945 LUA_API int
946 lua_next(lua_State * L, int idx)
947 {
948   StkId t;
949   int more;
950   lua_lock(L);
951   t = luaA_index(L, idx);
952   api_check(L, ttistable(t));
953   more = luaH_next(L, hvalue(t), L->top - 1);
954   if (more) {
955     api_incr_top(L);
956   } else                        /* no more elements */
957     L->top -= 1;                /* remove key */
958   lua_unlock(L);
959   return more;
960 }
961
962
963 LUA_API void
964 lua_concat(lua_State * L, int n)
965 {
966   lua_lock(L);
967   luaC_checkGC(L);
968   api_checknelems(L, n);
969   if (n >= 2) {
970     luaV_concat(L, n, L->top - L->base - 1);
971     L->top -= (n - 1);
972   } else if (n == 0) {          /* push empty string */
973     setsvalue2s(L->top, luaS_newlstr(L, NULL, 0));
974     api_incr_top(L);
975   }
976   /* else n == 1; nothing to do */
977   lua_unlock(L);
978 }
979
980
981 LUA_API void *
982 lua_newuserdata(lua_State * L, size_t size)
983 {
984   Udata *u;
985   lua_lock(L);
986   luaC_checkGC(L);
987   u = luaS_newudata(L, size);
988   setuvalue(L->top, u);
989   api_incr_top(L);
990   lua_unlock(L);
991   return u + 1;
992 }
993
994
995 LUA_API int
996 lua_pushupvalues(lua_State * L)
997 {
998   Closure *func;
999   int n, i;
1000   lua_lock(L);
1001   api_check(L, iscfunction(L->base - 1));
1002   func = clvalue(L->base - 1);
1003   n = func->c.nupvalues;
1004   luaD_checkstack(L, n + LUA_MINSTACK);
1005   for (i = 0; i < n; i++) {
1006     setobj2s(L->top, &func->c.upvalue[i]);
1007     L->top++;
1008   }
1009   lua_unlock(L);
1010   return n;
1011 }
1012
1013
1014 static const char *
1015 aux_upvalue(lua_State * L, int funcindex, int n, TObject ** val)
1016 {
1017   Closure *f;
1018   StkId fi = luaA_index(L, funcindex);
1019   if (!ttisfunction(fi))
1020     return NULL;
1021   f = clvalue(fi);
1022   if (f->c.isC) {
1023     if (n > f->c.nupvalues)
1024       return NULL;
1025     *val = &f->c.upvalue[n - 1];
1026     return "";
1027   } else {
1028     Proto *p = f->l.p;
1029     if (n > p->sizeupvalues)
1030       return NULL;
1031     *val = f->l.upvals[n - 1]->v;
1032     return getstr(p->upvalues[n - 1]);
1033   }
1034 }
1035
1036
1037 LUA_API const char *
1038 lua_getupvalue(lua_State * L, int funcindex, int n)
1039 {
1040   const char *name;
1041   TObject *val;
1042   lua_lock(L);
1043   name = aux_upvalue(L, funcindex, n, &val);
1044   if (name) {
1045     setobj2s(L->top, val);
1046     api_incr_top(L);
1047   }
1048   lua_unlock(L);
1049   return name;
1050 }
1051
1052
1053 LUA_API const char *
1054 lua_setupvalue(lua_State * L, int funcindex, int n)
1055 {
1056   const char *name;
1057   TObject *val;
1058   lua_lock(L);
1059   api_checknelems(L, 1);
1060   name = aux_upvalue(L, funcindex, n, &val);
1061   if (name) {
1062     L->top--;
1063     setobj(val, L->top);        /* write barrier */
1064   }
1065   lua_unlock(L);
1066   return name;
1067 }