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

tarantool / luajit / 6482677868

11 Oct 2023 12:31PM UTC coverage: 88.235% (-0.06%) from 88.296%
6482677868

push

github

Buristan
Fix base register coalescing in side trace.

Thanks to Sergey Kaplun, NiLuJe and Peter Cawley.

(cherry-picked from commit aa2db7ebd)

The previous patch fixed just part of the problem with the register
coalesing. For example, the parent base register may be used inside the
parent or child register sets when it shouldn't. This leads to incorrect
register allocations, which may lead to crashes or undefined behaviour.
This patch fixes it by excluding the parent base register from both
register sets.

The test case for this patch doesn't fail before the commit since it
requires specific register allocation, which is hard to construct and
very fragile. Due to the lack of ideal sync with the upstream
repository, the test is passed before the patch.
It should become correct in future patches.

Resolves tarantool/tarantool#8767
Part of tarantool/tarantool#9145

Sergey Kaplun:
* added the description and the test for the problem

5342 of 5974 branches covered (0.0%)

Branch coverage included in aggregate %.

5 of 5 new or added lines in 1 file covered. (100.0%)

20487 of 23299 relevant lines covered (87.93%)

2753402.99 hits per line

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

95.59
/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)
5,278✔
188
{
189
  /* Caller may set IRT_GUARD in t. */
190
  TRef ref = emitir_raw(IRT(IR_SLOAD, t), (int32_t)J->baseslot+slot, mode);
10,556✔
191
  J->base[slot] = ref;
5,278✔
192
  return ref;
5,278✔
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)
10,175✔
197
{
198
  IRType t = itype2irt(&J->L->base[slot]);
10,175✔
199
  TRef ref = emitir_raw(IRTG(IR_SLOAD, t), (int32_t)J->baseslot+slot,
10,175✔
200
                        IRSLOAD_TYPECHECK);
201
  if (irtype_ispri(t)) ref = TREF_PRI(t);  /* Canonicalize primitive refs. */
10,175✔
202
  J->base[slot] = ref;
10,175✔
203
  return ref;
10,175✔
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)
7,811✔
211
{
212
  if (J->base[-1-LJ_FR2])
7,811✔
213
    return J->base[-1-LJ_FR2];
214
  lj_assertJ(J->baseslot == 1+LJ_FR2, "bad baseslot");
2,707✔
215
  return sloadt(J, -1-LJ_FR2, IRT_FUNC, IRSLOAD_READONLY);
2,707✔
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)
2,010✔
225
{
226
  int diff = !lj_obj_equal(av, bv);
2,010✔
227
  if (!tref_isk2(a, b)) {  /* Shortcut, also handles primitives. */
2,010✔
228
    IRType ta = tref_isinteger(a) ? IRT_INT : tref_type(a);
2,010✔
229
    IRType tb = tref_isinteger(b) ? IRT_INT : tref_type(b);
2,010✔
230
    if (ta != tb) {
2,010✔
231
      /* Widen mixed number/int comparisons to number/number comparison. */
232
      if (ta == IRT_INT && tb == IRT_NUM) {
1,556✔
233
        a = emitir(IRTN(IR_CONV), a, IRCONV_NUM_INT);
1✔
234
        ta = IRT_NUM;
1✔
235
      } else if (ta == IRT_NUM && tb == IRT_INT) {
1,555✔
236
        b = emitir(IRTN(IR_CONV), b, IRCONV_NUM_INT);
122✔
237
      } else {
238
        return 2;  /* Two different types are never equal. */
239
      }
240
    }
241
    emitir(IRTG(diff ? IR_NE : IR_EQ, ta), a, b);
929✔
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)
4,787✔
248
{
249
  if (tvisgcv(o))
4,787✔
250
    return lj_ir_kgc(J, gcV(o), itype2irt(o));
4,706✔
251
  else if (tvisint(o))
81✔
252
    return lj_ir_kint(J, intV(o));
253
  else if (tvisnum(o))
81✔
254
    return lj_ir_knumint(J, numV(o));
81✔
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)
2,493✔
272
{
273
  BCReg s;
2,493✔
274
  if (LJ_DUALNUM) return;
2,493✔
275
  for (s = J->baseslot+J->maxslot-1; s >= 1; s--) {
32,093✔
276
    TRef tr = J->slot[s];
29,600✔
277
    if (tref_isinteger(tr)) {
29,600✔
278
      IRIns *ir = IR(tref_ref(tr));
1,009✔
279
      if (!(ir->o == IR_SLOAD && (ir->op2 & IRSLOAD_READONLY)))
1,009✔
280
        J->slot[s] = emitir(IRTN(IR_CONV), tr, IRCONV_NUM_INT);
942✔
281
    }
282
  }
283
}
284

285
/* Stop recording. */
286
void lj_record_stop(jit_State *J, TraceLink linktype, TraceNo lnk)
3,768✔
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);
3,768✔
293
  J->cur.linktype = (uint8_t)linktype;
3,768✔
294
  J->cur.link = (uint16_t)lnk;
3,768✔
295
  /* Looping back at the same stack level? */
296
  if (lnk == J->cur.traceno && J->framedepth + J->retdepth == 0) {
3,768✔
297
    if ((J->flags & JIT_F_OPT_LOOP))  /* Shall we try to create a loop? */
1,987✔
298
      goto nocanon;  /* Do not canonicalize or we lose the narrowing. */
1,275✔
299
    if (J->cur.root)  /* Otherwise ensure we always link to the root trace. */
712✔
300
      J->cur.link = J->cur.root;
1✔
301
  }
302
  canonicalize_slots(J);
2,493✔
303
nocanon:
3,768✔
304
  /* Note: all loop ops must set J->pc to the following instruction! */
305
  lj_snap_add(J);  /* Add loop snapshot. */
3,768✔
306
  J->needsnap = 0;
3,768✔
307
  J->mergesnap = 1;  /* In case recording continues. */
3,768✔
308
}
3,768✔
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,450✔
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,450✔
319
  for (pc = endpc-1; pc > startpc; pc--) {
15,128✔
320
    BCIns ins = *pc;
15,128✔
321
    BCOp op = bc_op(ins);
15,128✔
322
    /* First try to find the last instruction that stores to this slot. */
323
    if (bcmode_a(op) == BCMbase && bc_a(ins) <= slot) {
15,128✔
324
      return 0;  /* Multiple results, e.g. from a CALL or KNIL. */
325
    } else if (bcmode_a(op) == BCMdst && bc_a(ins) == slot) {
15,113✔
326
      if (op == BC_KSHORT || op == BC_KNUM) {  /* Found const. initializer. */
7,435✔
327
        /* Now try to verify there's no forward jump across it. */
328
        const BCIns *kpc = pc;
454,611✔
329
        for (; pc > startpc; pc--)
454,611✔
330
          if (bc_op(*pc) == BC_JMP) {
447,465✔
331
            const BCIns *target = pc+bc_j(*pc)+1;
41,393✔
332
            if (target > kpc && target <= endpc)
41,393✔
333
              return 0;  /* Conditional assignment. */
334
          }
335
        if (op == BC_KSHORT) {
7,146✔
336
          int32_t k = (int32_t)(int16_t)bc_d(ins);
7,080✔
337
          return t == IRT_INT ? lj_ir_kint(J, k) : lj_ir_knum(J, (lua_Number)k);
7,080✔
338
        } else {
339
          cTValue *tv = proto_knumtv(J->pt, bc_d(ins));
66✔
340
          if (t == IRT_INT) {
66✔
341
            int32_t k = numberVint(tv);
50✔
342
            if (tvisint(tv) || numV(tv) == (lua_Number)k)  /* -0 is ok here. */
50✔
343
              return lj_ir_kint(J, k);
46✔
344
            return 0;  /* Type mismatch. */
345
          } else {
346
            return lj_ir_knum(J, numberVnum(tv));
16✔
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,571✔
358
{
359
  int conv = (tvisint(&J->L->base[slot]) != (t==IRT_INT)) ? IRSLOAD_CONVERT : 0;
2,571✔
360
  return sloadt(J, (int32_t)slot,
7,713✔
361
                t + (((mode & IRSLOAD_TYPECHECK) ||
2,571✔
362
                      (conv && t == IRT_INT && !(mode >> 16))) ?
2,571✔
363
                     IRT_GUARD : 0),
2,571✔
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,270✔
369
                     IRType t, int mode)
370
{
371
  TRef tr = J->base[slot];
5,270✔
372
  if (!tr) {
5,270✔
373
    tr = find_kinit(J, fori, slot, t);
4,815✔
374
    if (!tr)
4,815✔
375
      tr = fori_load(J, slot, t, mode);
229✔
376
  }
377
  return tr;
5,270✔
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,443✔
384
{
385
  return (tvisint(o) ? intV(o) : (int32_t)o->u32.hi) >= 0;
5,443✔
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,585✔
390
{
391
  lua_Number stopv = numberVnum(&o[FORL_STOP]);
2,585✔
392
  lua_Number idxv = numberVnum(&o[FORL_IDX]);
2,585✔
393
  lua_Number stepv = numberVnum(&o[FORL_STEP]);
2,585✔
394
  if (isforl)
2,585✔
395
    idxv += stepv;
2,362✔
396
  if (rec_for_direction(&o[FORL_STEP])) {
2,585✔
397
    if (idxv <= stopv) {
2,525✔
398
      *op = IR_LE;
2,463✔
399
      return idxv + 2*stepv > stopv ? LOOPEV_ENTERLO : LOOPEV_ENTER;
2,463✔
400
    }
401
    *op = IR_GT; return LOOPEV_LEAVE;
62✔
402
  } else {
403
    if (stopv <= idxv) {
60✔
404
      *op = IR_GE;
60✔
405
      return idxv + 2*stepv < stopv ? LOOPEV_ENTERLO : LOOPEV_ENTER;
60✔
406
    }
407
    *op = IR_LT; return LOOPEV_LEAVE;
×
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,858✔
413
                          TRef stop, TRef step, int init)
414
{
415
  if (!tref_isk(step)) {
2,858✔
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);
234✔
418
    emitir(IRTG(dir ? IR_GE : IR_LT, t), step, zero);
235✔
419
    /* Add hoistable overflow checks for a narrowed FORL index. */
420
    if (init && t == IRT_INT) {
234✔
421
      if (tref_isk(stop)) {
5✔
422
        /* Constant stop: optimize check away or to a range check for step. */
423
        int32_t k = IR(tref_ref(stop))->i;
×
424
        if (dir) {
×
425
          if (k > 0)
×
426
            emitir(IRTGI(IR_LE), step, lj_ir_kint(J, (int32_t)0x7fffffff-k));
×
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,624✔
438
    /* Constant step: optimize overflow check to a range check for stop. */
439
    int32_t k = IR(tref_ref(step))->i;
205✔
440
    k = (int32_t)(dir ? 0x7fffffff : 0x80000000) - k;
205✔
441
    emitir(IRTGI(dir ? IR_LE : IR_GE), stop, lj_ir_kint(J, k));
235✔
442
  }
443
}
2,858✔
444

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

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

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

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

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

556
/* Record ITERL/JITERL. */
557
static LoopEvent rec_iterl(jit_State *J, const BCIns iterins)
105✔
558
{
559
  BCReg ra = bc_a(iterins);
105✔
560
  if (!tref_isnil(getslot(J, ra))) {  /* Looping back? */
105✔
561
    J->base[ra-1] = J->base[ra];  /* Copy result of ITERC to control var. */
80✔
562
    J->maxslot = ra-1+bc_b(J->pc[-1]);
80✔
563
    J->pc += bc_j(iterins)+1;
80✔
564
    return LOOPEV_ENTER;
80✔
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)
389✔
574
{
575
  if (ra < J->maxslot) J->maxslot = ra;
20✔
576
  J->pc++;
389✔
577
  return LOOPEV_ENTER;
389✔
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,210✔
585
    if (mref(J->penalty[i].pc, const BCIns) == pc) {
9,070✔
586
      if ((J->penalty[i].reason == LJ_TRERR_LLEAVE ||
22✔
587
           J->penalty[i].reason == LJ_TRERR_LINNER) &&
22✔
588
          J->penalty[i].val >= 2*PENALTY_MIN)
22✔
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,140✔
597
{
598
  if (J->parent == 0 && J->exitno == 0) {
2,140✔
599
    if (pc == J->startpc && J->framedepth + J->retdepth == 0) {
2,022✔
600
      /* Same loop? */
601
      if (ev == LOOPEV_LEAVE)  /* Must loop back to form a root trace. */
1,856✔
602
        lj_trace_err(J, LJ_TRERR_LLEAVE);
39✔
603
      lj_record_stop(J, LJ_TRLINK_LOOP, J->cur.traceno);  /* Looping trace. */
1,817✔
604
    } else if (ev != LOOPEV_LEAVE) {  /* Entering inner loop? */
166✔
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))
163✔
612
        lj_trace_err(J, LJ_TRERR_LINNER);  /* Root trace hit an inner loop. */
159✔
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. */
118✔
619
    J->loopref = J->cur.nins;
97✔
620
    if (--J->loopunroll < 0)
97✔
621
      lj_trace_err(J, LJ_TRERR_LUNROLL);  /* Limit loop unrolling. */
×
622
  }  /* Side trace continues across a loop that's left or not entered. */
623
}
1,942✔
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)
716✔
627
{
628
  if (J->parent == 0 && J->exitno == 0) {  /* Root trace hit an inner loop. */
716✔
629
    /* Better let the inner loop spawn a side trace back here. */
630
    lj_trace_err(J, LJ_TRERR_LINNER);
25✔
631
  } else if (ev != LOOPEV_LEAVE) {  /* Side trace enters a compiled loop. */
691✔
632
    J->instunroll = 0;  /* Cannot continue across a compiled loop op. */
669✔
633
    if (J->pc == J->startpc && J->framedepth + J->retdepth == 0)
669✔
634
      lj_record_stop(J, LJ_TRLINK_LOOP, J->cur.traceno);  /* Form extra loop. */
165✔
635
    else
636
      lj_record_stop(J, LJ_TRLINK_ROOT, lnk);  /* Link to the loop. */
504✔
637
  }  /* Side trace continues across a loop that's left or not entered. */
638
}
691✔
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)
194,876✔
669
{
670
  if (J->prof_mode && rec_profile_need(J, J->pt, pc)) {
194,876✔
671
    emitir(IRTG(IR_PROF, IRT_NIL), 0, 0);
1✔
672
    lj_snap_add(J);
1✔
673
  }
674
}
194,876✔
675

676
static void rec_profile_ret(jit_State *J)
4,032✔
677
{
678
  if (J->prof_mode == 'f') {
4,032✔
679
    emitir(IRTG(IR_PROF, IRT_NIL), 0, 0);
×
680
    J->prev_pt = NULL;
×
681
    lj_snap_add(J);
×
682
  }
683
}
4,032✔
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)
7,797✔
691
{
692
  TRef kfunc;
7,797✔
693
  if (isluafunc(fn)) {
7,797✔
694
    GCproto *pt = funcproto(fn);
4,137✔
695
    /* Too many closures created? Probably not a monomorphic function. */
696
    if (pt->flags >= PROTO_CLC_POLY) {  /* Specialize to prototype instead. */
4,137✔
697
      TRef trpt = emitir(IRT(IR_FLOAD, IRT_PGC), tr, IRFL_FUNC_PC);
9✔
698
      emitir(IRTG(IR_EQ, IRT_PGC), trpt, lj_ir_kptr(J, proto_bc(pt)));
9✔
699
      (void)lj_ir_kgc(J, obj2gco(pt), IRT_PROTO);  /* Prevent GC of proto. */
9✔
700
      return tr;
9✔
701
    }
702
  } else {
703
    /* Don't specialize to non-monomorphic builtins. */
704
    switch (fn->c.ffid) {
3,660✔
705
    case FF_coroutine_wrap_aux:
4✔
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);
4✔
710
        emitir(IRTG(IR_EQ, IRT_INT), trid, lj_ir_kint(J, fn->c.ffid));
4✔
711
      }
712
      return tr;
4✔
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);
7,784✔
720
  emitir(IRTG(IR_EQ, IRT_FUNC), tr, kfunc);
7,784✔
721
  return kfunc;
7,784✔
722
}
723

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

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

769
/* Record tail call. */
770
void lj_record_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs)
673✔
771
{
772
  rec_call_setup(J, func, nargs);
673✔
773
  if (frame_isvarg(J->L->base - 1)) {
673✔
774
    BCReg cbase = (BCReg)frame_delta(J->L->base - 1);
3✔
775
    if (--J->framedepth < 0)
3✔
776
      lj_trace_err(J, LJ_TRERR_NYIRETL);
×
777
    J->baseslot -= (BCReg)cbase;
3✔
778
    J->base -= cbase;
3✔
779
    func += cbase;
3✔
780
  }
781
  /* Move func + args down. */
782
  if (LJ_FR2 && J->baseslot == 2)
673✔
783
    J->base[func+1] = TREF_FRAME;
587✔
784
  memmove(&J->base[-1-LJ_FR2], &J->base[func], sizeof(TRef)*(J->maxslot+1+LJ_FR2));
673✔
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)
673✔
788
    lj_trace_err(J, LJ_TRERR_LUNROLL);
12✔
789
}
661✔
790

791
/* Check unroll limits for down-recursion. */
792
static int check_downrec_unroll(jit_State *J, GCproto *pt)
1,143✔
793
{
794
  IRRef ptref;
1,143✔
795
  for (ptref = J->chain[IR_KGC]; ptref; ptref = IR(ptref)->prev)
3,748✔
796
    if (ir_kgc(IR(ptref)) == obj2gco(pt)) {
2,648✔
797
      int count = 0;
61✔
798
      IRRef ref;
61✔
799
      for (ref = J->chain[IR_RETF]; ref; ref = IR(ref)->prev)
143✔
800
        if (IR(ref)->op1 == ptref)
82✔
801
          count++;
73✔
802
      if (count) {
61✔
803
        if (J->pc == J->startpc) {
61✔
804
          if (count + J->tailcalled > J->param[JIT_P_recunroll])
23✔
805
            return 1;
806
        } else {
807
          lj_trace_err(J, LJ_TRERR_DOWNREC);
38✔
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)
7,380✔
818
{
819
  TValue *frame = J->L->base - 1;
7,380✔
820
  ptrdiff_t i;
7,380✔
821
  for (i = 0; i < gotresults; i++)
14,088✔
822
    (void)getslot(J, rbase+i);  /* Ensure all results have a reference. */
6,708✔
823
  while (frame_ispcall(frame)) {  /* Immediately resolve pcall() returns. */
7,407✔
824
    BCReg cbase = (BCReg)frame_delta(frame);
38✔
825
    if (--J->framedepth <= 0)
38✔
826
      lj_trace_err(J, LJ_TRERR_NYIRETL);
11✔
827
    lj_assertJ(J->baseslot > 1+LJ_FR2, "bad baseslot for return");
27✔
828
    gotresults++;
27✔
829
    rbase += cbase;
27✔
830
    J->baseslot -= (BCReg)cbase;
27✔
831
    J->base -= cbase;
27✔
832
    J->base[--rbase] = TREF_TRUE;  /* Prepend true to results. */
27✔
833
    frame = frame_prevd(frame);
27✔
834
    J->needsnap = 1;  /* Stop catching on-trace errors. */
27✔
835
  }
836
  /* Return to lower frame via interpreter for unhandled cases. */
837
  if (J->framedepth == 0 && J->pt && bc_isret(bc_op(*J->pc)) &&
7,369✔
838
       (!frame_islua(frame) ||
1,289✔
839
        (J->parent == 0 && J->exitno == 0 &&
1,244✔
840
         !bc_isret(bc_op(J->cur.startins))))) {
203✔
841
    /* NYI: specialize to frame type and return directly, not via RET*. */
842
    for (i = 0; i < (ptrdiff_t)rbase; i++)
319✔
843
      J->base[i] = 0;  /* Purge dead slots. */
173✔
844
    J->maxslot = rbase + (BCReg)gotresults;
146✔
845
    lj_record_stop(J, LJ_TRLINK_RETURN, 0);  /* Return to interpreter. */
146✔
846
    return;
146✔
847
  }
848
  if (frame_isvarg(frame)) {
7,223✔
849
    BCReg cbase = (BCReg)frame_delta(frame);
25✔
850
    if (--J->framedepth < 0)  /* NYI: return of vararg func to lower frame. */
25✔
851
      lj_trace_err(J, LJ_TRERR_NYIRETL);
×
852
    lj_assertJ(J->baseslot > 1+LJ_FR2, "bad baseslot for return");
25✔
853
    rbase += cbase;
25✔
854
    J->baseslot -= (BCReg)cbase;
25✔
855
    J->base -= cbase;
25✔
856
    frame = frame_prevd(frame);
25✔
857
  }
858
  if (frame_islua(frame)) {  /* Return to Lua frame. */
7,223✔
859
    BCIns callins = *(frame_pc(frame)-1);
6,657✔
860
    ptrdiff_t nresults = bc_b(callins) ? (ptrdiff_t)bc_b(callins)-1 :gotresults;
6,657✔
861
    BCReg cbase = bc_a(callins);
6,657✔
862
    GCproto *pt = funcproto(frame_func(frame - (cbase+1+LJ_FR2)));
6,657✔
863
    if ((pt->flags & PROTO_NOJIT))
6,657✔
864
      lj_trace_err(J, LJ_TRERR_CJITOFF);
×
865
    if (J->framedepth == 0 && J->pt && frame == J->L->base - 1) {
6,657✔
866
      if (check_downrec_unroll(J, pt)) {
1,143✔
867
        J->maxslot = (BCReg)(rbase + gotresults);
5✔
868
        lj_snap_purge(J);
5✔
869
        lj_record_stop(J, LJ_TRLINK_DOWNREC, J->cur.traceno);  /* Down-rec. */
5✔
870
        return;
5✔
871
      }
872
      lj_snap_add(J);
1,100✔
873
    }
874
    for (i = 0; i < nresults; i++)  /* Adjust results. */
11,660✔
875
      J->base[i-1-LJ_FR2] = i < gotresults ? J->base[rbase+i] : TREF_NIL;
5,046✔
876
    J->maxslot = cbase+(BCReg)nresults;
6,614✔
877
    if (J->framedepth > 0) {  /* Return to a frame that is part of the trace. */
6,614✔
878
      J->framedepth--;
5,319✔
879
      lj_assertJ(J->baseslot > cbase+1+LJ_FR2, "bad baseslot for return");
5,319✔
880
      J->baseslot -= cbase+1+LJ_FR2;
5,319✔
881
      J->base -= cbase+1+LJ_FR2;
5,319✔
882
    } else if (J->parent == 0 && J->exitno == 0 &&
1,295✔
883
               !bc_isret(bc_op(J->cur.startins))) {
91✔
884
      /* Return to lower frame would leave the loop in a root trace. */
885
      lj_trace_err(J, LJ_TRERR_LLEAVE);
3✔
886
    } else if (J->needsnap) {  /* Tailcalled to ff with side-effects. */
1,292✔
887
      lj_trace_err(J, LJ_TRERR_NYIRETL);  /* No way to insert snapshot here. */
×
888
    } else {  /* Return to lower frame. Guard for the target we return to. */
889
      TRef trpt = lj_ir_kgc(J, obj2gco(pt), IRT_PROTO);
1,292✔
890
      TRef trpc = lj_ir_kptr(J, (void *)frame_pc(frame));
1,292✔
891
      emitir(IRTG(IR_RETF, IRT_PGC), trpt, trpc);
1,292✔
892
      J->retdepth++;
1,292✔
893
      J->needsnap = 1;
1,292✔
894
      lj_assertJ(J->baseslot == 1+LJ_FR2, "bad baseslot for return");
1,292✔
895
      /* Shift result slots up and clear the slots of the new frame below. */
896
      memmove(J->base + cbase, J->base-1-LJ_FR2, sizeof(TRef)*nresults);
1,292✔
897
      memset(J->base-1-LJ_FR2, 0, sizeof(TRef)*(cbase+1+LJ_FR2));
1,292✔
898
    }
899
  } else if (frame_iscont(frame)) {  /* Return to continuation frame. */
566✔
900
    ASMFunction cont = frame_contf(frame);
566✔
901
    BCReg cbase = (BCReg)frame_delta(frame);
566✔
902
    if ((J->framedepth -= 2) < 0)
566✔
903
      lj_trace_err(J, LJ_TRERR_NYIRETL);
4✔
904
    J->baseslot -= (BCReg)cbase;
562✔
905
    J->base -= cbase;
562✔
906
    J->maxslot = cbase-(2<<LJ_FR2);
562✔
907
    if (cont == lj_cont_ra) {
562✔
908
      /* Copy result to destination slot. */
909
      BCReg dst = bc_a(*(frame_contpc(frame)-1));
349✔
910
      J->base[dst] = gotresults ? J->base[cbase+rbase] : TREF_NIL;
349✔
911
      if (dst >= J->maxslot) {
349✔
912
        J->maxslot = dst+1;
×
913
      }
914
    } else if (cont == lj_cont_nop) {
213✔
915
      /* Nothing to do here. */
916
    } else if (cont == lj_cont_cat) {
111✔
917
      BCReg bslot = bc_b(*(frame_contpc(frame)-1));
5✔
918
      TRef tr = gotresults ? J->base[cbase+rbase] : TREF_NIL;
5✔
919
      if (bslot != J->maxslot) {  /* Concatenate the remainder. */
5✔
920
        TValue *b = J->L->base, save;  /* Simulate lower frame and result. */
2✔
921
        J->base[J->maxslot] = tr;
2✔
922
        copyTV(J->L, &save, b-(2<<LJ_FR2));
2✔
923
        if (gotresults)
2✔
924
          copyTV(J->L, b-(2<<LJ_FR2), b+rbase);
2✔
925
        else
926
          setnilV(b-(2<<LJ_FR2));
×
927
        J->L->base = b - cbase;
2✔
928
        tr = rec_cat(J, bslot, cbase-(2<<LJ_FR2));
2✔
929
        b = J->L->base + cbase;  /* Undo. */
2✔
930
        J->L->base = b;
2✔
931
        copyTV(J->L, b-(2<<LJ_FR2), &save);
2✔
932
      }
933
      if (tr) {  /* Store final result. */
5✔
934
        BCReg dst = bc_a(*(frame_contpc(frame)-1));
3✔
935
        J->base[dst] = tr;
3✔
936
        if (dst >= J->maxslot) {
3✔
937
          J->maxslot = dst+1;
×
938
        }
939
      }  /* Otherwise continue with another __concat call. */
940
    } else {
941
      /* Result type already specialized. */
942
      lj_assertJ(cont == lj_cont_condf || cont == lj_cont_condt,
943
                 "bad continuation type");
944
    }
945
  } else {
946
    lj_trace_err(J, LJ_TRERR_NYIRETL);  /* NYI: handle return to C frame. */
×
947
  }
948
  lj_assertJ(J->baseslot >= 1+LJ_FR2, "bad baseslot for return");
7,324✔
949
}
950

951
/* -- Metamethod handling ------------------------------------------------- */
952

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

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

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

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

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

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

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

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

1212
/* -- Indexed access ------------------------------------------------------ */
1213

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

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

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

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

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

1391
/* Determine whether a key is NOT one of the fast metamethod names. */
1392
static int nommstr(jit_State *J, TRef key)
48,548✔
1393
{
1394
  if (tref_isstr(key)) {
48,548✔
1395
    if (tref_isk(key)) {
45,740✔
1396
      GCstr *str = ir_kstr(IR(tref_ref(key)));
45,728✔
1397
      uint32_t mm;
45,728✔
1398
      for (mm = 0; mm <= MM_FAST; mm++)
320,096✔
1399
        if (mmname_str(J2G(J), mm) == str)
274,368✔
1400
          return 0;  /* MUST be one the fast metamethod names. */
1401
    } else {
1402
      return 0;  /* Variable string key MAY be a metamethod name. */
1403
    }
1404
  }
1405
  return 1;  /* CANNOT be a metamethod name. */
1406
}
1407

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

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

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

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

1466
  if (ix->val == 0) {  /* Indexed load */
101,679✔
1467
    IRType t = itype2irt(oldv);
53,121✔
1468
    TRef res;
53,121✔
1469
    if (oldv == niltvg(J2G(J))) {
53,121✔
1470
      emitir(IRTG(IR_EQ, IRT_PGC), xref, lj_ir_kkptr(J, niltvg(J2G(J))));
409✔
1471
      res = TREF_NIL;
409✔
1472
    } else {
1473
      res = emitir(IRTG(loadop, t), xref, 0);
52,712✔
1474
    }
1475
    if (tref_ref(res) < rbref) {  /* HREFK + load forwarded? */
53,121✔
1476
      lj_ir_rollback(J, rbref);  /* Rollback to eliminate hmask guard. */
1,540✔
1477
      J->guardemit = rbguard;
1,540✔
1478
    }
1479
    if (t == IRT_NIL && ix->idxchain && lj_record_mm_lookup(J, ix, MM_index))
53,121✔
1480
      goto handlemm;
107✔
1481
    if (irtype_ispri(t)) res = TREF_PRI(t);  /* Canonicalize primitives. */
53,014✔
1482
    return res;
53,014✔
1483
  } else {  /* Indexed store. */
1484
    GCtab *mt = tabref(tabV(&ix->tabv)->metatable);
48,558✔
1485
    int keybarrier = tref_isgcv(ix->key) && !tref_isnil(ix->val);
48,558✔
1486
    if (tref_ref(xref) < rbref) {  /* HREFK forwarded? */
48,558✔
1487
      lj_ir_rollback(J, rbref);  /* Rollback to eliminate hmask guard. */
195✔
1488
      J->guardemit = rbguard;
195✔
1489
    }
1490
    if (tvisnil(oldv)) {  /* Previous value was nil? */
48,558✔
1491
      /* Need to duplicate the hasmm check for the early guards. */
1492
      int hasmm = 0;
7,817✔
1493
      if (ix->idxchain && mt) {
7,817✔
1494
        cTValue *mo = lj_tab_getstr(mt, mmname_str(J2G(J), MM_newindex));
27✔
1495
        hasmm = mo && !tvisnil(mo);
27✔
1496
      }
1497
      if (hasmm)
10✔
1498
        emitir(IRTG(loadop, IRT_NIL), xref, 0);  /* Guard for nil value. */
10✔
1499
      else if (xrefop == IR_HREF)
7,807✔
1500
        emitir(IRTG(oldv == niltvg(J2G(J)) ? IR_EQ : IR_NE, IRT_PGC),
6,404✔
1501
               xref, lj_ir_kkptr(J, niltvg(J2G(J))));
1502
      if (ix->idxchain && lj_record_mm_lookup(J, ix, MM_newindex)) {
7,817✔
1503
        lj_assertJ(hasmm, "inconsistent metamethod handling");
10✔
1504
        goto handlemm;
10✔
1505
      }
1506
      lj_assertJ(!hasmm, "inconsistent metamethod handling");
7,807✔
1507
      if (oldv == niltvg(J2G(J))) {  /* Need to insert a new key. */
7,807✔
1508
        TRef key = ix->key;
6,770✔
1509
        if (tref_isinteger(key))  /* NEWREF needs a TValue as a key. */
6,770✔
1510
          key = emitir(IRTN(IR_CONV), key, IRCONV_NUM_INT);
121✔
1511
        else if (tref_isnumber(key) && tref_isk(key) && tvismzero(&ix->keyv))
6,649✔
1512
          key = lj_ir_knum_zero(J);  /* Canonicalize -0.0 to +0.0. */
2✔
1513
        xref = emitir(IRT(IR_NEWREF, IRT_PGC), ix->tab, key);
6,770✔
1514
        keybarrier = 0;  /* NEWREF already takes care of the key barrier. */
6,770✔
1515
#ifdef LUAJIT_ENABLE_TABLE_BUMP
1516
        if ((J->flags & JIT_F_OPT_SINK))  /* Avoid a separate flag. */
1517
          rec_idx_bump(J, ix);
1518
#endif
1519
      }
1520
    } else if (!lj_opt_fwd_wasnonnil(J, loadop, tref_ref(xref))) {
40,741✔
1521
      /* Cannot derive that the previous value was non-nil, must do checks. */
1522
      if (xrefop == IR_HREF)  /* Guard against store to niltv. */
38,558✔
1523
        emitir(IRTG(IR_NE, IRT_PGC), xref, lj_ir_kkptr(J, niltvg(J2G(J))));
6✔
1524
      if (ix->idxchain) {  /* Metamethod lookup required? */
38,558✔
1525
        /* A check for NULL metatable is cheaper (hoistable) than a load. */
1526
        if (!mt) {
38,549✔
1527
          TRef mtref = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_TAB_META);
38,536✔
1528
          emitir(IRTG(IR_EQ, IRT_TAB), mtref, lj_ir_knull(J, IRT_TAB));
38,536✔
1529
        } else {
1530
          IRType t = itype2irt(oldv);
13✔
1531
          emitir(IRTG(loadop, t), xref, 0);  /* Guard for non-nil value. */
13✔
1532
        }
1533
      }
1534
    } else {
1535
      keybarrier = 0;  /* Previous non-nil value kept the key alive. */
1536
    }
1537
    /* Convert int to number before storing. */
1538
    if (!LJ_DUALNUM && tref_isinteger(ix->val))
48,548✔
1539
      ix->val = emitir(IRTN(IR_CONV), ix->val, IRCONV_NUM_INT);
348✔
1540
    emitir(IRT(loadop+IRDELTA_L2S, tref_type(ix->val)), xref, ix->val);
48,548✔
1541
    if (keybarrier || tref_isgcv(ix->val))
48,548✔
1542
      emitir(IRT(IR_TBAR, IRT_NIL), ix->tab, 0);
39,922✔
1543
    /* Invalidate neg. metamethod cache for stores with certain string keys. */
1544
    if (!nommstr(J, ix->key)) {
94,276✔
1545
      TRef fref = emitir(IRT(IR_FREF, IRT_PGC), ix->tab, IRFL_TAB_NOMM);
12✔
1546
      emitir(IRT(IR_FSTORE, IRT_U8), fref, lj_ir_kint(J, 0));
12✔
1547
    }
1548
    J->needsnap = 1;
48,548✔
1549
    return 0;
48,548✔
1550
  }
1551
}
1552

1553
static void rec_tsetm(jit_State *J, BCReg ra, BCReg rn, int32_t i)
4✔
1554
{
1555
  RecordIndex ix;
4✔
1556
  cTValue *basev = J->L->base;
4✔
1557
  GCtab *t = tabV(&basev[ra-1]);
4✔
1558
  settabV(J->L, &ix.tabv, t);
4✔
1559
  ix.tab = getslot(J, ra-1);
4✔
1560
  ix.idxchain = 0;
4✔
1561
#ifdef LUAJIT_ENABLE_TABLE_BUMP
1562
  if ((J->flags & JIT_F_OPT_SINK)) {
1563
    if (t->asize < i+rn-ra)
1564
      lj_tab_reasize(J->L, t, i+rn-ra);
1565
    setnilV(&ix.keyv);
1566
    rec_idx_bump(J, &ix);
1567
  }
1568
#endif
1569
  for (; ra < rn; i++, ra++) {
8✔
1570
    setintV(&ix.keyv, i);
4✔
1571
    ix.key = lj_ir_kint(J, i);
4✔
1572
    copyTV(J->L, &ix.valv, &basev[ra]);
4✔
1573
    ix.val = getslot(J, ra);
4✔
1574
    lj_record_idx(J, &ix);
4✔
1575
  }
1576
}
4✔
1577

1578
/* -- Upvalue access ------------------------------------------------------ */
1579

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

1605
/* Record upvalue load/store. */
1606
static TRef rec_upvalue(jit_State *J, uint32_t uv, TRef val)
5,487✔
1607
{
1608
  GCupval *uvp = &gcref(J->fn->l.uvptr[uv])->uv;
5,487✔
1609
  TRef fn = getcurrf(J);
5,487✔
1610
  IRRef uref;
5,487✔
1611
  int needbarrier = 0;
5,487✔
1612
  if (rec_upvalue_constify(J, uvp)) {  /* Try to constify immutable upvalue. */
5,487✔
1613
    TRef tr, kfunc;
4,840✔
1614
    lj_assertJ(val == 0, "bad usage");
4,840✔
1615
    if (!tref_isk(fn)) {  /* Late specialization of current function. */
4,840✔
1616
      if (J->pt->flags >= PROTO_CLC_POLY)
1,321✔
1617
        goto noconstify;
54✔
1618
      kfunc = lj_ir_kfunc(J, J->fn);
1,267✔
1619
      emitir(IRTG(IR_EQ, IRT_FUNC), fn, kfunc);
1,267✔
1620
#if LJ_FR2
1621
      J->base[-2] = kfunc;
1,267✔
1622
#else
1623
      J->base[-1] = kfunc | TREF_FRAME;
1624
#endif
1625
      fn = kfunc;
1,267✔
1626
    }
1627
    tr = lj_record_constify(J, uvval(uvp));
4,786✔
1628
    if (tr)
4,786✔
1629
      return tr;
1630
  }
1631
noconstify:
647✔
1632
  /* Note: this effectively limits LJ_MAX_UPVAL to 127. */
1633
  uv = (uv << 8) | (hashrot(uvp->dhash, uvp->dhash + HASH_BIAS) & 0xff);
701✔
1634
  if (!uvp->closed) {
701✔
1635
    uref = tref_ref(emitir(IRTG(IR_UREFO, IRT_PGC), fn, uv));
379✔
1636
    /* In current stack? */
1637
    if (uvval(uvp) >= tvref(J->L->stack) &&
379✔
1638
        uvval(uvp) < tvref(J->L->maxstack)) {
379✔
1639
      int32_t slot = (int32_t)(uvval(uvp) - (J->L->base - J->baseslot));
370✔
1640
      if (slot >= 0) {  /* Aliases an SSA slot? */
370✔
1641
        emitir(IRTG(IR_EQ, IRT_PGC),
212✔
1642
               REF_BASE,
1643
               emitir(IRT(IR_ADD, IRT_PGC), uref,
1644
                      lj_ir_kint(J, (slot - 1 - LJ_FR2) * -8)));
1645
        slot -= (int32_t)J->baseslot;  /* Note: slot number may be negative! */
212✔
1646
        if (val == 0) {
212✔
1647
          return getslot(J, slot);
92✔
1648
        } else {
1649
          J->base[slot] = val;
120✔
1650
          if (slot >= (int32_t)J->maxslot) J->maxslot = (BCReg)(slot+1);
120✔
1651
          return 0;
120✔
1652
        }
1653
      }
1654
    }
1655
    emitir(IRTG(IR_UGT, IRT_PGC),
167✔
1656
           emitir(IRT(IR_SUB, IRT_PGC), uref, REF_BASE),
1657
           lj_ir_kint(J, (J->baseslot + J->maxslot) * 8));
1658
  } else {
1659
    needbarrier = 1;
322✔
1660
    uref = tref_ref(emitir(IRTG(IR_UREFC, IRT_PGC), fn, uv));
322✔
1661
  }
1662
  if (val == 0) {  /* Upvalue load */
489✔
1663
    IRType t = itype2irt(uvval(uvp));
437✔
1664
    TRef res = emitir(IRTG(IR_ULOAD, t), uref, 0);
437✔
1665
    if (irtype_ispri(t)) res = TREF_PRI(t);  /* Canonicalize primitive refs. */
437✔
1666
    return res;
437✔
1667
  } else {  /* Upvalue store. */
1668
    /* Convert int to number before storing. */
1669
    if (!LJ_DUALNUM && tref_isinteger(val))
52✔
1670
      val = emitir(IRTN(IR_CONV), val, IRCONV_NUM_INT);
1✔
1671
    emitir(IRT(IR_USTORE, tref_type(val)), uref, val);
52✔
1672
    if (needbarrier && tref_isgcv(val))
52✔
1673
      emitir(IRT(IR_OBAR, IRT_NIL), uref, val);
2✔
1674
    J->needsnap = 1;
52✔
1675
    return 0;
52✔
1676
  }
1677
}
1678

1679
/* -- Record calls to Lua functions --------------------------------------- */
1680

1681
/* Check unroll limits for calls. */
1682
static void check_call_unroll(jit_State *J, TraceNo lnk)
3,475✔
1683
{
1684
  cTValue *frame = J->L->base - 1;
3,475✔
1685
  void *pc = mref(frame_func(frame)->l.pc, void);
3,475✔
1686
  int32_t depth = J->framedepth;
3,475✔
1687
  int32_t count = 0;
3,475✔
1688
  if ((J->pt->flags & PROTO_VARARG)) depth--;  /* Vararg frame still missing. */
3,475✔
1689
  for (; depth > 0; depth--) {  /* Count frames with same prototype. */
12,079✔
1690
    if (frame_iscont(frame)) depth--;
8,604✔
1691
    frame = frame_prev(frame);
8,604✔
1692
    if (mref(frame_func(frame)->l.pc, void) == pc)
8,604✔
1693
      count++;
505✔
1694
  }
1695
  if (J->pc == J->startpc) {
3,475✔
1696
    if (count + J->tailcalled > J->param[JIT_P_recunroll]) {
69✔
1697
      J->pc++;
17✔
1698
      if (J->framedepth + J->retdepth == 0)
17✔
1699
        lj_record_stop(J, LJ_TRLINK_TAILREC, J->cur.traceno);  /* Tail-rec. */
5✔
1700
      else
1701
        lj_record_stop(J, LJ_TRLINK_UPREC, J->cur.traceno);  /* Up-recursion. */
12✔
1702
    }
1703
  } else {
1704
    if (count > J->param[JIT_P_callunroll]) {
3,406✔
1705
      if (lnk) {  /* Possible tail- or up-recursion. */
38✔
1706
        lj_trace_flush(J, lnk);  /* Flush trace that only returns. */
6✔
1707
        /* Set a small, pseudo-random hotcount for a quick retry of JFUNC*. */
1708
        hotcount_set(J2GG(J), J->pc+1, LJ_PRNG_BITS(J, 4));
6✔
1709
      }
1710
      lj_trace_err(J, LJ_TRERR_CUNROLL);
38✔
1711
    }
1712
  }
1713
}
3,437✔
1714

1715
/* Record Lua function setup. */
1716
static void rec_func_setup(jit_State *J)
4,135✔
1717
{
1718
  GCproto *pt = J->pt;
4,135✔
1719
  BCReg s, numparams = pt->numparams;
4,135✔
1720
  if ((pt->flags & PROTO_NOJIT))
4,135✔
1721
    lj_trace_err(J, LJ_TRERR_CJITOFF);
×
1722
  if (J->baseslot + pt->framesize >= LJ_MAX_JSLOTS)
4,135✔
1723
    lj_trace_err(J, LJ_TRERR_STACKOV);
×
1724
  /* Fill up missing parameters with nil. */
1725
  for (s = J->maxslot; s < numparams; s++)
4,480✔
1726
    J->base[s] = TREF_NIL;
345✔
1727
  /* The remaining slots should never be read before they are written. */
1728
  J->maxslot = numparams;
4,135✔
1729
}
4,135✔
1730

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

1755
/* Record entry to a Lua function. */
1756
static void rec_func_lua(jit_State *J)
892✔
1757
{
1758
  rec_func_setup(J);
892✔
1759
  check_call_unroll(J, 0);
892✔
1760
}
860✔
1761

1762
/* Record entry to an already compiled function. */
1763
static void rec_func_jit(jit_State *J, TraceNo lnk)
3,243✔
1764
{
1765
  GCtrace *T;
3,243✔
1766
  rec_func_setup(J);
3,243✔
1767
  T = traceref(J, lnk);
3,243✔
1768
  if (T->linktype == LJ_TRLINK_RETURN) {  /* Trace returns to interpreter? */
3,243✔
1769
    check_call_unroll(J, lnk);
2,583✔
1770
    /* Temporarily unpatch JFUNC* to continue recording across function. */
1771
    J->patchins = *J->pc;
2,577✔
1772
    J->patchpc = (BCIns *)J->pc;
2,577✔
1773
    *J->patchpc = T->startins;
2,577✔
1774
    return;
2,577✔
1775
  }
1776
  J->instunroll = 0;  /* Cannot continue across a compiled function. */
660✔
1777
  if (J->pc == J->startpc && J->framedepth + J->retdepth == 0)
660✔
1778
    lj_record_stop(J, LJ_TRLINK_TAILREC, J->cur.traceno);  /* Extra tail-rec. */
×
1779
  else
1780
    lj_record_stop(J, LJ_TRLINK_ROOT, lnk);  /* Link to the function. */
660✔
1781
}
1782

1783
/* -- Vararg handling ----------------------------------------------------- */
1784

1785
/* Detect y = select(x, ...) idiom. */
1786
static int select_detect(jit_State *J)
14✔
1787
{
1788
  BCIns ins = J->pc[1];
14✔
1789
  if (bc_op(ins) == BC_CALLM && bc_b(ins) == 2 && bc_c(ins) == 1) {
14✔
1790
    cTValue *func = &J->L->base[bc_a(ins)];
13✔
1791
    if (tvisfunc(func) && funcV(func)->c.ffid == FF_select) {
13✔
1792
      TRef kfunc = lj_ir_kfunc(J, funcV(func));
9✔
1793
      emitir(IRTG(IR_EQ, IRT_FUNC), getslot(J, bc_a(ins)), kfunc);
9✔
1794
      return 1;
9✔
1795
    }
1796
  }
1797
  return 0;
1798
}
1799

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

1904
/* -- Record allocations -------------------------------------------------- */
1905

1906
static TRef rec_tnew(jit_State *J, uint32_t ah)
404✔
1907
{
1908
  uint32_t asize = ah & 0x7ff;
404✔
1909
  uint32_t hbits = ah >> 11;
404✔
1910
  TRef tr;
404✔
1911
  if (asize == 0x7ff) asize = 0x801;
×
1912
  tr = emitir(IRTG(IR_TNEW, IRT_TAB), asize, hbits);
404✔
1913
#ifdef LUAJIT_ENABLE_TABLE_BUMP
1914
  J->rbchash[(tr & (RBCHASH_SLOTS-1))].ref = tref_ref(tr);
1915
  setmref(J->rbchash[(tr & (RBCHASH_SLOTS-1))].pc, J->pc);
1916
  setgcref(J->rbchash[(tr & (RBCHASH_SLOTS-1))].pt, obj2gco(J->pt));
1917
#endif
1918
  return tr;
404✔
1919
}
1920

1921
/* -- Concatenation ------------------------------------------------------- */
1922

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

1969
/* -- Record bytecode ops ------------------------------------------------- */
1970

1971
/* Prepare for comparison. */
1972
static void rec_comp_prep(jit_State *J)
3,170✔
1973
{
1974
  /* Prevent merging with snapshot #0 (GC exit) since we fixup the PC. */
1975
  if (J->cur.nsnap == 1 && J->cur.snap[0].ref == J->cur.nins)
3,170✔
1976
    emitir_raw(IRT(IR_NOP, IRT_NIL), 0, 0);
27✔
1977
  lj_snap_add(J);
3,170✔
1978
}
3,170✔
1979

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

2001
/* Record the next bytecode instruction (_before_ it's executed). */
2002
void lj_record_ins(jit_State *J)
195,392✔
2003
{
2004
  cTValue *lbase;
195,392✔
2005
  RecordIndex ix;
195,392✔
2006
  const BCIns *pc;
195,392✔
2007
  BCIns ins;
195,392✔
2008
  BCOp op;
195,392✔
2009
  TRef ra, rb, rc;
195,392✔
2010

2011
  /* Perform post-processing action before recording the next instruction. */
2012
  if (LJ_UNLIKELY(J->postproc != LJ_POST_NONE)) {
195,392✔
2013
    switch (J->postproc) {
3,342✔
2014
    case LJ_POST_FIXCOMP:  /* Fixup comparison. */
20✔
2015
      pc = (const BCIns *)(uintptr_t)J2G(J)->tmptv.u64;
20✔
2016
      rec_comp_fixup(J, pc, (!tvistruecond(&J2G(J)->tmptv2) ^ (bc_op(*pc)&1)));
20✔
2017
      /* fallthrough */
2018
    case LJ_POST_FIXGUARD:  /* Fixup and emit pending guard. */
48✔
2019
    case LJ_POST_FIXGUARDSNAP:  /* Fixup and emit pending guard and snapshot. */
2020
      if (!tvistruecond(&J2G(J)->tmptv2)) {
48✔
2021
        J->fold.ins.o ^= 1;  /* Flip guard to opposite. */
23✔
2022
        if (J->postproc == LJ_POST_FIXGUARDSNAP) {
23✔
2023
          SnapShot *snap = &J->cur.snap[J->cur.nsnap-1];
×
2024
          J->cur.snapmap[snap->mapofs+snap->nent-1]--;  /* False -> true. */
×
2025
        }
2026
      }
2027
      lj_opt_fold(J);  /* Emit pending guard. */
48✔
2028
      /* fallthrough */
2029
    case LJ_POST_FIXBOOL:
62✔
2030
      if (!tvistruecond(&J2G(J)->tmptv2)) {
62✔
2031
        BCReg s;
29✔
2032
        TValue *tv = J->L->base;
29✔
2033
        for (s = 0; s < J->maxslot; s++)  /* Fixup stack slot (if any). */
203✔
2034
          if (J->base[s] == TREF_TRUE && tvisfalse(&tv[s])) {
180✔
2035
            J->base[s] = TREF_FALSE;
6✔
2036
            break;
6✔
2037
          }
2038
      }
2039
      break;
2040
    case LJ_POST_FIXCONST:
1✔
2041
      {
2042
        BCReg s;
1✔
2043
        TValue *tv = J->L->base;
1✔
2044
        for (s = 0; s < J->maxslot; s++)  /* Constify stack slots (if any). */
13✔
2045
          if (J->base[s] == TREF_NIL && !tvisnil(&tv[s]))
12✔
2046
            J->base[s] = lj_record_constify(J, &tv[s]);
1✔
2047
      }
2048
      break;
2049
    case LJ_POST_FFRETRY:  /* Suppress recording of retried fast function. */
3,279✔
2050
      if (bc_op(*J->pc) >= BC__MAX)
3,279✔
2051
        return;
21✔
2052
      break;
2053
    default: lj_assertJ(0, "bad post-processing mode"); break;
2054
    }
2055
    J->postproc = LJ_POST_NONE;
3,339✔
2056
  }
2057

2058
  /* Need snapshot before recording next bytecode (e.g. after a store). */
2059
  if (J->needsnap) {
195,389✔
2060
    J->needsnap = 0;
53,409✔
2061
    if (J->pt) lj_snap_purge(J);
53,409✔
2062
    lj_snap_add(J);
53,409✔
2063
    J->mergesnap = 1;
53,409✔
2064
  }
2065

2066
  /* Skip some bytecodes. */
2067
  if (LJ_UNLIKELY(J->bcskip > 0)) {
195,389✔
2068
    J->bcskip--;
18✔
2069
    return;
18✔
2070
  }
2071

2072
  /* Record only closed loops for root traces. */
2073
  pc = J->pc;
195,371✔
2074
  if (J->framedepth == 0 &&
195,371✔
2075
     (MSize)((char *)pc - (char *)J->bc_min) >= J->bc_extent)
169,469✔
2076
    lj_trace_err(J, LJ_TRERR_LLEAVE);
495✔
2077

2078
#ifdef LUA_USE_ASSERT
2079
  rec_check_slots(J);
2080
  rec_check_ir(J);
2081
#endif
2082

2083
#if LJ_HASPROFILE
2084
  rec_profile_ins(J, pc);
194,876✔
2085
#endif
2086

2087
  /* Keep a copy of the runtime values of var/num/str operands. */
2088
#define rav        (&ix.valv)
2089
#define rbv        (&ix.tabv)
2090
#define rcv        (&ix.keyv)
2091

2092
  lbase = J->L->base;
194,876✔
2093
  ins = *pc;
194,876✔
2094
  op = bc_op(ins);
194,876✔
2095
  ra = bc_a(ins);
194,876✔
2096
  ix.val = 0;
194,876✔
2097
  switch (bcmode_a(op)) {
194,876✔
2098
  case BCMvar:
52,767✔
2099
    copyTV(J->L, rav, &lbase[ra]); ix.val = ra = getslot(J, ra); break;
52,767✔
2100
  default: break;  /* Handled later. */
2101
  }
2102
  rb = bc_b(ins);
194,876✔
2103
  rc = bc_c(ins);
194,876✔
2104
  switch (bcmode_b(op)) {
194,876✔
2105
  case BCMnone: rb = 0; rc = bc_d(ins); break;  /* Upgrade rc to 'rd'. */
40,752✔
2106
  case BCMvar:
147,305✔
2107
    copyTV(J->L, rbv, &lbase[rb]); ix.tab = rb = getslot(J, rb); break;
147,305✔
2108
  default: break;  /* Handled later. */
2109
  }
2110
  switch (bcmode_c(op)) {
194,876✔
2111
  case BCMvar:
58,516✔
2112
    copyTV(J->L, rcv, &lbase[rc]); ix.key = rc = getslot(J, rc); break;
58,516✔
2113
  case BCMpri: setpriV(rcv, ~rc); ix.key = rc = TREF_PRI(IRT_NIL+rc); break;
2,521✔
2114
  case BCMnum: { cTValue *tv = proto_knumtv(J->pt, rc);
3,564✔
2115
    copyTV(J->L, rcv, tv); ix.key = rc = tvisint(tv) ? lj_ir_kint(J, intV(tv)) :
3,564✔
2116
    lj_ir_knumint(J, numV(tv)); } break;
3,564✔
2117
  case BCMstr: { GCstr *s = gco2str(proto_kgc(J->pt, ~(ptrdiff_t)rc));
97,023✔
2118
    setstrV(J->L, rcv, s); ix.key = rc = lj_ir_kstr(J, s); } break;
97,023✔
2119
  default: break;  /* Handled later. */
2120
  }
2121

2122
  switch (op) {
194,876✔
2123

2124
  /* -- Comparison ops ---------------------------------------------------- */
2125

2126
  case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
1,591✔
2127
#if LJ_HASFFI
2128
    if (tref_iscdata(ra) || tref_iscdata(rc)) {
1,591✔
2129
      rec_mm_comp_cdata(J, &ix, op, ((int)op & 2) ? MM_le : MM_lt);
20✔
2130
      break;
20✔
2131
    }
2132
#endif
2133
    /* Emit nothing for two numeric or string consts. */
2134
    if (!(tref_isk2(ra,rc) && tref_isnumber_str(ra) && tref_isnumber_str(rc))) {
1,571✔
2135
      IRType ta = tref_isinteger(ra) ? IRT_INT : tref_type(ra);
1,162✔
2136
      IRType tc = tref_isinteger(rc) ? IRT_INT : tref_type(rc);
1,162✔
2137
      int irop;
1,162✔
2138
      if (ta != tc) {
1,162✔
2139
        /* Widen mixed number/int comparisons to number/number comparison. */
2140
        if (ta == IRT_INT && tc == IRT_NUM) {
771✔
2141
          ra = emitir(IRTN(IR_CONV), ra, IRCONV_NUM_INT);
402✔
2142
          ta = IRT_NUM;
402✔
2143
        } else if (ta == IRT_NUM && tc == IRT_INT) {
369✔
2144
          rc = emitir(IRTN(IR_CONV), rc, IRCONV_NUM_INT);
369✔
2145
        } else if (LJ_52) {
×
2146
          ta = IRT_NIL;  /* Force metamethod for different types. */
2147
        } else if (!((ta == IRT_FALSE || ta == IRT_TRUE) &&
×
2148
                     (tc == IRT_FALSE || tc == IRT_TRUE))) {
×
2149
          break;  /* Interpreter will throw for two different types. */
2150
        }
2151
      }
2152
      rec_comp_prep(J);
1,162✔
2153
      irop = (int)op - (int)BC_ISLT + (int)IR_LT;
1,162✔
2154
      if (ta == IRT_NUM) {
1,162✔
2155
        if ((irop & 1)) irop ^= 4;  /* ISGE/ISGT are unordered. */
1,066✔
2156
        if (!lj_ir_numcmp(numberVnum(rav), numberVnum(rcv), (IROp)irop))
1,066✔
2157
          irop ^= 5;
835✔
2158
      } else if (ta == IRT_INT) {
96✔
2159
        if (!lj_ir_numcmp(numberVnum(rav), numberVnum(rcv), (IROp)irop))
46✔
2160
          irop ^= 1;
5✔
2161
      } else if (ta == IRT_STR) {
50✔
2162
        if (!lj_ir_strcmp(strV(rav), strV(rcv), (IROp)irop)) irop ^= 1;
1✔
2163
        ra = lj_ir_call(J, IRCALL_lj_str_cmp, ra, rc);
1✔
2164
        rc = lj_ir_kint(J, 0);
1✔
2165
        ta = IRT_INT;
1✔
2166
      } else {
2167
        rec_mm_comp(J, &ix, (int)op);
49✔
2168
        break;
49✔
2169
      }
2170
      emitir(IRTG(irop, ta), ra, rc);
1,113✔
2171
      rec_comp_fixup(J, J->pc, ((int)op ^ irop) & 1);
1,113✔
2172
    }
2173
    break;
2174

2175
  case BC_ISEQV: case BC_ISNEV:
2,547✔
2176
  case BC_ISEQS: case BC_ISNES:
2177
  case BC_ISEQN: case BC_ISNEN:
2178
  case BC_ISEQP: case BC_ISNEP:
2179
#if LJ_HASFFI
2180
    if (tref_iscdata(ra) || tref_iscdata(rc)) {
2,547✔
2181
      rec_mm_comp_cdata(J, &ix, op, MM_eq);
28✔
2182
      break;
28✔
2183
    }
2184
#endif
2185
    /* Emit nothing for two non-table, non-udata consts. */
2186
    if (!(tref_isk2(ra, rc) && !(tref_istab(ra) || tref_isudata(ra)))) {
2,519✔
2187
      int diff;
2,008✔
2188
      rec_comp_prep(J);
2,008✔
2189
      diff = lj_record_objcmp(J, ra, rc, rav, rcv);
2,008✔
2190
      if (diff == 2 || !(tref_istab(ra) || tref_isudata(ra)))
2,008✔
2191
        rec_comp_fixup(J, J->pc, ((int)op & 1) == !diff);
1,956✔
2192
      else if (diff == 1)  /* Only check __eq if different, but same type. */
52✔
2193
        rec_mm_equal(J, &ix, (int)op);
10✔
2194
    }
2195
    break;
2196

2197
  /* -- Unary test and copy ops ------------------------------------------- */
2198

2199
  case BC_ISTC: case BC_ISFC:
169✔
2200
    if ((op & 1) == tref_istruecond(rc))
169✔
2201
      rc = 0;  /* Don't store if condition is not true. */
148✔
2202
    /* fallthrough */
2203
  case BC_IST: case BC_ISF:  /* Type specialization suffices. */
2204
    if (bc_a(pc[1]) < J->maxslot)
527✔
2205
      J->maxslot = bc_a(pc[1]);  /* Shrink used slots. */
95✔
2206
    break;
2207

2208
  case BC_ISTYPE: case BC_ISNUM:
2209
    /* These coercions need to correspond with lj_meta_istype(). */
2210
    if (LJ_DUALNUM && rc == ~LJ_TNUMX+1)
12✔
2211
      ra = lj_opt_narrow_toint(J, ra);
2212
    else if (rc == ~LJ_TNUMX+2)
12✔
2213
      ra = lj_ir_tonum(J, ra);
2✔
2214
    else if (rc == ~LJ_TSTR+1)
10✔
2215
      ra = lj_ir_tostr(J, ra);
6✔
2216
    /* else: type specialization suffices. */
2217
    J->base[bc_a(ins)] = ra;
12✔
2218
    break;
12✔
2219

2220
  /* -- Unary ops --------------------------------------------------------- */
2221

2222
  case BC_NOT:
6✔
2223
    /* Type specialization already forces const result. */
2224
    rc = tref_istruecond(rc) ? TREF_FALSE : TREF_TRUE;
6✔
2225
    break;
2226

2227
  case BC_LEN:
48✔
2228
    if (tref_isstr(rc))
48✔
2229
      rc = emitir(IRTI(IR_FLOAD), rc, IRFL_STR_LEN);
7✔
2230
    else if (!LJ_52 && tref_istab(rc))
41✔
2231
      rc = lj_ir_call(J, IRCALL_lj_tab_len, rc);
40✔
2232
    else
2233
      rc = rec_mm_len(J, rc, rcv);
1✔
2234
    break;
2235

2236
  /* -- Arithmetic ops ---------------------------------------------------- */
2237

2238
  case BC_UNM:
12✔
2239
    if (tref_isnumber_str(rc)) {
12✔
2240
      rc = lj_opt_narrow_unm(J, rc, rcv);
11✔
2241
    } else {
2242
      ix.tab = rc;
1✔
2243
      copyTV(J->L, &ix.tabv, rcv);
1✔
2244
      rc = rec_mm_arith(J, &ix, MM_unm);
1✔
2245
    }
2246
    break;
2247

2248
  case BC_ADDNV: case BC_SUBNV: case BC_MULNV: case BC_DIVNV: case BC_MODNV:
551✔
2249
    /* Swap rb/rc and rbv/rcv. rav is temp. */
2250
    ix.tab = rc; ix.key = rc = rb; rb = ix.tab;
551✔
2251
    copyTV(J->L, rav, rbv);
551✔
2252
    copyTV(J->L, rbv, rcv);
551✔
2253
    copyTV(J->L, rcv, rav);
551✔
2254
    if (op == BC_MODNV)
551✔
2255
      goto recmod;
1✔
2256
    /* fallthrough */
2257
  case BC_ADDVN: case BC_SUBVN: case BC_MULVN: case BC_DIVVN:
2258
  case BC_ADDVV: case BC_SUBVV: case BC_MULVV: case BC_DIVVV: {
2259
    MMS mm = bcmode_mm(op);
47,969✔
2260
    if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
47,969✔
2261
      rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv,
47,875✔
2262
                               (int)mm - (int)MM_add + (int)IR_ADD);
47,875✔
2263
    else
2264
      rc = rec_mm_arith(J, &ix, mm);
94✔
2265
    break;
2266
    }
2267

2268
  case BC_MODVN: case BC_MODVV:
2269
  recmod:
62✔
2270
    if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
62✔
2271
      rc = lj_opt_narrow_mod(J, rb, rc, rbv, rcv);
59✔
2272
    else
2273
      rc = rec_mm_arith(J, &ix, MM_mod);
3✔
2274
    break;
2275

2276
  case BC_POW:
240✔
2277
    if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
240✔
2278
      rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv, IR_POW);
237✔
2279
    else
2280
      rc = rec_mm_arith(J, &ix, MM_pow);
3✔
2281
    break;
2282

2283
  /* -- Miscellaneous ops ------------------------------------------------- */
2284

2285
  case BC_CAT:
258✔
2286
    rc = rec_cat(J, rb, rc);
258✔
2287
    break;
258✔
2288

2289
  /* -- Constant and move ops --------------------------------------------- */
2290

2291
  case BC_MOV:
5,676✔
2292
    /* Clear gap of method call to avoid resurrecting previous refs. */
2293
    if (ra > J->maxslot) {
5,676✔
2294
#if LJ_FR2
2295
      memset(J->base + J->maxslot, 0, (ra - J->maxslot) * sizeof(TRef));
2,420✔
2296
#else
2297
      J->base[ra-1] = 0;
2298
#endif
2299
    }
2300
    break;
2301
  case BC_KSTR: case BC_KNUM: case BC_KPRI:
2302
    break;
2303
  case BC_KSHORT:
3,544✔
2304
    rc = lj_ir_kint(J, (int32_t)(int16_t)rc);
3,544✔
2305
    break;
3,544✔
2306
  case BC_KNIL:
11✔
2307
    if (LJ_FR2 && ra > J->maxslot)
11✔
2308
      J->base[ra-1] = 0;
1✔
2309
    while (ra <= rc)
613✔
2310
      J->base[ra++] = TREF_NIL;
602✔
2311
    if (rc >= J->maxslot) J->maxslot = rc+1;
11✔
2312
    break;
2313
#if LJ_HASFFI
2314
  case BC_KCDATA:
37✔
2315
    rc = lj_ir_kgc(J, proto_kgc(J->pt, ~(ptrdiff_t)rc), IRT_CDATA);
37✔
2316
    break;
37✔
2317
#endif
2318

2319
  /* -- Upvalue and function ops ------------------------------------------ */
2320

2321
  case BC_UGET:
5,315✔
2322
    rc = rec_upvalue(J, rc, 0);
5,315✔
2323
    break;
5,315✔
2324
  case BC_USETV: case BC_USETS: case BC_USETN: case BC_USETP:
172✔
2325
    rec_upvalue(J, ra, rc);
172✔
2326
    break;
172✔
2327

2328
  /* -- Table ops --------------------------------------------------------- */
2329

2330
  case BC_GGET: case BC_GSET:
2,324✔
2331
    settabV(J->L, &ix.tabv, tabref(J->fn->l.env));
2,324✔
2332
    ix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), getcurrf(J), IRFL_FUNC_ENV);
2,324✔
2333
    ix.idxchain = LJ_MAX_IDXCHAIN;
2,324✔
2334
    rc = lj_record_idx(J, &ix);
2,324✔
2335
    break;
2,324✔
2336

2337
  case BC_TGETB: case BC_TSETB:
457✔
2338
    setintV(&ix.keyv, (int32_t)rc);
457✔
2339
    ix.key = lj_ir_kint(J, (int32_t)rc);
457✔
2340
    /* fallthrough */
2341
  case BC_TGETV: case BC_TGETS: case BC_TSETV: case BC_TSETS:
99,012✔
2342
    ix.idxchain = LJ_MAX_IDXCHAIN;
99,012✔
2343
    rc = lj_record_idx(J, &ix);
99,012✔
2344
    break;
99,012✔
2345
  case BC_TGETR: case BC_TSETR:
22✔
2346
    ix.idxchain = 0;
22✔
2347
    rc = lj_record_idx(J, &ix);
22✔
2348
    break;
22✔
2349

2350
  case BC_TSETM:
4✔
2351
    rec_tsetm(J, ra, (BCReg)(J->L->top - J->L->base), (int32_t)rcv->u32.lo);
4✔
2352
    J->maxslot = ra;  /* The table slot at ra-1 is the highest used slot. */
4✔
2353
    break;
4✔
2354

2355
  case BC_TNEW:
2356
    rc = rec_tnew(J, rc);
404✔
2357
    break;
404✔
2358
  case BC_TDUP:
52✔
2359
    rc = emitir(IRTG(IR_TDUP, IRT_TAB),
52✔
2360
                lj_ir_ktab(J, gco2tab(proto_kgc(J->pt, ~(ptrdiff_t)rc))), 0);
2361
#ifdef LUAJIT_ENABLE_TABLE_BUMP
2362
    J->rbchash[(rc & (RBCHASH_SLOTS-1))].ref = tref_ref(rc);
2363
    setmref(J->rbchash[(rc & (RBCHASH_SLOTS-1))].pc, pc);
2364
    setgcref(J->rbchash[(rc & (RBCHASH_SLOTS-1))].pt, obj2gco(J->pt));
2365
#endif
2366
    break;
52✔
2367

2368
  /* -- Calls and vararg handling ----------------------------------------- */
2369

2370
  case BC_ITERC:
106✔
2371
    J->base[ra] = getslot(J, ra-3);
106✔
2372
    J->base[ra+1+LJ_FR2] = getslot(J, ra-2);
106✔
2373
    J->base[ra+2+LJ_FR2] = getslot(J, ra-1);
106✔
2374
    { /* Do the actual copy now because lj_record_call needs the values. */
2375
      TValue *b = &J->L->base[ra];
106✔
2376
      copyTV(J->L, b, b-3);
106✔
2377
      copyTV(J->L, b+1+LJ_FR2, b-2);
106✔
2378
      copyTV(J->L, b+2+LJ_FR2, b-1);
106✔
2379
    }
2380
    lj_record_call(J, ra, (ptrdiff_t)rc-1);
106✔
2381
    break;
106✔
2382

2383
  /* L->top is set to L->base+ra+rc+NARGS-1+1. See lj_dispatch_ins(). */
2384
  case BC_CALLM:
667✔
2385
    rc = (BCReg)(J->L->top - J->L->base) - ra - LJ_FR2;
667✔
2386
    /* fallthrough */
2387
  case BC_CALL:
6,417✔
2388
    lj_record_call(J, ra, (ptrdiff_t)rc-1);
6,417✔
2389
    break;
6,417✔
2390

2391
  case BC_CALLMT:
5✔
2392
    rc = (BCReg)(J->L->top - J->L->base) - ra - LJ_FR2;
5✔
2393
    /* fallthrough */
2394
  case BC_CALLT:
670✔
2395
    lj_record_tailcall(J, ra, (ptrdiff_t)rc-1);
670✔
2396
    break;
670✔
2397

2398
  case BC_VARG:
38✔
2399
    rec_varg(J, ra, (ptrdiff_t)rb-1);
38✔
2400
    break;
38✔
2401

2402
  /* -- Returns ----------------------------------------------------------- */
2403

2404
  case BC_RETM:
12✔
2405
    /* L->top is set to L->base+ra+rc+NRESULTS-1, see lj_dispatch_ins(). */
2406
    rc = (BCReg)(J->L->top - J->L->base) - ra + 1;
12✔
2407
    /* fallthrough */
2408
  case BC_RET: case BC_RET0: case BC_RET1:
4,032✔
2409
#if LJ_HASPROFILE
2410
    rec_profile_ret(J);
4,032✔
2411
#endif
2412
    lj_record_ret(J, ra, (ptrdiff_t)rc-1);
4,032✔
2413
    break;
4,032✔
2414

2415
  /* -- Loops and branches ------------------------------------------------ */
2416

2417
  case BC_FORI:
154✔
2418
    if (rec_for(J, pc, 0) != LOOPEV_LEAVE)
154✔
2419
      J->loopref = J->cur.nins;
154✔
2420
    break;
2421
  case BC_JFORI:
70✔
2422
    lj_assertJ(bc_op(pc[(ptrdiff_t)rc-BCBIAS_J]) == BC_JFORL,
70✔
2423
               "JFORI does not point to JFORL");
2424
    if (rec_for(J, pc, 0) != LOOPEV_LEAVE)  /* Link to existing loop. */
70✔
2425
      lj_record_stop(J, LJ_TRLINK_ROOT, bc_d(pc[(ptrdiff_t)rc-BCBIAS_J]));
67✔
2426
    /* Continue tracing if the loop is not entered. */
2427
    break;
2428

2429
  case BC_FORL:
2,039✔
2430
    rec_loop_interp(J, pc, rec_for(J, pc+((ptrdiff_t)rc-BCBIAS_J), 1));
2,039✔
2431
    break;
2,039✔
2432
  case BC_ITERL:
41✔
2433
    rec_loop_interp(J, pc, rec_iterl(J, *pc));
41✔
2434
    break;
41✔
2435
  case BC_LOOP:
60✔
2436
    rec_loop_interp(J, pc, rec_loop(J, ra));
60✔
2437
    break;
60✔
2438

2439
  case BC_JFORL:
323✔
2440
    rec_loop_jit(J, rc, rec_for(J, pc+bc_j(traceref(J, rc)->startins), 1));
323✔
2441
    break;
323✔
2442
  case BC_JITERL:
64✔
2443
    rec_loop_jit(J, rc, rec_iterl(J, traceref(J, rc)->startins));
64✔
2444
    break;
64✔
2445
  case BC_JLOOP:
329✔
2446
    rec_loop_jit(J, rc, rec_loop(J, ra));
329✔
2447
    break;
329✔
2448

2449
  case BC_IFORL:
×
2450
  case BC_IITERL:
2451
  case BC_ILOOP:
2452
  case BC_IFUNCF:
2453
  case BC_IFUNCV:
2454
    lj_trace_err(J, LJ_TRERR_BLACKL);
×
2455
    break;
988✔
2456

2457
  case BC_JMP:
988✔
2458
    if (ra < J->maxslot)
988✔
2459
      J->maxslot = ra;  /* Shrink used slots. */
472✔
2460
    break;
2461

2462
  /* -- Function headers -------------------------------------------------- */
2463

2464
  case BC_FUNCF:
2465
    rec_func_lua(J);
792✔
2466
    break;
2467
  case BC_JFUNCF:
3,243✔
2468
    rec_func_jit(J, rc);
3,243✔
2469
    break;
3,243✔
2470

2471
  case BC_FUNCV:
100✔
2472
    rec_func_vararg(J);
100✔
2473
    rec_func_lua(J);
100✔
2474
    break;
2475
  case BC_JFUNCV:
2476
    /* Cannot happen. No hotcall counting for varag funcs. */
2477
    lj_assertJ(0, "unsupported vararg hotcall");
2478
    break;
2479

2480
  case BC_FUNCC:
1,262✔
2481
  case BC_FUNCCW:
2482
    lj_ffrecord_func(J);
1,262✔
2483
    break;
1,262✔
2484

2485
  default:
2,386✔
2486
    if (op >= BC__MAX) {
2,386✔
2487
      lj_ffrecord_func(J);
2,386✔
2488
      break;
2,386✔
2489
    }
2490
    /* fallthrough */
2491
  case BC_ITERN:
2492
  case BC_ISNEXT:
2493
  case BC_UCLO:
2494
  case BC_FNEW:
2495
    setintV(&J->errinfo, (int32_t)op);
48✔
2496
    lj_trace_err_info(J, LJ_TRERR_NYIBC);
48✔
2497
    break;
194,464✔
2498
  }
2499

2500
  /* rc == 0 if we have no result yet, e.g. pending __index metamethod call. */
2501
  if (bcmode_a(op) == BCMdst && rc) {
194,464✔
2502
    J->base[ra] = rc;
117,895✔
2503
    if (ra >= J->maxslot) {
117,895✔
2504
#if LJ_FR2
2505
      if (ra > J->maxslot) J->base[ra-1] = 0;
21,993✔
2506
#endif
2507
      J->maxslot = ra+1;
21,993✔
2508
    }
2509
  }
2510

2511
#undef rav
2512
#undef rbv
2513
#undef rcv
2514

2515
  /* Limit the number of recorded IR instructions and constants. */
2516
  if (J->cur.nins > REF_FIRST+(IRRef)J->param[JIT_P_maxrecord] ||
194,464✔
2517
      J->cur.nk < REF_BIAS-(IRRef)J->param[JIT_P_maxirconst])
194,464✔
2518
    lj_trace_err(J, LJ_TRERR_TRACEOV);
1✔
2519
}
2520

2521
/* -- Recording setup ----------------------------------------------------- */
2522

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

2579
/* Setup for recording a new trace. */
2580
void lj_record_setup(jit_State *J)
5,473✔
2581
{
2582
  uint32_t i;
5,473✔
2583

2584
  /* Initialize state related to current trace. */
2585
  memset(J->slot, 0, sizeof(J->slot));
5,473✔
2586
  memset(J->chain, 0, sizeof(J->chain));
5,473✔
2587
#ifdef LUAJIT_ENABLE_TABLE_BUMP
2588
  memset(J->rbchash, 0, sizeof(J->rbchash));
2589
#endif
2590
  memset(J->bpropcache, 0, sizeof(J->bpropcache));
5,473✔
2591
  J->scev.idx = REF_NIL;
5,473✔
2592
  setmref(J->scev.pc, NULL);
5,473✔
2593

2594
  J->baseslot = 1+LJ_FR2;  /* Invoking function is at base[-1-LJ_FR2]. */
5,473✔
2595
  J->base = J->slot + J->baseslot;
5,473✔
2596
  J->maxslot = 0;
5,473✔
2597
  J->framedepth = 0;
5,473✔
2598
  J->retdepth = 0;
5,473✔
2599

2600
  J->instunroll = J->param[JIT_P_instunroll];
5,473✔
2601
  J->loopunroll = J->param[JIT_P_loopunroll];
5,473✔
2602
  J->tailcalled = 0;
5,473✔
2603
  J->loopref = 0;
5,473✔
2604

2605
  J->bc_min = NULL;  /* Means no limit. */
5,473✔
2606
  J->bc_extent = ~(MSize)0;
5,473✔
2607

2608
  /* Emit instructions for fixed references. Also triggers initial IR alloc. */
2609
  emitir_raw(IRT(IR_BASE, IRT_PGC), J->parent, J->exitno);
5,473✔
2610
  for (i = 0; i <= 2; i++) {
27,365✔
2611
    IRIns *ir = IR(REF_NIL-i);
16,419✔
2612
    ir->i = 0;
16,419✔
2613
    ir->t.irt = (uint8_t)(IRT_NIL+i);
16,419✔
2614
    ir->o = IR_KPRI;
16,419✔
2615
    ir->prev = 0;
16,419✔
2616
  }
2617
  J->cur.nk = REF_TRUE;
5,473✔
2618

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

2687
#undef IR
2688
#undef emitir_raw
2689
#undef emitir
2690

2691
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc