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

tarantool / luajit / 8062004225

27 Feb 2024 08:41AM UTC coverage: 92.591% (-0.007%) from 92.598%
8062004225

push

github

Buristan
test: enable CLI-related lua-Harness tests back

Tarantool supports -b and -j options to use LuaJIT modules since the
commit bf8b76a4d ("lua: proxy -j and -b
flags"), so 241-standalone.t and 411-luajit.t tests in the lua-Harness
suite, disabled in the commit 39a4db500
("test: support Tarantool in lua-Harness"), can be enabled back.

However, the -O option is still not implemented in Tarantool, so the
related part in the 411-luajit.t test chunk is still disabled.

Follows up tarantool/tarantool#5541

Reviewed-by: Maxim Kokryashkin <m.kokryashkin@tarantool.org>
Reviewed-by: Sergey Kaplun <skaplun@tarantool.org>
Signed-off-by: Sergey Kaplun <skaplun@tarantool.org>
(cherry picked from commit e316cbf0d)

5657 of 6016 branches covered (94.03%)

Branch coverage included in aggregate %.

21588 of 23409 relevant lines covered (92.22%)

2817149.02 hits per line

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

77.41
/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,275,389✔
35
{
36
  if (idx > 0) {
25,275,389✔
37
    TValue *o = L->base + (idx - 1);
9,576,579✔
38
    return o < L->top ? o : niltv(L);
9,576,579✔
39
  } else if (idx > LUA_REGISTRYINDEX) {
15,698,810✔
40
    lj_checkapi(idx != 0 && -idx <= L->top - L->base,
10,395,020✔
41
                "bad stack slot %d", idx);
42
    return L->top + idx;
10,395,020✔
43
  } else if (idx == LUA_GLOBALSINDEX) {
5,303,790✔
44
    TValue *o = &G(L)->tmptv;
5,496✔
45
    settabV(L, o, tabref(L->env));
5,496✔
46
    return o;
5,496✔
47
  } else if (idx == LUA_REGISTRYINDEX) {
5,298,294✔
48
    return registry(L);
4,295,378✔
49
  } else {
50
    GCfunc *fn = curr_func(L);
1,002,916✔
51
    lj_checkapi(fn->c.gct == ~LJ_TFUNC && !isluafunc(fn),
1,002,916✔
52
                "calling frame is not a C function");
53
    if (idx == LUA_ENVIRONINDEX) {
1,002,916✔
54
      TValue *o = &G(L)->tmptv;
1,959✔
55
      settabV(L, o, tabref(fn->c.env));
1,959✔
56
      return o;
1,959✔
57
    } else {
58
      idx = LUA_GLOBALSINDEX - idx;
1,000,957✔
59
      return idx <= fn->c.nupvalues ? &fn->c.upvalue[idx-1] : niltv(L);
1,000,957✔
60
    }
61
  }
62
}
63

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

71
static TValue *index2adr_stack(lua_State *L, int idx)
19,087✔
72
{
73
  if (idx > 0) {
19,087✔
74
    TValue *o = L->base + (idx - 1);
1,545✔
75
    if (o < L->top) {
1,545✔
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,
17,542✔
84
                "invalid stack slot %d", idx);
85
    return L->top + idx;
17,542✔
86
  }
87
}
88

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

95
static void jit_secure_call(lua_State *L, TValue *base, int nres) {
5,210,655✔
96
  global_State *g = G(L);
5,210,655✔
97
  /* Forbid Lua world re-entrancy while running the trace */
98
  if (tvref(g->jit_base)) {
5,210,655✔
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,210,654✔
104
  lj_vm_call(L, base, nres);
5,210,654✔
105
}
5,210,648✔
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)
15,078✔
115
{
116
  if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) {
15,078✔
117
    return 0;  /* Stack overflow. */
118
  } else if (size > 0) {
15,078✔
119
    lj_state_checkstack(L, (MSize)size);
14,201✔
120
  }
121
  return 1;
122
}
123

124
LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
15,000✔
125
{
126
  if (!lua_checkstack(L, size))
15,000✔
127
    lj_err_callerv(L, LJ_ERR_STKOVM, msg);
×
128
}
15,000✔
129

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

143
LUA_API const lua_Number *lua_version(lua_State *L)
×
144
{
145
  static const lua_Number version = LUA_VERSION_NUM;
×
146
  UNUSED(L);
×
147
  return &version;
×
148
}
149

150
/* -- Stack manipulation -------------------------------------------------- */
151

152
LUA_API int lua_gettop(lua_State *L)
197,294✔
153
{
154
  return (int)(L->top - L->base);
197,294✔
155
}
156

157
LUA_API void lua_settop(lua_State *L, int idx)
3,112,858✔
158
{
159
  if (idx >= 0) {
3,112,858✔
160
    lj_checkapi(idx <= tvref(L->maxstack) - L->base, "bad stack slot %d", idx);
1,062,291✔
161
    if (L->base + idx > L->top) {
1,062,291✔
162
      if (L->base + idx >= tvref(L->maxstack))
60,158✔
163
        lj_state_growstack(L, (MSize)idx - (MSize)(L->top - L->base));
×
164
      do { setnilV(L->top++); } while (L->top < L->base + idx);
162,603✔
165
    } else {
166
      L->top = L->base + idx;
1,002,133✔
167
    }
168
  } else {
169
    lj_checkapi(-(idx+1) <= (L->top - L->base), "bad stack slot %d", idx);
2,050,567✔
170
    L->top += idx+1;  /* Shrinks top (idx < 0). */
2,050,567✔
171
  }
172
}
3,112,858✔
173

174
LUA_API void lua_remove(lua_State *L, int idx)
17,521✔
175
{
176
  TValue *p = index2adr_stack(L, idx);
17,521✔
177
  while (++p < L->top) copyTV(L, p-1, p);
34,595✔
178
  L->top--;
17,521✔
179
}
17,521✔
180

181
LUA_API void lua_insert(lua_State *L, int idx)
1,009✔
182
{
183
  TValue *q, *p = index2adr_stack(L, idx);
1,009✔
184
  for (q = L->top; q > p; q--) copyTV(L, q, q-1);
2,842✔
185
  copyTV(L, p, L->top);
1,009✔
186
}
1,009✔
187

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

209
LUA_API void lua_replace(lua_State *L, int idx)
×
210
{
211
  lj_checkapi_slot(1);
×
212
  copy_slot(L, L->top - 1, idx);
×
213
  L->top--;
×
214
}
×
215

216
LUA_API void lua_copy(lua_State *L, int fromidx, int toidx)
295✔
217
{
218
  copy_slot(L, index2adr(L, fromidx), toidx);
295✔
219
}
295✔
220

221
LUA_API void lua_pushvalue(lua_State *L, int idx)
3,764,726✔
222
{
223
  copyTV(L, L->top, index2adr(L, idx));
3,764,726✔
224
  incr_top(L);
3,764,726✔
225
}
3,764,726✔
226

227
/* -- Stack getters ------------------------------------------------------- */
228

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

252
LUALIB_API void luaL_checktype(lua_State *L, int idx, int tt)
43✔
253
{
254
  if (lua_type(L, idx) != tt)
43✔
255
    lj_err_argt(L, idx, tt);
×
256
}
43✔
257

258
LUALIB_API void luaL_checkany(lua_State *L, int idx)
×
259
{
260
  if (index2adr(L, idx) == niltv(L))
×
261
    lj_err_arg(L, idx, LJ_ERR_NOVAL);
×
262
}
×
263

264
LUA_API const char *lua_typename(lua_State *L, int t)
1✔
265
{
266
  UNUSED(L);
1✔
267
  return lj_obj_typename[t+1];
1✔
268
}
269

270
LUA_API int lua_iscfunction(lua_State *L, int idx)
18✔
271
{
272
  cTValue *o = index2adr(L, idx);
18✔
273
  return tvisfunc(o) && !isluafunc(funcV(o));
18✔
274
}
275

276
LUA_API int lua_isnumber(lua_State *L, int idx)
71,270✔
277
{
278
  cTValue *o = index2adr(L, idx);
71,270✔
279
  TValue tmp;
71,270✔
280
  return (tvisnumber(o) || (tvisstr(o) && lj_strscan_number(strV(o), &tmp)));
71,270✔
281
}
282

283
LUA_API int lua_isstring(lua_State *L, int idx)
11,712✔
284
{
285
  cTValue *o = index2adr(L, idx);
11,712✔
286
  return (tvisstr(o) || tvisnumber(o));
11,712✔
287
}
288

289
LUA_API int lua_isuserdata(lua_State *L, int idx)
×
290
{
291
  cTValue *o = index2adr(L, idx);
×
292
  return (tvisudata(o) || tvislightud(o));
×
293
}
294

295
LUA_API int lua_rawequal(lua_State *L, int idx1, int idx2)
×
296
{
297
  cTValue *o1 = index2adr(L, idx1);
×
298
  cTValue *o2 = index2adr(L, idx2);
×
299
  return (o1 == niltv(L) || o2 == niltv(L)) ? 0 : lj_obj_equal(o1, o2);
×
300
}
301

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

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

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

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

386
LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx)
12✔
387
{
388
  cTValue *o = index2adr(L, idx);
12✔
389
  TValue tmp;
12✔
390
  if (LJ_LIKELY(tvisnumber(o)))
12✔
391
    return numberVnum(o);
12✔
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
LUALIB_API lua_Number luaL_optnumber(lua_State *L, int idx, lua_Number def)
4✔
398
{
399
  cTValue *o = index2adr(L, idx);
4✔
400
  TValue tmp;
4✔
401
  if (LJ_LIKELY(tvisnumber(o)))
4✔
402
    return numberVnum(o);
4✔
403
  else if (tvisnil(o))
×
404
    return def;
405
  else if (!(tvisstr(o) && lj_strscan_num(strV(o), &tmp)))
×
406
    lj_err_argt(L, idx, LUA_TNUMBER);
×
407
  return numV(&tmp);
×
408
}
409

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

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

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

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

510
LUA_API int lua_toboolean(lua_State *L, int idx)
1,913,280✔
511
{
512
  cTValue *o = index2adr(L, idx);
1,913,280✔
513
  return tvistruecond(o);
1,913,280✔
514
}
515

516
LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len)
64,807✔
517
{
518
  TValue *o = index2adr(L, idx);
64,807✔
519
  GCstr *s;
64,807✔
520
  if (LJ_LIKELY(tvisstr(o))) {
64,807✔
521
    s = strV(o);
59,774✔
522
  } else if (tvisnumber(o)) {
5,033✔
523
    lj_gc_check(L);
5,008✔
524
    o = index2adr(L, idx);  /* GC may move the stack. */
5,008✔
525
    s = lj_strfmt_number(L, o);
5,008✔
526
    setstrV(L, o, s);
5,008✔
527
  } else {
528
    if (len != NULL) *len = 0;
25✔
529
    return NULL;
25✔
530
  }
531
  if (len != NULL) *len = s->len;
64,782✔
532
  return strdata(s);
64,782✔
533
}
534

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

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

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

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

598
LUA_API size_t lua_objlen(lua_State *L, int idx)
519✔
599
{
600
  TValue *o = index2adr(L, idx);
519✔
601
  if (tvisstr(o)) {
519✔
602
    return strV(o)->len;
517✔
603
  } else if (tvistab(o)) {
2✔
604
    return (size_t)lj_tab_len(tabV(o));
2✔
605
  } else if (tvisudata(o)) {
×
606
    return udataV(o)->len;
×
607
  } else if (tvisnumber(o)) {
×
608
    GCstr *s = lj_strfmt_number(L, o);
×
609
    setstrV(L, o, s);
×
610
    return s->len;
×
611
  } else {
612
    return 0;
613
  }
614
}
615

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

627
LUA_API void *lua_touserdata(lua_State *L, int idx)
4✔
628
{
629
  cTValue *o = index2adr(L, idx);
4✔
630
  if (tvisudata(o))
4✔
631
    return uddata(udataV(o));
4✔
632
  else if (tvislightud(o))
×
633
    return lightudV(G(L), o);
×
634
  else
635
    return NULL;
636
}
637

638
LUA_API lua_State *lua_tothread(lua_State *L, int idx)
12✔
639
{
640
  cTValue *o = index2adr(L, idx);
12✔
641
  return (!tvisthread(o)) ? NULL : threadV(o);
12✔
642
}
643

644
LUA_API const void *lua_topointer(lua_State *L, int idx)
256✔
645
{
646
  return lj_obj_ptr(G(L), index2adr(L, idx));
256✔
647
}
648

649
/* -- Stack setters (object creation) ------------------------------------- */
650

651
LUA_API void lua_pushnil(lua_State *L)
1,606✔
652
{
653
  setnilV(L->top);
1,606✔
654
  incr_top(L);
1,606✔
655
}
1,606✔
656

657
LUA_API void lua_pushnumber(lua_State *L, lua_Number n)
283✔
658
{
659
  setnumV(L->top, n);
283✔
660
  if (LJ_UNLIKELY(tvisnan(L->top)))
283✔
661
    setnanV(L->top);  /* Canonicalize injected NaNs. */
×
662
  incr_top(L);
283✔
663
}
283✔
664

665
LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
4,505,659✔
666
{
667
  setintptrV(L->top, n);
4,505,659✔
668
  incr_top(L);
4,505,659✔
669
}
4,505,655✔
670

671
LUA_API void lua_pushlstring(lua_State *L, const char *str, size_t len)
64,061✔
672
{
673
  GCstr *s;
64,061✔
674
  lj_gc_check(L);
64,061✔
675
  s = lj_str_new(L, str, len);
64,061✔
676
  setstrV(L, L->top, s);
64,061✔
677
  incr_top(L);
64,061✔
678
}
64,061✔
679

680
LUA_API void lua_pushstring(lua_State *L, const char *str)
4,436,573✔
681
{
682
  if (str == NULL) {
4,436,573✔
683
    setnilV(L->top);
58✔
684
  } else {
685
    GCstr *s;
4,436,515✔
686
    lj_gc_check(L);
4,436,515✔
687
    s = lj_str_newz(L, str);
4,436,515✔
688
    setstrV(L, L->top, s);
4,436,515✔
689
  }
690
  incr_top(L);
4,436,573✔
691
}
4,436,573✔
692

693
LUA_API const char *lua_pushvfstring(lua_State *L, const char *fmt,
×
694
                                     va_list argp)
695
{
696
  lj_gc_check(L);
×
697
  return lj_strfmt_pushvf(L, fmt, argp);
×
698
}
699

700
LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...)
3,708✔
701
{
702
  const char *ret;
3,708✔
703
  va_list argp;
3,708✔
704
  lj_gc_check(L);
3,708✔
705
  va_start(argp, fmt);
3,708✔
706
  ret = lj_strfmt_pushvf(L, fmt, argp);
3,708✔
707
  va_end(argp);
3,708✔
708
  return ret;
3,708✔
709
}
710

711
LUA_API void lua_pushcclosure(lua_State *L, lua_CFunction f, int n)
9,648✔
712
{
713
  GCfunc *fn;
9,648✔
714
  lj_gc_check(L);
9,648✔
715
  lj_checkapi_slot(n);
9,648✔
716
  fn = lj_func_newC(L, (MSize)n, getcurrenv(L));
19,296✔
717
  fn->c.f = f;
9,648✔
718
  L->top -= n;
9,648✔
719
  while (n--)
9,648✔
720
    copyTV(L, &fn->c.upvalue[n], L->top+n);
10,628✔
721
  setfuncV(L, L->top, fn);
9,648✔
722
  lj_assertL(iswhite(obj2gco(fn)), "new GC object is not white");
9,648✔
723
  incr_top(L);
9,648✔
724
}
9,648✔
725

726
LUA_API void lua_pushboolean(lua_State *L, int b)
1,000,289✔
727
{
728
  setboolV(L->top, (b != 0));
1,000,289✔
729
  incr_top(L);
1,000,289✔
730
}
1,000,289✔
731

732
LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
291✔
733
{
734
#if LJ_64
735
  p = lj_lightud_intern(L, p);
291✔
736
#endif
737
  setrawlightudV(L->top, p);
289✔
738
  incr_top(L);
289✔
739
}
289✔
740

741
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
1,089,563✔
742
{
743
  lj_gc_check(L);
1,089,563✔
744
  settabV(L, L->top, lj_tab_new_ah(L, narray, nrec));
1,089,563✔
745
  incr_top(L);
1,089,563✔
746
}
1,089,563✔
747

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

764
LUA_API int lua_pushthread(lua_State *L)
4✔
765
{
766
  setthreadV(L, L->top, L);
4✔
767
  incr_top(L);
4✔
768
  return (mainthread(G(L)) == L);
4✔
769
}
770

