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

tarantool / luajit / 6035198545

31 Aug 2023 08:55AM UTC coverage: 88.225% (+0.4%) from 87.822%
6035198545

push

github

fckxorg
test: don't skip tool CLI flag for tarantool

That skipcond was introduced to overcome the obstacles
of LuaJIT's integration testing in Tarantool. Since
the required patch is now in the Tarantool master, this
skipcond is now unnecessary.

Related to tarantool/tarantool#5688

5340 of 5975 branches covered (0.0%)

Branch coverage included in aggregate %.

20495 of 23308 relevant lines covered (87.93%)

1297339.67 hits per line

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

99.22
/src/lj_func.c
1
/*
2
** Function handling (prototypes, functions and upvalues).
3
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
4
**
5
** 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_func_c
10
#define LUA_CORE
11

12
#include "lj_obj.h"
13
#include "lj_gc.h"
14
#include "lj_func.h"
15
#include "lj_trace.h"
16
#include "lj_vm.h"
17

18
/* -- Prototypes ---------------------------------------------------------- */
19

20
void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt)
52,887✔
21
{
22
  lj_mem_free(g, pt, pt->sizept);
52,887✔
23
}
52,887✔
24

25
/* -- Upvalues ------------------------------------------------------------ */
26

27
static void unlinkuv(global_State *g, GCupval *uv)
13,826✔
28
{
29
  UNUSED(g);
13,826✔
30
  lj_assertG(uvprev(uvnext(uv)) == uv && uvnext(uvprev(uv)) == uv,
13,826✔
31
             "broken upvalue chain");
32
  setgcrefr(uvnext(uv)->prev, uv->prev);
13,826✔
33
  setgcrefr(uvprev(uv)->next, uv->next);
13,826✔
34
}
2,028✔
35

36
/* Find existing open upvalue for a stack slot or create a new one. */
37
static GCupval *func_finduv(lua_State *L, TValue *slot)
19,801✔
38
{
39
  global_State *g = G(L);
19,801✔
40
  GCRef *pp = &L->openupval;
19,801✔
41
  GCupval *p;
19,801✔
42
  GCupval *uv;
19,801✔
43
  /* Search the sorted list of open upvalues. */
44
  while (gcref(*pp) != NULL && uvval((p = gco2uv(gcref(*pp)))) >= slot) {
53,265✔
45
    lj_assertG(!p->closed && uvval(p) != &p->tv, "closed upvalue in chain");
39,439✔
46
    if (uvval(p) == slot) {  /* Found open upvalue pointing to same slot? */
39,439✔
47
      if (isdead(g, obj2gco(p)))  /* Resurrect it, if it's dead. */
5,975✔
48
        flipwhite(obj2gco(p));
×
49
      return p;
5,975✔
50
    }
51
    pp = &p->nextgc;
33,464✔
52
  }
53
  /* No matching upvalue found. Create a new one. */
54
  uv = lj_mem_newt(L, sizeof(GCupval), GCupval);
13,826✔
55
  newwhite(g, uv);
13,826✔
56
  uv->gct = ~LJ_TUPVAL;
13,826✔
57
  uv->closed = 0;  /* Still open. */
13,826✔
58
  setmref(uv->v, slot);  /* Pointing to the stack slot. */
13,826✔
59
  /* NOBARRIER: The GCupval is new (marked white) and open. */
60
  setgcrefr(uv->nextgc, *pp);  /* Insert into sorted list of open upvalues. */
13,826✔
61
  setgcref(*pp, obj2gco(uv));
13,826✔
62
  setgcref(uv->prev, obj2gco(&g->uvhead));  /* Insert into GC list, too. */
13,826✔
63
  setgcrefr(uv->next, g->uvhead.next);
13,826✔
64
  setgcref(uvnext(uv)->prev, obj2gco(uv));
13,826✔
65
  setgcref(g->uvhead.next, obj2gco(uv));
13,826✔
66
  lj_assertG(uvprev(uvnext(uv)) == uv && uvnext(uvprev(uv)) == uv,
13,826✔
67
             "broken upvalue chain");
68
  return uv;
13,826✔
69
}
70

71
/* Create an empty and closed upvalue. */
72
static GCupval *func_emptyuv(lua_State *L)
5✔
73
{
74
  GCupval *uv = (GCupval *)lj_mem_newgco(L, sizeof(GCupval));
10✔
75
  uv->gct = ~LJ_TUPVAL;
5✔
76
  uv->closed = 1;
5✔
77
  setnilV(&uv->tv);
5✔
78
  setmref(uv->v, &uv->tv);
5✔
79
  return uv;
5✔
80
}
81

82
/* Close all open upvalues pointing to some stack level or above. */
83
void LJ_FASTCALL lj_func_closeuv(lua_State *L, TValue *level)
33,467✔
84
{
85
  GCupval *uv;
33,467✔
86
  global_State *g = G(L);
33,467✔
87
  while (gcref(L->openupval) != NULL &&
45,273✔
88
         uvval((uv = gco2uv(gcref(L->openupval)))) >= level) {
42,450✔
89
    GCobj *o = obj2gco(uv);
11,806✔
90
    lj_assertG(!isblack(o), "bad black upvalue");
11,806✔
91
    lj_assertG(!uv->closed && uvval(uv) != &uv->tv, "closed upvalue in chain");
11,806✔
92
    setgcrefr(L->openupval, uv->nextgc);  /* No longer in open list. */
11,806✔
93
    if (isdead(g, o)) {
11,806✔
94
      lj_func_freeuv(g, uv);
8✔
95
    } else {
96
      unlinkuv(g, uv);
11,798✔
97
      lj_gc_closeuv(g, uv);
11,798✔
98
    }
99
  }
100
}
33,467✔
101

102
void LJ_FASTCALL lj_func_freeuv(global_State *g, GCupval *uv)
13,655✔
103
{
104
  if (!uv->closed)
13,655✔
105
    unlinkuv(g, uv);
2,028✔
106
  lj_mem_freet(g, uv);
13,655✔
107
}
13,655✔
108

109
/* -- Functions (closures) ------------------------------------------------ */
110

111
GCfunc *lj_func_newC(lua_State *L, MSize nelems, GCtab *env)
48,100✔
112
{
113
  GCfunc *fn = (GCfunc *)lj_mem_newgco(L, sizeCfunc(nelems));
48,100✔
114
  fn->c.gct = ~LJ_TFUNC;
48,100✔
115
  fn->c.ffid = FF_C;
48,100✔
116
  fn->c.nupvalues = (uint8_t)nelems;
48,100✔
117
  /* NOBARRIER: The GCfunc is new (marked white). */
118
  setmref(fn->c.pc, &G(L)->bc_cfunc_ext);
48,100✔
119
  setgcref(fn->c.env, obj2gco(env));
48,100✔
120
  return fn;
48,100✔
121
}
122

123
static GCfunc *func_newL(lua_State *L, GCproto *pt, GCtab *env)
1,083,410✔
124
{
125
  uint32_t count;
1,083,410✔
126
  GCfunc *fn = (GCfunc *)lj_mem_newgco(L, sizeLfunc((MSize)pt->sizeuv));
1,083,410✔
127
  fn->l.gct = ~LJ_TFUNC;
1,083,410✔
128
  fn->l.ffid = FF_LUA;
1,083,410✔
129
  fn->l.nupvalues = 0;  /* Set to zero until upvalues are initialized. */
1,083,410✔
130
  /* NOBARRIER: Really a setgcref. But the GCfunc is new (marked white). */
131
  setmref(fn->l.pc, proto_bc(pt));
1,083,410✔
132
  setgcref(fn->l.env, obj2gco(env));
1,083,410✔
133
  /* Saturating 3 bit counter (0..7) for created closures. */
134
  count = (uint32_t)pt->flags + PROTO_CLCOUNT;
1,083,410✔
135
  pt->flags = (uint8_t)(count - ((count >> PROTO_CLC_BITS) & PROTO_CLCOUNT));
1,083,410✔
136
  return fn;
1,083,410✔
137
}
138

139
/* Create a new Lua function with empty upvalues. */
140
GCfunc *lj_func_newL_empty(lua_State *L, GCproto *pt, GCtab *env)
40,477✔
141
{
142
  GCfunc *fn = func_newL(L, pt, env);
40,477✔
143
  MSize i, nuv = pt->sizeuv;
40,477✔
144
  /* NOBARRIER: The GCfunc is new (marked white). */
145
  for (i = 0; i < nuv; i++) {
40,482✔
146
    GCupval *uv = func_emptyuv(L);
5✔
147
    int32_t v = proto_uv(pt)[i];
5✔
148
    uv->immutable = ((v / PROTO_UV_IMMUTABLE) & 1);
5✔
149
    uv->dhash = (uint32_t)(uintptr_t)pt ^ (v << 24);
5✔
150
    setgcref(fn->l.uvptr[i], obj2gco(uv));
5✔
151
  }
152
  fn->l.nupvalues = (uint8_t)nuv;
40,477✔
153
  return fn;
40,477✔
154
}
155

156
/* Do a GC check and create a new Lua function with inherited upvalues. */
157
GCfunc *lj_func_newL_gc(lua_State *L, GCproto *pt, GCfuncL *parent)
1,042,933✔
158
{
159
  GCfunc *fn;
1,042,933✔
160
  GCRef *puv;
1,042,933✔
161
  MSize i, nuv;
1,042,933✔
162
  TValue *base;
1,042,933✔
163
  lj_gc_check_fixtop(L);
1,042,933✔
164
  fn = func_newL(L, pt, tabref(parent->env));
1,042,933✔
165
  /* NOBARRIER: The GCfunc is new (marked white). */
166
  puv = parent->uvptr;
1,042,933✔
167
  nuv = pt->sizeuv;
1,042,933✔
168
  base = L->base;
1,042,933✔
169
  for (i = 0; i < nuv; i++) {
1,066,387✔
170
    uint32_t v = proto_uv(pt)[i];
23,454✔
171
    GCupval *uv;
23,454✔
172
    if ((v & PROTO_UV_LOCAL)) {
23,454✔
173
      uv = func_finduv(L, base + (v & 0xff));
19,801✔
174
      uv->immutable = ((v / PROTO_UV_IMMUTABLE) & 1);
19,801✔
175
      uv->dhash = (uint32_t)(uintptr_t)mref(parent->pc, char) ^ (v << 24);
19,801✔
176
    } else {
177
      uv = &gcref(puv[v])->uv;
3,653✔
178
    }
179
    setgcref(fn->l.uvptr[i], obj2gco(uv));
23,454✔
180
  }
181
  fn->l.nupvalues = (uint8_t)nuv;
1,042,933✔
182
  return fn;
1,042,933✔
183
}
184

185
void LJ_FASTCALL lj_func_free(global_State *g, GCfunc *fn)
1,129,519✔
186
{
187
  MSize size = isluafunc(fn) ? sizeLfunc((MSize)fn->l.nupvalues) :
1,129,519✔
188
                               sizeCfunc((MSize)fn->c.nupvalues);
46,379✔
189
  lj_mem_free(g, fn, size);
1,129,519✔
190
}
1,129,519✔
191

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