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

tarantool / luajit / 5784751762

07 Aug 2023 11:54AM UTC coverage: 84.282% (-3.1%) from 87.373%
5784751762

push

github

ligurio
setup-gcovr [TO SQUASH]

5157 of 6002 branches covered (85.92%)

Branch coverage included in aggregate %.

19632 of 23410 relevant lines covered (83.86%)

229380.51 hits per line

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

71.31
/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 api_checknelems(L, n)                api_check(L, (n) <= (L->top - L->base))
32
#define api_checkvalidindex(L, i)        api_check(L, (i) != niltv(L))
33

34
static TValue *index2adr(lua_State *L, int idx)
5,765,558✔
35
{
36
  if (idx > 0) {
5,765,558✔
37
    TValue *o = L->base + (idx - 1);
3,440,525✔
38
    return o < L->top ? o : niltv(L);
3,440,525✔
39
  } else if (idx > LUA_REGISTRYINDEX) {
2,325,033✔
40
    api_check(L, idx != 0 && -idx <= L->top - L->base);
1,313,553✔
41
    return L->top + idx;
1,313,553✔
42
  } else if (idx == LUA_GLOBALSINDEX) {
1,011,480✔
43
    TValue *o = &G(L)->tmptv;
4,036✔
44
    settabV(L, o, tabref(L->env));
4,036✔
45
    return o;
4,036✔
46
  } else if (idx == LUA_REGISTRYINDEX) {
1,007,444✔
47
    return registry(L);
6,158✔
48
  } else {
49
    GCfunc *fn = curr_func(L);
1,001,286✔
50
    api_check(L, fn->c.gct == ~LJ_TFUNC && !isluafunc(fn));
1,001,286✔
51
    if (idx == LUA_ENVIRONINDEX) {
1,001,286✔
52
      TValue *o = &G(L)->tmptv;
1,279✔
53
      settabV(L, o, tabref(fn->c.env));
1,279✔
54
      return o;
1,279✔
55
    } else {
56
      idx = LUA_GLOBALSINDEX - idx;
1,000,007✔
57
      return idx <= fn->c.nupvalues ? &fn->c.upvalue[idx-1] : niltv(L);
1,000,007✔
58
    }
59
  }
60
}
61

62
static TValue *stkindex2adr(lua_State *L, int idx)
13,742✔
63
{
64
  if (idx > 0) {
13,742✔
65
    TValue *o = L->base + (idx - 1);
1,191✔
66
    return o < L->top ? o : niltv(L);
1,191✔
67
  } else {
68
    api_check(L, idx != 0 && -idx <= L->top - L->base);
12,551✔
69
    return L->top + idx;
12,551✔
70
  }
71
}
72

73
static GCtab *getcurrenv(lua_State *L)
1,009,785✔
74
{
75
  GCfunc *fn = curr_func(L);
1,009,785✔
76
  return fn->c.gct == ~LJ_TFUNC ? tabref(fn->c.env) : tabref(L->env);
1,009,785✔
77
}
78

79
static void jit_secure_call(lua_State *L, TValue *base, int nres) {
14,845✔
80
  global_State *g = G(L);
14,845✔
81
  /* Forbid Lua world re-entrancy while running the trace */
82
  if (tvref(g->jit_base)) {
14,845✔
83
    setstrV(L, L->top++, lj_err_str(L, LJ_ERR_JITCALL));
1✔
84
    if (g->panic) g->panic(L);
1✔
85
    exit(EXIT_FAILURE);
1✔
86
  }
87
  lj_trace_abort(g);  /* Never record across Lua VM entrance */
14,844✔
88
  lj_vm_call(L, base, nres);
14,844✔
89
}
14,841✔
90

91
/* -- Miscellaneous API functions ----------------------------------------- */
92

93
LUA_API int lua_status(lua_State *L)
×
94
{
95
  return L->status;
×
96
}
97

98
LUA_API int lua_checkstack(lua_State *L, int size)
2,315✔
99
{
100
  if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) {
2,315✔
101
    return 0;  /* Stack overflow. */
102
  } else if (size > 0) {
2,315✔
103
    lj_state_checkstack(L, (MSize)size);
1,731✔
104
  }
105
  return 1;
106
}
107

108
LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
2,291✔
109
{
110
  if (!lua_checkstack(L, size))
2,291✔
111
    lj_err_callerv(L, LJ_ERR_STKOVM, msg);
×
112
}
2,291✔
113

114
LUA_API void lua_xmove(lua_State *from, lua_State *to, int n)
3✔
115
{
116
  TValue *f, *t;
3✔
117
  if (from == to) return;
3✔
118
  api_checknelems(from, n);
×
119
  api_check(from, G(from) == G(to));
×
120
  lj_state_checkstack(to, (MSize)n);
×
121
  f = from->top;
×
122
  t = to->top = to->top + n;
×
123
  while (--n >= 0) copyTV(to, --t, --f);
×
124
  from->top = f;
×
125
}
126

127
LUA_API const lua_Number *lua_version(lua_State *L)
×
128
{
129
  static const lua_Number version = LUA_VERSION_NUM;
×
130
  UNUSED(L);
×
131
  return &version;
×
132
}
133

134
/* -- Stack manipulation -------------------------------------------------- */
135

136
LUA_API int lua_gettop(lua_State *L)
468✔
137
{
138
  return (int)(L->top - L->base);
468✔
139
}
140

141
LUA_API void lua_settop(lua_State *L, int idx)
1,101,379✔
142
{
143
  if (idx >= 0) {
1,101,379✔
144
    api_check(L, idx <= tvref(L->maxstack) - L->base);
1,022,300✔
145
    if (L->base + idx > L->top) {
1,022,300✔
146
      if (L->base + idx >= tvref(L->maxstack))
21,546✔
147
        lj_state_growstack(L, (MSize)idx - (MSize)(L->top - L->base));
×
148
      do { setnilV(L->top++); } while (L->top < L->base + idx);
48,766✔
149
    } else {
150
      L->top = L->base + idx;
1,000,754✔
151
    }
152
  } else {
153
    api_check(L, -(idx+1) <= (L->top - L->base));
79,079✔
154
    L->top += idx+1;  /* Shrinks top (idx < 0). */
79,079✔
155
  }
156
}
1,101,379✔
157

158
LUA_API void lua_remove(lua_State *L, int idx)
12,566✔
159
{
160
  TValue *p = stkindex2adr(L, idx);
12,566✔
161
  api_checkvalidindex(L, p);
162
  while (++p < L->top) copyTV(L, p-1, p);
24,738✔
163
  L->top--;
12,566✔
164
}
12,566✔
165

166
LUA_API void lua_insert(lua_State *L, int idx)
759✔
167
{
168
  TValue *q, *p = stkindex2adr(L, idx);
759✔
169
  api_checkvalidindex(L, p);
759✔
170
  for (q = L->top; q > p; q--) copyTV(L, q, q-1);
2,170✔
171
  copyTV(L, p, L->top);
759✔
172
}
759✔
173

