1 /*
2 ** $Id: lapi.c,v 2.55 2006/06/07 12:37:17 roberto Exp $
3 ** Lua API
4 ** See Copyright Notice in lua.h
5 */
6 
7 
8 #include <assert.h>
9 #include <math.h>
10 #include <stdarg.h>
11 #include <string.h>
12 
13 #define lapi_c
14 #define LUA_CORE
15 
16 #include "lua.h"
17 
18 #include "lapi.h"
19 #include "ldebug.h"
20 #include "ldo.h"
21 #include "lfunc.h"
22 #include "lgc.h"
23 #include "lmem.h"
24 #include "lobject.h"
25 #include "lstate.h"
26 #include "lstring.h"
27 #include "ltable.h"
28 #include "ltm.h"
29 #include "lundump.h"
30 #include "lvm.h"
31 
32 
33 
34 const char lua_ident[] =
35   "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n"
36   "$Authors: " LUA_AUTHORS " $\n"
37   "$URL: www.lua.org $\n";
38 
39 
40 
41 #define api_checknelems(L, n)	api_check(L, (n) <= (L->top - L->base))
42 
43 #define api_checkvalidindex(L, i)	api_check(L, (i) != luaO_nilobject)
44 
45 #define api_incr_top(L)   {api_check(L, L->top < L->ci->top); L->top++;}
46 
47 
48 
index2adr(lua_State * L,int idx)49 static TValue *index2adr (lua_State *L, int idx) {
50   if (idx > 0) {
51     TValue *o = L->base + (idx - 1);
52     api_check(L, idx <= L->ci->top - L->base);
53     if (o >= L->top) return cast(TValue *, luaO_nilobject);
54     else return o;
55   }
56   else if (idx > LUA_REGISTRYINDEX) {
57     api_check(L, idx != 0 && -idx <= L->top - L->base);
58     return L->top + idx;
59   }
60   else switch (idx) {  /* pseudo-indices */
61     case LUA_REGISTRYINDEX: return registry(L);
62     case LUA_ENVIRONINDEX: {
63       Closure *func = curr_func(L);
64       sethvalue(L, &L->env, func->c.env);
65       return &L->env;
66     }
67     case LUA_GLOBALSINDEX: return gt(L);
68     default: {
69       Closure *func = curr_func(L);
70       idx = LUA_GLOBALSINDEX - idx;
71       return (idx <= func->c.nupvalues)
72                 ? &func->c.upvalue[idx-1]
73                 : cast(TValue *, luaO_nilobject);
74     }
75   }
76 }
77 
78 
getcurrenv(lua_State * L)79 static Table *getcurrenv (lua_State *L) {
80   if (L->ci == L->base_ci)  /* no enclosing function? */
81     return hvalue(gt(L));  /* use global table as environment */
82   else {
83     Closure *func = curr_func(L);
84     return func->c.env;
85   }
86 }
87 
88 
luaA_pushobject(lua_State * L,const TValue * o)89 void luaA_pushobject (lua_State *L, const TValue *o) {
90   setobj2s(L, L->top, o);
91   api_incr_top(L);
92 }
93 
94 
lua_checkstack(lua_State * L,int size)95 LUA_API int lua_checkstack (lua_State *L, int size) {
96   int res;
97   lua_lock(L);
98   if ((L->top - L->base + size) > LUAI_MAXCSTACK)
99     res = 0;  /* stack overflow */
100   else {
101     luaD_checkstack(L, size);
102     if (L->ci->top < L->top + size)
103       L->ci->top = L->top + size;
104     res = 1;
105   }
106   lua_unlock(L);
107   return res;
108 }
109 
110 
lua_xmove(lua_State * from,lua_State * to,int n)111 LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
112   int i;
113   if (from == to) return;
114   lua_lock(to);
115   api_checknelems(from, n);
116   api_check(from, G(from) == G(to));
117   api_check(from, to->ci->top - to->top >= n);
118   from->top -= n;
119   for (i = 0; i < n; i++) {
120     setobj2s(to, to->top++, from->top + i);
121   }
122   lua_unlock(to);
123 }
124 
125 
lua_atpanic(lua_State * L,lua_CFunction panicf)126 LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
127   lua_CFunction old;
128   lua_lock(L);
129   old = G(L)->panic;
130   G(L)->panic = panicf;
131   lua_unlock(L);
132   return old;
133 }
134 
135 
lua_newthread(lua_State * L)136 LUA_API lua_State *lua_newthread (lua_State *L) {
137   lua_State *L1;
138   lua_lock(L);
139   luaC_checkGC(L);
140   L1 = luaE_newthread(L);
141   setthvalue(L, L->top, L1);
142   api_incr_top(L);
143   lua_unlock(L);
144   luai_userstatethread(L, L1);
145   return L1;
146 }
147 
148 
149 
150 /*
151 ** basic stack manipulation
152 */
153 
154 
lua_gettop(lua_State * L)155 LUA_API int lua_gettop (lua_State *L) {
156   return cast_int(L->top - L->base);
157 }
158 
159 
lua_settop(lua_State * L,int idx)160 LUA_API void lua_settop (lua_State *L, int idx) {
161   lua_lock(L);
162   if (idx >= 0) {
163     api_check(L, idx <= L->stack_last - L->base);
164     while (L->top < L->base + idx)
165       setnilvalue(L->top++);
166     L->top = L->base + idx;
167   }
168   else {
169     api_check(L, -(idx+1) <= (L->top - L->base));
170     L->top += idx+1;  /* `subtract' index (index is negative) */
171   }
172   lua_unlock(L);
173 }
174 
175 
lua_remove(lua_State * L,int idx)176 LUA_API void lua_remove (lua_State *L, int idx) {
177   StkId p;
178   lua_lock(L);
179   p = index2adr(L, idx);
180   api_checkvalidindex(L, p);
181   while (++p < L->top) setobjs2s(L, p-1, p);
182   L->top--;
183   lua_unlock(L);
184 }
185 
186 
lua_insert(lua_State * L,int idx)187 LUA_API void lua_insert (lua_State *L, int idx) {
188   StkId p;
189   StkId q;
190   lua_lock(L);
191   p = index2adr(L, idx);
192   api_checkvalidindex(L, p);
193   for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
194   setobjs2s(L, p, L->top);
195   lua_unlock(L);
196 }
197 
198 
lua_replace(lua_State * L,int idx)199 LUA_API void lua_replace (lua_State *L, int idx) {
200   StkId o;
201   lua_lock(L);
202   /* explicit test for incompatible code */
203   if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci)
204     luaG_runerror(L, "no calling environment");
205   api_checknelems(L, 1);
206   o = index2adr(L, idx);
207   api_checkvalidindex(L, o);
208   if (idx == LUA_ENVIRONINDEX) {
209     Closure *func = curr_func(L);
210     api_check(L, ttistable(L->top - 1));
211     func->c.env = hvalue(L->top - 1);
212     luaC_barrier(L, func, L->top - 1);
213   }
214   else {
215     setobj(L, o, L->top - 1);
216     if (idx < LUA_GLOBALSINDEX)  /* function upvalue? */
217       luaC_barrier(L, curr_func(L), L->top - 1);
218   }
219   L->top--;
220   lua_unlock(L);
221 }
222 
223 
lua_pushvalue(lua_State * L,int idx)224 LUA_API void lua_pushvalue (lua_State *L, int idx) {
225   lua_lock(L);
226   setobj2s(L, L->top, index2adr(L, idx));
227   api_incr_top(L);
228   lua_unlock(L);
229 }
230 
231 
232 
233 /*
234 ** access functions (stack -> C)
235 */
236 
237 
lua_type(lua_State * L,int idx)238 LUA_API int lua_type (lua_State *L, int idx) {
239   StkId o = index2adr(L, idx);
240   return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
241 }
242 
243 
lua_typename(lua_State * L,int t)244 LUA_API const char *lua_typename (lua_State *L, int t) {
245   UNUSED(L);
246   return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
247 }
248 
249 
lua_iscfunction(lua_State * L,int idx)250 LUA_API int lua_iscfunction (lua_State *L, int idx) {
251   StkId o = index2adr(L, idx);
252   return iscfunction(o);
253 }
254 
255 
lua_isnumber(lua_State * L,int idx)256 LUA_API int lua_isnumber (lua_State *L, int idx) {
257   TValue n;
258   const TValue *o = index2adr(L, idx);
259   return tonumber(o, &n);
260 }
261 
262 
lua_isstring(lua_State * L,int idx)263 LUA_API int lua_isstring (lua_State *L, int idx) {
264   int t = lua_type(L, idx);
265   return (t == LUA_TSTRING || t == LUA_TNUMBER);
266 }
267 
268 
lua_isuserdata(lua_State * L,int idx)269 LUA_API int lua_isuserdata (lua_State *L, int idx) {
270   const TValue *o = index2adr(L, idx);
271   return (ttisuserdata(o) || ttislightuserdata(o));
272 }
273 
274 
lua_rawequal(lua_State * L,int index1,int index2)275 LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
276   StkId o1 = index2adr(L, index1);
277   StkId o2 = index2adr(L, index2);
278   return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
279          : luaO_rawequalObj(o1, o2);
280 }
281 
282 
lua_equal(lua_State * L,int index1,int index2)283 LUA_API int lua_equal (lua_State *L, int index1, int index2) {
284   StkId o1, o2;
285   int i;
286   lua_lock(L);  /* may call tag method */
287   o1 = index2adr(L, index1);
288   o2 = index2adr(L, index2);
289   i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2);
290   lua_unlock(L);
291   return i;
292 }
293 
294 
lua_lessthan(lua_State * L,int index1,int index2)295 LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
296   StkId o1, o2;
297   int i;
298   lua_lock(L);  /* may call tag method */
299   o1 = index2adr(L, index1);
300   o2 = index2adr(L, index2);
301   i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
302        : luaV_lessthan(L, o1, o2);
303   lua_unlock(L);
304   return i;
305 }
306 
307 
308 
lua_tonumber(lua_State * L,int idx)309 LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
310   TValue n;
311   const TValue *o = index2adr(L, idx);
312   if (tonumber(o, &n))
313     return nvalue(o);
314   else
315     return 0;
316 }
317 
318 
lua_tointeger(lua_State * L,int idx)319 LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
320   TValue n;
321   const TValue *o = index2adr(L, idx);
322   if (tonumber(o, &n)) {
323     lua_Integer res;
324     lua_Number num = nvalue(o);
325     lua_number2integer(res, num);
326     return res;
327   }
328   else
329     return 0;
330 }
331 
332 
lua_toboolean(lua_State * L,int idx)333 LUA_API int lua_toboolean (lua_State *L, int idx) {
334   const TValue *o = index2adr(L, idx);
335   return !l_isfalse(o);
336 }
337 
338 
lua_tolstring(lua_State * L,int idx,size_t * len)339 LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
340   StkId o = index2adr(L, idx);
341   if (!ttisstring(o)) {
342     lua_lock(L);  /* `luaV_tostring' may create a new string */
343     if (!luaV_tostring(L, o)) {  /* conversion failed? */
344       if (len != NULL) *len = 0;
345       lua_unlock(L);
346       return NULL;
347     }
348     luaC_checkGC(L);
349     o = index2adr(L, idx);  /* previous call may reallocate the stack */
350     lua_unlock(L);
351   }
352   if (len != NULL) *len = tsvalue(o)->len;
353   return svalue(o);
354 }
355 
356 
lua_objlen(lua_State * L,int idx)357 LUA_API size_t lua_objlen (lua_State *L, int idx) {
358   StkId o = index2adr(L, idx);
359   switch (ttype(o)) {
360     case LUA_TSTRING: return tsvalue(o)->len;
361     case LUA_TUSERDATA: return uvalue(o)->len;
362     case LUA_TTABLE: return luaH_getn(hvalue(o));
363     case LUA_TNUMBER: {
364       size_t l;
365       lua_lock(L);  /* `luaV_tostring' may create a new string */
366       l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
367       lua_unlock(L);
368       return l;
369     }
370     default: return 0;
371   }
372 }
373 
374 
lua_tocfunction(lua_State * L,int idx)375 LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
376   StkId o = index2adr(L, idx);
377   return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;
378 }
379 
380 
lua_touserdata(lua_State * L,int idx)381 LUA_API void *lua_touserdata (lua_State *L, int idx) {
382   StkId o = index2adr(L, idx);
383   switch (ttype(o)) {
384     case LUA_TUSERDATA: return (rawuvalue(o) + 1);
385     case LUA_TLIGHTUSERDATA: return pvalue(o);
386     default: return NULL;
387   }
388 }
389 
390 
lua_tothread(lua_State * L,int idx)391 LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
392   StkId o = index2adr(L, idx);
393   return (!ttisthread(o)) ? NULL : thvalue(o);
394 }
395 
396 
lua_topointer(lua_State * L,int idx)397 LUA_API const void *lua_topointer (lua_State *L, int idx) {
398   StkId o = index2adr(L, idx);
399   switch (ttype(o)) {
400     case LUA_TTABLE: return hvalue(o);
401     case LUA_TFUNCTION: return clvalue(o);
402     case LUA_TTHREAD: return thvalue(o);
403     case LUA_TUSERDATA:
404     case LUA_TLIGHTUSERDATA:
405       return lua_touserdata(L, idx);
406     default: return NULL;
407   }
408 }
409 
410 
411 
412 /*
413 ** push functions (C -> stack)
414 */
415 
416 
lua_pushnil(lua_State * L)417 LUA_API void lua_pushnil (lua_State *L) {
418   lua_lock(L);
419   setnilvalue(L->top);
420   api_incr_top(L);
421   lua_unlock(L);
422 }
423 
424 
lua_pushnumber(lua_State * L,lua_Number n)425 LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
426   lua_lock(L);
427   setnvalue(L->top, n);
428   api_incr_top(L);
429   lua_unlock(L);
430 }
431 
432 
lua_pushinteger(lua_State * L,lua_Integer n)433 LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
434   lua_lock(L);
435   setnvalue(L->top, cast_num(n));
436   api_incr_top(L);
437   lua_unlock(L);
438 }
439 
440 
lua_pushlstring(lua_State * L,const char * s,size_t len)441 LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
442   lua_lock(L);
443   luaC_checkGC(L);
444   setsvalue2s(L, L->top, luaS_newlstr(L, s, len));
445   api_incr_top(L);
446   lua_unlock(L);
447 }
448 
449 
lua_pushstring(lua_State * L,const char * s)450 LUA_API void lua_pushstring (lua_State *L, const char *s) {
451   if (s == NULL)
452     lua_pushnil(L);
453   else
454     lua_pushlstring(L, s, strlen(s));
455 }
456 
457 
lua_pushvfstring(lua_State * L,const char * fmt,va_list argp)458 LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
459                                       va_list argp) {
460   const char *ret;
461   lua_lock(L);
462   luaC_checkGC(L);
463   ret = luaO_pushvfstring(L, fmt, argp);
464   lua_unlock(L);
465   return ret;
466 }
467 
468 
lua_pushfstring(lua_State * L,const char * fmt,...)469 LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
470   const char *ret;
471   va_list argp;
472   lua_lock(L);
473   luaC_checkGC(L);
474   va_start(argp, fmt);
475   ret = luaO_pushvfstring(L, fmt, argp);
476   va_end(argp);
477   lua_unlock(L);
478   return ret;
479 }
480 
481 
lua_pushcclosure(lua_State * L,lua_CFunction fn,int n)482 LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
483   Closure *cl;
484   lua_lock(L);
485   luaC_checkGC(L);
486   api_checknelems(L, n);
487   cl = luaF_newCclosure(L, n, getcurrenv(L));
488   cl->c.f = fn;
489   L->top -= n;
490   while (n--)
491     setobj2n(L, &cl->c.upvalue[n], L->top+n);
492   setclvalue(L, L->top, cl);
493   lua_assert(iswhite(obj2gco(cl)));
494   api_incr_top(L);
495   lua_unlock(L);
496 }
497 
498 
lua_pushboolean(lua_State * L,int b)499 LUA_API void lua_pushboolean (lua_State *L, int b) {
500   lua_lock(L);
501   setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
502   api_incr_top(L);
503   lua_unlock(L);
504 }
505 
506 
lua_pushlightuserdata(lua_State * L,void * p)507 LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
508   lua_lock(L);
509   setpvalue(L->top, p);
510   api_incr_top(L);
511   lua_unlock(L);
512 }
513 
514 
lua_pushthread(lua_State * L)515 LUA_API int lua_pushthread (lua_State *L) {
516   lua_lock(L);
517   setthvalue(L, L->top, L);
518   api_incr_top(L);
519   lua_unlock(L);
520   return (G(L)->mainthread == L);
521 }
522 
523 
524 
525 /*
526 ** get functions (Lua -> stack)
527 */
528 
529 
lua_gettable(lua_State * L,int idx)530 LUA_API void lua_gettable (lua_State *L, int idx) {
531   StkId t;
532   lua_lock(L);
533   t = index2adr(L, idx);
534   api_checkvalidindex(L, t);
535   luaV_gettable(L, t, L->top - 1, L->top - 1);
536   lua_unlock(L);
537 }
538 
539 
lua_getfield(lua_State * L,int idx,const char * k)540 LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
541   StkId t;
542   TValue key;
543   lua_lock(L);
544   t = index2adr(L, idx);
545   api_checkvalidindex(L, t);
546   setsvalue(L, &key, luaS_new(L, k));
547   luaV_gettable(L, t, &key, L->top);
548   api_incr_top(L);
549   lua_unlock(L);
550 }
551 
552 
lua_rawget(lua_State * L,int idx)553 LUA_API void lua_rawget (lua_State *L, int idx) {
554   StkId t;
555   lua_lock(L);
556   t = index2adr(L, idx);
557   api_check(L, ttistable(t));
558   setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
559   lua_unlock(L);
560 }
561 
562 
lua_rawgeti(lua_State * L,int idx,int n)563 LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
564   StkId o;
565   lua_lock(L);
566   o = index2adr(L, idx);
567   api_check(L, ttistable(o));
568   setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
569   api_incr_top(L);
570   lua_unlock(L);
571 }
572 
573 
lua_createtable(lua_State * L,int narray,int nrec)574 LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
575   lua_lock(L);
576   luaC_checkGC(L);
577   sethvalue(L, L->top, luaH_new(L, narray, nrec));
578   api_incr_top(L);
579   lua_unlock(L);
580 }
581 
582 
lua_getmetatable(lua_State * L,int objindex)583 LUA_API int lua_getmetatable (lua_State *L, int objindex) {
584   const TValue *obj;
585   Table *mt = NULL;
586   int res;
587   lua_lock(L);
588   obj = index2adr(L, objindex);
589   switch (ttype(obj)) {
590     case LUA_TTABLE:
591       mt = hvalue(obj)->metatable;
592       break;
593     case LUA_TUSERDATA:
594       mt = uvalue(obj)->metatable;
595       break;
596     default:
597       mt = G(L)->mt[ttype(obj)];
598       break;
599   }
600   if (mt == NULL)
601     res = 0;
602   else {
603     sethvalue(L, L->top, mt);
604     api_incr_top(L);
605     res = 1;
606   }
607   lua_unlock(L);
608   return res;
609 }
610 
611 
lua_getfenv(lua_State * L,int idx)612 LUA_API void lua_getfenv (lua_State *L, int idx) {
613   StkId o;
614   lua_lock(L);
615   o = index2adr(L, idx);
616   api_checkvalidindex(L, o);
617   switch (ttype(o)) {
618     case LUA_TFUNCTION:
619       sethvalue(L, L->top, clvalue(o)->c.env);
620       break;
621     case LUA_TUSERDATA:
622       sethvalue(L, L->top, uvalue(o)->env);
623       break;
624     case LUA_TTHREAD:
625       setobj2s(L, L->top,  gt(thvalue(o)));
626       break;
627     default:
628       setnilvalue(L->top);
629       break;
630   }
631   api_incr_top(L);
632   lua_unlock(L);
633 }
634 
635 
636 /*
637 ** set functions (stack -> Lua)
638 */
639 
640 
lua_settable(lua_State * L,int idx)641 LUA_API void lua_settable (lua_State *L, int idx) {
642   StkId t;
643   lua_lock(L);
644   api_checknelems(L, 2);
645   t = index2adr(L, idx);
646   api_checkvalidindex(L, t);
647   luaV_settable(L, t, L->top - 2, L->top - 1);
648   L->top -= 2;  /* pop index and value */
649   lua_unlock(L);
650 }
651 
652 
lua_setfield(lua_State * L,int idx,const char * k)653 LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
654   StkId t;
655   TValue key;
656   lua_lock(L);
657   api_checknelems(L, 1);
658   t = index2adr(L, idx);
659   api_checkvalidindex(L, t);
660   setsvalue(L, &key, luaS_new(L, k));
661   luaV_settable(L, t, &key, L->top - 1);
662   L->top--;  /* pop value */
663   lua_unlock(L);
664 }
665 
666 
lua_rawset(lua_State * L,int idx)667 LUA_API void lua_rawset (lua_State *L, int idx) {
668   StkId t;
669   lua_lock(L);
670   api_checknelems(L, 2);
671   t = index2adr(L, idx);
672   api_check(L, ttistable(t));
673   setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
674   luaC_barriert(L, hvalue(t), L->top-1);
675   L->top -= 2;
676   lua_unlock(L);
677 }
678 
679 
lua_rawseti(lua_State * L,int idx,int n)680 LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
681   StkId o;
682   lua_lock(L);
683   api_checknelems(L, 1);
684   o = index2adr(L, idx);
685   api_check(L, ttistable(o));
686   setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
687   luaC_barriert(L, hvalue(o), L->top-1);
688   L->top--;
689   lua_unlock(L);
690 }
691 
692 
lua_setmetatable(lua_State * L,int objindex)693 LUA_API int lua_setmetatable (lua_State *L, int objindex) {
694   TValue *obj;
695   Table *mt;
696   lua_lock(L);
697   api_checknelems(L, 1);
698   obj = index2adr(L, objindex);
699   api_checkvalidindex(L, obj);
700   if (ttisnil(L->top - 1))
701     mt = NULL;
702   else {
703     api_check(L, ttistable(L->top - 1));
704     mt = hvalue(L->top - 1);
705   }
706   switch (ttype(obj)) {
707     case LUA_TTABLE: {
708       hvalue(obj)->metatable = mt;
709       if (mt)
710         luaC_objbarriert(L, hvalue(obj), mt);
711       break;
712     }
713     case LUA_TUSERDATA: {
714       uvalue(obj)->metatable = mt;
715       if (mt)
716         luaC_objbarrier(L, rawuvalue(obj), mt);
717       break;
718     }
719     default: {
720       G(L)->mt[ttype(obj)] = mt;
721       break;
722     }
723   }
724   L->top--;
725   lua_unlock(L);
726   return 1;
727 }
728 
729 
lua_setfenv(lua_State * L,int idx)730 LUA_API int lua_setfenv (lua_State *L, int idx) {
731   StkId o;
732   int res = 1;
733   lua_lock(L);
734   api_checknelems(L, 1);
735   o = index2adr(L, idx);
736   api_checkvalidindex(L, o);
737   api_check(L, ttistable(L->top - 1));
738   switch (ttype(o)) {
739     case LUA_TFUNCTION:
740       clvalue(o)->c.env = hvalue(L->top - 1);
741       break;
742     case LUA_TUSERDATA:
743       uvalue(o)->env = hvalue(L->top - 1);
744       break;
745     case LUA_TTHREAD:
746       sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1));
747       break;
748     default:
749       res = 0;
750       break;
751   }
752   luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
753   L->top--;
754   lua_unlock(L);
755   return res;
756 }
757 
758 
759 /*
760 ** `load' and `call' functions (run Lua code)
761 */
762 
763 
764 #define adjustresults(L,nres) \
765     { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; }
766 
767 
768 #define checkresults(L,na,nr) \
769      api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
770 
771 
lua_call(lua_State * L,int nargs,int nresults)772 LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
773   StkId func;
774   lua_lock(L);
775   api_checknelems(L, nargs+1);
776   checkresults(L, nargs, nresults);
777   func = L->top - (nargs+1);
778   luaD_call(L, func, nresults);
779   adjustresults(L, nresults);
780   lua_unlock(L);
781 }
782 
783 
784 
785 /*
786 ** Execute a protected call.
787 */
788 struct CallS {  /* data to `f_call' */
789   StkId func;
790   int nresults;
791 };
792 
793 
f_call(lua_State * L,void * ud)794 static void f_call (lua_State *L, void *ud) {
795   struct CallS *c = cast(struct CallS *, ud);
796   luaD_call(L, c->func, c->nresults);
797 }
798 
799 
800 
lua_pcall(lua_State * L,int nargs,int nresults,int errfunc)801 LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
802   struct CallS c;
803   int status;
804   ptrdiff_t func;
805   lua_lock(L);
806   api_checknelems(L, nargs+1);
807   checkresults(L, nargs, nresults);
808   if (errfunc == 0)
809     func = 0;
810   else {
811     StkId o = index2adr(L, errfunc);
812     api_checkvalidindex(L, o);
813     func = savestack(L, o);
814   }
815   c.func = L->top - (nargs+1);  /* function to be called */
816   c.nresults = nresults;
817   status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
818   adjustresults(L, nresults);
819   lua_unlock(L);
820   return status;
821 }
822 
823 
824 /*
825 ** Execute a protected C call.
826 */
827 struct CCallS {  /* data to `f_Ccall' */
828   lua_CFunction func;
829   void *ud;
830 };
831 
832 
f_Ccall(lua_State * L,void * ud)833 static void f_Ccall (lua_State *L, void *ud) {
834   struct CCallS *c = cast(struct CCallS *, ud);
835   Closure *cl;
836   cl = luaF_newCclosure(L, 0, getcurrenv(L));
837   cl->c.f = c->func;
838   setclvalue(L, L->top, cl);  /* push function */
839   api_incr_top(L);
840   setpvalue(L->top, c->ud);  /* push only argument */
841   api_incr_top(L);
842   luaD_call(L, L->top - 2, 0);
843 }
844 
845 
lua_cpcall(lua_State * L,lua_CFunction func,void * ud)846 LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
847   struct CCallS c;
848   int status;
849   lua_lock(L);
850   c.func = func;
851   c.ud = ud;
852   status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
853   lua_unlock(L);
854   return status;
855 }
856 
857 
lua_load(lua_State * L,lua_Reader reader,void * data,const char * chunkname)858 LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
859                       const char *chunkname) {
860   ZIO z;
861   int status;
862   lua_lock(L);
863   if (!chunkname) chunkname = "?";
864   luaZ_init(L, &z, reader, data);
865   status = luaD_protectedparser(L, &z, chunkname);
866   lua_unlock(L);
867   return status;
868 }
869 
870 
lua_dump(lua_State * L,lua_Writer writer,void * data)871 LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
872   int status;
873   TValue *o;
874   lua_lock(L);
875   api_checknelems(L, 1);
876   o = L->top - 1;
877   if (isLfunction(o))
878     status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
879   else
880     status = 1;
881   lua_unlock(L);
882   return status;
883 }
884 
885 
lua_status(lua_State * L)886 LUA_API int  lua_status (lua_State *L) {
887   return L->status;
888 }
889 
890 
891 /*
892 ** Garbage-collection function
893 */
894 
lua_gc(lua_State * L,int what,int data)895 LUA_API int lua_gc (lua_State *L, int what, int data) {
896   int res = 0;
897   global_State *g;
898   lua_lock(L);
899   g = G(L);
900   switch (what) {
901     case LUA_GCSTOP: {
902       g->GCthreshold = MAX_LUMEM;
903       break;
904     }
905     case LUA_GCRESTART: {
906       g->GCthreshold = g->totalbytes;
907       break;
908     }
909     case LUA_GCCOLLECT: {
910       luaC_fullgc(L);
911       break;
912     }
913     case LUA_GCCOUNT: {
914       /* GC values are expressed in Kbytes: #bytes/2^10 */
915       res = cast_int(g->totalbytes >> 10);
916       break;
917     }
918     case LUA_GCCOUNTB: {
919       res = cast_int(g->totalbytes & 0x3ff);
920       break;
921     }
922     case LUA_GCSTEP: {
923       lu_mem a = (cast(lu_mem, data) << 10);
924       if (a <= g->totalbytes)
925         g->GCthreshold = g->totalbytes - a;
926       else
927         g->GCthreshold = 0;
928       while (g->GCthreshold <= g->totalbytes)
929         luaC_step(L);
930       if (g->gcstate == GCSpause)  /* end of cycle? */
931         res = 1;  /* signal it */
932       break;
933     }
934     case LUA_GCSETPAUSE: {
935       res = g->gcpause;
936       g->gcpause = data;
937       break;
938     }
939     case LUA_GCSETSTEPMUL: {
940       res = g->gcstepmul;
941       g->gcstepmul = data;
942       break;
943     }
944     default: res = -1;  /* invalid option */
945   }
946   lua_unlock(L);
947   return res;
948 }
949 
950 
951 
952 /*
953 ** miscellaneous functions
954 */
955 
956 
lua_error(lua_State * L)957 LUA_API int lua_error (lua_State *L) {
958   lua_lock(L);
959   api_checknelems(L, 1);
960   luaG_errormsg(L);
961   lua_unlock(L);
962   return 0;  /* to avoid warnings */
963 }
964 
965 
lua_next(lua_State * L,int idx)966 LUA_API int lua_next (lua_State *L, int idx) {
967   StkId t;
968   int more;
969   lua_lock(L);
970   t = index2adr(L, idx);
971   api_check(L, ttistable(t));
972   more = luaH_next(L, hvalue(t), L->top - 1);
973   if (more) {
974     api_incr_top(L);
975   }
976   else  /* no more elements */
977     L->top -= 1;  /* remove key */
978   lua_unlock(L);
979   return more;
980 }
981 
982 
lua_concat(lua_State * L,int n)983 LUA_API void lua_concat (lua_State *L, int n) {
984   lua_lock(L);
985   api_checknelems(L, n);
986   if (n >= 2) {
987     luaC_checkGC(L);
988     luaV_concat(L, n, cast_int(L->top - L->base) - 1);
989     L->top -= (n-1);
990   }
991   else if (n == 0) {  /* push empty string */
992     setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
993     api_incr_top(L);
994   }
995   /* else n == 1; nothing to do */
996   lua_unlock(L);
997 }
998 
999 
lua_getallocf(lua_State * L,void ** ud)1000 LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
1001   lua_Alloc f;
1002   lua_lock(L);
1003   if (ud) *ud = G(L)->ud;
1004   f = G(L)->frealloc;
1005   lua_unlock(L);
1006   return f;
1007 }
1008 
1009 
lua_setallocf(lua_State * L,lua_Alloc f,void * ud)1010 LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
1011   lua_lock(L);
1012   G(L)->ud = ud;
1013   G(L)->frealloc = f;
1014   lua_unlock(L);
1015 }
1016 
1017 
lua_newuserdata(lua_State * L,size_t size)1018 LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
1019   Udata *u;
1020   lua_lock(L);
1021   luaC_checkGC(L);
1022   u = luaS_newudata(L, size, getcurrenv(L));
1023   setuvalue(L, L->top, u);
1024   api_incr_top(L);
1025   lua_unlock(L);
1026   return u + 1;
1027 }
1028 
1029 
1030 
1031 
aux_upvalue(StkId fi,int n,TValue ** val)1032 static const char *aux_upvalue (StkId fi, int n, TValue **val) {
1033   Closure *f;
1034   if (!ttisfunction(fi)) return NULL;
1035   f = clvalue(fi);
1036   if (f->c.isC) {
1037     if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
1038     *val = &f->c.upvalue[n-1];
1039     return "";
1040   }
1041   else {
1042     Proto *p = f->l.p;
1043     if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
1044     *val = f->l.upvals[n-1]->v;
1045     return getstr(p->upvalues[n-1]);
1046   }
1047 }
1048 
1049 
lua_getupvalue(lua_State * L,int funcindex,int n)1050 LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
1051   const char *name;
1052   TValue *val;
1053   lua_lock(L);
1054   name = aux_upvalue(index2adr(L, funcindex), n, &val);
1055   if (name) {
1056     setobj2s(L, L->top, val);
1057     api_incr_top(L);
1058   }
1059   lua_unlock(L);
1060   return name;
1061 }
1062 
1063 
lua_setupvalue(lua_State * L,int funcindex,int n)1064 LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
1065   const char *name;
1066   TValue *val;
1067   StkId fi;
1068   lua_lock(L);
1069   fi = index2adr(L, funcindex);
1070   api_checknelems(L, 1);
1071   name = aux_upvalue(fi, n, &val);
1072   if (name) {
1073     L->top--;
1074     setobj(L, val, L->top);
1075     luaC_barrier(L, clvalue(fi), L->top);
1076   }
1077   lua_unlock(L);
1078   return name;
1079 }
1080 
1081