• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tarantool / luajit / 24835022592

23 Apr 2026 12:16PM UTC coverage: 93.072% (-0.05%) from 93.126%
24835022592

push

github

Buristan
ci: conditionally install lua-cjson for perf job

We have encountered the flakiness of the network on our CI runners. It
happens only on lua-cjson installation and only in some particular job
run.

This patch helps to deal with it by installing this package only if it
is not installed in the system. Also, it installs it only for Lua 5.1,
which is compatible with LuaJIT.

5718 of 6056 branches covered (94.42%)

Branch coverage included in aggregate %.

21834 of 23547 relevant lines covered (92.73%)

3973170.39 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.88
/src/lj_api.c
1
/*
2
** Public Lua/C API.
3
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
4
**
5
** Major portions taken verbatim or adapted from the Lua interpreter.
6
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7
*/
8

9
#define lj_api_c
10
#define LUA_CORE
11

12
#include "lj_obj.h"
13
#include "lj_gc.h"
14
#include "lj_err.h"
15
#include "lj_debug.h"
16
#include "lj_str.h"
17
#include "lj_tab.h"
18
#include "lj_func.h"
19
#include "lj_udata.h"
20
#include "lj_meta.h"
21
#include "lj_state.h"
22
#include "lj_bc.h"
23
#include "lj_frame.h"
24
#include "lj_trace.h"
25
#include "lj_vm.h"
26
#include "lj_strscan.h"
27
#include "lj_strfmt.h"
28

29
/* -- Common helper functions --------------------------------------------- */
30

31
#define lj_checkapi_slot(idx) \
32
  lj_checkapi((idx) <= (L->top - L->base), "stack slot %d out of range", (idx))
33

34
static TValue *index2adr(lua_State *L, int idx)
25,328,187✔
35
{
36
  if (idx > 0) {
25,328,187✔
37
    TValue *o = L->base + (idx - 1);
9,580,985✔
38
    return o < L->top ? o : niltv(L);
9,580,985✔
39
  } else if (idx > LUA_REGISTRYINDEX) {
15,747,202✔
40
    lj_checkapi(idx != 0 && -idx <= L->top - L->base,
10,431,627✔
41
                "bad stack slot %d", idx);
42
    return L->top + idx;
10,431,627✔
43
  } else if (idx == LUA_GLOBALSINDEX) {
5,315,575✔
44
    TValue *o = &G(L)->tmptv;
7,688✔
45
    settabV(L, o, tabref(L->env));
7,688✔
46
    return o;
7,688✔
47
  } else if (idx == LUA_REGISTRYINDEX) {
5,307,887✔
48
    return registry(L);
4,303,914✔
49
  } else {
50
    GCfunc *fn = curr_func(L);
1,003,973✔
51
    lj_checkapi(fn->c.gct == ~LJ_TFUNC && !isluafunc(fn),
1,003,973✔
52
                "calling frame is not a C function");
53
    if (idx == LUA_ENVIRONINDEX) {
1,003,973✔
54
      TValue *o = &G(L)->tmptv;
2,981✔
55
      settabV(L, o, tabref(fn->c.env));
2,981✔
56
      return o;
2,981✔
57
    } else {
58
      idx = LUA_GLOBALSINDEX - idx;
1,000,992✔
59
      return idx <= fn->c.nupvalues ? &fn->c.upvalue[idx-1] : niltv(L);
1,000,992✔
60
    }
61
  }
62
}
63

64
static LJ_AINLINE TValue *index2adr_check(lua_State *L, int idx)
1,185,286✔
65
{
66
  TValue *o = index2adr(L, idx);
2,370,572✔
67
  lj_checkapi(o != niltv(L), "invalid stack slot %d", idx);
1,185,286✔
68
  return o;
1,185,286✔
69
}
70

71
static TValue *index2adr_stack(lua_State *L, int idx)
25,346✔
72
{
73
  if (idx > 0) {
25,346✔
74
    TValue *o = L->base + (idx - 1);
2,084✔
75
    if (o < L->top) {
2,084✔
76
      return o;
77
    } else {
78
      lj_checkapi(0, "invalid stack slot %d", idx);
×
79
      return niltv(L);
×
80
    }
81
    return o < L->top ? o : niltv(L);
82
  } else {
83
    lj_checkapi(idx != 0 && -idx <= L->top - L->base,
23,262✔
84
                "invalid stack slot %d", idx);
85
    return L->top + idx;
23,262✔
86
  }
87
}
88

89
static GCtab *getcurrenv(lua_State *L)
1,021,069✔
90
{
91
  GCfunc *fn = curr_func(L);
1,021,069✔
92
  return fn->c.gct == ~LJ_TFUNC ? tabref(fn->c.env) : tabref(L->env);
1,021,069✔
93
}
94

95
static void jit_secure_call(lua_State *L, TValue *base, int nres) {
5,218,227✔
96
  global_State *g = G(L);
5,218,227✔
97
  /* Forbid Lua world re-entrancy while running the trace */
98
  if (tvref(g->jit_base)) {
5,218,227✔
99
    setstrV(L, L->top++, lj_err_str(L, LJ_ERR_JITCALL));
1✔
100
    if (g->panic) g->panic(L);
1✔
101
    exit(EXIT_FAILURE);
1✔
102
  }
103
  lj_trace_abort(g);  /* Never record across Lua VM entrance */
5,218,226✔
104
  lj_vm_call(L, base, nres);
5,218,226✔
105
}
5,218,218✔
106

107
/* -- Miscellaneous API functions ----------------------------------------- */
108

109
LUA_API int lua_status(lua_State *L)
12✔
110
{
111
  return L->status;
12✔
112
}
113

114
LUA_API int lua_checkstack(lua_State *L, int size)
20,269✔
115
{
116
  if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) {
20,269✔
117
    return 0;  /* Stack overflow. */
118
  } else if (size > 0) {
20,269✔
119
    int avail = (int)(mref(L->maxstack, TValue) - L->top);
19,132✔
120
    if (size > avail &&
19,480✔
121
        lj_state_cpgrowstack(L, (MSize)(size - avail)) != LUA_OK) {
348✔
122
      L->top--;
1✔
123
      return 0;  /* Out of memory. */
1✔
124
    }
125
  }
126
  return 1;
127
}
128

129
LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
19,785✔
130
{
131
  if (!lua_checkstack(L, size))
19,785✔
132
    lj_err_callerv(L, LJ_ERR_STKOVM, msg);
×
133
}
19,785✔
134

135
LUA_API void lua_xmove(lua_State *L, lua_State *to, int n)
46✔
136
{
137
  TValue *f, *t;
46✔
138
  if (L == to) return;
46✔
139
  lj_checkapi_slot(n);
24✔
140
  lj_checkapi(G(L) == G(to), "move across global states");
24✔
141
  lj_state_checkstack(to, (MSize)n);
24✔
142
  f = L->top;
24✔
143
  t = to->top = to->top + n;
24✔
144
  while (--n >= 0) copyTV(to, --t, --f);
64✔
145
  L->top = f;
24✔
146
}
147

148
LUA_API const lua_Number *lua_version(lua_State *L)
×
149
{
150
  static const lua_Number version = LUA_VERSION_NUM;
×
151
  UNUSED(L);
×
152
  return &version;
×
153
}
154

155
/* -- Stack manipulation -------------------------------------------------- */
156

157
LUA_API int lua_gettop(lua_State *L)
197,456✔
158
{
159
  return (int)(L->top - L->base);
197,456✔
160
}
161

162
LUA_API void lua_settop(lua_State *L, int idx)
3,131,112✔
163
{
164
  if (idx >= 0) {
3,131,112✔
165
    lj_checkapi(idx <= tvref(L->maxstack) - L->base, "bad stack slot %d", idx);
1,077,566✔
166
    if (L->base + idx > L->top) {
1,077,566✔
167
      if (L->base + idx >= tvref(L->maxstack))
74,858✔
168
        lj_state_growstack(L, (MSize)idx - (MSize)(L->top - L->base));
×
169
      do { setnilV(L->top++); } while (L->top < L->base + idx);
194,166✔
170
    } else {
171
      L->top = L->base + idx;
1,002,708✔
172
    }
173
  } else {
174
    lj_checkapi(-(idx+1) <= (L->top - L->base), "bad stack slot %d", idx);
2,053,546✔
175
    L->top += idx+1;  /* Shrinks top (idx < 0). */
2,053,546✔
176
  }
177
}
3,131,112✔
178

179
LUA_API void lua_remove(lua_State *L, int idx)
23,225✔
180
{
181
  TValue *p = index2adr_stack(L, idx);
23,225✔
182
  while (++p < L->top) copyTV(L, p-1, p);
45,816✔
183
  L->top--;
23,225✔
184
}
23,225✔
185

186
LUA_API void lua_insert(lua_State *L, int idx)
1,353✔
187
{
188
  TValue *q, *p = index2adr_stack(L, idx);
1,353✔
189
  for (q = L->top; q > p; q--) copyTV(L, q, q-1);
3,746✔
190
  copyTV(L, p, L->top);
1,353✔
191
}
1,353✔
192

193
static void copy_slot(lua_State *L, TValue *f, int idx)
416✔
194
{
195
  if (idx == LUA_GLOBALSINDEX) {
416✔
196
    lj_checkapi(tvistab(f), "stack slot %d is not a table", idx);
×
197
    /* NOBARRIER: A thread (i.e. L) is never black. */
198
    setgcref(L->env, obj2gco(tabV(f)));
×
199
  } else if (idx == LUA_ENVIRONINDEX) {
416✔
200
    GCfunc *fn = curr_func(L);
416✔
201
    if (fn->c.gct != ~LJ_TFUNC)
416✔
202
      lj_err_msg(L, LJ_ERR_NOENV);
×
203
    lj_checkapi(tvistab(f), "stack slot %d is not a table", idx);
416✔
204
    setgcref(fn->c.env, obj2gco(tabV(f)));
416✔
205
    lj_gc_barrier(L, fn, f);
416✔
206
  } else {
207
    TValue *o = index2adr_check(L, idx);
×
208
    copyTV(L, o, f);
×
209
    if (idx < LUA_GLOBALSINDEX)  /* Need a barrier for upvalues. */
×
210
      lj_gc_barrier(L, curr_func(L), f);
×
211
  }
212
}
416✔
213

214
LUA_API void lua_replace(lua_State *L, int idx)
×
215
{
216
  lj_checkapi_slot(1);
×
217
  copy_slot(L, L->top - 1, idx);
×
218
  L->top--;
×
219
}
×
220

221
LUA_API void lua_copy(lua_State *L, int fromidx, int toidx)
416✔
222
{
223
  copy_slot(L, index2adr(L, fromidx), toidx);
416✔
224
}
416✔
225

226
LUA_API void lua_pushvalue(lua_State *L, int idx)
3,771,920✔
227
{
228
  copyTV(L, L->top, index2adr(L, idx));
3,771,920✔
229
  incr_top(L);
3,771,920✔
230
}
3,771,920✔
231

232
/* -- Stack getters ------------------------------------------------------- */
233

234
LUA_API int lua_type(lua_State *L, int idx)
7,343,105✔
235
{
236
  cTValue *o = index2adr(L, idx);
7,343,105✔
237
  if (tvisnumber(o)) {
7,343,105✔
238
    return LUA_TNUMBER;
239
#if LJ_64 && !LJ_GC64
240
  } else if (tvislightud(o)) {
241
    return LUA_TLIGHTUSERDATA;
242
#endif
243
  } else if (o == niltv(L)) {
7,343,073✔
244
    return LUA_TNONE;
245
  } else {  /* Magic internal/external tag conversion. ORDER LJ_T */
246
    uint32_t t = ~itype(o);
7,343,041✔
247
#if LJ_64
248
    int tt = (int)((U64x(75a06,98042110) >> 4*t) & 15u);
7,343,041✔
249
#else
250
    int tt = (int)(((t < 8 ? 0x98042110u : 0x75a06u) >> 4*(t&7)) & 15u);
251
#endif
252
    lj_assertL(tt != LUA_TNIL || tvisnil(o), "bad tag conversion");
7,343,041✔
253
    return tt;
7,343,041✔
254
  }
255
}
256

257
LUALIB_API void luaL_checktype(lua_State *L, int idx, int tt)
57✔
258
{
259
  if (lua_type(L, idx) != tt)
57✔
260
    lj_err_argt(L, idx, tt);
×
261
}
57✔
262

263
LUALIB_API void luaL_checkany(lua_State *L, int idx)
5✔
264
{
265
  if (index2adr(L, idx) == niltv(L))
5✔
266
    lj_err_arg(L, idx, LJ_ERR_NOVAL);
×
267
}
5✔
268

269
LUA_API const char *lua_typename(lua_State *L, int t)
1✔
270
{
271
  UNUSED(L);
1✔
272
  return lj_obj_typename[t+1];
1✔
273
}
274

275
LUA_API int lua_iscfunction(lua_State *L, int idx)
18✔
276
{
277
  cTValue *o = index2adr(L, idx);
18✔
278
  return tvisfunc(o) && !isluafunc(funcV(o));
18✔
279
}
280

281
LUA_API int lua_isnumber(lua_State *L, int idx)
71,296✔
282
{
283
  cTValue *o = index2adr(L, idx);
71,296✔
284
  TValue tmp;
71,296✔
285
  return (tvisnumber(o) || (tvisstr(o) && lj_strscan_number(strV(o), &tmp)));
71,296✔
286
}
287

288
LUA_API int lua_isstring(lua_State *L, int idx)
12,115✔
289
{
290
  cTValue *o = index2adr(L, idx);
12,115✔
291
  return (tvisstr(o) || tvisnumber(o));
12,115✔
292
}
293

294
LUA_API int lua_isuserdata(lua_State *L, int idx)
×
295
{
296
  cTValue *o = index2adr(L, idx);
×
297
  return (tvisudata(o) || tvislightud(o));
×
298
}
299

300
LUA_API int lua_rawequal(lua_State *L, int idx1, int idx2)
×
301
{
302
  cTValue *o1 = index2adr(L, idx1);
×
303
  cTValue *o2 = index2adr(L, idx2);
×
304
  return (o1 == niltv(L) || o2 == niltv(L)) ? 0 : lj_obj_equal(o1, o2);
×
305
}
306

307
LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
×
308
{
309
  cTValue *o1 = index2adr(L, idx1);
×
310
  cTValue *o2 = index2adr(L, idx2);
×
311
  if (tvisint(o1) && tvisint(o2)) {
×
312
    return intV(o1) == intV(o2);
313
  } else if (tvisnumber(o1) && tvisnumber(o2)) {
×
314
    return numberVnum(o1) == numberVnum(o2);
×
315
  } else if (itype(o1) != itype(o2)) {
×
316
    return 0;
317
  } else if (tvispri(o1)) {
×
318
    return o1 != niltv(L) && o2 != niltv(L);
×
319
#if LJ_64 && !LJ_GC64
320
  } else if (tvislightud(o1)) {
321
    return o1->u64 == o2->u64;
322
#endif
323
  } else if (gcrefeq(o1->gcr, o2->gcr)) {
×
324
    return 1;
325
  } else if (!tvistabud(o1)) {
×
326
    return 0;
327
  } else {
328
    TValue *base = lj_meta_equal(L, gcV(o1), gcV(o2), 0);
×
329
    if ((uintptr_t)base <= 1) {
×
330
      return (int)(uintptr_t)base;
×
331
    } else {
332
      L->top = base+2;
×
333
      jit_secure_call(L, base, 1+1);
×
334
      L->top -= 2+LJ_FR2;
×
335
      return tvistruecond(L->top+1+LJ_FR2);
×
336
    }
337
  }
338
}
339

340
LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2)
1,049,215✔
341
{
342
  cTValue *o1 = index2adr(L, idx1);
1,049,215✔
343
  cTValue *o2 = index2adr(L, idx2);
1,049,215✔
344
  if (o1 == niltv(L) || o2 == niltv(L)) {
1,049,215✔
345
    return 0;
346
  } else if (tvisint(o1) && tvisint(o2)) {
1,049,215✔
347
    return intV(o1) < intV(o2);
348
  } else if (tvisnumber(o1) && tvisnumber(o2)) {
1,049,215✔
349
    return numberVnum(o1) < numberVnum(o2);
937,096✔
350
  } else {
351
    TValue *base = lj_meta_comp(L, o1, o2, 0);
112,119✔
352
    if ((uintptr_t)base <= 1) {
112,119✔
353
      return (int)(uintptr_t)base;
102,133✔
354
    } else {
355
      L->top = base+2;
9,986✔
356
      jit_secure_call(L, base, 1+1);
9,986✔
357
      L->top -= 2+LJ_FR2;
9,986✔
358
      return tvistruecond(L->top+1+LJ_FR2);
9,986✔
359
    }
360
  }
361
}
362

363
LUA_API lua_Number lua_tonumber(lua_State *L, int idx)
288✔
364
{
365
  cTValue *o = index2adr(L, idx);
288✔
366
  TValue tmp;
288✔
367
  if (LJ_LIKELY(tvisnumber(o)))
288✔
368
    return numberVnum(o);
284✔
369
  else if (tvisstr(o) && lj_strscan_num(strV(o), &tmp))
4✔
370
    return numV(&tmp);
4✔
371
  else
372
    return 0;
×
373
}
374

375
LUA_API lua_Number lua_tonumberx(lua_State *L, int idx, int *ok)
×
376
{
377
  cTValue *o = index2adr(L, idx);
×
378
  TValue tmp;
×
379
  if (LJ_LIKELY(tvisnumber(o))) {
×
380
    if (ok) *ok = 1;
×
381
    return numberVnum(o);
×
382
  } else if (tvisstr(o) && lj_strscan_num(strV(o), &tmp)) {
×
383
    if (ok) *ok = 1;
×
384
    return numV(&tmp);
×
385
  } else {
386
    if (ok) *ok = 0;
×
387
    return 0;
×
388
  }
389
}
390

391
LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx)
12✔
392
{
393
  cTValue *o = index2adr(L, idx);
12✔
394
  TValue tmp;
12✔
395
  if (LJ_LIKELY(tvisnumber(o)))
12✔
396
    return numberVnum(o);
12✔
397
  else if (!(tvisstr(o) && lj_strscan_num(strV(o), &tmp)))
×
398
    lj_err_argt(L, idx, LUA_TNUMBER);
×
399
  return numV(&tmp);
×
400
}
401

402
LUALIB_API lua_Number luaL_optnumber(lua_State *L, int idx, lua_Number def)
4✔
403
{
404
  cTValue *o = index2adr(L, idx);
4✔
405
  TValue tmp;
4✔
406
  if (LJ_LIKELY(tvisnumber(o)))
4✔
407
    return numberVnum(o);
4✔
408
  else if (tvisnil(o))
×
409
    return def;
410
  else if (!(tvisstr(o) && lj_strscan_num(strV(o), &tmp)))
×
411
    lj_err_argt(L, idx, LUA_TNUMBER);
×
412
  return numV(&tmp);
×
413
}
414

415
LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
71,257✔
416
{
417
  cTValue *o = index2adr(L, idx);
71,257✔
418
  TValue tmp;
71,257✔
419
  lua_Number n;
71,257✔
420
  if (LJ_LIKELY(tvisint(o))) {
71,257✔
421
    return intV(o);
422
  } else if (LJ_LIKELY(tvisnum(o))) {
71,257✔
423
    n = numV(o);
71,255✔
424
  } else {
425
    if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
2✔
426
      return 0;
2✔
427
    if (tvisint(&tmp))
×
428
      return intV(&tmp);
429
    n = numV(&tmp);
×
430
  }
431
#if LJ_64
432
  return (lua_Integer)n;
71,255✔
433
#else
434
  return lj_num2int(n);
435
#endif
436
}
437

438
LUA_API lua_Integer lua_tointegerx(lua_State *L, int idx, int *ok)
×
439
{
440
  cTValue *o = index2adr(L, idx);
×
441
  TValue tmp;
×
442
  lua_Number n;
×
443
  if (LJ_LIKELY(tvisint(o))) {
×
444
    if (ok) *ok = 1;
445
    return intV(o);
446
  } else if (LJ_LIKELY(tvisnum(o))) {
×
447
    n = numV(o);
×
448
  } else {
449
    if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp))) {
×
450
      if (ok) *ok = 0;
×
451
      return 0;
×
452
    }
453
    if (tvisint(&tmp)) {
×
454
      if (ok) *ok = 1;
455
      return intV(&tmp);
456
    }
457
    n = numV(&tmp);
×
458
  }
459
  if (ok) *ok = 1;
×
460
#if LJ_64
461
  return (lua_Integer)n;
×
462
#else
463
  return lj_num2int(n);
464
#endif
465
}
466

467
LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx)
60✔
468
{
469
  cTValue *o = index2adr(L, idx);
60✔
470
  TValue tmp;
60✔
471
  lua_Number n;
60✔
472
  if (LJ_LIKELY(tvisint(o))) {
60✔
473
    return intV(o);
474
  } else if (LJ_LIKELY(tvisnum(o))) {
60✔
475
    n = numV(o);
60✔
476
  } else {
477
    if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
×
478
      lj_err_argt(L, idx, LUA_TNUMBER);
×
479
    if (tvisint(&tmp))
×
480
      return (lua_Integer)intV(&tmp);
481
    n = numV(&tmp);
×
482
  }
483
#if LJ_64
484
  return (lua_Integer)n;
60✔
485
#else
486
  return lj_num2int(n);
487
#endif
488
}
489

490
LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int idx, lua_Integer def)
22,606✔
491
{
492
  cTValue *o = index2adr(L, idx);
22,606✔
493
  TValue tmp;
22,606✔
494
  lua_Number n;
22,606✔
495
  if (LJ_LIKELY(tvisint(o))) {
22,606✔
496
    return intV(o);
497
  } else if (LJ_LIKELY(tvisnum(o))) {
22,606✔
498
    n = numV(o);
47✔
499
  } else if (tvisnil(o)) {
22,559✔
500
    return def;
501
  } else {
502
    if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
×
503
      lj_err_argt(L, idx, LUA_TNUMBER);
×
504
    if (tvisint(&tmp))
×
505
      return (lua_Integer)intV(&tmp);
506
    n = numV(&tmp);
×
507
  }
508
#if LJ_64
509
  return (lua_Integer)n;
47✔
510
#else
511
  return lj_num2int(n);
512
#endif
513
}
514

515
LUA_API int lua_toboolean(lua_State *L, int idx)
1,914,071✔
516
{
517
  cTValue *o = index2adr(L, idx);
1,914,071✔
518
  return tvistruecond(o);
1,914,071✔
519
}
520

521
LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len)
66,089✔
522
{
523
  TValue *o = index2adr(L, idx);
66,089✔
524
  GCstr *s;
66,089✔
525
  if (LJ_LIKELY(tvisstr(o))) {
66,089✔
526
    s = strV(o);
61,059✔
527
  } else if (tvisnumber(o)) {
5,030✔
528
    lj_gc_check(L);
5,008✔
529
    o = index2adr(L, idx);  /* GC may move the stack. */
5,008✔
530
    s = lj_strfmt_number(L, o);
5,008✔
531
    setstrV(L, o, s);
5,008✔
532
  } else {
533
    if (len != NULL) *len = 0;
22✔
534
    return NULL;
22✔
535
  }
536
  if (len != NULL) *len = s->len;
66,067✔
537
  return strdata(s);
66,067✔
538
}
539

540
LUA_API uint32_t lua_hashstring(lua_State *L, int idx)
×
541
{
542
  TValue *o = index2adr(L, idx);
×
543
  lj_checkapi(tvisstr(o), "stack slot %d is not a string", idx);
×
544
  GCstr *s = strV(o);
×
545
  if (! strsmart(s))
×
546
    return s->hash;
×
547
  return lua_hash(strdata(s), s->len);
×
548
}
549

550
LUALIB_API const char *luaL_checklstring(lua_State *L, int idx, size_t *len)
48,880✔
551
{
552
  TValue *o = index2adr(L, idx);
48,880✔
553
  GCstr *s;
48,880✔
554
  if (LJ_LIKELY(tvisstr(o))) {
48,880✔
555
    s = strV(o);
48,880✔
556
  } else if (tvisnumber(o)) {
×
557
    lj_gc_check(L);
×
558
    o = index2adr(L, idx);  /* GC may move the stack. */
×
559
    s = lj_strfmt_number(L, o);
×
560
    setstrV(L, o, s);
×
561
  } else {
562
    lj_err_argt(L, idx, LUA_TSTRING);
×
563
  }
564
  if (len != NULL) *len = s->len;
48,880✔
565
  return strdata(s);
48,880✔
566
}
567

568
LUALIB_API const char *luaL_optlstring(lua_State *L, int idx,
71,278✔
569
                                       const char *def, size_t *len)
570
{
571
  TValue *o = index2adr(L, idx);
71,278✔
572
  GCstr *s;
71,278✔
573
  if (LJ_LIKELY(tvisstr(o))) {
71,278✔
574
    s = strV(o);
71,162✔
575
  } else if (tvisnil(o)) {
116✔
576
    if (len != NULL) *len = def ? strlen(def) : 0;
116✔
577
    return def;
116✔
578
  } else if (tvisnumber(o)) {
×
579
    lj_gc_check(L);
×
580
    o = index2adr(L, idx);  /* GC may move the stack. */
×
581
    s = lj_strfmt_number(L, o);
×
582
    setstrV(L, o, s);
×
583
  } else {
584
    lj_err_argt(L, idx, LUA_TSTRING);
×
585
  }
586
  if (len != NULL) *len = s->len;
71,162✔
587
  return strdata(s);
71,162✔
588
}
589

590
LUALIB_API int luaL_checkoption(lua_State *L, int idx, const char *def,
×
591
                                const char *const lst[])
592
{
593
  ptrdiff_t i;
×
594
  const char *s = lua_tolstring(L, idx, NULL);
×
595
  if (s == NULL && (s = def) == NULL)
×
596
    lj_err_argt(L, idx, LUA_TSTRING);
×
597
  for (i = 0; lst[i]; i++)
×
598
    if (strcmp(lst[i], s) == 0)
×
599
      return (int)i;
×
600
  lj_err_argv(L, idx, LJ_ERR_INVOPTM, s);
×
601
}
602

603
LUA_API size_t lua_objlen(lua_State *L, int idx)
518✔
604
{
605
  TValue *o = index2adr(L, idx);
518✔
606
  if (tvisstr(o)) {
518✔
607
    return strV(o)->len;
516✔
608
  } else if (tvistab(o)) {
2✔
609
    return (size_t)lj_tab_len(tabV(o));
2✔
610
  } else if (tvisudata(o)) {
×
611
    return udataV(o)->len;
×
612
  } else if (tvisnumber(o)) {
×
613
    GCstr *s = lj_strfmt_number(L, o);
×
614
    setstrV(L, o, s);
×
615
    return s->len;
×
616
  } else {
617
    return 0;
618
  }
619
}
620

621
LUA_API lua_CFunction lua_tocfunction(lua_State *L, int idx)
4✔
622
{
623
  cTValue *o = index2adr(L, idx);
4✔
624
  if (tvisfunc(o)) {
4✔
625
    BCOp op = bc_op(*mref(funcV(o)->c.pc, BCIns));
4✔
626
    if (op == BC_FUNCC || op == BC_FUNCCW)
4✔
627
      return funcV(o)->c.f;
4✔
628
  }
629
  return NULL;
630
}
631

632
LUA_API void *lua_touserdata(lua_State *L, int idx)
4✔
633
{
634
  cTValue *o = index2adr(L, idx);
4✔
635
  if (tvisudata(o))
4✔
636
    return uddata(udataV(o));
4✔
637
  else if (tvislightud(o))
×
638
    return lightudV(G(L), o);
×
639
  else
640
    return NULL;
641
}
642

643
LUA_API lua_State *lua_tothread(lua_State *L, int idx)
12✔
644
{
645
  cTValue *o = index2adr(L, idx);
12✔
646
  return (!tvisthread(o)) ? NULL : threadV(o);
12✔
647
}
648

649
LUA_API const void *lua_topointer(lua_State *L, int idx)
256✔
650
{
651
  return lj_obj_ptr(G(L), index2adr(L, idx));
256✔
652
}
653

654
/* -- Stack setters (object creation) ------------------------------------- */
655

656
LUA_API void lua_pushnil(lua_State *L)
3,771✔
657
{
658
  setnilV(L->top);
3,771✔
659
  incr_top(L);
3,771✔
660
}
3,771✔
661

662
LUA_API void lua_pushnumber(lua_State *L, lua_Number n)
283✔
663
{
664
  setnumV(L->top, n);
283✔
665
  if (LJ_UNLIKELY(tvisnan(L->top)))
283✔
666
    setnanV(L->top);  /* Canonicalize injected NaNs. */
×
667
  incr_top(L);
283✔
668
}
283✔
669

670
LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
4,508,888✔
671
{
672
  setintptrV(L->top, n);
4,508,888✔
673
  incr_top(L);
4,508,888✔
674
}
4,508,885✔
675

676
LUA_API void lua_pushlstring(lua_State *L, const char *str, size_t len)
77,923✔
677
{
678
  GCstr *s;
77,923✔
679
  lj_gc_check(L);
77,923✔
680
  s = lj_str_new(L, str, len);
77,923✔
681
  setstrV(L, L->top, s);
77,923✔
682
  incr_top(L);
77,923✔
683
}
77,923✔
684

685
LUA_API void lua_pushstring(lua_State *L, const char *str)
4,444,832✔
686
{
687
  if (str == NULL) {
4,444,832✔
688
    setnilV(L->top);
132✔
689
  } else {
690
    GCstr *s;
4,444,700✔
691
    lj_gc_check(L);
4,444,700✔
692
    s = lj_str_newz(L, str);
4,444,700✔
693
    setstrV(L, L->top, s);
4,444,700✔
694
  }
695
  incr_top(L);
4,444,832✔
696
}
4,444,832✔
697

698
LUA_API const char *lua_pushvfstring(lua_State *L, const char *fmt,
×
699
                                     va_list argp)
700
{
701
  lj_gc_check(L);
×
702
  return lj_strfmt_pushvf(L, fmt, argp);
×
703
}
704

705
LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...)
30,582✔
706
{
707
  const char *ret;
30,582✔
708
  va_list argp;
30,582✔
709
  lj_gc_check(L);
30,582✔
710
  va_start(argp, fmt);
30,582✔
711
  ret = lj_strfmt_pushvf(L, fmt, argp);
30,582✔
712
  va_end(argp);
30,580✔
713
  return ret;
30,580✔
714
}
715