174
static void copy_slot(lua_State *L, TValue *f, int idx)
215✔
175
{
176
  if (idx == LUA_GLOBALSINDEX) {
215✔
177
    api_check(L, tvistab(f));
×
178
    /* NOBARRIER: A thread (i.e. L) is never black. */
179
    setgcref(L->env, obj2gco(tabV(f)));
×
180
  } else if (idx == LUA_ENVIRONINDEX) {
215✔
181
    GCfunc *fn = curr_func(L);
215✔
182
    if (fn->c.gct != ~LJ_TFUNC)
215✔
183
      lj_err_msg(L, LJ_ERR_NOENV);
×
184
    api_check(L, tvistab(f));
215✔
185
    setgcref(fn->c.env, obj2gco(tabV(f)));
215✔
186
    lj_gc_barrier(L, fn, f);
215✔
187
  } else {
188
    TValue *o = index2adr(L, idx);
×
189
    api_checkvalidindex(L, o);
×
190
    copyTV(L, o, f);
×
191
    if (idx < LUA_GLOBALSINDEX)  /* Need a barrier for upvalues. */
×
192
      lj_gc_barrier(L, curr_func(L), f);
×
193
  }
194
}
215✔
195

196
LUA_API void lua_replace(lua_State *L, int idx)
×
197
{
198
  api_checknelems(L, 1);
×
199
  copy_slot(L, L->top - 1, idx);
×
200
  L->top--;
×
201
}
×
202

203
LUA_API void lua_copy(lua_State *L, int fromidx, int toidx)
215✔
204
{
205
  copy_slot(L, index2adr(L, fromidx), toidx);
215✔
206
}
215✔
207

208
LUA_API void lua_pushvalue(lua_State *L, int idx)
1,023,549✔
209
{
210
  copyTV(L, L->top, index2adr(L, idx));
1,023,549✔
211
  incr_top(L);
1,023,549✔
212
}
1,023,549✔
213

214
/* -- Stack getters ------------------------------------------------------- */
215

216
LUA_API int lua_type(lua_State *L, int idx)
1,141,976✔
217
{
218
  cTValue *o = index2adr(L, idx);
1,141,976✔
219
  if (tvisnumber(o)) {
1,141,976✔
220
    return LUA_TNUMBER;
221
#if LJ_64 && !LJ_GC64
222
  } else if (tvislightud(o)) {
223
    return LUA_TLIGHTUSERDATA;
224
#endif
225
  } else if (o == niltv(L)) {
1,141,965✔
226
    return LUA_TNONE;
227
  } else {  /* Magic internal/external tag conversion. ORDER LJ_T */
228
    uint32_t t = ~itype(o);
1,141,957✔
229
#if LJ_64
230
    int tt = (int)((U64x(75a06,98042110) >> 4*t) & 15u);
1,141,957✔
231
#else
232
    int tt = (int)(((t < 8 ? 0x98042110u : 0x75a06u) >> 4*(t&7)) & 15u);
233
#endif
234
    lua_assert(tt != LUA_TNIL || tvisnil(o));
1,141,957✔
235
    return tt;
1,141,957✔
236
  }
237
}
238

239
LUALIB_API void luaL_checktype(lua_State *L, int idx, int tt)
8✔
240
{
241
  if (lua_type(L, idx) != tt)
8✔
242
    lj_err_argt(L, idx, tt);
×
243
}
8✔
244

245
LUALIB_API void luaL_checkany(lua_State *L, int idx)
×
246
{
247
  if (index2adr(L, idx) == niltv(L))
×
248
    lj_err_arg(L, idx, LJ_ERR_NOVAL);
×
249
}
×
250

251
LUA_API const char *lua_typename(lua_State *L, int t)
1✔
252
{
253
  UNUSED(L);
1✔
254
  return lj_obj_typename[t+1];
1✔
255
}
256

257
LUA_API int lua_iscfunction(lua_State *L, int idx)
2✔
258
{
259
  cTValue *o = index2adr(L, idx);
2✔
260
  return tvisfunc(o) && !isluafunc(funcV(o));
2✔
261
}
262

263
LUA_API int lua_isnumber(lua_State *L, int idx)
75✔
264
{
265
  cTValue *o = index2adr(L, idx);
75✔
266
  TValue tmp;
75✔
267
  return (tvisnumber(o) || (tvisstr(o) && lj_strscan_number(strV(o), &tmp)));
75✔
268
}
269

270
LUA_API int lua_isstring(lua_State *L, int idx)
1,107✔
271
{
272
  cTValue *o = index2adr(L, idx);
1,107✔
273
  return (tvisstr(o) || tvisnumber(o));
1,107✔
274
}
275

276
LUA_API int lua_isuserdata(lua_State *L, int idx)
×
277
{
278
  cTValue *o = index2adr(L, idx);
×
279
  return (tvisudata(o) || tvislightud(o));
×
280
}
281

282
LUA_API int lua_rawequal(lua_State *L, int idx1, int idx2)
×
283
{
284
  cTValue *o1 = index2adr(L, idx1);
×
285
  cTValue *o2 = index2adr(L, idx2);
×
286
  return (o1 == niltv(L) || o2 == niltv(L)) ? 0 : lj_obj_equal(o1, o2);
×
287
}
288

289
LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
×
290
{
291
  cTValue *o1 = index2adr(L, idx1);
×
292
  cTValue *o2 = index2adr(L, idx2);
×
293
  if (tvisint(o1) && tvisint(o2)) {
×
294
    return intV(o1) == intV(o2);
295
  } else if (tvisnumber(o1) && tvisnumber(o2)) {
×
296
    return numberVnum(o1) == numberVnum(o2);
×
297
  } else if (itype(o1) != itype(o2)) {
×
298
    return 0;
299
  } else if (tvispri(o1)) {
×
300
    return o1 != niltv(L) && o2 != niltv(L);
×
301
#if LJ_64 && !LJ_GC64
302
  } else if (tvislightud(o1)) {
303
    return o1->u64 == o2->u64;
304
#endif
305
  } else if (gcrefeq(o1->gcr, o2->gcr)) {
×
306
    return 1;
307
  } else if (!tvistabud(o1)) {
×
308
    return 0;
309
  } else {
310
    TValue *base = lj_meta_equal(L, gcV(o1), gcV(o2), 0);
×
311
    if ((uintptr_t)base <= 1) {
×
312
      return (int)(uintptr_t)base;
×
313
    } else {
314
      L->top = base+2;
×
315
      jit_secure_call(L, base, 1+1);
×
316
      L->top -= 2+LJ_FR2;
×
317
      return tvistruecond(L->top+1+LJ_FR2);
×
318
    }
319
  }
320
}
321

322
LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2)
122,004✔
323
{
324
  cTValue *o1 = index2adr(L, idx1);
122,004✔
325
  cTValue *o2 = index2adr(L, idx2);
122,004✔
326
  if (o1 == niltv(L) || o2 == niltv(L)) {
122,004✔
327
    return 0;
328
  } else if (tvisint(o1) && tvisint(o2)) {
122,004✔
329
    return intV(o1) < intV(o2);
330
  } else if (tvisnumber(o1) && tvisnumber(o2)) {
122,004✔
331
    return numberVnum(o1) < numberVnum(o2);
9,959✔
332
  } else {
333
    TValue *base = lj_meta_comp(L, o1, o2, 0);
112,045✔
334
    if ((uintptr_t)base <= 1) {
112,045✔
335
      return (int)(uintptr_t)base;
102,086✔
336
    } else {
337
      L->top = base+2;
9,959✔
338
      jit_secure_call(L, base, 1+1);
9,959✔
339
      L->top -= 2+LJ_FR2;
9,959✔
340
      return tvistruecond(L->top+1+LJ_FR2);
9,959✔
341
    }
342
  }
343
}
344

