1 /*
2 ** $Id: lapi.c $
3 ** Lua API
4 ** See Copyright Notice in lua.h
5 */
6
7 #define lapi_c
8 #define LUA_CORE
9
10 #include "lprefix.h"
11
12
13 #include <limits.h>
14 #include <stdarg.h>
15 #include <string.h>
16
17 #include "lua.h"
18
19 #include "lapi.h"
20 #include "ldebug.h"
21 #include "ldo.h"
22 #include "lfunc.h"
23 #include "lgc.h"
24 #include "lmem.h"
25 #include "lobject.h"
26 #include "lstate.h"
27 #include "lstring.h"
28 #include "ltable.h"
29 #include "ltm.h"
30 #include "lundump.h"
31 #include "lvm.h"
32
33
34
35 const char lua_ident[] =
36 "$LuaVersion: " LUA_COPYRIGHT " $"
37 "$LuaAuthors: " LUA_AUTHORS " $";
38
39
40
41 /*
42 ** Test for a valid index (one that is not the 'nilvalue').
43 ** '!ttisnil(o)' implies 'o != &G(L)->nilvalue', so it is not needed.
44 ** However, it covers the most common cases in a faster way.
45 */
46 #define isvalid(L, o) (!ttisnil(o) || o != &G(L)->nilvalue)
47
48
49 /* test for pseudo index */
50 #define ispseudo(i) ((i) <= LUA_REGISTRYINDEX)
51
52 /* test for upvalue */
53 #define isupvalue(i) ((i) < LUA_REGISTRYINDEX)
54
55
index2value(lua_State * L,int idx)56 static TValue *index2value (lua_State *L, int idx) {
57 CallInfo *ci = L->ci;
58 if (idx > 0) {
59 StkId o = ci->func + idx;
60 api_check(L, idx <= L->ci->top - (ci->func + 1), "unacceptable index");
61 if (o >= L->top) return &G(L)->nilvalue;
62 else return s2v(o);
63 }
64 else if (!ispseudo(idx)) { /* negative index */
65 api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
66 return s2v(L->top + idx);
67 }
68 else if (idx == LUA_REGISTRYINDEX)
69 return &G(L)->l_registry;
70 else { /* upvalues */
71 idx = LUA_REGISTRYINDEX - idx;
72 api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
73 if (ttislcf(s2v(ci->func))) /* light C function? */
74 return &G(L)->nilvalue; /* it has no upvalues */
75 else {
76 CClosure *func = clCvalue(s2v(ci->func));
77 return (idx <= func->nupvalues) ? &func->upvalue[idx-1]
78 : &G(L)->nilvalue;
79 }
80 }
81 }
82
83
index2stack(lua_State * L,int idx)84 static StkId index2stack (lua_State *L, int idx) {
85 CallInfo *ci = L->ci;
86 if (idx > 0) {
87 StkId o = ci->func + idx;
88 api_check(L, o < L->top, "unacceptable index");
89 return o;
90 }
91 else { /* non-positive index */
92 api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
93 api_check(L, !ispseudo(idx), "invalid index");
94 return L->top + idx;
95 }
96 }
97
98
lua_checkstack(lua_State * L,int n)99 LUA_API int lua_checkstack (lua_State *L, int n) {
100 int res;
101 CallInfo *ci;
102 lua_lock(L);
103 ci = L->ci;
104 api_check(L, n >= 0, "negative 'n'");
105 if (L->stack_last - L->top > n) /* stack large enough? */
106 res = 1; /* yes; check is OK */
107 else { /* no; need to grow stack */
108 int inuse = cast_int(L->top - L->stack) + EXTRA_STACK;
109 if (inuse > LUAI_MAXSTACK - n) /* can grow without overflow? */
110 res = 0; /* no */
111 else /* try to grow stack */
112 res = luaD_growstack(L, n, 0);
113 }
114 if (res && ci->top < L->top + n)
115 ci->top = L->top + n; /* adjust frame top */
116 lua_unlock(L);
117 return res;
118 }
119
120
lua_xmove(lua_State * from,lua_State * to,int n)121 LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
122 int i;
123 if (from == to) return;
124 lua_lock(to);
125 api_checknelems(from, n);
126 api_check(from, G(from) == G(to), "moving among independent states");
127 api_check(from, to->ci->top - to->top >= n, "stack overflow");
128 from->top -= n;
129 for (i = 0; i < n; i++) {
130 setobjs2s(to, to->top, from->top + i);
131 to->top++; /* stack already checked by previous 'api_check' */
132 }
133 lua_unlock(to);
134 }
135
136
lua_atpanic(lua_State * L,lua_CFunction panicf)137 LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
138 lua_CFunction old;
139 lua_lock(L);
140 old = G(L)->panic;
141 G(L)->panic = panicf;
142 lua_unlock(L);
143 return old;
144 }
145
146
lua_version(lua_State * L)147 LUA_API lua_Number lua_version (lua_State *L) {
148 UNUSED(L);
149 return LUA_VERSION_NUM;
150 }
151
152
153
154 /*
155 ** basic stack manipulation
156 */
157
158
159 /*
160 ** convert an acceptable stack index into an absolute index
161 */
lua_absindex(lua_State * L,int idx)162 LUA_API int lua_absindex (lua_State *L, int idx) {
163 return (idx > 0 || ispseudo(idx))
164 ? idx
165 : cast_int(L->top - L->ci->func) + idx;
166 }
167
168
lua_gettop(lua_State * L)169 LUA_API int lua_gettop (lua_State *L) {
170 return cast_int(L->top - (L->ci->func + 1));
171 }
172
173
lua_settop(lua_State * L,int idx)174 LUA_API void lua_settop (lua_State *L, int idx) {
175 CallInfo *ci;
176 StkId func, newtop;
177 ptrdiff_t diff; /* difference for new top */
178 lua_lock(L);
179 ci = L->ci;
180 func = ci->func;
181 if (idx >= 0) {
182 api_check(L, idx <= ci->top - (func + 1), "new top too large");
183 diff = ((func + 1) + idx) - L->top;
184 for (; diff > 0; diff--)
185 setnilvalue(s2v(L->top++)); /* clear new slots */
186 }
187 else {
188 api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
189 diff = idx + 1; /* will "subtract" index (as it is negative) */
190 }
191 api_check(L, L->tbclist < L->top, "previous pop of an unclosed slot");
192 newtop = L->top + diff;
193 if (diff < 0 && L->tbclist >= newtop) {
194 lua_assert(hastocloseCfunc(ci->nresults));
195 luaF_close(L, newtop, CLOSEKTOP, 0);
196 }
197 L->top = newtop; /* correct top only after closing any upvalue */
198 lua_unlock(L);
199 }
200
201
lua_closeslot(lua_State * L,int idx)202 LUA_API void lua_closeslot (lua_State *L, int idx) {
203 StkId level;
204 lua_lock(L);
205 level = index2stack(L, idx);
206 api_check(L, hastocloseCfunc(L->ci->nresults) && L->tbclist == level,
207 "no variable to close at given level");
208 luaF_close(L, level, CLOSEKTOP, 0);
209 level = index2stack(L, idx); /* stack may be moved */
210 setnilvalue(s2v(level));
211 lua_unlock(L);
212 }
213
214
215 /*
216 ** Reverse the stack segment from 'from' to 'to'
217 ** (auxiliary to 'lua_rotate')
218 ** Note that we move(copy) only the value inside the stack.
219 ** (We do not move additional fields that may exist.)
220 */
reverse(lua_State * L,StkId from,StkId to)221 static void reverse (lua_State *L, StkId from, StkId to) {
222 for (; from < to; from++, to--) {
223 TValue temp;
224 setobj(L, &temp, s2v(from));
225 setobjs2s(L, from, to);
226 setobj2s(L, to, &temp);
227 }
228 }
229
230
231 /*
232 ** Let x = AB, where A is a prefix of length 'n'. Then,
233 ** rotate x n == BA. But BA == (A^r . B^r)^r.
234 */
lua_rotate(lua_State * L,int idx,int n)235 LUA_API void lua_rotate (lua_State *L, int idx, int n) {
236 StkId p, t, m;
237 lua_lock(L);
238 t = L->top - 1; /* end of stack segment being rotated */
239 p = index2stack(L, idx); /* start of segment */
240 api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
241 m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */
242 reverse(L, p, m); /* reverse the prefix with length 'n' */
243 reverse(L, m + 1, t); /* reverse the suffix */
244 reverse(L, p, t); /* reverse the entire segment */
245 lua_unlock(L);
246 }
247
248
lua_copy(lua_State * L,int fromidx,int toidx)249 LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
250 TValue *fr, *to;
251 lua_lock(L);
252 fr = index2value(L, fromidx);
253 to = index2value(L, toidx);
254 api_check(L, isvalid(L, to), "invalid index");
255 setobj(L, to, fr);
256 if (isupvalue(toidx)) /* function upvalue? */
257 luaC_barrier(L, clCvalue(s2v(L->ci->func)), fr);
258 /* LUA_REGISTRYINDEX does not need gc barrier
259 (collector revisits it before finishing collection) */
260 lua_unlock(L);
261 }
262
263
lua_pushvalue(lua_State * L,int idx)264 LUA_API void lua_pushvalue (lua_State *L, int idx) {
265 lua_lock(L);
266 setobj2s(L, L->top, index2value(L, idx));
267 api_incr_top(L);
268 lua_unlock(L);
269 }
270
271
272
273 /*
274 ** access functions (stack -> C)
275 */
276
277
lua_type(lua_State * L,int idx)278 LUA_API int lua_type (lua_State *L, int idx) {
279 const TValue *o = index2value(L, idx);
280 return (isvalid(L, o) ? ttype(o) : LUA_TNONE);
281 }
282
283
lua_typename(lua_State * L,int t)284 LUA_API const char *lua_typename (lua_State *L, int t) {
285 UNUSED(L);
286 api_check(L, LUA_TNONE <= t && t < LUA_NUMTYPES, "invalid type");
287 return ttypename(t);
288 }
289
290
lua_iscfunction(lua_State * L,int idx)291 LUA_API int lua_iscfunction (lua_State *L, int idx) {
292 const TValue *o = index2value(L, idx);
293 return (ttislcf(o) || (ttisCclosure(o)));
294 }
295
296
lua_isinteger(lua_State * L,int idx)297 LUA_API int lua_isinteger (lua_State *L, int idx) {
298 const TValue *o = index2value(L, idx);
299 return ttisinteger(o);
300 }
301
302
lua_isnumber(lua_State * L,int idx)303 LUA_API int lua_isnumber (lua_State *L, int idx) {
304 lua_Number n;
305 const TValue *o = index2value(L, idx);
306 return tonumber(o, &n);
307 }
308
309
lua_isstring(lua_State * L,int idx)310 LUA_API int lua_isstring (lua_State *L, int idx) {
311 const TValue *o = index2value(L, idx);
312 return (ttisstring(o) || cvt2str(o));
313 }
314
315
lua_isuserdata(lua_State * L,int idx)316 LUA_API int lua_isuserdata (lua_State *L, int idx) {
317 const TValue *o = index2value(L, idx);
318 return (ttisfulluserdata(o) || ttislightuserdata(o));
319 }
320
321
lua_rawequal(lua_State * L,int index1,int index2)322 LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
323 const TValue *o1 = index2value(L, index1);
324 const TValue *o2 = index2value(L, index2);
325 return (isvalid(L, o1) && isvalid(L, o2)) ? luaV_rawequalobj(o1, o2) : 0;
326 }
327
328
lua_arith(lua_State * L,int op)329 LUA_API void lua_arith (lua_State *L, int op) {
330 lua_lock(L);
331 if (op != LUA_OPUNM && op != LUA_OPBNOT)
332 api_checknelems(L, 2); /* all other operations expect two operands */
333 else { /* for unary operations, add fake 2nd operand */
334 api_checknelems(L, 1);
335 setobjs2s(L, L->top, L->top - 1);
336 api_incr_top(L);
337 }
338 /* first operand at top - 2, second at top - 1; result go to top - 2 */
339 luaO_arith(L, op, s2v(L->top - 2), s2v(L->top - 1), L->top - 2);
340 L->top--; /* remove second operand */
341 lua_unlock(L);
342 }
343
344
lua_compare(lua_State * L,int index1,int index2,int op)345 LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
346 const TValue *o1;
347 const TValue *o2;
348 int i = 0;
349 lua_lock(L); /* may call tag method */
350 o1 = index2value(L, index1);
351 o2 = index2value(L, index2);
352 if (isvalid(L, o1) && isvalid(L, o2)) {
353 switch (op) {
354 case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break;
355 case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
356 case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
357 default: api_check(L, 0, "invalid option");
358 }
359 }
360 lua_unlock(L);
361 return i;
362 }
363
364
lua_stringtonumber(lua_State * L,const char * s)365 LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
366 size_t sz = luaO_str2num(s, s2v(L->top));
367 if (sz != 0)
368 api_incr_top(L);
369 return sz;
370 }
371
372
lua_tonumberx(lua_State * L,int idx,int * pisnum)373 LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) {
374 lua_Number n = 0;
375 const TValue *o = index2value(L, idx);
376 int isnum = tonumber(o, &n);
377 if (pisnum)
378 *pisnum = isnum;
379 return n;
380 }
381
382
lua_tointegerx(lua_State * L,int idx,int * pisnum)383 LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) {
384 lua_Integer res = 0;
385 const TValue *o = index2value(L, idx);
386 int isnum = tointeger(o, &res);
387 if (pisnum)
388 *pisnum = isnum;
389 return res;
390 }
391
392
lua_toboolean(lua_State * L,int idx)393 LUA_API int lua_toboolean (lua_State *L, int idx) {
394 const TValue *o = index2value(L, idx);
395 return !l_isfalse(o);
396 }
397
398
lua_tolstring(lua_State * L,int idx,size_t * len)399 LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
400 TValue *o;
401 lua_lock(L);
402 o = index2value(L, idx);
403 if (!ttisstring(o)) {
404 if (!cvt2str(o)) { /* not convertible? */
405 if (len != NULL) *len = 0;
406 lua_unlock(L);
407 return NULL;
408 }
409 luaO_tostring(L, o);
410 luaC_checkGC(L);
411 o = index2value(L, idx); /* previous call may reallocate the stack */
412 }
413 if (len != NULL)
414 *len = vslen(o);
415 lua_unlock(L);
416 return svalue(o);
417 }
418
419
lua_rawlen(lua_State * L,int idx)420 LUA_API lua_Unsigned lua_rawlen (lua_State *L, int idx) {
421 const TValue *o = index2value(L, idx);
422 switch (ttypetag(o)) {
423 case LUA_VSHRSTR: return tsvalue(o)->shrlen;
424 case LUA_VLNGSTR: return tsvalue(o)->u.lnglen;
425 case LUA_VUSERDATA: return uvalue(o)->len;
426 case LUA_VTABLE: return luaH_getn(hvalue(o));
427 default: return 0;
428 }
429 }
430
431
lua_tocfunction(lua_State * L,int idx)432 LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
433 const TValue *o = index2value(L, idx);
434 if (ttislcf(o)) return fvalue(o);
435 else if (ttisCclosure(o))
436 return clCvalue(o)->f;
437 else return NULL; /* not a C function */
438 }
439
440
touserdata(const TValue * o)441 static void *touserdata (const TValue *o) {
442 switch (ttype(o)) {
443 case LUA_TUSERDATA: return getudatamem(uvalue(o));
444 case LUA_TLIGHTUSERDATA: return pvalue(o);
445 default: return NULL;
446 }
447 }
448
449
lua_touserdata(lua_State * L,int idx)450 LUA_API void *lua_touserdata (lua_State *L, int idx) {
451 const TValue *o = index2value(L, idx);
452 return touserdata(o);
453 }
454
455
lua_tothread(lua_State * L,int idx)456 LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
457 const TValue *o = index2value(L, idx);
458 return (!ttisthread(o)) ? NULL : thvalue(o);
459 }
460
461
462 /*
463 ** Returns a pointer to the internal representation of an object.
464 ** Note that ANSI C does not allow the conversion of a pointer to
465 ** function to a 'void*', so the conversion here goes through
466 ** a 'size_t'. (As the returned pointer is only informative, this
467 ** conversion should not be a problem.)
468 */
lua_topointer(lua_State * L,int idx)469 LUA_API const void *lua_topointer (lua_State *L, int idx) {
470 const TValue *o = index2value(L, idx);
471 switch (ttypetag(o)) {
472 case LUA_VLCF: return cast_voidp(cast_sizet(fvalue(o)));
473 case LUA_VUSERDATA: case LUA_VLIGHTUSERDATA:
474 return touserdata(o);
475 default: {
476 if (iscollectable(o))
477 return gcvalue(o);
478 else
479 return NULL;
480 }
481 }
482 }
483
484
485
486 /*
487 ** push functions (C -> stack)
488 */
489
490
lua_pushnil(lua_State * L)491 LUA_API void lua_pushnil (lua_State *L) {
492 lua_lock(L);
493 setnilvalue(s2v(L->top));
494 api_incr_top(L);
495 lua_unlock(L);
496 }
497
498
lua_pushnumber(lua_State * L,lua_Number n)499 LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
500 lua_lock(L);
501 setfltvalue(s2v(L->top), n);
502 api_incr_top(L);
503 lua_unlock(L);
504 }
505
506
lua_pushinteger(lua_State * L,lua_Integer n)507 LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
508 lua_lock(L);
509 setivalue(s2v(L->top), n);
510 api_incr_top(L);
511 lua_unlock(L);
512 }
513
514
515 /*
516 ** Pushes on the stack a string with given length. Avoid using 's' when
517 ** 'len' == 0 (as 's' can be NULL in that case), due to later use of
518 ** 'memcmp' and 'memcpy'.
519 */
lua_pushlstring(lua_State * L,const char * s,size_t len)520 LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
521 TString *ts;
522 lua_lock(L);
523 ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len);
524 setsvalue2s(L, L->top, ts);
525 api_incr_top(L);
526 luaC_checkGC(L);
527 lua_unlock(L);
528 return getstr(ts);
529 }
530
531
lua_pushstring(lua_State * L,const char * s)532 LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
533 lua_lock(L);
534 if (s == NULL)
535 setnilvalue(s2v(L->top));
536 else {
537 TString *ts;
538 ts = luaS_new(L, s);
539 setsvalue2s(L, L->top, ts);
540 s = getstr(ts); /* internal copy's address */
541 }
542 api_incr_top(L);
543 luaC_checkGC(L);
544 lua_unlock(L);
545 return s;
546 }
547
548
lua_pushvfstring(lua_State * L,const char * fmt,va_list argp)549 LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
550 va_list argp) {
551 const char *ret;
552 lua_lock(L);
553 ret = luaO_pushvfstring(L, fmt, argp);
554 luaC_checkGC(L);
555 lua_unlock(L);
556 return ret;
557 }
558
559
lua_pushfstring(lua_State * L,const char * fmt,...)560 LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
561 const char *ret;
562 va_list argp;
563 lua_lock(L);
564 va_start(argp, fmt);
565 ret = luaO_pushvfstring(L, fmt, argp);
566 va_end(argp);
567 luaC_checkGC(L);
568 lua_unlock(L);
569 return ret;
570 }
571
572
lua_pushcclosure(lua_State * L,lua_CFunction fn,int n)573 LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
574 lua_lock(L);
575 if (n == 0) {
576 setfvalue(s2v(L->top), fn);
577 api_incr_top(L);
578 }
579 else {
580 CClosure *cl;
581 api_checknelems(L, n);
582 api_check(L, n <= MAXUPVAL, "upvalue index too large");
583 cl = luaF_newCclosure(L, n);
584 cl->f = fn;
585 L->top -= n;
586 while (n--) {
587 setobj2n(L, &cl->upvalue[n], s2v(L->top + n));
588 /* does not need barrier because closure is white */
589 lua_assert(iswhite(cl));
590 }
591 setclCvalue(L, s2v(L->top), cl);
592 api_incr_top(L);
593 luaC_checkGC(L);
594 }
595 lua_unlock(L);
596 }
597
598
lua_pushboolean(lua_State * L,int b)599 LUA_API void lua_pushboolean (lua_State *L, int b) {
600 lua_lock(L);
601 if (b)
602 setbtvalue(s2v(L->top));
603 else
604 setbfvalue(s2v(L->top));
605 api_incr_top(L);
606 lua_unlock(L);
607 }
608
609
lua_pushlightuserdata(lua_State * L,void * p)610 LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
611 lua_lock(L);
612 setpvalue(s2v(L->top), p);
613 api_incr_top(L);
614 lua_unlock(L);
615 }
616
617
lua_pushthread(lua_State * L)618 LUA_API int lua_pushthread (lua_State *L) {
619 lua_lock(L);
620 setthvalue(L, s2v(L->top), L);
621 api_incr_top(L);
622 lua_unlock(L);
623 return (G(L)->mainthread == L);
624 }
625
626
627
628 /*
629 ** get functions (Lua -> stack)
630 */
631
632
auxgetstr(lua_State * L,const TValue * t,const char * k)633 static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
634 const TValue *slot;
635 TString *str = luaS_new(L, k);
636 if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
637 setobj2s(L, L->top, slot);
638 api_incr_top(L);
639 }
640 else {
641 setsvalue2s(L, L->top, str);
642 api_incr_top(L);
643 luaV_finishget(L, t, s2v(L->top - 1), L->top - 1, slot);
644 }
645 lua_unlock(L);
646 return ttype(s2v(L->top - 1));
647 }
648
649
650 /*
651 ** Get the global table in the registry. Since all predefined
652 ** indices in the registry were inserted right when the registry
653 ** was created and never removed, they must always be in the array
654 ** part of the registry.
655 */
656 #define getGtable(L) \
657 (&hvalue(&G(L)->l_registry)->array[LUA_RIDX_GLOBALS - 1])
658
659
lua_getglobal(lua_State * L,const char * name)660 LUA_API int lua_getglobal (lua_State *L, const char *name) {
661 const TValue *G;
662 lua_lock(L);
663 G = getGtable(L);
664 return auxgetstr(L, G, name);
665 }
666
667
lua_gettable(lua_State * L,int idx)668 LUA_API int lua_gettable (lua_State *L, int idx) {
669 const TValue *slot;
670 TValue *t;
671 lua_lock(L);
672 t = index2value(L, idx);
673 if (luaV_fastget(L, t, s2v(L->top - 1), slot, luaH_get)) {
674 setobj2s(L, L->top - 1, slot);
675 }
676 else
677 luaV_finishget(L, t, s2v(L->top - 1), L->top - 1, slot);
678 lua_unlock(L);
679 return ttype(s2v(L->top - 1));
680 }
681
682
lua_getfield(lua_State * L,int idx,const char * k)683 LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
684 lua_lock(L);
685 return auxgetstr(L, index2value(L, idx), k);
686 }
687
688
lua_geti(lua_State * L,int idx,lua_Integer n)689 LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
690 TValue *t;
691 const TValue *slot;
692 lua_lock(L);
693 t = index2value(L, idx);
694 if (luaV_fastgeti(L, t, n, slot)) {
695 setobj2s(L, L->top, slot);
696 }
697 else {
698 TValue aux;
699 setivalue(&aux, n);
700 luaV_finishget(L, t, &aux, L->top, slot);
701 }
702 api_incr_top(L);
703 lua_unlock(L);
704 return ttype(s2v(L->top - 1));
705 }
706
707
finishrawget(lua_State * L,const TValue * val)708 static int finishrawget (lua_State *L, const TValue *val) {
709 if (isempty(val)) /* avoid copying empty items to the stack */
710 setnilvalue(s2v(L->top));
711 else
712 setobj2s(L, L->top, val);
713 api_incr_top(L);
714 lua_unlock(L);
715 return ttype(s2v(L->top - 1));
716 }
717
718
gettable(lua_State * L,int idx)719 static Table *gettable (lua_State *L, int idx) {
720 TValue *t = index2value(L, idx);
721 api_check(L, ttistable(t), "table expected");
722 return hvalue(t);
723 }
724
725
lua_rawget(lua_State * L,int idx)726 LUA_API int lua_rawget (lua_State *L, int idx) {
727 Table *t;
728 const TValue *val;
729 lua_lock(L);
730 api_checknelems(L, 1);
731 t = gettable(L, idx);
732 val = luaH_get(t, s2v(L->top - 1));
733 L->top--; /* remove key */
734 return finishrawget(L, val);
735 }
736
737
lua_rawgeti(lua_State * L,int idx,lua_Integer n)738 LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
739 Table *t;
740 lua_lock(L);
741 t = gettable(L, idx);
742 return finishrawget(L, luaH_getint(t, n));
743 }
744
745
lua_rawgetp(lua_State * L,int idx,const void * p)746 LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
747 Table *t;
748 TValue k;
749 lua_lock(L);
750 t = gettable(L, idx);
751 setpvalue(&k, cast_voidp(p));
752 return finishrawget(L, luaH_get(t, &k));
753 }
754
755
lua_createtable(lua_State * L,int narray,int nrec)756 LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
757 Table *t;
758 lua_lock(L);
759 t = luaH_new(L);
760 sethvalue2s(L, L->top, t);
761 api_incr_top(L);
762 if (narray > 0 || nrec > 0)
763 luaH_resize(L, t, narray, nrec);
764 luaC_checkGC(L);
765 lua_unlock(L);
766 }
767
768
lua_getmetatable(lua_State * L,int objindex)769 LUA_API int lua_getmetatable (lua_State *L, int objindex) {
770 const TValue *obj;
771 Table *mt;
772 int res = 0;
773 lua_lock(L);
774 obj = index2value(L, objindex);
775 switch (ttype(obj)) {
776 case LUA_TTABLE:
777 mt = hvalue(obj)->metatable;
778 break;
779 case LUA_TUSERDATA:
780 mt = uvalue(obj)->metatable;
781 break;
782 default:
783 mt = G(L)->mt[ttype(obj)];
784 break;
785 }
786 if (mt != NULL) {
787 sethvalue2s(L, L->top, mt);
788 api_incr_top(L);
789 res = 1;
790 }
791 lua_unlock(L);
792 return res;
793 }
794
795
lua_getiuservalue(lua_State * L,int idx,int n)796 LUA_API int lua_getiuservalue (lua_State *L, int idx, int n) {
797 TValue *o;
798 int t;
799 lua_lock(L);
800 o = index2value(L, idx);
801 api_check(L, ttisfulluserdata(o), "full userdata expected");
802 if (n <= 0 || n > uvalue(o)->nuvalue) {
803 setnilvalue(s2v(L->top));
804 t = LUA_TNONE;
805 }
806 else {
807 setobj2s(L, L->top, &uvalue(o)->uv[n - 1].uv);
808 t = ttype(s2v(L->top));
809 }
810 api_incr_top(L);
811 lua_unlock(L);
812 return t;
813 }
814
815
816 /*
817 ** set functions (stack -> Lua)
818 */
819
820 /*
821 ** t[k] = value at the top of the stack (where 'k' is a string)
822 */
auxsetstr(lua_State * L,const TValue * t,const char * k)823 static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
824 const TValue *slot;
825 TString *str = luaS_new(L, k);
826 api_checknelems(L, 1);
827 if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
828 luaV_finishfastset(L, t, slot, s2v(L->top - 1));
829 L->top--; /* pop value */
830 }
831 else {
832 setsvalue2s(L, L->top, str); /* push 'str' (to make it a TValue) */
833 api_incr_top(L);
834 luaV_finishset(L, t, s2v(L->top - 1), s2v(L->top - 2), slot);
835 L->top -= 2; /* pop value and key */
836 }
837 lua_unlock(L); /* lock done by caller */
838 }
839
840
lua_setglobal(lua_State * L,const char * name)841 LUA_API void lua_setglobal (lua_State *L, const char *name) {
842 const TValue *G;
843 lua_lock(L); /* unlock done in 'auxsetstr' */
844 G = getGtable(L);
845 auxsetstr(L, G, name);
846 }
847
848
lua_settable(lua_State * L,int idx)849 LUA_API void lua_settable (lua_State *L, int idx) {
850 TValue *t;
851 const TValue *slot;
852 lua_lock(L);
853 api_checknelems(L, 2);
854 t = index2value(L, idx);
855 if (luaV_fastget(L, t, s2v(L->top - 2), slot, luaH_get)) {
856 luaV_finishfastset(L, t, slot, s2v(L->top - 1));
857 }
858 else
859 luaV_finishset(L, t, s2v(L->top - 2), s2v(L->top - 1), slot);
860 L->top -= 2; /* pop index and value */
861 lua_unlock(L);
862 }
863
864
lua_setfield(lua_State * L,int idx,const char * k)865 LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
866 lua_lock(L); /* unlock done in 'auxsetstr' */
867 auxsetstr(L, index2value(L, idx), k);
868 }
869
870
lua_seti(lua_State * L,int idx,lua_Integer n)871 LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
872 TValue *t;
873 const TValue *slot;
874 lua_lock(L);
875 api_checknelems(L, 1);
876 t = index2value(L, idx);
877 if (luaV_fastgeti(L, t, n, slot)) {
878 luaV_finishfastset(L, t, slot, s2v(L->top - 1));
879 }
880 else {
881 TValue aux;
882 setivalue(&aux, n);
883 luaV_finishset(L, t, &aux, s2v(L->top - 1), slot);
884 }
885 L->top--; /* pop value */
886 lua_unlock(L);
887 }
888
889
aux_rawset(lua_State * L,int idx,TValue * key,int n)890 static void aux_rawset (lua_State *L, int idx, TValue *key, int n) {
891 Table *t;
892 lua_lock(L);
893 api_checknelems(L, n);
894 t = gettable(L, idx);
895 luaH_set(L, t, key, s2v(L->top - 1));
896 invalidateTMcache(t);
897 luaC_barrierback(L, obj2gco(t), s2v(L->top - 1));
898 L->top -= n;
899 lua_unlock(L);
900 }
901
902
lua_rawset(lua_State * L,int idx)903 LUA_API void lua_rawset (lua_State *L, int idx) {
904 aux_rawset(L, idx, s2v(L->top - 2), 2);
905 }
906
907
lua_rawsetp(lua_State * L,int idx,const void * p)908 LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
909 TValue k;
910 setpvalue(&k, cast_voidp(p));
911 aux_rawset(L, idx, &k, 1);
912 }
913
914
lua_rawseti(lua_State * L,int idx,lua_Integer n)915 LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
916 Table *t;
917 lua_lock(L);
918 api_checknelems(L, 1);
919 t = gettable(L, idx);
920 luaH_setint(L, t, n, s2v(L->top - 1));
921 luaC_barrierback(L, obj2gco(t), s2v(L->top - 1));
922 L->top--;
923 lua_unlock(L);
924 }
925
926
lua_setmetatable(lua_State * L,int objindex)927 LUA_API int lua_setmetatable (lua_State *L, int objindex) {
928 TValue *obj;
929 Table *mt;
930 lua_lock(L);
931 api_checknelems(L, 1);
932 obj = index2value(L, objindex);
933 if (ttisnil(s2v(L->top - 1)))
934 mt = NULL;
935 else {
936 api_check(L, ttistable(s2v(L->top - 1)), "table expected");
937 mt = hvalue(s2v(L->top - 1));
938 }
939 switch (ttype(obj)) {
940 case LUA_TTABLE: {
941 hvalue(obj)->metatable = mt;
942 if (mt) {
943 luaC_objbarrier(L, gcvalue(obj), mt);
944 luaC_checkfinalizer(L, gcvalue(obj), mt);
945 }
946 break;
947 }
948 case LUA_TUSERDATA: {
949 uvalue(obj)->metatable = mt;
950 if (mt) {
951 luaC_objbarrier(L, uvalue(obj), mt);
952 luaC_checkfinalizer(L, gcvalue(obj), mt);
953 }
954 break;
955 }
956 default: {
957 G(L)->mt[ttype(obj)] = mt;
958 break;
959 }
960 }
961 L->top--;
962 lua_unlock(L);
963 return 1;
964 }
965
966
lua_setiuservalue(lua_State * L,int idx,int n)967 LUA_API int lua_setiuservalue (lua_State *L, int idx, int n) {
968 TValue *o;
969 int res;
970 lua_lock(L);
971 api_checknelems(L, 1);
972 o = index2value(L, idx);
973 api_check(L, ttisfulluserdata(o), "full userdata expected");
974 if (!(cast_uint(n) - 1u < cast_uint(uvalue(o)->nuvalue)))
975 res = 0; /* 'n' not in [1, uvalue(o)->nuvalue] */
976 else {
977 setobj(L, &uvalue(o)->uv[n - 1].uv, s2v(L->top - 1));
978 luaC_barrierback(L, gcvalue(o), s2v(L->top - 1));
979 res = 1;
980 }
981 L->top--;
982 lua_unlock(L);
983 return res;
984 }
985
986
987 /*
988 ** 'load' and 'call' functions (run Lua code)
989 */
990
991
992 #define checkresults(L,na,nr) \
993 api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
994 "results from function overflow current stack size")
995
996
lua_callk(lua_State * L,int nargs,int nresults,lua_KContext ctx,lua_KFunction k)997 LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
998 lua_KContext ctx, lua_KFunction k) {
999 StkId func;
1000 lua_lock(L);
1001 api_check(L, k == NULL || !isLua(L->ci),
1002 "cannot use continuations inside hooks");
1003 api_checknelems(L, nargs+1);
1004 api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
1005 checkresults(L, nargs, nresults);
1006 func = L->top - (nargs+1);
1007 if (k != NULL && yieldable(L)) { /* need to prepare continuation? */
1008 L->ci->u.c.k = k; /* save continuation */
1009 L->ci->u.c.ctx = ctx; /* save context */
1010 luaD_call(L, func, nresults); /* do the call */
1011 }
1012 else /* no continuation or no yieldable */
1013 luaD_callnoyield(L, func, nresults); /* just do the call */
1014 adjustresults(L, nresults);
1015 lua_unlock(L);
1016 }
1017
1018
1019
1020 /*
1021 ** Execute a protected call.
1022 */
1023 struct CallS { /* data to 'f_call' */
1024 StkId func;
1025 int nresults;
1026 };
1027
1028
f_call(lua_State * L,void * ud)1029 static void f_call (lua_State *L, void *ud) {
1030 struct CallS *c = cast(struct CallS *, ud);
1031 luaD_callnoyield(L, c->func, c->nresults);
1032 }
1033
1034
1035
lua_pcallk(lua_State * L,int nargs,int nresults,int errfunc,lua_KContext ctx,lua_KFunction k)1036 LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
1037 lua_KContext ctx, lua_KFunction k) {
1038 struct CallS c;
1039 int status;
1040 ptrdiff_t func;
1041 lua_lock(L);
1042 api_check(L, k == NULL || !isLua(L->ci),
1043 "cannot use continuations inside hooks");
1044 api_checknelems(L, nargs+1);
1045 api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
1046 checkresults(L, nargs, nresults);
1047 if (errfunc == 0)
1048 func = 0;
1049 else {
1050 StkId o = index2stack(L, errfunc);
1051 api_check(L, ttisfunction(s2v(o)), "error handler must be a function");
1052 func = savestack(L, o);
1053 }
1054 c.func = L->top - (nargs+1); /* function to be called */
1055 if (k == NULL || !yieldable(L)) { /* no continuation or no yieldable? */
1056 c.nresults = nresults; /* do a 'conventional' protected call */
1057 status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
1058 }
1059 else { /* prepare continuation (call is already protected by 'resume') */
1060 CallInfo *ci = L->ci;
1061 ci->u.c.k = k; /* save continuation */
1062 ci->u.c.ctx = ctx; /* save context */
1063 /* save information for error recovery */
1064 ci->u2.funcidx = cast_int(savestack(L, c.func));
1065 ci->u.c.old_errfunc = L->errfunc;
1066 L->errfunc = func;
1067 setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */
1068 ci->callstatus |= CIST_YPCALL; /* function can do error recovery */
1069 luaD_call(L, c.func, nresults); /* do the call */
1070 ci->callstatus &= ~CIST_YPCALL;
1071 L->errfunc = ci->u.c.old_errfunc;
1072 status = LUA_OK; /* if it is here, there were no errors */
1073 }
1074 adjustresults(L, nresults);
1075 lua_unlock(L);
1076 return status;
1077 }
1078
1079
lua_load(lua_State * L,lua_Reader reader,void * data,const char * chunkname,const char * mode)1080 LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
1081 const char *chunkname, const char *mode) {
1082 ZIO z;
1083 int status;
1084 lua_lock(L);
1085 if (!chunkname) chunkname = "?";
1086 luaZ_init(L, &z, reader, data);
1087 status = luaD_protectedparser(L, &z, chunkname, mode);
1088 if (status == LUA_OK) { /* no errors? */
1089 LClosure *f = clLvalue(s2v(L->top - 1)); /* get newly created function */
1090 if (f->nupvalues >= 1) { /* does it have an upvalue? */
1091 /* get global table from registry */
1092 const TValue *gt = getGtable(L);
1093 /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
1094 setobj(L, f->upvals[0]->v, gt);
1095 luaC_barrier(L, f->upvals[0], gt);
1096 }
1097 }
1098 lua_unlock(L);
1099 return status;
1100 }
1101
1102
lua_dump(lua_State * L,lua_Writer writer,void * data,int strip)1103 LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
1104 int status;
1105 TValue *o;
1106 lua_lock(L);
1107 api_checknelems(L, 1);
1108 o = s2v(L->top - 1);
1109 if (isLfunction(o))
1110 status = luaU_dump(L, getproto(o), writer, data, strip);
1111 else
1112 status = 1;
1113 lua_unlock(L);
1114 return status;
1115 }
1116
1117
lua_status(lua_State * L)1118 LUA_API int lua_status (lua_State *L) {
1119 return L->status;
1120 }
1121
1122
1123 /*
1124 ** Garbage-collection function
1125 */
lua_gc(lua_State * L,int what,...)1126 LUA_API int lua_gc (lua_State *L, int what, ...) {
1127 va_list argp;
1128 int res = 0;
1129 global_State *g;
1130 lua_lock(L);
1131 g = G(L);
1132 va_start(argp, what);
1133 switch (what) {
1134 case LUA_GCSTOP: {
1135 g->gcrunning = 0;
1136 break;
1137 }
1138 case LUA_GCRESTART: {
1139 luaE_setdebt(g, 0);
1140 g->gcrunning = 1;
1141 break;
1142 }
1143 case LUA_GCCOLLECT: {
1144 luaC_fullgc(L, 0);
1145 break;
1146 }
1147 case LUA_GCCOUNT: {
1148 /* GC values are expressed in Kbytes: #bytes/2^10 */
1149 res = cast_int(gettotalbytes(g) >> 10);
1150 break;
1151 }
1152 case LUA_GCCOUNTB: {
1153 res = cast_int(gettotalbytes(g) & 0x3ff);
1154 break;
1155 }
1156 case LUA_GCSTEP: {
1157 int data = va_arg(argp, int);
1158 l_mem debt = 1; /* =1 to signal that it did an actual step */
1159 lu_byte oldrunning = g->gcrunning;
1160 g->gcrunning = 1; /* allow GC to run */
1161 if (data == 0) {
1162 luaE_setdebt(g, 0); /* do a basic step */
1163 luaC_step(L);
1164 }
1165 else { /* add 'data' to total debt */
1166 debt = cast(l_mem, data) * 1024 + g->GCdebt;
1167 luaE_setdebt(g, debt);
1168 luaC_checkGC(L);
1169 }
1170 g->gcrunning = oldrunning; /* restore previous state */
1171 if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */
1172 res = 1; /* signal it */
1173 break;
1174 }
1175 case LUA_GCSETPAUSE: {
1176 int data = va_arg(argp, int);
1177 res = getgcparam(g->gcpause);
1178 setgcparam(g->gcpause, data);
1179 break;
1180 }
1181 case LUA_GCSETSTEPMUL: {
1182 int data = va_arg(argp, int);
1183 res = getgcparam(g->gcstepmul);
1184 setgcparam(g->gcstepmul, data);
1185 break;
1186 }
1187 case LUA_GCISRUNNING: {
1188 res = g->gcrunning;
1189 break;
1190 }
1191 case LUA_GCGEN: {
1192 int minormul = va_arg(argp, int);
1193 int majormul = va_arg(argp, int);
1194 res = isdecGCmodegen(g) ? LUA_GCGEN : LUA_GCINC;
1195 if (minormul != 0)
1196 g->genminormul = minormul;
1197 if (majormul != 0)
1198 setgcparam(g->genmajormul, majormul);
1199 luaC_changemode(L, KGC_GEN);
1200 break;
1201 }
1202 case LUA_GCINC: {
1203 int pause = va_arg(argp, int);
1204 int stepmul = va_arg(argp, int);
1205 int stepsize = va_arg(argp, int);
1206 res = isdecGCmodegen(g) ? LUA_GCGEN : LUA_GCINC;
1207 if (pause != 0)
1208 setgcparam(g->gcpause, pause);
1209 if (stepmul != 0)
1210 setgcparam(g->gcstepmul, stepmul);
1211 if (stepsize != 0)
1212 g->gcstepsize = stepsize;
1213 luaC_changemode(L, KGC_INC);
1214 break;
1215 }
1216 default: res = -1; /* invalid option */
1217 }
1218 va_end(argp);
1219 lua_unlock(L);
1220 return res;
1221 }
1222
1223
1224
1225 /*
1226 ** miscellaneous functions
1227 */
1228
1229
lua_error(lua_State * L)1230 LUA_API int lua_error (lua_State *L) {
1231 TValue *errobj;
1232 lua_lock(L);
1233 errobj = s2v(L->top - 1);
1234 api_checknelems(L, 1);
1235 /* error object is the memory error message? */
1236 if (ttisshrstring(errobj) && eqshrstr(tsvalue(errobj), G(L)->memerrmsg))
1237 luaM_error(L); /* raise a memory error */
1238 else
1239 luaG_errormsg(L); /* raise a regular error */
1240 /* code unreachable; will unlock when control actually leaves the kernel */
1241 return 0; /* to avoid warnings */
1242 }
1243
1244
lua_next(lua_State * L,int idx)1245 LUA_API int lua_next (lua_State *L, int idx) {
1246 Table *t;
1247 int more;
1248 lua_lock(L);
1249 api_checknelems(L, 1);
1250 t = gettable(L, idx);
1251 more = luaH_next(L, t, L->top - 1);
1252 if (more) {
1253 api_incr_top(L);
1254 }
1255 else /* no more elements */
1256 L->top -= 1; /* remove key */
1257 lua_unlock(L);
1258 return more;
1259 }
1260
1261
lua_toclose(lua_State * L,int idx)1262 LUA_API void lua_toclose (lua_State *L, int idx) {
1263 int nresults;
1264 StkId o;
1265 lua_lock(L);
1266 o = index2stack(L, idx);
1267 nresults = L->ci->nresults;
1268 api_check(L, L->tbclist < o, "given index below or equal a marked one");
1269 luaF_newtbcupval(L, o); /* create new to-be-closed upvalue */
1270 if (!hastocloseCfunc(nresults)) /* function not marked yet? */
1271 L->ci->nresults = codeNresults(nresults); /* mark it */
1272 lua_assert(hastocloseCfunc(L->ci->nresults));
1273 lua_unlock(L);
1274 }
1275
1276
lua_concat(lua_State * L,int n)1277 LUA_API void lua_concat (lua_State *L, int n) {
1278 lua_lock(L);
1279 api_checknelems(L, n);
1280 if (n > 0)
1281 luaV_concat(L, n);
1282 else { /* nothing to concatenate */
1283 setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); /* push empty string */
1284 api_incr_top(L);
1285 }
1286 luaC_checkGC(L);
1287 lua_unlock(L);
1288 }
1289
1290
lua_len(lua_State * L,int idx)1291 LUA_API void lua_len (lua_State *L, int idx) {
1292 TValue *t;
1293 lua_lock(L);
1294 t = index2value(L, idx);
1295 luaV_objlen(L, L->top, t);
1296 api_incr_top(L);
1297 lua_unlock(L);
1298 }
1299
1300
lua_getallocf(lua_State * L,void ** ud)1301 LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
1302 lua_Alloc f;
1303 lua_lock(L);
1304 if (ud) *ud = G(L)->ud;
1305 f = G(L)->frealloc;
1306 lua_unlock(L);
1307 return f;
1308 }
1309
1310
lua_setallocf(lua_State * L,lua_Alloc f,void * ud)1311 LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
1312 lua_lock(L);
1313 G(L)->ud = ud;
1314 G(L)->frealloc = f;
1315 lua_unlock(L);
1316 }
1317
1318
lua_setwarnf(lua_State * L,lua_WarnFunction f,void * ud)1319 void lua_setwarnf (lua_State *L, lua_WarnFunction f, void *ud) {
1320 lua_lock(L);
1321 G(L)->ud_warn = ud;
1322 G(L)->warnf = f;
1323 lua_unlock(L);
1324 }
1325
1326
lua_warning(lua_State * L,const char * msg,int tocont)1327 void lua_warning (lua_State *L, const char *msg, int tocont) {
1328 lua_lock(L);
1329 luaE_warning(L, msg, tocont);
1330 lua_unlock(L);
1331 }
1332
1333
1334
lua_newuserdatauv(lua_State * L,size_t size,int nuvalue)1335 LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) {
1336 Udata *u;
1337 lua_lock(L);
1338 api_check(L, 0 <= nuvalue && nuvalue < USHRT_MAX, "invalid value");
1339 u = luaS_newudata(L, size, nuvalue);
1340 setuvalue(L, s2v(L->top), u);
1341 api_incr_top(L);
1342 luaC_checkGC(L);
1343 lua_unlock(L);
1344 return getudatamem(u);
1345 }
1346
1347
1348
aux_upvalue(TValue * fi,int n,TValue ** val,GCObject ** owner)1349 static const char *aux_upvalue (TValue *fi, int n, TValue **val,
1350 GCObject **owner) {
1351 switch (ttypetag(fi)) {
1352 case LUA_VCCL: { /* C closure */
1353 CClosure *f = clCvalue(fi);
1354 if (!(cast_uint(n) - 1u < cast_uint(f->nupvalues)))
1355 return NULL; /* 'n' not in [1, f->nupvalues] */
1356 *val = &f->upvalue[n-1];
1357 if (owner) *owner = obj2gco(f);
1358 return "";
1359 }
1360 case LUA_VLCL: { /* Lua closure */
1361 LClosure *f = clLvalue(fi);
1362 TString *name;
1363 Proto *p = f->p;
1364 if (!(cast_uint(n) - 1u < cast_uint(p->sizeupvalues)))
1365 return NULL; /* 'n' not in [1, p->sizeupvalues] */
1366 *val = f->upvals[n-1]->v;
1367 if (owner) *owner = obj2gco(f->upvals[n - 1]);
1368 name = p->upvalues[n-1].name;
1369 return (name == NULL) ? "(no name)" : getstr(name);
1370 }
1371 default: return NULL; /* not a closure */
1372 }
1373 }
1374
1375
lua_getupvalue(lua_State * L,int funcindex,int n)1376 LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
1377 const char *name;
1378 TValue *val = NULL; /* to avoid warnings */
1379 lua_lock(L);
1380 name = aux_upvalue(index2value(L, funcindex), n, &val, NULL);
1381 if (name) {
1382 setobj2s(L, L->top, val);
1383 api_incr_top(L);
1384 }
1385 lua_unlock(L);
1386 return name;
1387 }
1388
1389
lua_setupvalue(lua_State * L,int funcindex,int n)1390 LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
1391 const char *name;
1392 TValue *val = NULL; /* to avoid warnings */
1393 GCObject *owner = NULL; /* to avoid warnings */
1394 TValue *fi;
1395 lua_lock(L);
1396 fi = index2value(L, funcindex);
1397 api_checknelems(L, 1);
1398 name = aux_upvalue(fi, n, &val, &owner);
1399 if (name) {
1400 L->top--;
1401 setobj(L, val, s2v(L->top));
1402 luaC_barrier(L, owner, val);
1403 }
1404 lua_unlock(L);
1405 return name;
1406 }
1407
1408
getupvalref(lua_State * L,int fidx,int n,LClosure ** pf)1409 static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
1410 static const UpVal *const nullup = NULL;
1411 LClosure *f;
1412 TValue *fi = index2value(L, fidx);
1413 api_check(L, ttisLclosure(fi), "Lua function expected");
1414 f = clLvalue(fi);
1415 if (pf) *pf = f;
1416 if (1 <= n && n <= f->p->sizeupvalues)
1417 return &f->upvals[n - 1]; /* get its upvalue pointer */
1418 else
1419 return (UpVal**)&nullup;
1420 }
1421
1422
lua_upvalueid(lua_State * L,int fidx,int n)1423 LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
1424 TValue *fi = index2value(L, fidx);
1425 switch (ttypetag(fi)) {
1426 case LUA_VLCL: { /* lua closure */
1427 return *getupvalref(L, fidx, n, NULL);
1428 }
1429 case LUA_VCCL: { /* C closure */
1430 CClosure *f = clCvalue(fi);
1431 if (1 <= n && n <= f->nupvalues)
1432 return &f->upvalue[n - 1];
1433 /* else */
1434 } /* FALLTHROUGH */
1435 case LUA_VLCF:
1436 return NULL; /* light C functions have no upvalues */
1437 default: {
1438 api_check(L, 0, "function expected");
1439 return NULL;
1440 }
1441 }
1442 }
1443
1444
lua_upvaluejoin(lua_State * L,int fidx1,int n1,int fidx2,int n2)1445 LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
1446 int fidx2, int n2) {
1447 LClosure *f1;
1448 UpVal **up1 = getupvalref(L, fidx1, n1, &f1);
1449 UpVal **up2 = getupvalref(L, fidx2, n2, NULL);
1450 api_check(L, *up1 != NULL && *up2 != NULL, "invalid upvalue index");
1451 *up1 = *up2;
1452 luaC_objbarrier(L, f1, *up1);
1453 }
1454
1455
1456