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

tarantool / luajit / 12298038079

12 Dec 2024 01:33PM UTC coverage: 92.888% (-0.003%) from 92.891%
12298038079

push

github

Buristan
test: skip <string/dump.lua> test for table bump

If the `foo()` function itself starts to be recorded on the very first
call, it leads to the changing of TNEW bytecode when table bump
optimization is enabled. This patch skips the test for this type of
build.

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

5673 of 6014 branches covered (94.33%)

Branch coverage included in aggregate %.

21609 of 23357 relevant lines covered (92.52%)

868792.21 hits per line

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

93.09
/src/lj_ir.c
1
/*
2
** SSA IR (Intermediate Representation) emitter.
3
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
4
*/
5

6
#define lj_ir_c
7
#define LUA_CORE
8

9
/* For pointers to libc/libm functions. */
10
#include <stdio.h>
11
#include <math.h>
12

13
#include "lj_obj.h"
14

15
#if LJ_HASJIT
16

17
#include "lj_gc.h"
18
#include "lj_buf.h"
19
#include "lj_str.h"
20
#include "lj_tab.h"
21
#include "lj_ir.h"
22
#include "lj_jit.h"
23
#include "lj_ircall.h"
24
#include "lj_iropt.h"
25
#include "lj_trace.h"
26
#if LJ_HASFFI
27
#include "lj_ctype.h"
28
#include "lj_cdata.h"
29
#include "lj_carith.h"
30
#endif
31
#include "lj_vm.h"
32
#include "lj_strscan.h"
33
#include "lj_strfmt.h"
34
#include "lj_lib.h"
35

36
/* Some local macros to save typing. Undef'd at the end. */
37
#define IR(ref)                        (&J->cur.ir[(ref)])
38
#define fins                        (&J->fold.ins)
39

40
/* Pass IR on to next optimization in chain (FOLD). */
41
#define emitir(ot, a, b)        (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
42

43
/* -- IR tables ----------------------------------------------------------- */
44

45
/* IR instruction modes. */
46
LJ_DATADEF const uint8_t lj_ir_mode[IR__MAX+1] = {
47
IRDEF(IRMODE)
48
  0
49
};
50

51
/* IR type sizes. */
52
LJ_DATADEF const uint8_t lj_ir_type_size[IRT__MAX+1] = {
53
#define IRTSIZE(name, size)        size,
54
IRTDEF(IRTSIZE)
55
#undef IRTSIZE
56
  0
57
};
58

