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

tarantool / luajit / 6943588694

21 Nov 2023 12:03PM UTC coverage: 88.44% (+0.05%) from 88.392%
6943588694

push

github

igormunkin
test: prevent hanging Tarantool CI by sysprof test

Sysprof tests often require long running loops to be executed, so a
certain situation is likely to occur. E.g the test added in scope of the
commit 285a1b0a1 ("sysprof: fix crash
during FFUNC stream") expects FFUNC VM state at the moment when
stacktrace is being collected. Unfortunately, it leads to test routine
hang for particular environments. Hence, it was decided to disable the
test at least for Tarantool CI, until the issue is not resolved.

Relates to tarantool/tarantool#9387

Signed-off-by: Igor Munkin <imun@tarantool.org>
(cherry picked from commit fef60a105)

5348 of 5967 branches covered (0.0%)

Branch coverage included in aggregate %.

20502 of 23262 relevant lines covered (88.14%)

703127.18 hits per line

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

96.18
/src/lj_record.c
1
/*
2
** Trace recorder (bytecode -> SSA IR).
3
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
4
*/
5

6
#define lj_record_c
7
#define LUA_CORE
8

9
#include "lj_obj.h"
10

11
#if LJ_HASJIT
12

13
#include "lj_err.h"
14
#include "lj_str.h"
15
#include "lj_tab.h"
16
#include "lj_meta.h"
17
#include "lj_frame.h"
18
#if LJ_HASFFI
19
#include "lj_ctype.h"
20
#endif
21
#include "lj_bc.h"
22
#include "lj_ff.h"
23
#if LJ_HASPROFILE
24
#include "lj_debug.h"
25
#endif
26
#include "lj_ir.h"
27
#include "lj_jit.h"
28
#include "lj_ircall.h"
29
#include "lj_iropt.h"
30
#include "lj_trace.h"
31
#include "lj_record.h"
32
#include "lj_ffrecord.h"
33
#include "lj_snap.h"
34
#include "lj_dispatch.h"
35
#include "lj_vm.h"
36

37
/* Some local macros to save typing. Undef'd at the end. */
38
#define IR(ref)                        (&J->cur.ir[(ref)])
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
/* Emit raw IR without passing through optimizations. */
44
#define emitir_raw(ot, a, b)        (lj_ir_set(J, (ot), (a), (b)), lj_ir_emit(J))
45

46
/* -- Sanity checks ------------------------------------------------------- */
47

48
#ifdef LUA_USE_ASSERT
49
/* Sanity check the whole IR -- sloooow. */
50
static void rec_check_ir(jit_State *J)
51
{
52
  IRRef i, nins = J->cur.nins, nk = J->cur.nk;
53
  lj_assertJ(nk <= REF_BIAS && nins >= REF_BIAS && nins < 65536,
54
             "inconsistent IR layout");
55
  for (i = nk; i < nins; i++) {
56
    IRIns *ir = IR(i);
57
    uint32_t mode = lj_ir_mode[ir->o];
58
    IRRef op1 = ir->op1;
59
    IRRef op2 = ir->op2;
60
    const char *err = NULL;
61
    switch (irm_op1(mode)) {
62
    case IRMnone:
63
      if (op1 != 0) err = "IRMnone op1 used";
64
      break;
65
    case IRMref:
66
      if (op1 < nk || (i >= REF_BIAS ? op1 >= i : op1 <= i))
67
        err = "IRMref op1 out of range";
68
      break;
69
    case IRMlit: break;
70
    case IRMcst:
71
      if (i >= REF_BIAS) { err = "constant in IR range"; break; }
72
      if (irt_is64(ir->t) && ir->o != IR_KNULL)
73
        i++;
74
      continue;
75
    }
76
    switch (irm_op2(mode)) {
77
    case IRMnone:
78
      if (op2) err = "IRMnone op2 used";
79
      break;
80
    case IRMref:
81
      if (op2 < nk || (i >= REF_BIAS ? op2 >= i : op2 <= i))
82
        err = "IRMref op2 out of range";
83
      break;
84
    case IRMlit: break;
85
    case IRMcst: err = "IRMcst op2"; break;
86
    }
87
    if (!err && ir->prev) {
88
      if (ir->prev < nk || (i >= REF_BIAS ? ir->prev >= i : ir->prev <= i))
89
        err = "chain out of range";
90
      else if (ir->o != IR_NOP && IR(ir->prev)->o != ir->o)
91
        err = "chain to different op";
92
    }
93
    lj_assertJ(!err, "bad IR %04d op %d(%04d,%04d): %s",
94
               i-REF_BIAS,
95
               ir->o,
96
               irm_op1(mode) == IRMref ? op1-REF_BIAS : op1,
97
               irm_op2(mode) == IRMref ? op2-REF_BIAS : op2,
98
               err);
99
  }
100
}
101

102
/* Compare stack slots and frames of the recorder and the VM. */
103
static void rec_check_slots(jit_State *J)
104
{
105
  BCReg s, nslots = J->baseslot + J->maxslot;
106
  int32_t depth = 0;
107
  cTValue *base = J->L->base - J->baseslot;
108
  lj_assertJ(J->baseslot >= 1+LJ_FR2, "bad baseslot");
109
  lj_assertJ(J->baseslot == 1+LJ_FR2 || (J->slot[J->baseslot-1] & TREF_FRAME),
110
             "baseslot does not point to frame");
111
  lj_assertJ(nslots <= LJ_MAX_JSLOTS, "slot overflow");
112
  for (s = 0; s < nslots; s++) {
113
    TRef tr = J->slot[s];
114
    if (tr) {
115
      cTValue *tv = &base[s];
116
      IRRef ref = tref_ref(tr);
117
      IRIns *ir = NULL;  /* Silence compiler. */
118
      lj_assertJ(tv < J->L->top, "slot %d above top of Lua stack", s);
119
      if (!LJ_FR2 || ref || !(tr & (TREF_FRAME | TREF_CONT))) {
120
        lj_assertJ(ref >= J->cur.nk && ref < J->cur.nins,
121
                   "slot %d ref %04d out of range", s, ref - REF_BIAS);
122
        ir = IR(ref);
123
        lj_assertJ(irt_t(ir->t) == tref_t(tr), "slot %d IR type mismatch", s);
124
      }
125
      if (s == 0) {
126
        lj_assertJ(tref_isfunc(tr), "frame slot 0 is not a function");
127
#if LJ_FR2
128
      } else if (s == 1) {
129
        lj_assertJ((tr & ~TREF_FRAME) == 0, "bad frame slot 1");
130
#endif
131
      } else if ((tr & TREF_FRAME)) {
132
        GCfunc *fn = gco2func(frame_gc(tv));
133
        BCReg delta = (BCReg)(tv - frame_prev(tv));
134
#if LJ_FR2
135
        lj_assertJ(!ref || ir_knum(ir)->u64 == tv->u64,
136
                   "frame slot %d PC mismatch", s);
137
        tr = J->slot[s-1];
138
        ir = IR(tref_ref(tr));
139
#endif
140
        lj_assertJ(tref_isfunc(tr),
141
                   "frame slot %d is not a function", s-LJ_FR2);
142
        lj_assertJ(!tref_isk(tr) || fn == ir_kfunc(ir),
143
                   "frame slot %d function mismatch", s-LJ_FR2);
144
        lj_assertJ(s > delta + LJ_FR2 ? (J->slot[s-delta] & TREF_FRAME)
145
                                      : (s == delta + LJ_FR2),
146
                   "frame slot %d broken chain", s-LJ_FR2);
147
        depth++;
148
      } else if ((tr & TREF_CONT)) {
149
#if LJ_FR2
150
        lj_assertJ(!ref || ir_knum(ir)->u64 == tv->u64,
151
                   "cont slot %d continuation mismatch", s);
152
#else
153
        lj_assertJ(ir_kptr(ir) == gcrefp(tv->gcr, void),
154
                   "cont slot %d continuation mismatch", s);
155
#endif
156
        lj_assertJ((J->slot[s+1+LJ_FR2] & TREF_FRAME),
157
                   "cont slot %d not followed by frame", s);
158
        depth++;
159
      } else {
160
        /* Number repr. may differ, but other types must be the same. */
161
        lj_assertJ(tvisnumber(tv) ? tref_isnumber(tr) :
162
                                    itype2irt(tv) == tref_type(tr),
163
                   "slot %d type mismatch: stack type %d vs IR type %d",
164
                   s, itypemap(tv), tref_type(tr));
165
        if (tref_isk(tr)) {  /* Compare constants. */
166
          TValue tvk;
167
          lj_ir_kvalue(J->L, &tvk, ir);
168
          lj_assertJ((tvisnum(&tvk) && tvisnan(&tvk)) ?
169
                     (tvisnum(tv) && tvisnan(tv)) :
170
                     lj_obj_equal(tv, &tvk),
171
                     "slot %d const mismatch: stack %016llx vs IR %016llx",
172
                     s, tv->u64, tvk.u64);
173
        }
174
      }
175
    }
176
  }
177
  lj_assertJ(J->framedepth == depth,
178
             "frame depth mismatch %d vs %d", J->framedepth, depth);
179
}
180
#endif
181

182
/* -- Type handling and specialization ------------------------------------ */
183

184
/* Note: these functions return tagged references (TRef). */
185

186
/* Specialize a slot to a specific type. Note: slot can be negative! */
187
static TRef sloadt(jit_State *J, int32_t slot, IRType t, int mode)
6,372✔
188
{
189
  /* Caller may set IRT_GUARD in t. */
190
  TRef ref = emitir_raw(IRT(IR_SLOAD, t), (int32_t)J->baseslot+slot, mode);
12,744✔
191
  J->base[slot] = ref;
6,372✔
192
  return ref;
6,372✔
193
}
194

195
/* Specialize a slot to the runtime type. Note: slot can be negative! */
196
static TRef sload(jit_State *J, int32_t slot)
13,257✔
197
{
198
  IRType t = itype2irt(&J->L->base[slot]);
13,257✔
199
  TRef ref = emitir_raw(IRTG(IR_SLOAD, t), (int32_t)J->baseslot+slot,
13,257✔
200
                        IRSLOAD_TYPECHECK);
201
  if (irtype_ispri(t)) ref = TREF_PRI(t);  /* Canonicalize primitive refs. */
13,257✔
202
  J->base[slot] = ref;
13,257✔
203
  return ref;
13,257✔
204
}
205

206
/* Get TRef from slot. Load slot and specialize if not done already. */
207
#define getslot(J, s)        (J->base[(s)] ? J->base[(s)] : sload(J, (int32_t)(s)))
208

209
/* Get TRef for current function. */
210
static TRef getcurrf(jit_State *J)
18,908✔
211
{
212
  if (J->base[-1-LJ_FR2])
18,908✔
213
    return J->base[-1-LJ_FR2];
214
  lj_assertJ(J->baseslot == 1+LJ_FR2, "bad baseslot");
3,809✔
215
  return sloadt(J, -1-LJ_FR2, IRT_FUNC, IRSLOAD_READONLY);
3,809✔
216
}
217

218
/* Compare for raw object equality.
219
** Returns 0 if the objects are the same.
220
** Returns 1 if they are different, but the same type.
221
** Returns 2 for two different types.
222
** Comparisons between primitives always return 1 -- no caller cares about it.
223
*/
224
int lj_record_objcmp(jit_State *J, TRef a, TRef b, cTValue *av, cTValue *bv)
7,466✔
225
{
226
  int diff = !lj_obj_equal(av, bv);
7,466✔
227
  if (!tref_isk2(a, b)) {  /* Shortcut, also handles primitives. */
7,466✔
228
    IRType ta = tref_isinteger(a) ? IRT_INT : tref_type(a);
7,466✔
229
    IRType tb = tref_isinteger(b) ? IRT_INT : tref_type(b);
7,466✔
230
    if (ta != tb) {
7,466✔
231
      /* Widen mixed number/int comparisons to number/number comparison. */
232
      if (ta == IRT_INT && tb == IRT_NUM) {
6,923✔
233
        a = emitir(IRTN(IR_CONV), a, IRCONV_NUM_INT);
2✔
234
        ta = IRT_NUM;
2✔
235
      } else if (ta == IRT_NUM && tb == IRT_INT) {
6,921✔
236
        b = emitir(IRTN(IR_CONV), b, IRCONV_NUM_INT);
175✔
237
      } else {
238
        return 2;  /* Two different types are never equal. */
239
      }
240
    }
241
    emitir(IRTG(diff ? IR_NE : IR_EQ, ta), a, b);
1,132✔
242
  }
243
  return diff;
244
}
245

246
/* Constify a value. Returns 0 for non-representable object types. */
247
TRef lj_record_constify(jit_State *J, cTValue *o)
15,373✔
248
{
249
  if (tvisgcv(o))
15,373✔
250
    return lj_ir_kgc(J, gcV(o), itype2irt(o));
15,079✔
251
  else if (tvisint(o))
294✔
252
    return lj_ir_kint(J, intV(o));
253
  else if (tvisnum(o))
294✔
254
    return lj_ir_knumint(J, numV(o));
294✔
255
  else if (tvisbool(o))
×
256
    return TREF_PRI(itype2irt(o));
×
257
  else
258
    return 0;  /* Can't represent lightuserdata (pointless). */
259
}
260

261
/* -- Record loop ops ----------------------------------------------------- */
262

263
/* Loop event. */
264
typedef enum {
265
  LOOPEV_LEAVE,                /* Loop is left or not entered. */
266
  LOOPEV_ENTERLO,        /* Loop is entered with a low iteration count left. */
267
  LOOPEV_ENTER                /* Loop is entered. */
268
} LoopEvent;
269

270
/* Canonicalize slots: convert integers to numbers. */
271
static void canonicalize_slots(jit_State *J)
3,891✔
272
{
273
  BCReg s;
3,891✔
274
  if (LJ_DUALNUM) return;
3,891✔
275
  for (s = J->baseslot+J->maxslot-1; s >= 1; s--) {
42,018✔
276
    TRef tr = J->slot[s];
38,127✔
277
    if (tref_isinteger(tr)) {
38,127✔
278
      IRIns *ir = IR(tref_ref(tr));
1,150✔
279
      if (!(ir->o == IR_SLOAD && (ir->op2 & IRSLOAD_READONLY)))
1,150✔
280
        J->slot[s] = emitir(IRTN(IR_CONV), tr, IRCONV_NUM_INT);
1,082✔
281
    }
282
  }
283
}
284

285
/* Stop recording. */
286
void lj_record_stop(jit_State *J, TraceLink linktype, TraceNo lnk)
5,172✔
287
{
288
#ifdef LUAJIT_ENABLE_TABLE_BUMP
289
  if (J->retryrec)
290
    lj_trace_err(J, LJ_TRERR_RETRY);
291
#endif
292
  lj_trace_end(J);
5,172✔
293
  J->cur.linktype = (uint8_t)linktype;
5,172✔
294
  J->cur.link = (uint16_t)lnk;
5,172✔
295
  /* Looping back at the same stack level? */
296
  if (lnk == J->cur.traceno && J->framedepth + J->retdepth == 0) {
5,172✔
297
    if ((J->flags & JIT_F_OPT_LOOP))  /* Shall we try to create a loop? */
1,994✔
298
      goto nocanon;  /* Do not canonicalize or we lose the narrowing. */
1,281✔
299
    if (J->cur.root)  /* Otherwise ensure we always link to the root trace. */
713✔
300
      J->cur.link = J->cur.root;
1✔
301
  }
302
  canonicalize_slots(J);
3,891✔
303
nocanon:
5,172✔
304
  /* Note: all loop ops must set J->pc to the following instruction! */
305
  lj_snap_add(J);  /* Add loop snapshot. */
5,172✔
306
  J->needsnap = 0;
5,172✔
307
  J->mergesnap = 1;  /* In case recording continues. */
5,172✔
308
}
5,172✔
309

310
/* Search bytecode backwards for a int/num constant slot initializer. */
311
static TRef find_kinit(jit_State *J, const BCIns *endpc, BCReg slot, IRType t)
7,541✔
312
{
313
  /* This algorithm is rather simplistic and assumes quite a bit about
314
  ** how the bytecode is generated. It works fine for FORI initializers,
315
  ** but it won't necessarily work in other cases (e.g. iterator arguments).
316
  ** It doesn't do anything fancy, either (like backpropagating MOVs).
317
  */
318
  const BCIns *pc, *startpc = proto_bc(J->pt);
7,541✔
319
  for (pc = endpc-1; pc > startpc; pc--) {
15,419✔
320
    BCIns ins = *pc;
15,419✔
321
    BCOp op = bc_op(ins);
15,419✔
322
    /* First try to find the last instruction that stores to this slot. */
323
    if (bcmode_a(op) == BCMbase && bc_a(ins) <= slot) {
15,419✔
324
      return 0;  /* Multiple results, e.g. from a CALL or KNIL. */
325
    } else if (bcmode_a(op) == BCMdst && bc_a(ins) == slot) {
15,404✔
326
      if (op == BC_KSHORT || op == BC_KNUM) {  /* Found const. initializer. */
7,526✔
327
        /* Now try to verify there's no forward jump across it. */
328
        const BCIns *kpc = pc;
455,596✔
329
        for (; pc > startpc; pc--)
455,596✔
330
          if (bc_op(*pc) == BC_JMP) {
448,356✔
331
            const BCIns *target = pc+bc_j(*pc)+1;
40,978✔
332
            if (target > kpc && target <= endpc)
40,978✔
333
              return 0;  /* Conditional assignment. */
334
          }
335
        if (op == BC_KSHORT) {
7,240✔
336
          int32_t k = (int32_t)(int16_t)bc_d(ins);
7,177✔
337
          return t == IRT_INT ? lj_ir_kint(J, k) : lj_ir_knum(J, (lua_Number)k);
7,177✔
338
        } else {
339
          cTValue *tv = proto_knumtv(J->pt, bc_d(ins));
63✔
340
          if (t == IRT_INT) {
63✔
341
            int32_t k = numberVint(tv);
49✔
342
            if (tvisint(tv) || numV(tv) == (lua_Number)k)  /* -0 is ok here. */
49✔
343
              return lj_ir_kint(J, k);
45✔
344
            return 0;  /* Type mismatch. */
345
          } else {
346
            return lj_ir_knum(J, numberVnum(tv));
14✔
347
          }
348
        }
349
      }
350
      return 0;  /* Non-constant initializer. */
351
    }
352
  }
353
  return 0;  /* No assignment to this slot found? */
354
}
355

356
/* Load and optionally convert a FORI argument from a slot. */
357
static TRef fori_load(jit_State *J, BCReg slot, IRType t, int mode)
2,563✔
358
{
359
  int conv = (tvisint(&J->L->base[slot]) != (t==IRT_INT)) ? IRSLOAD_CONVERT : 0;
2,563✔
360
  return sloadt(J, (int32_t)slot,
7,689✔
361
                t + (((mode & IRSLOAD_TYPECHECK) ||
2,563✔
362
                      (conv && t == IRT_INT && !(mode >> 16))) ?
2,563✔
363
                     IRT_GUARD : 0),
2,563✔
364
                mode + conv);
365
}
366

367
/* Peek before FORI to find a const initializer. Otherwise load from slot. */
368
static TRef fori_arg(jit_State *J, const BCIns *fori, BCReg slot,
5,466✔
369
                     IRType t, int mode)
370
{
371
  TRef tr = J->base[slot];
5,466✔
372
  if (!tr) {
5,466✔
373
    tr = find_kinit(J, fori, slot, t);
4,808✔
374
    if (!tr)
4,808✔
375
      tr = fori_load(J, slot, t, mode);
225✔
376
  }
377
  return tr;
5,466✔
378
}
379

380
/* Return the direction of the FOR loop iterator.
381
** It's important to exactly reproduce the semantics of the interpreter.
382
*/
383
static int rec_for_direction(cTValue *o)
5,665✔
384
{
385
  return (tvisint(o) ? intV(o) : (int32_t)o->u32.hi) >= 0;
5,665✔
386
}
387

388
/* Simulate the runtime behavior of the FOR loop iterator. */
389
static LoopEvent rec_for_iter(IROp *op, cTValue *o, int isforl)
2,699✔
390
{
391
  lua_Number stopv = numberVnum(&o[FORL_STOP]);
2,699✔
392
  lua_Number idxv = numberVnum(&o[FORL_IDX]);
2,699✔
393
  lua_Number stepv = numberVnum(&o[FORL_STEP]);
2,699✔
394
  if (isforl)
2,699✔
395
    idxv += stepv;
2,466✔
396
  if (rec_for_direction(&o[FORL_STEP])) {
2,699✔
397
    if (idxv <= stopv) {
2,639✔
398
      *op = IR_LE;
2,579✔
399
      return idxv + 2*stepv > stopv ? LOOPEV_ENTERLO : LOOPEV_ENTER;
2,579✔
400
    }
401
    *op = IR_GT; return LOOPEV_LEAVE;
60✔
402
  } else {
403
    if (stopv <= idxv) {
60✔
404
      *op = IR_GE;
59✔
405
      return idxv + 2*stepv < stopv ? LOOPEV_ENTERLO : LOOPEV_ENTER;
59✔
406
    }
407
    *op = IR_LT; return LOOPEV_LEAVE;
1✔
408
  }
409
}
410

411
/* Record checks for FOR loop overflow and step direction. */
412
static void rec_for_check(jit_State *J, IRType t, int dir,
2,966✔
413
                          TRef stop, TRef step, int init)
414
{
415
  if (!tref_isk(step)) {
2,966✔
416
    /* Non-constant step: need a guard for the direction. */
417
    TRef zero = (t == IRT_INT) ? lj_ir_kint(J, 0) : lj_ir_knum_zero(J);
244✔
418
    emitir(IRTG(dir ? IR_GE : IR_LT, t), step, zero);
245✔
419
    /* Add hoistable overflow checks for a narrowed FORL index. */
420
    if (init && t == IRT_INT) {
244✔
421
      if (tref_isk(stop)) {
7✔
422
        /* Constant stop: optimize check away or to a range check for step. */
423
        int32_t k = IR(tref_ref(stop))->i;
2✔
424
        if (dir) {
2✔
425
          if (k > 0)
2✔
426
            emitir(IRTGI(IR_LE), step, lj_ir_kint(J, (int32_t)0x7fffffff-k));
2✔
427
        } else {
428
          if (k < 0)
×
429
            emitir(IRTGI(IR_GE), step, lj_ir_kint(J, (int32_t)0x80000000-k));
×
430
        }
431
      } else {
432
        /* Stop+step variable: need full overflow check. */
433
        TRef tr = emitir(IRTGI(IR_ADDOV), step, stop);
5✔
434
        emitir(IRTI(IR_USE), tr, 0);  /* ADDOV is weak. Avoid dead result. */
5✔
435
      }
436
    }
437
  } else if (init && t == IRT_INT && !tref_isk(stop)) {
2,722✔
438
    /* Constant step: optimize overflow check to a range check for stop. */
439
    int32_t k = IR(tref_ref(step))->i;
200✔
440
    k = (int32_t)(dir ? 0x7fffffff : 0x80000000) - k;
200✔
441
    emitir(IRTGI(dir ? IR_LE : IR_GE), stop, lj_ir_kint(J, k));
229✔
442
  }
443
}
2,966✔
444

445
/* Record a FORL instruction. */
446
static void rec_for_loop(jit_State *J, const BCIns *fori, ScEvEntry *scev,
2,733✔
447
                         int init)
448
{
449
  BCReg ra = bc_a(*fori);
2,733✔
450
  cTValue *tv = &J->L->base[ra];
2,733✔
451
  TRef idx = J->base[ra+FORL_IDX];
2,733✔
452
  IRType t = idx ? tref_type(idx) :
2,733✔
453
             (init || LJ_DUALNUM) ? lj_opt_narrow_forl(J, tv) : IRT_NUM;
2,338✔
454
  int mode = IRSLOAD_INHERIT +
2,733✔
455
    ((!LJ_DUALNUM || tvisint(tv) == (t == IRT_INT)) ? IRSLOAD_READONLY : 0);
456
  TRef stop = fori_arg(J, fori, ra+FORL_STOP, t, mode);
2,733✔
457
  TRef step = fori_arg(J, fori, ra+FORL_STEP, t, mode);
2,733✔
458
  int tc, dir = rec_for_direction(&tv[FORL_STEP]);
2,733✔
459
  lj_assertJ(bc_op(*fori) == BC_FORI || bc_op(*fori) == BC_JFORI,
2,733✔
460
             "bad bytecode %d instead of FORI/JFORI", bc_op(*fori));
461
  scev->t.irt = t;
2,733✔
462
  scev->dir = dir;
2,733✔
463
  scev->stop = tref_ref(stop);
2,733✔
464
  scev->step = tref_ref(step);
2,733✔
465
  rec_for_check(J, t, dir, stop, step, init);
2,733✔
466
  scev->start = tref_ref(find_kinit(J, fori, ra+FORL_IDX, IRT_INT));
2,733✔
467
  tc = (LJ_DUALNUM &&
2,733✔
468
        !(scev->start && irref_isk(scev->stop) && irref_isk(scev->step) &&
469
          tvisint(&tv[FORL_IDX]) == (t == IRT_INT))) ?
470
        IRSLOAD_TYPECHECK : 0;
471
  if (tc) {
2,733✔
472
    J->base[ra+FORL_STOP] = stop;
473
    J->base[ra+FORL_STEP] = step;
474
  }
475
  if (!idx)
2,733✔
476
    idx = fori_load(J, ra+FORL_IDX, t,
2,338✔
477
                    IRSLOAD_INHERIT + tc + (J->scev.start << 16));
2,338✔
478
  if (!init)
2,733✔
479
    J->base[ra+FORL_IDX] = idx = emitir(IRT(IR_ADD, t), idx, step);
489✔
480
  J->base[ra+FORL_EXT] = idx;
2,733✔
481
  scev->idx = tref_ref(idx);
2,733✔
482
  setmref(scev->pc, fori);
2,733✔
483
  J->maxslot = ra+FORL_EXT+1;
2,733✔
484
}
2,733✔
485

486
/* Record FORL/JFORL or FORI/JFORI. */
487
static LoopEvent rec_for(jit_State *J, const BCIns *fori, int isforl)
2,700✔
488
{
489
  BCReg ra = bc_a(*fori);
2,700✔
490
  TValue *tv = &J->L->base[ra];
2,700✔
491
  TRef *tr = &J->base[ra];
2,700✔
492
  IROp op;
2,700✔
493
  LoopEvent ev;
2,700✔
494
  TRef stop;
2,700✔
495
  IRType t;
2,700✔
496
  if (isforl) {  /* Handle FORL/JFORL opcodes. */
2,700✔
497
    TRef idx = tr[FORL_IDX];
2,466✔
498
    if (mref(J->scev.pc, const BCIns) == fori && tref_ref(idx) == J->scev.idx) {
2,466✔
499
      t = J->scev.t.irt;
1,977✔
500
      stop = J->scev.stop;
1,977✔
501
      idx = emitir(IRT(IR_ADD, t), idx, J->scev.step);
1,977✔
502
      tr[FORL_EXT] = tr[FORL_IDX] = idx;
1,977✔
503
    } else {
504
      ScEvEntry scev;
489✔
505
      rec_for_loop(J, fori, &scev, 0);
489✔
506
      t = scev.t.irt;
489✔
507
      stop = scev.stop;
489✔
508
    }
509
  } else {  /* Handle FORI/JFORI opcodes. */
510
    BCReg i;
234✔
511
    lj_meta_for(J->L, tv);
234✔
512
    t = (LJ_DUALNUM || tref_isint(tr[FORL_IDX])) ? lj_opt_narrow_forl(J, tv) :
233✔
513
                                                   IRT_NUM;
514
    for (i = FORL_IDX; i <= FORL_STEP; i++) {
932✔
515
      if (!tr[i]) sload(J, ra+i);
699✔
516
      lj_assertJ(tref_isnumber_str(tr[i]), "bad FORI argument type");
699✔
517
      if (tref_isstr(tr[i]))
699✔
518
        tr[i] = emitir(IRTG(IR_STRTO, IRT_NUM), tr[i], 0);
1✔
519
      if (t == IRT_INT) {
699✔
520
        if (!tref_isinteger(tr[i]))
294✔
521
          tr[i] = emitir(IRTGI(IR_CONV), tr[i], IRCONV_INT_NUM|IRCONV_CHECK);
9✔
522
      } else {
523
        if (!tref_isnum(tr[i]))
405✔
524
          tr[i] = emitir(IRTN(IR_CONV), tr[i], IRCONV_NUM_INT);
373✔
525
      }
526
    }
527
    tr[FORL_EXT] = tr[FORL_IDX];
233✔
528
    stop = tr[FORL_STOP];
233✔
529
    rec_for_check(J, t, rec_for_direction(&tv[FORL_STEP]),
233✔
530
                  stop, tr[FORL_STEP], 1);
531
  }
532

533
  ev = rec_for_iter(&op, tv, isforl);
2,699✔
534
  if (ev == LOOPEV_LEAVE) {
2,699✔
535
    J->maxslot = ra+FORL_EXT+1;
61✔
536
    J->pc = fori+1;
61✔
537
  } else {
538
    J->maxslot = ra;
2,638✔
539
    J->pc = fori+bc_j(*fori)+1;
2,638✔
540
  }
541
  lj_snap_add(J);
2,699✔
542

543
  emitir(IRTG(op, t), tr[FORL_IDX], stop);
2,699✔
544

545
  if (ev == LOOPEV_LEAVE) {
2,699✔
546
    J->maxslot = ra;
61✔
547
    J->pc = fori+bc_j(*fori)+1;
61✔
548
  } else {
549
    J->maxslot = ra+FORL_EXT+1;
2,638✔
550
    J->pc = fori+1;
2,638✔
551
  }
552
  J->needsnap = 1;
2,699✔
553
  return ev;
2,699✔
554
}
555

556
/* Record ITERL/JITERL. */
557
static LoopEvent rec_iterl(jit_State *J, const BCIns iterins)
108✔
558
{
559
  BCReg ra = bc_a(iterins);
108✔
560
  if (!tref_isnil(getslot(J, ra))) {  /* Looping back? */
108✔
561
    J->base[ra-1] = J->base[ra];  /* Copy result of ITERC to control var. */
83✔
562
    J->maxslot = ra-1+bc_b(J->pc[-1]);
83✔
563
    J->pc += bc_j(iterins)+1;
83✔
564
    return LOOPEV_ENTER;
83✔
565
  } else {
566
    J->maxslot = ra-3;
25✔
567
    J->pc++;
25✔
568
    return LOOPEV_LEAVE;
25✔
569
  }
570
}
571

572
/* Record LOOP/JLOOP. Now, that was easy. */
573
static LoopEvent rec_loop(jit_State *J, BCReg ra)
1,507✔
574
{
575
  if (ra < J->maxslot) J->maxslot = ra;
92✔
576
  J->pc++;
1,507✔
577
  return LOOPEV_ENTER;
1,507✔
578
}
579

580
/* Check if a loop repeatedly failed to trace because it didn't loop back. */
581
static int innerloopleft(jit_State *J, const BCIns *pc)
582
{
583
  ptrdiff_t i;
584
  for (i = 0; i < PENALTY_SLOTS; i++)
9,443✔
585
    if (mref(J->penalty[i].pc, const BCIns) == pc) {
9,299✔
586
      if ((J->penalty[i].reason == LJ_TRERR_LLEAVE ||
15✔
587
           J->penalty[i].reason == LJ_TRERR_LINNER) &&
15✔
588
          J->penalty[i].val >= 2*PENALTY_MIN)
15✔
589
        return 1;
590
      break;
591
    }
592
  return 0;
593
}
594

595
/* Handle the case when an interpreted loop op is hit. */
596
static void rec_loop_interp(jit_State *J, const BCIns *pc, LoopEvent ev)
2,271✔
597
{
598
  if (J->parent == 0 && J->exitno == 0) {
2,271✔
599
    if (pc == J->startpc && J->framedepth + J->retdepth == 0) {
2,030✔
600
      /* Same loop? */
601
      if (ev == LOOPEV_LEAVE)  /* Must loop back to form a root trace. */
1,867✔
602
        lj_trace_err(J, LJ_TRERR_LLEAVE);
36✔
603
      lj_record_stop(J, LJ_TRLINK_LOOP, J->cur.traceno);  /* Looping trace. */
1,831✔
604
    } else if (ev != LOOPEV_LEAVE) {  /* Entering inner loop? */
163✔
605
      /* It's usually better to abort here and wait until the inner loop
606
      ** is traced. But if the inner loop repeatedly didn't loop back,
607
      ** this indicates a low trip count. In this case try unrolling
608
      ** an inner loop even in a root trace. But it's better to be a bit
609
      ** more conservative here and only do it for very short loops.
610
      */
611
      if (bc_j(*pc) != -1 && !innerloopleft(J, pc))
160✔
612
        lj_trace_err(J, LJ_TRERR_LINNER);  /* Root trace hit an inner loop. */
156✔
613
      if ((ev != LOOPEV_ENTERLO &&
4✔
614
           J->loopref && J->cur.nins - J->loopref > 24) || --J->loopunroll < 0)
4✔
615
        lj_trace_err(J, LJ_TRERR_LUNROLL);  /* Limit loop unrolling. */
×
616
      J->loopref = J->cur.nins;
4✔
617
    }
618
  } else if (ev != LOOPEV_LEAVE) {  /* Side trace enters an inner loop. */
241✔
619
    J->loopref = J->cur.nins;
218✔
620
    if (--J->loopunroll < 0)
218✔
621
      lj_trace_err(J, LJ_TRERR_LUNROLL);  /* Limit loop unrolling. */
6✔
622
  }  /* Side trace continues across a loop that's left or not entered. */
623
}
2,073✔
624

625
/* Handle the case when an already compiled loop op is hit. */
626
static void rec_loop_jit(jit_State *J, TraceNo lnk, LoopEvent ev)
1,810✔
627
{
628
  if (J->parent == 0 && J->exitno == 0) {  /* Root trace hit an inner loop. */
1,810✔
629
    /* Better let the inner loop spawn a side trace back here. */
630
    lj_trace_err(J, LJ_TRERR_LINNER);
110✔
631
  } else if (ev != LOOPEV_LEAVE) {  /* Side trace enters a compiled loop. */
1,700✔
632
    J->instunroll = 0;  /* Cannot continue across a compiled loop op. */
1,678✔
633
    if (J->pc == J->startpc && J->framedepth + J->retdepth == 0)
1,678✔
634
      lj_record_stop(J, LJ_TRLINK_LOOP, J->cur.traceno);  /* Form extra loop. */
158✔
635
    else
636
      lj_record_stop(J, LJ_TRLINK_ROOT, lnk);  /* Link to the loop. */
1,520✔
637
  }  /* Side trace continues across a loop that's left or not entered. */
638
}
1,700✔
639

640
/* -- Record profiler hook checks ----------------------------------------- */
641

642
#if LJ_HASPROFILE
643

644
/* Need to insert profiler hook check? */
645
static int rec_profile_need(jit_State *J, GCproto *pt, const BCIns *pc)
7✔
646
{
647
  GCproto *ppt;
7✔
648
  lj_assertJ(J->prof_mode == 'f' || J->prof_mode == 'l',
7✔
649
             "bad profiler mode %c", J->prof_mode);
650
  if (!pt)
7✔
651
    return 0;
652
  ppt = J->prev_pt;
6✔
653
  J->prev_pt = pt;
6✔
654
  if (pt != ppt && ppt) {
6✔
655
    J->prev_line = -1;
×
656
    return 1;
×
657
  }
658
  if (J->prof_mode == 'l') {
6✔
659
    BCLine line = lj_debug_line(pt, proto_bcpos(pt, pc));
4✔
660
    BCLine pline = J->prev_line;
4✔
661
    J->prev_line = line;
4✔
662
    if (pline != line)
4✔
663
      return 1;
1✔
664
  }
665
  return 0;
666
}
667

668
static void rec_profile_ins(jit_State *J, const BCIns *pc)
280,180✔
669
{
670
  if (J->prof_mode && rec_profile_need(J, J->pt, pc)) {
280,180✔
671
    emitir(IRTG(IR_PROF, IRT_NIL), 0, 0);
1✔
672
    lj_snap_add(J);
1✔
673
  }
674
}
280,180✔
675

676
static void rec_profile_ret(jit_State *J)
13,892✔
677
{
678
  if (J->prof_mode == 'f') {
13,892✔
679
    emitir(IRTG(IR_PROF, IRT_NIL), 0, 0);
×
680
    J->prev_pt = NULL;
×
681
    lj_snap_add(J);
×
682
  }
683
}
13,892✔
684

685
#endif
686

687
/* -- Record calls and returns -------------------------------------------- */
688

689
/* Specialize to the runtime value of the called function or its prototype. */
690
static TRef rec_call_specialize(jit_State *J, GCfunc *fn, TRef tr)
19,595✔
691
{
692
  TRef kfunc;
19,595✔
693
  if (isluafunc(fn)) {
19,595✔
694
    GCproto *pt = funcproto(fn);
13,426✔
695
    /* Too many closures created? Probably not a monomorphic function. */
696
    if (pt->flags >= PROTO_CLC_POLY) {  /* Specialize to prototype instead. */
13,426✔
697
      TRef trpt = emitir(IRT(IR_FLOAD, IRT_PGC), tr, IRFL_FUNC_PC);
18✔
698
      emitir(IRTG(IR_EQ, IRT_PGC), trpt, lj_ir_kptr(J, proto_bc(pt)));
18✔
699
      (void)lj_ir_kgc(J, obj2gco(pt), IRT_PROTO);  /* Prevent GC of proto. */
18✔
700
      return tr;
18✔
701
    }
702
  } else {
703
    /* Don't specialize to non-monomorphic builtins. */
704
    switch (fn->c.ffid) {
6,169✔
705
    case FF_coroutine_wrap_aux:
5✔
706
    case FF_string_gmatch_aux:
707
      /* NYI: io_file_iter doesn't have an ffid, yet. */
708
      {  /* Specialize to the ffid. */
709
        TRef trid = emitir(IRT(IR_FLOAD, IRT_U8), tr, IRFL_FUNC_FFID);
5✔
710
        emitir(IRTG(IR_EQ, IRT_INT), trid, lj_ir_kint(J, fn->c.ffid));
5✔
711
      }
712
      return tr;
5✔
713
    default:
714
      /* NYI: don't specialize to non-monomorphic C functions. */
715
      break;
716
    }
717
  }
718
  /* Otherwise specialize to the function (closure) value itself. */
719
  kfunc = lj_ir_kfunc(J, fn);
19,572✔
720
  emitir(IRTG(IR_EQ, IRT_FUNC), tr, kfunc);
19,572✔
721
  return kfunc;
19,572✔
722
}
723

724
/* Record call setup. */
725
static void rec_call_setup(jit_State *J, BCReg func, ptrdiff_t nargs)
19,595✔
726
{
727
  RecordIndex ix;
19,595✔
728
  TValue *functv = &J->L->base[func];
19,595✔
729
  TRef kfunc, *fbase = &J->base[func];
19,595✔
730
  ptrdiff_t i;
19,595✔
731
  (void)getslot(J, func); /* Ensure func has a reference. */
19,595✔
732
  for (i = 1; i <= nargs; i++)
45,894✔
733
    (void)getslot(J, func+LJ_FR2+i);  /* Ensure all args have a reference. */
26,299✔
734
  if (!tref_isfunc(fbase[0])) {  /* Resolve __call metamethod. */
19,595✔
735
    ix.tab = fbase[0];
65✔
736
    copyTV(J->L, &ix.tabv, functv);
65✔
737
    if (!lj_record_mm_lookup(J, &ix, MM_call) || !tref_isfunc(ix.mobj))
65✔
738
      lj_trace_err(J, LJ_TRERR_NOMM);
×
739
    for (i = ++nargs; i > LJ_FR2; i--)  /* Shift arguments up. */
167✔
740
      fbase[i+LJ_FR2] = fbase[i+LJ_FR2-1];
102✔
741
#if LJ_FR2
742
    fbase[2] = fbase[0];
65✔
743
#endif
744
    fbase[0] = ix.mobj;  /* Replace function. */
65✔
745
    functv = &ix.mobjv;
65✔
746
  }
747
  kfunc = rec_call_specialize(J, funcV(functv), fbase[0]);
19,595✔
748
#if LJ_FR2
749
  fbase[0] = kfunc;
19,595✔
750
  fbase[1] = TREF_FRAME;
19,595✔
751
#else
752
  fbase[0] = kfunc | TREF_FRAME;
753
#endif
754
  J->maxslot = (BCReg)nargs;
19,595✔
755
}
19,595✔
756

757
/* Record call. */
758
void lj_record_call(jit_State *J, BCReg func, ptrdiff_t nargs)
17,629✔
759
{
760
  rec_call_setup(J, func, nargs);
17,629✔
761
  /* Bump frame. */
762
  J->framedepth++;
17,629✔
763
  J->base += func+1+LJ_FR2;
17,629✔
764
  J->baseslot += func+1+LJ_FR2;
17,629✔
765
  if (J->baseslot + J->maxslot >= LJ_MAX_JSLOTS)
17,629✔
766
    lj_trace_err(J, LJ_TRERR_STACKOV);
1✔
767
}
17,628✔
768

769
/* Record tail call. */
770
void lj_record_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs)
1,966✔
771
{
772
  rec_call_setup(J, func, nargs);
1,966✔
773
  if (frame_isvarg(J->L->base - 1)) {
1,966✔
774
    BCReg cbase = (BCReg)frame_delta(J->L->base - 1);
4✔
775
    if (--J->framedepth < 0)
4✔
776
      lj_trace_err(J, LJ_TRERR_NYIRETL);
×
777
    J->baseslot -= (BCReg)cbase;
4✔
778
    J->base -= cbase;
4✔
779
    func += cbase;
4✔
780
  }
781
  /* Move func + args down. */
782
  if (LJ_FR2 && J->baseslot == 2)
1,966✔
783
    J->base[func+1] = TREF_FRAME;
1,813✔
784
  memmove(&J->base[-1-LJ_FR2], &J->base[func], sizeof(TRef)*(J->maxslot+1+LJ_FR2));
1,966✔
785
  /* Note: the new TREF_FRAME is now at J->base[-1] (even for slot #0). */
786
  /* Tailcalls can form a loop, so count towards the loop unroll limit. */
787
  if (++J->tailcalled > J->loopunroll)
1,966✔
788
    lj_trace_err(J, LJ_TRERR_LUNROLL);
12✔
789
}
1,954✔
790

791
/* Check unroll limits for down-recursion. */
792
static int check_downrec_unroll(jit_State *J, GCproto *pt)
2,181✔
793
{
794
  IRRef ptref;
2,181✔
795
  for (ptref = J->chain[IR_KGC]; ptref; ptref = IR(ptref)->prev)
10,447✔
796
    if (ir_kgc(IR(ptref)) == obj2gco(pt)) {
8,341✔
797
      int count = 0;
89✔
798
      IRRef ref;
89✔
799
      for (ref = J->chain[IR_RETF]; ref; ref = IR(ref)->prev)
213✔
800
        if (IR(ref)->op1 == ptref)
124✔
801
          count++;
105✔
802
      if (count) {
89✔
803
        if (J->pc == J->startpc) {
89✔
804
          if (count + J->tailcalled > J->param[JIT_P_recunroll])
22✔
805
            return 1;
806
        } else {
807
          lj_trace_err(J, LJ_TRERR_DOWNREC);
67✔
808
        }
809
      }
810
    }
811
  return 0;
812
}
813

814
static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot);
815

816
/* Record return. */
817
void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
19,729✔
818
{
819
  TValue *frame = J->L->base - 1;
19,729✔
820
  ptrdiff_t i;
19,729✔
821
  for (i = 0; i < gotresults; i++)
36,862✔
822
    (void)getslot(J, rbase+i);  /* Ensure all results have a reference. */
17,133✔
823
  while (frame_ispcall(frame)) {  /* Immediately resolve pcall() returns. */
19,757✔
824
    BCReg cbase = (BCReg)frame_delta(frame);
40✔
825
    if (--J->framedepth <= 0)
40✔
826
      lj_trace_err(J, LJ_TRERR_NYIRETL);
12✔
827
    lj_assertJ(J->baseslot > 1+LJ_FR2, "bad baseslot for return");
28✔
828
    gotresults++;
28✔
829
    rbase += cbase;
28✔
830
    J->baseslot -= (BCReg)cbase;
28✔
831
    J->base -= cbase;
28✔
832
    J->base[--rbase] = TREF_TRUE;  /* Prepend true to results. */
28✔
833
    frame = frame_prevd(frame);
28✔
834
  }
835
  /* Return to lower frame via interpreter for unhandled cases. */
836
  if (J->framedepth == 0 && J->pt && bc_isret(bc_op(*J->pc)) &&
19,717✔
837
       (!frame_islua(frame) ||
2,356✔
838
        (J->parent == 0 && J->exitno == 0 &&
2,314✔
839
         !bc_isret(bc_op(J->cur.startins))))) {
259✔
840
    /* NYI: specialize to frame type and return directly, not via RET*. */
841
    for (i = 0; i < (ptrdiff_t)rbase; i++)
388✔
842
      J->base[i] = 0;  /* Purge dead slots. */
213✔
843
    J->maxslot = rbase + (BCReg)gotresults;
175✔
844
    lj_record_stop(J, LJ_TRLINK_RETURN, 0);  /* Return to interpreter. */
175✔
845
    return;
175✔
846
  }
847
  if (frame_isvarg(frame)) {
19,542✔
848
    BCReg cbase = (BCReg)frame_delta(frame);
25✔
849
    if (--J->framedepth < 0)  /* NYI: return of vararg func to lower frame. */
25✔
850
      lj_trace_err(J, LJ_TRERR_NYIRETL);
×
851
    lj_assertJ(J->baseslot > 1+LJ_FR2, "bad baseslot for return");
25✔
852
    rbase += cbase;
25✔
853
    J->baseslot -= (BCReg)cbase;
25✔
854
    J->base -= cbase;
25✔
855
    frame = frame_prevd(frame);
25✔
856
  }
857
  if (frame_islua(frame)) {  /* Return to Lua frame. */
19,542✔
858
    BCIns callins = *(frame_pc(frame)-1);
18,814✔
859
    ptrdiff_t nresults = bc_b(callins) ? (ptrdiff_t)bc_b(callins)-1 :gotresults;
18,814✔
860
    BCReg cbase = bc_a(callins);
18,814✔
861
    GCproto *pt = funcproto(frame_func(frame - (cbase+1+LJ_FR2)));
18,814✔
862
    if ((pt->flags & PROTO_NOJIT))
18,814✔
863
      lj_trace_err(J, LJ_TRERR_CJITOFF);
×
864
    if (J->framedepth == 0 && J->pt && frame == J->L->base - 1) {
18,814✔
865
      if (check_downrec_unroll(J, pt)) {
2,181✔
866
        J->maxslot = (BCReg)(rbase + gotresults);
8✔
867
        lj_snap_purge(J);
8✔
868
        lj_record_stop(J, LJ_TRLINK_DOWNREC, J->cur.traceno);  /* Down-rec. */
8✔
869
        return;
8✔
870
      }
871
      lj_snap_add(J);
2,106✔
872
    }
873
    for (i = 0; i < nresults; i++)  /* Adjust results. */
33,699✔
874
      J->base[i-1-LJ_FR2] = i < gotresults ? J->base[rbase+i] : TREF_NIL;
14,960✔
875
    J->maxslot = cbase+(BCReg)nresults;
18,739✔
876
    if (J->framedepth > 0) {  /* Return to a frame that is part of the trace. */
18,739✔
877
      J->framedepth--;
16,401✔
878
      lj_assertJ(J->baseslot > cbase+1+LJ_FR2, "bad baseslot for return");
16,401✔
879
      J->baseslot -= cbase+1+LJ_FR2;
16,401✔
880
      J->base -= cbase+1+LJ_FR2;
16,401✔
881
    } else if (J->parent == 0 && J->exitno == 0 &&
2,338✔
882
               !bc_isret(bc_op(J->cur.startins))) {
117✔
883
      /* Return to lower frame would leave the loop in a root trace. */
884
      lj_trace_err(J, LJ_TRERR_LLEAVE);
14✔
885
    } else if (J->needsnap) {  /* Tailcalled to ff with side-effects. */
2,324✔
886
      lj_trace_err(J, LJ_TRERR_NYIRETL);  /* No way to insert snapshot here. */
×
887
    } else {  /* Return to lower frame. Guard for the target we return to. */
888
      TRef trpt = lj_ir_kgc(J, obj2gco(pt), IRT_PROTO);
2,324✔
889
      TRef trpc = lj_ir_kptr(J, (void *)frame_pc(frame));
2,324✔
890
      emitir(IRTG(IR_RETF, IRT_PGC), trpt, trpc);
2,324✔
891
      J->retdepth++;
2,324✔
892
      J->needsnap = 1;
2,324✔
893
      lj_assertJ(J->baseslot == 1+LJ_FR2, "bad baseslot for return");
2,324✔
894
      /* Shift result slots up and clear the slots of the new frame below. */
895
      memmove(J->base + cbase, J->base-1-LJ_FR2, sizeof(TRef)*nresults);
2,324✔
896
      memset(J->base-1-LJ_FR2, 0, sizeof(TRef)*(cbase+1+LJ_FR2));
2,324✔
897
    }
898
  } else if (frame_iscont(frame)) {  /* Return to continuation frame. */
728✔
899
    ASMFunction cont = frame_contf(frame);
728✔
900
    BCReg cbase = (BCReg)frame_delta(frame);
728✔
901
    if ((J->framedepth -= 2) < 0)
728✔
902
      lj_trace_err(J, LJ_TRERR_NYIRETL);
4✔
903
    J->baseslot -= (BCReg)cbase;
724✔
904
    J->base -= cbase;
724✔
905
    J->maxslot = cbase-(2<<LJ_FR2);
724✔
906
    if (cont == lj_cont_ra) {
724✔
907
      /* Copy result to destination slot. */
908
      BCReg dst = bc_a(*(frame_contpc(frame)-1));
451✔
909
      J->base[dst] = gotresults ? J->base[cbase+rbase] : TREF_NIL;
451✔
910
      if (dst >= J->maxslot) {
451✔
911
        J->maxslot = dst+1;
×
912
      }
913
    } else if (cont == lj_cont_nop) {
273✔
914
      /* Nothing to do here. */
915
    } else if (cont == lj_cont_cat) {
166✔
916
      BCReg bslot = bc_b(*(frame_contpc(frame)-1));
6✔
917
      TRef tr = gotresults ? J->base[cbase+rbase] : TREF_NIL;
6✔
918
      if (bslot != J->maxslot) {  /* Concatenate the remainder. */
6✔
919
        TValue *b = J->L->base, save;  /* Simulate lower frame and result. */
3✔
920
        /* Can't handle MM_concat + CALLT + fast func side-effects. */
921
        if (J->postproc != LJ_POST_NONE)
3✔
922
          lj_trace_err(J, LJ_TRERR_NYIRETL);
1✔
923
        J->base[J->maxslot] = tr;
2✔
924
        copyTV(J->L, &save, b-(2<<LJ_FR2));
2✔
925
        if (gotresults)
2✔
926
          copyTV(J->L, b-(2<<LJ_FR2), b+rbase);
2✔
927
        else
928
          setnilV(b-(2<<LJ_FR2));
×
929
        J->L->base = b - cbase;
2✔
930
        tr = rec_cat(J, bslot, cbase-(2<<LJ_FR2));
2✔
931
        b = J->L->base + cbase;  /* Undo. */
2✔
932
        J->L->base = b;
2✔
933
        copyTV(J->L, b-(2<<LJ_FR2), &save);
2✔
934
      }
935
      if (tr) {  /* Store final result. */
5✔
936
        BCReg dst = bc_a(*(frame_contpc(frame)-1));
3✔
937
        J->base[dst] = tr;
3✔
938
        if (dst >= J->maxslot) {
3✔
939
          J->maxslot = dst+1;
×
940
        }
941
      }  /* Otherwise continue with another __concat call. */
942
    } else {
943
      /* Result type already specialized. */
944
      lj_assertJ(cont == lj_cont_condf || cont == lj_cont_condt,
945
                 "bad continuation type");
946
    }
947
  } else {
948
    lj_trace_err(J, LJ_TRERR_NYIRETL);  /* NYI: handle return to C frame. */
×
949
  }
950
  lj_assertJ(J->baseslot >= 1+LJ_FR2, "bad baseslot for return");
19,631✔
951
}
952

953
/* -- Metamethod handling ------------------------------------------------- */
954

955
/* Prepare to record call to metamethod. */
956
static BCReg rec_mm_prep(jit_State *J, ASMFunction cont)
728✔
957
{
958
  BCReg s, top = cont == lj_cont_cat ? J->maxslot : curr_proto(J->L)->framesize;
728✔
959
#if LJ_FR2
960
  J->base[top] = lj_ir_k64(J, IR_KNUM, u64ptr(contptr(cont)));
728✔
961
  J->base[top+1] = TREF_CONT;
728✔
962
#else
963
  J->base[top] = lj_ir_kptr(J, contptr(cont)) | TREF_CONT;
964
#endif
965
  J->framedepth++;
728✔
966
  for (s = J->maxslot; s < top; s++)
2,410✔
967
    J->base[s] = 0;  /* Clear frame gap to avoid resurrecting previous refs. */
1,682✔
968
  return top+1+LJ_FR2;
728✔
969
}
970

971
/* Record metamethod lookup. */
972
int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm)
11,266✔
973
{
974
  RecordIndex mix;
11,266✔
975
  GCtab *mt;
11,266✔
976
  if (tref_istab(ix->tab)) {
11,266✔
977
    mt = tabref(tabV(&ix->tabv)->metatable);
10,375✔
978
    mix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_TAB_META);
10,375✔
979
  } else if (tref_isudata(ix->tab)) {
891✔
980
    int udtype = udataV(&ix->tabv)->udtype;
40✔
981
    mt = tabref(udataV(&ix->tabv)->metatable);
40✔
982
    /* The metatables of special userdata objects are treated as immutable. */
983
    if (udtype != UDTYPE_USERDATA) {
40✔
984
      cTValue *mo;
35✔
985
      if (LJ_HASFFI && udtype == UDTYPE_FFI_CLIB) {
35✔
986
        /* Specialize to the C library namespace object. */
987
        emitir(IRTG(IR_EQ, IRT_PGC), ix->tab, lj_ir_kptr(J, udataV(&ix->tabv)));
35✔
988
      } else {
989
        /* Specialize to the type of userdata. */
990
        TRef tr = emitir(IRT(IR_FLOAD, IRT_U8), ix->tab, IRFL_UDATA_UDTYPE);
×
991
        emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, udtype));
×
992
      }
993
  immutable_mt:
678✔
994
      mo = lj_tab_getstr(mt, mmname_str(J2G(J), mm));
678✔
995
      if (!mo || tvisnil(mo))
678✔
996
        return 0;  /* No metamethod. */
997
      /* Treat metamethod or index table as immutable, too. */
998
      if (!(tvisfunc(mo) || tvistab(mo)))
678✔
999
        lj_trace_err(J, LJ_TRERR_BADTYPE);
×
1000
      copyTV(J->L, &ix->mobjv, mo);
678✔
1001
      ix->mobj = lj_ir_kgc(J, gcV(mo), tvisfunc(mo) ? IRT_FUNC : IRT_TAB);
678✔
1002
      ix->mtv = mt;
678✔
1003
      ix->mt = TREF_NIL;  /* Dummy value for comparison semantics. */
678✔
1004
      return 1;  /* Got metamethod or index table. */
678✔
1005
    }
1006
    mix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_UDATA_META);
5✔
1007
  } else {
1008
    /* Specialize to base metatable. Must flush mcode in lua_setmetatable(). */
1009
    mt = tabref(basemt_obj(J2G(J), &ix->tabv));
851✔
1010
    if (mt == NULL) {
851✔
1011
      ix->mt = TREF_NIL;
50✔
1012
      return 0;  /* No metamethod. */
50✔
1013
    }
1014
    /* The cdata metatable is treated as immutable. */
1015
    if (LJ_HASFFI && tref_iscdata(ix->tab)) goto immutable_mt;
801✔
1016
#if LJ_GC64
1017
    /* TODO: fix ARM32 asm_fload(), so we can use this for all archs. */
1018
    ix->mt = mix.tab = lj_ir_ggfload(J, IRT_TAB,
315✔
1019
      GG_OFS(g.gcroot[GCROOT_BASEMT+itypemap(&ix->tabv)]));
157✔
1020
#else
1021
    ix->mt = mix.tab = lj_ir_ktab(J, mt);
1022
#endif
1023
    goto nocheck;
158✔
1024
  }
1025
  ix->mt = mt ? mix.tab : TREF_NIL;
10,380✔
1026
  emitir(IRTG(mt ? IR_NE : IR_EQ, IRT_TAB), mix.tab, lj_ir_knull(J, IRT_TAB));
20,377✔
1027
nocheck:
10,538✔
1028
  if (mt) {
10,538✔
1029
    GCstr *mmstr = mmname_str(J2G(J), mm);
541✔
1030
    cTValue *mo = lj_tab_getstr(mt, mmstr);
541✔
1031
    if (mo && !tvisnil(mo))
541✔
1032
      copyTV(J->L, &ix->mobjv, mo);
483✔
1033
    ix->mtv = mt;
541✔
1034
    settabV(J->L, &mix.tabv, mt);
541✔
1035
    setstrV(J->L, &mix.keyv, mmstr);
541✔
1036
    mix.key = lj_ir_kstr(J, mmstr);
541✔
1037
    mix.val = 0;
541✔
1038
    mix.idxchain = 0;
541✔
1039
    ix->mobj = lj_record_idx(J, &mix);
541✔
1040
    return !tref_isnil(ix->mobj);  /* 1 if metamethod found, 0 if not. */
541✔
1041
  }