716
LUA_API void lua_pushcclosure(lua_State *L, lua_CFunction f, int n)
13,704✔
717
{
718
  GCfunc *fn;
13,704✔
719
  lj_gc_check(L);
13,704✔
720
  lj_checkapi_slot(n);
13,704✔
721
  fn = lj_func_newC(L, (MSize)n, getcurrenv(L));
27,408✔
722
  fn->c.f = f;
13,704✔
723
  L->top -= n;
13,704✔
724
  while (n--)
13,704✔
725
    copyTV(L, &fn->c.upvalue[n], L->top+n);
15,413✔
726
  setfuncV(L, L->top, fn);
13,704✔
727
  lj_assertL(iswhite(obj2gco(fn)), "new GC object is not white");
13,704✔
728
  incr_top(L);
13,704✔
729
}
13,704✔
730

731
LUA_API void lua_pushboolean(lua_State *L, int b)
1,001,241✔
732
{
733
  setboolV(L->top, (b != 0));
1,001,241✔
734
  incr_top(L);
1,001,241✔
735
}
1,001,241✔
736

737
LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
291✔
738
{
739
#if LJ_64
740
  p = lj_lightud_intern(L, p);
291✔
741
#endif
742
  setrawlightudV(L->top, p);
289✔
743
  incr_top(L);
289✔
744
}
289✔
745

746
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
1,092,254✔
747
{
748
  lj_gc_check(L);
1,092,254✔
749
  settabV(L, L->top, lj_tab_new_ah(L, narray, nrec));
1,092,254✔
750
  incr_top(L);
1,092,254✔
751
}
1,092,254✔
752

753
LUALIB_API int luaL_newmetatable(lua_State *L, const char *tname)
419✔
754
{
755
  GCtab *regt = tabV(registry(L));
419✔
756
  TValue *tv = lj_tab_setstr(L, regt, lj_str_newz(L, tname));
419✔
757
  if (tvisnil(tv)) {
419✔
758
    GCtab *mt = lj_tab_new(L, 0, 1);
419✔
759
    settabV(L, tv, mt);
419✔
760
    settabV(L, L->top++, mt);
419✔
761
    lj_gc_anybarriert(L, regt);
419✔
762
    return 1;
419✔
763
  } else {
764
    copyTV(L, L->top++, tv);
×
765
    return 0;
×
766
  }
767
}
768

769
LUA_API int lua_pushthread(lua_State *L)
4✔
770
{
771
  setthreadV(L, L->top, L);
4✔
772
  incr_top(L);
4✔
773
  return (mainthread(G(L)) == L);
4✔
774
}
775

776
LUA_API lua_State *lua_newthread(lua_State *L)
1,530✔
777
{
778
  lua_State *L1;
1,530✔
779
  lj_gc_check(L);
1,530✔
780
  L1 = lj_state_new(L);
1,530✔
781
  setthreadV(L, L->top, L1);
1,530✔
782
  incr_top(L);
1,530✔
783
  return L1;
1,530✔
784
}
785

786
LUA_API void *lua_newuserdata(lua_State *L, size_t size)
1,006,953✔
787
{
788
  GCudata *ud;
1,006,953✔
789
  lj_gc_check(L);
1,006,953✔
790
  if (size > LJ_MAX_UDATA)
1,006,953✔
791
    lj_err_msg(L, LJ_ERR_UDATAOV);
×
792
  ud = lj_udata_new(L, (MSize)size, getcurrenv(L));
2,013,906✔
793
  setudataV(L, L->top, ud);
1,006,953✔
794
  incr_top(L);
1,006,953✔
795
  return uddata(ud);
1,006,953✔
796
}
797

798
LUA_API void lua_concat(lua_State *L, int n)
28,532✔
799
{
800
  lj_checkapi_slot(n);
28,532✔
801
  if (n >= 2) {
28,532✔
802
    n--;
1,187✔
803
    do {
1,187✔
804
      TValue *top = lj_meta_cat(L, L->top-1, -n);
1,187✔
805
      if (top == NULL) {
1,187✔
806
        L->top -= n;
1,186✔
807
        break;
1,186✔
808
      }
809
      n -= (int)(L->top - (top - 2*LJ_FR2));
1✔
810
      L->top = top+2;
1✔
811
      jit_secure_call(L, top, 1+1);
1✔
812
      L->top -= 1+LJ_FR2;
1✔
813
      copyTV(L, L->top-1, L->top+LJ_FR2);
1✔
814
    } while (--n > 0);
1✔
815
  } else if (n == 0) {  /* Push empty string. */
27,345✔
816
    setstrV(L, L->top, &G(L)->strempty);
31✔
817
    incr_top(L);
31✔
818
  }
819
  /* else n == 1: nothing to do. */
820
}
28,532✔
821

822
/* -- Object getters ------------------------------------------------------ */
823

824
LUA_API void lua_gettable(lua_State *L, int idx)
152✔
825
{
826
  cTValue *t = index2adr_check(L, idx);
152✔
827
  cTValue *v = lj_meta_tget(L, t, L->top-1);
152✔
828
  if (v == NULL) {
152✔
829
    L->top += 2;
2✔
830
    jit_secure_call(L, L->top-2, 1+1);
2✔
831
    L->top -= 2+LJ_FR2;
2✔
832
    v = L->top+1+LJ_FR2;
2✔
833
  }
834
  copyTV(L, L->top-1, v);
152✔
835
}
152✔
836

837
LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
15,568✔
838
{
839
  cTValue *v, *t = index2adr_check(L, idx);
15,568✔
840
  TValue key;
15,568✔
841
  setstrV(L, &key, lj_str_newz(L, k));
15,568✔
842
  v = lj_meta_tget(L, t, &key);
15,568✔
843
  if (v == NULL) {
15,568✔
844
    L->top += 2;
×
845
    jit_secure_call(L, L->top-2, 1+1);
×
846
    L->top -= 2+LJ_FR2;
×
847
    v = L->top+1+LJ_FR2;
×
848
  }
849
  copyTV(L, L->top, v);
15,568✔
850
  incr_top(L);
15,568✔
851
}
15,568✔
852

853
LUA_API void lua_rawget(lua_State *L, int idx)
4,309,862✔
854
{
855
  cTValue *t = index2adr(L, idx);
4,309,862✔
856
  lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
4,309,862✔
857
  copyTV(L, L->top-1, lj_tab_get(L, tabV(t), L->top-1));
4,309,862✔
858
}
4,309,862✔
859

860
LUA_API void lua_rawgeti(lua_State *L, int idx, int n)
2,296,530✔
861
{
862
  cTValue *v, *t = index2adr(L, idx);
2,296,530✔
863
  lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
2,296,530✔
864
  v = lj_tab_getint(tabV(t), n);
2,296,530✔
865
  if (v) {
2,296,530✔
866
    copyTV(L, L->top, v);
2,296,473✔
867
  } else {
868
    setnilV(L->top);
57✔
869
  }
870
  incr_top(L);
2,296,530✔
871
}
2,296,530✔
872

873
LUA_API int lua_getmetatable(lua_State *L, int idx)
22,018✔
874
{
875
  cTValue *o = index2adr(L, idx);
22,018✔
876
  GCtab *mt = NULL;
22,018✔
877
  if (tvistab(o))
22,018✔
878
    mt = tabref(tabV(o)->metatable);
16✔
879
  else if (tvisudata(o))
22,002✔
880
    mt = tabref(udataV(o)->metatable);
1,946✔
881
  else
882
    mt = tabref(basemt_obj(G(L), o));
20,056✔
883
  if (mt == NULL)
22,018✔
884
    return 0;
885
  settabV(L, L->top, mt);
22,004✔
886
  incr_top(L);
22,004✔
887
  return 1;
888
}
889

890
LUALIB_API int luaL_getmetafield(lua_State *L, int idx, const char *field)
1✔
891
{
892
  if (lua_getmetatable(L, idx)) {
1✔
893
    cTValue *tv = lj_tab_getstr(tabV(L->top-1), lj_str_newz(L, field));
×
894
    if (tv && !tvisnil(tv)) {
×
895
      copyTV(L, L->top-1, tv);
×
896
      return 1;
×
897
    }
898
    L->top--;
×
899
  }
900
  return 0;
901
}
902

903
LUA_API void lua_getfenv(lua_State *L, int idx)
14✔
904
{
905
  cTValue *o = index2adr_check(L, idx);
14✔
906
  if (tvisfunc(o)) {
14✔
907
    settabV(L, L->top, tabref(funcV(o)->c.env));
8✔
908
  } else if (tvisudata(o)) {
6✔
909
    settabV(L, L->top, tabref(udataV(o)->env));
×
910
  } else if (tvisthread(o)) {
6✔
911
    settabV(L, L->top, tabref(threadV(o)->env));
5✔
912
  } else {
913
    setnilV(L->top);
1✔
914
  }
915
  incr_top(L);
14✔
916
}
14✔
917

918
LUA_API int lua_next(lua_State *L, int idx)
159✔
919
{
920
  cTValue *t = index2adr(L, idx);
159✔
921
  int more;
159✔
922
  lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
159✔
923
  more = lj_tab_next(L, tabV(t), L->top-1);
159✔
924
  if (more) {
159✔
925
    incr_top(L);  /* Return new key and value slot. */
106✔
926
  } else {  /* End of traversal. */
927
    L->top--;  /* Remove key slot. */
53✔
928
  }
929
  return more;
159✔
930
}
931

932
LUA_API const char *lua_getupvalue(lua_State *L, int idx, int n)
12✔
933
{
934
  TValue *val;
12✔
935
  GCobj *o;
12✔
936
  const char *name = lj_debug_uvnamev(index2adr(L, idx), (uint32_t)(n-1), &val, &o);
12✔
937
  if (name) {
12✔
938
    copyTV(L, L->top, val);
7✔
939
    incr_top(L);
7✔
940
  }
941
  return name;
12✔
942
}
943

944
LUA_API void *lua_upvalueid(lua_State *L, int idx, int n)
×
945
{
946
  GCfunc *fn = funcV(index2adr(L, idx));
×
947
  n--;
×
948
  lj_checkapi((uint32_t)n < fn->l.nupvalues, "bad upvalue %d", n);
×
949
  return isluafunc(fn) ? (void *)gcref(fn->l.uvptr[n]) :
×
950
                         (void *)&fn->c.upvalue[n];
951
}
952

953
LUA_API void lua_upvaluejoin(lua_State *L, int idx1, int n1, int idx2, int n2)
×
954
{
955
  GCfunc *fn1 = funcV(index2adr(L, idx1));
×
956
  GCfunc *fn2 = funcV(index2adr(L, idx2));
×
957
  n1--; n2--;
×
958
  lj_checkapi(isluafunc(fn1), "stack slot %d is not a Lua function", idx1);
×
959
  lj_checkapi(isluafunc(fn2), "stack slot %d is not a Lua function", idx2);
×
960
  lj_checkapi((uint32_t)n1 < fn1->l.nupvalues, "bad upvalue %d", n1+1);
×
961
  lj_checkapi((uint32_t)n2 < fn2->l.nupvalues, "bad upvalue %d", n2+1);
×
962
  setgcrefr(fn1->l.uvptr[n1], fn2->l.uvptr[n2]);
×
963
  lj_gc_objbarrier(L, fn1, gcref(fn1->l.uvptr[n1]));
×
964
}
×
965

966
LUALIB_API void *luaL_testudata(lua_State *L, int idx, const char *tname)
30✔
967
{
968
  cTValue *o = index2adr(L, idx);
30✔
969
  if (tvisudata(o)) {
30✔
970
    GCudata *ud = udataV(o);
30✔
971
    cTValue *tv = lj_tab_getstr(tabV(registry(L)), lj_str_newz(L, tname));
30✔
972
    if (tv && tvistab(tv) && tabV(tv) == tabref(ud->metatable))
30✔
973
      return uddata(ud);
30✔
974
  }
975
  return NULL;  /* value is not a userdata with a metatable */
976
}
977

978
LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
30✔
979
{
980
  void *p = luaL_testudata(L, idx, tname);
30✔
981
  if (!p) lj_err_argtype(L, idx, tname);
30✔
982
  return p;
30✔
983
}
984

985
/* -- Object setters ------------------------------------------------------ */
986

987
LUA_API void lua_settable(lua_State *L, int idx)
7,139✔
988
{
989
  TValue *o;
7,139✔
990
  cTValue *t = index2adr_check(L, idx);
7,139✔
991
  lj_checkapi_slot(2);
7,139✔
992
  o = lj_meta_tset(L, t, L->top-2);
7,139✔
993
  if (o) {
7,139✔
994
    /* NOBARRIER: lj_meta_tset ensures the table is not black. */
995
    L->top -= 2;
7,137✔
996
    copyTV(L, o, L->top+1);
7,137✔
997
  } else {
998
    TValue *base = L->top;
2✔
999
    copyTV(L, base+2, base-3-2*LJ_FR2);
2✔
1000
    L->top = base+3;
2✔
1001
    jit_secure_call(L, base, 0+1);
2✔
1002
    L->top -= 3+LJ_FR2;
2✔
1003
  }
1004
}
7,139✔
1005

1006
LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
161,328✔
1007
{
1008
  TValue *o;
161,328✔
1009
  TValue key;
161,328✔
1010
  cTValue *t = index2adr_check(L, idx);
161,328✔
1011
  lj_checkapi_slot(1);
161,328✔
1012
  setstrV(L, &key, lj_str_newz(L, k));
161,328✔
1013
  o = lj_meta_tset(L, t, &key);
161,328✔
1014
  if (o) {
161,328✔
1015
    /* NOBARRIER: lj_meta_tset ensures the table is not black. */
1016
    copyTV(L, o, --L->top);
161,328✔
1017
  } else {
1018
    TValue *base = L->top;
×
1019
    copyTV(L, base+2, base-3-2*LJ_FR2);
×
1020
    L->top = base+3;
×
1021
    jit_secure_call(L, base, 0+1);
×
1022
    L->top -= 2+LJ_FR2;
×
1023
  }
1024
}
161,328✔
1025

1026
LUA_API void lua_rawset(lua_State *L, int idx)
1,000,367✔
1027
{
1028
  GCtab *t = tabV(index2adr(L, idx));
1,000,367✔
1029
  TValue *dst, *key;
1,000,367✔
1030
  lj_checkapi_slot(2);
1,000,367✔
1031
  key = L->top-2;
1,000,367✔
1032
  dst = lj_tab_set(L, t, key);
1,000,367✔
1033
  copyTV(L, dst, key+1);
1,000,366✔
1034
  lj_gc_anybarriert(L, t);
1,000,366✔
1035
  L->top = key;
1,000,366✔
1036
}
1,000,366✔
1037

1038
LUA_API void lua_rawseti(lua_State *L, int idx, int n)
1,016,237✔
1039
{
1040
  GCtab *t = tabV(index2adr(L, idx));
1,016,237✔
1041
  TValue *dst, *src;
1,016,237✔
1042
  lj_checkapi_slot(1);
1,016,237✔
1043
  dst = lj_tab_setint(L, t, n);
1,016,237✔
1044
  src = L->top-1;
1,016,237✔
1045
  copyTV(L, dst, src);
1,016,237✔
1046
  lj_gc_barriert(L, t, dst);
1,016,237✔
1047
  L->top = src;
1,016,237✔
1048
}
1,016,237✔
1049

1050
LUA_API int lua_setmetatable(lua_State *L, int idx)
1,001,066✔
1051
{
1052
  global_State *g;
1,001,066✔
1053
  GCtab *mt;
1,001,066✔
1054
  cTValue *o = index2adr_check(L, idx);
1,001,066✔
1055
  lj_checkapi_slot(1);
1,001,066✔
1056
  if (tvisnil(L->top-1)) {
1,001,066✔
1057
    mt = NULL;
1058
  } else {
1059
    lj_checkapi(tvistab(L->top-1), "top stack slot is not a table");
1,001,059✔
1060
    mt = tabV(L->top-1);
1,001,059✔
1061
  }
1062
  g = G(L);
1,001,066✔
1063
  if (tvistab(o)) {
1,001,066✔
1064
    setgcref(tabV(o)->metatable, obj2gco(mt));
10✔
1065
    if (mt)
10✔
1066
      lj_gc_objbarriert(L, tabV(o), mt);
10✔
1067
  } else if (tvisudata(o)) {
1,001,056✔
1068
    setgcref(udataV(o)->metatable, obj2gco(mt));
1,001,031✔
1069
    if (mt)
1,001,031✔
1070
      lj_gc_objbarrier(L, udataV(o), mt);
1,001,030✔
1071
  } else {
1072
    /* Flush cache, since traces specialize to basemt. But not during __gc. */
1073
    if (lj_trace_flushall(L))
25✔
1074
      lj_err_caller(L, LJ_ERR_NOGCMM);
×
1075
    o = index2adr(L, idx);  /* Stack may have been reallocated. */
25✔
1076
    if (tvisbool(o)) {
25✔
1077
      /* NOBARRIER: basemt is a GC root. */
1078
      setgcref(basemt_it(g, LJ_TTRUE), obj2gco(mt));
4✔
1079
      setgcref(basemt_it(g, LJ_TFALSE), obj2gco(mt));
4✔
1080
    } else {
1081
      /* NOBARRIER: basemt is a GC root. */
1082
      setgcref(basemt_obj(g, o), obj2gco(mt));
21✔
1083
    }
1084
  }
1085
  L->top--;
1,001,066✔
1086
  return 1;
1,001,066✔
1087
}
1088

1089
LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
30✔
1090
{
1091
  lua_getfield(L, LUA_REGISTRYINDEX, tname);
30✔
1092
  lua_setmetatable(L, -2);
30✔
1093
}
30✔
1094

1095
LUA_API int lua_setfenv(lua_State *L, int idx)
19✔
1096
{
1097
  cTValue *o = index2adr_check(L, idx);
19✔
1098
  GCtab *t;
19✔
1099
  lj_checkapi_slot(1);
19✔
1100
  lj_checkapi(tvistab(L->top-1), "top stack slot is not a table");
19✔
1101
  t = tabV(L->top-1);
19✔
1102
  if (tvisfunc(o)) {
19✔
1103
    setgcref(funcV(o)->c.env, obj2gco(t));
14✔
1104
  } else if (tvisudata(o)) {
5✔
1105
    setgcref(udataV(o)->env, obj2gco(t));
×
1106
  } else if (tvisthread(o)) {
5✔
1107
    setgcref(threadV(o)->env, obj2gco(t));
4✔
1108
  } else {
1109
    L->top--;
1✔
1110
    return 0;
1✔
1111
  }
1112
  lj_gc_objbarrier(L, gcV(o), t);
18✔
1113
  L->top--;
18✔
1114
  return 1;
18✔
1115
}
1116

1117
LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n)
9✔
1118
{
1119
  cTValue *f = index2adr(L, idx);
9✔
1120
  TValue *val;
9✔
1121
  GCobj *o;
9✔
1122
  const char *name;
9✔
1123
  lj_checkapi_slot(1);
9✔
1124
  name = lj_debug_uvnamev(f, (uint32_t)(n-1), &val, &o);
9✔
1125
  if (name) {
9✔
1126
    L->top--;
5✔
1127
    copyTV(L, val, L->top);
5✔
1128
    lj_gc_barrier(L, o, L->top);
5✔
1129
  }
1130
  return name;
9✔
1131
}
1132

1133
/* -- Calls --------------------------------------------------------------- */
1134

1135
#if LJ_FR2
1136
static TValue *api_call_base(lua_State *L, int nargs)
5,209,489✔
1137
{
1138
  TValue *o = L->top, *base = o - nargs;
5,209,489✔
1139
  L->top = o+1;
5,209,489✔
1140
  for (; o > base; o--) copyTV(L, o, o-1);
15,606,501✔
1141
  setnilV(o);
5,209,489✔
1142
  return o+1;
5,209,489✔
1143
}
1144
#else
1145
#define api_call_base(L, nargs)        (L->top - (nargs))
1146
#endif
1147

1148
LUA_API void lua_call(lua_State *L, int nargs, int nresults)
5,208,236✔
1149
{
1150
  lj_checkapi(L->status == LUA_OK || L->status == LUA_ERRERR,
5,208,236✔
1151
              "thread called in wrong state %d", L->status);
1152
  lj_checkapi_slot(nargs+1);
5,208,236✔
1153
  jit_secure_call(L, api_call_base(L, nargs), nresults+1);
10,416,472✔
1154
}
5,208,227✔
1155

1156
LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
1,250✔
1157
{
1158
  global_State *g = G(L);
1,250✔
1159
  uint8_t oldh = hook_save(g);
1,250✔
1160
  ptrdiff_t ef;
1,250✔
1161
  int status;
1,250✔
1162
  lj_checkapi(L->status == LUA_OK || L->status == LUA_ERRERR,
1,250✔
1163
              "thread called in wrong state %d", L->status);
1164
  lj_checkapi_slot(nargs+1);
1,250✔
1165
  if (errfunc == 0) {
1,250✔
1166
    ef = 0;
1167
  } else {
1168
    cTValue *o = index2adr_stack(L, errfunc);
768✔
1169
    ef = savestack(L, o);
768✔
1170
  }
1171
  /* Forbid Lua world re-entrancy while running the trace */
1172
  if (tvref(g->jit_base)) {
1,250✔
1173
    setstrV(L, L->top++, lj_err_str(L, LJ_ERR_JITCALL));
×
1174
    if (g->panic) g->panic(L);
×
1175
    exit(EXIT_FAILURE);
×
1176
  }
1177
  lj_trace_abort(g);  /* Never record across Lua VM entrance */
1,250✔
1178
  status = lj_vm_pcall(L, api_call_base(L, nargs), nresults+1, ef);
2,500✔
1179
  if (status) hook_restore(g, oldh);
987✔
1180
  return status;
987✔
1181
}
1182

1183
static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud)
412✔
1184
{
1185
  GCfunc *fn = lj_func_newC(L, 0, getcurrenv(L));
824✔
1186
  TValue *top = L->top;
412✔
1187
  fn->c.f = func;
412✔
1188
  setfuncV(L, top++, fn);
412✔
1189
  if (LJ_FR2) setnilV(top++);
412✔
1190
#if LJ_64
1191
  ud = lj_lightud_intern(L, ud);
412✔
1192
#endif
1193
  setrawlightudV(top++, ud);
412✔
1194
  cframe_nres(L->cframe) = 1+0;  /* Zero results. */
412✔
1195
  L->top = top;
412✔
1196
  return top-1;  /* Now call the newly allocated C function. */
412✔
1197
}
1198

1199
LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
412✔
1200
{
1201
  global_State *g = G(L);
412✔
1202
  uint8_t oldh = hook_save(g);
412✔
1203
  int status;
412✔
1204
  lj_checkapi(L->status == LUA_OK || L->status == LUA_ERRERR,
412✔
1205
              "thread called in wrong state %d", L->status);
1206
  /* Forbid Lua world re-entrancy while running the trace */
1207
  if (tvref(g->jit_base)) {
412✔
1208
    setstrV(L, L->top++, lj_err_str(L, LJ_ERR_JITCALL));
×
1209
    if (g->panic) g->panic(L);
×
1210
    exit(EXIT_FAILURE);
×
1211
  }
1212
  lj_trace_abort(g);  /* Never record across Lua VM entrance */
412✔
1213
  status = lj_vm_cpcall(L, func, ud, cpcall);
412✔
1214
  if (status) hook_restore(g, oldh);
149✔
1215
  return status;
149✔
1216
}
1217

