xref: /illumos-gate/usr/src/uts/common/fs/zfs/lua/lapi.c (revision dfc11533)
1*dfc11533SChris Williamson /*
2*dfc11533SChris Williamson ** $Id: lapi.c,v 2.171.1.1 2013/04/12 18:48:47 roberto Exp $
3*dfc11533SChris Williamson ** Lua API
4*dfc11533SChris Williamson ** See Copyright Notice in lua.h
5*dfc11533SChris Williamson */
6*dfc11533SChris Williamson 
7*dfc11533SChris Williamson 
8*dfc11533SChris Williamson #include <sys/zfs_context.h>
9*dfc11533SChris Williamson 
10*dfc11533SChris Williamson #define lapi_c
11*dfc11533SChris Williamson #define LUA_CORE
12*dfc11533SChris Williamson 
13*dfc11533SChris Williamson #include "lua.h"
14*dfc11533SChris Williamson 
15*dfc11533SChris Williamson #include "lapi.h"
16*dfc11533SChris Williamson #include "ldebug.h"
17*dfc11533SChris Williamson #include "ldo.h"
18*dfc11533SChris Williamson #include "lfunc.h"
19*dfc11533SChris Williamson #include "lgc.h"
20*dfc11533SChris Williamson #include "lmem.h"
21*dfc11533SChris Williamson #include "lobject.h"
22*dfc11533SChris Williamson #include "lstate.h"
23*dfc11533SChris Williamson #include "lstring.h"
24*dfc11533SChris Williamson #include "ltable.h"
25*dfc11533SChris Williamson #include "ltm.h"
26*dfc11533SChris Williamson #include "lundump.h"
27*dfc11533SChris Williamson #include "lvm.h"
28*dfc11533SChris Williamson 
29*dfc11533SChris Williamson 
30*dfc11533SChris Williamson 
31*dfc11533SChris Williamson const char lua_ident[] =
32*dfc11533SChris Williamson   "$LuaVersion: " LUA_COPYRIGHT " $"
33*dfc11533SChris Williamson   "$LuaAuthors: " LUA_AUTHORS " $";
34*dfc11533SChris Williamson 
35*dfc11533SChris Williamson 
36*dfc11533SChris Williamson /* value at a non-valid index */
37*dfc11533SChris Williamson #define NONVALIDVALUE		cast(TValue *, luaO_nilobject)
38*dfc11533SChris Williamson 
39*dfc11533SChris Williamson /* corresponding test */
40*dfc11533SChris Williamson #define isvalid(o)	((o) != luaO_nilobject)
41*dfc11533SChris Williamson 
42*dfc11533SChris Williamson /* test for pseudo index */
43*dfc11533SChris Williamson #define ispseudo(i)		((i) <= LUA_REGISTRYINDEX)
44*dfc11533SChris Williamson 
45*dfc11533SChris Williamson /* test for valid but not pseudo index */
46*dfc11533SChris Williamson #define isstackindex(i, o)	(isvalid(o) && !ispseudo(i))
47*dfc11533SChris Williamson 
48*dfc11533SChris Williamson #define api_checkvalidindex(L, o)  api_check(L, isvalid(o), "invalid index")
49*dfc11533SChris Williamson 
50*dfc11533SChris Williamson #define api_checkstackindex(L, i, o)  \
51*dfc11533SChris Williamson 	api_check(L, isstackindex(i, o), "index not in the stack")
52*dfc11533SChris Williamson 
53*dfc11533SChris Williamson 
index2addr(lua_State * L,int idx)54*dfc11533SChris Williamson static TValue *index2addr (lua_State *L, int idx) {
55*dfc11533SChris Williamson   CallInfo *ci = L->ci;
56*dfc11533SChris Williamson   if (idx > 0) {
57*dfc11533SChris Williamson     TValue *o = ci->func + idx;
58*dfc11533SChris Williamson     api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
59*dfc11533SChris Williamson     if (o >= L->top) return NONVALIDVALUE;
60*dfc11533SChris Williamson     else return o;
61*dfc11533SChris Williamson   }
62*dfc11533SChris Williamson   else if (!ispseudo(idx)) {  /* negative index */
63*dfc11533SChris Williamson     api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
64*dfc11533SChris Williamson     return L->top + idx;
65*dfc11533SChris Williamson   }
66*dfc11533SChris Williamson   else if (idx == LUA_REGISTRYINDEX)
67*dfc11533SChris Williamson     return &G(L)->l_registry;
68*dfc11533SChris Williamson   else {  /* upvalues */
69*dfc11533SChris Williamson     idx = LUA_REGISTRYINDEX - idx;
70*dfc11533SChris Williamson     api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
71*dfc11533SChris Williamson     if (ttislcf(ci->func))  /* light C function? */
72*dfc11533SChris Williamson       return NONVALIDVALUE;  /* it has no upvalues */
73*dfc11533SChris Williamson     else {
74*dfc11533SChris Williamson       CClosure *func = clCvalue(ci->func);
75*dfc11533SChris Williamson       return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE;
76*dfc11533SChris Williamson     }
77*dfc11533SChris Williamson   }
78*dfc11533SChris Williamson }
79*dfc11533SChris Williamson 
80*dfc11533SChris Williamson 
81*dfc11533SChris Williamson /*
82*dfc11533SChris Williamson ** to be called by 'lua_checkstack' in protected mode, to grow stack
83*dfc11533SChris Williamson ** capturing memory errors
84*dfc11533SChris Williamson */
growstack(lua_State * L,void * ud)85*dfc11533SChris Williamson static void growstack (lua_State *L, void *ud) {
86*dfc11533SChris Williamson   int size = *(int *)ud;
87*dfc11533SChris Williamson   luaD_growstack(L, size);
88*dfc11533SChris Williamson }
89*dfc11533SChris Williamson 
90*dfc11533SChris Williamson 
lua_checkstack(lua_State * L,int size)91*dfc11533SChris Williamson LUA_API int lua_checkstack (lua_State *L, int size) {
92*dfc11533SChris Williamson   int res;
93*dfc11533SChris Williamson   CallInfo *ci = L->ci;
94*dfc11533SChris Williamson   lua_lock(L);
95*dfc11533SChris Williamson   if (L->stack_last - L->top > size)  /* stack large enough? */
96*dfc11533SChris Williamson     res = 1;  /* yes; check is OK */
97*dfc11533SChris Williamson   else {  /* no; need to grow stack */
98*dfc11533SChris Williamson     int inuse = cast_int(L->top - L->stack) + EXTRA_STACK;
99*dfc11533SChris Williamson     if (inuse > LUAI_MAXSTACK - size)  /* can grow without overflow? */
100*dfc11533SChris Williamson       res = 0;  /* no */
101*dfc11533SChris Williamson     else  /* try to grow stack */
102*dfc11533SChris Williamson       res = (luaD_rawrunprotected(L, &growstack, &size) == LUA_OK);
103*dfc11533SChris Williamson   }
104*dfc11533SChris Williamson   if (res && ci->top < L->top + size)
105*dfc11533SChris Williamson     ci->top = L->top + size;  /* adjust frame top */
106*dfc11533SChris Williamson   lua_unlock(L);
107*dfc11533SChris Williamson   return res;
108*dfc11533SChris Williamson }
109*dfc11533SChris Williamson 
110*dfc11533SChris Williamson 
lua_xmove(lua_State * from,lua_State * to,int n)111*dfc11533SChris Williamson LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
112*dfc11533SChris Williamson   int i;
113*dfc11533SChris Williamson   if (from == to) return;
114*dfc11533SChris Williamson   lua_lock(to);
115*dfc11533SChris Williamson   api_checknelems(from, n);
116*dfc11533SChris Williamson   api_check(from, G(from) == G(to), "moving among independent states");
117*dfc11533SChris Williamson   api_check(from, to->ci->top - to->top >= n, "not enough elements to move");
118*dfc11533SChris Williamson   from->top -= n;
119*dfc11533SChris Williamson   for (i = 0; i < n; i++) {
120*dfc11533SChris Williamson     setobj2s(to, to->top++, from->top + i);
121*dfc11533SChris Williamson   }
122*dfc11533SChris Williamson   lua_unlock(to);
123*dfc11533SChris Williamson }
124*dfc11533SChris Williamson 
125*dfc11533SChris Williamson 
lua_atpanic(lua_State * L,lua_CFunction panicf)126*dfc11533SChris Williamson LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
127*dfc11533SChris Williamson   lua_CFunction old;
128*dfc11533SChris Williamson   lua_lock(L);
129*dfc11533SChris Williamson   old = G(L)->panic;
130*dfc11533SChris Williamson   G(L)->panic = panicf;
131*dfc11533SChris Williamson   lua_unlock(L);
132*dfc11533SChris Williamson   return old;
133*dfc11533SChris Williamson }
134*dfc11533SChris Williamson 
135*dfc11533SChris Williamson 
lua_version(lua_State * L)136*dfc11533SChris Williamson LUA_API const lua_Number *lua_version (lua_State *L) {
137*dfc11533SChris Williamson   static const lua_Number version = LUA_VERSION_NUM;
138*dfc11533SChris Williamson   if (L == NULL) return &version;
139*dfc11533SChris Williamson   else return G(L)->version;
140*dfc11533SChris Williamson }
141*dfc11533SChris Williamson 
142*dfc11533SChris Williamson 
143*dfc11533SChris Williamson 
144*dfc11533SChris Williamson /*
145*dfc11533SChris Williamson ** basic stack manipulation
146*dfc11533SChris Williamson */
147*dfc11533SChris Williamson 
148*dfc11533SChris Williamson 
149*dfc11533SChris Williamson /*
150*dfc11533SChris Williamson ** convert an acceptable stack index into an absolute index
151*dfc11533SChris Williamson */
lua_absindex(lua_State * L,int idx)152*dfc11533SChris Williamson LUA_API int lua_absindex (lua_State *L, int idx) {
153*dfc11533SChris Williamson   return (idx > 0 || ispseudo(idx))
154*dfc11533SChris Williamson          ? idx
155*dfc11533SChris Williamson          : cast_int(L->top - L->ci->func + idx);
156*dfc11533SChris Williamson }
157*dfc11533SChris Williamson 
158*dfc11533SChris Williamson 
lua_gettop(lua_State * L)159*dfc11533SChris Williamson LUA_API int lua_gettop (lua_State *L) {
160*dfc11533SChris Williamson   return cast_int(L->top - (L->ci->func + 1));
161*dfc11533SChris Williamson }
162*dfc11533SChris Williamson 
163*dfc11533SChris Williamson 
lua_settop(lua_State * L,int idx)164*dfc11533SChris Williamson LUA_API void lua_settop (lua_State *L, int idx) {
165*dfc11533SChris Williamson   StkId func = L->ci->func;
166*dfc11533SChris Williamson   lua_lock(L);
167*dfc11533SChris Williamson   if (idx >= 0) {
168*dfc11533SChris Williamson     api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
169*dfc11533SChris Williamson     while (L->top < (func + 1) + idx)
170*dfc11533SChris Williamson       setnilvalue(L->top++);
171*dfc11533SChris Williamson     L->top = (func + 1) + idx;
172*dfc11533SChris Williamson   }
173*dfc11533SChris Williamson   else {
174*dfc11533SChris Williamson     api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
175*dfc11533SChris Williamson     L->top += idx+1;  /* `subtract' index (index is negative) */
176*dfc11533SChris Williamson   }
177*dfc11533SChris Williamson   lua_unlock(L);
178*dfc11533SChris Williamson }
179*dfc11533SChris Williamson 
180*dfc11533SChris Williamson 
lua_remove(lua_State * L,int idx)181*dfc11533SChris Williamson LUA_API void lua_remove (lua_State *L, int idx) {
182*dfc11533SChris Williamson   StkId p;
183*dfc11533SChris Williamson   lua_lock(L);
184*dfc11533SChris Williamson   p = index2addr(L, idx);
185*dfc11533SChris Williamson   api_checkstackindex(L, idx, p);
186*dfc11533SChris Williamson   while (++p < L->top) setobjs2s(L, p-1, p);
187*dfc11533SChris Williamson   L->top--;
188*dfc11533SChris Williamson   lua_unlock(L);
189*dfc11533SChris Williamson }
190*dfc11533SChris Williamson 
191*dfc11533SChris Williamson 
lua_insert(lua_State * L,int idx)192*dfc11533SChris Williamson LUA_API void lua_insert (lua_State *L, int idx) {
193*dfc11533SChris Williamson   StkId p;
194*dfc11533SChris Williamson   StkId q;
195*dfc11533SChris Williamson   lua_lock(L);
196*dfc11533SChris Williamson   p = index2addr(L, idx);
197*dfc11533SChris Williamson   api_checkstackindex(L, idx, p);
198*dfc11533SChris Williamson   for (q = L->top; q > p; q--)  /* use L->top as a temporary */
199*dfc11533SChris Williamson     setobjs2s(L, q, q - 1);
200*dfc11533SChris Williamson   setobjs2s(L, p, L->top);
201*dfc11533SChris Williamson   lua_unlock(L);
202*dfc11533SChris Williamson }
203*dfc11533SChris Williamson 
204*dfc11533SChris Williamson 
moveto(lua_State * L,TValue * fr,int idx)205*dfc11533SChris Williamson static void moveto (lua_State *L, TValue *fr, int idx) {
206*dfc11533SChris Williamson   TValue *to = index2addr(L, idx);
207*dfc11533SChris Williamson   api_checkvalidindex(L, to);
208*dfc11533SChris Williamson   setobj(L, to, fr);
209*dfc11533SChris Williamson   if (idx < LUA_REGISTRYINDEX)  /* function upvalue? */
210*dfc11533SChris Williamson     luaC_barrier(L, clCvalue(L->ci->func), fr);
211*dfc11533SChris Williamson   /* LUA_REGISTRYINDEX does not need gc barrier
212*dfc11533SChris Williamson      (collector revisits it before finishing collection) */
213*dfc11533SChris Williamson }
214*dfc11533SChris Williamson 
215*dfc11533SChris Williamson 
lua_replace(lua_State * L,int idx)216*dfc11533SChris Williamson LUA_API void lua_replace (lua_State *L, int idx) {
217*dfc11533SChris Williamson   lua_lock(L);
218*dfc11533SChris Williamson   api_checknelems(L, 1);
219*dfc11533SChris Williamson   moveto(L, L->top - 1, idx);
220*dfc11533SChris Williamson   L->top--;
221*dfc11533SChris Williamson   lua_unlock(L);
222*dfc11533SChris Williamson }
223*dfc11533SChris Williamson 
224*dfc11533SChris Williamson 
lua_copy(lua_State * L,int fromidx,int toidx)225*dfc11533SChris Williamson LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
226*dfc11533SChris Williamson   TValue *fr;
227*dfc11533SChris Williamson   lua_lock(L);
228*dfc11533SChris Williamson   fr = index2addr(L, fromidx);
229*dfc11533SChris Williamson   moveto(L, fr, toidx);
230*dfc11533SChris Williamson   lua_unlock(L);
231*dfc11533SChris Williamson }
232*dfc11533SChris Williamson 
233*dfc11533SChris Williamson 
lua_pushvalue(lua_State * L,int idx)234*dfc11533SChris Williamson LUA_API void lua_pushvalue (lua_State *L, int idx) {
235*dfc11533SChris Williamson   lua_lock(L);
236*dfc11533SChris Williamson   setobj2s(L, L->top, index2addr(L, idx));
237*dfc11533SChris Williamson   api_incr_top(L);
238*dfc11533SChris Williamson   lua_unlock(L);
239*dfc11533SChris Williamson }
240*dfc11533SChris Williamson 
241*dfc11533SChris Williamson 
242*dfc11533SChris Williamson 
243*dfc11533SChris Williamson /*
244*dfc11533SChris Williamson ** access functions (stack -> C)
245*dfc11533SChris Williamson */
246*dfc11533SChris Williamson 
247*dfc11533SChris Williamson 
lua_type(lua_State * L,int idx)248*dfc11533SChris Williamson LUA_API int lua_type (lua_State *L, int idx) {
249*dfc11533SChris Williamson   StkId o = index2addr(L, idx);
250*dfc11533SChris Williamson   return (isvalid(o) ? ttypenv(o) : LUA_TNONE);
251*dfc11533SChris Williamson }
252*dfc11533SChris Williamson 
253*dfc11533SChris Williamson 
lua_typename(lua_State * L,int t)254*dfc11533SChris Williamson LUA_API const char *lua_typename (lua_State *L, int t) {
255*dfc11533SChris Williamson   UNUSED(L);
256*dfc11533SChris Williamson   return ttypename(t);
257*dfc11533SChris Williamson }
258*dfc11533SChris Williamson 
259*dfc11533SChris Williamson 
lua_iscfunction(lua_State * L,int idx)260*dfc11533SChris Williamson LUA_API int lua_iscfunction (lua_State *L, int idx) {
261*dfc11533SChris Williamson   StkId o = index2addr(L, idx);
262*dfc11533SChris Williamson   return (ttislcf(o) || (ttisCclosure(o)));
263*dfc11533SChris Williamson }
264*dfc11533SChris Williamson 
265*dfc11533SChris Williamson 
lua_isnumber(lua_State * L,int idx)266*dfc11533SChris Williamson LUA_API int lua_isnumber (lua_State *L, int idx) {
267*dfc11533SChris Williamson   TValue n;
268*dfc11533SChris Williamson   const TValue *o = index2addr(L, idx);
269*dfc11533SChris Williamson   return tonumber(o, &n);
270*dfc11533SChris Williamson }
271*dfc11533SChris Williamson 
272*dfc11533SChris Williamson 
lua_isstring(lua_State * L,int idx)273*dfc11533SChris Williamson LUA_API int lua_isstring (lua_State *L, int idx) {
274*dfc11533SChris Williamson   int t = lua_type(L, idx);
275*dfc11533SChris Williamson   return (t == LUA_TSTRING || t == LUA_TNUMBER);
276*dfc11533SChris Williamson }
277*dfc11533SChris Williamson 
278*dfc11533SChris Williamson 
lua_isuserdata(lua_State * L,int idx)279*dfc11533SChris Williamson LUA_API int lua_isuserdata (lua_State *L, int idx) {
280*dfc11533SChris Williamson   const TValue *o = index2addr(L, idx);
281*dfc11533SChris Williamson   return (ttisuserdata(o) || ttislightuserdata(o));
282*dfc11533SChris Williamson }
283*dfc11533SChris Williamson 
284*dfc11533SChris Williamson 
lua_rawequal(lua_State * L,int index1,int index2)285*dfc11533SChris Williamson LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
286*dfc11533SChris Williamson   StkId o1 = index2addr(L, index1);
287*dfc11533SChris Williamson   StkId o2 = index2addr(L, index2);
288*dfc11533SChris Williamson   return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0;
289*dfc11533SChris Williamson }
290*dfc11533SChris Williamson 
291*dfc11533SChris Williamson 
lua_arith(lua_State * L,int op)292*dfc11533SChris Williamson LUA_API void lua_arith (lua_State *L, int op) {
293*dfc11533SChris Williamson   StkId o1;  /* 1st operand */
294*dfc11533SChris Williamson   StkId o2;  /* 2nd operand */
295*dfc11533SChris Williamson   lua_lock(L);
296*dfc11533SChris Williamson   if (op != LUA_OPUNM) /* all other operations expect two operands */
297*dfc11533SChris Williamson     api_checknelems(L, 2);
298*dfc11533SChris Williamson   else {  /* for unary minus, add fake 2nd operand */
299*dfc11533SChris Williamson     api_checknelems(L, 1);
300*dfc11533SChris Williamson     setobjs2s(L, L->top, L->top - 1);
301*dfc11533SChris Williamson     L->top++;
302*dfc11533SChris Williamson   }
303*dfc11533SChris Williamson   o1 = L->top - 2;
304*dfc11533SChris Williamson   o2 = L->top - 1;
305*dfc11533SChris Williamson   if (ttisnumber(o1) && ttisnumber(o2)) {
306*dfc11533SChris Williamson     setnvalue(o1, luaO_arith(op, nvalue(o1), nvalue(o2)));
307*dfc11533SChris Williamson   }
308*dfc11533SChris Williamson   else
309*dfc11533SChris Williamson     luaV_arith(L, o1, o1, o2, cast(TMS, op - LUA_OPADD + TM_ADD));
310*dfc11533SChris Williamson   L->top--;
311*dfc11533SChris Williamson   lua_unlock(L);
312*dfc11533SChris Williamson }
313*dfc11533SChris Williamson 
314*dfc11533SChris Williamson 
lua_compare(lua_State * L,int index1,int index2,int op)315*dfc11533SChris Williamson LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
316*dfc11533SChris Williamson   StkId o1, o2;
317*dfc11533SChris Williamson   int i = 0;
318*dfc11533SChris Williamson   lua_lock(L);  /* may call tag method */
319*dfc11533SChris Williamson   o1 = index2addr(L, index1);
320*dfc11533SChris Williamson   o2 = index2addr(L, index2);
321*dfc11533SChris Williamson   if (isvalid(o1) && isvalid(o2)) {
322*dfc11533SChris Williamson     switch (op) {
323*dfc11533SChris Williamson       case LUA_OPEQ: i = equalobj(L, o1, o2); break;
324*dfc11533SChris Williamson       case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
325*dfc11533SChris Williamson       case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
326*dfc11533SChris Williamson       default: api_check(L, 0, "invalid option");
327*dfc11533SChris Williamson     }
328*dfc11533SChris Williamson   }
329*dfc11533SChris Williamson   lua_unlock(L);
330*dfc11533SChris Williamson   return i;
331*dfc11533SChris Williamson }
332*dfc11533SChris Williamson 
333*dfc11533SChris Williamson 
lua_tonumberx(lua_State * L,int idx,int * isnum)334*dfc11533SChris Williamson LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum) {
335*dfc11533SChris Williamson   TValue n;
336*dfc11533SChris Williamson   const TValue *o = index2addr(L, idx);
337*dfc11533SChris Williamson   if (tonumber(o, &n)) {
338*dfc11533SChris Williamson     if (isnum) *isnum = 1;
339*dfc11533SChris Williamson     return nvalue(o);
340*dfc11533SChris Williamson   }
341*dfc11533SChris Williamson   else {
342*dfc11533SChris Williamson     if (isnum) *isnum = 0;
343*dfc11533SChris Williamson     return 0;
344*dfc11533SChris Williamson   }
345*dfc11533SChris Williamson }
346*dfc11533SChris Williamson 
347*dfc11533SChris Williamson 
lua_tointegerx(lua_State * L,int idx,int * isnum)348*dfc11533SChris Williamson LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) {
349*dfc11533SChris Williamson   TValue n;
350*dfc11533SChris Williamson   const TValue *o = index2addr(L, idx);
351*dfc11533SChris Williamson   if (tonumber(o, &n)) {
352*dfc11533SChris Williamson     lua_Integer res;
353*dfc11533SChris Williamson     lua_Number num = nvalue(o);
354*dfc11533SChris Williamson     lua_number2integer(res, num);
355*dfc11533SChris Williamson     if (isnum) *isnum = 1;
356*dfc11533SChris Williamson     return res;
357*dfc11533SChris Williamson   }
358*dfc11533SChris Williamson   else {
359*dfc11533SChris Williamson     if (isnum) *isnum = 0;
360*dfc11533SChris Williamson     return 0;
361*dfc11533SChris Williamson   }
362*dfc11533SChris Williamson }
363*dfc11533SChris Williamson 
364*dfc11533SChris Williamson 
lua_tounsignedx(lua_State * L,int idx,int * isnum)365*dfc11533SChris Williamson LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) {
366*dfc11533SChris Williamson   TValue n;
367*dfc11533SChris Williamson   const TValue *o = index2addr(L, idx);
368*dfc11533SChris Williamson   if (tonumber(o, &n)) {
369*dfc11533SChris Williamson     lua_Unsigned res;
370*dfc11533SChris Williamson     lua_Number num = nvalue(o);
371*dfc11533SChris Williamson     lua_number2unsigned(res, num);
372*dfc11533SChris Williamson     if (isnum) *isnum = 1;
373*dfc11533SChris Williamson     return res;
374*dfc11533SChris Williamson   }
375*dfc11533SChris Williamson   else {
376*dfc11533SChris Williamson     if (isnum) *isnum = 0;
377*dfc11533SChris Williamson     return 0;
378*dfc11533SChris Williamson   }
379*dfc11533SChris Williamson }
380*dfc11533SChris Williamson 
381*dfc11533SChris Williamson 
lua_toboolean(lua_State * L,int idx)382*dfc11533SChris Williamson LUA_API int lua_toboolean (lua_State *L, int idx) {
383*dfc11533SChris Williamson   const TValue *o = index2addr(L, idx);
384*dfc11533SChris Williamson   return !l_isfalse(o);
385*dfc11533SChris Williamson }
386*dfc11533SChris Williamson 
387*dfc11533SChris Williamson 
lua_tolstring(lua_State * L,int idx,size_t * len)388*dfc11533SChris Williamson LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
389*dfc11533SChris Williamson   StkId o = index2addr(L, idx);
390*dfc11533SChris Williamson   if (!ttisstring(o)) {
391*dfc11533SChris Williamson     lua_lock(L);  /* `luaV_tostring' may create a new string */
392*dfc11533SChris Williamson     if (!luaV_tostring(L, o)) {  /* conversion failed? */
393*dfc11533SChris Williamson       if (len != NULL) *len = 0;
394*dfc11533SChris Williamson       lua_unlock(L);
395*dfc11533SChris Williamson       return NULL;
396*dfc11533SChris Williamson     }
397*dfc11533SChris Williamson     luaC_checkGC(L);
398*dfc11533SChris Williamson     o = index2addr(L, idx);  /* previous call may reallocate the stack */
399*dfc11533SChris Williamson     lua_unlock(L);
400*dfc11533SChris Williamson   }
401*dfc11533SChris Williamson   if (len != NULL) *len = tsvalue(o)->len;
402*dfc11533SChris Williamson   return svalue(o);
403*dfc11533SChris Williamson }
404*dfc11533SChris Williamson 
405*dfc11533SChris Williamson 
lua_rawlen(lua_State * L,int idx)406*dfc11533SChris Williamson LUA_API size_t lua_rawlen (lua_State *L, int idx) {
407*dfc11533SChris Williamson   StkId o = index2addr(L, idx);
408*dfc11533SChris Williamson   switch (ttypenv(o)) {
409*dfc11533SChris Williamson     case LUA_TSTRING: return tsvalue(o)->len;
410*dfc11533SChris Williamson     case LUA_TUSERDATA: return uvalue(o)->len;
411*dfc11533SChris Williamson     case LUA_TTABLE: return luaH_getn(hvalue(o));
412*dfc11533SChris Williamson     default: return 0;
413*dfc11533SChris Williamson   }
414*dfc11533SChris Williamson }
415*dfc11533SChris Williamson 
416*dfc11533SChris Williamson 
lua_tocfunction(lua_State * L,int idx)417*dfc11533SChris Williamson LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
418*dfc11533SChris Williamson   StkId o = index2addr(L, idx);
419*dfc11533SChris Williamson   if (ttislcf(o)) return fvalue(o);
420*dfc11533SChris Williamson   else if (ttisCclosure(o))
421*dfc11533SChris Williamson     return clCvalue(o)->f;
422*dfc11533SChris Williamson   else return NULL;  /* not a C function */
423*dfc11533SChris Williamson }
424*dfc11533SChris Williamson 
425*dfc11533SChris Williamson 
lua_touserdata(lua_State * L,int idx)426*dfc11533SChris Williamson LUA_API void *lua_touserdata (lua_State *L, int idx) {
427*dfc11533SChris Williamson   StkId o = index2addr(L, idx);
428*dfc11533SChris Williamson   switch (ttypenv(o)) {
429*dfc11533SChris Williamson     case LUA_TUSERDATA: return (rawuvalue(o) + 1);
430*dfc11533SChris Williamson     case LUA_TLIGHTUSERDATA: return pvalue(o);
431*dfc11533SChris Williamson     default: return NULL;
432*dfc11533SChris Williamson   }
433*dfc11533SChris Williamson }
434*dfc11533SChris Williamson 
435*dfc11533SChris Williamson 
lua_tothread(lua_State * L,int idx)436*dfc11533SChris Williamson LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
437*dfc11533SChris Williamson   StkId o = index2addr(L, idx);
438*dfc11533SChris Williamson   return (!ttisthread(o)) ? NULL : thvalue(o);
439*dfc11533SChris Williamson }
440*dfc11533SChris Williamson 
441*dfc11533SChris Williamson 
lua_topointer(lua_State * L,int idx)442*dfc11533SChris Williamson LUA_API const void *lua_topointer (lua_State *L, int idx) {
443*dfc11533SChris Williamson   StkId o = index2addr(L, idx);
444*dfc11533SChris Williamson   switch (ttype(o)) {
445*dfc11533SChris Williamson     case LUA_TTABLE: return hvalue(o);
446*dfc11533SChris Williamson     case LUA_TLCL: return clLvalue(o);
447*dfc11533SChris Williamson     case LUA_TCCL: return clCvalue(o);
448*dfc11533SChris Williamson     case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
449*dfc11533SChris Williamson     case LUA_TTHREAD: return thvalue(o);
450*dfc11533SChris Williamson     case LUA_TUSERDATA:
451*dfc11533SChris Williamson     case LUA_TLIGHTUSERDATA:
452*dfc11533SChris Williamson       return lua_touserdata(L, idx);
453*dfc11533SChris Williamson     default: return NULL;
454*dfc11533SChris Williamson   }
455*dfc11533SChris Williamson }
456*dfc11533SChris Williamson 
457*dfc11533SChris Williamson 
458*dfc11533SChris Williamson 
459*dfc11533SChris Williamson /*
460*dfc11533SChris Williamson ** push functions (C -> stack)
461*dfc11533SChris Williamson */
462*dfc11533SChris Williamson 
463*dfc11533SChris Williamson 
lua_pushnil(lua_State * L)464*dfc11533SChris Williamson LUA_API void lua_pushnil (lua_State *L) {
465*dfc11533SChris Williamson   lua_lock(L);
466*dfc11533SChris Williamson   setnilvalue(L->top);
467*dfc11533SChris Williamson   api_incr_top(L);
468*dfc11533SChris Williamson   lua_unlock(L);
469*dfc11533SChris Williamson }
470*dfc11533SChris Williamson 
471*dfc11533SChris Williamson 
lua_pushnumber(lua_State * L,lua_Number n)472*dfc11533SChris Williamson LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
473*dfc11533SChris Williamson   lua_lock(L);
474*dfc11533SChris Williamson   setnvalue(L->top, n);
475*dfc11533SChris Williamson   luai_checknum(L, L->top,
476*dfc11533SChris Williamson     luaG_runerror(L, "C API - attempt to push a signaling NaN"));
477*dfc11533SChris Williamson   api_incr_top(L);
478*dfc11533SChris Williamson   lua_unlock(L);
479*dfc11533SChris Williamson }
480*dfc11533SChris Williamson 
481*dfc11533SChris Williamson 
lua_pushinteger(lua_State * L,lua_Integer n)482*dfc11533SChris Williamson LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
483*dfc11533SChris Williamson   lua_lock(L);
484*dfc11533SChris Williamson   setnvalue(L->top, cast_num(n));
485*dfc11533SChris Williamson   api_incr_top(L);
486*dfc11533SChris Williamson   lua_unlock(L);
487*dfc11533SChris Williamson }
488*dfc11533SChris Williamson 
489*dfc11533SChris Williamson 
lua_pushunsigned(lua_State * L,lua_Unsigned u)490*dfc11533SChris Williamson LUA_API void lua_pushunsigned (lua_State *L, lua_Unsigned u) {
491*dfc11533SChris Williamson   lua_Number n;
492*dfc11533SChris Williamson   lua_lock(L);
493*dfc11533SChris Williamson   n = lua_unsigned2number(u);
494*dfc11533SChris Williamson   setnvalue(L->top, n);
495*dfc11533SChris Williamson   api_incr_top(L);
496*dfc11533SChris Williamson   lua_unlock(L);
497*dfc11533SChris Williamson }
498*dfc11533SChris Williamson 
499*dfc11533SChris Williamson 
lua_pushlstring(lua_State * L,const char * s,size_t len)500*dfc11533SChris Williamson LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
501*dfc11533SChris Williamson   TString *ts;
502*dfc11533SChris Williamson   lua_lock(L);
503*dfc11533SChris Williamson   luaC_checkGC(L);
504*dfc11533SChris Williamson   ts = luaS_newlstr(L, s, len);
505*dfc11533SChris Williamson   setsvalue2s(L, L->top, ts);
506*dfc11533SChris Williamson   api_incr_top(L);
507*dfc11533SChris Williamson   lua_unlock(L);
508*dfc11533SChris Williamson   return getstr(ts);
509*dfc11533SChris Williamson }
510*dfc11533SChris Williamson 
511*dfc11533SChris Williamson 
lua_pushstring(lua_State * L,const char * s)512*dfc11533SChris Williamson LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
513*dfc11533SChris Williamson   if (s == NULL) {
514*dfc11533SChris Williamson     lua_pushnil(L);
515*dfc11533SChris Williamson     return NULL;
516*dfc11533SChris Williamson   }
517*dfc11533SChris Williamson   else {
518*dfc11533SChris Williamson     TString *ts;
519*dfc11533SChris Williamson     lua_lock(L);
520*dfc11533SChris Williamson     luaC_checkGC(L);
521*dfc11533SChris Williamson     ts = luaS_new(L, s);
522*dfc11533SChris Williamson     setsvalue2s(L, L->top, ts);
523*dfc11533SChris Williamson     api_incr_top(L);
524*dfc11533SChris Williamson     lua_unlock(L);
525*dfc11533SChris Williamson     return getstr(ts);
526*dfc11533SChris Williamson   }
527*dfc11533SChris Williamson }
528*dfc11533SChris Williamson 
529*dfc11533SChris Williamson 
lua_pushvfstring(lua_State * L,const char * fmt,va_list argp)530*dfc11533SChris Williamson LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
531*dfc11533SChris Williamson                                       va_list argp) {
532*dfc11533SChris Williamson   const char *ret;
533*dfc11533SChris Williamson   lua_lock(L);
534*dfc11533SChris Williamson   luaC_checkGC(L);
535*dfc11533SChris Williamson   ret = luaO_pushvfstring(L, fmt, argp);
536*dfc11533SChris Williamson   lua_unlock(L);
537*dfc11533SChris Williamson   return ret;
538*dfc11533SChris Williamson }
539*dfc11533SChris Williamson 
540*dfc11533SChris Williamson 
lua_pushfstring(lua_State * L,const char * fmt,...)541*dfc11533SChris Williamson LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
542*dfc11533SChris Williamson   const char *ret;
543*dfc11533SChris Williamson   va_list argp;
544*dfc11533SChris Williamson   lua_lock(L);
545*dfc11533SChris Williamson   luaC_checkGC(L);
546*dfc11533SChris Williamson   va_start(argp, fmt);
547*dfc11533SChris Williamson   ret = luaO_pushvfstring(L, fmt, argp);
548*dfc11533SChris Williamson   va_end(argp);
549*dfc11533SChris Williamson   lua_unlock(L);
550*dfc11533SChris Williamson   return ret;
551*dfc11533SChris Williamson }
552*dfc11533SChris Williamson 
553*dfc11533SChris Williamson 
lua_pushcclosure(lua_State * L,lua_CFunction fn,int n)554*dfc11533SChris Williamson LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
555*dfc11533SChris Williamson   lua_lock(L);
556*dfc11533SChris Williamson   if (n == 0) {
557*dfc11533SChris Williamson     setfvalue(L->top, fn);
558*dfc11533SChris Williamson   }
559*dfc11533SChris Williamson   else {
560*dfc11533SChris Williamson     Closure *cl;
561*dfc11533SChris Williamson     api_checknelems(L, n);
562*dfc11533SChris Williamson     api_check(L, n <= MAXUPVAL, "upvalue index too large");
563*dfc11533SChris Williamson     luaC_checkGC(L);
564*dfc11533SChris Williamson     cl = luaF_newCclosure(L, n);
565*dfc11533SChris Williamson     cl->c.f = fn;
566*dfc11533SChris Williamson     L->top -= n;
567*dfc11533SChris Williamson     while (n--)
568*dfc11533SChris Williamson       setobj2n(L, &cl->c.upvalue[n], L->top + n);
569*dfc11533SChris Williamson     setclCvalue(L, L->top, cl);
570*dfc11533SChris Williamson   }
571*dfc11533SChris Williamson   api_incr_top(L);
572*dfc11533SChris Williamson   lua_unlock(L);
573*dfc11533SChris Williamson }
574*dfc11533SChris Williamson 
575*dfc11533SChris Williamson 
lua_pushboolean(lua_State * L,int b)576*dfc11533SChris Williamson LUA_API void lua_pushboolean (lua_State *L, int b) {
577*dfc11533SChris Williamson   lua_lock(L);
578*dfc11533SChris Williamson   setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
579*dfc11533SChris Williamson   api_incr_top(L);
580*dfc11533SChris Williamson   lua_unlock(L);
581*dfc11533SChris Williamson }
582*dfc11533SChris Williamson 
583*dfc11533SChris Williamson 
lua_pushlightuserdata(lua_State * L,void * p)584*dfc11533SChris Williamson LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
585*dfc11533SChris Williamson   lua_lock(L);
586*dfc11533SChris Williamson   setpvalue(L->top, p);
587*dfc11533SChris Williamson   api_incr_top(L);
588*dfc11533SChris Williamson   lua_unlock(L);
589*dfc11533SChris Williamson }
590*dfc11533SChris Williamson 
591*dfc11533SChris Williamson 
lua_pushthread(lua_State * L)592*dfc11533SChris Williamson LUA_API int lua_pushthread (lua_State *L) {
593*dfc11533SChris Williamson   lua_lock(L);
594*dfc11533SChris Williamson   setthvalue(L, L->top, L);
595*dfc11533SChris Williamson   api_incr_top(L);
596*dfc11533SChris Williamson   lua_unlock(L);
597*dfc11533SChris Williamson   return (G(L)->mainthread == L);
598*dfc11533SChris Williamson }
599*dfc11533SChris Williamson 
600*dfc11533SChris Williamson 
601*dfc11533SChris Williamson 
602*dfc11533SChris Williamson /*
603*dfc11533SChris Williamson ** get functions (Lua -> stack)
604*dfc11533SChris Williamson */
605*dfc11533SChris Williamson 
606*dfc11533SChris Williamson 
lua_getglobal(lua_State * L,const char * var)607*dfc11533SChris Williamson LUA_API void lua_getglobal (lua_State *L, const char *var) {
608*dfc11533SChris Williamson   Table *reg = hvalue(&G(L)->l_registry);
609*dfc11533SChris Williamson   const TValue *gt;  /* global table */
610*dfc11533SChris Williamson   lua_lock(L);
611*dfc11533SChris Williamson   gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
612*dfc11533SChris Williamson   setsvalue2s(L, L->top++, luaS_new(L, var));
613*dfc11533SChris Williamson   luaV_gettable(L, gt, L->top - 1, L->top - 1);
614*dfc11533SChris Williamson   lua_unlock(L);
615*dfc11533SChris Williamson }
616*dfc11533SChris Williamson 
617*dfc11533SChris Williamson 
lua_gettable(lua_State * L,int idx)618*dfc11533SChris Williamson LUA_API void lua_gettable (lua_State *L, int idx) {
619*dfc11533SChris Williamson   StkId t;
620*dfc11533SChris Williamson   lua_lock(L);
621*dfc11533SChris Williamson   t = index2addr(L, idx);
622*dfc11533SChris Williamson   luaV_gettable(L, t, L->top - 1, L->top - 1);
623*dfc11533SChris Williamson   lua_unlock(L);
624*dfc11533SChris Williamson }
625*dfc11533SChris Williamson 
626*dfc11533SChris Williamson 
lua_getfield(lua_State * L,int idx,const char * k)627*dfc11533SChris Williamson LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
628*dfc11533SChris Williamson   StkId t;
629*dfc11533SChris Williamson   lua_lock(L);
630*dfc11533SChris Williamson   t = index2addr(L, idx);
631*dfc11533SChris Williamson   setsvalue2s(L, L->top, luaS_new(L, k));
632*dfc11533SChris Williamson   api_incr_top(L);
633