xref: /netbsd-src/external/mit/lua/dist/src/lapi.c (revision 6cf6fe02a981b55727c49c3d37b0d8191a98c0ee)
1 /*	$NetBSD: lapi.c,v 1.2 2014/07/19 18:38:34 lneto Exp $	*/
2 
3 /*
4 ** $Id: lapi.c,v 1.2 2014/07/19 18:38:34 lneto Exp $
5 ** Lua API
6 ** See Copyright Notice in lua.h
7 */
8 
9 
10 #ifndef _KERNEL
11 #include <math.h>
12 #endif
13 #include <stdarg.h>
14 #ifndef _KERNEL
15 #include <string.h>
16 #endif
17 
18 #define lapi_c
19 #define LUA_CORE
20 
21 #include "lua.h"
22 
23 #include "lapi.h"
24 #include "ldebug.h"
25 #include "ldo.h"
26 #include "lfunc.h"
27 #include "lgc.h"
28 #include "lmem.h"
29 #include "lobject.h"
30 #include "lstate.h"
31 #include "lstring.h"
32 #include "ltable.h"
33 #include "ltm.h"
34 #include "lundump.h"
35 #include "lvm.h"
36 
37 
38 
39 const char lua_ident[] =
40   "$LuaVersion: " LUA_COPYRIGHT " $"
41   "$LuaAuthors: " LUA_AUTHORS " $";
42 
43 
44 /* value at a non-valid index */
45 #define NONVALIDVALUE		cast(TValue *, luaO_nilobject)
46 
47 /* corresponding test */
48 #define isvalid(o)	((o) != luaO_nilobject)
49 
50 /* test for pseudo index */
51 #define ispseudo(i)		((i) <= LUA_REGISTRYINDEX)
52 
53 /* test for valid but not pseudo index */
54 #define isstackindex(i, o)	(isvalid(o) && !ispseudo(i))
55 
56 #define api_checkvalidindex(L, o)  api_check(L, isvalid(o), "invalid index")
57 
58 #define api_checkstackindex(L, i, o)  \
59 	api_check(L, isstackindex(i, o), "index not in the stack")
60 
61 
62 static TValue *index2addr (lua_State *L, int idx) {
63   CallInfo *ci = L->ci;
64   if (idx > 0) {
65     TValue *o = ci->func + idx;
66     api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
67     if (o >= L->top) return NONVALIDVALUE;
68     else return o;
69   }
70   else if (!ispseudo(idx)) {  /* negative index */
71     api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
72     return L->top + idx;
73   }
74   else if (idx == LUA_REGISTRYINDEX)
75     return &G(L)->l_registry;
76   else {  /* upvalues */
77     idx = LUA_REGISTRYINDEX - idx;
78     api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
79     if (ttislcf(ci->func))  /* light C function? */
80       return NONVALIDVALUE;  /* it has no upvalues */
81     else {
82       CClosure *func = clCvalue(ci->func);
83       return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE;
84     }
85   }
86 }
87 
88 
89 /*
90 ** to be called by 'lua_checkstack' in protected mode, to grow stack
91 ** capturing memory errors
92 */
93 static void growstack (lua_State *L, void *ud) {
94   int size = *(int *)ud;
95   luaD_growstack(L, size);
96 }
97 
98 
99 LUA_API int lua_checkstack (lua_State *L, int size) {
100   int res;
101   CallInfo *ci = L->ci;
102   lua_lock(L);
103   api_check(L, size >= 0, "negative 'size'");
104   if (L->stack_last - L->top > size)  /* stack large enough? */
105     res = 1;  /* yes; check is OK */
106   else {  /* no; need to grow stack */
107     int inuse = cast_int(L->top - L->stack) + EXTRA_STACK;
108     if (inuse > LUAI_MAXSTACK - size)  /* can grow without overflow? */
109       res = 0;  /* no */
110     else  /* try to grow stack */
111       res = (luaD_rawrunprotected(L, &growstack, &size) == LUA_OK);
112   }
113   if (res && ci->top < L->top + size)
114     ci->top = L->top + size;  /* adjust frame top */
115   lua_unlock(L);
116   return res;
117 }
118 
119 
120 LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
121   int i;
122   if (from == to) return;
123   lua_lock(to);
124   api_checknelems(from, n);
125   api_check(from, G(from) == G(to), "moving among independent states");
126   api_check(from, to->ci->top - to->top >= n, "not enough elements to move");
127   from->top -= n;
128   for (i = 0; i < n; i++) {
129     setobj2s(to, to->top++, from->top + i);
130   }
131   lua_unlock(to);
132 }
133 
134 
135 LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
136   lua_CFunction old;
137   lua_lock(L);
138   old = G(L)->panic;
139   G(L)->panic = panicf;
140   lua_unlock(L);
141   return old;
142 }
143 
144 
145 LUA_API const lua_Number *lua_version (lua_State *L) {
146   static const lua_Number version = LUA_VERSION_NUM;
147   if (L == NULL) return &version;
148   else return G(L)->version;
149 }
150 
151 
152 
153 /*
154 ** basic stack manipulation
155 */
156 
157 
158 /*
159 ** convert an acceptable stack index into an absolute index
160 */
161 LUA_API int lua_absindex (lua_State *L, int idx) {
162   return (idx > 0 || ispseudo(idx))
163          ? idx
164          : cast_int(L->top - L->ci->func + idx);
165 }
166 
167 
168 LUA_API int lua_gettop (lua_State *L) {
169   return cast_int(L->top - (L->ci->func + 1));
170 }
171 
172 
173 LUA_API void lua_settop (lua_State *L, int idx) {
174   StkId func = L->ci->func;
175   lua_lock(L);
176   if (idx >= 0) {
177     api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
178     while (L->top < (func + 1) + idx)
179       setnilvalue(L->top++);
180     L->top = (func + 1) + idx;
181   }
182   else {
183     api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
184     L->top += idx+1;  /* `subtract' index (index is negative) */
185   }
186   lua_unlock(L);
187 }
188 
189 
190 /*
191 ** Reverse the stack segment from 'from' to 'to'
192 ** (auxiliar to 'lua_rotate')
193 */
194 static void reverse (lua_State *L, StkId from, StkId to) {
195   for (; from < to; from++, to--) {
196     TValue temp;
197     setobj(L, &temp, from);
198     setobjs2s(L, from, to);
199     setobj2s(L, to, &temp);
200   }
201 }
202 
203 
204 /*
205 ** Let x = AB, where A is a prefix of length 'n'. Then,
206 ** rotate x n == BA. But BA == (A^r . B^r)^r.
207 */
208 LUA_API void lua_rotate (lua_State *L, int idx, int n) {
209   StkId p, t, m;
210   lua_lock(L);
211   t = L->top - 1;  /* end of stack segment being rotated */
212   p = index2addr(L, idx);  /* start of segment */
213   api_checkstackindex(L, idx, p);
214   api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
215   m = (n >= 0 ? t - n : p - n - 1);  /* end of prefix */
216   reverse(L, p, m);  /* reverse the prefix with length 'n' */
217   reverse(L, m + 1, t);  /* reverse the suffix */
218   reverse(L, p, t);  /* reverse the entire segment */
219   lua_unlock(L);
220 }
221 
222 
223 static void moveto (lua_State *L, TValue *fr, int idx) {
224   TValue *to = index2addr(L, idx);
225   api_checkvalidindex(L, to);
226   setobj(L, to, fr);
227   if (idx < LUA_REGISTRYINDEX)  /* function upvalue? */
228     luaC_barrier(L, clCvalue(L->ci->func), fr);
229   /* LUA_REGISTRYINDEX does not need gc barrier
230      (collector revisits it before finishing collection) */
231 }
232 
233 
234 LUA_API void lua_replace (lua_State *L, int idx) {
235   lua_lock(L);
236   api_checknelems(L, 1);
237   moveto(L, L->top - 1, idx);
238   L->top--;
239   lua_unlock(L);
240 }
241 
242 
243 LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
244   TValue *fr;
245   lua_lock(L);
246   fr = index2addr(L, fromidx);
247   moveto(L, fr, toidx);
248   lua_unlock(L);
249 }
250 
251 
252 LUA_API void lua_pushvalue (lua_State *L, int idx) {
253   lua_lock(L);
254   setobj2s(L, L->top, index2addr(L, idx));
255   api_incr_top(L);
256   lua_unlock(L);
257 }
258 
259 
260 
261 /*
262 ** access functions (stack -> C)
263 */
264 
265 
266 LUA_API int lua_type (lua_State *L, int idx) {
267   StkId o = index2addr(L, idx);
268   return (isvalid(o) ? ttnov(o) : LUA_TNONE);
269 }
270 
271 
272 LUA_API const char *lua_typename (lua_State *L, int t) {
273   UNUSED(L);
274   return ttypename(t);
275 }
276 
277 
278 LUA_API int lua_iscfunction (lua_State *L, int idx) {
279   StkId o = index2addr(L, idx);
280   return (ttislcf(o) || (ttisCclosure(o)));
281 }
282 
283 
284 LUA_API int lua_isinteger (lua_State *L, int idx) {
285   StkId o = index2addr(L, idx);
286   return ttisinteger(o);
287 }
288 
289 
290 LUA_API int lua_isnumber (lua_State *L, int idx) {
291 #ifndef _KERNEL
292   lua_Number n;
293   const TValue *o = index2addr(L, idx);
294   return tonumber(o, &n);
295 #else
296   StkId o = index2addr(L, idx);
297   return ttisinteger(o);
298 #endif
299 }
300 
301 
302 LUA_API int lua_isstring (lua_State *L, int idx) {
303   int t = lua_type(L, idx);
304   return (t == LUA_TSTRING || t == LUA_TNUMBER);
305 }
306 
307 
308 LUA_API int lua_isuserdata (lua_State *L, int idx) {
309   const TValue *o = index2addr(L, idx);
310   return (ttisfulluserdata(o) || ttislightuserdata(o));
311 }
312 
313 
314 LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
315   StkId o1 = index2addr(L, index1);
316   StkId o2 = index2addr(L, index2);
317   return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0;
318 }
319 
320 
321 LUA_API void lua_arith (lua_State *L, int op) {
322   lua_lock(L);
323   if (op != LUA_OPUNM && op != LUA_OPBNOT)
324     api_checknelems(L, 2);  /* all other operations expect two operands */
325   else {  /* for unary operations, add fake 2nd operand */
326     api_checknelems(L, 1);
327     setobjs2s(L, L->top, L->top - 1);
328     L->top++;
329   }
330   /* first operand at top - 2, second at top - 1; result go to top - 2 */
331   luaO_arith(L, op, L->top - 2, L->top - 1, L->top - 2);
332   L->top--;  /* remove second operand */
333   lua_unlock(L);
334 }
335 
336 
337 LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
338   StkId o1, o2;
339   int i = 0;
340   lua_lock(L);  /* may call tag method */
341   o1 = index2addr(L, index1);
342   o2 = index2addr(L, index2);
343   if (isvalid(o1) && isvalid(o2)) {
344     switch (op) {
345       case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break;
346       case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
347       case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
348       default: api_check(L, 0, "invalid option");
349     }
350   }
351   lua_unlock(L);
352   return i;
353 }
354 
355 
356 LUA_API size_t lua_strtonum (lua_State *L, const char *s) {
357   size_t sz = luaO_str2num(s, L->top);
358   if (sz != 0)
359     api_incr_top(L);
360   return sz;
361 }
362 
363 
364 LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) {
365   lua_Number n;
366   const TValue *o = index2addr(L, idx);
367   int isnum = tonumber(o, &n);
368   if (!isnum)
369     n = 0;  /* call to 'tonumber' may change 'n' even if it fails */
370   if (pisnum) *pisnum = isnum;
371   return n;
372 }
373 
374 
375 LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) {
376   lua_Integer res;
377   const TValue *o = index2addr(L, idx);
378   int isnum = tointeger(o, &res);
379   if (!isnum)
380     res = 0;  /* call to 'tointeger' may change 'n' even if it fails */
381   if (pisnum) *pisnum = isnum;
382   return res;
383 }
384 
385 
386 LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *pisnum) {
387   lua_Unsigned res = 0;
388   const TValue *o = index2addr(L, idx);
389   int isnum = 0;
390   switch (ttype(o)) {
391     case LUA_TNUMINT: {
392       res = l_castS2U(ivalue(o));
393       isnum = 1;
394       break;
395     }
396 #ifndef _KERNEL
397     case LUA_TNUMFLT: {  /* compute floor(n) % 2^(numbits in an integer) */
398       const lua_Number two2n = cast_num(LUA_MAXUNSIGNED) + cast_num(1);
399       lua_Number n = fltvalue(o);  /* get value */
400       int neg = 0;
401       n = l_floor(n);  /* get its floor */
402       if (n < 0) {
403         neg = 1;
404         n = -n;  /* make 'n' positive, so that 'fmod' is the same as '%' */
405       }
406       n = l_mathop(fmod)(n, two2n);  /* n = n % 2^(numbits in an integer) */
407       if (luai_numisnan(n))   /* not a number? */
408         break;  /* not an integer, too */
409       res = cast(lua_Unsigned, n);  /* 'n' now must fit in an unsigned */
410       if (neg) res = 0u - res;  /* back to negative, if needed */
411       isnum = 1;
412       break;
413     }
414 #endif
415     default: break;
416   }
417   if (pisnum) *pisnum = isnum;
418   return res;
419 }
420 
421 
422 LUA_API int lua_toboolean (lua_State *L, int idx) {
423   const TValue *o = index2addr(L, idx);
424   return !l_isfalse(o);
425 }
426 
427 
428 LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
429   StkId o = index2addr(L, idx);
430   if (!ttisstring(o)) {
431     lua_lock(L);  /* `luaV_tostring' may create a new string */
432     if (!luaV_tostring(L, o)) {  /* conversion failed? */
433       if (len != NULL) *len = 0;
434       lua_unlock(L);
435       return NULL;
436     }
437     luaC_checkGC(L);
438     o = index2addr(L, idx);  /* previous call may reallocate the stack */
439     lua_unlock(L);
440   }
441   if (len != NULL) *len = tsvalue(o)->len;
442   return svalue(o);
443 }
444 
445 
446 LUA_API size_t lua_rawlen (lua_State *L, int idx) {
447   StkId o = index2addr(L, idx);
448   switch (ttnov(o)) {
449     case LUA_TSTRING: return tsvalue(o)->len;
450     case LUA_TUSERDATA: return uvalue(o)->len;
451     case LUA_TTABLE: return luaH_getn(hvalue(o));
452     default: return 0;
453   }
454 }
455 
456 
457 LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
458   StkId o = index2addr(L, idx);
459   if (ttislcf(o)) return fvalue(o);
460   else if (ttisCclosure(o))
461     return clCvalue(o)->f;
462   else return NULL;  /* not a C function */
463 }
464 
465 
466 LUA_API void *lua_touserdata (lua_State *L, int idx) {
467   StkId o = index2addr(L, idx);
468   switch (ttnov(o)) {
469     case LUA_TUSERDATA: return (rawuvalue(o) + 1);
470     case LUA_TLIGHTUSERDATA: return pvalue(o);
471     default: return NULL;
472   }
473 }
474 
475 
476 LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
477   StkId o = index2addr(L, idx);
478   return (!ttisthread(o)) ? NULL : thvalue(o);
479 }
480 
481 
482 LUA_API const void *lua_topointer (lua_State *L, int idx) {
483   StkId o = index2addr(L, idx);
484   switch (ttype(o)) {
485     case LUA_TTABLE: return hvalue(o);
486     case LUA_TLCL: return clLvalue(o);
487     case LUA_TCCL: return clCvalue(o);
488     case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
489     case LUA_TTHREAD: return thvalue(o);
490     case LUA_TUSERDATA:
491     case LUA_TLIGHTUSERDATA:
492       return lua_touserdata(L, idx);
493     default: return NULL;
494   }
495 }
496 
497 
498 
499 /*
500 ** push functions (C -> stack)
501 */
502 
503 
504 LUA_API void lua_pushnil (lua_State *L) {
505   lua_lock(L);
506   setnilvalue(L->top);
507   api_incr_top(L);
508   lua_unlock(L);
509 }
510 
511 
512 LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
513   lua_lock(L);
514 #ifndef _KERNEL
515   setfltvalue(L->top, n);
516 #else
517   setivalue(L->top, n);
518 #endif
519   api_incr_top(L);
520   lua_unlock(L);
521 }
522 
523 
524 LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
525   lua_lock(L);
526   setivalue(L->top, n);
527   api_incr_top(L);
528   lua_unlock(L);
529 }
530 
531 
532 LUA_API void lua_pushunsigned (lua_State *L, lua_Unsigned u) {
533   lua_lock(L);
534   setivalue(L->top, l_castU2S(u));
535   api_incr_top(L);
536   lua_unlock(L);
537 }
538 
539 
540 LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
541   TString *ts;
542   lua_lock(L);
543   luaC_checkGC(L);
544   ts = luaS_newlstr(L, s, len);
545   setsvalue2s(L, L->top, ts);
546   api_incr_top(L);
547   lua_unlock(L);
548   return getstr(ts);
549 }
550 
551 
552 LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
553   if (s == NULL) {
554     lua_pushnil(L);
555     return NULL;
556   }
557   else {
558     TString *ts;
559     lua_lock(L);
560     luaC_checkGC(L);
561     ts = luaS_new(L, s);
562     setsvalue2s(L, L->top, ts);
563     api_incr_top(L);
564     lua_unlock(L);
565     return getstr(ts);
566   }
567 }
568 
569 
570 LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
571                                       va_list argp) {
572   const char *ret;
573   lua_lock(L);
574   luaC_checkGC(L);
575   ret = luaO_pushvfstring(L, fmt, argp);
576   lua_unlock(L);
577   return ret;
578 }
579 
580 
581 LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
582   const char *ret;
583   va_list argp;
584   lua_lock(L);
585   luaC_checkGC(L);
586   va_start(argp, fmt);
587   ret = luaO_pushvfstring(L, fmt, argp);
588   va_end(argp);
589   lua_unlock(L);
590   return ret;
591 }
592 
593 
594 LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
595   lua_lock(L);
596   if (n == 0) {
597     setfvalue(L->top, fn);
598   }
599   else {
600     CClosure *cl;
601     api_checknelems(L, n);
602     api_check(L, n <= MAXUPVAL, "upvalue index too large");
603     luaC_checkGC(L);
604     cl = luaF_newCclosure(L, n);
605     cl->f = fn;
606     L->top -= n;
607     while (n--) {
608       setobj2n(L, &cl->upvalue[n], L->top + n);
609       /* does not need barrier because closure is white */
610     }
611     setclCvalue(L, L->top, cl);
612   }
613   api_incr_top(L);
614   lua_unlock(L);
615 }
616 
617 
618 LUA_API void lua_pushboolean (lua_State *L, int b) {
619   lua_lock(L);
620   setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
621   api_incr_top(L);
622   lua_unlock(L);
623 }
624 
625 
626 LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
627   lua_lock(L);
628   setpvalue(L->top, p);
629   api_incr_top(L);
630   lua_unlock(L);
631 }
632 
633 
634 LUA_API int lua_pushthread (lua_State *L) {
635   lua_lock(L);
636   setthvalue(L, L->top, L);
637   api_incr_top(L);
638   lua_unlock(L);
639   return (G(L)->mainthread == L);
640 }
641 
642 
643 
644 /*
645 ** get functions (Lua -> stack)
646 */
647 
648 
649 LUA_API int lua_getglobal (lua_State *L, const char *var) {
650   Table *reg = hvalue(&G(L)->l_registry);
651   const TValue *gt;  /* global table */
652   lua_lock(L);
653   gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
654   setsvalue2s(L, L->top++, luaS_new(L, var));
655   luaV_gettable(L, gt, L->top - 1, L->top - 1);
656   lua_unlock(L);
657   return ttnov(L->top - 1);
658 }
659 
660 
661 LUA_API int lua_gettable (lua_State *L, int idx) {
662   StkId t;
663   lua_lock(L);
664   t = index2addr(L, idx);
665   luaV_gettable(L, t, L->top - 1, L->top - 1);
666   lua_unlock(L);
667   return ttnov(L->top - 1);
668 }
669 
670 
671 LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
672   StkId t;
673   lua_lock(L);
674   t = index2addr(L, idx);
675   setsvalue2s(L, L->top, luaS_new(L, k));
676   api_incr_top(L);
677   luaV_gettable(L, t, L->top - 1, L->top - 1);
678   lua_unlock(L);
679   return ttnov(L->top - 1);
680 }
681 
682 
683 LUA_API int lua_rawget (lua_State *L, int idx) {
684   StkId t;
685   lua_lock(L);
686   t = index2addr(L, idx);
687   api_check(L, ttistable(t), "table expected");
688   setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
689   lua_unlock(L);
690   return ttnov(L->top - 1);
691 }
692 
693 
694 LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
695   StkId t;
696   lua_lock(L);
697   t = index2addr(L, idx);
698   api_check(L, ttistable(t), "table expected");
699   setobj2s(L, L->top, luaH_getint(hvalue(t), n));
700   api_incr_top(L);
701   lua_unlock(L);
702   return ttnov(L->top - 1);
703 }
704 
705 
706 LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
707   StkId t;
708   TValue k;
709   lua_lock(L);
710   t = index2addr(L, idx);
711   api_check(L, ttistable(t), "table expected");
712   setpvalue(&k, cast(void *, p));
713   setobj2s(L, L->top, luaH_get(hvalue(t), &k));
714   api_incr_top(L);
715   lua_unlock(L);
716   return ttnov(L->top - 1);
717 }
718 
719 
720 LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
721   Table *t;
722   lua_lock(L);
723   luaC_checkGC(L);
724   t = luaH_new(L);
725   sethvalue(L, L->top, t);
726   api_incr_top(L);
727   if (narray > 0 || nrec > 0)
728     luaH_resize(L, t, narray, nrec);
729   lua_unlock(L);
730 }
731 
732 
733 LUA_API int lua_getmetatable (lua_State *L, int objindex) {
734   const TValue *obj;
735   Table *mt = NULL;
736   int res;
737   lua_lock(L);
738   obj = index2addr(L, objindex);
739   switch (ttnov(obj)) {
740     case LUA_TTABLE:
741       mt = hvalue(obj)->metatable;
742       break;
743     case LUA_TUSERDATA:
744       mt = uvalue(obj)->metatable;
745       break;
746     default:
747       mt = G(L)->mt[ttnov(obj)];
748       break;
749   }
750   if (mt == NULL)
751     res = 0;
752   else {
753     sethvalue(L, L->top, mt);
754     api_incr_top(L);
755     res = 1;
756   }
757   lua_unlock(L);
758   return res;
759 }
760 
761 
762 LUA_API int lua_getuservalue (lua_State *L, int idx) {
763   StkId o;
764   lua_lock(L);
765   o = index2addr(L, idx);
766   api_check(L, ttisfulluserdata(o), "full userdata expected");
767   getuservalue(L, rawuvalue(o), L->top);
768   api_incr_top(L);
769   lua_unlock(L);
770   return ttnov(L->top - 1);
771 }
772 
773 
774 /*
775 ** set functions (stack -> Lua)
776 */
777 
778 
779 LUA_API void lua_setglobal (lua_State *L, const char *var) {
780   Table *reg = hvalue(&G(L)->l_registry);
781   const TValue *gt;  /* global table */
782   lua_lock(L);
783   api_checknelems(L, 1);
784   gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
785   setsvalue2s(L, L->top++, luaS_new(L, var));
786   luaV_settable(L, gt, L->top - 1, L->top - 2);
787   L->top -= 2;  /* pop value and key */
788   lua_unlock(L);
789 }
790 
791 
792 LUA_API void lua_settable (lua_State *L, int idx) {
793   StkId t;
794   lua_lock(L);
795   api_checknelems(L, 2);
796   t = index2addr(L, idx);
797   luaV_settable(L, t, L->top - 2, L->top - 1);
798   L->top -= 2;  /* pop index and value */
799   lua_unlock(L);
800 }
801 
802 
803 LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
804   StkId t;
805   lua_lock(L);
806   api_checknelems(L, 1);
807   t = index2addr(L, idx);
808   setsvalue2s(L, L->top++, luaS_new(L, k));
809   luaV_settable(L, t, L->top - 1, L->top - 2);
810   L->top -= 2;  /* pop value and key */
811   lua_unlock(L);
812 }
813 
814 
815 LUA_API void lua_rawset (lua_State *L, int idx) {
816   StkId t;
817   lua_lock(L);
818   api_checknelems(L, 2);
819   t = index2addr(L, idx);
820   api_check(L, ttistable(t), "table expected");
821   setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
822   invalidateTMcache(hvalue(t));
823   luaC_barrierback(L, gcvalue(t), L->top-1);
824   L->top -= 2;
825   lua_unlock(L);
826 }
827 
828 
829 LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
830   StkId t;
831   lua_lock(L);
832   api_checknelems(L, 1);
833   t = index2addr(L, idx);
834   api_check(L, ttistable(t), "table expected");
835   luaH_setint(L, hvalue(t), n, L->top - 1);
836   luaC_barrierback(L, gcvalue(t), L->top-1);
837   L->top--;
838   lua_unlock(L);
839 }
840 
841 
842 LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
843   StkId t;
844   TValue k;
845   lua_lock(L);
846   api_checknelems(L, 1);
847   t = index2addr(L, idx);
848   api_check(L, ttistable(t), "table expected");
849   setpvalue(&k, cast(void *, p));
850   setobj2t(L, luaH_set(L, hvalue(t), &k), L->top - 1);
851   luaC_barrierback(L, gcvalue(t), L->top - 1);
852   L->top--;
853   lua_unlock(L);
854 }
855 
856 
857 LUA_API int lua_setmetatable (lua_State *L, int objindex) {
858   TValue *obj;
859   Table *mt;
860   lua_lock(L);
861   api_checknelems(L, 1);
862   obj = index2addr(L, objindex);
863   if (ttisnil(L->top - 1))
864     mt = NULL;
865   else {
866     api_check(L, ttistable(L->top - 1), "table expected");
867     mt = hvalue(L->top - 1);
868   }
869   switch (ttnov(obj)) {
870     case LUA_TTABLE: {
871       hvalue(obj)->metatable = mt;
872       if (mt) {
873         luaC_objbarrier(L, gcvalue(obj), mt);
874         luaC_checkfinalizer(L, gcvalue(obj), mt);
875       }
876       break;
877     }
878     case LUA_TUSERDATA: {
879       uvalue(obj)->metatable = mt;
880       if (mt) {
881         luaC_objbarrier(L, rawuvalue(obj), mt);
882         luaC_checkfinalizer(L, gcvalue(obj), mt);
883       }
884       break;
885     }
886     default: {
887       G(L)->mt[ttnov(obj)] = mt;
888       break;
889     }
890   }
891   L->top--;
892   lua_unlock(L);
893   return 1;
894 }
895 
896 
897 LUA_API void lua_setuservalue (lua_State *L, int idx) {
898   StkId o;
899   lua_lock(L);
900   api_checknelems(L, 1);
901   o = index2addr(L, idx);
902   api_check(L, ttisfulluserdata(o), "full userdata expected");
903   setuservalue(L, rawuvalue(o), L->top - 1);
904   luaC_barrier(L, gcvalue(o), L->top - 1);
905   L->top--;
906   lua_unlock(L);
907 }
908 
909 
910 /*
911 ** `load' and `call' functions (run Lua code)
912 */
913 
914 
915 #define checkresults(L,na,nr) \
916      api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
917 	"results from function overflow current stack size")
918 
919 
920 LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx,
921                         lua_KFunction k) {
922   StkId func;
923   lua_lock(L);
924   api_check(L, k == NULL || !isLua(L->ci),
925     "cannot use continuations inside hooks");
926   api_checknelems(L, nargs+1);
927   api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
928   checkresults(L, nargs, nresults);
929   func = L->top - (nargs+1);
930   if (k != NULL && L->nny == 0) {  /* need to prepare continuation? */
931     L->ci->u.c.k = k;  /* save continuation */
932     L->ci->u.c.ctx = ctx;  /* save context */
933     luaD_call(L, func, nresults, 1);  /* do the call */
934   }
935   else  /* no continuation or no yieldable */
936     luaD_call(L, func, nresults, 0);  /* just do the call */
937   adjustresults(L, nresults);
938   lua_unlock(L);
939 }
940 
941 
942 
943 /*
944 ** Execute a protected call.
945 */
946 struct CallS {  /* data to `f_call' */
947   StkId func;
948   int nresults;
949 };
950 
951 
952 static void f_call (lua_State *L, void *ud) {
953   struct CallS *c = cast(struct CallS *, ud);
954   luaD_call(L, c->func, c->nresults, 0);
955 }
956 
957 
958 
959 LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
960                         int ctx, lua_KFunction k) {
961   struct CallS c;
962   int status;
963   ptrdiff_t func;
964   lua_lock(L);
965   api_check(L, k == NULL || !isLua(L->ci),
966     "cannot use continuations inside hooks");
967   api_checknelems(L, nargs+1);
968   api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
969   checkresults(L, nargs, nresults);
970   if (errfunc == 0)
971     func = 0;
972   else {
973     StkId o = index2addr(L, errfunc);
974     api_checkstackindex(L, errfunc, o);
975     func = savestack(L, o);
976   }
977   c.func = L->top - (nargs+1);  /* function to be called */
978   if (k == NULL || L->nny > 0) {  /* no continuation or no yieldable? */
979     c.nresults = nresults;  /* do a 'conventional' protected call */
980     status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
981   }
982   else {  /* prepare continuation (call is already protected by 'resume') */
983     CallInfo *ci = L->ci;
984     ci->u.c.k = k;  /* save continuation */
985     ci->u.c.ctx = ctx;  /* save context */
986     /* save information for error recovery */
987     ci->extra = savestack(L, c.func);
988     ci->u.c.old_errfunc = L->errfunc;
989     L->errfunc = func;
990     setoah(ci->callstatus, L->allowhook);  /* save value of 'allowhook' */
991     ci->callstatus |= CIST_YPCALL;  /* function can do error recovery */
992     luaD_call(L, c.func, nresults, 1);  /* do the call */
993     ci->callstatus &= ~CIST_YPCALL;
994     L->errfunc = ci->u.c.old_errfunc;
995     status = LUA_OK;  /* if it is here, there were no errors */
996   }
997   adjustresults(L, nresults);
998   lua_unlock(L);
999   return status;
1000 }
1001 
1002 
1003 LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
1004                       const char *chunkname, const char *mode) {
1005   ZIO z;
1006   int status;
1007   lua_lock(L);
1008   if (!chunkname) chunkname = "?";
1009   luaZ_init(L, &z, reader, data);
1010   status = luaD_protectedparser(L, &z, chunkname, mode);
1011   if (status == LUA_OK) {  /* no errors? */
1012     LClosure *f = clLvalue(L->top - 1);  /* get newly created function */
1013     if (f->nupvalues == 1) {  /* does it have one upvalue? */
1014       /* get global table from registry */
1015       Table *reg = hvalue(&G(L)->l_registry);
1016       const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
1017       /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
1018       setobj(L, f->upvals[0]->v, gt);
1019       luaC_barrier(L, f->upvals[0], gt);
1020     }
1021   }
1022   lua_unlock(L);
1023   return status;
1024 }
1025 
1026 
1027 LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
1028   int status;
1029   TValue *o;
1030   lua_lock(L);
1031   api_checknelems(L, 1);
1032   o = L->top - 1;
1033   if (isLfunction(o))
1034     status = luaU_dump(L, getproto(o), writer, data, strip);
1035   else
1036     status = 1;
1037   lua_unlock(L);
1038   return status;
1039 }
1040 
1041 
1042 LUA_API int lua_status (lua_State *L) {
1043   return L->status;
1044 }
1045 
1046 
1047 /*
1048 ** Garbage-collection function
1049 */
1050 
1051 LUA_API int lua_gc (lua_State *L, int what, int data) {
1052   int res = 0;
1053   global_State *g;
1054   lua_lock(L);
1055   g = G(L);
1056   switch (what) {
1057     case LUA_GCSTOP: {
1058       g->gcrunning = 0;
1059       break;
1060     }
1061     case LUA_GCRESTART: {
1062       luaE_setdebt(g, 0);
1063       g->gcrunning = 1;
1064       break;
1065     }
1066     case LUA_GCCOLLECT: {
1067       luaC_fullgc(L, 0);
1068       break;
1069     }
1070     case LUA_GCCOUNT: {
1071       /* GC values are expressed in Kbytes: #bytes/2^10 */
1072       res = cast_int(gettotalbytes(g) >> 10);
1073       break;
1074     }
1075     case LUA_GCCOUNTB: {
1076       res = cast_int(gettotalbytes(g) & 0x3ff);
1077       break;
1078     }
1079     case LUA_GCSTEP: {
1080       l_mem debt = 1;  /* =1 to signal that it did an actual step */
1081       int oldrunning = g->gcrunning;
1082       g->gcrunning = 1;  /* force GC to run */
1083       if (data == 0) {
1084         luaE_setdebt(g, -GCSTEPSIZE);  /* to do a "small" step */
1085         luaC_step(L);
1086       }
1087       else {  /* add 'data' to total debt */
1088         debt = cast(l_mem, data) * 1024 + g->GCdebt;
1089         luaE_setdebt(g, debt);
1090         luaC_checkGC(L);
1091       }
1092       g->gcrunning = oldrunning;  /* restore previous state */
1093       if (debt > 0 && g->gcstate == GCSpause)  /* end of cycle? */
1094         res = 1;  /* signal it */
1095       break;
1096     }
1097     case LUA_GCSETPAUSE: {
1098       res = g->gcpause;
1099       g->gcpause = data;
1100       break;
1101     }
1102     case LUA_GCSETSTEPMUL: {
1103       res = g->gcstepmul;
1104       if (data < 40) data = 40;  /* avoid ridiculous low values (and 0) */
1105       g->gcstepmul = data;
1106       break;
1107     }
1108     case LUA_GCISRUNNING: {
1109       res = g->gcrunning;
1110       break;
1111     }
1112     default: res = -1;  /* invalid option */
1113   }
1114   lua_unlock(L);
1115   return res;
1116 }
1117 
1118 
1119 
1120 /*
1121 ** miscellaneous functions
1122 */
1123 
1124 
1125 LUA_API int lua_error (lua_State *L) {
1126   lua_lock(L);
1127   api_checknelems(L, 1);
1128   luaG_errormsg(L);
1129   /* code unreachable; will unlock when control actually leaves the kernel */
1130   return 0;  /* to avoid warnings */
1131 }
1132 
1133 
1134 LUA_API int lua_next (lua_State *L, int idx) {
1135   StkId t;
1136   int more;
1137   lua_lock(L);
1138   t = index2addr(L, idx);
1139   api_check(L, ttistable(t), "table expected");
1140   more = luaH_next(L, hvalue(t), L->top - 1);
1141   if (more) {
1142     api_incr_top(L);
1143   }
1144   else  /* no more elements */
1145     L->top -= 1;  /* remove key */
1146   lua_unlock(L);
1147   return more;
1148 }
1149 
1150 
1151 LUA_API void lua_concat (lua_State *L, int n) {
1152   lua_lock(L);
1153   api_checknelems(L, n);
1154   if (n >= 2) {
1155     luaC_checkGC(L);
1156     luaV_concat(L, n);
1157   }
1158   else if (n == 0) {  /* push empty string */
1159     setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
1160     api_incr_top(L);
1161   }
1162   /* else n == 1; nothing to do */
1163   lua_unlock(L);
1164 }
1165 
1166 
1167 LUA_API void lua_len (lua_State *L, int idx) {
1168   StkId t;
1169   lua_lock(L);
1170   t = index2addr(L, idx);
1171   luaV_objlen(L, L->top, t);
1172   api_incr_top(L);
1173   lua_unlock(L);
1174 }
1175 
1176 
1177 LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
1178   lua_Alloc f;
1179   lua_lock(L);
1180   if (ud) *ud = G(L)->ud;
1181   f = G(L)->frealloc;
1182   lua_unlock(L);
1183   return f;
1184 }
1185 
1186 
1187 LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
1188   lua_lock(L);
1189   G(L)->ud = ud;
1190   G(L)->frealloc = f;
1191   lua_unlock(L);
1192 }
1193 
1194 
1195 LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
1196   Udata *u;
1197   lua_lock(L);
1198   luaC_checkGC(L);
1199   u = luaS_newudata(L, size);
1200   setuvalue(L, L->top, u);
1201   api_incr_top(L);
1202   lua_unlock(L);
1203   return u + 1;
1204 }
1205 
1206 
1207 
1208 static const char *aux_upvalue (StkId fi, int n, TValue **val,
1209                                 GCObject **owner, UpVal **uv) {
1210   switch (ttype(fi)) {
1211     case LUA_TCCL: {  /* C closure */
1212       CClosure *f = clCvalue(fi);
1213       if (!(1 <= n && n <= f->nupvalues)) return NULL;
1214       *val = &f->upvalue[n-1];
1215       if (owner) *owner = obj2gco(f);
1216       return "";
1217     }
1218     case LUA_TLCL: {  /* Lua closure */
1219       LClosure *f = clLvalue(fi);
1220       TString *name;
1221       Proto *p = f->p;
1222       if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
1223       *val = f->upvals[n-1]->v;
1224       if (uv) *uv = f->upvals[n - 1];
1225       name = p->upvalues[n-1].name;
1226       return (name == NULL) ? "(*no name)" : getstr(name);
1227     }
1228     default: return NULL;  /* not a closure */
1229   }
1230 }
1231 
1232 
1233 LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
1234   const char *name;
1235   TValue *val = NULL;  /* to avoid warnings */
1236   lua_lock(L);
1237   name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL, NULL);
1238   if (name) {
1239     setobj2s(L, L->top, val);
1240     api_incr_top(L);
1241   }
1242   lua_unlock(L);
1243   return name;
1244 }
1245 
1246 
1247 LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
1248   const char *name;
1249   TValue *val = NULL;  /* to avoid warnings */
1250   GCObject *owner = NULL;
1251   UpVal *uv = NULL;
1252   StkId fi;
1253   lua_lock(L);
1254   fi = index2addr(L, funcindex);
1255   api_checknelems(L, 1);
1256   name = aux_upvalue(fi, n, &val, &owner, &uv);
1257   if (name) {
1258     L->top--;
1259     setobj(L, val, L->top);
1260     if (owner) { luaC_barrier(L, owner, L->top); }
1261     else if (uv) { luaC_upvalbarrier(L, uv); }
1262   }
1263   lua_unlock(L);
1264   return name;
1265 }
1266 
1267 
1268 static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
1269   LClosure *f;
1270   StkId fi = index2addr(L, fidx);
1271   api_check(L, ttisLclosure(fi), "Lua function expected");
1272   f = clLvalue(fi);
1273   api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
1274   if (pf) *pf = f;
1275   return &f->upvals[n - 1];  /* get its upvalue pointer */
1276 }
1277 
1278 
1279 LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
1280   StkId fi = index2addr(L, fidx);
1281   switch (ttype(fi)) {
1282     case LUA_TLCL: {  /* lua closure */
1283       return *getupvalref(L, fidx, n, NULL);
1284     }
1285     case LUA_TCCL: {  /* C closure */
1286       CClosure *f = clCvalue(fi);
1287       api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index");
1288       return &f->upvalue[n - 1];
1289     }
1290     default: {
1291       api_check(L, 0, "closure expected");
1292       return NULL;
1293     }
1294   }
1295 }
1296 
1297 
1298 LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
1299                                             int fidx2, int n2) {
1300   LClosure *f1;
1301   UpVal **up1 = getupvalref(L, fidx1, n1, &f1);
1302   UpVal **up2 = getupvalref(L, fidx2, n2, NULL);
1303   luaC_upvdeccount(L, *up1);
1304   *up1 = *up2;
1305   (*up1)->refcount++;
1306   if (upisopen(*up1)) (*up1)->u.open.touched = 1;
1307   luaC_upvalbarrier(L, *up1);
1308 }
1309 
1310 
1311