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

tarantool / luajit / 24031030227

06 Apr 2026 11:55AM UTC coverage: 93.024% (-0.04%) from 93.062%
24031030227

push

github

Buristan
cmake: fixup tests build for old CMake

This patch is a follow-up to the commit
1e5887d88 ("FFI: Avoid dangling
cts->L."). The `target_link_options()` feature is introduced in the
CMake 3.13. Unfortunately, we have distros in Tarantool's CI with an
older default CMake version.

This patch workarounds this by the passing the LINK_FLAGS directly.

5716 of 6056 branches covered (94.39%)

Branch coverage included in aggregate %.

21822 of 23547 relevant lines covered (92.67%)

3973282.71 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,268✔
35
{
36
  if (idx > 0) {
25,328,268✔
37
    TValue *o = L->base + (idx - 1);
9,581,026✔
38
    return o < L->top ? o : niltv(L);
9,581,026✔
39
  } else if (idx > LUA_REGISTRYINDEX) {
15,747,242✔
40
    lj_checkapi(idx != 0 && -idx <= L->top - L->base,
10,431,647✔
41
                "bad stack slot %d", idx);
42
    return L->top + idx;
10,431,647✔
43
  } else if (idx == LUA_GLOBALSINDEX) {
5,315,595✔
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,907✔
48
    return registry(L);
4,303,934✔
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,247✔
96
  global_State *g = G(L);
5,218,247✔
97
  /* Forbid Lua world re-entrancy while running the trace */
98
  if (tvref(g->jit_base)) {
5,218,247✔
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,246✔
104
  lj_vm_call(L, base, nres);
5,218,246✔
105
}
5,218,238✔
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,125✔
235
{
236
  cTValue *o = index2adr(L, idx);
7,343,125✔
237
  if (tvisnumber(o)) {
7,343,125✔
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,093✔
244
    return LUA_TNONE;
245
  } else {  /* Magic internal/external tag conversion. ORDER LJ_T */
246
    uint32_t t = ~itype(o);
7,343,061✔
247
#if LJ_64
248
    int tt = (int)((U64x(75a06,98042110) >> 4*t) & 15u);
7,343,061✔
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,061✔
253
    return tt;
7,343,061✔
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,908✔
671
{
672
  setintptrV(L->top, n);
4,508,908✔
673
  incr_top(L);
4,508,908✔
674
}
4,508,905✔
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,852✔
686
{
687
  if (str == NULL) {
4,444,852✔
688
    setnilV(L->top);
132✔
689
  } else {
690
    GCstr *s;
4,444,720✔
691
    lj_gc_check(L);
4,444,720✔
692
    s = lj_str_newz(L, str);
4,444,720✔
693
    setstrV(L, L->top, s);
4,444,720✔
694
  }
695
  incr_top(L);
4,444,852✔
696
}
4,444,852✔
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,261✔
747
{
748
  lj_gc_check(L);
1,092,261✔
749
  settabV(L, L->top, lj_tab_new_ah(L, narray, nrec));
1,092,261✔
750
  incr_top(L);
1,092,261✔
751
}
1,092,261✔
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,882✔
854
{
855
  cTValue *t = index2adr(L, idx);
4,309,882✔
856
  lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
4,309,882✔
857
  copyTV(L, L->top-1, lj_tab_get(L, tabV(t), L->top-1));
4,309,882✔
858
}
4,309,882✔
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,021✔
874
{
875
  cTValue *o = index2adr(L, idx);
22,021✔
876
  GCtab *mt = NULL;
22,021✔
877
  if (tvistab(o))
22,021✔
878
    mt = tabref(tabV(o)->metatable);
16✔
879
  else if (tvisudata(o))
22,005✔
880
    mt = tabref(udataV(o)->metatable);
1,946✔
881
  else
882
    mt = tabref(basemt_obj(G(L), o));
20,059✔
883
  if (mt == NULL)
22,021✔
884
    return 0;
885
  settabV(L, L->top, mt);
22,007✔
886
  incr_top(L);
22,007✔
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,405✔
1027
{
1028
  GCtab *t = tabV(index2adr(L, idx));
1,000,405✔
1029
  TValue *dst, *key;
1,000,405✔
1030
  lj_checkapi_slot(2);
1,000,405✔
1031
  key = L->top-2;
1,000,405✔
1032
  dst = lj_tab_set(L, t, key);
1,000,405✔
1033
  copyTV(L, dst, key+1);
1,000,404✔
1034
  lj_gc_anybarriert(L, t);
1,000,404✔
1035
  L->top = key;
1,000,404✔
1036
}
1,000,404✔
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,503✔
1137
{
1138
  TValue *o = L->top, *base = o - nargs;
5,209,503✔
1139
  L->top = o+1;
5,209,503✔
1140
  for (; o > base; o--) copyTV(L, o, o-1);
15,606,537✔
1141
  setnilV(o);
5,209,503✔
1142
  return o+1;
5,209,503✔
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,256✔
1149
{
1150
  lj_checkapi(L->status == LUA_OK || L->status == LUA_ERRERR,
5,208,256✔
1151
              "thread called in wrong state %d", L->status);
1152
  lj_checkapi_slot(nargs+1);
5,208,256✔
1153
  jit_secure_call(L, api_call_base(L, nargs), nresults+1);
10,416,512✔
1154
}
5,208,247✔
1155

1156
LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
1,244✔
1157
{
1158
  global_State *g = G(L);
1,244✔
1159
  uint8_t oldh = hook_save(g);
1,244✔
1160
  ptrdiff_t ef;
1,244✔
1161
  int status;
1,244✔
1162
  lj_checkapi(L->status == LUA_OK || L->status == LUA_ERRERR,
1,244✔
1163
              "thread called in wrong state %d", L->status);
1164
  lj_checkapi_slot(nargs+1);
1,244✔
1165
  if (errfunc == 0) {
1,244✔
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,244✔
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,244✔
1178
  status = lj_vm_pcall(L, api_call_base(L, nargs), nresults+1, ef);
2,488✔
1179
  if (status) hook_restore(g, oldh);
981✔
1180
  return status;
981✔
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,618✔
1355
{
1356
  uint32_t h = len, a, b;
10,115,618✔
1357
  if (len >= 4) {
10,115,618✔
1358
    a = lj_getu32(str);
7,700,439✔
1359
    h ^= lj_getu32(str+len-4);
7,700,439✔
1360
    b = lj_getu32(str+(len>>1)-2);
7,700,439✔
1361
    h ^= b; h -= lj_rol(b, 14);
7,700,439✔
1362
    b += lj_getu32(str+(len>>2)-1);
7,700,439✔
1363
  } else if (len > 0) {
2,415,179✔
1364
    a = *str;
2,415,179✔
1365
    h ^= *(str+len-1);
2,415,179✔
1366
    b = *(str+(len>>1));
2,415,179✔
1367
    h ^= b; h -= lj_rol(b, 14);
2,415,179✔
1368
  } else {
1369
    return 0;
1370
  }
1371
  a ^= h; a -= lj_rol(h, 11);
10,115,618✔
1372
  b ^= a; b -= lj_rol(a, 25);
10,115,618✔
1373
  h ^= b; h -= lj_rol(b, 16);
10,115,618✔
1374
  return h;
10,115,618✔
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