1042
  return 0;  /* No metamethod. */
1043
}
1044

1045
/* Record call to arithmetic metamethod. */
1046
static TRef rec_mm_arith(jit_State *J, RecordIndex *ix, MMS mm)
162✔
1047
{
1048
  /* Set up metamethod call first to save ix->tab and ix->tabv. */
1049
  BCReg func = rec_mm_prep(J, mm == MM_concat ? lj_cont_cat : lj_cont_ra);
318✔
1050
  TRef *base = J->base + func;
162✔
1051
  TValue *basev = J->L->base + func;
162✔
1052
  base[1+LJ_FR2] = ix->tab; base[2+LJ_FR2] = ix->key;
162✔
1053
  copyTV(J->L, basev+1+LJ_FR2, &ix->tabv);
162✔
1054
  copyTV(J->L, basev+2+LJ_FR2, &ix->keyv);
162✔
1055
  if (!lj_record_mm_lookup(J, ix, mm)) {  /* Lookup mm on 1st operand. */
162✔
1056
    if (mm != MM_unm) {
9✔
1057
      ix->tab = ix->key;
9✔
1058
      copyTV(J->L, &ix->tabv, &ix->keyv);
9✔
1059
      if (lj_record_mm_lookup(J, ix, mm))  /* Lookup mm on 2nd operand. */
9✔
1060
        goto ok;
9✔
1061
    }
1062
    lj_trace_err(J, LJ_TRERR_NOMM);
×
1063
  }
1064
ok:
153✔
1065
  base[0] = ix->mobj;
162✔
1066
#if LJ_FR2
1067
  base[1] = 0;
162✔
1068
#endif
1069
  copyTV(J->L, basev+0, &ix->mobjv);
162✔
1070
  lj_record_call(J, func, 2);
162✔
1071
  return 0;  /* No result yet. */
161✔
1072
}
1073

1074
/* Record call to __len metamethod. */
1075
static TRef rec_mm_len(jit_State *J, TRef tr, TValue *tv)
1076
{
1077
  RecordIndex ix;
1078
  ix.tab = tr;
1079
  copyTV(J->L, &ix.tabv, tv);
1080
  if (lj_record_mm_lookup(J, &ix, MM_len)) {
1081
    BCReg func = rec_mm_prep(J, lj_cont_ra);
1082
    TRef *base = J->base + func;
1083
    TValue *basev = J->L->base + func;
1084
    base[0] = ix.mobj; copyTV(J->L, basev+0, &ix.mobjv);
1085
    base += LJ_FR2;
1086
    basev += LJ_FR2;
1087
    base[1] = tr; copyTV(J->L, basev+1, tv);
1088
#if LJ_52
1089
    base[2] = tr; copyTV(J->L, basev+2, tv);
1090
#else
1091
    base[2] = TREF_NIL; setnilV(basev+2);
1092
#endif
1093
    lj_record_call(J, func, 2);
1094
  } else {
1095
    if (LJ_52 && tref_istab(tr))
1096
      return lj_ir_call(J, IRCALL_lj_tab_len, tr);
1097
    lj_trace_err(J, LJ_TRERR_NOMM);
1098
  }
1099
  return 0;  /* No result yet. */
1100
}
1101

1102
/* Call a comparison metamethod. */
1103
static void rec_mm_callcomp(jit_State *J, RecordIndex *ix, int op)
160✔
1104
{
1105
  BCReg func = rec_mm_prep(J, (op&1) ? lj_cont_condf : lj_cont_condt);
230✔
1106
  TRef *base = J->base + func + LJ_FR2;
160✔
1107
  TValue *tv = J->L->base + func + LJ_FR2;
160✔
1108
  base[-LJ_FR2] = ix->mobj; base[1] = ix->val; base[2] = ix->key;
160✔
1109
  copyTV(J->L, tv-LJ_FR2, &ix->mobjv);
160✔
1110
  copyTV(J->L, tv+1, &ix->valv);
160✔
1111
  copyTV(J->L, tv+2, &ix->keyv);
160✔
1112
  lj_record_call(J, func, 2);
160✔
1113
}
160✔
1114

1115
/* Record call to equality comparison metamethod (for tab and udata only). */
1116
static void rec_mm_equal(jit_State *J, RecordIndex *ix, int op)
10✔
1117
{
1118
  ix->tab = ix->val;
10✔
1119
  copyTV(J->L, &ix->tabv, &ix->valv);
10✔
1120
  if (lj_record_mm_lookup(J, ix, MM_eq)) {  /* Lookup mm on 1st operand. */
10✔
1121
    cTValue *bv;
9✔
1122
    TRef mo1 = ix->mobj;
9✔
1123
    TValue mo1v;
9✔
1124
    copyTV(J->L, &mo1v, &ix->mobjv);
9✔
1125
    /* Avoid the 2nd lookup and the objcmp if the metatables are equal. */
1126
    bv = &ix->keyv;
9✔
1127
    if (tvistab(bv) && tabref(tabV(bv)->metatable) == ix->mtv) {
18✔
1128
      TRef mt2 = emitir(IRT(IR_FLOAD, IRT_TAB), ix->key, IRFL_TAB_META);
9✔
1129
      emitir(IRTG(IR_EQ, IRT_TAB), mt2, ix->mt);
9✔
1130
    } else if (tvisudata(bv) && tabref(udataV(bv)->metatable) == ix->mtv) {
×
1131
      TRef mt2 = emitir(IRT(IR_FLOAD, IRT_TAB), ix->key, IRFL_UDATA_META);
×
1132
      emitir(IRTG(IR_EQ, IRT_TAB), mt2, ix->mt);
×
1133
    } else {  /* Lookup metamethod on 2nd operand and compare both. */
1134
      ix->tab = ix->key;
×
1135
      copyTV(J->L, &ix->tabv, bv);
×
1136
      if (!lj_record_mm_lookup(J, ix, MM_eq) ||
×
1137
          lj_record_objcmp(J, mo1, ix->mobj, &mo1v, &ix->mobjv))
×
1138
        return;
×
1139
    }
1140
    rec_mm_callcomp(J, ix, op);
9✔
1141
  }
1142
}
1143

1144
/* Record call to ordered comparison metamethods (for arbitrary objects). */
1145
static void rec_mm_comp(jit_State *J, RecordIndex *ix, int op)
49✔
1146
{
1147
  ix->tab = ix->val;
49✔
1148
  copyTV(J->L, &ix->tabv, &ix->valv);
49✔
1149
  while (1) {
67✔
1150
    MMS mm = (op & 2) ? MM_le : MM_lt;  /* Try __le + __lt or only __lt. */
58✔
1151
#if LJ_52
1152
    if (!lj_record_mm_lookup(J, ix, mm)) {  /* Lookup mm on 1st operand. */
1153
      ix->tab = ix->key;
1154
      copyTV(J->L, &ix->tabv, &ix->keyv);
1155
      if (!lj_record_mm_lookup(J, ix, mm))  /* Lookup mm on 2nd operand. */
1156
        goto nomatch;
1157
    }
1158
    rec_mm_callcomp(J, ix, op);
1159
    return;
1160
#else
1161
    if (lj_record_mm_lookup(J, ix, mm)) {  /* Lookup mm on 1st operand. */
58✔
1162
      cTValue *bv;
49✔
1163
      TRef mo1 = ix->mobj;
49✔
1164
      TValue mo1v;
49✔
1165
      copyTV(J->L, &mo1v, &ix->mobjv);
49✔
1166
      /* Avoid the 2nd lookup and the objcmp if the metatables are equal. */
1167
      bv = &ix->keyv;
49✔
1168
      if (tvistab(bv) && tabref(tabV(bv)->metatable) == ix->mtv) {
98✔
1169
        TRef mt2 = emitir(IRT(IR_FLOAD, IRT_TAB), ix->key, IRFL_TAB_META);
49✔
1170
        emitir(IRTG(IR_EQ, IRT_TAB), mt2, ix->mt);
49✔
1171
      } else if (tvisudata(bv) && tabref(udataV(bv)->metatable) == ix->mtv) {
×
1172
        TRef mt2 = emitir(IRT(IR_FLOAD, IRT_TAB), ix->key, IRFL_UDATA_META);
×
1173
        emitir(IRTG(IR_EQ, IRT_TAB), mt2, ix->mt);
×
1174
      } else {  /* Lookup metamethod on 2nd operand and compare both. */
1175
        ix->tab = ix->key;
×
1176
        copyTV(J->L, &ix->tabv, bv);
×
1177
        if (!lj_record_mm_lookup(J, ix, mm) ||
×
1178
            lj_record_objcmp(J, mo1, ix->mobj, &mo1v, &ix->mobjv))
×
1179
          goto nomatch;
×
1180
      }
1181
      rec_mm_callcomp(J, ix, op);
49✔
1182
      return;
49✔
1183
    }
1184
#endif
1185
  nomatch:
9✔
1186
    /* Lookup failed. Retry with  __lt and swapped operands. */
1187
    if (!(op & 2)) break;  /* Already at __lt. Interpreter will throw. */
9✔
1188
    ix->tab = ix->key; ix->key = ix->val; ix->val = ix->tab;
9✔
1189
    copyTV(J->L, &ix->tabv, &ix->keyv);
9✔
1190
    copyTV(J->L, &ix->keyv, &ix->valv);
9✔
1191
    copyTV(J->L, &ix->valv, &ix->tabv);
9✔
1192
    op ^= 3;
9✔
1193
  }
1194
}
1195

1196
#if LJ_HASFFI
1197
/* Setup call to cdata comparison metamethod. */
1198
static void rec_mm_comp_cdata(jit_State *J, RecordIndex *ix, int op, MMS mm)
102✔
1199
{
1200
  lj_snap_add(J);
102✔
1201
  if (tref_iscdata(ix->val)) {
102✔
1202
    ix->tab = ix->val;
14✔
1203
    copyTV(J->L, &ix->tabv, &ix->valv);
14✔
1204
  } else {
1205
    lj_assertJ(tref_iscdata(ix->key), "cdata expected");
88✔
1206
    ix->tab = ix->key;
88✔
1207
    copyTV(J->L, &ix->tabv, &ix->keyv);
88✔
1208
  }
1209
  lj_record_mm_lookup(J, ix, mm);
102✔
1210
  rec_mm_callcomp(J, ix, op);
102✔
1211
}
102✔
1212
#endif
1213

1214
/* -- Indexed access ------------------------------------------------------ */
1215

1216
#ifdef LUAJIT_ENABLE_TABLE_BUMP
1217
/* Bump table allocations in bytecode when they grow during recording. */
1218
static void rec_idx_bump(jit_State *J, RecordIndex *ix)
1219
{
1220
  RBCHashEntry *rbc = &J->rbchash[(ix->tab & (RBCHASH_SLOTS-1))];
1221
  if (tref_ref(ix->tab) == rbc->ref) {
1222
    const BCIns *pc = mref(rbc->pc, const BCIns);
1223
    GCtab *tb = tabV(&ix->tabv);
1224
    uint32_t nhbits;
1225
    IRIns *ir;
1226
    if (!tvisnil(&ix->keyv))
1227
      (void)lj_tab_set(J->L, tb, &ix->keyv);  /* Grow table right now. */
1228
    nhbits = tb->hmask > 0 ? lj_fls(tb->hmask)+1 : 0;
1229
    ir = IR(tref_ref(ix->tab));
1230
    if (ir->o == IR_TNEW) {
1231
      uint32_t ah = bc_d(*pc);
1232
      uint32_t asize = ah & 0x7ff, hbits = ah >> 11;
1233
      if (nhbits > hbits) hbits = nhbits;
1234
      if (tb->asize > asize) {
1235
        asize = tb->asize <= 0x7ff ? tb->asize : 0x7ff;
1236
      }
1237
      if ((asize | (hbits<<11)) != ah) {  /* Has the size changed? */
1238
        /* Patch bytecode, but continue recording (for more patching). */
1239
        setbc_d(pc, (asize | (hbits<<11)));
1240
        /* Patching TNEW operands is only safe if the trace is aborted. */
1241
        ir->op1 = asize; ir->op2 = hbits;
1242
        J->retryrec = 1;  /* Abort the trace at the end of recording. */
1243
      }
1244
    } else if (ir->o == IR_TDUP) {
1245
      GCtab *tpl = gco2tab(proto_kgc(&gcref(rbc->pt)->pt, ~(ptrdiff_t)bc_d(*pc)));
1246
      /* Grow template table, but preserve keys with nil values. */
1247
      if ((tb->asize > tpl->asize && (1u << nhbits)-1 == tpl->hmask) ||
1248
          (tb->asize == tpl->asize && (1u << nhbits)-1 > tpl->hmask)) {
1249
        Node *node = noderef(tpl->node);
1250
        uint32_t i, hmask = tpl->hmask, asize;
1251
        TValue *array;
1252
        for (i = 0; i <= hmask; i++) {
1253
          if (!tvisnil(&node[i].key) && tvisnil(&node[i].val))
1254
            settabV(J->L, &node[i].val, tpl);
1255
        }
1256
        if (!tvisnil(&ix->keyv) && tref_isk(ix->key)) {
1257
          TValue *o = lj_tab_set(J->L, tpl, &ix->keyv);
1258
          if (tvisnil(o)) settabV(J->L, o, tpl);
1259
        }
1260
        lj_tab_resize(J->L, tpl, tb->asize, nhbits);
1261
        node = noderef(tpl->node);
1262
        hmask = tpl->hmask;
1263
        for (i = 0; i <= hmask; i++) {
1264
          /* This is safe, since template tables only hold immutable values. */
1265
          if (tvistab(&node[i].val))
1266
            setnilV(&node[i].val);
1267
        }
1268
        /* The shape of the table may have changed. Clean up array part, too. */
1269
        asize = tpl->asize;
1270
        array = tvref(tpl->array);
1271
        for (i = 0; i < asize; i++) {
1272
          if (tvistab(&array[i]))
1273
            setnilV(&array[i]);
1274
        }
1275
        J->retryrec = 1;  /* Abort the trace at the end of recording. */
1276
      }
1277
    }
1278
  }
1279
}
1280
#endif
1281

1282
/* Record bounds-check. */
1283
static void rec_idx_abc(jit_State *J, TRef asizeref, TRef ikey, uint32_t asize)
4,992✔
1284
{
1285
  /* Try to emit invariant bounds checks. */
1286
  if ((J->flags & (JIT_F_OPT_LOOP|JIT_F_OPT_ABC)) ==
4,992✔
1287
      (JIT_F_OPT_LOOP|JIT_F_OPT_ABC)) {
1288
    IRRef ref = tref_ref(ikey);
4,981✔
1289
    IRIns *ir = IR(ref);
4,981✔
1290
    int32_t ofs = 0;
4,981✔
1291
    IRRef ofsref = 0;
4,981✔
1292
    /* Handle constant offsets. */
1293
    if (ir->o == IR_ADD && irref_isk(ir->op2)) {
4,981✔
1294
      ofsref = ir->op2;
144✔
1295
      ofs = IR(ofsref)->i;
144✔
1296
      ref = ir->op1;
144✔
1297
      ir = IR(ref);
144✔
1298
    }
1299
    /* Got scalar evolution analysis results for this reference? */
1300
    if (ref == J->scev.idx) {
4,981✔
1301
      int32_t stop;
3,661✔
1302
      lj_assertJ(irt_isint(J->scev.t) && ir->o == IR_SLOAD,
3,661✔
1303
                 "only int SCEV supported");
1304
      stop = numberVint(&(J->L->base - J->baseslot)[ir->op1 + FORL_STOP]);
3,661✔
1305
      /* Runtime value for stop of loop is within bounds? */
1306
      if ((uint64_t)stop + ofs < (uint64_t)asize) {
3,661✔
1307
        /* Emit invariant bounds check for stop. */
1308
        emitir(IRTG(IR_ABC, IRT_P32), asizeref, ofs == 0 ? J->scev.stop :
111✔
1309
               emitir(IRTI(IR_ADD), J->scev.stop, ofsref));
1310
        /* Emit invariant bounds check for start, if not const or negative. */
1311
        if (!(J->scev.dir && J->scev.start &&
111✔
1312
              (int64_t)IR(J->scev.start)->i + ofs >= 0))
101✔
1313
          emitir(IRTG(IR_ABC, IRT_P32), asizeref, ikey);
10✔
1314
        return;
111✔
1315
      }
1316
    }
1317
  }
1318
  emitir(IRTGI(IR_ABC), asizeref, ikey);  /* Emit regular bounds check. */
4,881✔
1319
}
1320

1321
/* Record indexed key lookup. */
1322
static TRef rec_idx_key(jit_State *J, RecordIndex *ix, IRRef *rbref,
118,287✔
1323
                        IRType1 *rbguard)
1324
{
1325
  TRef key;
118,287✔
1326
  GCtab *t = tabV(&ix->tabv);
118,287✔
1327
  ix->oldv = lj_tab_get(J->L, t, &ix->keyv);  /* Lookup previous value. */
118,287✔
1328
  *rbref = 0;
118,287✔
1329
  rbguard->irt = 0;
118,287✔
1330

1331
  /* Integer keys are looked up in the array part first. */
1332
  key = ix->key;
118,287✔
1333
  if (tref_isnumber(key)) {
118,287✔
1334
    int32_t k = numberVint(&ix->keyv);
5,283✔
1335
    if (!tvisint(&ix->keyv) && numV(&ix->keyv) != (lua_Number)k)
5,283✔
1336
      k = LJ_MAX_ASIZE;
49✔
1337
    if ((MSize)k < LJ_MAX_ASIZE) {  /* Potential array key? */
5,283✔
1338
      TRef ikey = lj_opt_narrow_index(J, key);
5,203✔
1339
      TRef asizeref = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_ASIZE);
5,203✔
1340
      if ((MSize)k < t->asize) {  /* Currently an array key? */
5,203✔
1341
        TRef arrayref;
4,989✔
1342
        rec_idx_abc(J, asizeref, ikey, t->asize);
4,989✔
1343
        arrayref = emitir(IRT(IR_FLOAD, IRT_PGC), ix->tab, IRFL_TAB_ARRAY);
4,989✔
1344
        return emitir(IRT(IR_AREF, IRT_PGC), arrayref, ikey);
4,989✔
1345
      } else {  /* Currently not in array (may be an array extension)? */
1346
        emitir(IRTGI(IR_ULE), asizeref, ikey);  /* Inv. bounds check. */
214✔
1347
        if (k == 0 && tref_isk(key))
214✔
1348
          key = lj_ir_knum_zero(J);  /* Canonicalize 0 or +-0.0 to +0.0. */
4✔
1349
        /* And continue with the hash lookup. */
1350
      }
1351
    } else if (!tref_isk(key)) {
80✔
1352
      /* We can rule out const numbers which failed the integerness test
1353
      ** above. But all other numbers are potential array keys.
1354
      */
1355
      if (t->asize == 0) {  /* True sparse tables have an empty array part. */
80✔
1356
        /* Guard that the array part stays empty. */
1357
        TRef tmp = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_ASIZE);
71✔
1358
        emitir(IRTGI(IR_EQ), tmp, lj_ir_kint(J, 0));
71✔
1359
      } else {
1360
        lj_trace_err(J, LJ_TRERR_NYITMIX);
9✔
1361
      }
1362
    }
