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