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