771
LUA_API lua_State *lua_newthread(lua_State *L)
1,102✔
772
{
773
  lua_State *L1;
1,102✔
774
  lj_gc_check(L);
1,102✔
775
  L1 = lj_state_new(L);
1,102✔
776
  setthreadV(L, L->top, L1);
1,102✔
777
  incr_top(L);
1,102✔
778
  return L1;
1,102✔
779
}
780

781
LUA_API void *lua_newuserdata(lua_State *L, size_t size)
1,006,351✔
782
{
783
  GCudata *ud;
1,006,351✔
784
  lj_gc_check(L);
1,006,351✔
785
  if (size > LJ_MAX_UDATA)
1,006,351✔
786
    lj_err_msg(L, LJ_ERR_UDATAOV);
×
787
  ud = lj_udata_new(L, (MSize)size, getcurrenv(L));
2,012,702✔
788
  setudataV(L, L->top, ud);
1,006,351✔
789
  incr_top(L);
1,006,351✔
790
  return uddata(ud);
1,006,351✔
791
}
792

793
LUA_API void lua_concat(lua_State *L, int n)
27,391✔
794
{
795
  lj_checkapi_slot(n);
27,391✔
796
  if (n >= 2) {
27,391✔
797
    n--;
876✔
798
    do {
876✔
799
      TValue *top = lj_meta_cat(L, L->top-1, -n);
876✔
800
      if (top == NULL) {
876✔
801
        L->top -= n;
875✔
802
        break;
875✔
803
      }
804
      n -= (int)(L->top - (top - 2*LJ_FR2));
1✔
805
      L->top = top+2;
1✔
806
      jit_secure_call(L, top, 1+1);
1✔
807
      L->top -= 1+LJ_FR2;
1✔
808
      copyTV(L, L->top-1, L->top+LJ_FR2);
1✔
809
    } while (--n > 0);
1✔
810
  } else if (n == 0) {  /* Push empty string. */
26,515✔
811
    setstrV(L, L->top, &G(L)->strempty);
14✔
812
    incr_top(L);
14✔
813
  }
814
  /* else n == 1: nothing to do. */
815
}
27,391✔
816

817
/* -- Object getters ------------------------------------------------------ */
818

819
LUA_API void lua_gettable(lua_State *L, int idx)
131✔
820
{
821
  cTValue *t = index2adr_check(L, idx);
131✔
822
  cTValue *v = lj_meta_tget(L, t, L->top-1);
131✔
823
  if (v == NULL) {
131✔
824
    L->top += 2;
2✔
825
    jit_secure_call(L, L->top-2, 1+1);
2✔
826
    L->top -= 2+LJ_FR2;
2✔
827
    v = L->top+1+LJ_FR2;
2✔
828
  }
829
  copyTV(L, L->top-1, v);
131✔
830
}
131✔
831

832
LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
10,723✔
833
{
834
  cTValue *v, *t = index2adr_check(L, idx);
10,723✔
835
  TValue key;
10,723✔
836
  setstrV(L, &key, lj_str_newz(L, k));
10,723✔
837
  v = lj_meta_tget(L, t, &key);
10,723✔
838
  if (v == NULL) {
10,723✔
839
    L->top += 2;
×
840
    jit_secure_call(L, L->top-2, 1+1);
×
841
    L->top -= 2+LJ_FR2;
×
842
    v = L->top+1+LJ_FR2;
×
843
  }
844
  copyTV(L, L->top, v);
10,723✔
845
  incr_top(L);
10,723✔
846
}
10,723✔
847

848
LUA_API void lua_rawget(lua_State *L, int idx)
4,299,898✔
849
{
850
  cTValue *t = index2adr(L, idx);
4,299,898✔
851
  lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
4,299,898✔
852
  copyTV(L, L->top-1, lj_tab_get(L, tabV(t), L->top-1));
4,299,898✔
853
}
4,299,898✔
854

855
LUA_API void lua_rawgeti(lua_State *L, int idx, int n)
2,295,785✔
856
{
857
  cTValue *v, *t = index2adr(L, idx);
2,295,785✔
858
  lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
2,295,785✔
859
  v = lj_tab_getint(tabV(t), n);
2,295,785✔
860
  if (v) {
2,295,785✔
861
    copyTV(L, L->top, v);
2,295,728✔
862
  } else {
863
    setnilV(L->top);
57✔
864
  }
865
  incr_top(L);
2,295,785✔
866
}
2,295,785✔
867

868
LUA_API int lua_getmetatable(lua_State *L, int idx)
21,953✔
869
{
870
  cTValue *o = index2adr(L, idx);
21,953✔
871
  GCtab *mt = NULL;
21,953✔
872
  if (tvistab(o))
21,953✔
873
    mt = tabref(tabV(o)->metatable);
16✔
874
  else if (tvisudata(o))
21,937✔
875
    mt = tabref(udataV(o)->metatable);
1,889✔
876
  else
877
    mt = tabref(basemt_obj(G(L), o));
20,048✔
878
  if (mt == NULL)
21,953✔
879
    return 0;
880
  settabV(L, L->top, mt);
21,939✔
881
  incr_top(L);
21,939✔
882
  return 1;
883
}
884

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

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

913
LUA_API int lua_next(lua_State *L, int idx)
90✔
914
{
915
  cTValue *t = index2adr(L, idx);
90✔
916
  int more;
90✔
917
  lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
90✔
918
  more = lj_tab_next(L, tabV(t), L->top-1);
90✔
919
  if (more) {
90✔
920
    incr_top(L);  /* Return new key and value slot. */
60✔
921
  } else {  /* End of traversal. */
922
    L->top--;  /* Remove key slot. */
30✔
923
  }
924
  return more;
90✔
925
}
926

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

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

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

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

973
LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
21✔
974
{
975
  void *p = luaL_testudata(L, idx, tname);
21✔
976
  if (!p) lj_err_argtype(L, idx, tname);
21✔
977
  return p;
21✔
978
}
979

980
/* -- Object setters ------------------------------------------------------ */
981

982
LUA_API void lua_settable(lua_State *L, int idx)
5,064✔
983
{
984
  TValue *o;
5,064✔
985
  cTValue *t = index2adr_check(L, idx);
5,064✔
986
  lj_checkapi_slot(2);
5,064✔
987
  o = lj_meta_tset(L, t, L->top-2);
5,064✔
988
  if (o) {
5,064✔
989
    /* NOBARRIER: lj_meta_tset ensures the table is not black. */
990
    L->top -= 2;
5,062✔
991
    copyTV(L, o, L->top+1);
5,062✔
992
  } else {
993
    TValue *base = L->top;
2✔
994
    copyTV(L, base+2, base-3-2*LJ_FR2);
2✔
995
    L->top = base+3;
2✔
996
    jit_secure_call(L, base, 0+1);
2✔
997
    L->top -= 3+LJ_FR2;
2✔
998
  }
999
}
5,064✔
1000

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

1021
LUA_API void lua_rawset(lua_State *L, int idx)
1,000,349✔
1022
{
1023
  GCtab *t = tabV(index2adr(L, idx));
1,000,349✔
1024
  TValue *dst, *key;
1,000,349✔
1025
  lj_checkapi_slot(2);
1,000,349✔
1026
  key = L->top-2;
1,000,349✔
1027
  dst = lj_tab_set(L, t, key);
1,000,349✔
1028
  copyTV(L, dst, key+1);
1,000,348✔
1029
  lj_gc_anybarriert(L, t);
1,000,348✔
1030
  L->top = key;
1,000,348✔
1031
}
1,000,348✔
1032

1033
LUA_API void lua_rawseti(lua_State *L, int idx, int n)
1,015,120✔
1034
{
1035
  GCtab *t = tabV(index2adr(L, idx));
1,015,120✔
1036
  TValue *dst, *src;
1,015,120✔
1037
  lj_checkapi_slot(1);
1,015,120✔
1038
  dst = lj_tab_setint(L, t, n);
1,015,120✔
1039
  src = L->top-1;
1,015,120✔
1040
  copyTV(L, dst, src);
1,015,120✔
1041
  lj_gc_barriert(L, t, dst);
1,015,120✔
1042
  L->top = src;
1,015,120✔
1043
}
1,015,120✔
1044

1045
LUA_API int lua_setmetatable(lua_State *L, int idx)
1,001,017✔
1046
{
1047
  global_State *g;
1,001,017✔
1048
  GCtab *mt;
1,001,017✔
1049
  cTValue *o = index2adr_check(L, idx);
1,001,017✔
1050
  lj_checkapi_slot(1);
1,001,017✔
1051
  if (tvisnil(L->top-1)) {
1,001,017✔
1052
    mt = NULL;
1053
  } else {
1054
    lj_checkapi(tvistab(L->top-1), "top stack slot is not a table");
1,001,011✔
1055
    mt = tabV(L->top-1);
1,001,011✔
1056
  }
1057
  g = G(L);
1,001,017✔
1058
  if (tvistab(o)) {
1,001,017✔
1059
    setgcref(tabV(o)->metatable, obj2gco(mt));
10✔
1060
    if (mt)
10✔
1061
      lj_gc_objbarriert(L, tabV(o), mt);
10✔
1062
  } else if (tvisudata(o)) {
1,001,007✔
1063
    setgcref(udataV(o)->metatable, obj2gco(mt));
1,000,984✔
1064
    if (mt)
1,000,984✔
1065
      lj_gc_objbarrier(L, udataV(o), mt);
1,000,984✔
1066
  } else {
1067
    /* Flush cache, since traces specialize to basemt. But not during __gc. */
1068
    if (lj_trace_flushall(L))
23✔
1069
      lj_err_caller(L, LJ_ERR_NOGCMM);
×
1070
    if (tvisbool(o)) {
23✔
1071
      /* NOBARRIER: basemt is a GC root. */
1072
      setgcref(basemt_it(g, LJ_TTRUE), obj2gco(mt));
4✔
1073
      setgcref(basemt_it(g, LJ_TFALSE), obj2gco(mt));
4✔
1074
    } else {
1075
      /* NOBARRIER: basemt is a GC root. */
1076
      setgcref(basemt_obj(g, o), obj2gco(mt));
19✔
1077
    }
1078
  }
1079
  L->top--;
1,001,017✔
1080
  return 1;
1,001,017✔
1081
}
1082

1083
LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
21✔
1084
{
1085
  lua_getfield(L, LUA_REGISTRYINDEX, tname);
21✔
1086
  lua_setmetatable(L, -2);
21✔
1087
}
21✔
1088

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

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

1127
/* -- Calls --------------------------------------------------------------- */
1128

1129
#if LJ_FR2
1130
static TValue *api_call_base(lua_State *L, int nargs)
5,201,634✔
1131
{
1132
  TValue *o = L->top, *base = o - nargs;
5,201,634✔
1133
  L->top = o+1;
5,201,634✔
1134
  for (; o > base; o--) copyTV(L, o, o-1);
15,586,037✔
1135
  setnilV(o);
5,201,634✔
1136
  return o+1;
5,201,634✔
1137
}
1138
#else
1139
#define api_call_base(L, nargs)        (L->top - (nargs))
1140
#endif
1141

1142
LUA_API void lua_call(lua_State *L, int nargs, int nresults)
5,200,664✔
1143
{
1144
  lj_checkapi(L->status == LUA_OK || L->status == LUA_ERRERR,
5,200,664✔
1145
              "thread called in wrong state %d", L->status);
1146
  lj_checkapi_slot(nargs+1);
5,200,664✔
1147
  jit_secure_call(L, api_call_base(L, nargs), nresults+1);
10,401,328✔
1148
}
5,200,657✔
1149

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

1177
static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud)
294✔
1178
{
1179
  GCfunc *fn = lj_func_newC(L, 0, getcurrenv(L));
588✔
1180
  TValue *top = L->top;
294✔
1181
  fn->c.f = func;
294✔
1182
  setfuncV(L, top++, fn);
294✔
1183
  if (LJ_FR2) setnilV(top++);
294✔
1184
#if LJ_64
1185
  ud = lj_lightud_intern(L, ud);
294✔
1186
#endif
1187
  setrawlightudV(top++, ud);
294✔
1188
  cframe_nres(L->cframe) = 1+0;  /* Zero results. */
294✔
1189
  L->top = top;
294✔
1190
  return top-1;  /* Now call the newly allocated C function. */
294✔
1191
}
1192

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

1212
LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
1✔
1213
{
1214
  if (luaL_getmetafield(L, idx, field)) {
1✔
1215
    TValue *top = L->top--;
×
1216
    if (LJ_FR2) setnilV(top++);
×
1217
    copyTV(L, top++, index2adr(L, idx));
×
1218
    L->top = top;
×
1219
    jit_secure_call(L, top-1, 1+1);
×
1220
    return 1;
×
1221
  }
1222
  return 0;
1223
}
1224

1225
/* -- Coroutine yield and resume ------------------------------------------ */
1226

1227
LUA_API int lua_isyieldable(lua_State *L)
×
1228
{
1229
  return cframe_canyield(L->cframe);
×
1230
}
1231

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

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

1285
/* -- GC and memory management -------------------------------------------- */
1286

1287
LUA_API int lua_gc(lua_State *L, int what, int data)
1,988✔
1288
{
1289
  global_State *g = G(L);
1,988✔
1290
  int res = 0;
1,988✔
1291
  switch (what) {
1,988✔
1292
  case LUA_GCSTOP:
310✔
1293
    g->gc.threshold = LJ_MAX_MEM;
310✔
1294
    break;
310✔
1295
  case LUA_GCRESTART:
297✔
1296
    g->gc.threshold = data == -1 ? (g->gc.total/100)*g->gc.pause : g->gc.total;
297✔
1297
    break;
297✔
1298
  case LUA_GCCOLLECT:
941✔
1299
    lj_gc_fullgc(L);
941✔
1300
    break;
941✔
1301
  case LUA_GCCOUNT:
×
1302
    res = (int)(g->gc.total >> 10);
×
1303
    break;
×
1304
  case LUA_GCCOUNTB:
×
1305
    res = (int)(g->gc.total & 0x3ff);
×
1306
    break;
×
1307
  case LUA_GCSTEP: {
432✔
1308
    GCSize a = (GCSize)data << 10;
432✔
1309
    g->gc.threshold = (a <= g->gc.total) ? (g->gc.total - a) : 0;
432✔
1310
    while (g->gc.total >= g->gc.threshold)
988✔
1311
      if (lj_gc_step(L) > 0) {
563✔
1312
        res = 1;
1313
        break;
1314
      }
1315
    break;
1316
  }
1317
  case LUA_GCSETPAUSE:
2✔
1318
    res = (int)(g->gc.pause);
2✔
1319
    g->gc.pause = (MSize)data;
2✔
1320
    break;
2✔
1321
  case LUA_GCSETSTEPMUL:
6✔
1322
    res = (int)(g->gc.stepmul);
6✔
1323
    g->gc.stepmul = (MSize)data;
6✔
1324
    break;
6✔
1325
  case LUA_GCISRUNNING:
×
1326
    res = (g->gc.threshold != LJ_MAX_MEM);
×
1327
    break;
×
1328
  default:
1329
    res = -1;  /* Invalid option. */
1330
  }
1331
  return res;
1,988✔
1332
}
1333

1334
LUA_API lua_Alloc lua_getallocf(lua_State *L, void **ud)
10✔
1335
{
1336
  global_State *g = G(L);
10✔
1337
  if (ud) *ud = g->allocd;
10✔
1338
  return g->allocf;
10✔
1339
}
1340

1341
LUA_API void lua_setallocf(lua_State *L, lua_Alloc f, void *ud)
20✔
1342
{
1343
  global_State *g = G(L);
20✔
1344
  g->allocd = ud;
20✔
1345
  g->allocf = f;
20✔
1346
}
20✔
1347

1348
LUA_API uint32_t lua_hash(const char *str, uint32_t len)
9,167,025✔
1349
{
1350
  uint32_t h = len, a, b;
9,167,025✔
1351
  if (len >= 4) {
9,167,025✔
1352
    a = lj_getu32(str);
6,798,270✔
1353
    h ^= lj_getu32(str+len-4);
6,798,270✔
1354
    b = lj_getu32(str+(len>>1)-2);
6,798,270✔
1355
    h ^= b; h -= lj_rol(b, 14);
6,798,270✔
1356
    b += lj_getu32(str+(len>>2)-1);
6,798,270✔
1357
  } else if (len > 0) {
2,368,755✔
1358
    a = *str;
2,368,755✔
1359
    h ^= *(str+len-1);
2,368,755✔
1360
    b = *(str+(len>>1));
2,368,755✔
1361
    h ^= b; h -= lj_rol(b, 14);
2,368,755✔
1362
  } else {
1363
    return 0;
1364
  }
1365
  a ^= h; a -= lj_rol(h, 11);
9,167,025✔
1366
  b ^= a; b -= lj_rol(a, 25);
9,167,025✔
1367
  h ^= b; h -= lj_rol(b, 16);
9,167,025✔
1368
  return h;
9,167,025✔
1369
}
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

© 2025 Coveralls, Inc