1218
LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
1✔
1219
{
1220
  if (luaL_getmetafield(L, idx, field)) {
1✔
1221
    TValue *top = L->top--;
×
1222
    if (LJ_FR2) setnilV(top++);
×
1223
    copyTV(L, top++, index2adr(L, idx));
×
1224
    L->top = top;
×
1225
    jit_secure_call(L, top-1, 1+1);
×
1226
    return 1;
×
1227
  }
1228
  return 0;
1229
}
1230

1231
/* -- Coroutine yield and resume ------------------------------------------ */
1232

1233
LUA_API int lua_isyieldable(lua_State *L)
×
1234
{
1235
  return cframe_canyield(L->cframe);
×
1236
}
1237

1238
LUA_API int lua_yield(lua_State *L, int nresults)
11✔
1239
{
1240
  void *cf = L->cframe;
11✔
1241
  global_State *g = G(L);
11✔
1242
  if (cframe_canyield(cf)) {
11✔
1243
    cf = cframe_raw(cf);
11✔
1244
    if (!hook_active(g)) {  /* Regular yield: move results down if needed. */
11✔
1245
      cTValue *f = L->top - nresults;
9✔
1246
      if (f > L->base) {
9✔
1247
        TValue *t = L->base;
1248
        while (--nresults >= 0) copyTV(L, t++, f++);
×
1249
        L->top = t;
×
1250
      }
1251
      L->cframe = NULL;
9✔
1252
      L->status = LUA_YIELD;
9✔
1253
      return -1;
9✔
1254
    } else {  /* Yield from hook: add a pseudo-frame. */
1255
      TValue *top = L->top;
2✔
1256
      hook_leave(g);
2✔
1257
      (top++)->u64 = cframe_multres(cf);
2✔
1258
      setcont(top, lj_cont_hook);
2✔
1259
      if (LJ_FR2) top++;
2✔
1260
      setframe_pc(top, cframe_pc(cf)-1);
2✔
1261
      top++;
2✔
1262
      setframe_gc(top, obj2gco(L), LJ_TTHREAD);
2✔
1263
      if (LJ_FR2) top++;
2✔
1264
      setframe_ftsz(top, ((char *)(top+1)-(char *)L->base)+FRAME_CONT);
2✔
1265
      L->top = L->base = top+1;
2✔
1266
#if ((defined(__GNUC__) || defined(__clang__)) && (LJ_TARGET_X64 || defined(LUAJIT_UNWIND_EXTERNAL)) && !LJ_NO_UNWIND) || LJ_TARGET_WINDOWS
1267
      lj_err_throw(L, LUA_YIELD);
2✔
1268
#else
1269
      L->cframe = NULL;
1270
      L->status = LUA_YIELD;
1271
      lj_vm_unwind_c(cf, LUA_YIELD);
1272
#endif
1273
    }
1274
  }
1275
  lj_err_msg(L, LJ_ERR_CYIELD);
×
1276
  return 0;  /* unreachable */
1277
}
1278

1279
LUA_API int lua_resume(lua_State *L, int nargs)
11✔
1280
{
1281
  if (L->cframe == NULL && L->status <= LUA_YIELD)
11✔
1282
    return lj_vm_resume(L,
22✔
1283
      L->status == LUA_OK ? api_call_base(L, nargs) : L->top - nargs,
14✔
1284
      0, 0);
1285
  L->top = L->base;
×
1286
  setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP));
×
1287
  incr_top(L);
×
1288
  return LUA_ERRRUN;
1289
}
1290

1291
/* -- GC and memory management -------------------------------------------- */
1292

1293
LUA_API int lua_gc(lua_State *L, int what, int data)
52,724✔
1294
{
1295
  global_State *g = G(L);
52,724✔
1296
  int res = 0;
52,724✔
1297
  switch (what) {
52,724✔
1298
  case LUA_GCSTOP:
435✔
1299
    g->gc.threshold = LJ_MAX_MEM;
435✔
1300
    break;
435✔
1301
  case LUA_GCRESTART:
421✔
1302
    g->gc.threshold = data == -1 ? (g->gc.total/100)*g->gc.pause : g->gc.total;
421✔
1303
    break;
421✔
1304
  case LUA_GCCOLLECT:
11,076✔
1305
    lj_gc_fullgc(L);
11,076✔
1306
    break;
11,076✔
1307
  case LUA_GCCOUNT:
×
1308
    res = (int)(g->gc.total >> 10);
×
1309
    break;
×
1310
  case LUA_GCCOUNTB:
×
1311
    res = (int)(g->gc.total & 0x3ff);
×
1312
    break;
×
1313
  case LUA_GCSTEP: {
20,605✔
1314
    GCSize a = (GCSize)data << 10;
20,605✔
1315
    g->gc.threshold = (a <= g->gc.total) ? (g->gc.total - a) : 0;
20,605✔
1316
    while (g->gc.total >= g->gc.threshold)
51,575✔
1317
      if (lj_gc_step(L) > 0) {
36,024✔
1318
        res = 1;
1319
        break;
1320
      }
1321
    break;
1322
  }
1323
  case LUA_GCSETPAUSE:
10,089✔
1324
    res = (int)(g->gc.pause);
10,089✔
1325
    g->gc.pause = (MSize)data;
10,089✔
1326
    break;
10,089✔
1327
  case LUA_GCSETSTEPMUL:
10,098✔
1328
    res = (int)(g->gc.stepmul);
10,098✔
1329
    g->gc.stepmul = (MSize)data;
10,098✔
1330
    break;
10,098✔
1331
  case LUA_GCISRUNNING:
×
1332
    res = (g->gc.threshold != LJ_MAX_MEM);
×
1333
    break;
×
1334
  default:
1335
    res = -1;  /* Invalid option. */
1336
  }
1337
  return res;
52,724✔
1338
}
1339

1340
LUA_API lua_Alloc lua_getallocf(lua_State *L, void **ud)
27✔
1341
{
1342
  global_State *g = G(L);
27✔
1343
  if (ud) *ud = g->allocd;
27✔
1344
  return g->allocf;
27✔
1345
}
1346

1347
LUA_API void lua_setallocf(lua_State *L, lua_Alloc f, void *ud)
54✔
1348
{
1349
  global_State *g = G(L);
54✔
1350
  g->allocd = ud;
54✔
1351
  g->allocf = f;
54✔
1352
}
54✔
1353

1354
LUA_API uint32_t lua_hash(const char *str, uint32_t len)
10,115,234✔
1355
{
1356
  uint32_t h = len, a, b;
10,115,234✔
1357
  if (len >= 4) {
10,115,234✔
1358
    a = lj_getu32(str);
7,700,089✔
1359
    h ^= lj_getu32(str+len-4);
7,700,089✔
1360
    b = lj_getu32(str+(len>>1)-2);
7,700,089✔
1361
    h ^= b; h -= lj_rol(b, 14);
7,700,089✔
1362
    b += lj_getu32(str+(len>>2)-1);
7,700,089✔
1363
  } else if (len > 0) {
2,415,145✔
1364
    a = *str;
2,415,145✔
1365
    h ^= *(str+len-1);
2,415,145✔
1366
    b = *(str+(len>>1));
2,415,145✔
1367
    h ^= b; h -= lj_rol(b, 14);
2,415,145✔
1368
  } else {
1369
    return 0;
1370
  }
1371
  a ^= h; a -= lj_rol(h, 11);
10,115,234✔
1372
  b ^= a; b -= lj_rol(a, 25);
10,115,234✔
1373
  h ^= b; h -= lj_rol(b, 16);
10,115,234✔
1374
  return h;
10,115,234✔
1375
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc