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

tarantool / luajit / 11774765987

11 Nov 2024 08:22AM UTC coverage: 92.931% (-0.008%) from 92.939%
11774765987

push

github

mandesero
tmp commit for ci check

5694 of 6033 branches covered (94.38%)

Branch coverage included in aggregate %.

21704 of 23449 relevant lines covered (92.56%)

2961521.92 hits per line

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

98.72
/src/lj_tab.c
1
/*
2
** Table handling.
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_tab_c
10
#define LUA_CORE
11

12
#include "lj_obj.h"
13
#include "lj_gc.h"
14
#include "lj_err.h"
15
#include "lj_tab.h"
16

17
/* -- Object hashing ------------------------------------------------------ */
18

19
/* Hash values are masked with the table hash mask and used as an index. */
20
static LJ_AINLINE Node *hashmask(const GCtab *t, uint32_t hash)
149,948,323✔
21
{
22
  Node *n = noderef(t->node);
149,948,323✔
23
  return &n[hash & t->hmask];
134,621,766✔
24
}
25

26
/* String hashes are precomputed when they are interned. */
27
#define hashstr(t, s)                hashmask(t, (s)->hash)
28

29
#define hashlohi(t, lo, hi)        hashmask((t), hashrot((lo), (hi)))
30
#define hashnum(t, o)                hashlohi((t), (o)->u32.lo, ((o)->u32.hi << 1))
31
#if LJ_GC64
32
#define hashgcref(t, r) \
33
  hashlohi((t), (uint32_t)gcrefu(r), (uint32_t)(gcrefu(r) >> 32))
34
#else
35
#define hashgcref(t, r)                hashlohi((t), gcrefu(r), gcrefu(r) + HASH_BIAS)
36
#endif
37

38
/* Hash an arbitrary key and return its anchor position in the hash table. */
39
static Node *hashkey(const GCtab *t, cTValue *key)
40
{
41
  lj_assertX(!tvisint(key), "attempt to hash integer");
42
  if (tvisstr(key))
43
    return hashstr(t, strV(key));
44
  else if (tvisnum(key))
45
    return hashnum(t, key);
46
  else if (tvisbool(key))
47
    return hashmask(t, boolV(key));
48
  else
49
    return hashgcref(t, key->gcr);
50
  /* Only hash 32 bits of lightuserdata on a 64 bit CPU. Good enough? */
51
}
52

53
/* -- Table creation and destruction -------------------------------------- */
54

55
/* Create new hash part for table. */
56
static LJ_AINLINE void newhpart(lua_State *L, GCtab *t, uint32_t hbits)
1,797,657✔
57
{
58
  uint32_t hsize;
1,797,657✔
59
  Node *node;
1,797,657✔
60
  lj_assertL(hbits != 0, "zero hash size");
1,797,657✔
61
  if (hbits > LJ_MAX_HBITS)
1,797,657✔
62
    lj_err_msg(L, LJ_ERR_TABOV);
3✔
63
  hsize = 1u << hbits;
1,797,654✔
64
  node = lj_mem_newvec(L, hsize, Node);
1,797,654✔
65
  setmref(t->node, node);
1,797,654✔
66
  setfreetop(t, node, &node[hsize]);
1,797,654✔
67
  t->hmask = hsize-1;
1,797,654✔
68
}
488,524✔
69

70
/*
71
** Q: Why all of these copies of t->hmask, t->node etc. to local variables?
72
** A: Because alias analysis for C is _really_ tough.
73
**    Even state-of-the-art C compilers won't produce good code without this.
74
*/
75

76
/* Clear hash part of table. */
77
static LJ_AINLINE void clearhpart(GCtab *t)
1,407,481✔
78
{
79
  uint32_t i, hmask = t->hmask;
1,407,481✔
80
  Node *node = noderef(t->node);
1,407,481✔
81
  lj_assertX(t->hmask != 0, "empty hash part");
1,407,481✔
82
  for (i = 0; i <= hmask; i++) {
609,687,789✔
83
    Node *n = &node[i];
608,280,308✔
84
    setmref(n->next, NULL);
608,280,308✔
85
    setnilV(&n->key);
608,280,308✔
86
    setnilV(&n->val);
608,280,308✔
87
  }
88
}
89

90
/* Clear array part of table. */
91
static LJ_AINLINE void clearapart(GCtab *t)
1,527,715✔
92
{
93
  uint32_t i, asize = t->asize;
1,527,715✔
94
  TValue *array = tvref(t->array);
1,527,715✔
95
  for (i = 0; i < asize; i++)
2,740,970✔
96
    setnilV(&array[i]);
1,213,255✔
97
}
98

99
/* Create a new table. Note: the slots are not initialized (yet). */
100
static GCtab *newtab(lua_State *L, uint32_t asize, uint32_t hbits)
1,979,218✔
101
{
102
  GCtab *t;
1,979,218✔
103
  /* First try to colocate the array part. */
104
  if (LJ_MAX_COLOSIZE != 0 && asize > 0 && asize <= LJ_MAX_COLOSIZE) {
1,979,218✔
105
    Node *nilnode;
308,580✔
106
    lj_assertL((sizeof(GCtab) & 7) == 0, "bad GCtab size");
308,580✔
107
    t = (GCtab *)lj_mem_newgco(L, sizetabcolo(asize));
308,580✔
108
    t->gct = ~LJ_TTAB;
308,580✔
109
    t->nomm = (uint8_t)~0;
308,580✔
110
    t->colo = (int8_t)asize;
308,580✔
111
    setmref(t->array, (TValue *)((char *)t + sizeof(GCtab)));
308,580✔
112
    setgcrefnull(t->metatable);
308,580✔
113
    t->asize = asize;
308,580✔
114
    t->hmask = 0;
308,580✔
115
    nilnode = &G(L)->nilnode;
308,580✔
116
    setmref(t->node, nilnode);
308,580✔
117
#if LJ_GC64
118
    setmref(t->freetop, nilnode);
308,580✔
119
#endif
120
  } else {  /* Otherwise separately allocate the array part. */
121
    Node *nilnode;
1,670,638✔
122
    t = lj_mem_newobj(L, GCtab);
1,670,638✔
123
    t->gct = ~LJ_TTAB;
1,670,638✔
124
    t->nomm = (uint8_t)~0;
1,670,638✔
125
    t->colo = 0;
1,670,638✔
126
    setmref(t->array, NULL);
1,670,638✔
127
    setgcrefnull(t->metatable);
1,670,638✔
128
    t->asize = 0;  /* In case the array allocation fails. */
1,670,638✔
129
    t->hmask = 0;
1,670,638✔
130
    nilnode = &G(L)->nilnode;
1,670,638✔
131
    setmref(t->node, nilnode);
1,670,638✔
132
#if LJ_GC64
133
    setmref(t->freetop, nilnode);
1,670,638✔
134
#endif
135
    if (asize > 0) {
1,670,638✔
136
      if (asize > LJ_MAX_ASIZE)
329✔
137
        lj_err_msg(L, LJ_ERR_TABOV);
×
138
      setmref(t->array, lj_mem_newvec(L, asize, TValue));
329✔
139
      t->asize = asize;
329✔
140
    }
141
  }
142
  if (hbits)
1,979,218✔
143
    newhpart(L, t, hbits);
488,524✔
144
  G(L)->gc.tabnum++;
1,979,218✔
145
  return t;
1,979,218✔
146
}
147

148
/* Create a new table.
149
**
150
** IMPORTANT NOTE: The API differs from lua_createtable()!
151
**
152
** The array size is non-inclusive. E.g. asize=128 creates array slots
153
** for 0..127, but not for 128. If you need slots 1..128, pass asize=129
154
** (slot 0 is wasted in this case).
155
**
156
** The hash size is given in hash bits. hbits=0 means no hash part.
157
** hbits=1 creates 2 hash slots, hbits=2 creates 4 hash slots and so on.
158
*/
159
GCtab *lj_tab_new(lua_State *L, uint32_t asize, uint32_t hbits)
1,267,292✔
160
{
161
  GCtab *t = newtab(L, asize, hbits);
1,267,292✔
162
  clearapart(t);
1,267,292✔
163
  if (t->hmask > 0) clearhpart(t);
1,267,292✔
164
  return t;
1,267,292✔
165
}
166

167
/* The API of this function conforms to lua_createtable(). */
168
GCtab *lj_tab_new_ah(lua_State *L, int32_t a, int32_t h)
1,093,342✔
169
{
170
  return lj_tab_new(L, (uint32_t)(a > 0 ? a+1 : 0), hsize2hbits(h));
1,093,342✔
171
}
172

173
#if LJ_HASJIT
174
GCtab * LJ_FASTCALL lj_tab_new1(lua_State *L, uint32_t ahsize)
260,374✔
175
{
176
  GCtab *t = newtab(L, ahsize & 0xffffff, ahsize >> 24);
260,374✔
177
  clearapart(t);
260,374✔
178
  if (t->hmask > 0) clearhpart(t);
260,374✔
179
  return t;
260,374✔
180
}
181
#endif
182

