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