"SfR Fresh" - the SfR Freeware/Shareware Archive 
Member "lua-5.1.4/src/lapi.c" of archive lua-5.1.4.tar.gz:
As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers.
Alternatively you can here view or download the uninterpreted source code file.
That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
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
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
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
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
89 void luaA_pushobject (lua_State *L, const TValue *o) {
90 setobj2s(L, L->top, o);
91 api_incr_top(L);
92 }
93
94
95 LUA_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
110 LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
111 int i;
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 from->top -= n;
118 for (i = 0; i < n; i++) {
119 setobj2s(to, to->top++, from->top + i);
120 }
121 lua_unlock(to);
122 }
123
124
125 LUA_API void lua_setlevel (lua_State *from, lua_State *to) {
126 to->nCcalls = from->nCcalls;
127 }
128
129
130 LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
131 lua_CFunction old;
132 lua_lock(L);
133 old = G(L)->panic;
134 G(L)->panic = panicf;
135 lua_unlock(L);
136 return old;
137 }
138
139
140 LUA_API lua_State *lua_newthread (lua_State *L) {
141 lua_State *L1;
142 lua_lock(L);
143 luaC_checkGC(L);
144 L1 = luaE_newthread(L);
145 setthvalue(L, L->top, L1);
146 api_incr_top(L);
147 lua_unlock(L);
148 luai_userstatethread(L, L1);
149 return L1;
150 }
151
152
153
154 /*
155 ** basic stack manipulation
156 */
157
158
159 LUA_API int lua_gettop (lua_State *L) {
160 return cast_int(L->top - L->base);
161 }
162
163
164 LUA_API void lua_settop (lua_State *L, int idx) {
165 lua_lock(L);
166 if (idx >= 0) {
167 api_check(L, idx <= L->stack_last - L->base);
168 while (L->top < L->base + idx)
169 setnilvalue(L->top++);
170 L->top = L->base + idx;
171 }
172 else {
173 api_check(L, -(idx+1) <= (L->top - L->base));
174 L->top += idx+1; /* `subtract' index (index is negative) */
175 }
176 lua_unlock(L);
177 }
178
179
180 LUA_API void lua_remove (lua_State *L, int idx) {
181 StkId p;
182 lua_lock(L);
183 p = index2adr(L, idx);
184 api_checkvalidindex(L, p);
185 while (++p < L->top) setobjs2s(L, p-1, p);
186 L->top--;
187 lua_unlock(L);
188 }
189
190
191 LUA_API void lua_insert (lua_State *L, int idx) {
192 StkId p;
193 StkId q;
194 lua_lock(L);
195 p = index2adr(L, idx);
196 api_checkvalidindex(L, p);
197 for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
198 setobjs2s(L, p, L->top);
199 lua_unlock(L);
200 }
201
202
203 LUA_API void lua_replace (lua_State *L, int idx) {
204 StkId o;
205 lua_lock(L);
206 /* explicit test for incompatible code */
207 if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci)
208 luaG_runerror(L, "no calling environment");
209 api_checknelems(L, 1);
210 o = index2adr(L, idx);
211 api_checkvalidindex(L, o);
212 if (idx == LUA_ENVIRONINDEX) {
213 Closure *func = curr_func(L);
214 api_check(L, ttistable(L->top - 1));
215 func->c.env = hvalue(L->top - 1);
216 luaC_barrier(L, func, L->top - 1);
217 }
218 else {
219 setobj(L, o, L->top - 1);
220 if (idx < LUA_GLOBALSINDEX) /* function upvalue? */
221 luaC_barrier(L, curr_func(L), L->top - 1);
222 }
223 L->top--;
224 lua_unlock(L);
225 }
226
227
228 LUA_API void lua_pushvalue (lua_State *L, int idx) {
229 lua_lock(L);
230 setobj2s(L, L->top, index2adr(L, idx));
231 api_incr_top(L);
232 lua_unlock(L);
233 }
234
235
236
237 /*
238 ** access functions (stack -> C)
239 */
240
241
242 LUA_API int lua_type (lua_State *L, int idx) {
243 StkId o = index2adr(L, idx);
244 return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
245 }
246
247
248 LUA_API const char *lua_typename (lua_State *L, int t) {
249 UNUSED(L);
250 return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
251 }
252
253
254 LUA_API int lua_iscfunction (lua_State *L, int idx) {
255 StkId o = index2adr(L, idx);
256 return iscfunction(o);
257 }
258
259
260 LUA_API int lua_isnumber (lua_State *L, int idx) {
261 TValue n;
262 const TValue *o = index2adr(L, idx);
263 return tonumber(o, &n);
264 }
265
266
267 LUA_API int lua_isstring (lua_State *L, int idx) {
268 int t = lua_type(L, idx);
269 return (t == LUA_TSTRING || t == LUA_TNUMBER);
270 }
271
272
273 LUA_API int lua_isuserdata (lua_State *L, int idx) {
274 const TValue *o = index2adr(L, idx);
275 return (ttisuserdata(o) || ttislightuserdata(o));
276 }
277
278
279 LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
280 StkId o1 = index2adr(L, index1);
281 StkId o2 = index2adr(L, index2);
282 return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
283 : luaO_rawequalObj(o1, o2);
284 }
285
286
287 LUA_API int lua_equal (lua_State *L, int index1, int index2) {
288 StkId o1, o2;
289 int i;
290 lua_lock(L); /* may call tag method */
291 o1 = index2adr(L, index1);
292 o2 = index2adr(L, index2);
293 i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2);
294 lua_unlock(L);
295 return i;
296 }
297
298
299 LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
300 StkId o1, o2;
301 int i;
302 lua_lock(L); /* may call tag method */
303 o1 = index2adr(L, index1);
304 o2 = index2adr(L, index2);
305 i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
306 : luaV_lessthan(L, o1, o2);
307 lua_unlock(L);
308 return i;
309 }
310
311
312
313 LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
314 TValue n;
315 const TValue *o = index2adr(L, idx);
316 if (tonumber(o, &n))
317 return nvalue(o);
318 else
319 return 0;
320 }
321
322
323 LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
324 TValue n;
325 const TValue *o = index2adr(L, idx);
326 if (tonumber(o, &n)) {
327 lua_Integer res;
328 lua_Number num = nvalue(o);
329 lua_number2integer(res, num);
330 return res;
331 }
332 else
333 return 0;
334 }
335
336
337 LUA_API int lua_toboolean (lua_State *L, int idx) {
338 const TValue *o = index2adr(L, idx);
339 return !l_isfalse(o);
340 }
341
342
343 LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
344 StkId o = index2adr(L, idx);
345 if (!ttisstring(o)) {
346 lua_lock(L); /* `luaV_tostring' may create a new string */
347 if (!luaV_tostring(L, o)) { /* conversion failed? */
348 if (len != NULL) *len = 0;
349 lua_unlock(L);
350 return NULL;
351 }
352 luaC_checkGC(L);
353 o = index2adr(L, idx); /* previous call may reallocate the stack */
354 lua_unlock(L);
355 }
356 if (len != NULL) *len = tsvalue(o)->len;
357 return svalue(o);
358 }
359
360
361 LUA_API size_t lua_objlen (lua_State *L, int idx) {
362 StkId o = index2adr(L, idx);
363 switch (ttype(o)) {
364 case LUA_TSTRING: return tsvalue(o)->len;
365 case LUA_TUSERDATA: return uvalue(o)->len;
366 case LUA_TTABLE: return luaH_getn(hvalue(o));
367 case LUA_TNUMBER: {
368 size_t l;
369 lua_lock(L); /* `luaV_tostring' may create a new string */
370 l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
371 lua_unlock(L);
372 return l;
373 }
374 default: return 0;
375 }
376 }
377
378
379 LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
380 StkId o = index2adr(L, idx);
381 return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;
382 }
383
384
385 LUA_API void *lua_touserdata (lua_State *L, int idx) {
386 StkId o = index2adr(L, idx);
387 switch (ttype(o)) {
388 case LUA_TUSERDATA: return (rawuvalue(o) + 1);
389 case LUA_TLIGHTUSERDATA: return pvalue(o);
390 default: return NULL;
391 }
392 }
393
394
395 LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
396 StkId o = index2adr(L, idx);
397 return (!ttisthread(o)) ? NULL : thvalue(o);
398 }
399
400
401 LUA_API const void *lua_topointer (lua_State *L, int idx) {
402 StkId o = index2adr(L, idx);
403 switch (ttype(o)) {
404 case LUA_TTABLE: return hvalue(o);
405 case LUA_TFUNCTION: return clvalue(o);
406 case LUA_TTHREAD: return thvalue(o);
407 case LUA_TUSERDATA:
408 case LUA_TLIGHTUSERDATA:
409 return lua_touserdata(L, idx);
410 default: return NULL;
411 }
412 }
413
414
415
416 /*
417 ** push functions (C -> stack)
418 */
419
420
421 LUA_API void lua_pushnil (lua_State *L) {
422 lua_lock(L);
423 setnilvalue(L->top);
424 api_incr_top(L);
425 lua_unlock(L);
426 }
427
428
429 LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
430 lua_lock(L);
431 setnvalue(L->top, n);
432 api_incr_top(L);
433 lua_unlock(L);
434 }
435
436
437 LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
438 lua_lock(L);
439 setnvalue(L->top, cast_num(n));
440 api_incr_top(L);
441 lua_unlock(L);
442 }
443
444
445 LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
446 lua_lock(L);
447 luaC_checkGC(L);
448 setsvalue2s(L, L->top, luaS_newlstr(L, s, len));
449 api_incr_top(L);
450 lua_unlock(L);
451 }
452
453
454 LUA_API void lua_pushstring (lua_State *L, const char *s) {
455 if (s == NULL)
456 lua_pushnil(L);
457 else
458 lua_pushlstring(L, s, strlen(s));
459 }
460
461
462 LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
463 va_list argp) {
464 const char *ret;
465 lua_lock(L);
466 luaC_checkGC(L);
467 ret = luaO_pushvfstring(L, fmt, argp);
468 lua_unlock(L);
469 return ret;
470 }
471
472
473 LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
474 const char *ret;
475 va_list argp;
476 lua_lock(L);
477 luaC_checkGC(L);
478 va_start(argp, fmt);
479 ret = luaO_pushvfstring(L, fmt, argp);
480 va_end(argp);
481 lua_unlock(L);
482 return ret;
483 }
484
485
486 LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
487 Closure *cl;
488 lua_lock(L);
489 luaC_checkGC(L);
490 api_checknelems(L, n);
491 cl = luaF_newCclosure(L, n, getcurrenv(L));
492 cl->c.f = fn;
493 L->top -= n;
494 while (n--)
495 setobj2n(L, &cl->c.upvalue[n], L->top+n);
496 setclvalue(L, L->top, cl);
497 lua_assert(iswhite(obj2gco(cl)));
498 api_incr_top(L);
499 lua_unlock(L);
500 }
501
502
503 LUA_API void lua_pushboolean (lua_State *L, int b) {
504 lua_lock(L);
505 setbvalue(L->top, (b != 0)); /* ensure that true is 1 */
506 api_incr_top(L);
507 lua_unlock(L);
508 }
509
510
511 LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
512 lua_lock(L);
513 setpvalue(L->top, p);
514 api_incr_top(L);
515 lua_unlock(L);
516 }
517
518
519 LUA_API int lua_pushthread (lua_State *L) {
520 lua_lock(L);
521 setthvalue(L, L->top, L);
522 api_incr_top(L);
523 lua_unlock(L);
524 return (G(L)->mainthread == L);
525 }
526
527
528
529 /*
530 ** get functions (Lua -> stack)
531 */
532
533
534 LUA_API void lua_gettable (lua_State *L, int idx) {
535 StkId t;
536 lua_lock(L);
537 t = index2adr(L, idx);
538 api_checkvalidindex(L, t);
539 luaV_gettable(L, t, L->top - 1, L->top - 1);
540 lua_unlock(L);
541 }
542
543
544 LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
545 StkId t;
546 TValue key;
547 lua_lock(L);
548 t = index2adr(L, idx);
549 api_checkvalidindex(L, t);
550 setsvalue(L, &key, luaS_new(L, k));
551 luaV_gettable(L, t, &key, L->top);
552 api_incr_top(L);
553 lua_unlock(L);
554 }
555
556
557 LUA_API void lua_rawget (lua_State *L, int idx) {
558 StkId t;
559 lua_lock(L);
560 t = index2adr(L, idx);
561 api_check(L, ttistable(t));
562 setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
563 lua_unlock(L);
564 }
565
566
567 LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
568 StkId o;
569 lua_lock(L);
570 o = index2adr(L, idx);
571 api_check(L, ttistable(o));
572 setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
573 api_incr_top(L);
574 lua_unlock(L);
575 }
576
577
578 LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
579 lua_lock(L);
580 luaC_checkGC(L);
581 sethvalue(L, L->top, luaH_new(L, narray, nrec));
582 api_incr_top(L);
583 lua_unlock(L);
584 }
585
586
587 LUA_API int lua_getmetatable (lua_State *L, int objindex) {
588 const TValue *obj;
589 Table *mt = NULL;
590 int res;
591 lua_lock(L);
592 obj = index2adr(L, objindex);
593 switch (ttype(obj)) {
594 case LUA_TTABLE:
595 mt = hvalue(obj)->metatable;
596 break;
597 case LUA_TUSERDATA:
598 mt = uvalue(obj)->metatable;
599 break;
600 default:
601 mt = G(L)->mt[ttype(obj)];
602 break;
603 }
604 if (mt == NULL)
605 res = 0;
606 else {
607 sethvalue(L, L->top, mt);
608 api_incr_top(L);
609 res = 1;
610 }
611 lua_unlock(L);
612 return res;
613 }
614
615
616 LUA_API void lua_getfenv (lua_State *L, int idx) {
617 StkId o;
618 lua_lock(L);
619 o = index2adr(L, idx);
620 api_checkvalidindex(L, o);
621 switch (ttype(o)) {
622 case LUA_TFUNCTION:
623 sethvalue(L, L->top, clvalue(o)->c.env);
624 break;
625 case LUA_TUSERDATA:
626 sethvalue(L, L->top, uvalue(o)->env);
627 break;
628 case LUA_TTHREAD:
629 setobj2s(L, L->top, gt(thvalue(o)));
630 break;
631 default:
632 setnilvalue(L->top);
633 break;
634 }
635 api_incr_top(L);
636 lua_unlock(L);
637 }
638
639
640 /*
641 ** set functions (stack -> Lua)
642 */
643
644
645 LUA_API void lua_settable (lua_State *L, int idx) {
646 StkId t;
647 lua_lock(L);
648 api_checknelems(L, 2);
649 t = index2adr(L, idx);
650 api_checkvalidindex(L, t);
651 luaV_settable(L, t, L->top - 2, L->top - 1);
652 L->top -= 2; /* pop index and value */
653 lua_unlock(L);
654 }
655
656
657 LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
658 StkId t;
659 TValue key;
660 lua_lock(L);
661 api_checknelems(L, 1);
662 t = index2adr(L, idx);
663 api_checkvalidindex(L, t);
664 setsvalue(L, &key, luaS_new(L, k));
665 luaV_settable(L, t, &key, L->top - 1);
666 L->top--; /* pop value */
667 lua_unlock(L);
668 }
669
670
671 LUA_API void lua_rawset (lua_State *L, int idx) {
672 StkId t;
673 lua_lock(L);
674 api_checknelems(L, 2);
675 t = index2adr(L, idx);
676 api_check(L, ttistable(t));
677 setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
678 luaC_barriert(L, hvalue(t), L->top-1);
679 L->top -= 2;
680 lua_unlock(L);
681 }
682
683
684 LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
685 StkId o;
686 lua_lock(L);
687 api_checknelems(L, 1);
688 o = index2adr(L, idx);
689 api_check(L, ttistable(o));
690 setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
691 luaC_barriert(L, hvalue(o), L->top-1);
692 L->top--;
693 lua_unlock(L);
694 }
695
696
697 LUA_API int lua_setmetatable (lua_State *L, int objindex) {
698 TValue *obj;
699 Table *mt;
700 lua_lock(L);
701 api_checknelems(L, 1);
702 obj = index2adr(L, objindex);
703 api_checkvalidindex(L, obj);
704 if (ttisnil(L->top - 1))
705 mt = NULL;
706 else {
707 api_check(L, ttistable(L->top - 1));
708 mt = hvalue(L->top - 1);
709 }
710 switch (ttype(obj)) {
711 case LUA_TTABLE: {
712 hvalue(obj)->metatable = mt;
713 if (mt)
714 luaC_objbarriert(L, hvalue(obj), mt);
715 break;
716 }
717 case LUA_TUSERDATA: {
718 uvalue(obj)->metatable = mt;
719 if (mt)
720 luaC_objbarrier(L, rawuvalue(obj), mt);
721 break;
722 }
723 default: {
724 G(L)->mt[ttype(obj)] = mt;
725 break;
726 }
727 }
728 L->top--;
729 lua_unlock(L);
730 return 1;
731 }
732
733
734 LUA_API int lua_setfenv (lua_State *L, int idx) {
735 StkId o;
736 int res = 1;
737 lua_lock(L);
738 api_checknelems(L, 1);
739 o = index2adr(L, idx);
740 api_checkvalidindex(L, o);
741 api_check(L, ttistable(L->top - 1));
742 switch (ttype(o)) {
743 case LUA_TFUNCTION:
744 clvalue(o)->c.env = hvalue(L->top - 1);
745 break;
746 case LUA_TUSERDATA:
747 uvalue(o)->env = hvalue(L->top - 1);
748 break;
749 case LUA_TTHREAD:
750 sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1));
751 break;
752 default:
753 res = 0;
754 break;
755 }
756 if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
757 L->top--;
758 lua_unlock(L);
759 return res;
760 }
761
762
763 /*
764 ** `load' and `call' functions (run Lua code)
765 */
766
767
768 #define adjustresults(L,nres) \
769 { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; }
770
771
772 #define checkresults(L,na,nr) \
773 api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
774
775
776 LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
777 StkId func;
778 lua_lock(L);
779 api_checknelems(L, nargs+1);
780 checkresults(L, nargs, nresults);
781 func = L->top - (nargs+1);
782 luaD_call(L, func, nresults);
783 adjustresults(L, nresults);
784 lua_unlock(L);
785 }
786
787
788
789 /*
790 ** Execute a protected call.
791 */
792 struct CallS { /* data to `f_call' */
793 StkId func;
794 int nresults;
795 };
796
797
798 static void f_call (lua_State *L, void *ud) {
799 struct CallS *c = cast(struct CallS *, ud);
800 luaD_call(L, c->func, c->nresults);
801 }
802
803
804
805 LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
806 struct CallS c;
807 int status;
808 ptrdiff_t func;
809 lua_lock(L);
810 api_checknelems(L, nargs+1);
811 checkresults(L, nargs, nresults);
812 if (errfunc == 0)
813 func = 0;
814 else {
815 StkId o = index2adr(L, errfunc);
816 api_checkvalidindex(L, o);
817 func = savestack(L, o);
818 }
819 c.func = L->top - (nargs+1); /* function to be called */
820 c.nresults = nresults;
821 status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
822 adjustresults(L, nresults);
823 lua_unlock(L);
824 return status;
825 }
826
827
828 /*
829 ** Execute a protected C call.
830 */
831 struct CCallS { /* data to `f_Ccall' */
832 lua_CFunction func;
833 void *ud;
834 };
835
836
837 static void f_Ccall (lua_State *L, void *ud) {
838 struct CCallS *c = cast(struct CCallS *, ud);
839 Closure *cl;
840 cl = luaF_newCclosure(L, 0, getcurrenv(L));
841 cl->c.f = c->func;
842 setclvalue(L, L->top, cl); /* push function */
843 api_incr_top(L);
844 setpvalue(L->top, c->ud); /* push only argument */
845 api_incr_top(L);
846 luaD_call(L, L->top - 2, 0);
847 }
848
849
850 LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
851 struct CCallS c;
852 int status;
853 lua_lock(L);
854 c.func = func;
855 c.ud = ud;
856 status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
857 lua_unlock(L);
858 return status;
859 }
860
861
862 LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
863 const char *chunkname) {
864 ZIO z;
865 int status;
866 lua_lock(L);
867 if (!chunkname) chunkname = "?";
868 luaZ_init(L, &z, reader, data);
869 status = luaD_protectedparser(L, &z, chunkname<