xref: /netbsd-src/external/mit/lua/dist/src/lapi.c (revision bdda0531de537df87feb2bf576711ab1be9b3675)
1*bdda0531Snikita /*	$NetBSD: lapi.c,v 1.15 2023/06/08 21:12:08 nikita Exp $	*/
2dbec5304Smbalmer 
3dbec5304Smbalmer /*
4f0dad708Snikita ** Id: lapi.c
5dbec5304Smbalmer ** Lua API
6dbec5304Smbalmer ** See Copyright Notice in lua.h
7dbec5304Smbalmer */
8dbec5304Smbalmer 
973008250Slneto #define lapi_c
1073008250Slneto #define LUA_CORE
11dbec5304Smbalmer 
1273008250Slneto #include "lprefix.h"
1373008250Slneto 
1473008250Slneto 
15f0dad708Snikita #ifndef _KERNEL
16f0dad708Snikita #include <limits.h>
17f0dad708Snikita #endif /* _KERNEL */
18dbec5304Smbalmer #include <stdarg.h>
194ab4902eSlneto #ifndef _KERNEL
20dbec5304Smbalmer #include <string.h>
212d6cb6c2Slneto #endif /* _KERNEL */
22dbec5304Smbalmer 
23dbec5304Smbalmer #include "lua.h"
24dbec5304Smbalmer 
25dbec5304Smbalmer #include "lapi.h"
26dbec5304Smbalmer #include "ldebug.h"
27dbec5304Smbalmer #include "ldo.h"
28dbec5304Smbalmer #include "lfunc.h"
29dbec5304Smbalmer #include "lgc.h"
30dbec5304Smbalmer #include "lmem.h"
31dbec5304Smbalmer #include "lobject.h"
32dbec5304Smbalmer #include "lstate.h"
33dbec5304Smbalmer #include "lstring.h"
34dbec5304Smbalmer #include "ltable.h"
35dbec5304Smbalmer #include "ltm.h"
36dbec5304Smbalmer #include "lundump.h"
37dbec5304Smbalmer #include "lvm.h"
38dbec5304Smbalmer 
39dbec5304Smbalmer 
40dbec5304Smbalmer 
41dbec5304Smbalmer const char lua_ident[] =
424ab4902eSlneto   "$LuaVersion: " LUA_COPYRIGHT " $"
434ab4902eSlneto   "$LuaAuthors: " LUA_AUTHORS " $";
44dbec5304Smbalmer 
45dbec5304Smbalmer 
46dbec5304Smbalmer 
47f0dad708Snikita /*
48f0dad708Snikita ** Test for a valid index (one that is not the 'nilvalue').
49f0dad708Snikita ** '!ttisnil(o)' implies 'o != &G(L)->nilvalue', so it is not needed.
50f0dad708Snikita ** However, it covers the most common cases in a faster way.
51f0dad708Snikita */
52f0dad708Snikita #define isvalid(L, o)	(!ttisnil(o) || o != &G(L)->nilvalue)
53f0dad708Snikita 
54dbec5304Smbalmer 
554ab4902eSlneto /* test for pseudo index */
564ab4902eSlneto #define ispseudo(i)		((i) <= LUA_REGISTRYINDEX)
57dbec5304Smbalmer 
5873008250Slneto /* test for upvalue */
5973008250Slneto #define isupvalue(i)		((i) < LUA_REGISTRYINDEX)
6073008250Slneto 
614ab4902eSlneto 
62f0dad708Snikita /*
63f0dad708Snikita ** Convert an acceptable index to a pointer to its respective value.
64f0dad708Snikita ** Non-valid indices return the special nil value 'G(L)->nilvalue'.
65f0dad708Snikita */
index2value(lua_State * L,int idx)66f0dad708Snikita static TValue *index2value (lua_State *L, int idx) {
674ab4902eSlneto   CallInfo *ci = L->ci;
68dbec5304Smbalmer   if (idx > 0) {
69*bdda0531Snikita     StkId o = ci->func.p + idx;
70*bdda0531Snikita     api_check(L, idx <= ci->top.p - (ci->func.p + 1), "unacceptable index");
71*bdda0531Snikita     if (o >= L->top.p) return &G(L)->nilvalue;
72f0dad708Snikita     else return s2v(o);
73dbec5304Smbalmer   }
744ab4902eSlneto   else if (!ispseudo(idx)) {  /* negative index */
75*bdda0531Snikita     api_check(L, idx != 0 && -idx <= L->top.p - (ci->func.p + 1),
76*bdda0531Snikita                  "invalid index");
77*bdda0531Snikita     return s2v(L->top.p + idx);
78dbec5304Smbalmer   }
794ab4902eSlneto   else if (idx == LUA_REGISTRYINDEX)
804ab4902eSlneto     return &G(L)->l_registry;
814ab4902eSlneto   else {  /* upvalues */
824ab4902eSlneto     idx = LUA_REGISTRYINDEX - idx;
83bee09862Smbalmer     api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
84*bdda0531Snikita     if (ttisCclosure(s2v(ci->func.p))) {  /* C closure? */
85*bdda0531Snikita       CClosure *func = clCvalue(s2v(ci->func.p));
86f0dad708Snikita       return (idx <= func->nupvalues) ? &func->upvalue[idx-1]
87f0dad708Snikita                                       : &G(L)->nilvalue;
88f0dad708Snikita     }
89f0dad708Snikita     else {  /* light C function or Lua function (through a hook)?) */
90*bdda0531Snikita       api_check(L, ttislcf(s2v(ci->func.p)), "caller not a C function");
91f0dad708Snikita       return &G(L)->nilvalue;  /* no upvalues */
924ab4902eSlneto     }
93dbec5304Smbalmer   }
94dbec5304Smbalmer }
95dbec5304Smbalmer 
96dbec5304Smbalmer 
97f0dad708Snikita 
984ab4902eSlneto /*
99f0dad708Snikita ** Convert a valid actual index (not a pseudo-index) to its address.
1004ab4902eSlneto */
index2stack(lua_State * L,int idx)101f0dad708Snikita l_sinline StkId index2stack (lua_State *L, int idx) {
102f0dad708Snikita   CallInfo *ci = L->ci;
103f0dad708Snikita   if (idx > 0) {
104*bdda0531Snikita     StkId o = ci->func.p + idx;
105*bdda0531Snikita     api_check(L, o < L->top.p, "invalid index");
106f0dad708Snikita     return o;
107f0dad708Snikita   }
108f0dad708Snikita   else {    /* non-positive index */
109*bdda0531Snikita     api_check(L, idx != 0 && -idx <= L->top.p - (ci->func.p + 1),
110*bdda0531Snikita                  "invalid index");
111f0dad708Snikita     api_check(L, !ispseudo(idx), "invalid index");
112*bdda0531Snikita     return L->top.p + idx;
113f0dad708Snikita   }
114dbec5304Smbalmer }
115dbec5304Smbalmer 
116dbec5304Smbalmer 
lua_checkstack(lua_State * L,int n)11773008250Slneto LUA_API int lua_checkstack (lua_State *L, int n) {
1184ab4902eSlneto   int res;
119f0dad708Snikita   CallInfo *ci;
120dbec5304Smbalmer   lua_lock(L);
121f0dad708Snikita   ci = L->ci;
122bee09862Smbalmer   api_check(L, n >= 0, "negative 'n'");
123*bdda0531Snikita   if (L->stack_last.p - L->top.p > n)  /* stack large enough? */
1244ab4902eSlneto     res = 1;  /* yes; check is OK */
125*bdda0531Snikita   else  /* need to grow stack */
126f0dad708Snikita     res = luaD_growstack(L, n, 0);
127*bdda0531Snikita   if (res && ci->top.p < L->top.p + n)
128*bdda0531Snikita     ci->top.p = L->top.p + n;  /* adjust frame top */
129dbec5304Smbalmer   lua_unlock(L);
130dbec5304Smbalmer   return res;
131dbec5304Smbalmer }
132dbec5304Smbalmer 
133dbec5304Smbalmer 
lua_xmove(lua_State * from,lua_State * to,int n)134dbec5304Smbalmer LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
135dbec5304Smbalmer   int i;
136dbec5304Smbalmer   if (from == to) return;
137dbec5304Smbalmer   lua_lock(to);
138dbec5304Smbalmer   api_checknelems(from, n);
139bee09862Smbalmer   api_check(from, G(from) == G(to), "moving among independent states");
140*bdda0531Snikita   api_check(from, to->ci->top.p - to->top.p >= n, "stack overflow");
141*bdda0531Snikita   from->top.p -= n;
142dbec5304Smbalmer   for (i = 0; i < n; i++) {
143*bdda0531Snikita     setobjs2s(to, to->top.p, from->top.p + i);
144*bdda0531Snikita     to->top.p++;  /* stack already checked by previous 'api_check' */
145dbec5304Smbalmer   }
146dbec5304Smbalmer   lua_unlock(to);
147dbec5304Smbalmer }
148dbec5304Smbalmer 
149dbec5304Smbalmer 
lua_atpanic(lua_State * L,lua_CFunction panicf)150dbec5304Smbalmer LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
151dbec5304Smbalmer   lua_CFunction old;
152dbec5304Smbalmer   lua_lock(L);
153dbec5304Smbalmer   old = G(L)->panic;
154dbec5304Smbalmer   G(L)->panic = panicf;
155dbec5304Smbalmer   lua_unlock(L);
156dbec5304Smbalmer   return old;
157dbec5304Smbalmer }
158dbec5304Smbalmer 
159dbec5304Smbalmer 
lua_version(lua_State * L)160f0dad708Snikita LUA_API lua_Number lua_version (lua_State *L) {
161f0dad708Snikita   UNUSED(L);
162f0dad708Snikita   return LUA_VERSION_NUM;
163dbec5304Smbalmer }
164dbec5304Smbalmer 
165dbec5304Smbalmer 
166dbec5304Smbalmer 
167dbec5304Smbalmer /*
168dbec5304Smbalmer ** basic stack manipulation
169dbec5304Smbalmer */
170dbec5304Smbalmer 
171dbec5304Smbalmer 
1724ab4902eSlneto /*
1734ab4902eSlneto ** convert an acceptable stack index into an absolute index
1744ab4902eSlneto */
lua_absindex(lua_State * L,int idx)1754ab4902eSlneto LUA_API int lua_absindex (lua_State *L, int idx) {
1764ab4902eSlneto   return (idx > 0 || ispseudo(idx))
1774ab4902eSlneto          ? idx
178*bdda0531Snikita          : cast_int(L->top.p - L->ci->func.p) + idx;
1794ab4902eSlneto }
1804ab4902eSlneto 
1814ab4902eSlneto 
lua_gettop(lua_State * L)182dbec5304Smbalmer LUA_API int lua_gettop (lua_State *L) {
183*bdda0531Snikita   return cast_int(L->top.p - (L->ci->func.p + 1));
184dbec5304Smbalmer }
185dbec5304Smbalmer 
186dbec5304Smbalmer 
lua_settop(lua_State * L,int idx)187dbec5304Smbalmer LUA_API void lua_settop (lua_State *L, int idx) {
188f0dad708Snikita   CallInfo *ci;
189f0dad708Snikita   StkId func, newtop;
190f0dad708Snikita   ptrdiff_t diff;  /* difference for new top */
191dbec5304Smbalmer   lua_lock(L);
192f0dad708Snikita   ci = L->ci;
193*bdda0531Snikita   func = ci->func.p;
194dbec5304Smbalmer   if (idx >= 0) {
195*bdda0531Snikita     api_check(L, idx <= ci->top.p - (func + 1), "new top too large");
196*bdda0531Snikita     diff = ((func + 1) + idx) - L->top.p;
197f0dad708Snikita     for (; diff > 0; diff--)
198*bdda0531Snikita       setnilvalue(s2v(L->top.p++));  /* clear new slots */
199dbec5304Smbalmer   }
200dbec5304Smbalmer   else {
201*bdda0531Snikita     api_check(L, -(idx+1) <= (L->top.p - (func + 1)), "invalid new top");
202f0dad708Snikita     diff = idx + 1;  /* will "subtract" index (as it is negative) */
203dbec5304Smbalmer   }
204*bdda0531Snikita   api_check(L, L->tbclist.p < L->top.p, "previous pop of an unclosed slot");
205*bdda0531Snikita   newtop = L->top.p + diff;
206*bdda0531Snikita   if (diff < 0 && L->tbclist.p >= newtop) {
207f0dad708Snikita     lua_assert(hastocloseCfunc(ci->nresults));
2086c647b81Snikita     newtop = luaF_close(L, newtop, CLOSEKTOP, 0);
209f0dad708Snikita   }
210*bdda0531Snikita   L->top.p = newtop;  /* correct top only after closing any upvalue */
211f0dad708Snikita   lua_unlock(L);
212f0dad708Snikita }
213f0dad708Snikita 
214f0dad708Snikita 
lua_closeslot(lua_State * L,int idx)215f0dad708Snikita LUA_API void lua_closeslot (lua_State *L, int idx) {
216f0dad708Snikita   StkId level;
217f0dad708Snikita   lua_lock(L);
218f0dad708Snikita   level = index2stack(L, idx);
219*bdda0531Snikita   api_check(L, hastocloseCfunc(L->ci->nresults) && L->tbclist.p == level,
220f0dad708Snikita      "no variable to close at given level");
2216c647b81Snikita   level = luaF_close(L, level, CLOSEKTOP, 0);
222f0dad708Snikita   setnilvalue(s2v(level));
223dbec5304Smbalmer   lua_unlock(L);
224dbec5304Smbalmer }
225dbec5304Smbalmer 
226dbec5304Smbalmer 
2274ab4902eSlneto /*
2284ab4902eSlneto ** Reverse the stack segment from 'from' to 'to'
22973008250Slneto ** (auxiliary to 'lua_rotate')
230f0dad708Snikita ** Note that we move(copy) only the value inside the stack.
231f0dad708Snikita ** (We do not move additional fields that may exist.)
2324ab4902eSlneto */
reverse(lua_State * L,StkId from,StkId to)233f0dad708Snikita l_sinline void reverse (lua_State *L, StkId from, StkId to) {
2344ab4902eSlneto   for (; from < to; from++, to--) {
2354ab4902eSlneto     TValue temp;
236f0dad708Snikita     setobj(L, &temp, s2v(from));
2374ab4902eSlneto     setobjs2s(L, from, to);
2384ab4902eSlneto     setobj2s(L, to, &temp);
2394ab4902eSlneto   }
2404ab4902eSlneto }
2414ab4902eSlneto 
2424ab4902eSlneto 
2434ab4902eSlneto /*
2444ab4902eSlneto ** Let x = AB, where A is a prefix of length 'n'. Then,
2454ab4902eSlneto ** rotate x n == BA. But BA == (A^r . B^r)^r.
2464ab4902eSlneto */
lua_rotate(lua_State * L,int idx,int n)2474ab4902eSlneto LUA_API void lua_rotate (lua_State *L, int idx, int n) {
2484ab4902eSlneto   StkId p, t, m;
249dbec5304Smbalmer   lua_lock(L);
250*bdda0531Snikita   t = L->top.p - 1;  /* end of stack segment being rotated */
251f0dad708Snikita   p = index2stack(L, idx);  /* start of segment */
252bee09862Smbalmer   api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
2534ab4902eSlneto   m = (n >= 0 ? t - n : p - n - 1);  /* end of prefix */
2544ab4902eSlneto   reverse(L, p, m);  /* reverse the prefix with length 'n' */
2554ab4902eSlneto   reverse(L, m + 1, t);  /* reverse the suffix */
2564ab4902eSlneto   reverse(L, p, t);  /* reverse the entire segment */
257dbec5304Smbalmer   lua_unlock(L);
258dbec5304Smbalmer }
259dbec5304Smbalmer 
260dbec5304Smbalmer 
lua_copy(lua_State * L,int fromidx,int toidx)26173008250Slneto LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
26273008250Slneto   TValue *fr, *to;
26373008250Slneto   lua_lock(L);
264f0dad708Snikita   fr = index2value(L, fromidx);
265f0dad708Snikita   to = index2value(L, toidx);
266f0dad708Snikita   api_check(L, isvalid(L, to), "invalid index");
2674ab4902eSlneto   setobj(L, to, fr);
26873008250Slneto   if (isupvalue(toidx))  /* function upvalue? */
269*bdda0531Snikita     luaC_barrier(L, clCvalue(s2v(L->ci->func.p)), fr);
2704ab4902eSlneto   /* LUA_REGISTRYINDEX does not need gc barrier
2714ab4902eSlneto      (collector revisits it before finishing collection) */
2724ab4902eSlneto   lua_unlock(L);
2734ab4902eSlneto }
2744ab4902eSlneto 
2754ab4902eSlneto 
lua_pushvalue(lua_State * L,int idx)276dbec5304Smbalmer LUA_API void lua_pushvalue (lua_State *L, int idx) {
277dbec5304Smbalmer   lua_lock(L);
278*bdda0531Snikita   setobj2s(L, L->top.p, index2value(L, idx));
279dbec5304Smbalmer   api_incr_top(L);
280dbec5304Smbalmer   lua_unlock(L);
281dbec5304Smbalmer }
282dbec5304Smbalmer 
283dbec5304Smbalmer 
284dbec5304Smbalmer 
285dbec5304Smbalmer /*
286dbec5304Smbalmer ** access functions (stack -> C)
287dbec5304Smbalmer */
288dbec5304Smbalmer 
289dbec5304Smbalmer 
lua_type(lua_State * L,int idx)290dbec5304Smbalmer LUA_API int lua_type (lua_State *L, int idx) {
291f0dad708Snikita   const TValue *o = index2value(L, idx);
292f0dad708Snikita   return (isvalid(L, o) ? ttype(o) : LUA_TNONE);
293dbec5304Smbalmer }
294dbec5304Smbalmer 
295dbec5304Smbalmer 
lua_typename(lua_State * L,int t)296dbec5304Smbalmer LUA_API const char *lua_typename (lua_State *L, int t) {
297dbec5304Smbalmer   UNUSED(L);
298f0dad708Snikita   api_check(L, LUA_TNONE <= t && t < LUA_NUMTYPES, "invalid type");
2994ab4902eSlneto   return ttypename(t);
300dbec5304Smbalmer }
301dbec5304Smbalmer 
302dbec5304Smbalmer 
lua_iscfunction(lua_State * L,int idx)303dbec5304Smbalmer LUA_API int lua_iscfunction (lua_State *L, int idx) {
304f0dad708Snikita   const TValue *o = index2value(L, idx);
3054ab4902eSlneto   return (ttislcf(o) || (ttisCclosure(o)));
3064ab4902eSlneto }
3074ab4902eSlneto 
3084ab4902eSlneto 
lua_isinteger(lua_State * L,int idx)3094ab4902eSlneto LUA_API int lua_isinteger (lua_State *L, int idx) {
310f0dad708Snikita   const TValue *o = index2value(L, idx);
3114ab4902eSlneto   return ttisinteger(o);
312dbec5304Smbalmer }
313dbec5304Smbalmer 
314dbec5304Smbalmer 
lua_isnumber(lua_State * L,int idx)31573008250Slneto LUA_API int lua_isnumber (lua_State *L, int idx) {
3164ab4902eSlneto   lua_Number n;
317f0dad708Snikita   const TValue *o = index2value(L, idx);
318dbec5304Smbalmer   return tonumber(o, &n);
319dbec5304Smbalmer }
320dbec5304Smbalmer 
321dbec5304Smbalmer 
lua_isstring(lua_State * L,int idx)322dbec5304Smbalmer LUA_API int lua_isstring (lua_State *L, int idx) {
323f0dad708Snikita   const TValue *o = index2value(L, idx);
32473008250Slneto   return (ttisstring(o) || cvt2str(o));
325dbec5304Smbalmer }
326dbec5304Smbalmer 
327dbec5304Smbalmer 
lua_isuserdata(lua_State * L,int idx)328dbec5304Smbalmer LUA_API int lua_isuserdata (lua_State *L, int idx) {
329f0dad708Snikita   const TValue *o = index2value(L, idx);
3304ab4902eSlneto   return (ttisfulluserdata(o) || ttislightuserdata(o));
331dbec5304Smbalmer }
332dbec5304Smbalmer 
333dbec5304Smbalmer 
lua_rawequal(lua_State * L,int index1,int index2)334dbec5304Smbalmer LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
335f0dad708Snikita   const TValue *o1 = index2value(L, index1);
336f0dad708Snikita   const TValue *o2 = index2value(L, index2);
337f0dad708Snikita   return (isvalid(L, o1) && isvalid(L, o2)) ? luaV_rawequalobj(o1, o2) : 0;
338dbec5304Smbalmer }
339dbec5304Smbalmer 
340dbec5304Smbalmer 
lua_arith(lua_State * L,int op)3414ab4902eSlneto LUA_API void lua_arith (lua_State *L, int op) {
3424ab4902eSlneto   lua_lock(L);
3434ab4902eSlneto   if (op != LUA_OPUNM && op != LUA_OPBNOT)
3444ab4902eSlneto     api_checknelems(L, 2);  /* all other operations expect two operands */
3454ab4902eSlneto   else {  /* for unary operations, add fake 2nd operand */
3464ab4902eSlneto     api_checknelems(L, 1);
347*bdda0531Snikita     setobjs2s(L, L->top.p, L->top.p - 1);
348bee09862Smbalmer     api_incr_top(L);
3494ab4902eSlneto   }
3504ab4902eSlneto   /* first operand at top - 2, second at top - 1; result go to top - 2 */
351*bdda0531Snikita   luaO_arith(L, op, s2v(L->top.p - 2), s2v(L->top.p - 1), L->top.p - 2);
352*bdda0531Snikita   L->top.p--;  /* remove second operand */
3534ab4902eSlneto   lua_unlock(L);
3544ab4902eSlneto }
3554ab4902eSlneto 
3564ab4902eSlneto 
lua_compare(lua_State * L,int index1,int index2,int op)3574ab4902eSlneto LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
358f0dad708Snikita   const TValue *o1;
359f0dad708Snikita   const TValue *o2;
3604ab4902eSlneto   int i = 0;
361dbec5304Smbalmer   lua_lock(L);  /* may call tag method */
362f0dad708Snikita   o1 = index2value(L, index1);
363f0dad708Snikita   o2 = index2value(L, index2);
364f0dad708Snikita   if (isvalid(L, o1) && isvalid(L, o2)) {
3654ab4902eSlneto     switch (op) {
3664ab4902eSlneto       case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break;
3674ab4902eSlneto       case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
3684ab4902eSlneto       case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
369bee09862Smbalmer       default: api_check(L, 0, "invalid option");
3704ab4902eSlneto     }
3714ab4902eSlneto   }
372dbec5304Smbalmer   lua_unlock(L);
373dbec5304Smbalmer   return i;
374dbec5304Smbalmer }
375dbec5304Smbalmer 
376dbec5304Smbalmer 
lua_stringtonumber(lua_State * L,const char * s)37773008250Slneto LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
378*bdda0531Snikita   size_t sz = luaO_str2num(s, s2v(L->top.p));
3794ab4902eSlneto   if (sz != 0)
3804ab4902eSlneto     api_incr_top(L);
3814ab4902eSlneto   return sz;
382dbec5304Smbalmer }
383dbec5304Smbalmer 
384dbec5304Smbalmer 
38573008250Slneto #ifndef _KERNEL
lua_tonumberx(lua_State * L,int idx,int * pisnum)3864ab4902eSlneto LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) {
387f0dad708Snikita   lua_Number n = 0;
388f0dad708Snikita   const TValue *o = index2value(L, idx);
3894ab4902eSlneto   int isnum = tonumber(o, &n);
390f0dad708Snikita   if (pisnum)
391f0dad708Snikita     *pisnum = isnum;
3924ab4902eSlneto   return n;
393dbec5304Smbalmer }
3942d6cb6c2Slneto #endif /* _KERNEL */
395dbec5304Smbalmer 
396dbec5304Smbalmer 
lua_tointegerx(lua_State * L,int idx,int * pisnum)3974ab4902eSlneto LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) {
398f0dad708Snikita   lua_Integer res = 0;
399f0dad708Snikita   const TValue *o = index2value(L, idx);
4004ab4902eSlneto   int isnum = tointeger(o, &res);
401f0dad708Snikita   if (pisnum)
402f0dad708Snikita     *pisnum = isnum;
403dbec5304Smbalmer   return res;
404dbec5304Smbalmer }
4054ab4902eSlneto 
4064ab4902eSlneto 
lua_toboolean(lua_State * L,int idx)407dbec5304Smbalmer LUA_API int lua_toboolean (lua_State *L, int idx) {
408f0dad708Snikita   const TValue *o = index2value(L, idx);
409dbec5304Smbalmer   return !l_isfalse(o);
410dbec5304Smbalmer }
411dbec5304Smbalmer 
412dbec5304Smbalmer 
lua_tolstring(lua_State * L,int idx,size_t * len)413dbec5304Smbalmer LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
414f0dad708Snikita   TValue *o;
415f0dad708Snikita   lua_lock(L);
416f0dad708Snikita   o = index2value(L, idx);
417dbec5304Smbalmer   if (!ttisstring(o)) {
41873008250Slneto     if (!cvt2str(o)) {  /* not convertible? */
419dbec5304Smbalmer       if (len != NULL) *len = 0;
420f0dad708Snikita       lua_unlock(L);
421dbec5304Smbalmer       return NULL;
422dbec5304Smbalmer     }
423c7f896d7Ssalazar     luaO_tostring(L, o);
424dbec5304Smbalmer     luaC_checkGC(L);
425f0dad708Snikita     o = index2value(L, idx);  /* previous call may reallocate the stack */
426dbec5304Smbalmer   }
427bee09862Smbalmer   if (len != NULL)
428bee09862Smbalmer     *len = vslen(o);
429f0dad708Snikita   lua_unlock(L);
430dbec5304Smbalmer   return svalue(o);
431dbec5304Smbalmer }
432dbec5304Smbalmer 
433dbec5304Smbalmer 
lua_rawlen(lua_State * L,int idx)434f0dad708Snikita LUA_API lua_Unsigned lua_rawlen (lua_State *L, int idx) {
435f0dad708Snikita   const TValue *o = index2value(L, idx);
436f0dad708Snikita   switch (ttypetag(o)) {
437f0dad708Snikita     case LUA_VSHRSTR: return tsvalue(o)->shrlen;
438f0dad708Snikita     case LUA_VLNGSTR: return tsvalue(o)->u.lnglen;
439f0dad708Snikita     case LUA_VUSERDATA: return uvalue(o)->len;
440f0dad708Snikita     case LUA_VTABLE: return luaH_getn(hvalue(o));
441dbec5304Smbalmer     default: return 0;
442dbec5304Smbalmer   }
443dbec5304Smbalmer }
444dbec5304Smbalmer 
445dbec5304Smbalmer 
lua_tocfunction(lua_State * L,int idx)446dbec5304Smbalmer LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
447f0dad708Snikita   const TValue *o = index2value(L, idx);
4484ab4902eSlneto   if (ttislcf(o)) return fvalue(o);
4494ab4902eSlneto   else if (ttisCclosure(o))
4504ab4902eSlneto     return clCvalue(o)->f;
4514ab4902eSlneto   else return NULL;  /* not a C function */
452dbec5304Smbalmer }
453dbec5304Smbalmer 
454dbec5304Smbalmer 
touserdata(const TValue * o)455f0dad708Snikita l_sinline void *touserdata (const TValue *o) {
456f0dad708Snikita   switch (ttype(o)) {
45773008250Slneto     case LUA_TUSERDATA: return getudatamem(uvalue(o));
458dbec5304Smbalmer     case LUA_TLIGHTUSERDATA: return pvalue(o);
459dbec5304Smbalmer     default: return NULL;
460dbec5304Smbalmer   }
461dbec5304Smbalmer }
462dbec5304Smbalmer 
463dbec5304Smbalmer 
lua_touserdata(lua_State * L,int idx)464f0dad708Snikita LUA_API void *lua_touserdata (lua_State *L, int idx) {
465f0dad708Snikita   const TValue *o = index2value(L, idx);
466f0dad708Snikita   return touserdata(o);
467f0dad708Snikita }
468f0dad708Snikita 
469f0dad708Snikita 
lua_tothread(lua_State * L,int idx)470dbec5304Smbalmer LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
471f0dad708Snikita   const TValue *o = index2value(L, idx);
472dbec5304Smbalmer   return (!ttisthread(o)) ? NULL : thvalue(o);
473dbec5304Smbalmer }
474dbec5304Smbalmer 
475dbec5304Smbalmer 
476f0dad708Snikita /*
477f0dad708Snikita ** Returns a pointer to the internal representation of an object.
478f0dad708Snikita ** Note that ANSI C does not allow the conversion of a pointer to
479f0dad708Snikita ** function to a 'void*', so the conversion here goes through
480f0dad708Snikita ** a 'size_t'. (As the returned pointer is only informative, this
481f0dad708Snikita ** conversion should not be a problem.)
482f0dad708Snikita */
lua_topointer(lua_State * L,int idx)483dbec5304Smbalmer LUA_API const void *lua_topointer (lua_State *L, int idx) {
484f0dad708Snikita   const TValue *o = index2value(L, idx);
485f0dad708Snikita   switch (ttypetag(o)) {
486f0dad708Snikita     case LUA_VLCF: return cast_voidp(cast_sizet(fvalue(o)));
487f0dad708Snikita     case LUA_VUSERDATA: case LUA_VLIGHTUSERDATA:
488f0dad708Snikita       return touserdata(o);
489f0dad708Snikita     default: {
490f0dad708Snikita       if (iscollectable(o))
491f0dad708Snikita         return gcvalue(o);
492f0dad708Snikita       else
493f0dad708Snikita         return NULL;
494f0dad708Snikita     }
495dbec5304Smbalmer   }
496dbec5304Smbalmer }
497dbec5304Smbalmer 
498dbec5304Smbalmer 
499dbec5304Smbalmer 
500dbec5304Smbalmer /*
501dbec5304Smbalmer ** push functions (C -> stack)
502dbec5304Smbalmer */
503dbec5304Smbalmer 
504dbec5304Smbalmer 
lua_pushnil(lua_State * L)505dbec5304Smbalmer LUA_API void lua_pushnil (lua_State *L) {
506dbec5304Smbalmer   lua_lock(L);
507*bdda0531Snikita   setnilvalue(s2v(L->top.p));
508dbec5304Smbalmer   api_incr_top(L);
509dbec5304Smbalmer   lua_unlock(L);
510dbec5304Smbalmer }
511dbec5304Smbalmer 
512dbec5304Smbalmer 
51373008250Slneto #ifndef _KERNEL
lua_pushnumber(lua_State * L,lua_Number n)514dbec5304Smbalmer LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
515dbec5304Smbalmer   lua_lock(L);
516*bdda0531Snikita   setfltvalue(s2v(L->top.p), n);
517dbec5304Smbalmer   api_incr_top(L);
518dbec5304Smbalmer   lua_unlock(L);
519dbec5304Smbalmer }
5202d6cb6c2Slneto #endif /* _KERNEL */
521dbec5304Smbalmer 
522dbec5304Smbalmer 
lua_pushinteger(lua_State * L,lua_Integer n)523dbec5304Smbalmer LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
524dbec5304Smbalmer   lua_lock(L);
525*bdda0531Snikita   setivalue(s2v(L->top.p), n);
526dbec5304Smbalmer   api_incr_top(L);
527dbec5304Smbalmer   lua_unlock(L);
528dbec5304Smbalmer }
529dbec5304Smbalmer 
530dbec5304Smbalmer 
5312d6cb6c2Slneto /*
5322d6cb6c2Slneto ** Pushes on the stack a string with given length. Avoid using 's' when
5332d6cb6c2Slneto ** 'len' == 0 (as 's' can be NULL in that case), due to later use of
5342d6cb6c2Slneto ** 'memcmp' and 'memcpy'.
5352d6cb6c2Slneto */
lua_pushlstring(lua_State * L,const char * s,size_t len)5364ab4902eSlneto LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
5374ab4902eSlneto   TString *ts;
538dbec5304Smbalmer   lua_lock(L);
5392d6cb6c2Slneto   ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len);
540*bdda0531Snikita   setsvalue2s(L, L->top.p, ts);
541dbec5304Smbalmer   api_incr_top(L);
542c7f896d7Ssalazar   luaC_checkGC(L);
543dbec5304Smbalmer   lua_unlock(L);
5444ab4902eSlneto   return getstr(ts);
545dbec5304Smbalmer }
546dbec5304Smbalmer 
547dbec5304Smbalmer 
lua_pushstring(lua_State * L,const char * s)5484ab4902eSlneto LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
549bee09862Smbalmer   lua_lock(L);
550bee09862Smbalmer   if (s == NULL)
551*bdda0531Snikita     setnilvalue(s2v(L->top.p));
5524ab4902eSlneto   else {
5534ab4902eSlneto     TString *ts;
5544ab4902eSlneto     ts = luaS_new(L, s);
555*bdda0531Snikita     setsvalue2s(L, L->top.p, ts);
556bee09862Smbalmer     s = getstr(ts);  /* internal copy's address */
557bee09862Smbalmer   }
5584ab4902eSlneto   api_incr_top(L);
559c7f896d7Ssalazar   luaC_checkGC(L);
5604ab4902eSlneto   lua_unlock(L);
561bee09862Smbalmer   return s;
562dbec5304Smbalmer }
563dbec5304Smbalmer 
564dbec5304Smbalmer 
lua_pushvfstring(lua_State * L,const char * fmt,va_list argp)565dbec5304Smbalmer LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
566dbec5304Smbalmer                                       va_list argp) {
567dbec5304Smbalmer   const char *ret;
568dbec5304Smbalmer   lua_lock(L);
569dbec5304Smbalmer   ret = luaO_pushvfstring(L, fmt, argp);
570c7f896d7Ssalazar   luaC_checkGC(L);
571dbec5304Smbalmer   lua_unlock(L);
572dbec5304Smbalmer   return ret;
573dbec5304Smbalmer }
574dbec5304Smbalmer 
575dbec5304Smbalmer 
lua_pushfstring(lua_State * L,const char * fmt,...)576dbec5304Smbalmer LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
577dbec5304Smbalmer   const char *ret;
578dbec5304Smbalmer   va_list argp;
579dbec5304Smbalmer   lua_lock(L);
580dbec5304Smbalmer   va_start(argp, fmt);
581dbec5304Smbalmer   ret = luaO_pushvfstring(L, fmt, argp);
582dbec5304Smbalmer   va_end(argp);
583c7f896d7Ssalazar   luaC_checkGC(L);
584dbec5304Smbalmer   lua_unlock(L);
585dbec5304Smbalmer   return ret;
586dbec5304Smbalmer }
587dbec5304Smbalmer 
588dbec5304Smbalmer 
lua_pushcclosure(lua_State * L,lua_CFunction fn,int n)589dbec5304Smbalmer LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
590dbec5304Smbalmer   lua_lock(L);
5914ab4902eSlneto   if (n == 0) {
592*bdda0531Snikita     setfvalue(s2v(L->top.p), fn);
5930f9874acSmbalmer     api_incr_top(L);
5944ab4902eSlneto   }
5954ab4902eSlneto   else {
5964ab4902eSlneto     CClosure *cl;
597dbec5304Smbalmer     api_checknelems(L, n);
598bee09862Smbalmer     api_check(L, n <= MAXUPVAL, "upvalue index too large");
5994ab4902eSlneto     cl = luaF_newCclosure(L, n);
6004ab4902eSlneto     cl->f = fn;
601*bdda0531Snikita     L->top.p -= n;
6024ab4902eSlneto     while (n--) {
603*bdda0531Snikita       setobj2n(L, &cl->upvalue[n], s2v(L->top.p + n));
6044ab4902eSlneto       /* does not need barrier because closure is white */
605f0dad708Snikita       lua_assert(iswhite(cl));
6064ab4902eSlneto     }
607*bdda0531Snikita     setclCvalue(L, s2v(L->top.p), cl);
608dbec5304Smbalmer     api_incr_top(L);
609c7f896d7Ssalazar     luaC_checkGC(L);
6100f9874acSmbalmer   }
611dbec5304Smbalmer   lua_unlock(L);
612dbec5304Smbalmer }
613dbec5304Smbalmer 
614dbec5304Smbalmer 
lua_pushboolean(lua_State * L,int b)615dbec5304Smbalmer LUA_API void lua_pushboolean (lua_State *L, int b) {
616dbec5304Smbalmer   lua_lock(L);
617f0dad708Snikita   if (b)
618*bdda0531Snikita     setbtvalue(s2v(L->top.p));
619f0dad708Snikita   else
620*bdda0531Snikita     setbfvalue(s2v(L->top.p));
621dbec5304Smbalmer   api_incr_top(L);
622dbec5304Smbalmer   lua_unlock(L);
623dbec5304Smbalmer }
624dbec5304Smbalmer 
625dbec5304Smbalmer 
lua_pushlightuserdata(lua_State * L,void * p)626dbec5304Smbalmer LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
627dbec5304Smbalmer   lua_lock(L);
628*bdda0531Snikita   setpvalue(s2v(L->top.p), p);
629dbec5304Smbalmer   api_incr_top(L);
630dbec5304Smbalmer   lua_unlock(L);
631dbec5304Smbalmer }
632dbec5304Smbalmer 
633dbec5304Smbalmer 
lua_pushthread(lua_State * L)634dbec5304Smbalmer LUA_API int lua_pushthread (lua_State *L) {
635dbec5304Smbalmer   lua_lock(L);
636*bdda0531Snikita   setthvalue(L, s2v(L->top.p), L);
637dbec5304Smbalmer   api_incr_top(L);
638dbec5304Smbalmer   lua_unlock(L);
639dbec5304Smbalmer   return (G(L)->mainthread == L);
640dbec5304Smbalmer }
641dbec5304Smbalmer 
642dbec5304Smbalmer 
643dbec5304Smbalmer 
644dbec5304Smbalmer /*
645dbec5304Smbalmer ** get functions (Lua -> stack)
646dbec5304Smbalmer */
647dbec5304Smbalmer 
648dbec5304Smbalmer 
auxgetstr(lua_State * L,const TValue * t,const char * k)649f0dad708Snikita l_sinline int auxgetstr (lua_State *L, const TValue *t, const char *k) {
650c7f896d7Ssalazar   const TValue *slot;
6512d6cb6c2Slneto   TString *str = luaS_new(L, k);
652c7f896d7Ssalazar   if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
653*bdda0531Snikita     setobj2s(L, L->top.p, slot);
654bee09862Smbalmer     api_incr_top(L);
6552d6cb6c2Slneto   }
6562d6cb6c2Slneto   else {
657*bdda0531Snikita     setsvalue2s(L, L->top.p, str);
6582d6cb6c2Slneto     api_incr_top(L);
659*bdda0531Snikita     luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, slot);
6602d6cb6c2Slneto   }
6614ab4902eSlneto   lua_unlock(L);
662*bdda0531Snikita   return ttype(s2v(L->top.p - 1));
6634ab4902eSlneto }
6644ab4902eSlneto 
6654ab4902eSlneto 
666f0dad708Snikita /*
667f0dad708Snikita ** Get the global table in the registry. Since all predefined
668f0dad708Snikita ** indices in the registry were inserted right when the registry
669f0dad708Snikita ** was created and never removed, they must always be in the array
670f0dad708Snikita ** part of the registry.
671f0dad708Snikita */
672f0dad708Snikita #define getGtable(L)  \
673f0dad708Snikita 	(&hvalue(&G(L)->l_registry)->array[LUA_RIDX_GLOBALS - 1])
674f0dad708Snikita 
675f0dad708Snikita 
lua_getglobal(lua_State * L,const char * name)6762d6cb6c2Slneto LUA_API int lua_getglobal (lua_State *L, const char *name) {
677f0dad708Snikita   const TValue *G;
6782d6cb6c2Slneto   lua_lock(L);
679f0dad708Snikita   G = getGtable(L);
680f0dad708Snikita   return auxgetstr(L, G, name);
6812d6cb6c2Slneto }
6822d6cb6c2Slneto 
6832d6cb6c2Slneto 
lua_gettable(lua_State * L,int idx)6844ab4902eSlneto LUA_API int lua_gettable (lua_State *L, int idx) {
685f0dad708Snikita   const TValue *slot;
686f0dad708Snikita   TValue *t;
687dbec5304Smbalmer   lua_lock(L);
688f0dad708Snikita   t = index2value(L, idx);
689*bdda0531Snikita   if (luaV_fastget(L, t, s2v(L->top.p - 1), slot, luaH_get)) {
690*bdda0531Snikita     setobj2s(L, L->top.p - 1, slot);
691f0dad708Snikita   }
692f0dad708Snikita   else
693*bdda0531Snikita     luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, slot);
694dbec5304Smbalmer   lua_unlock(L);
695*bdda0531Snikita   return ttype(s2v(L->top.p - 1));
696dbec5304Smbalmer }
697dbec5304Smbalmer 
698dbec5304Smbalmer 
lua_getfield(lua_State * L,int idx,const char * k)6994ab4902eSlneto LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
700dbec5304Smbalmer   lua_lock(L);
701f0dad708Snikita   return auxgetstr(L, index2value(L, idx), k);
702dbec5304Smbalmer }
703dbec5304Smbalmer 
704dbec5304Smbalmer 
lua_geti(lua_State * L,int idx,lua_Integer n)70573008250Slneto LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
706f0dad708Snikita   TValue *t;
707c7f896d7Ssalazar   const TValue *slot;
70873008250Slneto   lua_lock(L);
709f0dad708Snikita   t = index2value(L, idx);
710f0dad708Snikita   if (luaV_fastgeti(L, t, n, slot)) {
711*bdda0531Snikita     setobj2s(L, L->top.p, slot);
7122d6cb6c2Slneto   }
7132d6cb6c2Slneto   else {
714f0dad708Snikita     TValue aux;
715f0dad708Snikita     setivalue(&aux, n);
716*bdda0531Snikita     luaV_finishget(L, t, &aux, L->top.p, slot);
7172d6cb6c2Slneto   }
718f0dad708Snikita   api_incr_top(L);
71973008250Slneto   lua_unlock(L);
720*bdda0531Snikita   return ttype(s2v(L->top.p - 1));
721f0dad708Snikita }
722f0dad708Snikita 
723f0dad708Snikita 
finishrawget(lua_State * L,const TValue * val)724f0dad708Snikita l_sinline int finishrawget (lua_State *L, const TValue *val) {
725f0dad708Snikita   if (isempty(val))  /* avoid copying empty items to the stack */
726*bdda0531Snikita     setnilvalue(s2v(L->top.p));
727f0dad708Snikita   else
728*bdda0531Snikita     setobj2s(L, L->top.p, val);
729f0dad708Snikita   api_incr_top(L);
730f0dad708Snikita   lua_unlock(L);
731*bdda0531Snikita   return ttype(s2v(L->top.p - 1));
732f0dad708Snikita }
733f0dad708Snikita 
734f0dad708Snikita 
gettable(lua_State * L,int idx)735f0dad708Snikita static Table *gettable (lua_State *L, int idx) {
736f0dad708Snikita   TValue *t = index2value(L, idx);
737f0dad708Snikita   api_check(L, ttistable(t), "table expected");
738f0dad708Snikita   return hvalue(t);
73973008250Slneto }
74073008250Slneto 
74173008250Slneto 
lua_rawget(lua_State * L,int idx)7424ab4902eSlneto LUA_API int lua_rawget (lua_State *L, int idx) {
743f0dad708Snikita   Table *t;
744f0dad708Snikita   const TValue *val;
745dbec5304Smbalmer   lua_lock(L);
746f0dad708Snikita   api_checknelems(L, 1);
747f0dad708Snikita   t = gettable(L, idx);
748*bdda0531Snikita   val = luaH_get(t, s2v(L->top.p - 1));
749*bdda0531Snikita   L->top.p--;  /* remove key */
750f0dad708Snikita   return finishrawget(L, val);
751dbec5304Smbalmer }
752dbec5304Smbalmer 
753dbec5304Smbalmer 
lua_rawgeti(lua_State * L,int idx,lua_Integer n)7544ab4902eSlneto LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
755f0dad708Snikita   Table *t;
756dbec5304Smbalmer   lua_lock(L);
757f0dad708Snikita   t = gettable(L, idx);
758f0dad708Snikita   return finishrawget(L, luaH_getint(t, n));
7594ab4902eSlneto }
7604ab4902eSlneto 
7614ab4902eSlneto 
lua_rawgetp(lua_State * L,int idx,const void * p)7624ab4902eSlneto LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
763f0dad708Snikita   Table *t;
7644ab4902eSlneto   TValue k;
7654ab4902eSlneto   lua_lock(L);
766f0dad708Snikita   t = gettable(L, idx);
767f0dad708Snikita   setpvalue(&k, cast_voidp(p));
768f0dad708Snikita   return finishrawget(L, luaH_get(t, &k));
769dbec5304Smbalmer }
770dbec5304Smbalmer 
771dbec5304Smbalmer 
lua_createtable(lua_State * L,int narray,int nrec)772dbec5304Smbalmer LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
7734ab4902eSlneto   Table *t;
774dbec5304Smbalmer   lua_lock(L);
7754ab4902eSlneto   t = luaH_new(L);
776*bdda0531Snikita   sethvalue2s(L, L->top.p, t);
777dbec5304Smbalmer   api_incr_top(L);
7784ab4902eSlneto   if (narray > 0 || nrec > 0)
7794ab4902eSlneto     luaH_resize(L, t, narray, nrec);
780c7f896d7Ssalazar   luaC_checkGC(L);
781dbec5304Smbalmer   lua_unlock(L);
782dbec5304Smbalmer }
783dbec5304Smbalmer 
784dbec5304Smbalmer 
lua_getmetatable(lua_State * L,int objindex)785dbec5304Smbalmer LUA_API int lua_getmetatable (lua_State *L, int objindex) {
786dbec5304Smbalmer   const TValue *obj;
78773008250Slneto   Table *mt;
78873008250Slneto   int res = 0;
789dbec5304Smbalmer   lua_lock(L);
790f0dad708Snikita   obj = index2value(L, objindex);
791f0dad708Snikita   switch (ttype(obj)) {
792dbec5304Smbalmer     case LUA_TTABLE:
793dbec5304Smbalmer       mt = hvalue(obj)->metatable;
794dbec5304Smbalmer       break;
795dbec5304Smbalmer     case LUA_TUSERDATA:
796dbec5304Smbalmer       mt = uvalue(obj)->metatable;
797dbec5304Smbalmer       break;
798dbec5304Smbalmer     default:
799f0dad708Snikita       mt = G(L)->mt[ttype(obj)];
800dbec5304Smbalmer       break;
801dbec5304Smbalmer   }
80273008250Slneto   if (mt != NULL) {
803*bdda0531Snikita     sethvalue2s(L, L->top.p, mt);
804dbec5304Smbalmer     api_incr_top(L);
805dbec5304Smbalmer     res = 1;
806dbec5304Smbalmer   }
807dbec5304Smbalmer   lua_unlock(L);
808dbec5304Smbalmer   return res;
809dbec5304Smbalmer }
810dbec5304Smbalmer 
811dbec5304Smbalmer 
lua_getiuservalue(lua_State * L,int idx,int n)812f0dad708Snikita LUA_API int lua_getiuservalue (lua_State *L, int idx, int n) {
813f0dad708Snikita   TValue *o;
814f0dad708Snikita   int t;
815dbec5304Smbalmer   lua_lock(L);
816f0dad708Snikita   o = index2value(L, idx);
817bee09862Smbalmer   api_check(L, ttisfulluserdata(o), "full userdata expected");
818f0dad708Snikita   if (n <= 0 || n > uvalue(o)->nuvalue) {
819*bdda0531Snikita     setnilvalue(s2v(L->top.p));
820f0dad708Snikita     t = LUA_TNONE;
821f0dad708Snikita   }
822f0dad708Snikita   else {
823*bdda0531Snikita     setobj2s(L, L->top.p, &uvalue(o)->uv[n - 1].uv);
824*bdda0531Snikita     t = ttype(s2v(L->top.p));
825f0dad708Snikita   }
826dbec5304Smbalmer   api_incr_top(L);
827dbec5304Smbalmer   lua_unlock(L);
828f0dad708Snikita   return t;
829dbec5304Smbalmer }
830dbec5304Smbalmer 
831dbec5304Smbalmer 
832dbec5304Smbalmer /*
833dbec5304Smbalmer ** set functions (stack -> Lua)
834dbec5304Smbalmer */
835dbec5304Smbalmer 
8362d6cb6c2Slneto /*
8372d6cb6c2Slneto ** t[k] = value at the top of the stack (where 'k' is a string)
8382d6cb6c2Slneto */
auxsetstr(lua_State * L,const TValue * t,const char * k)8392d6cb6c2Slneto static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
840c7f896d7Ssalazar   const TValue *slot;
8412d6cb6c2Slneto   TString *str = luaS_new(L, k);
8422d6cb6c2Slneto   api_checknelems(L, 1);
843f0dad708Snikita   if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
844*bdda0531Snikita     luaV_finishfastset(L, t, slot, s2v(L->top.p - 1));
845*bdda0531Snikita     L->top.p--;  /* pop value */
846f0dad708Snikita   }
8472d6cb6c2Slneto   else {
848*bdda0531Snikita     setsvalue2s(L, L->top.p, str);  /* push 'str' (to make it a TValue) */
8492d6cb6c2Slneto     api_incr_top(L);
850*bdda0531Snikita     luaV_finishset(L, t, s2v(L->top.p - 1), s2v(L->top.p - 2), slot);
851*bdda0531Snikita     L->top.p -= 2;  /* pop value and key */
8522d6cb6c2Slneto   }
8532d6cb6c2Slneto   lua_unlock(L);  /* lock done by caller */
8542d6cb6c2Slneto }
8552d6cb6c2Slneto 
856dbec5304Smbalmer 
lua_setglobal(lua_State * L,const char * name)85773008250Slneto LUA_API void lua_setglobal (lua_State *L, const char *name) {
858f0dad708Snikita   const TValue *G;
8592d6cb6c2Slneto   lua_lock(L);  /* unlock done in 'auxsetstr' */
860f0dad708Snikita   G = getGtable(L);
861f0dad708Snikita   auxsetstr(L, G, name);
8624ab4902eSlneto }
8634ab4902eSlneto 
8644ab4902eSlneto 
lua_settable(lua_State * L,int idx)865dbec5304Smbalmer LUA_API void lua_settable (lua_State *L, int idx) {
866f0dad708Snikita   TValue *t;
867f0dad708Snikita   const TValue *slot;
868dbec5304Smbalmer   lua_lock(L);
869dbec5304Smbalmer   api_checknelems(L, 2);
870f0dad708Snikita   t = index2value(L, idx);
871*bdda0531Snikita   if (luaV_fastget(L, t, s2v(L->top.p - 2), slot, luaH_get)) {
872*bdda0531Snikita     luaV_finishfastset(L, t, slot, s2v(L->top.p - 1));
873f0dad708Snikita   }
874f0dad708Snikita   else
875*bdda0531Snikita     luaV_finishset(L, t, s2v(L->top.p - 2), s2v(L->top.p - 1), slot);
876*bdda0531Snikita   L->top.p -= 2;  /* pop index and value */
877dbec5304Smbalmer   lua_unlock(L);
878dbec5304Smbalmer }
879dbec5304Smbalmer 
880dbec5304Smbalmer 
lua_setfield(lua_State * L,int idx,const char * k)881dbec5304Smbalmer LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
8822d6cb6c2Slneto   lua_lock(L);  /* unlock done in 'auxsetstr' */
883f0dad708Snikita   auxsetstr(L, index2value(L, idx), k);
884dbec5304Smbalmer }
885dbec5304Smbalmer 
886dbec5304Smbalmer 
lua_seti(lua_State * L,int idx,lua_Integer n)88773008250Slneto LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
888f0dad708Snikita   TValue *t;
889c7f896d7Ssalazar   const TValue *slot;
890dbec5304Smbalmer   lua_lock(L);
89173008250Slneto   api_checknelems(L, 1);
892f0dad708Snikita   t = index2value(L, idx);
893f0dad708Snikita   if (luaV_fastgeti(L, t, n, slot)) {
894*bdda0531Snikita     luaV_finishfastset(L, t, slot, s2v(L->top.p - 1));
8952d6cb6c2Slneto   }
896f0dad708Snikita   else {
897f0dad708Snikita     TValue aux;
898f0dad708Snikita     setivalue(&aux, n);
899*bdda0531Snikita     luaV_finishset(L, t, &aux, s2v(L->top.p - 1), slot);
900f0dad708Snikita   }
901*bdda0531Snikita   L->top.p--;  /* pop value */
902f0dad708Snikita   lua_unlock(L);
903f0dad708Snikita }
904f0dad708Snikita 
905f0dad708Snikita 
aux_rawset(lua_State * L,int idx,TValue * key,int n)906f0dad708Snikita static void aux_rawset (lua_State *L, int idx, TValue *key, int n) {
907f0dad708Snikita   Table *t;
908f0dad708Snikita   lua_lock(L);
909f0dad708Snikita   api_checknelems(L, n);
910f0dad708Snikita   t = gettable(L, idx);
911*bdda0531Snikita   luaH_set(L, t, key, s2v(L->top.p - 1));
912f0dad708Snikita   invalidateTMcache(t);
913*bdda0531Snikita   luaC_barrierback(L, obj2gco(t), s2v(L->top.p - 1));
914*bdda0531Snikita   L->top.p -= n;
91573008250Slneto   lua_unlock(L);
91673008250Slneto }
91773008250Slneto 
91873008250Slneto 
lua_rawset(lua_State * L,int idx)91973008250Slneto LUA_API void lua_rawset (lua_State *L, int idx) {
920*bdda0531Snikita   aux_rawset(L, idx, s2v(L->top.p - 2), 2);
9214ab4902eSlneto }
9224ab4902eSlneto 
9234ab4902eSlneto 
lua_rawsetp(lua_State * L,int idx,const void * p)9244ab4902eSlneto LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
925f0dad708Snikita   TValue k;
926f0dad708Snikita   setpvalue(&k, cast_voidp(p));
927f0dad708Snikita   aux_rawset(L, idx, &k, 1);
928f0dad708Snikita }
929f0dad708Snikita 
930f0dad708Snikita 
lua_rawseti(lua_State * L,int idx,lua_Integer n)931f0dad708Snikita LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
932f0dad708Snikita   Table *t;
9334ab4902eSlneto   lua_lock(L);
9344ab4902eSlneto   api_checknelems(L, 1);
935f0dad708Snikita   t = gettable(L, idx);
936*bdda0531Snikita   luaH_setint(L, t, n, s2v(L->top.p - 1));
937*bdda0531Snikita   luaC_barrierback(L, obj2gco(t), s2v(L->top.p - 1));
938*bdda0531Snikita   L->top.p--;
939dbec5304Smbalmer   lua_unlock(L);
940dbec5304Smbalmer }
941dbec5304Smbalmer 
942dbec5304Smbalmer 
lua_setmetatable(lua_State * L,int objindex)943dbec5304Smbalmer LUA_API int lua_setmetatable (lua_State *L, int objindex) {
944dbec5304Smbalmer   TValue *obj;
945dbec5304Smbalmer   Table *mt;
946dbec5304Smbalmer   lua_lock(L);
947dbec5304Smbalmer   api_checknelems(L, 1);
948f0dad708Snikita   obj = index2value(L, objindex);
949*bdda0531Snikita   if (ttisnil(s2v(L->top.p - 1)))
950dbec5304Smbalmer     mt = NULL;
951dbec5304Smbalmer   else {
952*bdda0531Snikita     api_check(L, ttistable(s2v(L->top.p - 1)), "table expected");
953*bdda0531Snikita     mt = hvalue(s2v(L->top.p - 1));
954dbec5304Smbalmer   }
955f0dad708Snikita   switch (ttype(obj)) {
956dbec5304Smbalmer     case LUA_TTABLE: {
957dbec5304Smbalmer       hvalue(obj)->metatable = mt;
9584ab4902eSlneto       if (mt) {
9594ab4902eSlneto         luaC_objbarrier(L, gcvalue(obj), mt);
9604ab4902eSlneto         luaC_checkfinalizer(L, gcvalue(obj), mt);
9614ab4902eSlneto       }
962dbec5304Smbalmer       break;
963dbec5304Smbalmer     }
964dbec5304Smbalmer     case LUA_TUSERDATA: {
965dbec5304Smbalmer       uvalue(obj)->metatable = mt;
9664ab4902eSlneto       if (mt) {
96773008250Slneto         luaC_objbarrier(L, uvalue(obj), mt);
9684ab4902eSlneto         luaC_checkfinalizer(L, gcvalue(obj), mt);
9694ab4902eSlneto       }
970dbec5304Smbalmer       break;
971dbec5304Smbalmer     }
972dbec5304Smbalmer     default: {
973f0dad708Snikita       G(L)->mt[ttype(obj)] = mt;
974dbec5304Smbalmer       break;
975dbec5304Smbalmer     }
976dbec5304Smbalmer   }
977*bdda0531Snikita   L->top.p--;
978dbec5304Smbalmer   lua_unlock(L);
979dbec5304Smbalmer   return 1;
980dbec5304Smbalmer }
981dbec5304Smbalmer 
982dbec5304Smbalmer 
lua_setiuservalue(lua_State * L,int idx,int n)983f0dad708Snikita LUA_API int lua_setiuservalue (lua_State *L, int idx, int n) {
984f0dad708Snikita   TValue *o;
985f0dad708Snikita   int res;
986dbec5304Smbalmer   lua_lock(L);
987dbec5304Smbalmer   api_checknelems(L, 1);
988f0dad708Snikita   o = index2value(L, idx);
989bee09862Smbalmer   api_check(L, ttisfulluserdata(o), "full userdata expected");
990f0dad708Snikita   if (!(cast_uint(n) - 1u < cast_uint(uvalue(o)->nuvalue)))
991f0dad708Snikita     res = 0;  /* 'n' not in [1, uvalue(o)->nuvalue] */
992f0dad708Snikita   else {
993*bdda0531Snikita     setobj(L, &uvalue(o)->uv[n - 1].uv, s2v(L->top.p - 1));
994*bdda0531Snikita     luaC_barrierback(L, gcvalue(o), s2v(L->top.p - 1));
995f0dad708Snikita     res = 1;
996f0dad708Snikita   }
997*bdda0531Snikita   L->top.p--;
998dbec5304Smbalmer   lua_unlock(L);
999f0dad708Snikita   return res;
1000dbec5304Smbalmer }
1001dbec5304Smbalmer 
1002dbec5304Smbalmer 
1003dbec5304Smbalmer /*
100473008250Slneto ** 'load' and 'call' functions (run Lua code)
1005dbec5304Smbalmer */
1006dbec5304Smbalmer 
1007dbec5304Smbalmer 
1008dbec5304Smbalmer #define checkresults(L,na,nr) \
1009*bdda0531Snikita      api_check(L, (nr) == LUA_MULTRET \
1010*bdda0531Snikita                || (L->ci->top.p - L->top.p >= (nr) - (na)), \
10114ab4902eSlneto 	"results from function overflow current stack size")
1012dbec5304Smbalmer 
1013dbec5304Smbalmer 
lua_callk(lua_State * L,int nargs,int nresults,lua_KContext ctx,lua_KFunction k)101473008250Slneto LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
101573008250Slneto                         lua_KContext ctx, lua_KFunction k) {
1016dbec5304Smbalmer   StkId func;
1017dbec5304Smbalmer   lua_lock(L);
1018bee09862Smbalmer   api_check(L, k == NULL || !isLua(L->ci),
10194ab4902eSlneto     "cannot use continuations inside hooks");
1020dbec5304Smbalmer   api_checknelems(L, nargs+1);
1021bee09862Smbalmer   api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
1022dbec5304Smbalmer   checkresults(L, nargs, nresults);
1023*bdda0531Snikita   func = L->top.p - (nargs+1);
1024f0dad708Snikita   if (k != NULL && yieldable(L)) {  /* need to prepare continuation? */
10254ab4902eSlneto     L->ci->u.c.k = k;  /* save continuation */
10264ab4902eSlneto     L->ci->u.c.ctx = ctx;  /* save context */
10272d6cb6c2Slneto     luaD_call(L, func, nresults);  /* do the call */
10284ab4902eSlneto   }
10294ab4902eSlneto   else  /* no continuation or no yieldable */
10302d6cb6c2Slneto     luaD_callnoyield(L, func, nresults);  /* just do the call */
1031dbec5304Smbalmer   adjustresults(L, nresults);
1032dbec5304Smbalmer   lua_unlock(L);
1033dbec5304Smbalmer }
1034dbec5304Smbalmer 
1035dbec5304Smbalmer 
1036dbec5304Smbalmer 
1037dbec5304Smbalmer /*
1038dbec5304Smbalmer ** Execute a protected call.
1039dbec5304Smbalmer */
104073008250Slneto struct CallS {  /* data to 'f_call' */
1041dbec5304Smbalmer   StkId func;
1042dbec5304Smbalmer   int nresults;
1043dbec5304Smbalmer };
1044dbec5304Smbalmer 
1045dbec5304Smbalmer 
f_call(lua_State * L,void * ud)1046dbec5304Smbalmer static void f_call (lua_State *L, void *ud) {
1047dbec5304Smbalmer   struct CallS *c = cast(struct CallS *, ud);
10482d6cb6c2Slneto   luaD_callnoyield(L, c->func, c->nresults);
1049dbec5304Smbalmer }
1050dbec5304Smbalmer 
1051dbec5304Smbalmer 
1052dbec5304Smbalmer 
lua_pcallk(lua_State * L,int nargs,int nresults,int errfunc,lua_KContext ctx,lua_KFunction k)10534ab4902eSlneto LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
105473008250Slneto                         lua_KContext ctx, lua_KFunction k) {
1055dbec5304Smbalmer   struct CallS c;
1056dbec5304Smbalmer   int status;
1057dbec5304Smbalmer   ptrdiff_t func;
1058dbec5304Smbalmer   lua_lock(L);
1059bee09862Smbalmer   api_check(L, k == NULL || !isLua(L->ci),
10604ab4902eSlneto     "cannot use continuations inside hooks");
1061dbec5304Smbalmer   api_checknelems(L, nargs+1);
1062bee09862Smbalmer   api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
1063dbec5304Smbalmer   checkresults(L, nargs, nresults);
1064dbec5304Smbalmer   if (errfunc == 0)
1065dbec5304Smbalmer     func = 0;
1066dbec5304Smbalmer   else {
1067f0dad708Snikita     StkId o = index2stack(L, errfunc);
1068f0dad708Snikita     api_check(L, ttisfunction(s2v(o)), "error handler must be a function");
1069dbec5304Smbalmer     func = savestack(L, o);
1070dbec5304Smbalmer   }
1071*bdda0531Snikita   c.func = L->top.p - (nargs+1);  /* function to be called */
1072f0dad708Snikita   if (k == NULL || !yieldable(L)) {  /* no continuation or no yieldable? */
10734ab4902eSlneto     c.nresults = nresults;  /* do a 'conventional' protected call */
1074dbec5304Smbalmer     status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
10754ab4902eSlneto   }
10764ab4902eSlneto   else {  /* prepare continuation (call is already protected by 'resume') */
10774ab4902eSlneto     CallInfo *ci = L->ci;
10784ab4902eSlneto     ci->u.c.k = k;  /* save continuation */
10794ab4902eSlneto     ci->u.c.ctx = ctx;  /* save context */
10804ab4902eSlneto     /* save information for error recovery */
1081f0dad708Snikita     ci->u2.funcidx = cast_int(savestack(L, c.func));
10824ab4902eSlneto     ci->u.c.old_errfunc = L->errfunc;
10834ab4902eSlneto     L->errfunc = func;
10844ab4902eSlneto     setoah(ci->callstatus, L->allowhook);  /* save value of 'allowhook' */
10854ab4902eSlneto     ci->callstatus |= CIST_YPCALL;  /* function can do error recovery */
10862d6cb6c2Slneto     luaD_call(L, c.func, nresults);  /* do the call */
10874ab4902eSlneto     ci->callstatus &= ~CIST_YPCALL;
10884ab4902eSlneto     L->errfunc = ci->u.c.old_errfunc;
10894ab4902eSlneto     status = LUA_OK;  /* if it is here, there were no errors */
10904ab4902eSlneto   }
1091dbec5304Smbalmer   adjustresults(L, nresults);
1092dbec5304Smbalmer   lua_unlock(L);
1093dbec5304Smbalmer   return status;
1094dbec5304Smbalmer }
1095dbec5304Smbalmer 
1096dbec5304Smbalmer 
lua_load(lua_State * L,lua_Reader reader,void * data,const char * chunkname,const char * mode)1097dbec5304Smbalmer LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
10984ab4902eSlneto                       const char *chunkname, const char *mode) {
1099dbec5304Smbalmer   ZIO z;
1100dbec5304Smbalmer   int status;
1101dbec5304Smbalmer   lua_lock(L);
1102dbec5304Smbalmer   if (!chunkname) chunkname = "?";
1103dbec5304Smbalmer   luaZ_init(L, &z, reader, data);
11044ab4902eSlneto   status = luaD_protectedparser(L, &z, chunkname, mode);
11054ab4902eSlneto   if (status == LUA_OK) {  /* no errors? */
1106*bdda0531Snikita     LClosure *f = clLvalue(s2v(L->top.p - 1));  /* get new function */
110773008250Slneto     if (f->nupvalues >= 1) {  /* does it have an upvalue? */
11084ab4902eSlneto       /* get global table from registry */
1109f0dad708Snikita       const TValue *gt = getGtable(L);
11104ab4902eSlneto       /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
1111*bdda0531Snikita       setobj(L, f->upvals[0]->v.p, gt);
1112f0dad708Snikita       luaC_barrier(L, f->upvals[0], gt);
11134ab4902eSlneto     }
11144ab4902eSlneto   }
1115dbec5304Smbalmer   lua_unlock(L);
1116dbec5304Smbalmer   return status;
1117dbec5304Smbalmer }
1118dbec5304Smbalmer 
1119dbec5304Smbalmer 
lua_dump(lua_State * L,lua_Writer writer,void * data,int strip)11204ab4902eSlneto LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
1121dbec5304Smbalmer   int status;
1122dbec5304Smbalmer   TValue *o;
1123dbec5304Smbalmer   lua_lock(L);
1124dbec5304Smbalmer   api_checknelems(L, 1);
1125*bdda0531Snikita   o = s2v(L->top.p - 1);
1126dbec5304Smbalmer   if (isLfunction(o))
11274ab4902eSlneto     status = luaU_dump(L, getproto(o), writer, data, strip);
1128dbec5304Smbalmer   else
1129dbec5304Smbalmer     status = 1;
1130dbec5304Smbalmer   lua_unlock(L);
1131dbec5304Smbalmer   return status;
1132dbec5304Smbalmer }
1133dbec5304Smbalmer 
1134dbec5304Smbalmer 
lua_status(lua_State * L)1135dbec5304Smbalmer LUA_API int lua_status (lua_State *L) {
1136dbec5304Smbalmer   return L->status;
1137dbec5304Smbalmer }
1138dbec5304Smbalmer 
1139dbec5304Smbalmer 
1140dbec5304Smbalmer /*
1141dbec5304Smbalmer ** Garbage-collection function
1142dbec5304Smbalmer */
lua_gc(lua_State * L,int what,...)1143f0dad708Snikita LUA_API int lua_gc (lua_State *L, int what, ...) {
1144f0dad708Snikita   va_list argp;
1145dbec5304Smbalmer   int res = 0;
1146f0dad708Snikita   global_State *g = G(L);
1147f0dad708Snikita   if (g->gcstp & GCSTPGC)  /* internal stop? */
1148f0dad708Snikita     return -1;  /* all options are invalid when stopped */
1149dbec5304Smbalmer   lua_lock(L);
1150f0dad708Snikita   va_start(argp, what);
1151dbec5304Smbalmer   switch (what) {
1152dbec5304Smbalmer     case LUA_GCSTOP: {
1153f0dad708Snikita       g->gcstp = GCSTPUSR;  /* stopped by the user */
1154dbec5304Smbalmer       break;
1155dbec5304Smbalmer     }
1156dbec5304Smbalmer     case LUA_GCRESTART: {
11574ab4902eSlneto       luaE_setdebt(g, 0);
1158f0dad708Snikita       g->gcstp = 0;  /* (GCSTPGC must be already zero here) */
1159dbec5304Smbalmer       break;
1160dbec5304Smbalmer     }
1161dbec5304Smbalmer     case LUA_GCCOLLECT: {
11624ab4902eSlneto       luaC_fullgc(L, 0);
1163dbec5304Smbalmer       break;
1164dbec5304Smbalmer     }
1165dbec5304Smbalmer     case LUA_GCCOUNT: {
1166dbec5304Smbalmer       /* GC values are expressed in Kbytes: #bytes/2^10 */
11674ab4902eSlneto       res = cast_int(gettotalbytes(g) >> 10);
1168dbec5304Smbalmer       break;
1169dbec5304Smbalmer     }
1170dbec5304Smbalmer     case LUA_GCCOUNTB: {
11714ab4902eSlneto       res = cast_int(gettotalbytes(g) & 0x3ff);
1172dbec5304Smbalmer       break;
1173dbec5304Smbalmer     }
1174dbec5304Smbalmer     case LUA_GCSTEP: {
1175f0dad708Snikita       int data = va_arg(argp, int);
11764ab4902eSlneto       l_mem debt = 1;  /* =1 to signal that it did an actual step */
1177f0dad708Snikita       lu_byte oldstp = g->gcstp;
1178f0dad708Snikita       g->gcstp = 0;  /* allow GC to run (GCSTPGC must be zero here) */
11794ab4902eSlneto       if (data == 0) {
1180f0dad708Snikita         luaE_setdebt(g, 0);  /* do a basic step */
1181dbec5304Smbalmer         luaC_step(L);
11824ab4902eSlneto       }
11834ab4902eSlneto       else {  /* add 'data' to total debt */
11844ab4902eSlneto         debt = cast(l_mem, data) * 1024 + g->GCdebt;
11854ab4902eSlneto         luaE_setdebt(g, debt);
11864ab4902eSlneto         luaC_checkGC(L);
11874ab4902eSlneto       }
1188f0dad708Snikita       g->gcstp = oldstp;  /* restore previous state */
11894ab4902eSlneto       if (debt > 0 && g->gcstate == GCSpause)  /* end of cycle? */
1190dbec5304Smbalmer         res = 1;  /* signal it */
1191dbec5304Smbalmer       break;
1192dbec5304Smbalmer     }
1193dbec5304Smbalmer     case LUA_GCSETPAUSE: {
1194f0dad708Snikita       int data = va_arg(argp, int);
1195f0dad708Snikita       res = getgcparam(g->gcpause);
1196f0dad708Snikita       setgcparam(g->gcpause, data);
1197dbec5304Smbalmer       break;
1198dbec5304Smbalmer     }
1199dbec5304Smbalmer     case LUA_GCSETSTEPMUL: {
1200f0dad708Snikita       int data = va_arg(argp, int);
1201f0dad708Snikita       res = getgcparam(g->gcstepmul);
1202f0dad708Snikita       setgcparam(g->gcstepmul, data);
1203dbec5304Smbalmer       break;
1204dbec5304Smbalmer     }
12054ab4902eSlneto     case LUA_GCISRUNNING: {
1206f0dad708Snikita       res = gcrunning(g);
1207f0dad708Snikita       break;
1208f0dad708Snikita     }
1209f0dad708Snikita     case LUA_GCGEN: {
1210f0dad708Snikita       int minormul = va_arg(argp, int);
1211f0dad708Snikita       int majormul = va_arg(argp, int);
1212f0dad708Snikita       res = isdecGCmodegen(g) ? LUA_GCGEN : LUA_GCINC;
1213f0dad708Snikita       if (minormul != 0)
1214f0dad708Snikita         g->genminormul = minormul;
1215f0dad708Snikita       if (majormul != 0)
1216f0dad708Snikita         setgcparam(g->genmajormul, majormul);
1217f0dad708Snikita       luaC_changemode(L, KGC_GEN);
1218f0dad708Snikita       break;
1219f0dad708Snikita     }
1220f0dad708Snikita     case LUA_GCINC: {
1221f0dad708Snikita       int pause = va_arg(argp, int);
1222f0dad708Snikita       int stepmul = va_arg(argp, int);
1223f0dad708Snikita       int stepsize = va_arg(argp, int);
1224f0dad708Snikita       res = isdecGCmodegen(g) ? LUA_GCGEN : LUA_GCINC;
1225f0dad708Snikita       if (pause != 0)
1226f0dad708Snikita         setgcparam(g->gcpause, pause);
1227f0dad708Snikita       if (stepmul != 0)
1228f0dad708Snikita         setgcparam(g->gcstepmul, stepmul);
1229f0dad708Snikita       if (stepsize != 0)
1230f0dad708Snikita         g->gcstepsize = stepsize;
1231f0dad708Snikita       luaC_changemode(L, KGC_INC);
12324ab4902eSlneto       break;
12334ab4902eSlneto     }
1234dbec5304Smbalmer     default: res = -1;  /* invalid option */
1235dbec5304Smbalmer   }
1236f0dad708Snikita   va_end(argp);
1237dbec5304Smbalmer   lua_unlock(L);
1238dbec5304Smbalmer   return res;
1239dbec5304Smbalmer }
1240dbec5304Smbalmer 
1241dbec5304Smbalmer 
1242dbec5304Smbalmer 
1243dbec5304Smbalmer /*
1244dbec5304Smbalmer ** miscellaneous functions
1245dbec5304Smbalmer */
1246dbec5304Smbalmer 
1247dbec5304Smbalmer 
lua_error(lua_State * L)1248dbec5304Smbalmer LUA_API int lua_error (lua_State *L) {
1249f0dad708Snikita   TValue *errobj;
1250dbec5304Smbalmer   lua_lock(L);
1251*bdda0531Snikita   errobj = s2v(L->top.p - 1);
1252dbec5304Smbalmer   api_checknelems(L, 1);
1253f0dad708Snikita   /* error object is the memory error message? */
1254f0dad708Snikita   if (ttisshrstring(errobj) && eqshrstr(tsvalue(errobj), G(L)->memerrmsg))
1255f0dad708Snikita     luaM_error(L);  /* raise a memory error */
1256f0dad708Snikita   else
1257f0dad708Snikita     luaG_errormsg(L);  /* raise a regular error */
12584ab4902eSlneto   /* code unreachable; will unlock when control actually leaves the kernel */
1259dbec5304Smbalmer   return 0;  /* to avoid warnings */
1260dbec5304Smbalmer }
1261dbec5304Smbalmer 
1262dbec5304Smbalmer 
lua_next(lua_State * L,int idx)1263dbec5304Smbalmer LUA_API int lua_next (lua_State *L, int idx) {
1264f0dad708Snikita   Table *t;
1265dbec5304Smbalmer   int more;
1266dbec5304Smbalmer   lua_lock(L);
1267f0dad708Snikita   api_checknelems(L, 1);
1268f0dad708Snikita   t = gettable(L, idx);
1269*bdda0531Snikita   more = luaH_next(L, t, L->top.p - 1);
1270dbec5304Smbalmer   if (more) {
1271dbec5304Smbalmer     api_incr_top(L);
1272dbec5304Smbalmer   }
1273dbec5304Smbalmer   else  /* no more elements */
1274*bdda0531Snikita     L->top.p -= 1;  /* remove key */
1275dbec5304Smbalmer   lua_unlock(L);
1276dbec5304Smbalmer   return more;
1277dbec5304Smbalmer }
1278dbec5304Smbalmer 
1279dbec5304Smbalmer 
lua_toclose(lua_State * L,int idx)1280f0dad708Snikita LUA_API void lua_toclose (lua_State *L, int idx) {
1281f0dad708Snikita   int nresults;
1282f0dad708Snikita   StkId o;
1283f0dad708Snikita   lua_lock(L);
1284f0dad708Snikita   o = index2stack(L, idx);
1285f0dad708Snikita   nresults = L->ci->nresults;
1286*bdda0531Snikita   api_check(L, L->tbclist.p < o, "given index below or equal a marked one");
1287f0dad708Snikita   luaF_newtbcupval(L, o);  /* create new to-be-closed upvalue */
1288f0dad708Snikita   if (!hastocloseCfunc(nresults))  /* function not marked yet? */
1289f0dad708Snikita     L->ci->nresults = codeNresults(nresults);  /* mark it */
1290f0dad708Snikita   lua_assert(hastocloseCfunc(L->ci->nresults));
1291f0dad708Snikita   lua_unlock(L);
1292f0dad708Snikita }
1293f0dad708Snikita 
1294f0dad708Snikita 
lua_concat(lua_State * L,int n)1295dbec5304Smbalmer LUA_API void lua_concat (lua_State *L, int n) {
1296dbec5304Smbalmer   lua_lock(L);
1297dbec5304Smbalmer   api_checknelems(L, n);
1298f0dad708Snikita   if (n > 0)
12994ab4902eSlneto     luaV_concat(L, n);
1300f0dad708Snikita   else {  /* nothing to concatenate */
1301*bdda0531Snikita     setsvalue2s(L, L->top.p, luaS_newlstr(L, "", 0));  /* push empty string */
1302dbec5304Smbalmer     api_incr_top(L);
1303dbec5304Smbalmer   }
1304c7f896d7Ssalazar   luaC_checkGC(L);
1305dbec5304Smbalmer   lua_unlock(L);
1306dbec5304Smbalmer }
1307dbec5304Smbalmer 
1308dbec5304Smbalmer 
lua_len(lua_State * L,int idx)13094ab4902eSlneto LUA_API void lua_len (lua_State *L, int idx) {
1310f0dad708Snikita   TValue *t;
13114ab4902eSlneto   lua_lock(L);
1312f0dad708Snikita   t = index2value(L, idx);
1313*bdda0531Snikita   luaV_objlen(L, L->top.p, t);
13144ab4902eSlneto   api_incr_top(L);
13154ab4902eSlneto   lua_unlock(L);
13164ab4902eSlneto }
13174ab4902eSlneto 
13184ab4902eSlneto 
lua_getallocf(lua_State * L,void ** ud)1319dbec5304Smbalmer LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
1320dbec5304Smbalmer   lua_Alloc f;
1321dbec5304Smbalmer   lua_lock(L);
1322dbec5304Smbalmer   if (ud) *ud = G(L)->ud;
1323dbec5304Smbalmer   f = G(L)->frealloc;
1324dbec5304Smbalmer   lua_unlock(L);
1325dbec5304Smbalmer   return f;
1326dbec5304Smbalmer }
1327dbec5304Smbalmer 
1328dbec5304Smbalmer 
lua_setallocf(lua_State * L,lua_Alloc f,void * ud)1329dbec5304Smbalmer LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
1330dbec5304Smbalmer   lua_lock(L);
1331dbec5304Smbalmer   G(L)->ud = ud;
1332dbec5304Smbalmer   G(L)->frealloc = f;
1333dbec5304Smbalmer   lua_unlock(L);
1334dbec5304Smbalmer }
1335dbec5304Smbalmer 
1336dbec5304Smbalmer 
lua_setwarnf(lua_State * L,lua_WarnFunction f,void * ud)1337f0dad708Snikita void lua_setwarnf (lua_State *L, lua_WarnFunction f, void *ud) {
1338f0dad708Snikita   lua_lock(L);
1339f0dad708Snikita   G(L)->ud_warn = ud;
1340f0dad708Snikita   G(L)->warnf = f;
1341f0dad708Snikita   lua_unlock(L);
1342f0dad708Snikita }
1343f0dad708Snikita 
1344f0dad708Snikita 
lua_warning(lua_State * L,const char * msg,int tocont)1345f0dad708Snikita void lua_warning (lua_State *L, const char *msg, int tocont) {
1346f0dad708Snikita   lua_lock(L);
1347f0dad708Snikita   luaE_warning(L, msg, tocont);
1348f0dad708Snikita   lua_unlock(L);
1349f0dad708Snikita }
1350f0dad708Snikita 
1351f0dad708Snikita 
1352f0dad708Snikita 
lua_newuserdatauv(lua_State * L,size_t size,int nuvalue)1353f0dad708Snikita LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) {
1354dbec5304Smbalmer   Udata *u;
1355dbec5304Smbalmer   lua_lock(L);
1356f0dad708Snikita   api_check(L, 0 <= nuvalue && nuvalue < USHRT_MAX, "invalid value");
1357f0dad708Snikita   u = luaS_newudata(L, size, nuvalue);
1358*bdda0531Snikita   setuvalue(L, s2v(L->top.p), u);
1359dbec5304Smbalmer   api_incr_top(L);
1360c7f896d7Ssalazar   luaC_checkGC(L);
1361dbec5304Smbalmer   lua_unlock(L);
136273008250Slneto   return getudatamem(u);
1363dbec5304Smbalmer }
1364dbec5304Smbalmer 
1365dbec5304Smbalmer 
1366dbec5304Smbalmer 
aux_upvalue(TValue * fi,int n,TValue ** val,GCObject ** owner)1367f0dad708Snikita static const char *aux_upvalue (TValue *fi, int n, TValue **val,
1368f0dad708Snikita                                 GCObject **owner) {
1369f0dad708Snikita   switch (ttypetag(fi)) {
1370f0dad708Snikita     case LUA_VCCL: {  /* C closure */
13714ab4902eSlneto       CClosure *f = clCvalue(fi);
1372f0dad708Snikita       if (!(cast_uint(n) - 1u < cast_uint(f->nupvalues)))
1373f0dad708Snikita         return NULL;  /* 'n' not in [1, f->nupvalues] */
13744ab4902eSlneto       *val = &f->upvalue[n-1];
1375f0dad708Snikita       if (owner) *owner = obj2gco(f);
1376dbec5304Smbalmer       return "";
1377dbec5304Smbalmer     }
1378f0dad708Snikita     case LUA_VLCL: {  /* Lua closure */
13794ab4902eSlneto       LClosure *f = clLvalue(fi);
13804ab4902eSlneto       TString *name;
13814ab4902eSlneto       Proto *p = f->p;
1382f0dad708Snikita       if (!(cast_uint(n) - 1u  < cast_uint(p->sizeupvalues)))
1383f0dad708Snikita         return NULL;  /* 'n' not in [1, p->sizeupvalues] */
1384*bdda0531Snikita       *val = f->upvals[n-1]->v.p;
1385f0dad708Snikita       if (owner) *owner = obj2gco(f->upvals[n - 1]);
13864ab4902eSlneto       name = p->upvalues[n-1].name;
1387f0dad708Snikita       return (name == NULL) ? "(no name)" : getstr(name);
13884ab4902eSlneto     }
13894ab4902eSlneto     default: return NULL;  /* not a closure */
1390dbec5304Smbalmer   }
1391dbec5304Smbalmer }
1392dbec5304Smbalmer 
1393dbec5304Smbalmer 
lua_getupvalue(lua_State * L,int funcindex,int n)1394dbec5304Smbalmer LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
1395dbec5304Smbalmer   const char *name;
13964ab4902eSlneto   TValue *val = NULL;  /* to avoid warnings */
1397dbec5304Smbalmer   lua_lock(L);
1398f0dad708Snikita   name = aux_upvalue(index2value(L, funcindex), n, &val, NULL);
1399dbec5304Smbalmer   if (name) {
1400*bdda0531Snikita     setobj2s(L, L->top.p, val);
1401dbec5304Smbalmer     api_incr_top(L);
1402dbec5304Smbalmer   }
1403dbec5304Smbalmer   lua_unlock(L);
1404dbec5304Smbalmer   return name;
1405dbec5304Smbalmer }
1406dbec5304Smbalmer 
1407dbec5304Smbalmer 
lua_setupvalue(lua_State * L,int funcindex,int n)1408dbec5304Smbalmer LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
1409dbec5304Smbalmer   const char *name;
14104ab4902eSlneto   TValue *val = NULL;  /* to avoid warnings */
1411f0dad708Snikita   GCObject *owner = NULL;  /* to avoid warnings */
1412f0dad708Snikita   TValue *fi;
1413dbec5304Smbalmer   lua_lock(L);
1414f0dad708Snikita   fi = index2value(L, funcindex);
1415dbec5304Smbalmer   api_checknelems(L, 1);
1416f0dad708Snikita   name = aux_upvalue(fi, n, &val, &owner);
1417dbec5304Smbalmer   if (name) {
1418*bdda0531Snikita     L->top.p--;
1419*bdda0531Snikita     setobj(L, val, s2v(L->top.p));
1420f0dad708Snikita     luaC_barrier(L, owner, val);
1421dbec5304Smbalmer   }
1422dbec5304Smbalmer   lua_unlock(L);
1423dbec5304Smbalmer   return name;
1424dbec5304Smbalmer }
1425dbec5304Smbalmer 
14264ab4902eSlneto 
getupvalref(lua_State * L,int fidx,int n,LClosure ** pf)14274ab4902eSlneto static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
1428f0dad708Snikita   static const UpVal *const nullup = NULL;
14294ab4902eSlneto   LClosure *f;
1430f0dad708Snikita   TValue *fi = index2value(L, fidx);
1431bee09862Smbalmer   api_check(L, ttisLclosure(fi), "Lua function expected");
14324ab4902eSlneto   f = clLvalue(fi);
14334ab4902eSlneto   if (pf) *pf = f;
1434f0dad708Snikita   if (1 <= n && n <= f->p->sizeupvalues)
14354ab4902eSlneto     return &f->upvals[n - 1];  /* get its upvalue pointer */
1436f0dad708Snikita   else
1437f0dad708Snikita     return (UpVal**)&nullup;
14384ab4902eSlneto }
14394ab4902eSlneto 
14404ab4902eSlneto 
lua_upvalueid(lua_State * L,int fidx,int n)14414ab4902eSlneto LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
1442f0dad708Snikita   TValue *fi = index2value(L, fidx);
1443f0dad708Snikita   switch (ttypetag(fi)) {
1444f0dad708Snikita     case LUA_VLCL: {  /* lua closure */
14454ab4902eSlneto       return *getupvalref(L, fidx, n, NULL);
14464ab4902eSlneto     }
1447f0dad708Snikita     case LUA_VCCL: {  /* C closure */
14484ab4902eSlneto       CClosure *f = clCvalue(fi);
1449f0dad708Snikita       if (1 <= n && n <= f->nupvalues)
14504ab4902eSlneto         return &f->upvalue[n - 1];
1451f0dad708Snikita       /* else */
1452f0dad708Snikita     }  /* FALLTHROUGH */
1453f0dad708Snikita     case LUA_VLCF:
1454f0dad708Snikita       return NULL;  /* light C functions have no upvalues */
14554ab4902eSlneto     default: {
1456f0dad708Snikita       api_check(L, 0, "function expected");
14574ab4902eSlneto       return NULL;
14584ab4902eSlneto     }
14594ab4902eSlneto   }
14604ab4902eSlneto }
14614ab4902eSlneto 
14624ab4902eSlneto 
lua_upvaluejoin(lua_State * L,int fidx1,int n1,int fidx2,int n2)14634ab4902eSlneto LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
14644ab4902eSlneto                                             int fidx2, int n2) {
14654ab4902eSlneto   LClosure *f1;
14664ab4902eSlneto   UpVal **up1 = getupvalref(L, fidx1, n1, &f1);
14674ab4902eSlneto   UpVal **up2 = getupvalref(L, fidx2, n2, NULL);
1468f0dad708Snikita   api_check(L, *up1 != NULL && *up2 != NULL, "invalid upvalue index");
14694ab4902eSlneto   *up1 = *up2;
1470f0dad708Snikita   luaC_objbarrier(L, f1, *up1);
14714ab4902eSlneto }
14724ab4902eSlneto 
14734ab4902eSlneto 
1474