1363
  }
1364

1365
  /* Otherwise the key is located in the hash part. */
1366
  if (t->hmask == 0) {  /* Shortcut for empty hash part. */
113,289✔
1367
    /* Guard that the hash part stays empty. */
1368
    TRef tmp = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_HMASK);
433✔
1369
    emitir(IRTGI(IR_EQ), tmp, lj_ir_kint(J, 0));
433✔
1370
    return lj_ir_kkptr(J, niltvg(J2G(J)));
433✔
1371
  }
1372
  if (tref_isinteger(key))  /* Hash keys are based on numbers, not ints. */
112,856✔
1373
    key = emitir(IRTN(IR_CONV), key, IRCONV_NUM_INT);
81✔
1374
  if (tref_isk(key)) {
112,856✔
1375
    /* Optimize lookup of constant hash keys. */
1376
    MSize hslot = (MSize)((char *)ix->oldv - (char *)&noderef(t->node)[0].val);
112,642✔
1377
    if (t->hmask > 0 && hslot <= t->hmask*(MSize)sizeof(Node) &&
112,642✔
1378
        hslot <= 65535*(MSize)sizeof(Node)) {
1379
      TRef node, kslot, hm;
104,676✔
1380
      *rbref = J->cur.nins;  /* Mark possible rollback point. */
104,676✔
1381
      *rbguard = J->guardemit;
104,676✔
1382
      hm = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_HMASK);
104,676✔
1383
      emitir(IRTGI(IR_EQ), hm, lj_ir_kint(J, (int32_t)t->hmask));
104,676✔
1384
      node = emitir(IRT(IR_FLOAD, IRT_PGC), ix->tab, IRFL_TAB_NODE);
104,676✔
1385
      kslot = lj_ir_kslot(J, key, hslot / sizeof(Node));
104,676✔
1386
      return emitir(IRTG(IR_HREFK, IRT_PGC), node, kslot);
104,676✔
1387
    }
1388
  }
1389
  /* Fall back to a regular hash lookup. */
1390
  return emitir(IRT(IR_HREF, IRT_PGC), ix->tab, key);
8,180✔
1391
}
1392

1393
/* Determine whether a key is NOT one of the fast metamethod names. */
1394
static int nommstr(jit_State *J, TRef key)
52,261✔
1395
{
1396
  if (tref_isstr(key)) {
52,261✔
1397
    if (tref_isk(key)) {
49,442✔
1398
      GCstr *str = ir_kstr(IR(tref_ref(key)));
49,431✔
1399
      uint32_t mm;
49,431✔
1400
      for (mm = 0; mm <= MM_FAST; mm++)
346,017✔
1401
        if (mmname_str(J2G(J), mm) == str)
296,586✔
1402
          return 0;  /* MUST be one the fast metamethod names. */
1403
    } else {
1404
      return 0;  /* Variable string key MAY be a metamethod name. */
1405
    }
1406
  }
1407
  return 1;  /* CANNOT be a metamethod name. */
1408
}
1409

1410
/* Record indexed load/store. */
1411
TRef lj_record_idx(jit_State *J, RecordIndex *ix)
118,475✔
1412
{
1413
  TRef xref;
118,475✔
1414
  IROp xrefop, loadop;
118,475✔
1415
  IRRef rbref;
118,475✔
1416
  IRType1 rbguard;
118,475✔
1417
  cTValue *oldv;
118,475✔
1418

1419
  while (!tref_istab(ix->tab)) { /* Handle non-table lookup. */
118,839✔
1420
    /* Never call raw lj_record_idx() on non-table. */
1421
    lj_assertJ(ix->idxchain != 0, "bad usage");
550✔
1422
    if (!lj_record_mm_lookup(J, ix, ix->val ? MM_newindex : MM_index))
550✔
1423
      lj_trace_err(J, LJ_TRERR_NOMM);
×
1424
  handlemm:
550✔
1425
    if (tref_isfunc(ix->mobj)) {  /* Handle metamethod call. */
769✔
1426
      BCReg func = rec_mm_prep(J, ix->val ? lj_cont_nop : lj_cont_ra);
702✔
1427
      TRef *base = J->base + func + LJ_FR2;
405✔
1428
      TValue *tv = J->L->base + func + LJ_FR2;
405✔
1429
      base[-LJ_FR2] = ix->mobj; base[1] = ix->tab; base[2] = ix->key;
405✔
1430
      setfuncV(J->L, tv-LJ_FR2, funcV(&ix->mobjv));
405✔
1431
      copyTV(J->L, tv+1, &ix->tabv);
405✔
1432
      copyTV(J->L, tv+2, &ix->keyv);
405✔
1433
      if (ix->val) {
405✔
1434
        base[3] = ix->val;
108✔
1435
        copyTV(J->L, tv+3, &ix->valv);
108✔
1436
        lj_record_call(J, func, 3);  /* mobj(tab, key, val) */
108✔
1437
        return 0;
108✔
1438
      } else {
1439
        lj_record_call(J, func, 2);  /* res = mobj(tab, key) */
297✔
1440
        return 0;  /* No result yet. */
297✔
1441
      }
1442
    }
1443
    /* Otherwise retry lookup with metaobject. */
1444
    ix->tab = ix->mobj;
364✔
1445
    copyTV(J->L, &ix->tabv, &ix->mobjv);
364✔
1446
    if (--ix->idxchain == 0)
364✔
1447
      lj_trace_err(J, LJ_TRERR_IDXLOOP);
×
1448
  }
1449

1450
  /* First catch nil and NaN keys for tables. */
1451
  if (tvisnil(&ix->keyv) || (tvisnum(&ix->keyv) && tvisnan(&ix->keyv))) {
118,289✔
1452
    if (ix->val)  /* Better fail early. */
2✔
1453
      lj_trace_err(J, LJ_TRERR_STORENN);
2✔
1454
    if (tref_isk(ix->key)) {
×
1455
      if (ix->idxchain && lj_record_mm_lookup(J, ix, MM_index))
×
1456
        goto handlemm;
×
1457
      return TREF_NIL;
×
1458
    }
1459
  }
1460

1461
  /* Record the key lookup. */
1462
  xref = rec_idx_key(J, ix, &rbref, &rbguard);
118,287✔
1463
  xrefop = IR(tref_ref(xref))->o;
118,278✔
1464
  loadop = xrefop == IR_AREF ? IR_ALOAD : IR_HLOAD;
118,278✔
1465
  /* The lj_meta_tset() inconsistency is gone, but better play safe. */
1466
  oldv = xrefop == IR_KKPTR ? (cTValue *)ir_kptr(IR(tref_ref(xref))) : ix->oldv;
118,278✔
1467

1468
  if (ix->val == 0) {  /* Indexed load */
118,278✔
1469
    IRType t = itype2irt(oldv);
66,007✔
1470
    TRef res;
66,007✔
1471
    if (oldv == niltvg(J2G(J))) {
66,007✔
1472
      emitir(IRTG(IR_EQ, IRT_PGC), xref, lj_ir_kkptr(J, niltvg(J2G(J))));
1,273✔
1473
      res = TREF_NIL;
1,273✔
1474
    } else {
1475
      res = emitir(IRTG(loadop, t), xref, 0);
64,734✔
1476
    }
1477
    if (tref_ref(res) < rbref) {  /* HREFK + load forwarded? */
66,007✔
1478
      lj_ir_rollback(J, rbref);  /* Rollback to eliminate hmask guard. */
5,459✔
1479
      J->guardemit = rbguard;
5,459✔
1480
    }
1481
    if (t == IRT_NIL && ix->idxchain && lj_record_mm_lookup(J, ix, MM_index))
66,007✔
1482
      goto handlemm;
209✔
1483
    if (irtype_ispri(t)) res = TREF_PRI(t);  /* Canonicalize primitives. */
65,798✔
1484
    return res;
65,798✔
1485
  } else {  /* Indexed store. */
1486
    GCtab *mt = tabref(tabV(&ix->tabv)->metatable);
52,271✔
1487
    int keybarrier = tref_isgcv(ix->key) && !tref_isnil(ix->val);
52,271✔
1488
    if (tref_ref(xref) < rbref) {  /* HREFK forwarded? */
52,271✔
1489
      lj_ir_rollback(J, rbref);  /* Rollback to eliminate hmask guard. */
635✔
1490
      J->guardemit = rbguard;
635✔
1491
    }
1492
    if (tvisnil(oldv)) {  /* Previous value was nil? */
52,271✔
1493
      /* Need to duplicate the hasmm check for the early guards. */
1494
      int hasmm = 0;
8,446✔
1495
      if (ix->idxchain && mt) {
8,446✔
1496
        cTValue *mo = lj_tab_getstr(mt, mmname_str(J2G(J), MM_newindex));
24✔
1497
        hasmm = mo && !tvisnil(mo);
24✔
1498
      }
1499
      if (hasmm)
10✔
1500
        emitir(IRTG(loadop, IRT_NIL), xref, 0);  /* Guard for nil value. */
10✔
1501
      else if (xrefop == IR_HREF)
8,436✔
1502
        emitir(IRTG(oldv == niltvg(J2G(J)) ? IR_EQ : IR_NE, IRT_PGC),
6,844✔
1503
               xref, lj_ir_kkptr(J, niltvg(J2G(J))));
1504
      if (ix->idxchain && lj_record_mm_lookup(J, ix, MM_newindex)) {
8,446✔
1505
        lj_assertJ(hasmm, "inconsistent metamethod handling");
10✔
1506
        goto handlemm;
10✔
1507
      }
1508
      lj_assertJ(!hasmm, "inconsistent metamethod handling");
8,436✔
1509
      if (oldv == niltvg(J2G(J))) {  /* Need to insert a new key. */
8,436✔
1510
        TRef key = ix->key;
7,219✔
1511
        if (tref_isinteger(key)) {  /* NEWREF needs a TValue as a key. */
7,219✔
1512
          key = emitir(IRTN(IR_CONV), key, IRCONV_NUM_INT);
129✔
1513
        } else if (tref_isnum(key)) {
7,090✔
1514
          if (tref_isk(key)) {
50✔
1515
            if (tvismzero(&ix->keyv))
2✔
1516
              key = lj_ir_knum_zero(J);  /* Canonicalize -0.0 to +0.0. */
2✔
1517
          } else {
1518
            emitir(IRTG(IR_EQ, IRT_NUM), key, key);  /* Check for !NaN. */
48✔
1519
          }
1520
        }
1521
        xref = emitir(IRT(IR_NEWREF, IRT_PGC), ix->tab, key);
7,219✔
1522
        keybarrier = 0;  /* NEWREF already takes care of the key barrier. */
7,219✔
1523
#ifdef LUAJIT_ENABLE_TABLE_BUMP
1524
        if ((J->flags & JIT_F_OPT_SINK))  /* Avoid a separate flag. */
1525
          rec_idx_bump(J, ix);
1526
#endif
1527
      }
1528
    } else if (!lj_opt_fwd_wasnonnil(J, loadop, tref_ref(xref))) {
43,825✔
1529
      /* Cannot derive that the previous value was non-nil, must do checks. */
1530
      if (xrefop == IR_HREF)  /* Guard against store to niltv. */
41,252✔
1531
        emitir(IRTG(IR_NE, IRT_PGC), xref, lj_ir_kkptr(J, niltvg(J2G(J))));
13✔
1532
      if (ix->idxchain) {  /* Metamethod lookup required? */
41,252✔
1533
        /* A check for NULL metatable is cheaper (hoistable) than a load. */
1534
        if (!mt) {
41,243✔
1535
          TRef mtref = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_TAB_META);
41,227✔
1536
          emitir(IRTG(IR_EQ, IRT_TAB), mtref, lj_ir_knull(J, IRT_TAB));
41,227✔
1537
        } else {
1538
          IRType t = itype2irt(oldv);
16✔
1539
          emitir(IRTG(loadop, t), xref, 0);  /* Guard for non-nil value. */
16✔
1540
        }
1541
      }
1542
    } else {
1543
      keybarrier = 0;  /* Previous non-nil value kept the key alive. */
1544
    }
1545
    /* Convert int to number before storing. */
1546
    if (!LJ_DUALNUM && tref_isinteger(ix->val))
52,261✔
1547
      ix->val = emitir(IRTN(IR_CONV), ix->val, IRCONV_NUM_INT);
597✔
1548
    emitir(IRT(loadop+IRDELTA_L2S, tref_type(ix->val)), xref, ix->val);
52,261✔
1549
    if (keybarrier || tref_isgcv(ix->val))
52,261✔
1550
      emitir(IRT(IR_TBAR, IRT_NIL), ix->tab, 0);
43,120✔
1551
    /* Invalidate neg. metamethod cache for stores with certain string keys. */
1552
    if (!nommstr(J, ix->key)) {
101,692✔
1553
      TRef fref = emitir(IRT(IR_FREF, IRT_PGC), ix->tab, IRFL_TAB_NOMM);
11✔
1554
      emitir(IRT(IR_FSTORE, IRT_U8), fref, lj_ir_kint(J, 0));
11✔
1555
    }
1556
    J->needsnap = 1;
52,261✔
1557
    return 0;
52,261✔
1558
  }
1559
}
1560

1561
static void rec_tsetm(jit_State *J, BCReg ra, BCReg rn, int32_t i)
5✔
1562
{
1563
  RecordIndex ix;
5✔
1564
  cTValue *basev = J->L->base;
5✔
1565
  GCtab *t = tabV(&basev[ra-1]);
5✔
1566
  settabV(J->L, &ix.tabv, t);
5✔
1567
  ix.tab = getslot(J, ra-1);
5✔
1568
  ix.idxchain = 0;
5✔
1569
#ifdef LUAJIT_ENABLE_TABLE_BUMP
1570
  if ((J->flags & JIT_F_OPT_SINK)) {
1571
    if (t->asize < i+rn-ra)
1572
      lj_tab_reasize(J->L, t, i+rn-ra);
1573
    setnilV(&ix.keyv);
1574
    rec_idx_bump(J, &ix);
1575
  }
1576
#endif
1577
  for (; ra < rn; i++, ra++) {
14✔
1578
    setintV(&ix.keyv, i);
9✔
1579
    ix.key = lj_ir_kint(J, i);
9✔
1580
    copyTV(J->L, &ix.valv, &basev[ra]);
9✔
1581
    ix.val = getslot(J, ra);
9✔
1582
    lj_record_idx(J, &ix);
9✔
1583
  }
1584
}
5✔
1585

1586
/* -- Upvalue access ------------------------------------------------------ */
1587

1588
/* Check whether upvalue is immutable and ok to constify. */
1589
static int rec_upvalue_constify(jit_State *J, GCupval *uvp)
1590
{
1591
  if (uvp->immutable) {
1592
    cTValue *o = uvval(uvp);
1593
    /* Don't constify objects that may retain large amounts of memory. */
1594
#if LJ_HASFFI
1595
    if (tviscdata(o)) {
1596
      GCcdata *cd = cdataV(o);
1597
      if (!cdataisv(cd) && !(cd->marked & LJ_GC_CDATA_FIN)) {
1598
        CType *ct = ctype_raw(ctype_ctsG(J2G(J)), cd->ctypeid);
1599
        if (!ctype_hassize(ct->info) || ct->size <= 16)
1600
          return 1;
1601
      }
1602
      return 0;
1603
    }
1604
#else
1605
    UNUSED(J);
1606
#endif
1607
    if (!(tvistab(o) || tvisudata(o) || tvisthread(o)))
1608
      return 1;
1609
  }
1610
  return 0;
1611
}
1612

1613
/* Record upvalue load/store. */
1614
static TRef rec_upvalue(jit_State *J, uint32_t uv, TRef val)
16,511✔
1615
{
1616
  GCupval *uvp = &gcref(J->fn->l.uvptr[uv])->uv;
16,511✔
1617
  TRef fn = getcurrf(J);
16,511✔
1618
  IRRef uref;
16,511✔
1619
  int needbarrier = 0;
16,511✔
1620
  if (rec_upvalue_constify(J, uvp)) {  /* Try to constify immutable upvalue. */
16,511✔
1621
    TRef tr, kfunc;
15,456✔
1622
    lj_assertJ(val == 0, "bad usage");
15,456✔
1623
    if (!tref_isk(fn)) {  /* Late specialization of current function. */
15,456✔
1624
      if (J->pt->flags >= PROTO_CLC_POLY)
2,411✔
1625
        goto noconstify;
84✔
1626
      kfunc = lj_ir_kfunc(J, J->fn);
2,327✔
1627
      emitir(IRTG(IR_EQ, IRT_FUNC), fn, kfunc);
2,327✔
1628
#if LJ_FR2
1629
      J->base[-2] = kfunc;
2,327✔
1630
#else
1631
      J->base[-1] = kfunc | TREF_FRAME;
1632
#endif
1633
      fn = kfunc;
2,327✔
1634
    }
1635
    tr = lj_record_constify(J, uvval(uvp));
15,372✔
1636
    if (tr)
15,372✔
1637
      return tr;
1638
  }
1639
noconstify:
1,055✔
1640
  /* Note: this effectively limits LJ_MAX_UPVAL to 127. */
1641
  uv = (uv << 8) | (hashrot(uvp->dhash, uvp->dhash + HASH_BIAS) & 0xff);
1,139✔
1642
  if (!uvp->closed) {
1,139✔
1643
    uref = tref_ref(emitir(IRTG(IR_UREFO, IRT_PGC), fn, uv));
374✔
1644
    /* In current stack? */
1645
    if (uvval(uvp) >= tvref(J->L->stack) &&
374✔
1646
        uvval(uvp) < tvref(J->L->maxstack)) {
374✔
1647
      int32_t slot = (int32_t)(uvval(uvp) - (J->L->base - J->baseslot));
365✔
1648
      if (slot >= 0) {  /* Aliases an SSA slot? */
365✔
1649
        emitir(IRTG(IR_EQ, IRT_PGC),
210✔
1650
               REF_BASE,
1651
               emitir(IRT(IR_ADD, IRT_PGC), uref,
1652
                      lj_ir_kint(J, (slot - 1 - LJ_FR2) * -8)));
1653
        slot -= (int32_t)J->baseslot;  /* Note: slot number may be negative! */
210✔
1654
        if (val == 0) {
210✔
1655
          return getslot(J, slot);
93✔
1656
        } else {
1657
          J->base[slot] = val;
117✔
1658
          if (slot >= (int32_t)J->maxslot) J->maxslot = (BCReg)(slot+1);
117✔
1659
          return 0;
117✔
1660
        }
1661
      }
1662
    }
1663
    emitir(IRTG(IR_UGT, IRT_PGC),
164✔
1664
           emitir(IRT(IR_SUB, IRT_PGC), uref, REF_BASE),
1665
           lj_ir_kint(J, (J->baseslot + J->maxslot) * 8));
1666
  } else {
1667
    needbarrier = 1;
765✔
1668
    uref = tref_ref(emitir(IRTG(IR_UREFC, IRT_PGC), fn, uv));
765✔
1669
  }
1670
  if (val == 0) {  /* Upvalue load */
929✔
1671
    IRType t = itype2irt(uvval(uvp));
878✔
1672
    TRef res = emitir(IRTG(IR_ULOAD, t), uref, 0);
878✔
1673
    if (irtype_ispri(t)) res = TREF_PRI(t);  /* Canonicalize primitive refs. */
878✔
1674
    return res;
878✔
1675
  } else {  /* Upvalue store. */
1676
    /* Convert int to number before storing. */
1677
    if (!LJ_DUALNUM && tref_isinteger(val))
51✔
1678
      val = emitir(IRTN(IR_CONV), val, IRCONV_NUM_INT);
1✔
1679
    emitir(IRT(IR_USTORE, tref_type(val)), uref, val);
51✔
1680
    if (needbarrier && tref_isgcv(val))
51✔
1681
      emitir(IRT(IR_OBAR, IRT_NIL), uref, val);
2✔
1682
    J->needsnap = 1;
51✔
1683
    return 0;
51✔
1684
  }
1685
}
1686

