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