183
/* Duplicate a table. */
184
GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt)
451,552✔
185
{
186
  GCtab *t;
451,552✔
187
  uint32_t asize, hmask;
451,552✔
188
  t = newtab(L, kt->asize, kt->hmask > 0 ? lj_fls(kt->hmask)+1 : 0);
451,552✔
189
  lj_assertL(kt->asize == t->asize && kt->hmask == t->hmask,
451,552✔
190
             "mismatched size of table and template");
191
  t->nomm = 0;  /* Keys with metamethod names may be present. */
451,552✔
192
  asize = kt->asize;
451,552✔
193
  if (asize > 0) {
451,552✔
194
    TValue *array = tvref(t->array);
61,401✔
195
    TValue *karray = tvref(kt->array);
61,401✔
196
    if (asize < 64) {  /* An inlined loop beats memcpy for < 512 bytes. */
61,401✔
197
      uint32_t i;
198
      for (i = 0; i < asize; i++)
192,802✔
199
        copyTV(L, &array[i], &karray[i]);
131,502✔
200
    } else {
201
      memcpy(array, karray, asize*sizeof(TValue));
101✔
202
    }
203
  }
204
  hmask = kt->hmask;
451,552✔
205
  if (hmask > 0) {
451,552✔
206
    uint32_t i;
390,198✔
207
    Node *node = noderef(t->node);
390,198✔
208
    Node *knode = noderef(kt->node);
390,198✔
209
    ptrdiff_t d = (char *)node - (char *)knode;
390,198✔
210
    setfreetop(t, node, (Node *)((char *)getfreetop(kt, knode) + d));
390,198✔
211
    for (i = 0; i <= hmask; i++) {
1,525,366✔
212
      Node *kn = &knode[i];
1,135,168✔
213
      Node *n = &node[i];
1,135,168✔
214
      Node *next = nextnode(kn);
1,135,168✔
215
      /* Don't use copyTV here, since it asserts on a copy of a dead key. */
216
      n->val = kn->val; n->key = kn->key;
1,135,168✔
217
      setmref(n->next, next == NULL? next : (Node *)((char *)next + d));
1,135,168✔
218
    }
219
  }
220
  return t;
451,552✔
221
}
222

223
/* Clear a table. */
224
void LJ_FASTCALL lj_tab_clear(GCtab *t)
49✔
225
{
226
  clearapart(t);
49✔
227
  if (t->hmask > 0) {
49✔
228
    Node *node = noderef(t->node);
25✔
229
    setfreetop(t, node, &node[t->hmask+1]);
25✔
230
    clearhpart(t);
25✔
231
  }
232
}
49✔
233

234
/* Free a table. */
235
void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t)
1,978,717✔
236
{
237
  if (t->hmask > 0)
1,978,717✔
238
    lj_mem_freevec(g, noderef(t->node), t->hmask+1, Node);
1,564,777✔
239
  if (t->asize > 0 && LJ_MAX_COLOSIZE != 0 && t->colo <= 0)
1,978,717✔
240
    lj_mem_freevec(g, tvref(t->array), t->asize, TValue);
11,598✔
241
  if (LJ_MAX_COLOSIZE != 0 && t->colo)
1,978,717✔
242
    lj_mem_free(g, t, sizetabcolo((uint32_t)t->colo & 0x7f));
308,556✔
243
  else
244
    lj_mem_freet(g, t);
1,670,161✔
245
  g->gc.tabnum--;
1,978,717✔
246
}
1,978,717✔
247

248
/* -- Table resizing ------------------------------------------------------ */
249

250
/* Resize a table to fit the new array/hash part sizes. */
251
void lj_tab_resize(lua_State *L, GCtab *t, uint32_t asize, uint32_t hbits)
1,334,395✔
252
{
253
  Node *oldnode = noderef(t->node);
1,334,395✔
254
  uint32_t oldasize = t->asize;
1,334,395✔
255
  uint32_t oldhmask = t->hmask;
1,334,395✔
256
  if (asize > oldasize) {  /* Array part grows? */
1,334,395✔
257
    TValue *array;
27,624✔
258
    uint32_t i;
27,624✔
259
    if (asize > LJ_MAX_ASIZE)
27,624✔
260
      lj_err_msg(L, LJ_ERR_TABOV);
×
261
    if (LJ_MAX_COLOSIZE != 0 && t->colo > 0) {
27,624✔
262
      /* A colocated array must be separated and copied. */
263
      TValue *oarray = tvref(t->array);
2,077✔
264
      array = lj_mem_newvec(L, asize, TValue);
2,077✔
265
      t->colo = (int8_t)(t->colo | 0x80);  /* Mark as separated (colo < 0). */
2,077✔
266
      for (i = 0; i < oldasize; i++)
6,144✔
267
        copyTV(L, &array[i], &oarray[i]);
4,067✔
268
    } else {
269
      array = (TValue *)lj_mem_realloc(L, tvref(t->array),
25,547✔
270
                          oldasize*sizeof(TValue), asize*sizeof(TValue));
271
    }
272
    setmref(t->array, array);
27,624✔
273
    t->asize = asize;
27,624✔
274
    for (i = oldasize; i < asize; i++)  /* Clear newly allocated slots. */
135,119,254✔
275
      setnilV(&array[i]);
135,091,630✔
276
  }
277
  /* Create new (empty) hash part. */
278
  if (hbits) {
1,334,395✔
279
    newhpart(L, t, hbits);
1,309,133✔
280
    clearhpart(t);
1,309,130✔
281
  } else {
282
    global_State *g = G(L);
25,262✔
283
    setmref(t->node, &g->nilnode);
25,262✔
284
#if LJ_GC64
285
    setmref(t->freetop, &g->nilnode);
25,262✔
286
#endif
287
    t->hmask = 0;
25,262✔
288
  }
289
  if (asize < oldasize) {  /* Array part shrinks? */
1,334,392✔
290
    TValue *array = tvref(t->array);
40✔
291
    uint32_t i;
40✔
292
    t->asize = asize;  /* Note: This 'shrinks' even colocated arrays. */
40✔
293
    for (i = asize; i < oldasize; i++)  /* Reinsert old array values. */
17,223✔
294
      if (!tvisnil(&array[i]))
17,183✔
295
        copyTV(L, lj_tab_setinth(L, t, (int32_t)i), &array[i]);
17,183✔
296
    /* Physically shrink only separated arrays. */
297
    if (LJ_MAX_COLOSIZE != 0 && t->colo <= 0)
40✔
298
      setmref(t->array, lj_mem_realloc(L, array,
16✔
299
              oldasize*sizeof(TValue), asize*sizeof(TValue)));
300
  }
301
  if (oldhmask > 0) {  /* Reinsert pairs from old hash part. */
1,334,392✔
302
    global_State *g;
303
    uint32_t i;
304
    for (i = 0; i <= oldhmask; i++) {
205,963,257✔
305
      Node *n = &oldnode[i];
205,730,856✔
306
      if (!tvisnil(&n->val))
205,730,856✔
307
        copyTV(L, lj_tab_set(L, t, &n->key), &n->val);
205,730,856✔
308
    }
309
    g = G(L);
232,401✔
310
    lj_mem_freevec(g, oldnode, oldhmask+1, Node);
232,401✔
311
  }
312
}
1,334,392✔
313

314
static uint32_t countint(cTValue *key, uint32_t *bins)
315
{
316
  lj_assertX(!tvisint(key), "bad integer key");
317
  if (tvisnum(key)) {
318
    lua_Number nk = numV(key);
319
    int32_t k = lj_num2int(nk);
320
    if ((uint32_t)k < LJ_MAX_ASIZE && nk == (lua_Number)k) {
321
      bins[(k > 2 ? lj_fls((uint32_t)(k-1)) : 0)]++;
322
      return 1;
323
    }
324
  }
325
  return 0;
326
}
327

328
static uint32_t countarray(const GCtab *t, uint32_t *bins)
329
{
330
  uint32_t na, b, i;
331
  if (t->asize == 0) return 0;
332
  for (na = i = b = 0; b < LJ_MAX_ABITS; b++) {
333
    uint32_t n, top = 2u << b;
334
    TValue *array;
335
    if (top >= t->asize) {
336
      top = t->asize-1;
337
      if (i > top)
338
        break;
339
    }
340
    array = tvref(t->array);
341
    for (n = 0; i <= top; i++)
342
      if (!tvisnil(&array[i]))
343
        n++;
344
    bins[b] += n;
345
    na += n;
346
  }
347
  return na;
348
}
349