345
LUA_API lua_Number lua_tonumber(lua_State *L, int idx)
267✔
346
{
347
  cTValue *o = index2adr(L, idx);
267✔
348
  TValue tmp;
267✔
349
  if (LJ_LIKELY(tvisnumber(o)))
267✔
350
    return numberVnum(o);
263✔
351
  else if (tvisstr(o) && lj_strscan_num(strV(o), &tmp))
4✔
352
    return numV(&tmp);
4✔
353
  else
354
    return 0;
×
355
}
356

357
LUA_API lua_Number lua_tonumberx(lua_State *L, int idx, int *ok)
×
358
{
359
  cTValue *o = index2adr(L, idx);
×
360
  TValue tmp;
×
361
  if (LJ_LIKELY(tvisnumber(o))) {
×
362
    if (ok) *ok = 1;
×
363
    return numberVnum(o);
×
364
  } else if (tvisstr(o) && lj_strscan_num(strV(o), &tmp)) {
×
365
    if (ok) *ok = 1;
×
366
    return numV(&tmp);
×
367
  } else {
368
    if (ok) *ok = 0;
×
369
    return 0;
×
370
  }
371
}
372

373
LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx)
5✔
374
{
375
  cTValue *o = index2adr(L, idx);
5✔
376
  TValue tmp;
5✔
377
  if (LJ_LIKELY(tvisnumber(o)))
5✔
378
    return numberVnum(o);
5✔
379
  else if (!(tvisstr(o) && lj_strscan_num(strV(o), &tmp)))
×
380
    lj_err_argt(L, idx, LUA_TNUMBER);
×
381
  return numV(&tmp);
×
382
}
383

384
LUALIB_API lua_Number luaL_optnumber(lua_State *L, int idx, lua_Number def)
1✔
385
{
386
  cTValue *o = index2adr(L, idx);
1✔
387
  TValue tmp;
1✔
388
  if (LJ_LIKELY(tvisnumber(o)))
1✔
389
    return numberVnum(o);
1✔
390
  else if (tvisnil(o))
×
391
    return def;
392
  else if (!(tvisstr(o) && lj_strscan_num(strV(o), &tmp)))
×
393
    lj_err_argt(L, idx, LUA_TNUMBER);
×
394
  return numV(&tmp);
×
395
}
396

397
LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
55✔
398
{
399
  cTValue *o = index2adr(L, idx);
55✔
400
  TValue tmp;
55✔
401
  lua_Number n;
55✔
402
  if (LJ_LIKELY(tvisint(o))) {
55✔
403
    return intV(o);
404
  } else if (LJ_LIKELY(tvisnum(o))) {
55✔
405
    n = numV(o);
53✔
406
  } else {
407
    if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
2✔
408
      return 0;
2✔
409
    if (tvisint(&tmp))
×
410
      return intV(&tmp);
411
    n = numV(&tmp);
×
412
  }
413
#if LJ_64
414
  return (lua_Integer)n;
53✔
415
#else
416
  return lj_num2int(n);
417
#endif
418
}
419

420
LUA_API lua_Integer lua_tointegerx(lua_State *L, int idx, int *ok)
×
421
{
422
  cTValue *o = index2adr(L, idx);
×
423
  TValue tmp;
×
424
  lua_Number n;
×
425
  if (LJ_LIKELY(tvisint(o))) {
×
426
    if (ok) *ok = 1;
427
    return intV(o);
428
  } else if (LJ_LIKELY(tvisnum(o))) {
×
429
    n = numV(o);
×
430
  } else {
431
    if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp))) {
×
432
      if (ok) *ok = 0;
×
433
      return 0;
×
434
    }
435
    if (tvisint(&tmp)) {
×
436
      if (ok) *ok = 1;
437
      return intV(&tmp);
438
    }
439
    n = numV(&tmp);
×
440
  }
441
  if (ok) *ok = 1;
×
442
#if LJ_64
443
  return (lua_Integer)n;
×
444
#else
445
  return lj_num2int(n);
446
#endif
447
}
448

449
LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx)
×
450
{
451
  cTValue *o = index2adr(L, idx);
×
452
  TValue tmp;
×
453
  lua_Number n;
×
454
  if (LJ_LIKELY(tvisint(o))) {
×
455
    return intV(o);
456
  } else if (LJ_LIKELY(tvisnum(o))) {
×
457
    n = numV(o);
×
458
  } else {
459
    if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
×
460
      lj_err_argt(L, idx, LUA_TNUMBER);
×
461
    if (tvisint(&tmp))
×
462
      return (lua_Integer)intV(&tmp);
463
    n = numV(&tmp);
×
464
  }
465
#if LJ_64
466
  return (lua_Integer)n;
×
467
#else
468
  return lj_num2int(n);
469
#endif
470
}
471

472
LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int idx, lua_Integer def)
665✔
473
{
474
  cTValue *o = index2adr(L, idx);
665✔
475
  TValue tmp;
665✔
476
  lua_Number n;
665✔
477
  if (LJ_LIKELY(tvisint(o))) {
665✔
478
    return intV(o);
479
  } else if (LJ_LIKELY(tvisnum(o))) {
665✔
480
    n = numV(o);
4✔
481
  } else if (tvisnil(o)) {
661✔
482
    return def;
483
  } else {
484
    if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
×
485
      lj_err_argt(L, idx, LUA_TNUMBER);
×
486
    if (tvisint(&tmp))
×
487
      return (lua_Integer)intV(&tmp);
488
    n = numV(&tmp);
×
489
  }
490
#if LJ_64
491
  return (lua_Integer)n;
4✔
492
#else
493
  return lj_num2int(n);
494
#endif
495
}
496

497
LUA_API int lua_toboolean(lua_State *L, int idx)
1,003,479✔
498
{
499
  cTValue *o = index2adr(L, idx);
1,003,479✔
500
  return tvistruecond(o);
1,003,479✔
501
}
502

503
LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len)
7,604✔
504
{
505
  TValue *o = index2adr(L, idx);
7,604✔
506
  GCstr *s;
7,604✔
507
  if (LJ_LIKELY(tvisstr(o))) {
7,604✔
508
    s = strV(o);
7,590✔
509
  } else if (tvisnumber(o)) {
14✔
510
    lj_gc_check(L);
×
511
    o = index2adr(L, idx);  /* GC may move the stack. */
×
512
    s = lj_strfmt_number(L, o);
×
513
    setstrV(L, o, s);
×
514
  } else {
515
    if (len != NULL) *len = 0;
14✔
516
    return NULL;
14✔
517
  }
518
  if (len != NULL) *len = s->len;
7,590✔
519
  return strdata(s);
7,590✔
520
}
521

522
LUA_API uint32_t lua_hashstring(lua_State *L, int idx)
×
523
{
524
  TValue *o = index2adr(L, idx);
×
525
  lua_assert(tvisstr(o));
×
526
  GCstr *s = strV(o);
×
527
  if (! strsmart(s))
×
528
    return s->hash;
×
529
  return lua_hash(strdata(s), s->len);
×
530
}
531

532
LUALIB_API const char *luaL_checklstring(lua_State *L, int idx, size_t *len)
2,924✔
533
{
534
  TValue *o = index2adr(L, idx);
2,924✔
535
  GCstr *s;
2,924✔
536
  if (LJ_LIKELY(tvisstr(o))) {
2,924✔
537
    s = strV(o);
2,924✔
538
  } else if (tvisnumber(o)) {
×
539
    lj_gc_check(L);
×
540
    o = index2adr(L, idx);  /* GC may move the stack. */
×
541
    s = lj_strfmt_number(L, o);
×
542
    setstrV(L, o, s);
×
543
  } else {
544
    lj_err_argt(L, idx, LUA_TSTRING);
×
545
  }
546
  if (len != NULL) *len = s->len;
2,924✔
547
  return strdata(s);
2,924✔
548
}
549

