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