59
/* C call info for CALL* instructions. */
60
LJ_DATADEF const CCallInfo lj_ir_callinfo[] = {
61
#define IRCALLCI(cond, name, nargs, kind, type, flags) \
62
  { (ASMFunction)IRCALLCOND_##cond(name), \
63
    (nargs)|(CCI_CALL_##kind)|(IRT_##type<<CCI_OTSHIFT)|(flags) },
64
IRCALLDEF(IRCALLCI)
65
#undef IRCALLCI
66
  { NULL, 0 }
67
};
68

69
/* -- IR emitter ---------------------------------------------------------- */
70

71
/* Grow IR buffer at the top. */
72
void LJ_FASTCALL lj_ir_growtop(jit_State *J)
224✔
73
{
74
  IRIns *baseir = J->irbuf + J->irbotlim;
224✔
75
  MSize szins = J->irtoplim - J->irbotlim;
224✔
76
  if (szins) {
224✔
77
    baseir = (IRIns *)lj_mem_realloc(J->L, baseir, szins*sizeof(IRIns),
171✔
78
                                     2*szins*sizeof(IRIns));
86✔
79
    J->irtoplim = J->irbotlim + 2*szins;
85✔
80
  } else {
81
    baseir = (IRIns *)lj_mem_realloc(J->L, NULL, 0, LJ_MIN_IRSZ*sizeof(IRIns));
138✔
82
    J->irbotlim = REF_BASE - LJ_MIN_IRSZ/4;
138✔
83
    J->irtoplim = J->irbotlim + LJ_MIN_IRSZ;
138✔
84
  }
85
  J->cur.ir = J->irbuf = baseir - J->irbotlim;
223✔
86
}
223✔
87

88
/* Grow IR buffer at the bottom or shift it up. */
89
static void lj_ir_growbot(jit_State *J)
342✔
90
{
91
  IRIns *baseir = J->irbuf + J->irbotlim;
342✔
92
  MSize szins = J->irtoplim - J->irbotlim;
342✔
93
  lj_assertJ(szins != 0, "zero IR size");
342✔
94
  lj_assertJ(J->cur.nk == J->irbotlim || J->cur.nk-1 == J->irbotlim,
342✔
95
             "unexpected IR growth");
96
  if (J->cur.nins + (szins >> 1) < J->irtoplim) {
342✔
97
    /* More than half of the buffer is free on top: shift up by a quarter. */
98
    MSize ofs = szins >> 2;
89✔
99
    memmove(baseir + ofs, baseir, (J->cur.nins - J->irbotlim)*sizeof(IRIns));
89✔
100
    J->irbotlim -= ofs;
89✔
101
    J->irtoplim -= ofs;
89✔
102
    J->cur.ir = J->irbuf = baseir - J->irbotlim;
89✔
103
  } else {
104
    /* Double the buffer size, but split the growth amongst top/bottom. */
105
    IRIns *newbase = lj_mem_newt(J->L, 2*szins*sizeof(IRIns), IRIns);
253✔
106
    MSize ofs = szins >= 256 ? 128 : (szins >> 1);  /* Limit bottom growth. */
253✔
107
    memcpy(newbase + ofs, baseir, (J->cur.nins - J->irbotlim)*sizeof(IRIns));
253✔
108
    lj_mem_free(G(J->L), baseir, szins*sizeof(IRIns));
253✔
109
    J->irbotlim -= ofs;
253✔
110
    J->irtoplim = J->irbotlim + 2*szins;
253✔
111
    J->cur.ir = J->irbuf = newbase - J->irbotlim;
253✔
112
  }
113
}
342✔
114

115
/* Emit IR without any optimizations. */
116
TRef LJ_FASTCALL lj_ir_emit(jit_State *J)
1,522,360✔
117
{
118
  IRRef ref = lj_ir_nextins(J);
1,522,360✔
119
  IRIns *ir = IR(ref);
1,522,360✔
120
  IROp op = fins->o;
1,522,360✔
121
  ir->prev = J->chain[op];
1,522,360✔
122
  J->chain[op] = (IRRef1)ref;
1,522,360✔
123
  ir->o = op;
1,522,360✔
124
  ir->op1 = fins->op1;
1,522,360✔
125
  ir->op2 = fins->op2;
1,522,360✔
126
  J->guardemit.irt |= fins->t.irt;
1,522,360✔
127
  return TREF(ref, irt_t((ir->t = fins->t)));
1,522,360✔
128
}
129

130
/* Emit call to a C function. */
131
TRef lj_ir_call(jit_State *J, IRCallID id, ...)
616✔
132
{
133
  const CCallInfo *ci = &lj_ir_callinfo[id];
616✔
134
  uint32_t n = CCI_NARGS(ci);
616✔
135
  TRef tr = TREF_NIL;
616✔
136
  va_list argp;
616✔
137
  va_start(argp, id);
616✔
138
  if ((ci->flags & CCI_L)) n--;
616✔
139
  if (n > 0)
616✔
140
    tr = va_arg(argp, IRRef);
615✔
141
  while (n-- > 1)
1,821✔
142
    tr = emitir(IRT(IR_CARG, IRT_NIL), tr, va_arg(argp, IRRef));
1,205✔
143
  va_end(argp);
616✔
144
  if (CCI_OP(ci) == IR_CALLS)
616✔
145
    J->needsnap = 1;  /* Need snapshot after call with side effect. */
183✔
146
  return emitir(CCI_OPTYPE(ci), tr, id);
616✔
147
}
148

149
/* Load field of type t from GG_State + offset. Must be 32 bit aligned. */
150
LJ_FUNC TRef lj_ir_ggfload(jit_State *J, IRType t, uintptr_t ofs)
514✔
151
{
152
  lj_assertJ((ofs & 3) == 0, "unaligned GG_State field offset");
514✔
153
  ofs >>= 2;
514✔
154
  lj_assertJ(ofs >= IRFL__MAX && ofs <= 0x3ff,
514✔
155
             "GG_State field offset breaks 10 bit FOLD key limit");
156
  lj_ir_set(J, IRT(IR_FLOAD, t), REF_NIL, ofs);
514✔
157
  return lj_opt_fold(J);
514✔
158
}
159

160
/* -- Interning of constants ---------------------------------------------- */
161

162
/*
163
** IR instructions for constants are kept between J->cur.nk >= ref < REF_BIAS.
164
** They are chained like all other instructions, but grow downwards.
165
** The are interned (like strings in the VM) to facilitate reference
166
** comparisons. The same constant must get the same reference.
167
*/
168

169
/* Get ref of next IR constant and optionally grow IR.
170
** Note: this may invalidate all IRIns *!
171
*/
172
static LJ_AINLINE IRRef ir_nextk(jit_State *J)
300,027✔
173
{
174
  IRRef ref = J->cur.nk;
300,027✔
175
  if (LJ_UNLIKELY(ref <= J->irbotlim)) lj_ir_growbot(J);
95✔
176
  J->cur.nk = --ref;
300,027✔
177
  return ref;
300,027✔
178
}
179

180
/* Get ref of next 64 bit IR constant and optionally grow IR.
181
** Note: this may invalidate all IRIns *!
182
*/
183
static LJ_AINLINE IRRef ir_nextk64(jit_State *J)
672,673✔
184
{
185
  IRRef ref = J->cur.nk - 2;
672,673✔
186
  lj_assertJ(J->state != LJ_TRACE_ASM, "bad JIT state");
672,673✔
187
  if (LJ_UNLIKELY(ref < J->irbotlim)) lj_ir_growbot(J);
247✔
188
  J->cur.nk = ref;
672,673✔
189
  return ref;
672,673✔
190
}
191

192
#if LJ_GC64
193
#define ir_nextkgc ir_nextk64
194
#else
195
#define ir_nextkgc ir_nextk
196
#endif
197

198
/* Intern int32_t constant. */
199
TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k)
1,581,558✔
200
{
201
  IRIns *ir, *cir = J->cur.ir;
1,581,558✔
202
  IRRef ref;
1,581,558✔
203
  for (ref = J->chain[IR_KINT]; ref; ref = cir[ref].prev)
7,035,683✔
204
    if (cir[ref].i == k)
6,905,765✔
205
      goto found;
1,451,640✔
206
  ref = ir_nextk(J);
129,918✔
207
  ir = IR(ref);
129,918✔
208
  ir->i = k;
129,918✔
209
  ir->t.irt = IRT_INT;
129,918✔
210
  ir->o = IR_KINT;
129,918✔
211
  ir->prev = J->chain[IR_KINT];
129,918✔
212
  J->chain[IR_KINT] = (IRRef1)ref;
129,918✔
213
found:
1,581,558✔
214
  return TREF(ref, IRT_INT);
1,581,558✔
215
}
216

217
/* Intern 64 bit constant, given by its 64 bit pattern. */
218
TRef lj_ir_k64(jit_State *J, IROp op, uint64_t u64)
934,652✔
219
{
220
  IRIns *ir, *cir = J->cur.ir;
934,652✔
221
  IRRef ref;
934,652✔
222
  IRType t = op == IR_KNUM ? IRT_NUM : IRT_I64;
934,652✔
223
  for (ref = J->chain[op]; ref; ref = cir[ref].prev)
7,207,357✔
224
    if (ir_k64(&cir[ref])->u64 == u64)
6,974,331✔
225
      goto found;
701,626✔
226
  ref = ir_nextk64(J);
233,026✔
227
  ir = IR(ref);
233,026✔
228
  ir[1].tv.u64 = u64;
233,026✔
229
  ir->t.irt = t;
233,026✔
230
  ir->o = op;
233,026✔
231
  ir->op12 = 0;
233,026✔
232
  ir->prev = J->chain[op];
233,026✔
233
  J->chain[op] = (IRRef1)ref;
233,026✔
234
found:
934,652✔
235
  return TREF(ref, t);
934,652✔
236
}
237

238
/* Intern FP constant, given by its 64 bit pattern. */
239
TRef lj_ir_knum_u64(jit_State *J, uint64_t u64)
275,788✔
240
{
241
  return lj_ir_k64(J, IR_KNUM, u64);
275,788✔
242
}
243

244
/* Intern 64 bit integer constant. */
245
TRef lj_ir_kint64(jit_State *J, uint64_t u64)
97,955✔
246
{
247
  return lj_ir_k64(J, IR_KINT64, u64);
97,955✔
248
}
249

250
/* Check whether a number is int and return it. -0 is NOT considered an int. */
251
static int numistrueint(lua_Number n, int32_t *kp)
182,573✔
252
{
253
  int32_t k = lj_num2int(n);
182,573✔
254
  if (n == (lua_Number)k) {
182,573✔
255
    if (kp) *kp = k;
180,496✔
256
    if (k == 0) {  /* Special check for -0. */
180,496✔
257
      TValue tv;
25,460✔
258
      setnumV(&tv, n);
25,460✔
259
      if (tv.u32.hi != 0)
25,460✔
260
        return 0;
261
    }
262
    return 1;
180,496✔
263
  }
264
  return 0;
265
}
266

267
/* Intern number as int32_t constant if possible, otherwise as FP constant. */
268
TRef lj_ir_knumint(jit_State *J, lua_Number n)
182,573✔
269
{
270
  int32_t k;
182,573✔
271
  if (numistrueint(n, &k))
182,573✔
272
    return lj_ir_kint(J, k);
180,496✔
273
  else
274
    return lj_ir_knum(J, n);
2,077✔
275
}
276

277
/* Intern GC object "constant". */
278
TRef lj_ir_kgc(jit_State *J, GCobj *o, IRType t)
2,778,368✔
279
{
280
  IRIns *ir, *cir = J->cur.ir;
2,778,368✔
281
  IRRef ref;
2,778,368✔
282
  lj_assertJ(!isdead(J2G(J), o), "interning of dead GC object");
2,778,368✔
283
  for (ref = J->chain[IR_KGC]; ref; ref = cir[ref].prev)
24,798,168✔
284
    if (ir_kgc(&cir[ref]) == o)
24,411,547✔
285
      goto found;
2,391,747✔
286
  ref = ir_nextkgc(J);
386,621✔
287
  ir = IR(ref);
386,621✔
288
  /* NOBARRIER: Current trace is a GC root. */
289
  ir->op12 = 0;
386,621✔
290
  setgcref(ir[LJ_GC64].gcr, o);
386,621✔
291
  ir->t.irt = (uint8_t)t;
386,621✔
292
  ir->o = IR_KGC;
386,621✔
293
  ir->prev = J->chain[IR_KGC];
386,621✔
294
  J->chain[IR_KGC] = (IRRef1)ref;
386,621✔
295
found:
2,778,368✔
296
  return TREF(ref, t);
2,778,368✔
297
}
298

299
/* Allocate GCtrace constant placeholder (no interning). */
300
TRef lj_ir_ktrace(jit_State *J)
261✔
301
{
302
  IRRef ref = ir_nextkgc(J);
261✔
303
  IRIns *ir = IR(ref);
261✔
304
  lj_assertJ(irt_toitype_(IRT_P64) == LJ_TTRACE, "mismatched type mapping");
261✔
305
  ir->t.irt = IRT_P64;
261✔
306
  ir->o = LJ_GC64 ? IR_KNUM : IR_KNULL;  /* Not IR_KGC yet, but same size. */
261✔
307
  ir->op12 = 0;
261✔
308
  ir->prev = 0;
261✔
309
  return TREF(ref, IRT_P64);
261✔
310
}
311

312
/* Intern pointer constant. */
313
TRef lj_ir_kptr_(jit_State *J, IROp op, void *ptr)
132,465✔
314
{
315
  IRIns *ir, *cir = J->cur.ir;
132,465✔
316
  IRRef ref;
132,465✔
317
#if LJ_64 && !LJ_GC64
318
  lj_assertJ((void *)(uintptr_t)u32ptr(ptr) == ptr, "out-of-range GC pointer");
319
#endif
320
  for (ref = J->chain[op]; ref; ref = cir[ref].prev)
244,580✔
321
    if (ir_kptr(&cir[ref]) == ptr)
191,815✔
322
      goto found;
79,700✔
323
#if LJ_GC64
324
  ref = ir_nextk64(J);
52,765✔
325
#else
326
  ref = ir_nextk(J);
327
#endif
328
  ir = IR(ref);
52,765✔
329
  ir->op12 = 0;
52,765✔
330
  setmref(ir[LJ_GC64].ptr, ptr);
52,765✔
331
  ir->t.irt = IRT_PGC;
52,765✔
332
  ir->o = op;
52,765✔
333
  ir->prev = J->chain[op];
52,765✔
334
  J->chain[op] = (IRRef1)ref;
52,765✔
335
found:
132,465✔
336
  return TREF(ref, IRT_PGC);
132,465✔
337
}
338

339
/* Intern typed NULL constant. */
340
TRef lj_ir_knull(jit_State *J, IRType t)
228,847✔
341
{
342
  IRIns *ir, *cir = J->cur.ir;
228,847✔
343
  IRRef ref;
228,847✔
344
  for (ref = J->chain[IR_KNULL]; ref; ref = cir[ref].prev)
228,943✔
345
    if (irt_t(cir[ref].t) == t)
217,006✔
346
      goto found;
216,910✔
347
  ref = ir_nextk(J);
11,937✔
348
  ir = IR(ref);
11,937✔
349
  ir->i = 0;
11,937✔
350
  ir->t.irt = (uint8_t)t;
11,937✔
351
  ir->o = IR_KNULL;
11,937✔
352
  ir->prev = J->chain[IR_KNULL];
11,937✔
353
  J->chain[IR_KNULL] = (IRRef1)ref;
11,937✔
354
found:
228,847✔
355
  return TREF(ref, t);
228,847✔
356
}
357

358
/* Intern key slot. */
359
TRef lj_ir_kslot(jit_State *J, TRef key, IRRef slot)
1,000,624✔
360
{
361
  IRIns *ir, *cir = J->cur.ir;
1,000,624✔
362
  IRRef2 op12 = IRREF2((IRRef1)key, (IRRef1)slot);
1,000,624✔
363
  IRRef ref;
1,000,624✔
364
  /* Const part is not touched by CSE/DCE, so 0-65535 is ok for IRMlit here. */
365
  lj_assertJ(tref_isk(key) && slot == (IRRef)(IRRef1)slot,
1,000,624✔
366
             "out-of-range key/slot");
367
  for (ref = J->chain[IR_KSLOT]; ref; ref = cir[ref].prev)
4,629,721✔
368
    if (cir[ref].op12 == op12)
4,471,549✔
369
      goto found;
842,452✔
370
  ref = ir_nextk(J);
158,172✔
371
  ir = IR(ref);
158,172✔
372
  ir->op12 = op12;
158,172✔
373
  ir->t.irt = IRT_P32;
158,172✔
374
  ir->o = IR_KSLOT;
158,172✔
375
  ir->prev = J->chain[IR_KSLOT];
158,172✔
376
  J->chain[IR_KSLOT] = (IRRef1)ref;
158,172✔
377
found:
1,000,624✔
378
  return TREF(ref, IRT_P32);
1,000,624✔
379
}
380

381
/* -- Access to IR constants ---------------------------------------------- */
382

383
/* Copy value of IR constant. */
384
void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir)
379,666✔
385
{
386
  UNUSED(L);
379,666✔
387
  lj_assertL(ir->o != IR_KSLOT, "unexpected KSLOT");  /* Common mistake. */
379,666✔
388
  switch (ir->o) {
379,666✔
389
  case IR_KPRI: setpriV(tv, irt_toitype(ir->t)); break;
11,394✔
390
  case IR_KINT: setintV(tv, ir->i); break;
6,887✔
391
  case IR_KGC: setgcV(L, tv, ir_kgc(ir), irt_toitype(ir->t)); break;
261,031✔
392
  case IR_KPTR: case IR_KKPTR:
×
393
    setnumV(tv, (lua_Number)(uintptr_t)ir_kptr(ir));
×
394
    break;
×
395
  case IR_KNULL: setintV(tv, 0); break;
1✔
396
  case IR_KNUM: setnumV(tv, ir_knum(ir)->n); break;
100,353✔
397
#if LJ_HASFFI
398
  case IR_KINT64: {
399
    GCcdata *cd = lj_cdata_new_(L, CTID_INT64, 8);
×
400
    *(uint64_t *)cdataptr(cd) = ir_kint64(ir)->u64;
×
401
    setcdataV(L, tv, cd);
×
402
    break;
403
    }
404
#endif
405
  default: lj_assertL(0, "bad IR constant op %d", ir->o); break;
406
  }
407
}
379,666✔
408

409
/* -- Convert IR operand types -------------------------------------------- */
410

411
/* Convert from string to number. */
412
TRef LJ_FASTCALL lj_ir_tonumber(jit_State *J, TRef tr)
147,280✔
413
{
414
  if (!tref_isnumber(tr)) {
147,280✔
415
    if (tref_isstr(tr))
×
416
      tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0);
×
417
    else
418
      lj_trace_err(J, LJ_TRERR_BADTYPE);
×
419
  }
420
  return tr;
147,280✔
421
}
422

423
/* Convert from integer or string to number. */
424
TRef LJ_FASTCALL lj_ir_tonum(jit_State *J, TRef tr)
756✔
425
{
426
  if (!tref_isnum(tr)) {
756✔
427
    if (tref_isinteger(tr))
176✔
428
      tr = emitir(IRTN(IR_CONV), tr, IRCONV_NUM_INT);
176✔
429
    else if (tref_isstr(tr))
×
430
      tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0);
×
431
    else
432
      lj_trace_err(J, LJ_TRERR_BADTYPE);
×
433
  }
434
  return tr;
756✔
435
}
436

437
/* Convert from integer or number to string. */
438
TRef LJ_FASTCALL lj_ir_tostr(jit_State *J, TRef tr)
717✔
439
{
440
  if (!tref_isstr(tr)) {
717✔
441
    if (!tref_isnumber(tr))
4✔
442
      lj_trace_err(J, LJ_TRERR_BADTYPE);
×
443
    tr = emitir(IRT(IR_TOSTR, IRT_STR), tr,
4✔
444
                tref_isnum(tr) ? IRTOSTR_NUM : IRTOSTR_INT);
445
  }
446
  return tr;
717✔
447
}
448