350
static uint32_t counthash(const GCtab *t, uint32_t *bins, uint32_t *narray)
351
{
352
  uint32_t total, na, i, hmask = t->hmask;
353
  Node *node = noderef(t->node);
354
  for (total = na = 0, i = 0; i <= hmask; i++) {
355
    Node *n = &node[i];
356
    if (!tvisnil(&n->val)) {
357
      na += countint(&n->key, bins);
358
      total++;
359
    }
360
  }
361
  *narray += na;
362
  return total;
363
}
364

365
static uint32_t bestasize(uint32_t bins[], uint32_t *narray)
1,334,183✔
366
{
367
  uint32_t b, sum, na = 0, sz = 0, nn = *narray;
1,334,183✔
368
  for (b = 0, sum = 0; 2*nn > (1u<<b) && sum != nn; b++)
1,399,855✔
369
    if (bins[b] > 0 && 2*(sum += bins[b]) > (1u<<b)) {
65,672✔
370
      sz = (2u<<b)+1;
60,764✔
371
      na = sum;
60,764✔
372
    }
373
  *narray = sz;
1,334,183✔
374
  return na;
1,334,183✔
375
}
376

377
static void rehashtab(lua_State *L, GCtab *t, cTValue *ek)
1,334,183✔
378
{
379
  uint32_t bins[LJ_MAX_ABITS];
1,334,183✔
380
  uint32_t total, asize, na, i;
1,334,183✔
381
  for (i = 0; i < LJ_MAX_ABITS; i++) bins[i] = 0;
38,691,307✔
382
  asize = countarray(t, bins);
1,334,183✔
383
  total = 1 + asize;
1,334,183✔
384
  total += counthash(t, bins, &asize);
1,334,183✔
385
  asize += countint(ek, bins);
1,334,183✔
386
  na = bestasize(bins, &asize);
1,334,183✔
387
  total -= na;
1,334,183✔
388
  lj_tab_resize(L, t, asize, hsize2hbits(total));
1,334,183✔
389
}
1,334,180✔
390

391
void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize)
212✔
392
{
393
  lj_tab_resize(L, t, nasize+1, t->hmask > 0 ? lj_fls(t->hmask)+1 : 0);
212✔
394
}
212✔
395

396
/* -- Table getters ------------------------------------------------------- */
397

398
cTValue * LJ_FASTCALL lj_tab_getinth(GCtab *t, int32_t key)
67,353,581✔
399
{
400
  TValue k;
67,353,581✔
401
  Node *n;
67,353,581✔
402
  k.n = (lua_Number)key;
67,353,581✔
403
  n = hashnum(t, &k);
67,353,581✔
404
  do {
148,160,611✔
405
    if (tvisnum(&n->key) && n->key.n == k.n)
148,160,611✔
406
      return &n->val;
230,555✔
407
  } while ((n = nextnode(n)));
147,930,056✔
408
  return NULL;
409
}
410

411
cTValue *lj_tab_getstr(GCtab *t, GCstr *key)
7,926,080✔
412
{
413
  Node *n = hashstr(t, key);
5,435,276✔
414
  do {
8,683,954✔
415
    if (tvisstr(&n->key) && strV(&n->key) == key)
8,683,954✔
416
      return &n->val;
7,382,828✔
417
  } while ((n = nextnode(n)));
1,301,126✔
418
  return NULL;
419
}
420

421
cTValue *lj_tab_get(lua_State *L, GCtab *t, cTValue *key)
74,150,526✔
422
{
423
  if (tvisstr(key)) {
74,150,526✔
424
    cTValue *tv = lj_tab_getstr(t, strV(key));
2,490,804✔
425
    if (tv)
2,490,804✔
426
      return tv;
427
  } else if (tvisint(key)) {
71,659,722✔
428
    cTValue *tv = lj_tab_getint(t, intV(key));
429
    if (tv)
430
      return tv;
431
  } else if (tvisnum(key)) {
71,659,722✔
432
    lua_Number nk = numV(key);
71,656,550✔
433
    int32_t k = lj_num2int(nk);
71,656,550✔
434
    if (nk == (lua_Number)k) {
71,656,550✔
435
      cTValue *tv = lj_tab_getint(t, k);
67,330,426✔
436
      if (tv)
67,330,426✔
437
        return tv;
438
    } else {
439
      goto genlookup;  /* Else use the generic lookup. */
4,326,124✔
440
    }
441
  } else if (!tvisnil(key)) {
3,172✔
442
    Node *n;
4,329,292✔
443
  genlookup:
3,168✔
444
    n = hashkey(t, key);
4,329,292✔
445
    do {
4,384,730✔
446
      if (lj_obj_equal(&n->key, key))
4,384,730✔
447
        return &n->val;
4,301,591✔
448
    } while ((n = nextnode(n)));
83,139✔
449
  }
450
  return niltv(L);
67,665,385✔
451
}
452

453
/* -- Table setters ------------------------------------------------------- */
454

455
/* Insert new key. Use Brent's variation to optimize the chain length. */
456
TValue *lj_tab_newkey(lua_State *L, GCtab *t, cTValue *key)
411,419,112✔
457
{
458
  Node *n = hashkey(t, key);
411,419,112✔
459
  if (!tvisnil(&n->val) || t->hmask == 0) {
411,419,112✔
460
    Node *nodebase = noderef(t->node);
190,661,844✔
461
    Node *collide, *freenode = getfreetop(t, nodebase);
190,661,844✔
462
    lj_assertL(freenode >= nodebase && freenode <= nodebase+t->hmask+1,
409,167,316✔
463
               "bad freenode");
464
    do {
409,167,316✔
465
      if (freenode == nodebase) {  /* No free node found? */
409,167,316✔
466
        rehashtab(L, t, key);  /* Rehash table. */
1,334,183✔
467
        return lj_tab_set(L, t, key);  /* Retry key insertion. */
1,334,180✔
468
      }
469
    } while (!tvisnil(&(--freenode)->key));
407,833,133✔
470
    setfreetop(t, nodebase, freenode);
189,327,661✔
471
    lj_assertL(freenode != &G(L)->nilnode, "store to fallback hash");
189,327,661✔
472
    collide = hashkey(t, &n->key);
189,327,661✔
473
    if (collide != n) {  /* Colliding node not the main node? */
189,327,661✔
474
      Node *nn;
475
      while (noderef(collide->next) != n)  /* Find predecessor. */
59,755,805✔
476
        collide = nextnode(collide);
477
      setmref(collide->next, freenode);  /* Relink chain. */
43,320,310✔
478
      /* Copy colliding node into free node and free main node. */
479
      freenode->val = n->val;
43,320,310✔
480
      freenode->key = n->key;
43,320,310✔
481
      freenode->next = n->next;
43,320,310✔
482
      setmref(n->next, NULL);
43,320,310✔
483
      setnilV(&n->val);
43,320,310✔
484
      /*
485
      ** Nodes after n might have n as their main node, and need rechaining
486
      ** back onto n. We make use of the following property of tables: for all
487
      ** nodes m, at least one of the following four statements is true:
488
      **  1. tvisnil(&m->key)  NB: tvisnil(&m->val) is a stronger statement
489
      **  2. tvisstr(&m->key)
490
      **  3. tvisstr(&main(m)->key)
491
      **  4. main(m) == main(main(m))
492
      ** Initially, we need to rechain any nn which has main(nn) == n. As
493
      ** main(n) != n (because collide != n earlier), main(nn) == n requires
494
      ** either statement 2 or statement 3 to be true about nn.
495
      */
496
      if (!tvisstr(&n->key)) {
43,320,310✔
497
        /* Statement 3 is not true, so only need to consider string keys. */
498
        while ((nn = nextnode(freenode))) {
58,962,396✔
499
          if (tvisstr(&nn->key) && !tvisnil(&nn->val) &&
15,921,200✔
500
              hashstr(t, strV(&nn->key)) == n) {
1,896✔
501
            goto rechain;
3✔
502
          }
503
          freenode = nn;
504
        }
505
      } else {
506
        /* Statement 3 is true, so need to consider all types of key. */
507
        while ((nn = nextnode(freenode))) {
318,801✔
508
          if (!tvisnil(&nn->val) && hashkey(t, &nn->key) == n) {
39,695✔
509
          rechain:
5✔
510
            freenode->next = nn->next;
8✔
511
            nn->next = n->next;
8✔
512
            setmref(n->next, nn);
8✔
513
            /*
514
            ** Rechaining one node onto n creates a new dilemma: we now need
515
            ** to rechain any nn which has main(nn) == n OR has main(nn) equal
516
            ** to any node which has already been rechained. Furthermore, at
517
            ** least one of n and n->next will have a string key, so all types
518
            ** of nn key need to be considered. Rather than testing whether
519
            ** main(nn) definitely _is_ in the new chain, we test whether it
520
            ** might _not_ be in the old chain, and if so re-link it into
521
            ** the correct chain.
522
            */
523
            while ((nn = nextnode(freenode))) {
12✔
524
              if (!tvisnil(&nn->val)) {
4✔
525
                Node *mn = hashkey(t, &nn->key);
4✔
526
                if (mn != freenode && mn != nn) {
4✔
527
                  freenode->next = nn->next;
1✔
528
                  nn->next = mn->next;
1✔
529
                  setmref(mn->next, nn);
1✔
530
                } else {
531
                  freenode = nn;
532
                }
533
              } else {
534
                freenode = nn;
535
              }
536
            }
537
            break;
538
          } else {
539
            freenode = nn;
540
          }
541
        }
542
      }
543
    } else {  /* Otherwise use free node. */
544
      setmrefr(freenode->next, n->next);  /* Insert into chain. */
146,007,351✔
545
      setmref(n->next, freenode);
146,007,351✔
546
      n = freenode;
146,007,351✔
547
    }
548
  }
549
  n->key.u64 = key->u64;
410,084,929✔
550
  if (LJ_UNLIKELY(tvismzero(&n->key)))
410,084,929✔
551
    n->key.u64 = 0;
6✔
552
  lj_gc_anybarriert(L, t);
410,084,929✔
553
  lj_assertL(tvisnil(&n->val), "new hash slot is not empty");
410,084,929✔
554
  return &n->val;
410,084,929✔
555
}
556

557
TValue *lj_tab_setinth(lua_State *L, GCtab *t, int32_t key)
67,268,185✔
558
{
559
  TValue k;
67,268,185✔
560
  Node *n;
67,268,185✔
561
  k.n = (lua_Number)key;
67,268,185✔
562
  n = hashnum(t, &k);
67,268,185✔
563
  do {
92,687,376✔
564
    if (tvisnum(&n->key) && n->key.n == k.n)
92,687,376✔
565
      return &n->val;
1,466✔
566
  } while ((n = nextnode(n)));
92,685,910✔
567
  return lj_tab_newkey(L, t, &k);
67,266,719✔
568
}
569

570
TValue *lj_tab_setstr(lua_State *L, GCtab *t, GCstr *key)
7,398,581✔
571
{
572
  TValue k;
7,398,581✔
573
  Node *n = hashstr(t, key);
7,398,581✔
574
  do {
8,762,567✔
575
    if (tvisstr(&n->key) && strV(&n->key) == key)
8,762,567✔
576
      return &n->val;
2,975,205✔
577
  } while ((n = nextnode(n)));
5,787,362✔
578
  setstrV(L, &k, key);
4,423,376✔
579
  return lj_tab_newkey(L, t, &k);
4,423,376✔
580
}
581

582
TValue *lj_tab_set(lua_State *L, GCtab *t, cTValue *key)
409,867,049✔
583
{
584
  Node *n;
409,867,049✔
585
  t->nomm = 0;  /* Invalidate negative metamethod cache. */
409,867,049✔
586
  if (tvisstr(key)) {
409,867,049✔
587
    return lj_tab_setstr(L, t, strV(key));
4,129,712✔
588
  } else if (tvisint(key)) {
405,737,337✔
589
    return lj_tab_setint(L, t, intV(key));
590
  } else if (tvisnum(key)) {
405,737,337✔
591
    lua_Number nk = numV(key);
67,846,209✔
592
    int32_t k = lj_num2int(nk);
67,846,209✔
593
    if (nk == (lua_Number)k)
67,846,209✔
594
      return lj_tab_setint(L, t, k);
67,410,732✔
595
    if (tvisnan(key))
435,477✔
596
      lj_err_msg(L, LJ_ERR_NANIDX);
×
597
    /* Else use the generic lookup. */
598
  } else if (tvisnil(key)) {
337,891,128✔
599
    lj_err_msg(L, LJ_ERR_NILIDX);
1✔
600
  }
601
  n = hashkey(t, key);
338,326,604✔
602
  do {
447,986,148✔
603
    if (lj_obj_equal(&n->key, key))
447,986,148✔
604
      return &n->val;
134,307,032✔
605
  } while ((n = nextnode(n)));
313,679,116✔
606
  return lj_tab_newkey(L, t, key);
204,019,572✔
607
}
608

609
/* -- Table traversal ----------------------------------------------------- */
610

611
/* Get the traversal index of a key. */
612
static uint32_t keyindex(lua_State *L, GCtab *t, cTValue *key)
95,815✔
613
{
614
  TValue tmp;
95,815✔
615
  if (tvisint(key)) {
95,815✔
616
    int32_t k = intV(key);
617
    if ((uint32_t)k < t->asize)
618
      return (uint32_t)k;  /* Array key indexes: [0..t->asize-1] */
619
    setnumV(&tmp, (lua_Number)k);
620
    key = &tmp;
621
  } else if (tvisnum(key)) {
95,815✔
622
    lua_Number nk = numV(key);
50,138✔
623
    int32_t k = lj_num2int(nk);
50,138✔
624
    if ((uint32_t)k < t->asize && nk == (lua_Number)k)
50,138✔
625
      return (uint32_t)k;  /* Array key indexes: [0..t->asize-1] */
626
  }
627
  if (!tvisnil(key)) {
45,785✔
628
    Node *n = hashkey(t, key);
45,379✔
629
    do {
50,945✔
630
      if (lj_obj_equal(&n->key, key))
50,945✔
631
        return t->asize + (uint32_t)(n - noderef(t->node));
45,374✔
632
        /* Hash key indexes: [t->asize..t->asize+t->nmask] */
633
    } while ((n = nextnode(n)));
5,571✔
634
    if (key->u32.hi == 0xfffe7fff)  /* ITERN was despecialized while running. */
5✔
635
      return key->u32.lo - 1;
2✔
636
    lj_err_msg(L, LJ_ERR_NEXTIDX);
3✔
637
    return 0;  /* unreachable */
638
  }
639
  return ~0u;  /* A nil key starts the traversal. */
640
}
641

642
/* Advance to the next step in a table traversal. */
643
int lj_tab_next(lua_State *L, GCtab *t, TValue *key)
95,815✔
644
{
645
  uint32_t i = keyindex(L, t, key);  /* Find predecessor key index. */
95,815✔
646
  for (i++; i < t->asize; i++)  /* First traverse the array keys. */
160,645✔
647
    if (!tvisnil(arrayslot(t, i))) {
114,866✔
648
      setintV(key, i);
50,033✔
649
      copyTV(L, key+1, arrayslot(t, i));
50,033✔
650
      return 1;
50,033✔
651
    }
652
  for (i -= t->asize; i <= t->hmask; i++) {  /* Then traverse the hash keys. */
90,559✔
653
    Node *n = &noderef(t->node)[i];
90,459✔
654
    if (!tvisnil(&n->val)) {
90,459✔
655
      copyTV(L, key, &n->key);
45,679✔
656
      copyTV(L, key+1, &n->val);
45,679✔
657
      return 1;
45,679✔
658
    }
659
  }
660
  return 0;  /* End of traversal. */
661
}
662

663
/* -- Table length calculation -------------------------------------------- */
664

665
static MSize unbound_search(GCtab *t, MSize j)
140✔
666
{
667
  cTValue *tv;
140✔
668
  MSize i = j;  /* i is zero or a present index */
140✔
669
  j++;
140✔
670
  /* find `i' and `j' such that i is present and j is not */
671
  while ((tv = lj_tab_getint(t, (int32_t)j)) && !tvisnil(tv)) {
608✔
672
    i = j;
468✔
673
    j *= 2;
468✔
674
    if (j > (MSize)(INT_MAX-2)) {  /* overflow? */
468✔
675
      /* table was built with bad purposes: resort to linear search */
676
      i = 1;
677
      while ((tv = lj_tab_getint(t, (int32_t)i)) && !tvisnil(tv)) i++;
×
678
      return i - 1;
×
679
    }
680
  }
681
  /* now do a binary search between them */
682
  while (j - i > 1) {
516✔
683
    MSize m = (i+j)/2;
376✔
684
    cTValue *tvb = lj_tab_getint(t, (int32_t)m);
376✔
685
    if (tvb && !tvisnil(tvb)) i = m; else j = m;
376✔
686
  }
687
  return i;
688
}
689

690
/*
691
** Try to find a boundary in table `t'. A `boundary' is an integer index
692
** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
693
*/
694
MSize LJ_FASTCALL lj_tab_len(GCtab *t)
50,450✔
695
{
696
  MSize j = (MSize)t->asize;
50,450✔
697
  if (j > 1 && tvisnil(arrayslot(t, j-1))) {
50,450✔
698
    MSize i = 1;
699
    while (j - i > 1) {
428,491✔
700
      MSize m = (i+j)/2;
379,453✔
701
      if (tvisnil(arrayslot(t, m-1))) j = m; else i = m;
428,491✔
702
    }
703
    return i-1;
49,038✔
704
  }
705
  if (j) j--;
1,412✔
706
  if (t->hmask <= 0)
1,412✔
707
    return j;
708
  return unbound_search(t, j);
140✔
709
}
710

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