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