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