|
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); |
|
870 lua_unlock(L); |
|
871 return status; |
|
872 } |
|
873 |
|
874 |
|
875 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 o = L->top - 1; |
|
881 if (isLfunction(o)) |
|
882 status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0); |
|
883 else |
|
884 status = 1; |
|
885 lua_unlock(L); |
|
886 return status; |
|
887 } |
|
888 |
|
889 |
|
890 LUA_API int lua_status (lua_State *L) { |
|
891 return L->status; |
|
892 } |
|
893 |
|
894 |
|
895 /* |
|
896 ** Garbage-collection function |
|
897 */ |
|
898 |
|
899 LUA_API int lua_gc (lua_State *L, int what, int data) { |
|
900 int res = 0; |
|
901 global_State *g; |
|
902 lua_lock(L); |
|
903 g = G(L); |
|
904 switch (what) { |
|
905 case LUA_GCSTOP: { |
|
906 g->GCthreshold = MAX_LUMEM; |
|
907 break; |
|
908 } |
|
909 case LUA_GCRESTART: { |
|
910 g->GCthreshold = g->totalbytes; |
|
911 break; |
|
912 } |
|
913 case LUA_GCCOLLECT: { |
|
914 luaC_fullgc(L); |
|
915 break; |
|
916 } |
|
917 case LUA_GCCOUNT: { |
|
918 /* GC values are expressed in Kbytes: #bytes/2^10 */ |
|
919 res = cast_int(g->totalbytes >> 10); |
|
920 break; |
|
921 } |
|
922 case LUA_GCCOUNTB: { |
|
923 res = cast_int(g->totalbytes & 0x3ff); |
|
924 break; |
|
925 } |
|
926 case LUA_GCSTEP: { |
|
927 lu_mem a = (cast(lu_mem, data) << 10); |
|
928 if (a <= g->totalbytes) |
|
929 g->GCthreshold = g->totalbytes - a; |
|
930 else |
|
931 g->GCthreshold = 0; |
|
932 while (g->GCthreshold <= g->totalbytes) { |
|
933 luaC_step(L); |
|
934 if (g->gcstate == GCSpause) { /* end of cycle? */ |
|
935 res = 1; /* signal it */ |
|
936 break; |
|
937 } |
|
938 } |
|
939 break; |
|
940 } |
|
941 case LUA_GCSETPAUSE: { |
|
942 res = g->gcpause; |
|
943 g->gcpause = data; |
|
944 break; |
|
945 } |
|
946 case LUA_GCSETSTEPMUL: { |
|
947 res = g->gcstepmul; |
|
948 g->gcstepmul = data; |
|
949 break; |
|
950 } |
|
951 default: res = -1; /* invalid option */ |
|
952 } |
|
953 lua_unlock(L); |
|
954 return res; |
|
955 } |
|
956 |
|
957 |
|
958 |
|
959 /* |
|
960 ** miscellaneous functions |
|
961 */ |
|
962 |
|
963 |
|
964 LUA_API int lua_error (lua_State *L) { |
|
965 lua_lock(L); |
|
966 api_checknelems(L, 1); |
|
967 luaG_errormsg(L); |
|
968 lua_unlock(L); |
|
969 return 0; /* to avoid warnings */ |
|
970 } |
|
971 |
|
972 |
|
973 LUA_API int lua_next (lua_State *L, int idx) { |
|
974 StkId t; |
|
975 int more; |
|
976 lua_lock(L); |
|
977 t = index2adr(L, idx); |
|
978 api_check(L, ttistable(t)); |
|
979 more = luaH_next(L, hvalue(t), L->top - 1); |
|
980 if (more) { |
|
981 api_incr_top(L); |
|
982 } |
|
983 else /* no more elements */ |
|
984 L->top -= 1; /* remove key */ |
|
985 lua_unlock(L); |
|
986 return more; |
|
987 } |
|
988 |
|
989 |
|
990 LUA_API void lua_concat (lua_State *L, int n) { |
|
991 lua_lock(L); |
|
992 api_checknelems(L, n); |
|
993 if (n >= 2) { |
|
994 luaC_checkGC(L); |
|
995 luaV_concat(L, n, cast_int(L->top - L->base) - 1); |
|
996 L->top -= (n-1); |
|
997 } |
|
998 else if (n == 0) { /* push empty string */ |
|
999 setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); |
|
1000 api_incr_top(L); |
|
1001 } |
|
1002 /* else n == 1; nothing to do */ |
|
1003 lua_unlock(L); |
|
1004 } |
|
1005 |
|
1006 |
|
1007 LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { |
|
1008 lua_Alloc f; |
|
1009 lua_lock(L); |
|
1010 if (ud) *ud = G(L)->ud; |
|
1011 f = G(L)->frealloc; |
|
1012 lua_unlock(L); |
|
1013 return f; |
|
1014 } |
|
1015 |
|
1016 |
|
1017 LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { |
|
1018 lua_lock(L); |
|
1019 G(L)->ud = ud; |
|
1020 G(L)->frealloc = f; |
|
1021 lua_unlock(L); |
|
1022 } |
|
1023 |
|
1024 |
|
1025 LUA_API void *lua_newuserdata (lua_State *L, size_t size) { |
|
1026 Udata *u; |
|
1027 lua_lock(L); |
|
1028 luaC_checkGC(L); |
|
1029 u = luaS_newudata(L, size, getcurrenv(L)); |
|
1030 setuvalue(L, L->top, u); |
|
1031 api_incr_top(L); |
|
1032 lua_unlock(L); |
|
1033 return u + 1; |
|
1034 } |
|
1035 |
|
1036 |
|
1037 |
|
1038 |
|
1039 static const char *aux_upvalue (StkId fi, int n, TValue **val) { |
|
1040 Closure *f; |
|
1041 if (!ttisfunction(fi)) return NULL; |
|
1042 f = clvalue(fi); |
|
1043 if (f->c.isC) { |
|
1044 if (!(1 <= n && n <= f->c.nupvalues)) return NULL; |
|
1045 *val = &f->c.upvalue[n-1]; |
|
1046 return ""; |
|
1047 } |
|
1048 else { |
|
1049 Proto *p = f->l.p; |
|
1050 if (!(1 <= n && n <= p->sizeupvalues)) return NULL; |
|
1051 *val = f->l.upvals[n-1]->v; |
|
1052 return getstr(p->upvalues[n-1]); |
|
1053 } |
|
1054 } |
|
1055 |
|
1056 |
|
1057 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 name = aux_upvalue(index2adr(L, funcindex), n, &val); |
|
1062 if (name) { |
|
1063 setobj2s(L, L->top, val); |
|
1064 api_incr_top(L); |
|
1065 } |
|
1066 lua_unlock(L); |
|
1067 return name; |
|
1068 } |
|
1069 |
|
1070 |
|
1071 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 fi = index2adr(L, funcindex); |
|
1077 api_checknelems(L, 1); |
|
1078 name = aux_upvalue(fi, n, &val); |
|
1079 if (name) { |
|
1080 L->top--; |
|
1081 setobj(L, val, L->top); |
|
1082 luaC_barrier(L, clvalue(fi), L->top); |
|
1083 } |
|
1084 lua_unlock(L); |
|
1085 return name; |
|
1086 } |
|
1087 |