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