550
LUALIB_API const char *luaL_optlstring(lua_State *L, int idx,
73✔
551
                                       const char *def, size_t *len)
552
{
553
  TValue *o = index2adr(L, idx);
73✔
554
  GCstr *s;
73✔
555
  if (LJ_LIKELY(tvisstr(o))) {
73✔
556
    s = strV(o);
26✔
557
  } else if (tvisnil(o)) {
47✔
558
    if (len != NULL) *len = def ? strlen(def) : 0;
47✔
559
    return def;
47✔
560
  } else if (tvisnumber(o)) {
×
561
    lj_gc_check(L);
×
562
    o = index2adr(L, idx);  /* GC may move the stack. */
×
563
    s = lj_strfmt_number(L, o);
×
564
    setstrV(L, o, s);
×
565
  } else {
566
    lj_err_argt(L, idx, LUA_TSTRING);
×
567
  }
568
  if (len != NULL) *len = s->len;
26✔
569
  return strdata(s);
26✔
570
}
571

572
LUALIB_API int luaL_checkoption(lua_State *L, int idx, const char *def,
×
573
                                const char *const lst[])
574
{
575
  ptrdiff_t i;
×
576
  const char *s = lua_tolstring(L, idx, NULL);
×
577
  if (s == NULL && (s = def) == NULL)
×
578
    lj_err_argt(L, idx, LUA_TSTRING);
×
579
  for (i = 0; lst[i]; i++)
×
580
    if (strcmp(lst[i], s) == 0)
×
581
      return (int)i;
×
582
  lj_err_argv(L, idx, LJ_ERR_INVOPTM, s);
×
583
}
584

585
LUA_API size_t lua_objlen(lua_State *L, int idx)
130✔
586
{
587
  TValue *o = index2adr(L, idx);
130✔
588
  if (tvisstr(o)) {
130✔
589
    return strV(o)->len;
128✔
590
  } else if (tvistab(o)) {
2✔
591
    return (size_t)lj_tab_len(tabV(o));
2✔
592
  } else if (tvisudata(o)) {
×
593
    return udataV(o)->len;
×
594
  } else if (tvisnumber(o)) {
×
595
    GCstr *s = lj_strfmt_number(L, o);
×
596
    setstrV(L, o, s);
×
597
    return s->len;
×
598
  } else {
599
    return 0;
600
  }
601
}
602

603
LUA_API lua_CFunction lua_tocfunction(lua_State *L, int idx)
×
604
{
605
  cTValue *o = index2adr(L, idx);
×
606
  if (tvisfunc(o)) {
×
607
    BCOp op = bc_op(*mref(funcV(o)->c.pc, BCIns));
×
608
    if (op == BC_FUNCC || op == BC_FUNCCW)
×
609
      return funcV(o)->c.f;
×
610
  }
611
  return NULL;
612
}
613

614
LUA_API void *lua_touserdata(lua_State *L, int idx)
1✔
615
{
616
  cTValue *o = index2adr(L, idx);
1✔
617
  if (tvisudata(o))
1✔
618
    return uddata(udataV(o));
1✔
619
  else if (tvislightud(o))
×
620
    return lightudV(G(L), o);
×
621
  else
622
    return NULL;
623
}
624

625
LUA_API lua_State *lua_tothread(lua_State *L, int idx)
×
626
{
627
  cTValue *o = index2adr(L, idx);
×
628
  return (!tvisthread(o)) ? NULL : threadV(o);
×
629
}
630

631
LUA_API const void *lua_topointer(lua_State *L, int idx)
256✔
632
{
633
  return lj_obj_ptr(G(L), index2adr(L, idx));
256✔
634
}
635

636
/* -- Stack setters (object creation) ------------------------------------- */
637

638
LUA_API void lua_pushnil(lua_State *L)
252✔
639
{
640
  setnilV(L->top);
252✔
641
  incr_top(L);
252✔
642
}
252✔
643

644
LUA_API void lua_pushnumber(lua_State *L, lua_Number n)
268✔
645
{
646
  setnumV(L->top, n);
268✔
647
  if (LJ_UNLIKELY(tvisnan(L->top)))
268✔
648
    setnanV(L->top);  /* Canonicalize injected NaNs. */
×
649
  incr_top(L);
268✔
650
}
268✔
651

652
LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
1,602✔
653
{
654
  setintptrV(L->top, n);
1,602✔
655
  incr_top(L);
1,602✔
656
}
1,602✔
657

658
LUA_API void lua_pushlstring(lua_State *L, const char *str, size_t len)
20,838✔
659
{
660
  GCstr *s;
20,838✔
661
  lj_gc_check(L);
20,838✔
662
  s = lj_str_new(L, str, len);
20,838✔
663
  setstrV(L, L->top, s);
20,838✔
664
  incr_top(L);
20,838✔
665
}
20,838✔
666

667
LUA_API void lua_pushstring(lua_State *L, const char *str)
5,773✔
668
{
669
  if (str == NULL) {
5,773✔
670
    setnilV(L->top);
21✔
671
  } else {
672
    GCstr *s;
5,752✔
673
    lj_gc_check(L);
5,752✔
674
    s = lj_str_newz(L, str);
5,752✔
675
    setstrV(L, L->top, s);
5,752✔
676
  }
677
  incr_top(L);
5,773✔
678
}
5,773✔
679

680
LUA_API const char *lua_pushvfstring(lua_State *L, const char *fmt,
×
681
                                     va_list argp)
682
{
683
  lj_gc_check(L);
×
684
  return lj_strfmt_pushvf(L, fmt, argp);
×
685
}
686

687
LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...)
2,459✔
688
{
689
  const char *ret;
2,459✔
690
  va_list argp;
2,459✔
691
  lj_gc_check(L);
2,459✔
692
  va_start(argp, fmt);
2,459✔
693
  ret = lj_strfmt_pushvf(L, fmt, argp);
2,459✔
694
  va_end(argp);
2,459✔
695
  return ret;
2,459✔
696
}
697

698
LUA_API void lua_pushcclosure(lua_State *L, lua_CFunction f, int n)
6,417✔
699
{
700
  GCfunc *fn;
6,417✔
701
  lj_gc_check(L);
6,417✔
702
  api_checknelems(L, n);
6,417✔
703
  fn = lj_func_newC(L, (MSize)n, getcurrenv(L));
12,834✔
704
  fn->c.f = f;
6,417✔
705
  L->top -= n;
6,417✔
706
  while (n--)
6,417✔
707
    copyTV(L, &fn->c.upvalue[n], L->top+n);
6,671✔
708
  setfuncV(L, L->top, fn);
6,417✔
709
  lua_assert(iswhite(obj2gco(fn)));
6,417✔
710
  incr_top(L);
6,417✔
711
}
6,417✔
712

713
LUA_API void lua_pushboolean(lua_State *L, int b)
1,000,168✔
714
{
715
  setboolV(L->top, (b != 0));
1,000,168✔
716
  incr_top(L);
1,000,168✔
717
}
1,000,168✔
718