449
/* -- Miscellaneous IR ops ------------------------------------------------ */
450

451
/* Evaluate numeric comparison. */
452
int lj_ir_numcmp(lua_Number a, lua_Number b, IROp op)
142,006✔
453
{
454
  switch (op) {
142,006✔
455
  case IR_EQ: return (a == b);
4✔
456
  case IR_NE: return (a != b);
×
457
  case IR_LT: return (a < b);
34✔
458
  case IR_GE: return (a >= b);
42✔
459
  case IR_LE: return (a <= b);
238✔
460
  case IR_GT: return (a > b);
11✔
461
  case IR_ULT: return !(a >= b);
×
462
  case IR_UGE: return !(a < b);
10,459✔
463
  case IR_ULE: return !(a > b);
×
464
  case IR_UGT: return !(a <= b);
131,218✔
465
  default: lj_assertX(0, "bad IR op %d", op); return 0;
466
  }
467
}
468

469
/* Evaluate string comparison. */
470
int lj_ir_strcmp(GCstr *a, GCstr *b, IROp op)
1✔
471
{
472
  int res = lj_str_cmp(a, b);
1✔
473
  switch (op) {
1✔
474
  case IR_LT: return (res < 0);
×
475
  case IR_GE: return (res >= 0);
×
476
  case IR_LE: return (res <= 0);
1✔
477
  case IR_GT: return (res > 0);
×
478
  default: lj_assertX(0, "bad IR op %d", op); return 0;
479
  }
480
}
481

482
/* Rollback IR to previous state. */
483
void lj_ir_rollback(jit_State *J, IRRef ref)
402,454✔
484
{
485
  IRRef nins = J->cur.nins;
402,454✔
486
  while (nins > ref) {
406,741✔
487
    IRIns *ir;
4,287✔
488
    nins--;
4,287✔
489
    ir = IR(nins);
4,287✔
490
    J->chain[ir->o] = ir->prev;
4,287✔
491
  }
492
  J->cur.nins = nins;
402,454✔
493
}
402,454✔
494

495
#undef IR
496
#undef fins
497
#undef emitir
498

499
#endif
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