Security Patch
[platform/upstream/lua.git] / src / lapi.c
1 /*
2 ** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $
3 ** Lua API
4 ** See Copyright Notice in lua.h
5 */
6
7
8 #include <assert.h>
9 #include <math.h>
10 #include <stdarg.h>
11 #include <string.h>
12
13 #define lapi_c
14 #define LUA_CORE
15
16 #include "lua.h"
17
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"
31
32
33
34 const char lua_ident[] =
35   "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n"
36   "$Authors: " LUA_AUTHORS " $\n"
37   "$URL: www.lua.org $\n";
38
39
40
41 #define api_checknelems(L, n)   api_check(L, (n) <= (L->top - L->base))
42
43 #define api_checkvalidindex(L, i)       api_check(L, (i) != luaO_nilobject)
44
45 #define api_incr_top(L)   {api_check(L, L->top < L->ci->top); L->top++;}
46
47
48
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 }
77
78
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 }
87
88
89 void luaA_pushobject (lua_State *L, const TValue *o) {
90   setobj2s(L, L->top, o);
91   api_incr_top(L);
92 }
93
94
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 }
108
109
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 }
123
124
125 LUA_API void lua_setlevel (lua_State *from, lua_State *to) {
126   to->nCcalls = from->nCcalls;
127 }
128
129
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 }
138
139
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 }
151
152
153
154 /*
155 ** basic stack manipulation
156 */
157
158
159 LUA_API int lua_gettop (lua_State *L) {
160   return cast_int(L->top - L->base);
161 }
162
163
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 }
178
179
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 }
189
190
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 }
201
202
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 }
226
227
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 }
234
235
236
237 /*
238 ** access functions (stack -> C)
239 */
240
241
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 }
246
247
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 }
252
253
254 LUA_API int lua_iscfunction (lua_State *L, int idx) {
255   StkId o = index2adr(L, idx);
256   return iscfunction(o);
257 }
258
259
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 }
265
266
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 }
271
272
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 }
277
278
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) ? 0
283          : luaO_rawequalObj(o1, o2);
284 }
285
286
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 }
297
298
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) ? 0
306        : luaV_lessthan(L, o1, o2);
307   lua_unlock(L);
308   return i;
309 }
310
311
312
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   else
319     return 0;
320 }
321
322
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   else
333     return 0;
334 }
335
336
337 LUA_API int lua_toboolean (lua_State *L, int idx) {
338   const TValue *o = index2adr(L, idx);
339   return !l_isfalse(o);
340 }
341
342
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 }
359
360
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 }
377
378
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 }
383
384
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 }
393
394
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 }
399
400
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 }
413
414
415
416 /*
417 ** push functions (C -> stack)
418 */
419
420
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 }
427
428
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 }
435
436
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 }
443
444
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 }
452
453
454 LUA_API void lua_pushstring (lua_State *L, const char *s) {
455   if (s == NULL)
456     lua_pushnil(L);
457   else
458     lua_pushlstring(L, s, strlen(s));
459 }
460
461
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 }
471
472
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 }
484
485
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 }
501
502
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 }
509
510
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 }
517
518
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 }
526
527
528
529 /*
530 ** get functions (Lua -> stack)
531 */
532
533
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 }
542
543
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 }
555
556
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 }
565
566
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 }
576
577
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 }
585
586
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 }
614
615
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 }
638
639
640 /*
641 ** set functions (stack -> Lua)
642 */
643
644
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 }
655
656
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 }
669
670
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 }
682
683
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 }
695
696
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 }
732
733
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 }
761
762
763 /*
764 ** `load' and `call' functions (run Lua code)
765 */
766
767
768 #define adjustresults(L,nres) \
769     { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; }
770
771
772 #define checkresults(L,na,nr) \
773      api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
774         
775
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 }
786
787
788
789 /*
790 ** Execute a protected call.
791 */
792 struct CallS {  /* data to `f_call' */
793   StkId func;
794   int nresults;
795 };
796
797
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 }
802
803
804
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 }
826
827
828 /*
829 ** Execute a protected C call.
830 */
831 struct CCallS {  /* data to `f_Ccall' */
832   lua_CFunction func;
833   void *ud;
834 };
835
836
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 }
848
849
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 }
860
861
862 LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
863                       const char *chunkname) {
864   return lua_loadEx(L, reader, data, chunkname, NULL);
865 }
866
867
868 LUA_API int lua_loadEx (lua_State *L, lua_Reader reader, void *data,
869                       const char *chunkname, const char *mode) {
870   ZIO z;
871   int status;
872   lua_lock(L);
873   if (!chunkname) chunkname = "?";
874   luaZ_init(L, &z, reader, data);
875   status = luaD_protectedparserEx(L, &z, chunkname, mode);
876   lua_unlock(L);
877   return status;
878 }
879
880
881 LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
882   int status;
883   TValue *o;
884   lua_lock(L);
885   api_checknelems(L, 1);
886   o = L->top - 1;
887   if (isLfunction(o))
888     status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
889   else
890     status = 1;
891   lua_unlock(L);
892   return status;
893 }
894
895
896 LUA_API int  lua_status (lua_State *L) {
897   return L->status;
898 }
899
900
901 /*
902 ** Garbage-collection function
903 */
904
905 LUA_API int lua_gc (lua_State *L, int what, int data) {
906   int res = 0;
907   global_State *g;
908   lua_lock(L);
909   g = G(L);
910   switch (what) {
911     case LUA_GCSTOP: {
912       g->GCthreshold = MAX_LUMEM;
913       break;
914     }
915     case LUA_GCRESTART: {
916       g->GCthreshold = g->totalbytes;
917       break;
918     }
919     case LUA_GCCOLLECT: {
920       luaC_fullgc(L);
921       break;
922     }
923     case LUA_GCCOUNT: {
924       /* GC values are expressed in Kbytes: #bytes/2^10 */
925       res = cast_int(g->totalbytes >> 10);
926       break;
927     }
928     case LUA_GCCOUNTB: {
929       res = cast_int(g->totalbytes & 0x3ff);
930       break;
931     }
932     case LUA_GCSTEP: {
933       lu_mem a = (cast(lu_mem, data) << 10);
934       if (a <= g->totalbytes)
935         g->GCthreshold = g->totalbytes - a;
936       else
937         g->GCthreshold = 0;
938       while (g->GCthreshold <= g->totalbytes) {
939         luaC_step(L);
940         if (g->gcstate == GCSpause) {  /* end of cycle? */
941           res = 1;  /* signal it */
942           break;
943         }
944       }
945       break;
946     }
947     case LUA_GCSETPAUSE: {
948       res = g->gcpause;
949       g->gcpause = data;
950       break;
951     }
952     case LUA_GCSETSTEPMUL: {
953       res = g->gcstepmul;
954       g->gcstepmul = data;
955       break;
956     }
957     default: res = -1;  /* invalid option */
958   }
959   lua_unlock(L);
960   return res;
961 }
962
963
964
965 /*
966 ** miscellaneous functions
967 */
968
969
970 LUA_API int lua_error (lua_State *L) {
971   lua_lock(L);
972   api_checknelems(L, 1);
973   luaG_errormsg(L);
974   lua_unlock(L);
975   return 0;  /* to avoid warnings */
976 }
977
978
979 LUA_API int lua_next (lua_State *L, int idx) {
980   StkId t;
981   int more;
982   lua_lock(L);
983   t = index2adr(L, idx);
984   api_check(L, ttistable(t));
985   more = luaH_next(L, hvalue(t), L->top - 1);
986   if (more) {
987     api_incr_top(L);
988   }
989   else  /* no more elements */
990     L->top -= 1;  /* remove key */
991   lua_unlock(L);
992   return more;
993 }
994
995
996 LUA_API void lua_concat (lua_State *L, int n) {
997   lua_lock(L);
998   api_checknelems(L, n);
999   if (n >= 2) {
1000     luaC_checkGC(L);
1001     luaV_concat(L, n, cast_int(L->top - L->base) - 1);
1002     L->top -= (n-1);
1003   }
1004   else if (n == 0) {  /* push empty string */
1005     setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
1006     api_incr_top(L);
1007   }
1008   /* else n == 1; nothing to do */
1009   lua_unlock(L);
1010 }
1011
1012
1013 LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
1014   lua_Alloc f;
1015   lua_lock(L);
1016   if (ud) *ud = G(L)->ud;
1017   f = G(L)->frealloc;
1018   lua_unlock(L);
1019   return f;
1020 }
1021
1022
1023 LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
1024   lua_lock(L);
1025   G(L)->ud = ud;
1026   G(L)->frealloc = f;
1027   lua_unlock(L);
1028 }
1029
1030
1031 LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
1032   Udata *u;
1033   lua_lock(L);
1034   luaC_checkGC(L);
1035   u = luaS_newudata(L, size, getcurrenv(L));
1036   setuvalue(L, L->top, u);
1037   api_incr_top(L);
1038   lua_unlock(L);
1039   return u + 1;
1040 }
1041
1042
1043
1044
1045 static const char *aux_upvalue (StkId fi, int n, TValue **val) {
1046   Closure *f;
1047   if (!ttisfunction(fi)) return NULL;
1048   f = clvalue(fi);
1049   if (f->c.isC) {
1050     if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
1051     *val = &f->c.upvalue[n-1];
1052     return "";
1053   }
1054   else {
1055     Proto *p = f->l.p;
1056     if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
1057     *val = f->l.upvals[n-1]->v;
1058     return getstr(p->upvalues[n-1]);
1059   }
1060 }
1061
1062
1063 LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
1064   const char *name;
1065   TValue *val;
1066   lua_lock(L);
1067   name = aux_upvalue(index2adr(L, funcindex), n, &val);
1068   if (name) {
1069     setobj2s(L, L->top, val);
1070     api_incr_top(L);
1071   }
1072   lua_unlock(L);
1073   return name;
1074 }
1075
1076
1077 LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
1078   const char *name;
1079   TValue *val;
1080   StkId fi;
1081   lua_lock(L);
1082   fi = index2adr(L, funcindex);
1083   api_checknelems(L, 1);
1084   name = aux_upvalue(fi, n, &val);
1085   if (name) {
1086     L->top--;
1087     setobj(L, val, L->top);
1088     luaC_barrier(L, clvalue(fi), L->top);
1089   }
1090   lua_unlock(L);
1091   return name;
1092 }
1093