719
LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
260✔
720
{
721
#if LJ_64
722
  p = lj_lightud_intern(L, p);
260✔
723
#endif
724
  setrawlightudV(L->top, p);
258✔
725
  incr_top(L);
258✔
726
}
258✔
727

728
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
1,004,737✔
729
{
730
  lj_gc_check(L);
1,004,737✔
731
  settabV(L, L->top, lj_tab_new_ah(L, narray, nrec));
1,004,737✔
732
  incr_top(L);
1,004,737✔
733
}
1,004,737✔
734

735
LUALIB_API int luaL_newmetatable(lua_State *L, const char *tname)
217✔
736
{
737
  GCtab *regt = tabV(registry(L));
217✔
738
  TValue *tv = lj_tab_setstr(L, regt, lj_str_newz(L, tname));
217✔
739
  if (tvisnil(tv)) {
217✔
740
    GCtab *mt = lj_tab_new(L, 0, 1);
217✔
741
    settabV(L, tv, mt);
217✔
742
    settabV(L, L->top++, mt);
217✔
743
    lj_gc_anybarriert(L, regt);
217✔
744
    return 1;
217✔
745
  } else {
746
    copyTV(L, L->top++, tv);
×
747
    return 0;
×
748
  }
749
}
750

751
LUA_API int lua_pushthread(lua_State *L)
1✔
752
{
753
  setthreadV(L, L->top, L);
1✔
754
  incr_top(L);
1✔
755
  return (mainthread(G(L)) == L);
1✔
756
}
757

758
LUA_API lua_State *lua_newthread(lua_State *L)
52✔
759
{
760
  lua_State *L1;
52✔
761
  lj_gc_check(L);
52✔
762
  L1 = lj_state_new(L);
52✔
763
  setthreadV(L, L->top, L1);
52✔
764
  incr_top(L);
52✔
765
  return L1;
52✔
766
}
767

768
LUA_API void *lua_newuserdata(lua_State *L, size_t size)
1,003,151✔
769
{
770
  GCudata *ud;
1,003,151✔
771
  lj_gc_check(L);
1,003,151✔
772
  if (size > LJ_MAX_UDATA)
1,003,151✔
773
    lj_err_msg(L, LJ_ERR_UDATAOV);
×
774
  ud = lj_udata_new(L, (MSize)size, getcurrenv(L));
2,006,302✔
775
  setudataV(L, L->top, ud);
1,003,151✔
776
  incr_top(L);
1,003,151✔
777
  return uddata(ud);
1,003,151✔
778
}
779

780
LUA_API void lua_concat(lua_State *L, int n)
4,177✔
781
{
782
  api_checknelems(L, n);
4,177✔
783
  if (n >= 2) {
4,177✔
784
    n--;
621✔
785
    do {
621✔
786
      TValue *top = lj_meta_cat(L, L->top-1, -n);
621✔
787
      if (top == NULL) {
621✔
788
        L->top -= n;
621✔
789
        break;
621✔
790
      }
791
      n -= (int)(L->top - top);
×
792
      L->top = top+2;
×
793
      jit_secure_call(L, top, 1+1);
×
794
      L->top -= 1+LJ_FR2;
×
795
      copyTV(L, L->top-1, L->top+LJ_FR2);
×
796
    } while (--n > 0);
×
797
  } else if (n == 0) {  /* Push empty string. */
3,556✔
798
    setstrV(L, L->top, &G(L)->strempty);
×
799
    incr_top(L);
×
800
  }
801
  /* else n == 1: nothing to do. */
802
}
4,177✔
803

804
/* -- Object getters ------------------------------------------------------ */
805

806
LUA_API void lua_gettable(lua_State *L, int idx)
78✔
807
{
808
  cTValue *v, *t = index2adr(L, idx);
78✔
809
  api_checkvalidindex(L, t);
78✔
810
  v = lj_meta_tget(L, t, L->top-1);
78✔
811
  if (v == NULL) {
78✔
812
    L->top += 2;
×
813
    jit_secure_call(L, L->top-2, 1+1);
×
814
    L->top -= 2+LJ_FR2;
×
815
    v = L->top+1+LJ_FR2;
×
816
  }
817
  copyTV(L, L->top-1, v);
78✔
818
}
78✔
819

820
LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
7,321✔
821
{
822
  cTValue *v, *t = index2adr(L, idx);
7,321✔
823
  TValue key;
7,321✔
824
  api_checkvalidindex(L, t);
7,321✔
825
  setstrV(L, &key, lj_str_newz(L, k));
7,321✔
826
  v = lj_meta_tget(L, t, &key);
7,321✔
827
  if (v == NULL) {
7,321✔
828
    L->top += 2;
×
829
    jit_secure_call(L, L->top-2, 1+1);
×
830
    L->top -= 2+LJ_FR2;
×
831
    v = L->top+1+LJ_FR2;
×
832
  }
833
  copyTV(L, L->top, v);
7,321✔
834
  incr_top(L);
7,321✔
835
}
7,321✔
836

837
LUA_API void lua_rawget(lua_State *L, int idx)
8,878✔
838
{
839
  cTValue *t = index2adr(L, idx);
8,878✔
840
  api_check(L, tvistab(t));
8,878✔
841
  copyTV(L, L->top-1, lj_tab_get(L, tabV(t), L->top-1));
8,878✔
842
}
8,878✔
843

844
LUA_API void lua_rawgeti(lua_State *L, int idx, int n)
204,493✔
845
{
846
  cTValue *v, *t = index2adr(L, idx);
204,493✔
847
  api_check(L, tvistab(t));
204,493✔
848
  v = lj_tab_getint(tabV(t), n);
204,493✔
849
  if (v) {
204,493✔
850
    copyTV(L, L->top, v);
204,439✔
851
  } else {
852
    setnilV(L->top);
54✔
853
  }
854
  incr_top(L);
204,493✔
855
}
204,493✔
856

857
LUA_API int lua_getmetatable(lua_State *L, int idx)
16✔
858
{
859
  cTValue *o = index2adr(L, idx);
16✔
860
  GCtab *mt = NULL;
16✔
861
  if (tvistab(o))
16✔
862
    mt = tabref(tabV(o)->metatable);
8✔
863
  else if (tvisudata(o))
8✔
864
    mt = tabref(udataV(o)->metatable);
3✔
865
  else
866
    mt = tabref(basemt_obj(G(L), o));
5✔
867
  if (mt == NULL)
16✔
868
    return 0;
869
  settabV(L, L->top, mt);
9✔
870
  incr_top(L);
9✔
871
  return 1;
872
}
873

874
LUALIB_API int luaL_getmetafield(lua_State *L, int idx, const char *field)
1✔
875
{
876
  if (lua_getmetatable(L, idx)) {
1✔
877
    cTValue *tv = lj_tab_getstr(tabV(L->top-1), lj_str_newz(L, field));
×
878
    if (tv && !tvisnil(tv)) {
×
879
      copyTV(L, L->top-1, tv);
×
880
      return 1;
×
881
    }
882
    L->top--;
×
883
  }
884
  return 0;
885
}
886

887
LUA_API void lua_getfenv(lua_State *L, int idx)
13✔
888
{
889
  cTValue *o = index2adr(L, idx);
13✔
890
  api_checkvalidindex(L, o);
13✔
891
  if (tvisfunc(o)) {
13✔
892
    settabV(L, L->top, tabref(funcV(o)->c.env));
8✔
893
  } else if (tvisudata(o)) {
5✔
894
    settabV(L, L->top, tabref(udataV(o)->env));
×
895
  } else if (tvisthread(o)) {
5✔
896
    settabV(L, L->top, tabref(threadV(o)->env));
4✔
897
  } else {
898
    setnilV(L->top);
1✔
899
  }
900
  incr_top(L);
13✔
901
}
13✔
902

