Coverage Report

Created: 2025-12-28 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tarantool/third_party/luajit/src/lj_lib.c
Line
Count
Source
1
/*
2
** Library function support.
3
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
4
*/
5
6
#define lj_lib_c
7
#define LUA_CORE
8
9
#include "lauxlib.h"
10
11
#include "lj_obj.h"
12
#include "lj_gc.h"
13
#include "lj_err.h"
14
#include "lj_str.h"
15
#include "lj_tab.h"
16
#include "lj_func.h"
17
#include "lj_bc.h"
18
#include "lj_dispatch.h"
19
#include "lj_vm.h"
20
#include "lj_strscan.h"
21
#include "lj_strfmt.h"
22
#include "lj_lex.h"
23
#include "lj_bcdump.h"
24
#include "lj_lib.h"
25
26
/* -- Library initialization ---------------------------------------------- */
27
28
static GCtab *lib_create_table(lua_State *L, const char *libname, int hsize)
29
477k
{
30
477k
  if (libname) {
31
397k
    luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
32
397k
    lua_getfield(L, -1, libname);
33
397k
    if (!tvistab(L->top-1)) {
34
397k
      L->top--;
35
397k
      if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, hsize) != NULL)
36
0
  lj_err_callerv(L, LJ_ERR_BADMODN, libname);
37
397k
      settabV(L, L->top, tabV(L->top-1));
38
0
      L->top++;
39
397k
      lua_setfield(L, -3, libname);  /* _LOADED[libname] = new table */
40
397k
    }
41
397k
    L->top--;
42
397k
    settabV(L, L->top-1, tabV(L->top));
43
397k
  } else {
44
79.8k
    lua_createtable(L, 0, hsize);
45
79.8k
  }
46
477k
  return tabV(L->top-1);
47
477k
}
48
49
static const uint8_t *lib_read_lfunc(lua_State *L, const uint8_t *p, GCtab *tab)
50
227k
{
51
227k
  int len = *p++;
52
227k
  GCstr *name = lj_str_new(L, (const char *)p, len);
53
227k
  LexState ls;
54
227k
  GCproto *pt;
55
227k
  GCfunc *fn;
56
227k
  memset(&ls, 0, sizeof(ls));
57
227k
  ls.L = L;
58
227k
  ls.p = (const char *)(p+len);
59
227k
  ls.pe = (const char *)~(uintptr_t)0;
60
227k
  ls.c = -1;
61
227k
  ls.level = (BCDUMP_F_STRIP|(LJ_BE*BCDUMP_F_BE));
62
227k
  ls.chunkname = name;
63
227k
  pt = lj_bcread_proto(&ls);
64
227k
  pt->firstline = ~(BCLine)0;
65
227k
  fn = lj_func_newL_empty(L, pt, tabref(L->env));
66
  /* NOBARRIER: See below for common barrier. */
67
227k
  setfuncV(L, lj_tab_setstr(L, tab, name), fn);
68
227k
  return (const uint8_t *)ls.p;
69
227k
}
70
71
void lj_lib_register(lua_State *L, const char *libname,
72
         const uint8_t *p, const lua_CFunction *cf)
73
477k
{
74
477k
  GCtab *env = tabref(L->env);
75
477k
  GCfunc *ofn = NULL;
76
477k
  int ffid = *p++;
77
477k
  BCIns *bcff = &L2GG(L)->bcff[*p++];
78
477k
  GCtab *tab = lib_create_table(L, libname, *p++);
79
477k
  ptrdiff_t tpos = L->top - L->base;
80
81
  /* Avoid barriers further down. */
82
477k
  lj_gc_anybarriert(L, tab);
83
477k
  tab->nomm = 0;
84
85
7.17M
  for (;;) {
86
7.17M
    uint32_t tag = *p++;
87
7.17M
    MSize len = tag & LIBINIT_LENMASK;
88
7.17M
    tag &= LIBINIT_TAGMASK;
89
7.17M
    if (tag != LIBINIT_STRING) {
90
4.74M
      const char *name;
91
4.74M
      MSize nuv = (MSize)(L->top - L->base - tpos);
92
4.74M
      GCfunc *fn = lj_func_newC(L, nuv, env);
93
4.74M
      if (nuv) {
94
198k
  L->top = L->base + tpos;
95
198k
  memcpy(fn->c.upvalue, L->top, sizeof(TValue)*nuv);
96
198k
      }
97
4.74M
      fn->c.ffid = (uint8_t)(ffid++);
98
4.74M
      name = (const char *)p;
99
4.74M
      p += len;
100
4.74M
      if (tag == LIBINIT_CF)
101
3.15M
  setmref(fn->c.pc, &G(L)->bc_cfunc_int);
102
1.59M
      else
103
1.59M
  setmref(fn->c.pc, bcff++);
104
4.74M
      if (tag == LIBINIT_ASM_)
105
823k
  fn->c.f = ofn->c.f;  /* Copy handler from previous function. */
106
3.92M
      else
107
3.92M
  fn->c.f = *cf++;  /* Get cf or handler from C function table. */
108
4.74M
      if (len) {
109
  /* NOBARRIER: See above for common barrier. */
110
4.71M
  setfuncV(L, lj_tab_setstr(L, tab, lj_str_new(L, name, len)), fn);
111
4.71M
      }
112
4.74M
      ofn = fn;
113
4.74M
    } else {
114
2.42M
      switch (tag | len) {
115
227k
      case LIBINIT_LUA:
116
227k
  p = lib_read_lfunc(L, p, tab);
117
227k
  break;
118
345k
      case LIBINIT_SET:
119
345k
  L->top -= 2;
120
691k
  if (tvisstr(L->top+1) && strV(L->top+1)->len == 0)
121
54.1k
    env = tabV(L->top);
122
291k
  else  /* NOBARRIER: See above for common barrier. */
123
291k
    copyTV(L, lj_tab_set(L, tab, L->top+1), L->top);
124
345k
  break;
125
345k
      case LIBINIT_NUMBER:
126
56.8k
  memcpy(&L->top->n, p, sizeof(double));
127
56.8k
  L->top++;
128
56.8k
  p += sizeof(double);
129
56.8k
  break;
130
418k
      case LIBINIT_COPY:
131
418k
  copyTV(L, L->top, L->top - *p++);
132
418k
  L->top++;
133
418k
  break;
134
56.8k
      case LIBINIT_LASTCL:
135
56.8k
  setfuncV(L, L->top++, ofn);
136
56.8k
  break;
137
113k
      case LIBINIT_FFID:
138
113k
  ffid++;
139
113k
  break;
140
477k
      case LIBINIT_END:
141
477k
  return;
142
727k
      default:
143
727k
  setstrV(L, L->top++, lj_str_new(L, (const char *)p, len));
144
727k
  p += len;
145
727k
  break;
146
2.42M
      }
147
2.42M
    }
148
7.17M
  }
149
477k
}
150
151
/* Push internal function on the stack. */
152
GCfunc *lj_lib_pushcc(lua_State *L, lua_CFunction f, int id, int n)
153
142k
{
154
142k
  GCfunc *fn;
155
142k
  lua_pushcclosure(L, f, n);
156
142k
  fn = funcV(L->top-1);
157
0
  fn->c.ffid = (uint8_t)id;
158
142k
  setmref(fn->c.pc, &G(L)->bc_cfunc_int);
159
142k
  return fn;
160
142k
}
161
162
void lj_lib_prereg(lua_State *L, const char *name, lua_CFunction f, GCtab *env)
163
113k
{
164
113k
  luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD", 4);
165
113k
  lua_pushcfunction(L, f);
166
  /* NOBARRIER: The function is new (marked white). */
167
113k
  setgcref(funcV(L->top-1)->c.env, obj2gco(env));
168
0
  lua_setfield(L, -2, name);
169
113k
  L->top--;
170
113k
}
171
172
int lj_lib_postreg(lua_State *L, lua_CFunction cf, int id, const char *name)
173
0
{
174
0
  GCfunc *fn = lj_lib_pushcf(L, cf, id);
175
0
  GCtab *t = tabref(curr_func(L)->c.env);  /* Reference to parent table. */
176
0
  setfuncV(L, lj_tab_setstr(L, t, lj_str_newz(L, name)), fn);
177
0
  lj_gc_anybarriert(L, t);
178
0
  setfuncV(L, L->top++, fn);
179
0
  return 1;
180
0
}
181
182
/* -- Type checks --------------------------------------------------------- */
183
184
TValue *lj_lib_checkany(lua_State *L, int narg)
185
3.72M
{
186
3.72M
  TValue *o = L->base + narg-1;
187
3.72M
  if (o >= L->top)
188
5.27k
    lj_err_arg(L, narg, LJ_ERR_NOVAL);
189
3.71M
  return o;
190
3.72M
}
191
192
GCstr *lj_lib_checkstr(lua_State *L, int narg)
193
6.37M
{
194
6.37M
  TValue *o = L->base + narg-1;
195
6.37M
  if (o < L->top) {
196
6.35M
    if (LJ_LIKELY(tvisstr(o))) {
197
6.19M
      return strV(o);
198
6.19M
    } else if (tvisnumber(o)) {
199
155k
      GCstr *s = lj_strfmt_number(L, o);
200
155k
      setstrV(L, o, s);
201
155k
      return s;
202
155k
    }
203
6.35M
  }
204
23.8k
  lj_err_argt(L, narg, LUA_TSTRING);
205
0
  return NULL;  /* unreachable */
206
6.37M
}
207
208
GCstr *lj_lib_optstr(lua_State *L, int narg)
209
12.3M
{
210
12.3M
  TValue *o = L->base + narg-1;
211
12.3M
  return (o < L->top && !tvisnil(o)) ? lj_lib_checkstr(L, narg) : NULL;
212
12.3M
}
213
214
#if LJ_DUALNUM
215
void lj_lib_checknumber(lua_State *L, int narg)
216
{
217
  TValue *o = L->base + narg-1;
218
  if (!(o < L->top && lj_strscan_numberobj(o)))
219
    lj_err_argt(L, narg, LUA_TNUMBER);
220
}
221
#endif
222
223
lua_Number lj_lib_checknum(lua_State *L, int narg)
224
851k
{
225
851k
  TValue *o = L->base + narg-1;
226
851k
  if (!(o < L->top &&
227
851k
  (tvisnumber(o) || (tvisstr(o) && lj_strscan_num(strV(o), o)))))
228
107
    lj_err_argt(L, narg, LUA_TNUMBER);
229
851k
  if (LJ_UNLIKELY(tvisint(o))) {
230
0
    lua_Number n = (lua_Number)intV(o);
231
0
    setnumV(o, n);
232
0
    return n;
233
851k
  } else {
234
851k
    return numV(o);
235
851k
  }
236
851k
}
237
238
int32_t lj_lib_checkint(lua_State *L, int narg)
239
2.40M
{
240
2.40M
  TValue *o = L->base + narg-1;
241
2.40M
  if (!(o < L->top && lj_strscan_numberobj(o)))
242
2.73k
    lj_err_argt(L, narg, LUA_TNUMBER);
243
2.39M
  if (LJ_LIKELY(tvisint(o))) {
244
0
    return intV(o);
245
2.39M
  } else {
246
2.39M
    int32_t i = lj_num2int(numV(o));
247
2.39M
    if (LJ_DUALNUM) setintV(o, i);
248
2.39M
    return i;
249
2.39M
  }
250
2.39M
}
251
252
int32_t lj_lib_optint(lua_State *L, int narg, int32_t def)
253
2.71M
{
254
2.71M
  TValue *o = L->base + narg-1;
255
2.71M
  return (o < L->top && !tvisnil(o)) ? lj_lib_checkint(L, narg) : def;
256
2.71M
}
257
258
GCfunc *lj_lib_checkfunc(lua_State *L, int narg)
259
502k
{
260
502k
  TValue *o = L->base + narg-1;
261
502k
  if (!(o < L->top && tvisfunc(o)))
262
48.1k
    lj_err_argt(L, narg, LUA_TFUNCTION);
263
454k
  return funcV(o);
264
454k
}
265
266
GCtab *lj_lib_checktab(lua_State *L, int narg)
267
2.22M
{
268
2.22M
  TValue *o = L->base + narg-1;
269
2.22M
  if (!(o < L->top && tvistab(o)))
270
917
    lj_err_argt(L, narg, LUA_TTABLE);
271
2.22M
  return tabV(o);
272
2.22M
}
273
274
GCtab *lj_lib_checktabornil(lua_State *L, int narg)
275
78.2k
{
276
78.2k
  TValue *o = L->base + narg-1;
277
78.2k
  if (o < L->top) {
278
78.1k
    if (tvistab(o))
279
78.1k
      return tabV(o);
280
4.98k
    else if (tvisnil(o))
281
4.89k
      return NULL;
282
78.1k
  }
283
162
  lj_err_arg(L, narg, LJ_ERR_NOTABN);
284
0
  return NULL;  /* unreachable */
285
78.2k
}
286
287
int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst)
288
95.5k
{
289
95.5k
  GCstr *s = def >= 0 ? lj_lib_optstr(L, narg) : lj_lib_checkstr(L, narg);
290
95.5k
  if (s) {
291
27.4k
    const char *opt = strdata(s);
292
27.4k
    MSize len = s->len;
293
27.4k
    int i;
294
156k
    for (i = 0; *(const uint8_t *)lst; i++) {
295
155k
      if (*(const uint8_t *)lst == len && memcmp(opt, lst+1, len) == 0)
296
26.4k
  return i;
297
128k
      lst += 1+*(const uint8_t *)lst;
298
128k
    }
299
1.06k
    lj_err_argv(L, narg, LJ_ERR_INVOPTM, opt);
300
27.4k
  }
301
68.0k
  return def;
302
95.5k
}
303