1687
/* -- Record calls to Lua functions --------------------------------------- */
1688

1689
/* Check unroll limits for calls. */
1690
static void check_call_unroll(jit_State *J, TraceNo lnk)
12,641✔
1691
{
1692
  cTValue *frame = J->L->base - 1;
12,641✔
1693
  void *pc = mref(frame_func(frame)->l.pc, void);
12,641✔
1694
  int32_t depth = J->framedepth;
12,641✔
1695
  int32_t count = 0;
12,641✔
1696
  if ((J->pt->flags & PROTO_VARARG)) depth--;  /* Vararg frame still missing. */
12,641✔
1697
  for (; depth > 0; depth--) {  /* Count frames with same prototype. */
35,276✔
1698
    if (frame_iscont(frame)) depth--;
22,635✔
1699
    frame = frame_prev(frame);
22,635✔
1700
    if (mref(frame_func(frame)->l.pc, void) == pc)
22,635✔
1701
      count++;
421✔
1702
  }
1703
  if (J->pc == J->startpc) {
12,641✔
1704
    if (count + J->tailcalled > J->param[JIT_P_recunroll]) {
76✔
1705
      J->pc++;
20✔
1706
      if (J->framedepth + J->retdepth == 0)
20✔
1707
        lj_record_stop(J, LJ_TRLINK_TAILREC, J->cur.traceno);  /* Tail-rec. */
5✔
1708
      else
1709
        lj_record_stop(J, LJ_TRLINK_UPREC, J->cur.traceno);  /* Up-recursion. */
15✔
1710
    }
1711
  } else {
1712
    if (count > J->param[JIT_P_callunroll]) {
12,565✔
1713
      if (lnk) {  /* Possible tail- or up-recursion. */
24✔
1714
        lj_trace_flush(J, lnk);  /* Flush trace that only returns. */
5✔
1715
        /* Set a small, pseudo-random hotcount for a quick retry of JFUNC*. */
1716
        hotcount_set(J2GG(J), J->pc+1, LJ_PRNG_BITS(J, 4));
5✔
1717
      }
1718
      lj_trace_err(J, LJ_TRERR_CUNROLL);
24✔
1719
    }
1720
  }
1721
}
12,617✔
1722

1723
/* Record Lua function setup. */
1724
static void rec_func_setup(jit_State *J)
13,425✔
1725
{
1726
  GCproto *pt = J->pt;
13,425✔
1727
  BCReg s, numparams = pt->numparams;
13,425✔
1728
  if ((pt->flags & PROTO_NOJIT))
13,425✔
1729
    lj_trace_err(J, LJ_TRERR_CJITOFF);
×
1730
  if (J->baseslot + pt->framesize >= LJ_MAX_JSLOTS)
13,425✔
1731
    lj_trace_err(J, LJ_TRERR_STACKOV);
×
1732
  /* Fill up missing parameters with nil. */
1733
  for (s = J->maxslot; s < numparams; s++)
13,760✔
1734
    J->base[s] = TREF_NIL;
335✔
1735
  /* The remaining slots should never be read before they are written. */
1736
  J->maxslot = numparams;
13,425✔
1737
}
13,425✔
1738

1739
/* Record Lua vararg function setup. */
1740
static void rec_func_vararg(jit_State *J)
101✔
1741
{
1742
  GCproto *pt = J->pt;
101✔
1743
  BCReg s, fixargs, vframe = J->maxslot+1+LJ_FR2;
101✔
1744
  lj_assertJ((pt->flags & PROTO_VARARG), "FUNCV in non-vararg function");
101✔
1745
  if (J->baseslot + vframe + pt->framesize >= LJ_MAX_JSLOTS)
101✔
1746
    lj_trace_err(J, LJ_TRERR_STACKOV);
×
1747
  J->base[vframe-1-LJ_FR2] = J->base[-1-LJ_FR2];  /* Copy function up. */
101✔
1748
#if LJ_FR2
1749
  J->base[vframe-1] = TREF_FRAME;
101✔
1750
#endif
1751
  /* Copy fixarg slots up and set their original slots to nil. */
1752
  fixargs = pt->numparams < J->maxslot ? pt->numparams : J->maxslot;
101✔
1753
  for (s = 0; s < fixargs; s++) {
128✔
1754
    J->base[vframe+s] = J->base[s];
27✔
1755
    J->base[s] = TREF_NIL;
27✔
1756
  }
1757
  J->maxslot = fixargs;
101✔
1758
  J->framedepth++;
101✔
1759
  J->base += vframe;
101✔
1760
  J->baseslot += vframe;
101✔
1761
}
101✔
1762

1763
/* Record entry to a Lua function. */
1764
static void rec_func_lua(jit_State *J)
2,298✔
1765
{
1766
  rec_func_setup(J);
2,298✔
1767
  check_call_unroll(J, 0);
2,298✔
1768
}
2,279✔
1769

1770
/* Record entry to an already compiled function. */
1771
static void rec_func_jit(jit_State *J, TraceNo lnk)
11,127✔
1772
{
1773
  GCtrace *T;
11,127✔
1774
  rec_func_setup(J);
11,127✔
1775
  T = traceref(J, lnk);
11,127✔
1776
  if (T->linktype == LJ_TRLINK_RETURN) {  /* Trace returns to interpreter? */
11,127✔
1777
    check_call_unroll(J, lnk);
10,343✔
1778
    /* Temporarily unpatch JFUNC* to continue recording across function. */
1779
    J->patchins = *J->pc;
10,338✔
1780
    J->patchpc = (BCIns *)J->pc;
10,338✔
1781
    *J->patchpc = T->startins;
10,338✔
1782
    return;
10,338✔
1783
  }
1784
  J->instunroll = 0;  /* Cannot continue across a compiled function. */
784✔
1785
  if (J->pc == J->startpc && J->framedepth + J->retdepth == 0)
784✔
1786
    lj_record_stop(J, LJ_TRLINK_TAILREC, J->cur.traceno);  /* Extra tail-rec. */
×
1787
  else
1788
    lj_record_stop(J, LJ_TRLINK_ROOT, lnk);  /* Link to the function. */
784✔
1789
}
1790

1791
/* -- Vararg handling ----------------------------------------------------- */
1792

1793
/* Detect y = select(x, ...) idiom. */
1794
static int select_detect(jit_State *J)
13✔
1795
{
1796
  BCIns ins = J->pc[1];
13✔
1797
  if (bc_op(ins) == BC_CALLM && bc_b(ins) == 2 && bc_c(ins) == 1) {
13✔
1798
    cTValue *func = &J->L->base[bc_a(ins)];
12✔
1799
    if (tvisfunc(func) && funcV(func)->c.ffid == FF_select) {
12✔
1800
      TRef kfunc = lj_ir_kfunc(J, funcV(func));
8✔
1801
      emitir(IRTG(IR_EQ, IRT_FUNC), getslot(J, bc_a(ins)), kfunc);
8✔
1802
      return 1;
8✔
1803
    }
1804
  }
1805
  return 0;
1806
}
1807

1808
/* Record vararg instruction. */
1809
static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults)
38✔
1810
{
1811
  int32_t numparams = J->pt->numparams;
38✔
1812
  ptrdiff_t nvararg = frame_delta(J->L->base-1) - numparams - 1 - LJ_FR2;
38✔
1813
  lj_assertJ(frame_isvarg(J->L->base-1), "VARG in non-vararg frame");
38✔
1814
  if (LJ_FR2 && dst > J->maxslot)
38✔
1815
    J->base[dst-1] = 0;  /* Prevent resurrection of unrelated slot. */
2✔
1816
  if (J->framedepth > 0) {  /* Simple case: varargs defined on-trace. */
38✔
1817
    ptrdiff_t i;
15✔
1818
    if (nvararg < 0) nvararg = 0;
15✔
1819
    if (nresults != 1) {
15✔
1820
      if (nresults == -1) nresults = nvararg;
14✔
1821
      J->maxslot = dst + (BCReg)nresults;
14✔
1822
    } else if (dst >= J->maxslot) {
1✔
1823
      J->maxslot = dst + 1;
×
1824
    }
1825
    for (i = 0; i < nresults; i++)
28✔
1826
      J->base[dst+i] = i < nvararg ? getslot(J, i - nvararg - 1 - LJ_FR2) : TREF_NIL;
13✔
1827
  } else {  /* Unknown number of varargs passed to trace. */
1828
    TRef fr = emitir(IRTI(IR_SLOAD), LJ_FR2, IRSLOAD_READONLY|IRSLOAD_FRAME);
23✔
1829
    int32_t frofs = 8*(1+LJ_FR2+numparams)+FRAME_VARG;
23✔
1830
    if (nresults >= 0) {  /* Known fixed number of results. */
23✔
1831
      ptrdiff_t i;
10✔
1832
      if (nvararg > 0) {
10✔
1833
        ptrdiff_t nload = nvararg >= nresults ? nresults : nvararg;
7✔
1834
        TRef vbase;
7✔
1835
        if (nvararg >= nresults)
7✔
1836
          emitir(IRTGI(IR_GE), fr, lj_ir_kint(J, frofs+8*(int32_t)nresults));
6✔
1837
        else
1838
          emitir(IRTGI(IR_EQ), fr,
1✔
1839
                 lj_ir_kint(J, (int32_t)frame_ftsz(J->L->base-1)));
1840
        vbase = emitir(IRT(IR_SUB, IRT_IGC), REF_BASE, fr);
7✔
1841
        vbase = emitir(IRT(IR_ADD, IRT_PGC), vbase, lj_ir_kint(J, frofs-8*(1+LJ_FR2)));
7✔
1842
        for (i = 0; i < nload; i++) {
25✔
1843
          IRType t = itype2irt(&J->L->base[i-1-LJ_FR2-nvararg]);
11✔
1844
          TRef aref = emitir(IRT(IR_AREF, IRT_PGC),
11✔
1845
                             vbase, lj_ir_kint(J, (int32_t)i));
1846
          TRef tr = emitir(IRTG(IR_VLOAD, t), aref, 0);
11✔
1847
          if (irtype_ispri(t)) tr = TREF_PRI(t);  /* Canonicalize primitives. */
11✔
1848
          J->base[dst+i] = tr;
11✔
1849
        }
1850
      } else {
1851
        emitir(IRTGI(IR_LE), fr, lj_ir_kint(J, frofs));
3✔
1852
        nvararg = 0;
3✔
1853
      }
1854
      for (i = nvararg; i < nresults; i++)
14✔
1855
        J->base[dst+i] = TREF_NIL;
4✔
1856
      if (nresults != 1 || dst >= J->maxslot) {
10✔
1857
        J->maxslot = dst + (BCReg)nresults;
7✔
1858
      }
1859
    } else if (select_detect(J)) {  /* y = select(x, ...) */
13✔
1860
      TRef tridx = J->base[dst-1];
8✔
1861
      TRef tr = TREF_NIL;
8✔
1862
      ptrdiff_t idx = lj_ffrecord_select_mode(J, tridx, &J->L->base[dst-1]);
8✔
1863
      if (idx < 0) goto nyivarg;
8✔
1864
      if (idx != 0 && !tref_isinteger(tridx))
8✔
1865
        tridx = emitir(IRTGI(IR_CONV), tridx, IRCONV_INT_NUM|IRCONV_INDEX);
×
1866
      if (idx != 0 && tref_isk(tridx)) {
8✔
1867
        emitir(IRTGI(idx <= nvararg ? IR_GE : IR_LT),
3✔
1868
               fr, lj_ir_kint(J, frofs+8*(int32_t)idx));
1869
        frofs -= 8;  /* Bias for 1-based index. */
2✔
1870
      } else if (idx <= nvararg) {  /* Compute size. */
6✔
1871
        TRef tmp = emitir(IRTI(IR_ADD), fr, lj_ir_kint(J, -frofs));
4✔
1872
        if (numparams)
4✔
1873
          emitir(IRTGI(IR_GE), tmp, lj_ir_kint(J, 0));
3✔
1874
        tr = emitir(IRTI(IR_BSHR), tmp, lj_ir_kint(J, 3));
4✔
1875
        if (idx != 0) {
4✔
1876
          tridx = emitir(IRTI(IR_ADD), tridx, lj_ir_kint(J, -1));
3✔
1877
          rec_idx_abc(J, tr, tridx, (uint32_t)nvararg);
3✔
1878
        }
1879
      } else {
1880
        TRef tmp = lj_ir_kint(J, frofs);
2✔
1881
        if (idx != 0) {
2✔
1882
          TRef tmp2 = emitir(IRTI(IR_BSHL), tridx, lj_ir_kint(J, 3));
2✔
1883
          tmp = emitir(IRTI(IR_ADD), tmp2, tmp);
2✔
1884
        } else {
1885
          tr = lj_ir_kint(J, 0);
×
1886
        }
1887
        emitir(IRTGI(IR_LT), fr, tmp);
2✔
1888
      }
1889
      if (idx != 0 && idx <= nvararg) {
8✔
1890
        IRType t;
4✔
1891
        TRef aref, vbase = emitir(IRT(IR_SUB, IRT_IGC), REF_BASE, fr);
4✔
1892
        vbase = emitir(IRT(IR_ADD, IRT_PGC), vbase,
4✔
1893
                       lj_ir_kint(J, frofs-(8<<LJ_FR2)));
1894
        t = itype2irt(&J->L->base[idx-2-LJ_FR2-nvararg]);
4✔
1895
        aref = emitir(IRT(IR_AREF, IRT_PGC), vbase, tridx);
4✔
1896
        tr = emitir(IRTG(IR_VLOAD, t), aref, 0);
4✔
1897
        if (irtype_ispri(t)) tr = TREF_PRI(t);  /* Canonicalize primitives. */
4✔
1898
      }
1899
      J->base[dst-2-LJ_FR2] = tr;
8✔
1900
      J->maxslot = dst-1-LJ_FR2;
8✔
1901
      J->bcskip = 2;  /* Skip CALLM + select. */
8✔
1902
    } else {
1903
    nyivarg:
5✔
1904
      setintV(&J->errinfo, BC_VARG);
5✔
1905
      lj_trace_err_info(J, LJ_TRERR_NYIBC);
5✔
1906
    }
1907
  }
1908
  if (J->baseslot + J->maxslot >= LJ_MAX_JSLOTS)
33✔
1909
    lj_trace_err(J, LJ_TRERR_STACKOV);
×
1910
}
33✔
1911

1912
/* -- Record allocations -------------------------------------------------- */
1913

1914
static TRef rec_tnew(jit_State *J, uint32_t ah)
494✔
1915
{
1916
  uint32_t asize = ah & 0x7ff;
494✔
1917
  uint32_t hbits = ah >> 11;
494✔
1918
  TRef tr;
494✔
1919
  if (asize == 0x7ff) asize = 0x801;
×
1920
  tr = emitir(IRTG(IR_TNEW, IRT_TAB), asize, hbits);
494✔
1921
#ifdef LUAJIT_ENABLE_TABLE_BUMP
1922
  J->rbchash[(tr & (RBCHASH_SLOTS-1))].ref = tref_ref(tr);
1923
  setmref(J->rbchash[(tr & (RBCHASH_SLOTS-1))].pc, J->pc);
1924
  setgcref(J->rbchash[(tr & (RBCHASH_SLOTS-1))].pt, obj2gco(J->pt));
1925
#endif
1926
  return tr;
494✔
1927
}
1928

1929
/* -- Concatenation ------------------------------------------------------- */
1930

1931
static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
301✔
1932
{
1933
  TRef *top = &J->base[topslot];
301✔
1934
  TValue savetv[5];
301✔
1935
  BCReg s;
301✔
1936
  RecordIndex ix;
301✔
1937
  lj_assertJ(baseslot < topslot, "bad CAT arg");
301✔
1938
  for (s = baseslot; s <= topslot; s++)
1,063✔
1939
    (void)getslot(J, s);  /* Ensure all arguments have a reference. */
762✔
1940
  if (tref_isnumber_str(top[0]) && tref_isnumber_str(top[-1])) {
301✔
1941
    TRef tr, hdr, *trp, *xbase, *base = &J->base[baseslot];
296✔
1942
    /* First convert numbers to strings. */
1943
    for (trp = top; trp >= base; trp--) {
1,044✔
1944
      if (tref_isnumber(*trp))
749✔
1945
        *trp = emitir(IRT(IR_TOSTR, IRT_STR), *trp,
42✔
1946
                      tref_isnum(*trp) ? IRTOSTR_NUM : IRTOSTR_INT);
1947
      else if (!tref_isstr(*trp))
707✔
1948
        break;
1949
    }
1950
    xbase = ++trp;
296✔
1951
    tr = hdr = emitir(IRT(IR_BUFHDR, IRT_PGC),
296✔
1952
                      lj_ir_kptr(J, &J2G(J)->tmpbuf), IRBUFHDR_RESET);
1953
    do {
748✔
1954
      tr = emitir(IRT(IR_BUFPUT, IRT_PGC), tr, *trp++);
748✔
1955
    } while (trp <= top);
748✔
1956
    tr = emitir(IRT(IR_BUFSTR, IRT_STR), tr, hdr);
296✔
1957
    J->maxslot = (BCReg)(xbase - J->base);
296✔
1958
    if (xbase == base) return tr;  /* Return simple concatenation result. */
296✔
1959
    /* Pass partial result. */
1960
    topslot = J->maxslot--;
1✔
1961
    *xbase = tr;
1✔
1962
    top = xbase;
1✔
1963
    setstrV(J->L, &ix.keyv, &J2G(J)->strempty);  /* Simulate string result. */
1✔
1964
  } else {
1965
    J->maxslot = topslot-1;
5✔
1966
    copyTV(J->L, &ix.keyv, &J->L->base[topslot]);
5✔
1967
  }
1968
  copyTV(J->L, &ix.tabv, &J->L->base[topslot-1]);
6✔
1969
  ix.tab = top[-1];
6✔
1970
  ix.key = top[0];
6✔
1971
  memcpy(savetv, &J->L->base[topslot-1], sizeof(savetv));  /* Save slots. */
6✔
1972
  rec_mm_arith(J, &ix, MM_concat);  /* Call __concat metamethod. */
6✔
1973
  memcpy(&J->L->base[topslot-1], savetv, sizeof(savetv));  /* Restore slots. */
6✔
1974
  return 0;  /* No result yet. */
6✔
1975
}
1976

1977
/* -- Record bytecode ops ------------------------------------------------- */
1978

1979
/* Prepare for comparison. */
1980
static void rec_comp_prep(jit_State *J)
11,432✔
1981
{
1982
  /* Prevent merging with snapshot #0 (GC exit) since we fixup the PC. */
1983
  if (J->cur.nsnap == 1 && J->cur.snap[0].ref == J->cur.nins)
11,432✔
1984
    emitir_raw(IRT(IR_NOP, IRT_NIL), 0, 0);
69✔
1985
  lj_snap_add(J);
11,432✔
1986
}
11,432✔
1987