903
LUA_API int lua_next(lua_State *L, int idx)
18✔
904
{
905
  cTValue *t = index2adr(L, idx);
18✔
906
  int more;
18✔
907
  api_check(L, tvistab(t));
18✔
908
  more = lj_tab_next(L, tabV(t), L->top-1);
18✔
909
  if (more) {
18✔
910
    incr_top(L);  /* Return new key and value slot. */
9✔
911
  } else {  /* End of traversal. */
912
    L->top--;  /* Remove key slot. */
9✔
913
  }
914
  return more;
18✔
915
}
916

917
LUA_API const char *lua_getupvalue(lua_State *L, int idx, int n)
1✔
918
{
919
  TValue *val;
1✔
920
  GCobj *o;
1✔
921
  const char *name = lj_debug_uvnamev(index2adr(L, idx), (uint32_t)(n-1), &val, &o);
1✔
922
  if (name) {
1✔
923
    copyTV(L, L->top, val);
1✔
924
    incr_top(L);
1✔
925
  }
926
  return name;
1✔
927
}
928

929
LUA_API void *lua_upvalueid(lua_State *L, int idx, int n)
×
930
{
931
  GCfunc *fn = funcV(index2adr(L, idx));
×
932
  n--;
×
933
  api_check(L, (uint32_t)n < fn->l.nupvalues);
×
934
  return isluafunc(fn) ? (void *)gcref(fn->l.uvptr[n]) :
×
935
                         (void *)&fn->c.upvalue[n];
936
}
937

938
LUA_API void lua_upvaluejoin(lua_State *L, int idx1, int n1, int idx2, int n2)
×
939
{
940
  GCfunc *fn1 = funcV(index2adr(L, idx1));
×
941
  GCfunc *fn2 = funcV(index2adr(L, idx2));
×
942
  n1--; n2--;
×
943
  api_check(L, isluafunc(fn1) && (uint32_t)n1 < fn1->l.nupvalues);
×
944
  api_check(L, isluafunc(fn2) && (uint32_t)n2 < fn2->l.nupvalues);
×
945
  setgcrefr(fn1->l.uvptr[n1], fn2->l.uvptr[n2]);
×
946
  lj_gc_objbarrier(L, fn1, gcref(fn1->l.uvptr[n1]));
×
947
}
×
948

949
LUALIB_API void *luaL_testudata(lua_State *L, int idx, const char *tname)
12✔
950
{
951
  cTValue *o = index2adr(L, idx);
12✔
952
  if (tvisudata(o)) {
12✔
953
    GCudata *ud = udataV(o);
12✔
954
    cTValue *tv = lj_tab_getstr(tabV(registry(L)), lj_str_newz(L, tname));
12✔
955
    if (tv && tvistab(tv) && tabV(tv) == tabref(ud->metatable))
12✔
956
      return uddata(ud);
12✔
957
  }
958
  return NULL;  /* value is not a userdata with a metatable */
959
}
960

961
LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
12✔
962
{
963
  void *p = luaL_testudata(L, idx, tname);
12✔
964
  if (!p) lj_err_argtype(L, idx, tname);
12✔
965
  return p;
12✔
966
}
967

968
/* -- Object setters ------------------------------------------------------ */
969

970
LUA_API void lua_settable(lua_State *L, int idx)
3,466✔
971
{
972
  TValue *o;
3,466✔
973
  cTValue *t = index2adr(L, idx);
3,466✔
974
  api_checknelems(L, 2);
3,466✔
975
  api_checkvalidindex(L, t);
3,466✔
976
  o = lj_meta_tset(L, t, L->top-2);
3,466✔
977
  if (o) {
3,466✔
978
    /* NOBARRIER: lj_meta_tset ensures the table is not black. */
979
    L->top -= 2;
3,466✔
980
    copyTV(L, o, L->top+1);
3,466✔
981
  } else {
982
    TValue *base = L->top;
×
983
    copyTV(L, base+2, base-3-2*LJ_FR2);
×
984
    L->top = base+3;
×
985
    jit_secure_call(L, base, 0+1);
×
986
    L->top -= 3+LJ_FR2;
×
987
  }
988
}
3,466✔
989

990
LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
9,301✔
991
{
992
  TValue *o;
9,301✔
993
  TValue key;
9,301✔
994
  cTValue *t = index2adr(L, idx);
9,301✔
995
  api_checknelems(L, 1);
9,301✔
996
  api_checkvalidindex(L, t);
9,301✔
997
  setstrV(L, &key, lj_str_newz(L, k));
9,301✔
998
  o = lj_meta_tset(L, t, &key);
9,301✔
999
  if (o) {
9,301✔
1000
    /* NOBARRIER: lj_meta_tset ensures the table is not black. */
1001
    copyTV(L, o, --L->top);
9,301✔
1002
  } else {
1003
    TValue *base = L->top;
×
1004
    copyTV(L, base+2, base-3-2*LJ_FR2);
×
1005
    L->top = base+3;
×
1006
    jit_secure_call(L, base, 0+1);
×
1007
    L->top -= 2+LJ_FR2;
×
1008
  }
1009
}
9,301✔
1010

1011
LUA_API void lua_rawset(lua_State *L, int idx)
1,000,260✔
1012
{
1013
  GCtab *t = tabV(index2adr(L, idx));
1,000,260✔
1014
  TValue *dst, *key;
1,000,260✔
1015
  api_checknelems(L, 2);
1,000,260✔
1016
  key = L->top-2;
1,000,260✔
1017
  dst = lj_tab_set(L, t, key);
1,000,260✔
1018
  copyTV(L, dst, key+1);
1,000,259✔
1019
  lj_gc_anybarriert(L, t);
1,000,259✔
1020
  L->top = key;
1,000,259✔
1021
}
1,000,259✔
1022

1023
LUA_API void lua_rawseti(lua_State *L, int idx, int n)
105,252✔
1024
{
1025
  GCtab *t = tabV(index2adr(L, idx));
105,252✔
1026
  TValue *dst, *src;
105,252✔
1027
  api_checknelems(L, 1);
105,252✔
1028
  dst = lj_tab_setint(L, t, n);
105,252✔
1029
  src = L->top-1;
105,252✔
1030
  copyTV(L, dst, src);
105,252✔
1031
  lj_gc_barriert(L, t, dst);
105,252✔
1032
  L->top = src;
105,252✔
1033
}
105,252✔
1034

1035
LUA_API int lua_setmetatable(lua_State *L, int idx)
1,000,046✔
1036
{
1037
  global_State *g;
1,000,046✔
1038
  GCtab *mt;
1,000,046✔
1039
  cTValue *o = index2adr(L, idx);
1,000,046✔
1040
  api_checknelems(L, 1);
1,000,046✔
1041
  api_checkvalidindex(L, o);
1,000,046✔
1042
  if (tvisnil(L->top-1)) {
1,000,046✔
1043
    mt = NULL;
1044
  } else {
1045
    api_check(L, tvistab(L->top-1));
1,000,043✔
1046
    mt = tabV(L->top-1);
1,000,043✔
1047
  }
1048
  g = G(L);
1,000,046✔
1049
  if (tvistab(o)) {
1,000,046✔
1050
    setgcref(tabV(o)->metatable, obj2gco(mt));
5✔
1051
    if (mt)
5✔
1052
      lj_gc_objbarriert(L, tabV(o), mt);
5✔
1053
  } else if (tvisudata(o)) {
1,000,041✔
1054
    setgcref(udataV(o)->metatable, obj2gco(mt));
1,000,025✔
1055
    if (mt)
1,000,025✔
1056
      lj_gc_objbarrier(L, udataV(o), mt);
1,000,025✔
1057
  } else {
1058
    /* Flush cache, since traces specialize to basemt. But not during __gc. */
1059
    if (lj_trace_flushall(L))
16✔
1060
      lj_err_caller(L, LJ_ERR_NOGCMM);
×
1061
    if (tvisbool(o)) {
16✔
1062
      /* NOBARRIER: basemt is a GC root. */
1063
      setgcref(basemt_it(g, LJ_TTRUE), obj2gco(mt));
2✔
1064
      setgcref(basemt_it(g, LJ_TFALSE), obj2gco(mt));
2✔
1065
    } else {
1066
      /* NOBARRIER: basemt is a GC root. */
1067
      setgcref(basemt_obj(g, o), obj2gco(mt));
14✔
1068
    }
1069
  }
1070
  L->top--;
1,000,046✔
1071
  return 1;
1,000,046✔
1072
}
1073

1074
LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
13✔
1075
{
1076
  lua_getfield(L, LUA_REGISTRYINDEX, tname);
13✔
1077
  lua_setmetatable(L, -2);
13✔
1078
}
13✔
1079

1080
LUA_API int lua_setfenv(lua_State *L, int idx)
8✔
1081
{
1082
  cTValue *o = index2adr(L, idx);
8✔
1083
  GCtab *t;
8✔
1084
  api_checknelems(L, 1);
8✔
1085
  api_checkvalidindex(L, o);
8✔
1086
  api_check(L, tvistab(L->top-1));
8✔
1087
  t = tabV(L->top-1);
8✔
1088
  if (tvisfunc(o)) {
8✔
1089
    setgcref(funcV(o)->c.env, obj2gco(t));
4✔
1090
  } else if (tvisudata(o)) {
4✔
1091
    setgcref(udataV(o)->env, obj2gco(t));
×
1092
  } else if (tvisthread(o)) {
4✔
1093
    setgcref(threadV(o)->env, obj2gco(t));
3✔
1094
  } else {
1095
    L->top--;
1✔
1096
    return 0;
1✔
1097
  }
1098
  lj_gc_objbarrier(L, gcV(o), t);
7✔
1099
  L->top--;
7✔
1100
  return 1;
7✔
1101
}
1102

1103
LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n)
3✔
1104
{
1105
  cTValue *f = index2adr(L, idx);
3✔
1106
  TValue *val;
3✔
1107
  GCobj *o;
3✔
1108
  const char *name;
3✔
1109
  api_checknelems(L, 1);
3✔
1110
  name = lj_debug_uvnamev(f, (uint32_t)(n-1), &val, &o);
3✔
1111
  if (name) {
3✔
1112
    L->top--;
2✔
1113
    copyTV(L, val, L->top);
2✔
1114
    lj_gc_barrier(L, o, L->top);
2✔
1115
  }
1116
  return name;
3✔
1117
}
1118

1119
/* -- Calls --------------------------------------------------------------- */
1120

1121
#if LJ_FR2
1122
static TValue *api_call_base(lua_State *L, int nargs)
5,670✔
1123
{
1124
  TValue *o = L->top, *base = o - nargs;
5,670✔
1125
  L->top = o+1;
5,670✔
1126
  for (; o > base; o--) copyTV(L, o, o-1);
11,985✔
1127
  setnilV(o);
5,670✔
1128
  return o+1;
5,670✔
1129
}
1130
#else
1131
#define api_call_base(L, nargs)        (L->top - (nargs))
1132
#endif
1133

1134
LUA_API void lua_call(lua_State *L, int nargs, int nresults)
4,886✔
1135
{
1136
  api_check(L, L->status == LUA_OK || L->status == LUA_ERRERR);
4,886✔
1137
  api_checknelems(L, nargs+1);
4,886✔
1138
  jit_secure_call(L, api_call_base(L, nargs), nresults+1);
9,772✔
1139
}
4,882✔
1140

1141
LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
784✔
1142
{
1143
  global_State *g = G(L);
784✔
1144
  uint8_t oldh = hook_save(g);
784✔
1145
  ptrdiff_t ef;
784✔
1146
  int status;
784✔
1147
  api_check(L, L->status == LUA_OK || L->status == LUA_ERRERR);
784✔
1148
  api_checknelems(L, nargs+1);
784✔
1149
  if (errfunc == 0) {
784✔
1150
    ef = 0;
1151
  } else {
1152
    cTValue *o = stkindex2adr(L, errfunc);
417✔
1153
    api_checkvalidindex(L, o);
417✔
1154
    ef = savestack(L, o);
417✔
1155
  }
1156
  /* Forbid Lua world re-entrancy while running the trace */
1157
  if (tvref(g->jit_base)) {
784✔
1158
    setstrV(L, L->top++, lj_err_str(L, LJ_ERR_JITCALL));
×
1159
    if (g->panic) g->panic(L);
×
1160
    exit(EXIT_FAILURE);
×
1161
  }
1162
  lj_trace_abort(g);  /* Never record across Lua VM entrance */
784✔
1163
  status = lj_vm_pcall(L, api_call_base(L, nargs), nresults+1, ef);
1,568✔
1164
  if (status) hook_restore(g, oldh);
700✔
1165
  return status;
700✔
1166
}
1167

1168
static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud)
217✔
1169
{
1170
  GCfunc *fn = lj_func_newC(L, 0, getcurrenv(L));
434✔
1171
  TValue *top = L->top;
217✔
1172
  fn->c.f = func;
217✔
1173
  setfuncV(L, top++, fn);
217✔
1174
  if (LJ_FR2) setnilV(top++);
217✔
1175
#if LJ_64
1176
  ud = lj_lightud_intern(L, ud);
217✔
1177
#endif
1178
  setrawlightudV(top++, ud);
217✔
1179
  cframe_nres(L->cframe) = 1+0;  /* Zero results. */
217✔
1180
  L->top = top;
217✔
1181
  return top-1;  /* Now call the newly allocated C function. */
217✔
1182
}
1183

1184
LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
217✔
1185
{
1186
  global_State *g = G(L);
217✔
1187
  uint8_t oldh = hook_save(g);
217✔
1188
  int status;
217✔
1189
  api_check(L, L->status == LUA_OK || L->status == LUA_ERRERR);
217✔
1190
  /* Forbid Lua world re-entrancy while running the trace */
1191
  if (tvref(g->jit_base)) {
217✔
1192
    setstrV(L, L->top++, lj_err_str(L, LJ_ERR_JITCALL));
×
1193
    if (g->panic) g->panic(L);
×
1194
    exit(EXIT_FAILURE);
×
1195
  }
1196
  lj_trace_abort(g);  /* Never record across Lua VM entrance */
217✔
1197
  status = lj_vm_cpcall(L, func, ud, cpcall);
217✔
1198
  if (status) hook_restore(g, oldh);
133✔
1199
  return status;
133✔
1200
}
1201

1202
LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
1✔
1203
{
1204
  if (luaL_getmetafield(L, idx, field)) {
1✔
1205
    TValue *top = L->top--;
×
1206
    if (LJ_FR2) setnilV(top++);
×
1207
    copyTV(L, top++, index2adr(L, idx));
×
1208
    L->top = top;
×
1209
    jit_secure_call(L, top-1, 1+1);
×
1210
    return 1;
×
1211
  }
1212
  return 0;
1213
}
1214

1215
/* -- Coroutine yield and resume ------------------------------------------ */
1216

1217
LUA_API int lua_isyieldable(lua_State *L)
×
1218
{
1219
  return cframe_canyield(L->cframe);
×
1220
}
1221

1222
LUA_API int lua_yield(lua_State *L, int nresults)
2✔
1223
{
1224
  void *cf = L->cframe;
2✔
1225
  global_State *g = G(L);
2✔
1226
  if (cframe_canyield(cf)) {
2✔
1227
    cf = cframe_raw(cf);
2✔
1228
    if (!hook_active(g)) {  /* Regular yield: move results down if needed. */
2✔
1229
      cTValue *f = L->top - nresults;
×
1230
      if (f > L->base) {
×
1231
        TValue *t = L->base;
1232
        while (--nresults >= 0) copyTV(L, t++, f++);
×
1233
        L->top = t;
×
1234
      }
1235
      L->cframe = NULL;
×
1236
      L->status = LUA_YIELD;
×
1237
      return -1;
×
1238
    } else {  /* Yield from hook: add a pseudo-frame. */
1239
      TValue *top = L->top;
2✔
1240
      hook_leave(g);
2✔
1241
      (top++)->u64 = cframe_multres(cf);
2✔
1242
      setcont(top, lj_cont_hook);
2✔
1243
      if (LJ_FR2) top++;
2✔
1244
      setframe_pc(top, cframe_pc(cf)-1);
2✔
1245
      top++;
2✔
1246
      setframe_gc(top, obj2gco(L), LJ_TTHREAD);
2✔
1247
      if (LJ_FR2) top++;
2✔
1248
      setframe_ftsz(top, ((char *)(top+1)-(char *)L->base)+FRAME_CONT);
2✔
1249
      L->top = L->base = top+1;
2✔
1250
#if ((defined(__GNUC__) || defined(__clang__)) && (LJ_TARGET_X64 || defined(LUAJIT_UNWIND_EXTERNAL)) && !LJ_NO_UNWIND) || LJ_TARGET_WINDOWS
1251
      lj_err_throw(L, LUA_YIELD);
2✔
1252
#else
1253
      L->cframe = NULL;
1254
      L->status = LUA_YIELD;
1255
      lj_vm_unwind_c(cf, LUA_YIELD);
1256
#endif
1257
    }
1258
  }
1259
  lj_err_msg(L, LJ_ERR_CYIELD);
×
1260
  return 0;  /* unreachable */
1261
}
1262

1263
LUA_API int lua_resume(lua_State *L, int nargs)
×
1264
{
1265
  if (L->cframe == NULL && L->status <= LUA_YIELD)
×
1266
    return lj_vm_resume(L,
×
1267
      L->status == LUA_OK ? api_call_base(L, nargs) : L->top - nargs,
×
1268
      0, 0);
1269
  L->top = L->base;
×
1270
  setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP));
×
1271
  incr_top(L);
×
1272
  return LUA_ERRRUN;
1273
}
1274

1275
/* -- GC and memory management -------------------------------------------- */
1276

1277
LUA_API int lua_gc(lua_State *L, int what, int data)
940✔
1278
{
1279
  global_State *g = G(L);
940✔
1280
  int res = 0;
940✔
1281
  switch (what) {
940✔
1282
  case LUA_GCSTOP:
220✔
1283
    g->gc.threshold = LJ_MAX_MEM;
220✔
1284
    break;
220✔
1285
  case LUA_GCRESTART:
216✔
1286
    g->gc.threshold = data == -1 ? (g->gc.total/100)*g->gc.pause : g->gc.total;
216✔
1287
    break;
216✔
1288
  case LUA_GCCOLLECT:
154✔
1289
    lj_gc_fullgc(L);
154✔
1290
    break;
154✔
1291
  case LUA_GCCOUNT:
×
1292
    res = (int)(g->gc.total >> 10);
×
1293
    break;
×
1294
  case LUA_GCCOUNTB:
×
1295
    res = (int)(g->gc.total & 0x3ff);
×
1296
    break;
×
1297
  case LUA_GCSTEP: {
346✔
1298
    GCSize a = (GCSize)data << 10;
346✔
1299
    g->gc.threshold = (a <= g->gc.total) ? (g->gc.total - a) : 0;
346✔
1300
    while (g->gc.total >= g->gc.threshold)
691✔
1301
      if (lj_gc_step(L) > 0) {
346✔
1302
        res = 1;
1303
        break;
1304
      }
1305
    break;
1306
  }
1307
  case LUA_GCSETPAUSE:
1✔
1308
    res = (int)(g->gc.pause);
1✔
1309
    g->gc.pause = (MSize)data;
1✔
1310
    break;
1✔
1311
  case LUA_GCSETSTEPMUL:
3✔
1312
    res = (int)(g->gc.stepmul);
3✔
1313
    g->gc.stepmul = (MSize)data;
3✔
1314
    break;
3✔
1315
  case LUA_GCISRUNNING:
×
1316
    res = (g->gc.threshold != LJ_MAX_MEM);
×
1317
    break;
×
1318
  default:
1319
    res = -1;  /* Invalid option. */
1320
  }
1321
  return res;
939✔
1322
}
1323

1324
LUA_API lua_Alloc lua_getallocf(lua_State *L, void **ud)
9✔
1325
{
1326
  global_State *g = G(L);
9✔
1327
  if (ud) *ud = g->allocd;
9✔
1328
  return g->allocf;
9✔
1329
}
1330

1331
LUA_API void lua_setallocf(lua_State *L, lua_Alloc f, void *ud)
18✔
1332
{
1333
  global_State *g = G(L);
18✔
1334
  g->allocd = ud;
18✔
1335
  g->allocf = f;
18✔
1336
}
18✔
1337

1338
LUA_API uint32_t lua_hash(const char *str, uint32_t len)
1,649,707✔
1339
{
1340
  uint32_t h = len, a, b;
1,649,707✔
1341
  if (len >= 4) {
1,649,707✔
1342
    a = lj_getu32(str);
1,177,084✔
1343
    h ^= lj_getu32(str+len-4);
1,177,084✔
1344
    b = lj_getu32(str+(len>>1)-2);
1,177,084✔
1345
    h ^= b; h -= lj_rol(b, 14);
1,177,084✔
1346
    b += lj_getu32(str+(len>>2)-1);
1,177,084✔
1347
  } else if (len > 0) {
472,623✔
1348
    a = *str;
472,623✔
1349
    h ^= *(str+len-1);
472,623✔
1350
    b = *(str+(len>>1));
472,623✔
1351
    h ^= b; h -= lj_rol(b, 14);
472,623✔
1352
  } else {
1353
    return 0;
1354
  }
1355
  a ^= h; a -= lj_rol(h, 11);
1,649,707✔
1356
  b ^= a; b -= lj_rol(a, 25);
1,649,707✔
1357
  h ^= b; h -= lj_rol(b, 16);
1,649,707✔
1358
  return h;
1,649,707✔
1359
}
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