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