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