1988
/* Fixup comparison. */
1989
static void rec_comp_fixup(jit_State *J, const BCIns *pc, int cond)
11,392✔
1990
{
1991
  BCIns jmpins = pc[1];
11,392✔
1992
  const BCIns *npc = pc + 2 + (cond ? bc_j(jmpins) : 0);
11,392✔
1993
  SnapShot *snap = &J->cur.snap[J->cur.nsnap-1];
11,392✔
1994
  /* Set PC to opposite target to avoid re-recording the comp. in side trace. */
1995
#if LJ_FR2
1996
  SnapEntry *flink = &J->cur.snapmap[snap->mapofs + snap->nent];
11,392✔
1997
  uint64_t pcbase;
11,392✔
1998
  memcpy(&pcbase, flink, sizeof(uint64_t));
11,392✔
1999
  pcbase = (pcbase & 0xff) | (u64ptr(npc) << 8);
11,392✔
2000
  memcpy(flink, &pcbase, sizeof(uint64_t));
11,392✔
2001
#else
2002
  J->cur.snapmap[snap->mapofs + snap->nent] = SNAP_MKPC(npc);
2003
#endif
2004
  J->needsnap = 1;
11,392✔
2005
  if (bc_a(jmpins) < J->maxslot) J->maxslot = bc_a(jmpins);
11,392✔
2006
  lj_snap_shrink(J);  /* Shrink last snapshot if possible. */
11,392✔
2007
}
11,392✔
2008

2009
/* Record the next bytecode instruction (_before_ it's executed). */
2010
void lj_record_ins(jit_State *J)
280,692✔
2011
{
2012
  cTValue *lbase;
280,692✔
2013
  RecordIndex ix;
280,692✔
2014
  const BCIns *pc;
280,692✔
2015
  BCIns ins;
280,692✔
2016
  BCOp op;
280,692✔
2017
  TRef ra, rb, rc;
280,692✔
2018

2019
  /* Perform post-processing action before recording the next instruction. */
2020
  if (LJ_UNLIKELY(J->postproc != LJ_POST_NONE)) {
280,692✔
2021
    switch (J->postproc) {
5,819✔
2022
    case LJ_POST_FIXCOMP:  /* Fixup comparison. */
66✔
2023
      pc = (const BCIns *)(uintptr_t)J2G(J)->tmptv.u64;
66✔
2024
      rec_comp_fixup(J, pc, (!tvistruecond(&J2G(J)->tmptv2) ^ (bc_op(*pc)&1)));
66✔
2025
      /* fallthrough */
2026
    case LJ_POST_FIXGUARD:  /* Fixup and emit pending guard. */
102✔
2027
    case LJ_POST_FIXGUARDSNAP:  /* Fixup and emit pending guard and snapshot. */
2028
      if (!tvistruecond(&J2G(J)->tmptv2)) {
102✔
2029
        J->fold.ins.o ^= 1;  /* Flip guard to opposite. */
30✔
2030
        if (J->postproc == LJ_POST_FIXGUARDSNAP) {
30✔
2031
          SnapShot *snap = &J->cur.snap[J->cur.nsnap-1];
×
2032
          J->cur.snapmap[snap->mapofs+snap->nent-1]--;  /* False -> true. */
×
2033
        }
2034
      }
2035
      lj_opt_fold(J);  /* Emit pending guard. */
102✔
2036
      /* fallthrough */
2037
    case LJ_POST_FIXBOOL:
115✔
2038
      if (!tvistruecond(&J2G(J)->tmptv2)) {
115✔
2039
        BCReg s;
36✔
2040
        TValue *tv = J->L->base;
36✔
2041
        for (s = 0; s < J->maxslot; s++)  /* Fixup stack slot (if any). */
238✔
2042
          if (J->base[s] == TREF_TRUE && tvisfalse(&tv[s])) {
208✔
2043
            J->base[s] = TREF_FALSE;
6✔
2044
            break;
6✔
2045
          }
2046
      }
2047
      break;
2048
    case LJ_POST_FIXCONST:
1✔
2049
      {
2050
        BCReg s;
1✔
2051
        TValue *tv = J->L->base;
1✔
2052
        for (s = 0; s < J->maxslot; s++)  /* Constify stack slots (if any). */
13✔
2053
          if (J->base[s] == TREF_NIL && !tvisnil(&tv[s]))
12✔
2054
            J->base[s] = lj_record_constify(J, &tv[s]);
1✔
2055
      }
2056
      break;
2057
    case LJ_POST_FFRETRY:  /* Suppress recording of retried fast function. */
5,702✔
2058
      if (bc_op(*J->pc) >= BC__MAX)
5,702✔
2059
        return;
19✔
2060
      break;
2061
    default: lj_assertJ(0, "bad post-processing mode"); break;
2062
    }
2063
    J->postproc = LJ_POST_NONE;
5,815✔
2064
  }
2065

2066
  /* Need snapshot before recording next bytecode (e.g. after a store). */
2067
  if (J->needsnap) {
280,688✔
2068
    J->needsnap = 0;
66,540✔
2069
    lj_snap_purge(J);
66,540✔
2070
    lj_snap_add(J);
66,540✔
2071
    J->mergesnap = 1;
66,540✔
2072
  }
2073

2074
  /* Skip some bytecodes. */
2075
  if (LJ_UNLIKELY(J->bcskip > 0)) {
280,688✔
2076
    J->bcskip--;
16✔
2077
    return;
16✔
2078
  }
2079

2080
  /* Record only closed loops for root traces. */
2081
  pc = J->pc;
280,672✔
2082
  if (J->framedepth == 0 &&
280,672✔
2083
     (MSize)((char *)pc - (char *)J->bc_min) >= J->bc_extent)
194,987✔
2084
    lj_trace_err(J, LJ_TRERR_LLEAVE);
492✔
2085

2086
#ifdef LUA_USE_ASSERT
2087
  rec_check_slots(J);
2088
  rec_check_ir(J);
2089
#endif
2090

2091
#if LJ_HASPROFILE
2092
  rec_profile_ins(J, pc);
280,180✔
2093
#endif
2094

2095
  /* Keep a copy of the runtime values of var/num/str operands. */
2096
#define rav        (&ix.valv)
2097
#define rbv        (&ix.tabv)
2098
#define rcv        (&ix.keyv)
2099

2100
  lbase = J->L->base;
280,180✔
2101
  ins = *pc;
280,180✔
2102
  op = bc_op(ins);
280,180✔
2103
  ra = bc_a(ins);
280,180✔
2104
  ix.val = 0;
280,180✔
2105
  switch (bcmode_a(op)) {
280,180✔
2106
  case BCMvar:
65,973✔
2107
    copyTV(J->L, rav, &lbase[ra]); ix.val = ra = getslot(J, ra); break;
65,973✔
2108
  default: break;  /* Handled later. */
2109
  }
2110
  rb = bc_b(ins);
280,180✔
2111
  rc = bc_c(ins);
280,180✔
2112
  switch (bcmode_b(op)) {
280,180✔
2113
  case BCMnone: rb = 0; rc = bc_d(ins); break;  /* Upgrade rc to 'rd'. */
95,954✔
2114
  case BCMvar:
167,025✔
2115
    copyTV(J->L, rbv, &lbase[rb]); ix.tab = rb = getslot(J, rb); break;
167,025✔
2116
  default: break;  /* Handled later. */
2117
  }
2118
  switch (bcmode_c(op)) {
280,180✔
2119
  case BCMvar:
68,660✔
2120
    copyTV(J->L, rcv, &lbase[rc]); ix.key = rc = getslot(J, rc); break;
68,660✔
2121
  case BCMpri: setpriV(rcv, ~rc); ix.key = rc = TREF_PRI(IRT_NIL+rc); break;
8,901✔
2122
  case BCMnum: { cTValue *tv = proto_knumtv(J->pt, rc);
5,593✔
2123
    copyTV(J->L, rcv, tv); ix.key = rc = tvisint(tv) ? lj_ir_kint(J, intV(tv)) :
5,593✔
2124
    lj_ir_knumint(J, numV(tv)); } break;
5,593✔
2125
  case BCMstr: { GCstr *s = gco2str(proto_kgc(J->pt, ~(ptrdiff_t)rc));
113,659✔
2126
    setstrV(J->L, rcv, s); ix.key = rc = lj_ir_kstr(J, s); } break;
113,659✔
2127
  default: break;  /* Handled later. */
2128
  }
2129

2130
  switch (op) {
280,180✔
2131

2132
  /* -- Comparison ops ---------------------------------------------------- */
2133

2134
  case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
4,619✔
2135
#if LJ_HASFFI
2136
    if (tref_iscdata(ra) || tref_iscdata(rc)) {
4,619✔
2137
      rec_mm_comp_cdata(J, &ix, op, ((int)op & 2) ? MM_le : MM_lt);
65✔
2138
      break;
65✔
2139
    }
2140
#endif
2141
    /* Emit nothing for two numeric or string consts. */
2142
    if (!(tref_isk2(ra,rc) && tref_isnumber_str(ra) && tref_isnumber_str(rc))) {
4,554✔
2143
      IRType ta = tref_isinteger(ra) ? IRT_INT : tref_type(ra);
3,968✔
2144
      IRType tc = tref_isinteger(rc) ? IRT_INT : tref_type(rc);
3,968✔
2145
      int irop;
3,968✔
2146
      if (ta != tc) {
3,968✔
2147
        /* Widen mixed number/int comparisons to number/number comparison. */
2148
        if (ta == IRT_INT && tc == IRT_NUM) {
3,234✔
2149
          ra = emitir(IRTN(IR_CONV), ra, IRCONV_NUM_INT);
1,683✔
2150
          ta = IRT_NUM;
1,683✔
2151
        } else if (ta == IRT_NUM && tc == IRT_INT) {
1,551✔
2152
          rc = emitir(IRTN(IR_CONV), rc, IRCONV_NUM_INT);
1,551✔
2153
        } else if (LJ_52) {
×
2154
          ta = IRT_NIL;  /* Force metamethod for different types. */
2155
        } else if (!((ta == IRT_FALSE || ta == IRT_TRUE) &&
×
2156
                     (tc == IRT_FALSE || tc == IRT_TRUE))) {
×
2157
          break;  /* Interpreter will throw for two different types. */
2158
        }
2159
      }
2160
      rec_comp_prep(J);
3,968✔
2161
      irop = (int)op - (int)BC_ISLT + (int)IR_LT;
3,968✔
2162
      if (ta == IRT_NUM) {
3,968✔
2163
        if ((irop & 1)) irop ^= 4;  /* ISGE/ISGT are unordered. */
3,827✔
2164
        if (!lj_ir_numcmp(numberVnum(rav), numberVnum(rcv), (IROp)irop))
3,827✔
2165
          irop ^= 5;
3,274✔
2166
      } else if (ta == IRT_INT) {
141✔
2167
        if (!lj_ir_numcmp(numberVnum(rav), numberVnum(rcv), (IROp)irop))
91✔
2168
          irop ^= 1;
44✔
2169
      } else if (ta == IRT_STR) {
50✔
2170
        if (!lj_ir_strcmp(strV(rav), strV(rcv), (IROp)irop)) irop ^= 1;
1✔
2171
        ra = lj_ir_call(J, IRCALL_lj_str_cmp, ra, rc);
1✔
2172
        rc = lj_ir_kint(J, 0);
1✔
2173
        ta = IRT_INT;
1✔
2174
      } else {
2175
        rec_mm_comp(J, &ix, (int)op);
49✔
2176
        break;
49✔
2177
      }
2178
      emitir(IRTG(irop, ta), ra, rc);
3,919✔
2179
      rec_comp_fixup(J, J->pc, ((int)op ^ irop) & 1);
3,919✔
2180
    }
2181
    break;
2182

2183
  case BC_ISEQV: case BC_ISNEV:
8,998✔
2184
  case BC_ISEQS: case BC_ISNES:
2185
  case BC_ISEQN: case BC_ISNEN:
2186
  case BC_ISEQP: case BC_ISNEP:
2187
#if LJ_HASFFI
2188
    if (tref_iscdata(ra) || tref_iscdata(rc)) {
8,998✔
2189
      rec_mm_comp_cdata(J, &ix, op, MM_eq);
37✔
2190
      break;
37✔
2191
    }
2192
#endif
2193
    /* Emit nothing for two non-table, non-udata consts. */
2194
    if (!(tref_isk2(ra, rc) && !(tref_istab(ra) || tref_isudata(ra)))) {
8,961✔
2195
      int diff;
7,464✔
2196
      rec_comp_prep(J);
7,464✔
2197
      diff = lj_record_objcmp(J, ra, rc, rav, rcv);
7,464✔
2198
      if (diff == 2 || !(tref_istab(ra) || tref_isudata(ra)))
7,464✔
2199
        rec_comp_fixup(J, J->pc, ((int)op & 1) == !diff);
7,407✔
2200
      else if (diff == 1)  /* Only check __eq if different, but same type. */
57✔
2201
        rec_mm_equal(J, &ix, (int)op);
10✔
2202
    }
2203
    break;
2204

2205
  /* -- Unary test and copy ops ------------------------------------------- */
2206

2207
  case BC_ISTC: case BC_ISFC:
180✔
2208
    if ((op & 1) == tref_istruecond(rc))
180✔
2209
      rc = 0;  /* Don't store if condition is not true. */
162✔
2210
    /* fallthrough */
2211
  case BC_IST: case BC_ISF:  /* Type specialization suffices. */
2212
    if (bc_a(pc[1]) < J->maxslot)
667✔
2213
      J->maxslot = bc_a(pc[1]);  /* Shrink used slots. */
151✔
2214
    break;
2215

2216
  case BC_ISTYPE: case BC_ISNUM:
2217
    /* These coercions need to correspond with lj_meta_istype(). */
2218
    if (LJ_DUALNUM && rc == ~LJ_TNUMX+1)
11✔
2219
      ra = lj_opt_narrow_toint(J, ra);
2220
    else if (rc == ~LJ_TNUMX+2)
11✔
2221
      ra = lj_ir_tonum(J, ra);
2✔
2222
    else if (rc == ~LJ_TSTR+1)
9✔
2223
      ra = lj_ir_tostr(J, ra);
3✔
2224
    /* else: type specialization suffices. */
2225
    J->base[bc_a(ins)] = ra;
11✔
2226
    break;
11✔
2227

2228
  /* -- Unary ops --------------------------------------------------------- */
2229

2230
  case BC_NOT:
5✔
2231
    /* Type specialization already forces const result. */
2232
    rc = tref_istruecond(rc) ? TREF_FALSE : TREF_TRUE;
5✔
2233
    break;
2234

2235
  case BC_LEN:
46✔
2236
    if (tref_isstr(rc))
46✔
2237
      rc = emitir(IRTI(IR_FLOAD), rc, IRFL_STR_LEN);
4✔
2238
    else if (!LJ_52 && tref_istab(rc))
42✔
2239
      rc = lj_ir_call(J, IRCALL_lj_tab_len, rc);
41✔
2240
    else
2241
      rc = rec_mm_len(J, rc, rcv);
1✔
2242
    break;
2243

2244
  /* -- Arithmetic ops ---------------------------------------------------- */
2245

2246
  case BC_UNM:
13✔
2247
    if (tref_isnumber_str(rc)) {
13✔
2248
      rc = lj_opt_narrow_unm(J, rc, rcv);
12✔
2249
    } else {
2250
      ix.tab = rc;
1✔
2251
      copyTV(J->L, &ix.tabv, rcv);
1✔
2252
      rc = rec_mm_arith(J, &ix, MM_unm);
1✔
2253
    }
2254
    break;
2255

2256
  case BC_ADDNV: case BC_SUBNV: case BC_MULNV: case BC_DIVNV: case BC_MODNV:
2,546✔
2257
    /* Swap rb/rc and rbv/rcv. rav is temp. */
2258
    ix.tab = rc; ix.key = rc = rb; rb = ix.tab;
2,546✔
2259
    copyTV(J->L, rav, rbv);
2,546✔
2260
    copyTV(J->L, rbv, rcv);
2,546✔
2261
    copyTV(J->L, rcv, rav);
2,546✔
2262
    if (op == BC_MODNV)
2,546✔
2263
      goto recmod;
17✔
2264
    /* fallthrough */
2265
  case BC_ADDVN: case BC_SUBVN: case BC_MULVN: case BC_DIVVN:
2266
  case BC_ADDVV: case BC_SUBVV: case BC_MULVV: case BC_DIVVV: {
2267
    MMS mm = bcmode_mm(op);
51,273✔
2268
    if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
51,273✔
2269
      rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv,
51,124✔
2270
                               (int)mm - (int)MM_add + (int)IR_ADD);
51,124✔
2271
    else
2272
      rc = rec_mm_arith(J, &ix, mm);
149✔
2273
    break;
2274
    }
2275

2276
  case BC_MODVN: case BC_MODVV:
2277
  recmod:
111✔
2278
    if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
111✔
2279
      rc = lj_opt_narrow_mod(J, rb, rc, rbv, rcv);
108✔
2280
    else
2281
      rc = rec_mm_arith(J, &ix, MM_mod);
3✔
2282
    break;
2283

2284
  case BC_POW:
243✔
2285
    if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
243✔
2286
      rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv, IR_POW);
240✔
2287
    else
2288
      rc = rec_mm_arith(J, &ix, MM_pow);
3✔
2289
    break;
2290

2291
  /* -- Miscellaneous ops ------------------------------------------------- */
2292

2293
  case BC_CAT:
299✔
2294
    rc = rec_cat(J, rb, rc);
299✔
2295
    break;
299✔
2296

2297
  /* -- Constant and move ops --------------------------------------------- */
2298

2299
  case BC_MOV:
11,047✔
2300
    /* Clear gap of method call to avoid resurrecting previous refs. */
2301
    if (ra > J->maxslot) {
11,047✔
2302
#if LJ_FR2
2303
      memset(J->base + J->maxslot, 0, (ra - J->maxslot) * sizeof(TRef));
6,475✔
2304
#else
2305
      J->base[ra-1] = 0;
2306
#endif
2307
    }
2308
    break;
2309
  case BC_KSTR: case BC_KNUM: case BC_KPRI:
2310
    break;
2311
  case BC_KSHORT:
7,324✔
2312
    rc = lj_ir_kint(J, (int32_t)(int16_t)rc);
7,324✔
2313
    break;
7,324✔
2314
  case BC_KNIL:
11✔
2315
    if (LJ_FR2 && ra > J->maxslot)
11✔
2316
      J->base[ra-1] = 0;
1✔
2317
    while (ra <= rc)
613✔
2318
      J->base[ra++] = TREF_NIL;
602✔
2319
    if (rc >= J->maxslot) J->maxslot = rc+1;
11✔
2320
    break;
2321
#if LJ_HASFFI
2322
  case BC_KCDATA:
30✔
2323
    rc = lj_ir_kgc(J, proto_kgc(J->pt, ~(ptrdiff_t)rc), IRT_CDATA);
30✔
2324
    break;
30✔
2325
#endif
2326

2327
  /* -- Upvalue and function ops ------------------------------------------ */
2328

2329
  case BC_UGET:
16,343✔
2330
    rc = rec_upvalue(J, rc, 0);
16,343✔
2331
    break;
16,343✔
2332
  case BC_USETV: case BC_USETS: case BC_USETN: case BC_USETP:
168✔
2333
    rec_upvalue(J, ra, rc);
168✔
2334
    break;
168✔
2335

2336
  /* -- Table ops --------------------------------------------------------- */
2337

2338
  case BC_GGET: case BC_GSET:
2,397✔
2339
    settabV(J->L, &ix.tabv, tabref(J->fn->l.env));
2,397✔
2340
    ix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), getcurrf(J), IRFL_FUNC_ENV);
2,397✔
2341
    ix.idxchain = LJ_MAX_IDXCHAIN;
2,397✔
2342
    rc = lj_record_idx(J, &ix);
2,397✔
2343
    break;
2,397✔
2344

2345
  case BC_TGETB: case BC_TSETB:
462✔
2346
    setintV(&ix.keyv, (int32_t)rc);
462✔
2347
    ix.key = lj_ir_kint(J, (int32_t)rc);
462✔
2348
    /* fallthrough */
2349
  case BC_TGETV: case BC_TGETS: case BC_TSETV: case BC_TSETS:
115,372✔
2350
    ix.idxchain = LJ_MAX_IDXCHAIN;
115,372✔
2351
    rc = lj_record_idx(J, &ix);
115,372✔
2352
    break;
115,372✔
2353
  case BC_TGETR: case BC_TSETR:
26✔
2354
    ix.idxchain = 0;
26✔
2355
    rc = lj_record_idx(J, &ix);
26✔
2356
    break;
26✔
2357

2358
  case BC_TSETM:
5✔
2359
    rec_tsetm(J, ra, (BCReg)(J->L->top - J->L->base), (int32_t)rcv->u32.lo);
5✔
2360
    J->maxslot = ra;  /* The table slot at ra-1 is the highest used slot. */
5✔
2361
    break;
5✔
2362

2363
  case BC_TNEW:
2364
    rc = rec_tnew(J, rc);
494✔
2365
    break;
494✔
2366
  case BC_TDUP:
173✔
2367
    rc = emitir(IRTG(IR_TDUP, IRT_TAB),
173✔
2368
                lj_ir_ktab(J, gco2tab(proto_kgc(J->pt, ~(ptrdiff_t)rc))), 0);
2369
#ifdef LUAJIT_ENABLE_TABLE_BUMP
2370
    J->rbchash[(rc & (RBCHASH_SLOTS-1))].ref = tref_ref(rc);
2371
    setmref(J->rbchash[(rc & (RBCHASH_SLOTS-1))].pc, pc);
2372
    setgcref(J->rbchash[(rc & (RBCHASH_SLOTS-1))].pt, obj2gco(J->pt));
2373
#endif
2374
    break;
173✔
2375

2376
  /* -- Calls and vararg handling ----------------------------------------- */
2377

2378
  case BC_ITERC:
110✔
2379
    J->base[ra] = getslot(J, ra-3);
110✔
2380
    J->base[ra+1+LJ_FR2] = getslot(J, ra-2);
110✔
2381
    J->base[ra+2+LJ_FR2] = getslot(J, ra-1);
110✔
2382
    { /* Do the actual copy now because lj_record_call needs the values. */
2383
      TValue *b = &J->L->base[ra];
110✔
2384
      copyTV(J->L, b, b-3);
110✔
2385
      copyTV(J->L, b+1+LJ_FR2, b-2);
110✔
2386
      copyTV(J->L, b+2+LJ_FR2, b-1);
110✔
2387
    }
2388
    lj_record_call(J, ra, (ptrdiff_t)rc-1);
110✔
2389
    break;
110✔
2390

2391
  /* L->top is set to L->base+ra+rc+NARGS-1+1. See lj_dispatch_ins(). */
2392
  case BC_CALLM:
2,650✔
2393
    rc = (BCReg)(J->L->top - J->L->base) - ra - LJ_FR2;
2,650✔
2394
    /* fallthrough */
2395
  case BC_CALL:
16,754✔
2396
    lj_record_call(J, ra, (ptrdiff_t)rc-1);
16,754✔
2397
    break;
16,754✔
2398

2399
  case BC_CALLMT:
6✔
2400
    rc = (BCReg)(J->L->top - J->L->base) - ra - LJ_FR2;
6✔
2401
    /* fallthrough */
2402
  case BC_CALLT:
1,963✔
2403
    lj_record_tailcall(J, ra, (ptrdiff_t)rc-1);
1,963✔
2404
    break;
1,963✔
2405

2406
  case BC_VARG:
38✔
2407
    rec_varg(J, ra, (ptrdiff_t)rb-1);
38✔
2408
    break;
38✔
2409

2410
  /* -- Returns ----------------------------------------------------------- */
2411

2412
  case BC_RETM:
26✔
2413
    /* L->top is set to L->base+ra+rc+NRESULTS-1, see lj_dispatch_ins(). */
2414
    rc = (BCReg)(J->L->top - J->L->base) - ra + 1;
26✔
2415
    /* fallthrough */
2416
  case BC_RET: case BC_RET0: case BC_RET1:
13,892✔
2417
#if LJ_HASPROFILE
2418
    rec_profile_ret(J);
13,892✔
2419
#endif
2420
    lj_record_ret(J, ra, (ptrdiff_t)rc-1);
13,892✔
2421
    break;
13,892✔
2422

2423
  /* -- Loops and branches ------------------------------------------------ */
2424

2425
  case BC_FORI:
163✔
2426
    if (rec_for(J, pc, 0) != LOOPEV_LEAVE)
163✔
2427
      J->loopref = J->cur.nins;
163✔
2428
    break;
2429
  case BC_JFORI:
71✔
2430
    lj_assertJ(bc_op(pc[(ptrdiff_t)rc-BCBIAS_J]) == BC_JFORL,
71✔
2431
               "JFORI does not point to JFORL");
2432
    if (rec_for(J, pc, 0) != LOOPEV_LEAVE)  /* Link to existing loop. */
71✔
2433
      lj_record_stop(J, LJ_TRLINK_ROOT, bc_d(pc[(ptrdiff_t)rc-BCBIAS_J]));
68✔
2434
    /* Continue tracing if the loop is not entered. */
2435
    break;
2436

2437
  case BC_FORL:
2,151✔
2438
    rec_loop_interp(J, pc, rec_for(J, pc+((ptrdiff_t)rc-BCBIAS_J), 1));
2,151✔
2439
    break;
2,151✔
2440
  case BC_ITERL:
45✔
2441
    rec_loop_interp(J, pc, rec_iterl(J, *pc));
45✔
2442
    break;
45✔
2443
  case BC_LOOP:
75✔
2444
    rec_loop_interp(J, pc, rec_loop(J, ra));
75✔
2445
    break;
75✔
2446

2447
  case BC_JFORL:
315✔
2448
    rec_loop_jit(J, rc, rec_for(J, pc+bc_j(traceref(J, rc)->startins), 1));
315✔
2449
    break;
315✔
2450
  case BC_JITERL:
63✔
2451
    rec_loop_jit(J, rc, rec_iterl(J, traceref(J, rc)->startins));
63✔
2452
    break;
63✔
2453
  case BC_JLOOP:
1,432✔
2454
    rec_loop_jit(J, rc, rec_loop(J, ra));
1,432✔
2455
    break;
1,432✔
2456

2457
  case BC_IFORL:
×
2458
  case BC_IITERL:
2459
  case BC_ILOOP:
2460
  case BC_IFUNCF:
2461
  case BC_IFUNCV:
2462
    lj_trace_err(J, LJ_TRERR_BLACKL);
×
2463
    break;
1,523✔
2464

2465
  case BC_JMP:
1,523✔
2466
    if (ra < J->maxslot)
1,523✔
2467
      J->maxslot = ra;  /* Shrink used slots. */
975✔
2468
    break;
2469

2470
  /* -- Function headers -------------------------------------------------- */
2471

2472
  case BC_FUNCF:
2473
    rec_func_lua(J);
2,197✔
2474
    break;
2475
  case BC_JFUNCF:
11,127✔
2476
    rec_func_jit(J, rc);
11,127✔
2477
    break;
11,127✔
2478

2479
  case BC_FUNCV:
101✔
2480
    rec_func_vararg(J);
101✔
2481
    rec_func_lua(J);
101✔
2482
    break;
2483
  case BC_JFUNCV:
2484
    /* Cannot happen. No hotcall counting for varag funcs. */
2485
    lj_assertJ(0, "unsupported vararg hotcall");
2486
    break;
2487

2488
  case BC_FUNCC:
1,556✔
2489
  case BC_FUNCCW:
2490
    lj_ffrecord_func(J);
1,556✔
2491
    break;
1,556✔
2492

2493
  default:
4,601✔
2494
    if (op >= BC__MAX) {
4,601✔
2495
      lj_ffrecord_func(J);
4,601✔
2496
      break;
4,601✔
2497
    }
2498
    /* fallthrough */
2499
  case BC_ITERN:
2500
  case BC_ISNEXT:
2501
  case BC_UCLO:
2502
  case BC_FNEW:
2503
    setintV(&J->errinfo, (int32_t)op);
43✔
2504
    lj_trace_err_info(J, LJ_TRERR_NYIBC);
43✔
2505
    break;
279,661✔
2506
  }
2507

2508
  /* rc == 0 if we have no result yet, e.g. pending __index metamethod call. */
2509
  if (bcmode_a(op) == BCMdst && rc) {
279,661✔
2510
    J->base[ra] = rc;
154,692✔
2511
    if (ra >= J->maxslot) {
154,692✔
2512
#if LJ_FR2
2513
      if (ra > J->maxslot) J->base[ra-1] = 0;
53,995✔
2514
#endif
2515
      J->maxslot = ra+1;
53,995✔
2516
    }
2517
  }
2518

2519
#undef rav
2520
#undef rbv
2521
#undef rcv
2522

2523
  /* Limit the number of recorded IR instructions and constants. */
2524
  if (J->cur.nins > REF_FIRST+(IRRef)J->param[JIT_P_maxrecord] ||
279,661✔
2525
      J->cur.nk < REF_BIAS-(IRRef)J->param[JIT_P_maxirconst])
279,661✔
2526
    lj_trace_err(J, LJ_TRERR_TRACEOV);
1✔
2527
}
2528

2529
/* -- Recording setup ----------------------------------------------------- */
2530

2531
/* Setup recording for a root trace started by a hot loop. */
2532
static const BCIns *rec_setup_root(jit_State *J)
3,804✔
2533
{
2534
  /* Determine the next PC and the bytecode range for the loop. */
2535
  const BCIns *pcj, *pc = J->pc;
3,804✔
2536
  BCIns ins = *pc;
3,804✔
2537
  BCReg ra = bc_a(ins);
3,804✔
2538
  switch (bc_op(ins)) {
3,804✔
2539
  case BC_FORL:
2,080✔
2540
    J->bc_extent = (MSize)(-bc_j(ins))*sizeof(BCIns);
2,080✔
2541
    pc += 1+bc_j(ins);
2,080✔
2542
    J->bc_min = pc;
2,080✔
2543
    break;
2,080✔
2544
  case BC_ITERL:
36✔
2545
    lj_assertJ(bc_op(pc[-1]) == BC_ITERC, "no ITERC before ITERL");
36✔
2546
    J->maxslot = ra + bc_b(pc[-1]) - 1;
36✔
2547
    J->bc_extent = (MSize)(-bc_j(ins))*sizeof(BCIns);
36✔
2548
    pc += 1+bc_j(ins);
36✔
2549
    lj_assertJ(bc_op(pc[-1]) == BC_JMP, "ITERL does not point to JMP+1");
36✔
2550
    J->bc_min = pc;
36✔
2551
    break;
36✔
2552
  case BC_LOOP:
865✔
2553
    /* Only check BC range for real loops, but not for "repeat until true". */
2554
    pcj = pc + bc_j(ins);
865✔
2555
    ins = *pcj;
865✔
2556
    if (bc_op(ins) == BC_JMP && bc_j(ins) < 0) {
865✔
2557
      J->bc_min = pcj+1 + bc_j(ins);
860✔
2558
      J->bc_extent = (MSize)(-bc_j(ins))*sizeof(BCIns);
860✔
2559
    }
2560
    J->maxslot = ra;
865✔
2561
    pc++;
865✔
2562
    break;
865✔
2563
  case BC_RET:
67✔
2564
  case BC_RET0:
2565
  case BC_RET1:
2566
    /* No bytecode range check for down-recursive root traces. */
2567
    J->maxslot = ra + bc_d(ins) - 1;
67✔
2568
    break;
67✔
2569
  case BC_FUNCF:
688✔
2570
    /* No bytecode range check for root traces started by a hot call. */
2571
    J->maxslot = J->pt->numparams;
688✔
2572
    pc++;
688✔
2573
    break;
688✔
2574
  case BC_CALLM:
68✔
2575
  case BC_CALL:
2576
  case BC_ITERC:
2577
    /* No bytecode range check for stitched traces. */
2578
    pc++;
68✔
2579
    break;
68✔
2580
  default:
2581
    lj_assertJ(0, "bad root trace start bytecode %d", bc_op(ins));
2582
    break;
2583
  }
2584
  return pc;
3,804✔
2585
}
2586

2587
/* Setup for recording a new trace. */
2588
void lj_record_setup(jit_State *J)
6,960✔
2589
{
2590
  uint32_t i;
6,960✔
2591

2592
  /* Initialize state related to current trace. */
2593
  memset(J->slot, 0, sizeof(J->slot));
6,960✔
2594
  memset(J->chain, 0, sizeof(J->chain));
6,960✔
2595
#ifdef LUAJIT_ENABLE_TABLE_BUMP
2596
  memset(J->rbchash, 0, sizeof(J->rbchash));
2597
#endif
2598
  memset(J->bpropcache, 0, sizeof(J->bpropcache));
6,960✔
2599
  J->scev.idx = REF_NIL;
6,960✔
2600
  setmref(J->scev.pc, NULL);
6,960✔
2601

2602
  J->baseslot = 1+LJ_FR2;  /* Invoking function is at base[-1-LJ_FR2]. */
6,960✔
2603
  J->base = J->slot + J->baseslot;
6,960✔
2604
  J->maxslot = 0;
6,960✔
2605
  J->framedepth = 0;
6,960✔
2606
  J->retdepth = 0;
6,960✔
2607

2608
  J->instunroll = J->param[JIT_P_instunroll];
6,960✔
2609
  J->loopunroll = J->param[JIT_P_loopunroll];
6,960✔
2610
  J->tailcalled = 0;
6,960✔
2611
  J->loopref = 0;
6,960✔
2612

2613
  J->bc_min = NULL;  /* Means no limit. */
6,960✔
2614
  J->bc_extent = ~(MSize)0;
6,960✔
2615

2616
  /* Emit instructions for fixed references. Also triggers initial IR alloc. */
2617
  emitir_raw(IRT(IR_BASE, IRT_PGC), J->parent, J->exitno);
6,960✔
2618
  for (i = 0; i <= 2; i++) {
34,800✔
2619
    IRIns *ir = IR(REF_NIL-i);
20,880✔
2620
    ir->i = 0;
20,880✔
2621
    ir->t.irt = (uint8_t)(IRT_NIL+i);
20,880✔
2622
    ir->o = IR_KPRI;
20,880✔
2623
    ir->prev = 0;
20,880✔
2624
  }
2625
  J->cur.nk = REF_TRUE;
6,960✔
2626

2627
  J->startpc = J->pc;
6,960✔
2628
  setmref(J->cur.startpc, J->pc);
6,960✔
2629
  if (J->parent) {  /* Side trace. */
6,960✔
2630
    GCtrace *T = traceref(J, J->parent);
3,156✔
2631
    TraceNo root = T->root ? T->root : J->parent;
3,156✔
2632
    J->cur.root = (uint16_t)root;
3,156✔
2633
    J->cur.startins = BCINS_AD(BC_JMP, 0, 0);
3,156✔
2634
    /* Check whether we could at least potentially form an extra loop. */
2635
    if (J->exitno == 0 && T->snap[0].nent == 0) {
3,156✔
2636
      /* We can narrow a FORL for some side traces, too. */
2637
      if (J->pc > proto_bc(J->pt) && bc_op(J->pc[-1]) == BC_JFORI &&
360✔
2638
          bc_d(J->pc[bc_j(J->pc[-1])-1]) == root) {
164✔
2639
        lj_snap_add(J);
164✔
2640
        rec_for_loop(J, J->pc-1, &J->scev, 1);
164✔
2641
        goto sidecheck;
164✔
2642
      }
2643
    } else {
2644
      J->startpc = NULL;  /* Prevent forming an extra loop. */
2,796✔
2645
    }
2646
    lj_snap_replay(J, T);
2,992✔
2647
  sidecheck:
3,156✔
2648
    if (traceref(J, J->cur.root)->nchild >= J->param[JIT_P_maxside] ||
3,156✔
2649
        T->snap[J->exitno].count >= J->param[JIT_P_hotexit] +
2,902✔
2650
                                    J->param[JIT_P_tryside]) {
2,902✔
2651
      lj_record_stop(J, LJ_TRLINK_INTERP, 0);
344✔
2652
    }
2653
  } else {  /* Root trace. */
2654
    J->cur.root = 0;
3,804✔
2655
    J->cur.startins = *J->pc;
3,804✔
2656
    J->pc = rec_setup_root(J);
3,804✔
2657
    /* Note: the loop instruction itself is recorded at the end and not
2658
    ** at the start! So snapshot #0 needs to point to the *next* instruction.
2659
    */
2660
    lj_snap_add(J);
3,804✔
2661
    if (bc_op(J->cur.startins) == BC_FORL)
3,804✔
2662
      rec_for_loop(J, J->pc-1, &J->scev, 1);
2,080✔
2663
    else if (bc_op(J->cur.startins) == BC_ITERC)
1,724✔
2664
      J->startpc = NULL;
2✔
2665
    if (1 + J->pt->framesize >= LJ_MAX_JSLOTS)
3,804✔
2666
      lj_trace_err(J, LJ_TRERR_STACKOV);
×
2667
  }
2668
#if LJ_HASPROFILE
2669
  J->prev_pt = NULL;
6,960✔
2670
  J->prev_line = -1;
6,960✔
2671
#endif
2672
#ifdef LUAJIT_ENABLE_CHECKHOOK
2673
  /* Regularly check for instruction/line hooks from compiled code and
2674
  ** exit to the interpreter if the hooks are set.
2675
  **
2676
  ** This is a compile-time option and disabled by default, since the
2677
  ** hook checks may be quite expensive in tight loops.
2678
  **
2679
  ** Note this is only useful if hooks are *not* set most of the time.
2680
  ** Use this only if you want to *asynchronously* interrupt the execution.
2681
  **
2682
  ** You can set the instruction hook via lua_sethook() with a count of 1
2683
  ** from a signal handler or another native thread. Please have a look
2684
  ** at the first few functions in luajit.c for an example (Ctrl-C handler).
2685
  */
2686
  {
2687
    TRef tr = emitir(IRT(IR_XLOAD, IRT_U8),
2688
                     lj_ir_kptr(J, &J2G(J)->hookmask), IRXLOAD_VOLATILE);
2689
    tr = emitir(IRTI(IR_BAND), tr, lj_ir_kint(J, (LUA_MASKLINE|LUA_MASKCOUNT)));
2690
    emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, 0));
2691
  }
2692
#endif
2693
}
6,960✔
2694

2695
#undef IR
2696
#undef emitir_raw
2697
#undef emitir
2698

2699
#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

© 2026 Coveralls, Inc