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

tarantool / luajit / 12412391679

19 Dec 2024 12:05PM UTC coverage: 92.962% (+0.04%) from 92.921%
12412391679

push

github

Buristan
test: fix flaky fix-slots-overflow-for-varg-record

The aforementioned test is flaky when it is run by Tarantool, since the
necessary trace isn't compiled due to hotcount collisions. This patch
fixes this by adding the additional reset of hot counters.

5695 of 6033 branches covered (94.4%)

Branch coverage included in aggregate %.

21712 of 23449 relevant lines covered (92.59%)

2992781.39 hits per line

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

96.34
/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)
143,971✔
188
{
189
  /* Caller may set IRT_GUARD in t. */
190
  TRef ref = emitir_raw(IRT(IR_SLOAD, t), (int32_t)J->baseslot+slot, mode);
287,942✔
191
  J->base[slot] = ref;
143,971✔
192
  return ref;
143,971✔
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)
312,687✔
197
{
198
  IRType t = itype2irt(&J->L->base[slot]);
312,687✔
199
  TRef ref = emitir_raw(IRTG(IR_SLOAD, t), (int32_t)J->baseslot+slot,
312,687✔
200
                        IRSLOAD_TYPECHECK);
201
  if (irtype_ispri(t)) ref = TREF_PRI(t);  /* Canonicalize primitive refs. */
312,687✔
202
  J->base[slot] = ref;
312,687✔
203
  return ref;
312,687✔
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)
1,253,406✔
211
{
212
  if (J->base[-1-LJ_FR2])
1,253,406✔
213
    return J->base[-1-LJ_FR2];
214
  /* Non-base frame functions ought to be loaded already. */
215
  lj_assertJ(J->baseslot == 1+LJ_FR2, "bad baseslot");
140,889✔
216
  return sloadt(J, -1-LJ_FR2, IRT_FUNC, IRSLOAD_READONLY);
140,889✔
217
}
218

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

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

262
/* -- Record loop ops ----------------------------------------------------- */
263

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

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

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

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

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

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

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

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

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

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

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

534
  ev = rec_for_iter(&op, tv, isforl);
3,160✔
535
  if (ev == LOOPEV_LEAVE) {
3,160✔
536
    J->maxslot = ra+FORL_EXT+1;
60✔
537
    J->pc = fori+1;
60✔
538
  } else {
539
    J->maxslot = ra;
3,100✔
540
    J->pc = fori+bc_j(*fori)+1;
3,100✔
541
  }
542
  lj_snap_add(J);
3,160✔
543

544
  emitir(IRTG(op, t), tr[FORL_IDX], stop);
3,160✔
545

546
  if (ev == LOOPEV_LEAVE) {
3,160✔
547
    J->maxslot = ra;
60✔
548
    J->pc = fori+bc_j(*fori)+1;
60✔
549
  } else {
550
    J->maxslot = ra+FORL_EXT+1;
3,100✔
551
    J->pc = fori+1;
3,100✔
552
  }
553
  J->needsnap = 1;
3,160✔
554
  return ev;
3,160✔
555
}
556

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

573
/* Record LOOP/JLOOP. Now, that was easy. */
574
static LoopEvent rec_loop(jit_State *J, BCReg ra, int skip)
35,128✔
575
{
576
  if (ra < J->maxslot) J->maxslot = ra;
20,372✔
577
  J->pc += skip;
35,128✔
578
  return LOOPEV_ENTER;
35,128✔
579
}
580

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

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

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

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

643
#if LJ_HASPROFILE
644

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

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

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

686
#endif
687

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

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

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

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

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

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

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

817
/* Record return. */
818
void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
1,322,649✔
819
{
820
  TValue *frame = J->L->base - 1;
1,322,649✔
821
  ptrdiff_t i;
1,322,649✔
822
  BCReg baseadj = 0;
1,322,649✔
823
  for (i = 0; i < gotresults; i++)
2,522,063✔
824
    (void)getslot(J, rbase+i);  /* Ensure all results have a reference. */
1,199,414✔
825
  while (frame_ispcall(frame)) {  /* Immediately resolve pcall() returns. */
1,322,681✔
826
    BCReg cbase = (BCReg)frame_delta(frame);
59✔
827
    if (--J->framedepth <= 0)
59✔
828
      lj_trace_err(J, LJ_TRERR_NYIRETL);
27✔
829
    lj_assertJ(J->baseslot > 1+LJ_FR2, "bad baseslot for return");
32✔
830
    gotresults++;
32✔
831
    baseadj += cbase;
32✔
832
    rbase += cbase;
32✔
833
    J->baseslot -= (BCReg)cbase;
32✔
834
    J->base -= cbase;
32✔
835
    J->base[--rbase] = TREF_TRUE;  /* Prepend true to results. */
32✔
836
    frame = frame_prevd(frame);
32✔
837
    J->needsnap = 1;  /* Stop catching on-trace errors. */
32✔
838
  }
839
  /* Return to lower frame via interpreter for unhandled cases. */
840
  if (J->framedepth == 0 && J->pt && bc_isret(bc_op(*J->pc)) &&
1,322,622✔
841
       (!frame_islua(frame) ||
149,893✔
842
        (J->parent == 0 && J->exitno == 0 &&
149,839✔
843
         !bc_isret(bc_op(J->cur.startins))))) {
1,145✔
844
    /* NYI: specialize to frame type and return directly, not via RET*. */
845
    for (i = 0; i < (ptrdiff_t)rbase; i++)
2,770✔
846
      J->base[i] = 0;  /* Purge dead slots. */
1,572✔
847
    J->maxslot = rbase + (BCReg)gotresults;
1,198✔
848
    lj_record_stop(J, LJ_TRLINK_RETURN, 0);  /* Return to interpreter. */
1,198✔
849
    return;
1,198✔
850
  }
851
  if (frame_isvarg(frame)) {
1,321,424✔
852
    BCReg cbase = (BCReg)frame_delta(frame);
27✔
853
    if (--J->framedepth < 0)  /* NYI: return of vararg func to lower frame. */
27✔
854
      lj_trace_err(J, LJ_TRERR_NYIRETL);
×
855
    lj_assertJ(J->baseslot > 1+LJ_FR2, "bad baseslot for return");
27✔
856
    baseadj += cbase;
27✔
857
    rbase += cbase;
27✔
858
    J->baseslot -= (BCReg)cbase;
27✔
859
    J->base -= cbase;
27✔
860
    frame = frame_prevd(frame);
27✔
861
  }
862
  if (frame_islua(frame)) {  /* Return to Lua frame. */
1,321,424✔
863
    BCIns callins = *(frame_pc(frame)-1);
1,207,704✔
864
    ptrdiff_t nresults = bc_b(callins) ? (ptrdiff_t)bc_b(callins)-1 :gotresults;
1,207,704✔
865
    BCReg cbase = bc_a(callins);
1,207,704✔
866
    GCproto *pt = funcproto(frame_func(frame - (cbase+1+LJ_FR2)));
1,207,704✔
867
    if ((pt->flags & PROTO_NOJIT))
1,207,704✔
868
      lj_trace_err(J, LJ_TRERR_CJITOFF);
×
869
    if (J->framedepth == 0 && J->pt && frame == J->L->base - 1) {
1,207,704✔
870
      if (!J->cur.root && check_downrec_unroll(J, pt)) {
148,695✔
871
        J->maxslot = (BCReg)(rbase + gotresults);
×
872
        lj_snap_purge(J);
×
873
        lj_record_stop(J, LJ_TRLINK_DOWNREC, J->cur.traceno);  /* Down-rec. */
×
874
        return;
×
875
      }
876
      lj_snap_add(J);
148,694✔
877
    }
878
    for (i = 0; i < nresults; i++)  /* Adjust results. */
2,243,326✔
879
      J->base[i-1-LJ_FR2] = i < gotresults ? J->base[rbase+i] : TREF_NIL;
1,035,623✔
880
    J->maxslot = cbase+(BCReg)nresults;
1,207,703✔
881
    if (J->framedepth > 0) {  /* Return to a frame that is part of the trace. */
1,207,703✔
882
      J->framedepth--;
1,058,479✔
883
      lj_assertJ(J->baseslot > cbase+1+LJ_FR2, "bad baseslot for return");
1,058,479✔
884
      J->baseslot -= cbase+1+LJ_FR2;
1,058,479✔
885
      J->base -= cbase+1+LJ_FR2;
1,058,479✔
886
    } else if (J->parent == 0 && J->exitno == 0 &&
149,224✔
887
               !bc_isret(bc_op(J->cur.startins))) {
16✔
888
      /* Return to lower frame would leave the loop in a root trace. */
889
      lj_trace_err(J, LJ_TRERR_LLEAVE);
15✔
890
    } else if (J->needsnap) {  /* Tailcalled to ff with side-effects. */
149,209✔
891
      lj_trace_err(J, LJ_TRERR_NYIRETL);  /* No way to insert snapshot here. */
×
892
    } else if (1 + pt->framesize >= LJ_MAX_JSLOTS) {
149,209✔
893
      lj_trace_err(J, LJ_TRERR_STACKOV);
1✔
894
    } else {  /* Return to lower frame. Guard for the target we return to. */
895
      TRef trpt = lj_ir_kgc(J, obj2gco(pt), IRT_PROTO);
149,208✔
896
      TRef trpc = lj_ir_kptr(J, (void *)frame_pc(frame));
149,208✔
897
      emitir(IRTG(IR_RETF, IRT_PGC), trpt, trpc);
149,208✔
898
      J->retdepth++;
149,208✔
899
      J->needsnap = 1;
149,208✔
900
      lj_assertJ(J->baseslot == 1+LJ_FR2, "bad baseslot for return");
149,208✔
901
      /* Shift result slots up and clear the slots of the new frame below. */
902
      memmove(J->base + cbase, J->base-1-LJ_FR2, sizeof(TRef)*nresults);
149,208✔
903
      memset(J->base-1-LJ_FR2, 0, sizeof(TRef)*(cbase+1+LJ_FR2));
149,208✔
904
    }
905
  } else if (frame_iscont(frame)) {  /* Return to continuation frame. */
113,720✔
906
    ASMFunction cont = frame_contf(frame);
113,720✔
907
    BCReg cbase = (BCReg)frame_delta(frame);
113,720✔
908
    if ((J->framedepth -= 2) < 0)
113,720✔
909
      lj_trace_err(J, LJ_TRERR_NYIRETL);
5✔
910
    J->baseslot -= (BCReg)cbase;
113,715✔
911
    J->base -= cbase;
113,715✔
912
    J->maxslot = cbase-(2<<LJ_FR2);
113,715✔
913
    if (cont == lj_cont_ra) {
113,715✔
914
      /* Copy result to destination slot. */
915
      BCReg dst = bc_a(*(frame_contpc(frame)-1));
77,145✔
916
      J->base[dst] = gotresults ? J->base[cbase+rbase] : TREF_NIL;
77,145✔
917
      if (dst >= J->maxslot) {
77,145✔
918
        J->maxslot = dst+1;
×
919
      }
920
    } else if (cont == lj_cont_nop) {
36,570✔
921
      /* Nothing to do here. */
922
    } else if (cont == lj_cont_cat) {
36,422✔
923
      BCReg bslot = bc_b(*(frame_contpc(frame)-1));
12✔
924
      TRef tr = gotresults ? J->base[cbase+rbase] : TREF_NIL;
12✔
925
      if (bslot != J->maxslot) {  /* Concatenate the remainder. */
12✔
926
        /* Simulate lower frame and result. */
927
        TValue *b = J->L->base - baseadj, save;
6✔
928
        /* Can't handle MM_concat + CALLT + fast func side-effects. */
929
        if (J->postproc != LJ_POST_NONE)
6✔
930
          lj_trace_err(J, LJ_TRERR_NYIRETL);
1✔
931
        J->base[J->maxslot] = tr;
5✔
932
        copyTV(J->L, &save, b-(2<<LJ_FR2));
5✔
933
        if (gotresults)
5✔
934
          copyTV(J->L, b-(2<<LJ_FR2), b+rbase);
5✔
935
        else
936
          setnilV(b-(2<<LJ_FR2));
×
937
        J->L->base = b - cbase;
5✔
938
        tr = rec_cat(J, bslot, cbase-(2<<LJ_FR2));
5✔
939
        b = J->L->base + cbase;  /* Undo. */
5✔
940
        J->L->base = b + baseadj;
5✔
941
        copyTV(J->L, b-(2<<LJ_FR2), &save);
5✔
942
      }
943
      if (tr >= 0xffffff00) {
11✔
944
        lj_err_throw(J->L, -(int32_t)tr);  /* Propagate errors. */
1✔
945
      } else if (tr) {  /* Store final result. */
10✔
946
        BCReg dst = bc_a(*(frame_contpc(frame)-1));
6✔
947
        J->base[dst] = tr;
6✔
948
        if (dst >= J->maxslot) {
6✔
949
          J->maxslot = dst+1;
×
950
        }
951
      }  /* Otherwise continue with another __concat call. */
952
    } else {
953
      /* Result type already specialized. */
954
      lj_assertJ(cont == lj_cont_condf || cont == lj_cont_condt,
955
                 "bad continuation type");
956
    }
957
  } else {
958
    lj_trace_err(J, LJ_TRERR_NYIRETL);  /* NYI: handle return to C frame. */
×
959
  }
960
  lj_assertJ(J->baseslot >= 1+LJ_FR2, "bad baseslot for return");
1,322,598✔
961
}
962

963
/* -- Metamethod handling ------------------------------------------------- */
964

965
/* Prepare to record call to metamethod. */
966
static BCReg rec_mm_prep(jit_State *J, ASMFunction cont)
113,725✔
967
{
968
  BCReg s, top = cont == lj_cont_cat ? J->maxslot : curr_proto(J->L)->framesize;
113,725✔
969
#if LJ_FR2
970
  J->base[top] = lj_ir_k64(J, IR_KNUM, u64ptr(contptr(cont)));
113,725✔
971
  J->base[top+1] = TREF_CONT;
113,725✔
972
#else
973
  J->base[top] = lj_ir_kptr(J, contptr(cont)) | TREF_CONT;
974
#endif
975
  J->framedepth++;
113,725✔
976
  for (s = J->maxslot; s < top; s++)
527,741✔
977
    J->base[s] = 0;  /* Clear frame gap to avoid resurrecting previous refs. */
414,016✔
978
  return top+1+LJ_FR2;
113,725✔
979
}
980

981
/* Record metamethod lookup. */
982
int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm)
200,904✔
983
{
984
  RecordIndex mix;
200,904✔
985
  GCtab *mt;
200,904✔
986
  if (tref_istab(ix->tab)) {
200,904✔
987
    mt = tabref(tabV(&ix->tabv)->metatable);
73,320✔
988
    mix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_TAB_META);
73,320✔
989
  } else if (tref_isudata(ix->tab)) {
127,584✔
990
    int udtype = udataV(&ix->tabv)->udtype;
13,515✔
991
    mt = tabref(udataV(&ix->tabv)->metatable);
13,515✔
992
    /* The metatables of special userdata objects are treated as immutable. */
993
    if (udtype != UDTYPE_USERDATA) {
13,515✔
994
      cTValue *mo;
13,510✔
995
      if (LJ_HASFFI && udtype == UDTYPE_FFI_CLIB) {
13,510✔
996
        /* Specialize to the C library namespace object. */
997
        emitir(IRTG(IR_EQ, IRT_PGC), ix->tab, lj_ir_kptr(J, udataV(&ix->tabv)));
13,510✔
998
      } else {
999
        /* Specialize to the type of userdata. */
1000
        TRef tr = emitir(IRT(IR_FLOAD, IRT_U8), ix->tab, IRFL_UDATA_UDTYPE);
×
1001
        emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, udtype));
×
1002
      }
1003
  immutable_mt:
127,180✔
1004
      mo = lj_tab_getstr(mt, mmname_str(J2G(J), mm));
127,180✔
1005
      if (!mo || tvisnil(mo))
127,180✔
1006
        return 0;  /* No metamethod. */
1007
      /* Treat metamethod or index table as immutable, too. */
1008
      if (!(tvisfunc(mo) || tvistab(mo)))
127,180✔
1009
        lj_trace_err(J, LJ_TRERR_BADTYPE);
×
1010
      copyTV(J->L, &ix->mobjv, mo);
127,180✔
1011
      ix->mobj = lj_ir_kgc(J, gcV(mo), tvisfunc(mo) ? IRT_FUNC : IRT_TAB);
127,180✔
1012
      ix->mtv = mt;
127,180✔
1013
      ix->mt = TREF_NIL;  /* Dummy value for comparison semantics. */
127,180✔
1014
      return 1;  /* Got metamethod or index table. */
127,180✔
1015
    }
1016
    mix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_UDATA_META);
5✔
1017
  } else {
1018
    /* Specialize to base metatable. Must flush mcode in lua_setmetatable(). */
1019
    mt = tabref(basemt_obj(J2G(J), &ix->tabv));
114,069✔
1020
    if (mt == NULL) {
114,069✔
1021
      ix->mt = TREF_NIL;
158✔
1022
      return 0;  /* No metamethod. */
158✔
1023
    }
1024
    /* The cdata metatable is treated as immutable. */
1025
    if (LJ_HASFFI && tref_iscdata(ix->tab)) goto immutable_mt;
113,911✔
1026
#if LJ_GC64
1027
    /* TODO: fix ARM32 asm_fload(), so we can use this for all archs. */
1028
    ix->mt = mix.tab = lj_ir_ggfload(J, IRT_TAB,
478✔
1029
      GG_OFS(g.gcroot[GCROOT_BASEMT+itypemap(&ix->tabv)]));
237✔
1030
#else
1031
    ix->mt = mix.tab = lj_ir_ktab(J, mt);
1032
#endif
1033
    goto nocheck;
241✔
1034
  }
1035
  ix->mt = mt ? mix.tab : TREF_NIL;
73,325✔
1036
  emitir(IRTG(mt ? IR_NE : IR_EQ, IRT_TAB), mix.tab, lj_ir_knull(J, IRT_TAB));
105,383✔
1037
nocheck:
73,566✔
1038
  if (mt) {
73,566✔
1039
    GCstr *mmstr = mmname_str(J2G(J), mm);
41,508✔
1040
    cTValue *mo = lj_tab_getstr(mt, mmstr);
41,508✔
1041
    if (mo && !tvisnil(mo))
41,508✔
1042
      copyTV(J->L, &ix->mobjv, mo);
41,432✔
1043
    ix->mtv = mt;
41,508✔
1044
    settabV(J->L, &mix.tabv, mt);
41,508✔
1045
    setstrV(J->L, &mix.keyv, mmstr);
41,508✔
1046
    mix.key = lj_ir_kstr(J, mmstr);
41,508✔
1047
    mix.val = 0;
41,508✔
1048
    mix.idxchain = 0;
41,508✔
1049
    ix->mobj = lj_record_idx(J, &mix);
41,508✔
1050
    return !tref_isnil(ix->mobj);  /* 1 if metamethod found, 0 if not. */
41,508✔
1051
  }
1052
  return 0;  /* No metamethod. */
1053
}
1054

1055
/* Record call to arithmetic metamethod. */
1056
static TRef rec_mm_arith(jit_State *J, RecordIndex *ix, MMS mm)
40,782✔
1057
{
1058
  /* Set up metamethod call first to save ix->tab and ix->tabv. */
1059
  BCReg func = rec_mm_prep(J, mm == MM_concat ? lj_cont_cat : lj_cont_ra);
81,551✔
1060
  TRef *base = J->base + func;
40,782✔
1061
  TValue *basev = J->L->base + func;
40,782✔
1062
  base[1+LJ_FR2] = ix->tab; base[2+LJ_FR2] = ix->key;
40,782✔
1063
  copyTV(J->L, basev+1+LJ_FR2, &ix->tabv);
40,782✔
1064
  copyTV(J->L, basev+2+LJ_FR2, &ix->keyv);
40,782✔
1065
  if (!lj_record_mm_lookup(J, ix, mm)) {  /* Lookup mm on 1st operand. */
40,782✔
1066
    if (mm != MM_unm) {
19✔
1067
      ix->tab = ix->key;
19✔
1068
      copyTV(J->L, &ix->tabv, &ix->keyv);
19✔
1069
      if (lj_record_mm_lookup(J, ix, mm))  /* Lookup mm on 2nd operand. */
19✔
1070
        goto ok;
18✔
1071
    }
1072
    lj_trace_err(J, LJ_TRERR_NOMM);
1✔
1073
  }
1074
ok:
40,763✔
1075
  base[0] = ix->mobj;
40,781✔
1076
#if LJ_FR2
1077
  base[1] = 0;
40,781✔
1078
#endif
1079
  copyTV(J->L, basev+0, &ix->mobjv);
40,781✔
1080
  lj_record_call(J, func, 2);
40,781✔
1081
  return 0;  /* No result yet. */
40,780✔
1082
}
1083

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

1112
/* Call a comparison metamethod. */
1113
static void rec_mm_callcomp(jit_State *J, RecordIndex *ix, int op)
36,412✔
1114
{
1115
  BCReg func = rec_mm_prep(J, (op&1) ? lj_cont_condf : lj_cont_condt);
49,962✔
1116
  TRef *base = J->base + func + LJ_FR2;
36,412✔
1117
  TValue *tv = J->L->base + func + LJ_FR2;
36,412✔
1118
  base[-LJ_FR2] = ix->mobj; base[1] = ix->val; base[2] = ix->key;
36,412✔
1119
  copyTV(J->L, tv-LJ_FR2, &ix->mobjv);
36,412✔
1120
  copyTV(J->L, tv+1, &ix->valv);
36,412✔
1121
  copyTV(J->L, tv+2, &ix->keyv);
36,412✔
1122
  lj_record_call(J, func, 2);
36,412✔
1123
}
36,412✔
1124

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

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

1206
#if LJ_HASFFI
1207
/* Setup call to cdata comparison metamethod. */
1208
static void rec_mm_comp_cdata(jit_State *J, RecordIndex *ix, int op, MMS mm)
36,356✔
1209
{
1210
  lj_snap_add(J);
36,356✔
1211
  if (tref_iscdata(ix->val)) {
36,356✔
1212
    ix->tab = ix->val;
48✔
1213
    copyTV(J->L, &ix->tabv, &ix->valv);
48✔
1214
  } else {
1215
    lj_assertJ(tref_iscdata(ix->key), "cdata expected");
36,308✔
1216
    ix->tab = ix->key;
36,308✔
1217
    copyTV(J->L, &ix->tabv, &ix->keyv);
36,308✔
1218
  }
1219
  lj_record_mm_lookup(J, ix, mm);
36,356✔
1220
  rec_mm_callcomp(J, ix, op);
36,356✔
1221
}
36,356✔
1222
#endif
1223

1224
/* -- Indexed access ------------------------------------------------------ */
1225

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

1292
/* Record bounds-check. */
1293
static void rec_idx_abc(jit_State *J, TRef asizeref, TRef ikey, uint32_t asize)
5,357✔
1294
{
1295
  /* Try to emit invariant bounds checks. */
1296
  if ((J->flags & (JIT_F_OPT_LOOP|JIT_F_OPT_ABC)) ==
5,357✔
1297
      (JIT_F_OPT_LOOP|JIT_F_OPT_ABC)) {
1298
    IRRef ref = tref_ref(ikey);
5,346✔
1299
    IRIns *ir = IR(ref);
5,346✔
1300
    int32_t ofs = 0;
5,346✔
1301
    IRRef ofsref = 0;
5,346✔
1302
    /* Handle constant offsets. */
1303
    if (ir->o == IR_ADD && irref_isk(ir->op2)) {
5,346✔
1304
      ofsref = ir->op2;
156✔
1305
      ofs = IR(ofsref)->i;
156✔
1306
      ref = ir->op1;
156✔
1307
      ir = IR(ref);
156✔
1308
    }
1309
    /* Got scalar evolution analysis results for this reference? */
1310
    if (ref == J->scev.idx) {
5,346✔
1311
      int32_t stop;
3,716✔
1312
      lj_assertJ(irt_isint(J->scev.t) && ir->o == IR_SLOAD,
3,716✔
1313
                 "only int SCEV supported");
1314
      stop = numberVint(&(J->L->base - J->baseslot)[ir->op1 + FORL_STOP]);
3,716✔
1315
      /* Runtime value for stop of loop is within bounds? */
1316
      if ((uint64_t)stop + ofs < (uint64_t)asize) {
3,716✔
1317
        /* Emit invariant bounds check for stop. */
1318
        emitir(IRTG(IR_ABC, IRT_P32), asizeref, ofs == 0 ? J->scev.stop :
139✔
1319
               emitir(IRTI(IR_ADD), J->scev.stop, ofsref));
1320
        /* Emit invariant bounds check for start, if not const or negative. */
1321
        if (!(J->scev.dir && J->scev.start &&
139✔
1322
              (int64_t)IR(J->scev.start)->i + ofs >= 0))
128✔
1323
          emitir(IRTG(IR_ABC, IRT_P32), asizeref, ikey);
11✔
1324
        return;
139✔
1325
      }
1326
    }
1327
  }
1328
  emitir(IRTGI(IR_ABC), asizeref, ikey);  /* Emit regular bounds check. */
5,218✔
1329
}
1330

1331
/* Record indexed key lookup. */
1332
static TRef rec_idx_key(jit_State *J, RecordIndex *ix, IRRef *rbref,
1,760,765✔
1333
                        IRType1 *rbguard)
1334
{
1335
  TRef key;
1,760,765✔
1336
  GCtab *t = tabV(&ix->tabv);
1,760,765✔
1337
  ix->oldv = lj_tab_get(J->L, t, &ix->keyv);  /* Lookup previous value. */
1,760,765✔
1338
  *rbref = 0;
1,760,765✔
1339
  rbguard->irt = 0;
1,760,765✔
1340

1341
  /* Integer keys are looked up in the array part first. */
1342
  key = ix->key;
1,760,765✔
1343
  if (tref_isnumber(key)) {
1,760,765✔
1344
    int32_t k = numberVint(&ix->keyv);
32,874✔
1345
    if (!tvisint(&ix->keyv) && numV(&ix->keyv) != (lua_Number)k)
32,874✔
1346
      k = LJ_MAX_ASIZE;
94✔
1347
    if ((MSize)k < LJ_MAX_ASIZE) {  /* Potential array key? */
32,874✔
1348
      TRef ikey = lj_opt_narrow_index(J, key);
32,745✔
1349
      TRef asizeref = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_ASIZE);
32,745✔
1350
      if ((MSize)k < t->asize) {  /* Currently an array key? */
32,745✔
1351
        TRef arrayref;
5,354✔
1352
        rec_idx_abc(J, asizeref, ikey, t->asize);
5,354✔
1353
        arrayref = emitir(IRT(IR_FLOAD, IRT_PGC), ix->tab, IRFL_TAB_ARRAY);
5,354✔
1354
        return emitir(IRT(IR_AREF, IRT_PGC), arrayref, ikey);
5,354✔
1355
      } else {  /* Currently not in array (may be an array extension)? */
1356
        emitir(IRTGI(IR_ULE), asizeref, ikey);  /* Inv. bounds check. */
27,391✔
1357
        if (k == 0 && tref_isk(key))
27,391✔
1358
          key = lj_ir_knum_zero(J);  /* Canonicalize 0 or +-0.0 to +0.0. */
4✔
1359
        /* And continue with the hash lookup. */
1360
      }
1361
    } else if (!tref_isk(key)) {
129✔
1362
      /* We can rule out const numbers which failed the integerness test
1363
      ** above. But all other numbers are potential array keys.
1364
      */
1365
      if (t->asize == 0) {  /* True sparse tables have an empty array part. */
129✔
1366
        /* Guard that the array part stays empty. */
1367
        TRef tmp = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_ASIZE);
117✔
1368
        emitir(IRTGI(IR_EQ), tmp, lj_ir_kint(J, 0));
117✔
1369
      } else {
1370
        lj_trace_err(J, LJ_TRERR_NYITMIX);
12✔
1371
      }
1372
    }
1373
  }
1374

1375
  /* Otherwise the key is located in the hash part. */
1376
  if (t->hmask == 0) {  /* Shortcut for empty hash part. */
1,755,399✔
1377
    /* Guard that the hash part stays empty. */
1378
    TRef tmp = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_HMASK);
451✔
1379
    emitir(IRTGI(IR_EQ), tmp, lj_ir_kint(J, 0));
451✔
1380
    return lj_ir_kkptr(J, niltvg(J2G(J)));
451✔
1381
  }
1382
  if (tref_isinteger(key))  /* Hash keys are based on numbers, not ints. */
1,754,948✔
1383
    key = emitir(IRTN(IR_CONV), key, IRCONV_NUM_INT);
27,248✔
1384
  if (tref_isk(key)) {
1,754,948✔
1385
    /* Optimize lookup of constant hash keys. */
1386
    GCSize hslot = (GCSize)((char *)ix->oldv-(char *)&noderef(t->node)[0].val);
1,727,533✔
1387
    if (hslot <= t->hmask*(GCSize)sizeof(Node) &&
1,727,533✔
1388
        hslot <= 65535*(GCSize)sizeof(Node)) {
1389
      TRef node, kslot, hm;
1,662,240✔
1390
      *rbref = J->cur.nins;  /* Mark possible rollback point. */
1,662,240✔
1391
      *rbguard = J->guardemit;
1,662,240✔
1392
      hm = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_HMASK);
1,662,240✔
1393
      emitir(IRTGI(IR_EQ), hm, lj_ir_kint(J, (int32_t)t->hmask));
1,662,240✔
1394
      node = emitir(IRT(IR_FLOAD, IRT_PGC), ix->tab, IRFL_TAB_NODE);
1,662,240✔
1395
      kslot = lj_ir_kslot(J, key, (IRRef)(hslot / sizeof(Node)));
1,662,240✔
1396
      return emitir(IRTG(IR_HREFK, IRT_PGC), node, kslot);
1,662,240✔
1397
    }
1398
  }
1399
  /* Fall back to a regular hash lookup. */
1400
  return emitir(IRT(IR_HREF, IRT_PGC), ix->tab, key);
92,708✔
1401
}
1402

1403
/* Determine whether a key is NOT one of the fast metamethod names. */
1404
static int nommstr(jit_State *J, TRef key)
346,146✔
1405
{
1406
  if (tref_isstr(key)) {
346,146✔
1407
    if (tref_isk(key)) {
343,044✔
1408
      GCstr *str = ir_kstr(IR(tref_ref(key)));
343,032✔
1409
      uint32_t mm;
343,032✔
1410
      for (mm = 0; mm <= MM_FAST; mm++)
2,401,213✔
1411
        if (mmname_str(J2G(J), mm) == str)
2,058,183✔
1412
          return 0;  /* MUST be one the fast metamethod names. */
1413
    } else {
1414
      return 0;  /* Variable string key MAY be a metamethod name. */
1415
    }
1416
  }
1417
  return 1;  /* CANNOT be a metamethod name. */
1418
}
1419

1420
/* Record indexed load/store. */
1421
TRef lj_record_idx(jit_State *J, RecordIndex *ix)
1,756,213✔
1422
{
1423
  TRef xref;
1,756,213✔
1424
  IROp xrefop, loadop;
1,756,213✔
1425
  IRRef rbref;
1,756,213✔
1426
  IRType1 rbguard;
1,756,213✔
1427
  cTValue *oldv;
1,756,213✔
1428

1429
  while (!tref_istab(ix->tab)) { /* Handle non-table lookup. */
1,797,518✔
1430
    /* Never call raw lj_record_idx() on non-table. */
1431
    lj_assertJ(ix->idxchain != 0, "bad usage");
36,751✔
1432
    if (!lj_record_mm_lookup(J, ix, ix->val ? MM_newindex : MM_index))
36,751✔
1433
      lj_trace_err(J, LJ_TRERR_NOMM);
×
1434
  handlemm:
36,751✔
1435
    if (tref_isfunc(ix->mobj)) {  /* Handle metamethod call. */
77,834✔
1436
      BCReg func = rec_mm_prep(J, ix->val ? lj_cont_nop : lj_cont_ra);
72,909✔
1437
      TRef *base = J->base + func + LJ_FR2;
36,529✔
1438
      TValue *tv = J->L->base + func + LJ_FR2;
36,529✔
1439
      base[-LJ_FR2] = ix->mobj; base[1] = ix->tab; base[2] = ix->key;
36,529✔
1440
      setfuncV(J->L, tv-LJ_FR2, funcV(&ix->mobjv));
36,529✔
1441
      copyTV(J->L, tv+1, &ix->tabv);
36,529✔
1442
      copyTV(J->L, tv+2, &ix->keyv);
36,529✔
1443
      if (ix->val) {
36,529✔
1444
        base[3] = ix->val;
149✔
1445
        copyTV(J->L, tv+3, &ix->valv);
149✔
1446
        lj_record_call(J, func, 3);  /* mobj(tab, key, val) */
149✔
1447
        return 0;
149✔
1448
      } else {
1449
        lj_record_call(J, func, 2);  /* res = mobj(tab, key) */
36,380✔
1450
        return 0;  /* No result yet. */
36,380✔
1451
      }
1452
    }
1453
    /* Otherwise retry lookup with metaobject. */
1454
    ix->tab = ix->mobj;
41,305✔
1455
    copyTV(J->L, &ix->tabv, &ix->mobjv);
41,305✔
1456
    if (--ix->idxchain == 0)
41,305✔
1457
      lj_trace_err(J, LJ_TRERR_IDXLOOP);
×
1458
  }
1459

1460
  /* First catch nil and NaN keys for tables. */
1461
  if (tvisnil(&ix->keyv) || (tvisnum(&ix->keyv) && tvisnan(&ix->keyv))) {
1,760,767✔
1462
    if (ix->val)  /* Better fail early. */
2✔
1463
      lj_trace_err(J, LJ_TRERR_STORENN);
2✔
1464
    if (tref_isk(ix->key)) {
×
1465
      if (ix->idxchain && lj_record_mm_lookup(J, ix, MM_index))
×
1466
        goto handlemm;
×
1467
      return TREF_NIL;
×
1468
    }
1469
  }
1470

1471
  /* Record the key lookup. */
1472
  xref = rec_idx_key(J, ix, &rbref, &rbguard);
1,760,765✔
1473
  xrefop = IR(tref_ref(xref))->o;
1,760,753✔
1474
  loadop = xrefop == IR_AREF ? IR_ALOAD : IR_HLOAD;
1,760,753✔
1475
  /* The lj_meta_tset() inconsistency is gone, but better play safe. */
1476
  oldv = xrefop == IR_KKPTR ? (cTValue *)ir_kptr(IR(tref_ref(xref))) : ix->oldv;
1,760,753✔
1477

1478
  if (ix->val == 0) {  /* Indexed load */
1,760,753✔
1479
    IRType t = itype2irt(oldv);
1,414,596✔
1480
    TRef res;
1,414,596✔
1481
    if (oldv == niltvg(J2G(J))) {
1,414,596✔
1482
      emitir(IRTG(IR_EQ, IRT_PGC), xref, lj_ir_kkptr(J, niltvg(J2G(J))));
55,738✔
1483
      res = TREF_NIL;
55,738✔
1484
    } else {
1485
      res = emitir(IRTG(loadop, t), xref, 0);
1,358,858✔
1486
    }
1487
    if (tref_ref(res) < rbref) {  /* HREFK + load forwarded? */
1,414,596✔
1488
      lj_ir_rollback(J, rbref);  /* Rollback to eliminate hmask guard. */
622,895✔
1489
      J->guardemit = rbguard;
622,895✔
1490
    }
1491
    if (t == IRT_NIL && ix->idxchain && lj_record_mm_lookup(J, ix, MM_index))
1,414,596✔
1492
      goto handlemm;
41,072✔
1493
    if (irtype_ispri(t)) res = TREF_PRI(t);  /* Canonicalize primitives. */
1,373,524✔
1494
    return res;
1,373,524✔
1495
  } else {  /* Indexed store. */
1496
    GCtab *mt = tabref(tabV(&ix->tabv)->metatable);
346,157✔
1497
    int keybarrier = tref_isgcv(ix->key) && !tref_isnil(ix->val);
346,157✔
1498
    if (tref_ref(xref) < rbref) {  /* HREFK forwarded? */
346,157✔
1499
      lj_ir_rollback(J, rbref);  /* Rollback to eliminate hmask guard. */
32,945✔
1500
      J->guardemit = rbguard;
32,945✔
1501
    }
1502
    if (tvisnil(oldv)) {  /* Previous value was nil? */
346,157✔
1503
      /* Need to duplicate the hasmm check for the early guards. */
1504
      int hasmm = 0;
12,547✔
1505
      if (ix->idxchain && mt) {
12,547✔
1506
        cTValue *mo = lj_tab_getstr(mt, mmname_str(J2G(J), MM_newindex));
36✔
1507
        hasmm = mo && !tvisnil(mo);
36✔
1508
      }
1509
      if (hasmm)
11✔
1510
        emitir(IRTG(loadop, IRT_NIL), xref, 0);  /* Guard for nil value. */
11✔
1511
      else if (xrefop == IR_HREF)
12,536✔
1512
        emitir(IRTG(oldv == niltvg(J2G(J)) ? IR_EQ : IR_NE, IRT_PGC),
9,672✔
1513
               xref, lj_ir_kkptr(J, niltvg(J2G(J))));
1514
      if (ix->idxchain && lj_record_mm_lookup(J, ix, MM_newindex)) {
12,547✔
1515
        lj_assertJ(hasmm, "inconsistent metamethod handling");
11✔
1516
        goto handlemm;
11✔
1517
      }
1518
      lj_assertJ(!hasmm, "inconsistent metamethod handling");
12,536✔
1519
      if (oldv == niltvg(J2G(J))) {  /* Need to insert a new key. */
12,536✔
1520
        TRef key = ix->key;
10,119✔
1521
        if (tref_isinteger(key)) {  /* NEWREF needs a TValue as a key. */
10,119✔
1522
          key = emitir(IRTN(IR_CONV), key, IRCONV_NUM_INT);
134✔
1523
        } else if (tref_isnum(key)) {
9,985✔
1524
          if (tref_isk(key)) {
71✔
1525
            if (tvismzero(&ix->keyv))
2✔
1526
              key = lj_ir_knum_zero(J);  /* Canonicalize -0.0 to +0.0. */
2✔
1527
          } else {
1528
            emitir(IRTG(IR_EQ, IRT_NUM), key, key);  /* Check for !NaN. */
69✔
1529
          }
1530
        }
1531
        xref = emitir(IRT(IR_NEWREF, IRT_PGC), ix->tab, key);
10,119✔
1532
        keybarrier = 0;  /* NEWREF already takes care of the key barrier. */
10,119✔
1533
#ifdef LUAJIT_ENABLE_TABLE_BUMP
1534
        if ((J->flags & JIT_F_OPT_SINK))  /* Avoid a separate flag. */
1535
          rec_idx_bump(J, ix);
1536
#endif
1537
      }
1538
    } else if (!lj_opt_fwd_wasnonnil(J, loadop, tref_ref(xref))) {
333,610✔
1539
      /* Cannot derive that the previous value was non-nil, must do checks. */
1540
      if (xrefop == IR_HREF)  /* Guard against store to niltv. */
298,846✔
1541
        emitir(IRTG(IR_NE, IRT_PGC), xref, lj_ir_kkptr(J, niltvg(J2G(J))));
28✔
1542
      if (ix->idxchain) {  /* Metamethod lookup required? */
298,846✔
1543
        /* A check for NULL metatable is cheaper (hoistable) than a load. */
1544
        if (!mt) {
298,837✔
1545
          TRef mtref = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_TAB_META);
298,820✔
1546
          emitir(IRTG(IR_EQ, IRT_TAB), mtref, lj_ir_knull(J, IRT_TAB));
298,820✔
1547
        } else {
1548
          IRType t = itype2irt(oldv);
17✔
1549
          emitir(IRTG(loadop, t), xref, 0);  /* Guard for non-nil value. */
17✔
1550
        }
1551
      }
1552
    } else {
1553
      keybarrier = 0;  /* Previous non-nil value kept the key alive. */
1554
    }
1555
    /* Convert int to number before storing. */
1556
    if (!LJ_DUALNUM && tref_isinteger(ix->val))
346,146✔
1557
      ix->val = emitir(IRTN(IR_CONV), ix->val, IRCONV_NUM_INT);
3,730✔
1558
    emitir(IRT(loadop+IRDELTA_L2S, tref_type(ix->val)), xref, ix->val);
346,146✔
1559
    if (keybarrier || tref_isgcv(ix->val))
346,146✔
1560
      emitir(IRT(IR_TBAR, IRT_NIL), ix->tab, 0);
307,824✔
1561
    /* Invalidate neg. metamethod cache for stores with certain string keys. */
1562
    if (!nommstr(J, ix->key)) {
689,178✔
1563
      TRef fref = emitir(IRT(IR_FREF, IRT_PGC), ix->tab, IRFL_TAB_NOMM);
14✔
1564
      emitir(IRT(IR_FSTORE, IRT_U8), fref, lj_ir_kint(J, 0));
14✔
1565
    }
1566
    J->needsnap = 1;
346,146✔
1567
    return 0;
346,146✔
1568
  }
1569
}
1570

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

1596
/* -- Upvalue access ------------------------------------------------------ */
1597

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

1623
/* Record upvalue load/store. */
1624
static TRef rec_upvalue(jit_State *J, uint32_t uv, TRef val)
1,248,005✔
1625
{
1626
  GCupval *uvp = &gcref(J->fn->l.uvptr[uv])->uv;
1,248,005✔
1627
  TRef fn = getcurrf(J);
1,248,005✔
1628
  IRRef uref;
1,248,005✔
1629
  int needbarrier = 0;
1,248,005✔
1630
  if (rec_upvalue_constify(J, uvp)) {  /* Try to constify immutable upvalue. */
1,248,005✔
1631
    TRef tr, kfunc;
1,170,468✔
1632
    lj_assertJ(val == 0, "bad usage");
1,170,468✔
1633
    if (!tref_isk(fn)) {  /* Late specialization of current function. */
1,170,468✔
1634
      if (J->pt->flags >= PROTO_CLC_POLY)
137,320✔
1635
        goto noconstify;
48✔
1636
      kfunc = lj_ir_kfunc(J, J->fn);
137,272✔
1637
      emitir(IRTG(IR_EQ, IRT_FUNC), fn, kfunc);
137,272✔
1638
#if LJ_FR2
1639
      J->base[-2] = kfunc;
137,272✔
1640
#else
1641
      J->base[-1] = kfunc | TREF_FRAME;
1642
#endif
1643
      fn = kfunc;
137,272✔
1644
    }
1645
    tr = lj_record_constify(J, uvval(uvp));
1,170,420✔
1646
    if (tr)
1,170,420✔
1647
      return tr;
1648
  }
1649
noconstify:
77,537✔
1650
  /* Note: this effectively limits LJ_MAX_UPVAL to 127. */
1651
  uv = (uv << 8) | (hashrot(uvp->dhash, uvp->dhash + HASH_BIAS) & 0xff);
77,585✔
1652
  if (!uvp->closed) {
77,585✔
1653
    uref = tref_ref(emitir(IRTG(IR_UREFO, IRT_PGC), fn, uv));
493✔
1654
    /* In current stack? */
1655
    if (uvval(uvp) >= tvref(J->L->stack) &&
493✔
1656
        uvval(uvp) < tvref(J->L->maxstack)) {
492✔
1657
      int32_t slot = (int32_t)(uvval(uvp) - (J->L->base - J->baseslot));
484✔
1658
      if (slot >= 0) {  /* Aliases an SSA slot? */
484✔
1659
        emitir(IRTG(IR_EQ, IRT_PGC),
210✔
1660
               REF_BASE,
1661
               emitir(IRT(IR_ADD, IRT_PGC), uref,
1662
                      lj_ir_kint(J, (slot - 1 - LJ_FR2) * -8)));
1663
        slot -= (int32_t)J->baseslot;  /* Note: slot number may be negative! */
210✔
1664
        if (val == 0) {
210✔
1665
          return getslot(J, slot);
96✔
1666
        } else {
1667
          J->base[slot] = val;
114✔
1668
          if (slot >= (int32_t)J->maxslot) J->maxslot = (BCReg)(slot+1);
114✔
1669
          return 0;
114✔
1670
        }
1671
      }
1672
    }
1673
    emitir(IRTG(IR_UGT, IRT_PGC),
283✔
1674
           emitir(IRT(IR_SUB, IRT_PGC), uref, REF_BASE),
1675
           lj_ir_kint(J, (J->baseslot + J->maxslot) * 8));
1676
  } else {
1677
    needbarrier = 1;
77,092✔
1678
    uref = tref_ref(emitir(IRTG(IR_UREFC, IRT_PGC), fn, uv));
77,092✔
1679
  }
1680
  if (val == 0) {  /* Upvalue load */
77,375✔
1681
    IRType t = itype2irt(uvval(uvp));
77,293✔
1682
    TRef res = emitir(IRTG(IR_ULOAD, t), uref, 0);
77,293✔
1683
    if (irtype_ispri(t)) res = TREF_PRI(t);  /* Canonicalize primitive refs. */
77,293✔
1684
    return res;
77,293✔
1685
  } else {  /* Upvalue store. */
1686
    /* Convert int to number before storing. */
1687
    if (!LJ_DUALNUM && tref_isinteger(val))
82✔
1688
      val = emitir(IRTN(IR_CONV), val, IRCONV_NUM_INT);
15✔
1689
    emitir(IRT(IR_USTORE, tref_type(val)), uref, val);
82✔
1690
    if (needbarrier && tref_isgcv(val))
82✔
1691
      emitir(IRT(IR_OBAR, IRT_NIL), uref, val);
4✔
1692
    J->needsnap = 1;
82✔
1693
    return 0;
82✔
1694
  }
1695
}
1696

1697
/* -- Record calls to Lua functions --------------------------------------- */
1698

1699
/* Check unroll limits for calls. */
1700
static void check_call_unroll(jit_State *J, TraceNo lnk)
961,500✔
1701
{
1702
  cTValue *frame = J->L->base - 1;
961,500✔
1703
  void *pc = mref(frame_func(frame)->l.pc, void);
961,500✔
1704
  int32_t depth = J->framedepth;
961,500✔
1705
  int32_t count = 0;
961,500✔
1706
  if ((J->pt->flags & PROTO_VARARG)) depth--;  /* Vararg frame still missing. */
961,500✔
1707
  for (; depth > 0; depth--) {  /* Count frames with same prototype. */
2,383,319✔
1708
    if (frame_iscont(frame)) depth--;
1,421,819✔
1709
    frame = frame_prev(frame);
1,421,819✔
1710
    if (mref(frame_func(frame)->l.pc, void) == pc)
1,421,819✔
1711
      count++;
2,393✔
1712
  }
1713
  if (J->pc == J->startpc) {
961,500✔
1714
    if (count + J->tailcalled > J->param[JIT_P_recunroll]) {
559✔
1715
      J->pc++;
164✔
1716
      if (J->framedepth + J->retdepth == 0)
164✔
1717
        lj_record_stop(J, LJ_TRLINK_TAILREC, J->cur.traceno);  /* Tail-rec. */
6✔
1718
      else
1719
        lj_record_stop(J, LJ_TRLINK_UPREC, J->cur.traceno);  /* Up-recursion. */
158✔
1720
    }
1721
  } else {
1722
    if (count > J->param[JIT_P_callunroll]) {
960,941✔
1723
      if (lnk) {  /* Possible tail- or up-recursion. */
119✔
1724
        lj_trace_flush(J, lnk);  /* Flush trace that only returns. */
52✔
1725
        /* Set a small, pseudo-random hotcount for a quick retry of JFUNC*. */
1726
        hotcount_set(J2GG(J), J->pc+1, LJ_PRNG_BITS(J, 4));
52✔
1727
      }
1728
      lj_trace_err(J, LJ_TRERR_CUNROLL);
119✔
1729
    }
1730
  }
1731
}
961,381✔
1732

1733
/* Record Lua function setup. */
1734
static void rec_func_setup(jit_State *J)
964,840✔
1735
{
1736
  GCproto *pt = J->pt;
964,840✔
1737
  BCReg s, numparams = pt->numparams;
964,840✔
1738
  if ((pt->flags & PROTO_NOJIT))
964,840✔
1739
    lj_trace_err(J, LJ_TRERR_CJITOFF);
1✔
1740
  if (J->baseslot + pt->framesize >= LJ_MAX_JSLOTS)
964,839✔
1741
    lj_trace_err(J, LJ_TRERR_STACKOV);
×
1742
  /* Fill up missing parameters with nil. */
1743
  for (s = J->maxslot; s < numparams; s++)
965,217✔
1744
    J->base[s] = TREF_NIL;
378✔
1745
  /* The remaining slots should never be read before they are written. */
1746
  J->maxslot = numparams;
964,839✔
1747
}
964,839✔
1748

1749
/* Record Lua vararg function setup. */
1750
static void rec_func_vararg(jit_State *J)
106✔
1751
{
1752
  GCproto *pt = J->pt;
106✔
1753
  BCReg s, fixargs, vframe = J->maxslot+1+LJ_FR2;
106✔
1754
  lj_assertJ((pt->flags & PROTO_VARARG), "FUNCV in non-vararg function");
106✔
1755
  if (J->baseslot + vframe + pt->framesize >= LJ_MAX_JSLOTS)
106✔
1756
    lj_trace_err(J, LJ_TRERR_STACKOV);
×
1757
  J->base[vframe-1-LJ_FR2] = J->base[-1-LJ_FR2];  /* Copy function up. */
106✔
1758
#if LJ_FR2
1759
  J->base[vframe-1] = TREF_FRAME;
106✔
1760
#endif
1761
  /* Copy fixarg slots up and set their original slots to nil. */
1762
  fixargs = pt->numparams < J->maxslot ? pt->numparams : J->maxslot;
106✔
1763
  for (s = 0; s < fixargs; s++) {
134✔
1764
    J->base[vframe+s] = J->base[s];
28✔
1765
    J->base[s] = TREF_NIL;
28✔
1766
  }
1767
  J->maxslot = fixargs;
106✔
1768
  J->framedepth++;
106✔
1769
  J->base += vframe;
106✔
1770
  J->baseslot += vframe;
106✔
1771
}
106✔
1772

1773
/* Record entry to a Lua function. */
1774
static void rec_func_lua(jit_State *J)
158,860✔
1775
{
1776
  rec_func_setup(J);
158,860✔
1777
  check_call_unroll(J, 0);
158,859✔
1778
}
158,792✔
1779

1780
/* Record entry to an already compiled function. */
1781
static void rec_func_jit(jit_State *J, TraceNo lnk)
805,980✔
1782
{
1783
  GCtrace *T;
805,980✔
1784
  rec_func_setup(J);
805,980✔
1785
  T = traceref(J, lnk);
805,980✔
1786
  if (T->linktype == LJ_TRLINK_RETURN) {  /* Trace returns to interpreter? */
805,980✔
1787
    check_call_unroll(J, lnk);
802,641✔
1788
    /* Temporarily unpatch JFUNC* to continue recording across function. */
1789
    J->patchins = *J->pc;
802,589✔
1790
    J->patchpc = (BCIns *)J->pc;
802,589✔
1791
    *J->patchpc = T->startins;
802,589✔
1792
    return;
802,589✔
1793
  }
1794
  J->instunroll = 0;  /* Cannot continue across a compiled function. */
3,339✔
1795
  if (J->pc == J->startpc && J->framedepth + J->retdepth == 0)
3,339✔
1796
    lj_record_stop(J, LJ_TRLINK_TAILREC, J->cur.traceno);  /* Extra tail-rec. */
×
1797
  else
1798
    lj_record_stop(J, LJ_TRLINK_ROOT, lnk);  /* Link to the function. */
3,339✔
1799
}
1800

1801
/* -- Vararg handling ----------------------------------------------------- */
1802

1803
/* Detect y = select(x, ...) idiom. */
1804
static int select_detect(jit_State *J)
15✔
1805
{
1806
  BCIns ins = J->pc[1];
15✔
1807
  if (bc_op(ins) == BC_CALLM && bc_b(ins) == 2 && bc_c(ins) == 1) {
15✔
1808
    cTValue *func = &J->L->base[bc_a(ins)];
13✔
1809
    if (tvisfunc(func) && funcV(func)->c.ffid == FF_select) {
13✔
1810
      TRef kfunc = lj_ir_kfunc(J, funcV(func));
9✔
1811
      emitir(IRTG(IR_EQ, IRT_FUNC), getslot(J, bc_a(ins)), kfunc);
9✔
1812
      return 1;
9✔
1813
    }
1814
  }
1815
  return 0;
1816
}
1817

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

1925
/* -- Record allocations -------------------------------------------------- */
1926

1927
static TRef rec_tnew(jit_State *J, uint32_t ah)
584✔
1928
{
1929
  uint32_t asize = ah & 0x7ff;
584✔
1930
  uint32_t hbits = ah >> 11;
584✔
1931
  TRef tr;
584✔
1932
  if (asize == 0x7ff) asize = 0x801;
×
1933
  tr = emitir(IRTG(IR_TNEW, IRT_TAB), asize, hbits);
584✔
1934
#ifdef LUAJIT_ENABLE_TABLE_BUMP
1935
  J->rbchash[(tr & (RBCHASH_SLOTS-1))].ref = tref_ref(tr);
1936
  setmref(J->rbchash[(tr & (RBCHASH_SLOTS-1))].pc, J->pc);
1937
  setgcref(J->rbchash[(tr & (RBCHASH_SLOTS-1))].pt, obj2gco(J->pt));
1938
#endif
1939
  return tr;
584✔
1940
}
1941

1942
/* -- Concatenation ------------------------------------------------------- */
1943

1944
typedef struct RecCatDataCP {
1945
  jit_State *J;
1946
  RecordIndex *ix;
1947
} RecCatDataCP;
1948

1949
static TValue *rec_mm_concat_cp(lua_State *L, lua_CFunction dummy, void *ud)
13✔
1950
{
1951
  RecCatDataCP *rcd = (RecCatDataCP *)ud;
13✔
1952
  UNUSED(L); UNUSED(dummy);
13✔
1953
  rec_mm_arith(rcd->J, rcd->ix, MM_concat);  /* Call __concat metamethod. */
13✔
1954
  return NULL;
12✔
1955
}
1956

1957
static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
294✔
1958
{
1959
  TRef *top = &J->base[topslot];
294✔
1960
  TValue savetv[5+LJ_FR2];
294✔
1961
  BCReg s;
294✔
1962
  RecordIndex ix;
294✔
1963
  RecCatDataCP rcd;
294✔
1964
  int errcode;
294✔
1965
  lj_assertJ(baseslot < topslot, "bad CAT arg");
294✔
1966
  for (s = baseslot; s <= topslot; s++)
1,049✔
1967
    (void)getslot(J, s);  /* Ensure all arguments have a reference. */
755✔
1968
  if (tref_isnumber_str(top[0]) && tref_isnumber_str(top[-1])) {
294✔
1969
    TRef tr, hdr, *trp, *xbase, *base = &J->base[baseslot];
283✔
1970
    /* First convert numbers to strings. */
1971
    for (trp = top; trp >= base; trp--) {
1,008✔
1972
      if (tref_isnumber(*trp))
727✔
1973
        *trp = emitir(IRT(IR_TOSTR, IRT_STR), *trp,
49✔
1974
                      tref_isnum(*trp) ? IRTOSTR_NUM : IRTOSTR_INT);
1975
      else if (!tref_isstr(*trp))
678✔
1976
        break;
1977
    }
1978
    xbase = ++trp;
283✔
1979
    tr = hdr = emitir(IRT(IR_BUFHDR, IRT_PGC),
283✔
1980
                      lj_ir_kptr(J, &J2G(J)->tmpbuf), IRBUFHDR_RESET);
1981
    do {
725✔
1982
      tr = emitir(IRT(IR_BUFPUT, IRT_PGC), tr, *trp++);
725✔
1983
    } while (trp <= top);
725✔
1984
    tr = emitir(IRT(IR_BUFSTR, IRT_STR), tr, hdr);
283✔
1985
    J->maxslot = (BCReg)(xbase - J->base);
283✔
1986
    if (xbase == base) return tr;  /* Return simple concatenation result. */
283✔
1987
    /* Pass partial result. */
1988
    topslot = J->maxslot--;
2✔
1989
    *xbase = tr;
2✔
1990
    top = xbase;
2✔
1991
    setstrV(J->L, &ix.keyv, &J2G(J)->strempty);  /* Simulate string result. */
2✔
1992
  } else {
1993
    J->maxslot = topslot-1;
11✔
1994
    copyTV(J->L, &ix.keyv, &J->L->base[topslot]);
11✔
1995
  }
1996
  copyTV(J->L, &ix.tabv, &J->L->base[topslot-1]);
13✔
1997
  ix.tab = top[-1];
13✔
1998
  ix.key = top[0];
13✔
1999
  memcpy(savetv, &J->L->base[topslot-1], sizeof(savetv));  /* Save slots. */
13✔
2000
  rcd.J = J;
13✔
2001
  rcd.ix = &ix;
13✔
2002
  errcode = lj_vm_cpcall(J->L, NULL, &rcd, rec_mm_concat_cp);
13✔
2003
  memcpy(&J->L->base[topslot-1], savetv, sizeof(savetv));  /* Restore slots. */
13✔
2004
  if (errcode) return (TRef)(-errcode);
13✔
2005
  return 0;  /* No result yet. */
2006
}
2007

2008
/* -- Record bytecode ops ------------------------------------------------- */
2009

2010
/* Prepare for comparison. */
2011
static void rec_comp_prep(jit_State *J)
909,768✔
2012
{
2013
  /* Prevent merging with snapshot #0 (GC exit) since we fixup the PC. */
2014
  if (J->cur.nsnap == 1 && J->cur.snap[0].ref == J->cur.nins)
909,768✔
2015
    emitir_raw(IRT(IR_NOP, IRT_NIL), 0, 0);
257✔
2016
  lj_snap_add(J);
909,768✔
2017
}
909,768✔
2018

2019
/* Fixup comparison. */
2020
static void rec_comp_fixup(jit_State *J, const BCIns *pc, int cond)
932,531✔
2021
{
2022
  BCIns jmpins = pc[1];
932,531✔
2023
  const BCIns *npc = pc + 2 + (cond ? bc_j(jmpins) : 0);
932,531✔
2024
  SnapShot *snap = &J->cur.snap[J->cur.nsnap-1];
932,531✔
2025
  /* Set PC to opposite target to avoid re-recording the comp. in side trace. */
2026
#if LJ_FR2
2027
  SnapEntry *flink = &J->cur.snapmap[snap->mapofs + snap->nent];
932,531✔
2028
  uint64_t pcbase;
932,531✔
2029
  memcpy(&pcbase, flink, sizeof(uint64_t));
932,531✔
2030
  pcbase = (pcbase & 0xff) | (u64ptr(npc) << 8);
932,531✔
2031
  memcpy(flink, &pcbase, sizeof(uint64_t));
932,531✔
2032
#else
2033
  J->cur.snapmap[snap->mapofs + snap->nent] = SNAP_MKPC(npc);
2034
#endif
2035
  J->needsnap = 1;
932,531✔
2036
  if (bc_a(jmpins) < J->maxslot) J->maxslot = bc_a(jmpins);
932,531✔
2037
  lj_snap_shrink(J);  /* Shrink last snapshot if possible. */
932,531✔
2038
}
932,531✔
2039

2040
/* Record the next bytecode instruction (_before_ it's executed). */
2041
void lj_record_ins(jit_State *J)
9,193,894✔
2042
{
2043
  cTValue *lbase;
9,193,894✔
2044
  RecordIndex ix;
9,193,894✔
2045
  const BCIns *pc;
9,193,894✔
2046
  BCIns ins;
9,193,894✔
2047
  BCOp op;
9,193,894✔
2048
  TRef ra, rb, rc;
9,193,894✔
2049

2050
  /* Perform post-processing action before recording the next instruction. */
2051
  if (LJ_UNLIKELY(J->postproc != LJ_POST_NONE)) {
9,193,894✔
2052
    switch (J->postproc) {
355,655✔
2053
    case LJ_POST_FIXCOMP:  /* Fixup comparison. */
22,865✔
2054
      pc = (const BCIns *)(uintptr_t)J2G(J)->tmptv.u64;
22,865✔
2055
      rec_comp_fixup(J, pc, (!tvistruecond(&J2G(J)->tmptv2) ^ (bc_op(*pc)&1)));
22,865✔
2056
      /* fallthrough */
2057
    case LJ_POST_FIXGUARD:  /* Fixup and emit pending guard. */
36,361✔
2058
    case LJ_POST_FIXGUARDSNAP:  /* Fixup and emit pending guard and snapshot. */
2059
      if (!tvistruecond(&J2G(J)->tmptv2)) {
36,361✔
2060
        J->fold.ins.o ^= 1;  /* Flip guard to opposite. */
13,492✔
2061
        if (J->postproc == LJ_POST_FIXGUARDSNAP) {
13,492✔
2062
          SnapShot *snap = &J->cur.snap[J->cur.nsnap-1];
1✔
2063
          J->cur.snapmap[snap->mapofs+snap->nent-1]--;  /* False -> true. */
1✔
2064
        }
2065
      }
2066
      lj_opt_fold(J);  /* Emit pending guard. */
36,361✔
2067
      /* fallthrough */
2068
    case LJ_POST_FIXBOOL:
36,375✔
2069
      if (!tvistruecond(&J2G(J)->tmptv2)) {
36,375✔
2070
        BCReg s;
13,498✔
2071
        TValue *tv = J->L->base;
13,498✔
2072
        for (s = 0; s < J->maxslot; s++)  /* Fixup stack slot (if any). */
67,626✔
2073
          if (J->base[s] == TREF_TRUE && tvisfalse(&tv[s])) {
54,136✔
2074
            J->base[s] = TREF_FALSE;
8✔
2075
            break;
8✔
2076
          }
2077
      }
2078
      break;
2079
    case LJ_POST_FIXCONST:
1✔
2080
      {
2081
        BCReg s;
1✔
2082
        TValue *tv = J->L->base;
1✔
2083
        for (s = 0; s < J->maxslot; s++)  /* Constify stack slots (if any). */
13✔
2084
          if (J->base[s] == TREF_NIL && !tvisnil(&tv[s]))
12✔
2085
            J->base[s] = lj_record_constify(J, &tv[s]);
1✔
2086
      }
2087
      break;
2088
    case LJ_POST_FFRETRY:  /* Suppress recording of retried fast function. */
319,279✔
2089
      if (bc_op(*J->pc) >= BC__MAX)
319,279✔
2090
        return;
21✔
2091
      break;
2092
    default: lj_assertJ(0, "bad post-processing mode"); break;
2093
    }
2094
    J->postproc = LJ_POST_NONE;
355,652✔
2095
  }
2096

2097
  /* Need snapshot before recording next bytecode (e.g. after a store). */
2098
  if (J->needsnap) {
9,193,891✔
2099
    J->needsnap = 0;
1,442,147✔
2100
    if (J->pt) lj_snap_purge(J);
1,442,147✔
2101
    lj_snap_add(J);
1,442,147✔
2102
    J->mergesnap = 1;
1,442,147✔
2103
  }
2104

2105
  /* Skip some bytecodes. */
2106
  if (LJ_UNLIKELY(J->bcskip > 0)) {
9,193,891✔
2107
    J->bcskip--;
18✔
2108
    return;
18✔
2109
  }
2110

2111
  /* Record only closed loops for root traces. */
2112
  pc = J->pc;
9,193,873✔
2113
  if (J->framedepth == 0 &&
9,193,873✔
2114
     (MSize)((char *)pc - (char *)J->bc_min) >= J->bc_extent)
2,891,093✔
2115
    lj_trace_err(J, LJ_TRERR_LLEAVE);
516✔
2116

2117
#ifdef LUA_USE_ASSERT
2118
  rec_check_slots(J);
2119
  rec_check_ir(J);
2120
#endif
2121

2122
#if LJ_HASPROFILE
2123
  rec_profile_ins(J, pc);
9,193,357✔
2124
#endif
2125

2126
  /* Keep a copy of the runtime values of var/num/str operands. */
2127
#define rav        (&ix.valv)
2128
#define rbv        (&ix.tabv)
2129
#define rcv        (&ix.keyv)
2130

2131
  lbase = J->L->base;
9,193,357✔
2132
  ins = *pc;
9,193,357✔
2133
  op = bc_op(ins);
9,193,357✔
2134
  ra = bc_a(ins);
9,193,357✔
2135
  ix.val = 0;
9,193,357✔
2136
  switch (bcmode_a(op)) {
9,193,357✔
2137
  case BCMvar:
1,333,163✔
2138
    copyTV(J->L, rav, &lbase[ra]); ix.val = ra = getslot(J, ra); break;
1,333,163✔
2139
  default: break;  /* Handled later. */
2140
  }
2141
  rb = bc_b(ins);
9,193,357✔
2142
  rc = bc_c(ins);
9,193,357✔
2143
  switch (bcmode_b(op)) {
9,193,357✔
2144
  case BCMnone: rb = 0; rc = bc_d(ins); break;  /* Upgrade rc to 'rd'. */
6,017,331✔
2145
  case BCMvar:
2,093,268✔
2146
    copyTV(J->L, rbv, &lbase[rb]); ix.tab = rb = getslot(J, rb); break;
2,093,268✔
2147
  default: break;  /* Handled later. */
2148
  }
2149
  switch (bcmode_c(op)) {
9,193,357✔
2150
  case BCMvar:
1,315,675✔
2151
    copyTV(J->L, rcv, &lbase[rc]); ix.key = rc = getslot(J, rc); break;
1,315,675✔
2152
  case BCMpri: setpriV(rcv, ~rc); ix.key = rc = TREF_PRI(IRT_NIL+rc); break;
704,372✔
2153
  case BCMnum: { cTValue *tv = proto_knumtv(J->pt, rc);
195,248✔
2154
    copyTV(J->L, rcv, tv); ix.key = rc = tvisint(tv) ? lj_ir_kint(J, intV(tv)) :
195,248✔
2155
    lj_ir_knumint(J, numV(tv)); } break;
195,248✔
2156
  case BCMstr: { GCstr *s = gco2str(proto_kgc(J->pt, ~(ptrdiff_t)rc));
1,707,266✔
2157
    setstrV(J->L, rcv, s); ix.key = rc = lj_ir_kstr(J, s); } break;
1,707,266✔
2158
  default: break;  /* Handled later. */
2159
  }
2160

2161
  switch (op) {
9,193,357✔
2162

2163
  /* -- Comparison ops ---------------------------------------------------- */
2164

2165
  case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
305,827✔
2166
#if LJ_HASFFI
2167
    if (tref_iscdata(ra) || tref_iscdata(rc)) {
305,827✔
2168
      rec_mm_comp_cdata(J, &ix, op, ((int)op & 2) ? MM_le : MM_lt);
22,846✔
2169
      break;
22,846✔
2170
    }
2171
#endif
2172
    /* Emit nothing for two numeric or string consts. */
2173
    if (!(tref_isk2(ra,rc) && tref_isnumber_str(ra) && tref_isnumber_str(rc))) {
282,981✔
2174
      IRType ta = tref_isinteger(ra) ? IRT_INT : tref_type(ra);
258,582✔
2175
      IRType tc = tref_isinteger(rc) ? IRT_INT : tref_type(rc);
258,582✔
2176
      int irop;
258,582✔
2177
      if (ta != tc) {
258,582✔
2178
        /* Widen mixed number/int comparisons to number/number comparison. */
2179
        if (ta == IRT_INT && tc == IRT_NUM) {
249,984✔
2180
          ra = emitir(IRTN(IR_CONV), ra, IRCONV_NUM_INT);
126,355✔
2181
          ta = IRT_NUM;
126,355✔
2182
        } else if (ta == IRT_NUM && tc == IRT_INT) {
123,629✔
2183
          rc = emitir(IRTN(IR_CONV), rc, IRCONV_NUM_INT);
123,629✔
2184
        } else if (LJ_52) {
×
2185
          ta = IRT_NIL;  /* Force metamethod for different types. */
2186
        } else if (!((ta == IRT_FALSE || ta == IRT_TRUE) &&
×
2187
                     (tc == IRT_FALSE || tc == IRT_TRUE))) {
×
2188
          break;  /* Interpreter will throw for two different types. */
2189
        }
2190
      }
2191
      rec_comp_prep(J);
258,582✔
2192
      irop = (int)op - (int)BC_ISLT + (int)IR_LT;
258,582✔
2193
      if (ta == IRT_NUM) {
258,582✔
2194
        if ((irop & 1)) irop ^= 4;  /* ISGE/ISGT are unordered. */
258,454✔
2195
        if (!lj_ir_numcmp(numberVnum(rav), numberVnum(rcv), (IROp)irop))
258,454✔
2196
          irop ^= 5;
248,834✔
2197
      } else if (ta == IRT_INT) {
128✔
2198
        if (!lj_ir_numcmp(numberVnum(rav), numberVnum(rcv), (IROp)irop))
80✔
2199
          irop ^= 1;
20✔
2200
      } else if (ta == IRT_STR) {
48✔
2201
        if (!lj_ir_strcmp(strV(rav), strV(rcv), (IROp)irop)) irop ^= 1;
1✔
2202
        ra = lj_ir_call(J, IRCALL_lj_str_cmp, ra, rc);
1✔
2203
        rc = lj_ir_kint(J, 0);
1✔
2204
        ta = IRT_INT;
1✔
2205
      } else {
2206
        rec_mm_comp(J, &ix, (int)op);
47✔
2207
        break;
47✔
2208
      }
2209
      emitir(IRTG(irop, ta), ra, rc);
258,535✔
2210
      rec_comp_fixup(J, J->pc, ((int)op ^ irop) & 1);
258,535✔
2211
    }
2212
    break;
2213

2214
  case BC_ISEQV: case BC_ISNEV:
681,056✔
2215
  case BC_ISEQS: case BC_ISNES:
2216
  case BC_ISEQN: case BC_ISNEN:
2217
  case BC_ISEQP: case BC_ISNEP:
2218
#if LJ_HASFFI
2219
    if (tref_iscdata(ra) || tref_iscdata(rc)) {
681,056✔
2220
      rec_mm_comp_cdata(J, &ix, op, MM_eq);
13,510✔
2221
      break;
13,510✔
2222
    }
2223
#endif
2224
    /* Emit nothing for two non-table, non-udata consts. */
2225
    if (!(tref_isk2(ra, rc) && !(tref_istab(ra) || tref_isudata(ra)))) {
667,546✔
2226
      int diff;
651,186✔
2227
      rec_comp_prep(J);
651,186✔
2228
      diff = lj_record_objcmp(J, ra, rc, rav, rcv);
651,186✔
2229
      if (diff == 2 || !(tref_istab(ra) || tref_isudata(ra)))
651,186✔
2230
        rec_comp_fixup(J, J->pc, ((int)op & 1) == !diff);
651,131✔
2231
      else if (diff == 1)  /* Only check __eq if different, but same type. */
55✔
2232
        rec_mm_equal(J, &ix, (int)op);
10✔
2233
    }
2234
    break;
2235

2236
  /* -- Unary test and copy ops ------------------------------------------- */
2237

2238
  case BC_ISTC: case BC_ISFC:
215✔
2239
    if ((op & 1) == tref_istruecond(rc))
215✔
2240
      rc = 0;  /* Don't store if condition is not true. */
189✔
2241
    /* fallthrough */
2242
  case BC_IST: case BC_ISF:  /* Type specialization suffices. */
2243
    if (bc_a(pc[1]) < J->maxslot)
64,044✔
2244
      J->maxslot = bc_a(pc[1]);  /* Shrink used slots. */
36,210✔
2245
    break;
2246

2247
  case BC_ISTYPE: case BC_ISNUM:
2248
    /* These coercions need to correspond with lj_meta_istype(). */
2249
    if (LJ_DUALNUM && rc == ~LJ_TNUMX+1)
10✔
2250
      ra = lj_opt_narrow_toint(J, ra);
2251
    else if (rc == ~LJ_TNUMX+2)
10✔
2252
      ra = lj_ir_tonum(J, ra);
2✔
2253
    else if (rc == ~LJ_TSTR+1)
8✔
2254
      ra = lj_ir_tostr(J, ra);
3✔
2255
    /* else: type specialization suffices. */
2256
    J->base[bc_a(ins)] = ra;
10✔
2257
    break;
10✔
2258

2259
  /* -- Unary ops --------------------------------------------------------- */
2260

2261
  case BC_NOT:
4✔
2262
    /* Type specialization already forces const result. */
2263
    rc = tref_istruecond(rc) ? TREF_FALSE : TREF_TRUE;
4✔
2264
    break;
2265

2266
  case BC_LEN:
53✔
2267
    if (tref_isstr(rc))
53✔
2268
      rc = emitir(IRTI(IR_FLOAD), rc, IRFL_STR_LEN);
5✔
2269
    else if (!LJ_52 && tref_istab(rc))
48✔
2270
      rc = lj_ir_call(J, IRCALL_lj_tab_len, rc);
46✔
2271
    else
2272
      rc = rec_mm_len(J, rc, rcv);
2✔
2273
    break;
2274

2275
  /* -- Arithmetic ops ---------------------------------------------------- */
2276

2277
  case BC_UNM:
25✔
2278
    if (tref_isnumber_str(rc)) {
25✔
2279
      rc = lj_opt_narrow_unm(J, rc, rcv);
22✔
2280
    } else {
2281
      ix.tab = rc;
3✔
2282
      copyTV(J->L, &ix.tabv, rcv);
3✔
2283
      rc = rec_mm_arith(J, &ix, MM_unm);
3✔
2284
    }
2285
    break;
2286

2287
  case BC_ADDNV: case BC_SUBNV: case BC_MULNV: case BC_DIVNV: case BC_MODNV:
133,307✔
2288
    /* Swap rb/rc and rbv/rcv. rav is temp. */
2289
    ix.tab = rc; ix.key = rc = rb; rb = ix.tab;
133,307✔
2290
    copyTV(J->L, rav, rbv);
133,307✔
2291
    copyTV(J->L, rbv, rcv);
133,307✔
2292
    copyTV(J->L, rcv, rav);
133,307✔
2293
    if (op == BC_MODNV)
133,307✔
2294
      goto recmod;
1✔
2295
    /* fallthrough */
2296
  case BC_ADDVN: case BC_SUBVN: case BC_MULVN: case BC_DIVVN:
2297
  case BC_ADDVV: case BC_SUBVV: case BC_MULVV: case BC_DIVVV: {
2298
    MMS mm = bcmode_mm(op);
374,981✔
2299
    if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
374,981✔
2300
      rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv,
334,225✔
2301
                               (int)mm - (int)MM_add + (int)IR_ADD);
334,225✔
2302
    else
2303
      rc = rec_mm_arith(J, &ix, mm);
40,756✔
2304
    break;
2305
    }
2306

2307
  case BC_MODVN: case BC_MODVV:
2308
  recmod:
73✔
2309
    if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
73✔
2310
      rc = lj_opt_narrow_mod(J, rb, rc, rbv, rcv);
68✔
2311
    else
2312
      rc = rec_mm_arith(J, &ix, MM_mod);
5✔
2313
    break;
2314

2315
  case BC_POW:
9,054✔
2316
    if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
9,054✔
2317
      rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv, IR_POW);
9,049✔
2318
    else
2319
      rc = rec_mm_arith(J, &ix, MM_pow);
5✔
2320
    break;
2321

2322
  /* -- Miscellaneous ops ------------------------------------------------- */
2323

2324
  case BC_CAT:
289✔
2325
    rc = rec_cat(J, rb, rc);
289✔
2326
    if (rc >= 0xffffff00)
289✔
2327
      lj_err_throw(J->L, -(int32_t)rc);  /* Propagate errors. */
×
2328
    break;
2329

2330
  /* -- Constant and move ops --------------------------------------------- */
2331

2332
  case BC_MOV:
651,293✔
2333
    /* Clear gap of method call to avoid resurrecting previous refs. */
2334
    if (ra > J->maxslot) {
651,293✔
2335
#if LJ_FR2
2336
      memset(J->base + J->maxslot, 0, (ra - J->maxslot) * sizeof(TRef));
496,533✔
2337
#else
2338
      J->base[ra-1] = 0;
2339
#endif
2340
    }
2341
    break;
2342
  case BC_KSTR: case BC_KNUM: case BC_KPRI:
2343
    break;
2344
  case BC_KSHORT:
329,755✔
2345
    rc = lj_ir_kint(J, (int32_t)(int16_t)rc);
329,755✔
2346
    break;
329,755✔
2347
  case BC_KNIL:
16✔
2348
    if (LJ_FR2 && ra > J->maxslot)
16✔
2349
      J->base[ra-1] = 0;
1✔
2350
    while (ra <= rc)
828✔
2351
      J->base[ra++] = TREF_NIL;
812✔
2352
    if (rc >= J->maxslot) J->maxslot = rc+1;
16✔
2353
    break;
2354
#if LJ_HASFFI
2355
  case BC_KCDATA:
59✔
2356
    rc = lj_ir_kgc(J, proto_kgc(J->pt, ~(ptrdiff_t)rc), IRT_CDATA);
59✔
2357
    break;
59✔
2358
#endif
2359

2360
  /* -- Upvalue and function ops ------------------------------------------ */
2361

2362
  case BC_UGET:
1,247,809✔
2363
    rc = rec_upvalue(J, rc, 0);
1,247,809✔
2364
    break;
1,247,809✔
2365
  case BC_USETV: case BC_USETS: case BC_USETN: case BC_USETP:
196✔
2366
    rec_upvalue(J, ra, rc);
196✔
2367
    break;
196✔
2368

2369
  /* -- Table ops --------------------------------------------------------- */
2370

2371
  case BC_GGET: case BC_GSET:
5,401✔
2372
    settabV(J->L, &ix.tabv, tabref(J->fn->l.env));
5,401✔
2373
    ix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), getcurrf(J), IRFL_FUNC_ENV);
5,401✔
2374
    ix.idxchain = LJ_MAX_IDXCHAIN;
5,401✔
2375
    rc = lj_record_idx(J, &ix);
5,401✔
2376
    break;
5,401✔
2377

2378
  case BC_TGETB: case BC_TSETB:
728✔
2379
    setintV(&ix.keyv, (int32_t)rc);
728✔
2380
    ix.key = lj_ir_kint(J, (int32_t)rc);
728✔
2381
    /* fallthrough */
2382
  case BC_TGETV: case BC_TGETS: case BC_TSETV: case BC_TSETS:
1,709,134✔
2383
    ix.idxchain = LJ_MAX_IDXCHAIN;
1,709,134✔
2384
    rc = lj_record_idx(J, &ix);
1,709,134✔
2385
    break;
1,709,134✔
2386
  case BC_TGETR: case BC_TSETR:
26✔
2387
    ix.idxchain = 0;
26✔
2388
    rc = lj_record_idx(J, &ix);
26✔
2389
    break;
26✔
2390

2391
  case BC_TSETM:
5✔
2392
    rec_tsetm(J, ra, (BCReg)(J->L->top - J->L->base), (int32_t)rcv->u32.lo);
5✔
2393
    J->maxslot = ra;  /* The table slot at ra-1 is the highest used slot. */
5✔
2394
    break;
5✔
2395

2396
  case BC_TNEW:
2397
    rc = rec_tnew(J, rc);
584✔
2398
    break;
584✔
2399
  case BC_TDUP:
640✔
2400
    rc = emitir(IRTG(IR_TDUP, IRT_TAB),
640✔
2401
                lj_ir_ktab(J, gco2tab(proto_kgc(J->pt, ~(ptrdiff_t)rc))), 0);
2402
#ifdef LUAJIT_ENABLE_TABLE_BUMP
2403
    J->rbchash[(rc & (RBCHASH_SLOTS-1))].ref = tref_ref(rc);
2404
    setmref(J->rbchash[(rc & (RBCHASH_SLOTS-1))].pc, pc);
2405
    setgcref(J->rbchash[(rc & (RBCHASH_SLOTS-1))].pt, obj2gco(J->pt));
2406
#endif
2407
    break;
640✔
2408

2409
  /* -- Calls and vararg handling ----------------------------------------- */
2410

2411
  case BC_ITERC:
113✔
2412
    J->base[ra] = getslot(J, ra-3);
113✔
2413
    J->base[ra+1+LJ_FR2] = getslot(J, ra-2);
113✔
2414
    J->base[ra+2+LJ_FR2] = getslot(J, ra-1);
113✔
2415
    { /* Do the actual copy now because lj_record_call needs the values. */
2416
      TValue *b = &J->L->base[ra];
113✔
2417
      copyTV(J->L, b, b-3);
113✔
2418
      copyTV(J->L, b+1+LJ_FR2, b-2);
113✔
2419
      copyTV(J->L, b+2+LJ_FR2, b-1);
113✔
2420
    }
2421
    lj_record_call(J, ra, (ptrdiff_t)rc-1);
113✔
2422
    break;
113✔
2423

2424
  /* L->top is set to L->base+ra+rc+NARGS-1+1. See lj_dispatch_ins(). */
2425
  case BC_CALLM:
142,234✔
2426
    rc = (BCReg)(J->L->top - J->L->base) - ra - LJ_FR2;
142,234✔
2427
    /* fallthrough */
2428
  case BC_CALL:
1,082,312✔
2429
    lj_record_call(J, ra, (ptrdiff_t)rc-1);
1,082,312✔
2430
    break;
1,082,312✔
2431

2432
  case BC_CALLMT:
10✔
2433
    rc = (BCReg)(J->L->top - J->L->base) - ra - LJ_FR2;
10✔
2434
    /* fallthrough */
2435
  case BC_CALLT:
126,008✔
2436
    lj_record_tailcall(J, ra, (ptrdiff_t)rc-1);
126,008✔
2437
    break;
126,008✔
2438

2439
  case BC_VARG:
44✔
2440
    rec_varg(J, ra, (ptrdiff_t)rb-1);
44✔
2441
    break;
44✔
2442

2443
  /* -- Returns ----------------------------------------------------------- */
2444

2445
  case BC_RETM:
33✔
2446
    /* L->top is set to L->base+ra+rc+NRESULTS-1, see lj_dispatch_ins(). */
2447
    rc = (BCReg)(J->L->top - J->L->base) - ra + 1;
33✔
2448
    /* fallthrough */
2449
  case BC_RET: case BC_RET0: case BC_RET1:
966,971✔
2450
#if LJ_HASPROFILE
2451
    rec_profile_ret(J);
966,971✔
2452
#endif
2453
    lj_record_ret(J, ra, (ptrdiff_t)rc-1);
966,971✔
2454
    break;
966,971✔
2455

2456
  /* -- Loops and branches ------------------------------------------------ */
2457

2458
  case BC_FORI:
161✔
2459
    if (rec_for(J, pc, 0) != LOOPEV_LEAVE)
161✔
2460
      J->loopref = J->cur.nins;
161✔
2461
    break;
2462
  case BC_JFORI:
103✔
2463
    lj_assertJ(bc_op(pc[(ptrdiff_t)rc-BCBIAS_J]) == BC_JFORL,
103✔
2464
               "JFORI does not point to JFORL");
2465
    if (rec_for(J, pc, 0) != LOOPEV_LEAVE)  /* Link to existing loop. */
103✔
2466
      lj_record_stop(J, LJ_TRLINK_ROOT, bc_d(pc[(ptrdiff_t)rc-BCBIAS_J]));
100✔
2467
    /* Continue tracing if the loop is not entered. */
2468
    break;
2469

2470
  case BC_FORL:
2,520✔
2471
    rec_loop_interp(J, pc, rec_for(J, pc+((ptrdiff_t)rc-BCBIAS_J), 1));
2,520✔
2472
    break;
2,520✔
2473
  case BC_ITERL:
47✔
2474
    rec_loop_interp(J, pc, rec_iterl(J, *pc));
47✔
2475
    break;
47✔
2476
  case BC_LOOP:
22,272✔
2477
    rec_loop_interp(J, pc, rec_loop(J, ra, 1));
22,272✔
2478
    break;
22,272✔
2479

2480
  case BC_JFORL:
377✔
2481
    rec_loop_jit(J, rc, rec_for(J, pc+bc_j(traceref(J, rc)->startins), 1));
377✔
2482
    break;
377✔
2483
  case BC_JITERL:
64✔
2484
    rec_loop_jit(J, rc, rec_iterl(J, traceref(J, rc)->startins));
64✔
2485
    break;
64✔
2486
  case BC_JLOOP:
12,856✔
2487
    rec_loop_jit(J, rc, rec_loop(J, ra,
25,712✔
2488
                                 !bc_isret(bc_op(traceref(J, rc)->startins))));
12,856✔
2489
    break;
12,856✔
2490

2491
  case BC_IFORL:
2✔
2492
  case BC_IITERL:
2493
  case BC_ILOOP:
2494
  case BC_IFUNCF:
2495
  case BC_IFUNCV:
2496
    lj_trace_err(J, LJ_TRERR_BLACKL);
2✔
2497
    break;
156,011✔
2498

2499
  case BC_JMP:
156,011✔
2500
    if (ra < J->maxslot)
156,011✔
2501
      J->maxslot = ra;  /* Shrink used slots. */
141,843✔
2502
    break;
2503

2504
  /* -- Function headers -------------------------------------------------- */
2505

2506
  case BC_FUNCF:
2507
    rec_func_lua(J);
158,754✔
2508
    break;
2509
  case BC_JFUNCF:
805,980✔
2510
    rec_func_jit(J, rc);
805,980✔
2511
    break;
805,980✔
2512

2513
  case BC_FUNCV:
106✔
2514
    rec_func_vararg(J);
106✔
2515
    rec_func_lua(J);
106✔
2516
    break;
2517
  case BC_JFUNCV:
2518
    /* Cannot happen. No hotcall counting for varag funcs. */
2519
    lj_assertJ(0, "unsupported vararg hotcall");
2520
    break;
2521

2522
  case BC_FUNCC:
151,378✔
2523
  case BC_FUNCCW:
2524
    lj_ffrecord_func(J);
151,378✔
2525
    break;
151,378✔
2526

2527
  default:
204,759✔
2528
    if (op >= BC__MAX) {
204,759✔
2529
      lj_ffrecord_func(J);
204,759✔
2530
      break;
204,759✔
2531
    }
2532
    /* fallthrough */
2533
  case BC_ITERN:
2534
  case BC_ISNEXT:
2535
  case BC_UCLO:
2536
  case BC_FNEW:
2537
    setintV(&J->errinfo, (int32_t)op);
68✔
2538
    lj_trace_err_info(J, LJ_TRERR_NYIBC);
68✔
2539
    break;
9,191,096✔
2540
  }
2541

2542
  /* rc == 0 if we have no result yet, e.g. pending __index metamethod call. */
2543
  if (bcmode_a(op) == BCMdst && rc) {
9,191,096✔
2544
    J->base[ra] = rc;
4,027,890✔
2545
    if (ra >= J->maxslot) {
4,027,890✔
2546
#if LJ_FR2
2547
      if (ra > J->maxslot) J->base[ra-1] = 0;
3,334,061✔
2548
#endif
2549
      J->maxslot = ra+1;
3,334,061✔
2550
    }
2551
  }
2552

2553
#undef rav
2554
#undef rbv
2555
#undef rcv
2556

2557
  /* Limit the number of recorded IR instructions and constants. */
2558
  if (J->cur.nins > REF_FIRST+(IRRef)J->param[JIT_P_maxrecord] ||
9,191,096✔
2559
      J->cur.nk < REF_BIAS-(IRRef)J->param[JIT_P_maxirconst])
9,191,096✔
2560
    lj_trace_err(J, LJ_TRERR_TRACEOV);
2✔
2561
}
2562

2563
/* -- Recording setup ----------------------------------------------------- */
2564

2565
/* Setup recording for a root trace started by a hot loop. */
2566
static const BCIns *rec_setup_root(jit_State *J)
6,002✔
2567
{
2568
  /* Determine the next PC and the bytecode range for the loop. */
2569
  const BCIns *pcj, *pc = J->pc;
6,002✔
2570
  BCIns ins = *pc;
6,002✔
2571
  BCReg ra = bc_a(ins);
6,002✔
2572
  switch (bc_op(ins)) {
6,002✔
2573
  case BC_FORL:
2,487✔
2574
    J->bc_extent = (MSize)(-bc_j(ins))*sizeof(BCIns);
2,487✔
2575
    pc += 1+bc_j(ins);
2,487✔
2576
    J->bc_min = pc;
2,487✔
2577
    break;
2,487✔
2578
  case BC_ITERL:
37✔
2579
    lj_assertJ(bc_op(pc[-1]) == BC_ITERC, "no ITERC before ITERL");
37✔
2580
    J->maxslot = ra + bc_b(pc[-1]) - 1;
37✔
2581
    J->bc_extent = (MSize)(-bc_j(ins))*sizeof(BCIns);
37✔
2582
    pc += 1+bc_j(ins);
37✔
2583
    lj_assertJ(bc_op(pc[-1]) == BC_JMP, "ITERL does not point to JMP+1");
37✔
2584
    J->bc_min = pc;
37✔
2585
    break;
37✔
2586
  case BC_LOOP:
1,250✔
2587
    /* Only check BC range for real loops, but not for "repeat until true". */
2588
    pcj = pc + bc_j(ins);
1,250✔
2589
    ins = *pcj;
1,250✔
2590
    if (bc_op(ins) == BC_JMP && bc_j(ins) < 0) {
1,250✔
2591
      J->bc_min = pcj+1 + bc_j(ins);
1,246✔
2592
      J->bc_extent = (MSize)(-bc_j(ins))*sizeof(BCIns);
1,246✔
2593
    }
2594
    J->maxslot = ra;
1,250✔
2595
    pc++;
1,250✔
2596
    break;
1,250✔
2597
  case BC_RET:
1✔
2598
  case BC_RET0:
2599
  case BC_RET1:
2600
    /* No bytecode range check for down-recursive root traces. */
2601
    J->maxslot = ra + bc_d(ins) - 1;
1✔
2602
    break;
1✔
2603
  case BC_FUNCF:
2,133✔
2604
    /* No bytecode range check for root traces started by a hot call. */
2605
    J->maxslot = J->pt->numparams;
2,133✔
2606
    pc++;
2,133✔
2607
    break;
2,133✔
2608
  case BC_CALLM:
94✔
2609
  case BC_CALL:
2610
  case BC_ITERC:
2611
    /* No bytecode range check for stitched traces. */
2612
    pc++;
94✔
2613
    break;
94✔
2614
  default:
2615
    lj_assertJ(0, "bad root trace start bytecode %d", bc_op(ins));
2616
    break;
2617
  }
2618
  return pc;
6,002✔
2619
}
2620

2621
/* Setup for recording a new trace. */
2622
void lj_record_setup(jit_State *J)
24,231✔
2623
{
2624
  uint32_t i;
24,231✔
2625

2626
  /* Initialize state related to current trace. */
2627
  memset(J->slot, 0, sizeof(J->slot));
24,231✔
2628
  memset(J->chain, 0, sizeof(J->chain));
24,231✔
2629
#ifdef LUAJIT_ENABLE_TABLE_BUMP
2630
  memset(J->rbchash, 0, sizeof(J->rbchash));
2631
#endif
2632
  memset(J->bpropcache, 0, sizeof(J->bpropcache));
24,231✔
2633
  J->scev.idx = REF_NIL;
24,231✔
2634
  setmref(J->scev.pc, NULL);
24,231✔
2635

2636
  J->baseslot = 1+LJ_FR2;  /* Invoking function is at base[-1-LJ_FR2]. */
24,231✔
2637
  J->base = J->slot + J->baseslot;
24,231✔
2638
  J->maxslot = 0;
24,231✔
2639
  J->framedepth = 0;
24,231✔
2640
  J->retdepth = 0;
24,231✔
2641

2642
  J->instunroll = J->param[JIT_P_instunroll];
24,231✔
2643
  J->loopunroll = J->param[JIT_P_loopunroll];
24,231✔
2644
  J->tailcalled = 0;
24,231✔
2645
  J->loopref = 0;
24,231✔
2646

2647
  J->bc_min = NULL;  /* Means no limit. */
24,231✔
2648
  J->bc_extent = ~(MSize)0;
24,231✔
2649

2650
  /* Emit instructions for fixed references. Also triggers initial IR alloc. */
2651
  emitir_raw(IRT(IR_BASE, IRT_PGC), J->parent, J->exitno);
24,231✔
2652
  for (i = 0; i <= 2; i++) {
121,155✔
2653
    IRIns *ir = IR(REF_NIL-i);
72,693✔
2654
    ir->i = 0;
72,693✔
2655
    ir->t.irt = (uint8_t)(IRT_NIL+i);
72,693✔
2656
    ir->o = IR_KPRI;
72,693✔
2657
    ir->prev = 0;
72,693✔
2658
  }
2659
  J->cur.nk = REF_TRUE;
24,231✔
2660

2661
  J->startpc = J->pc;
24,231✔
2662
  setmref(J->cur.startpc, J->pc);
24,231✔
2663
  if (J->parent) {  /* Side trace. */
24,231✔
2664
    GCtrace *T = traceref(J, J->parent);
18,229✔
2665
    TraceNo root = T->root ? T->root : J->parent;
18,229✔
2666
    J->cur.root = (uint16_t)root;
18,229✔
2667
    J->cur.startins = BCINS_AD(BC_JMP, 0, 0);
18,229✔
2668
    /* Check whether we could at least potentially form an extra loop. */
2669
    if (J->exitno == 0 && T->snap[0].nent == 0) {
18,229✔
2670
      /* We can narrow a FORL for some side traces, too. */
2671
      if (J->pc > proto_bc(J->pt) && bc_op(J->pc[-1]) == BC_JFORI &&
2,561✔
2672
          bc_d(J->pc[bc_j(J->pc[-1])-1]) == root) {
191✔
2673
        lj_snap_add(J);
191✔
2674
        rec_for_loop(J, J->pc-1, &J->scev, 1);
191✔
2675
        goto sidecheck;
191✔
2676
      }
2677
    } else {
2678
      J->startpc = NULL;  /* Prevent forming an extra loop. */
15,668✔
2679
    }
2680
    lj_snap_replay(J, T);
18,038✔
2681
  sidecheck:
18,229✔
2682
    if (traceref(J, J->cur.root)->nchild >= J->param[JIT_P_maxside] ||
18,229✔
2683
        T->snap[J->exitno].count >= J->param[JIT_P_hotexit] +
18,229✔
2684
                                    J->param[JIT_P_tryside]) {
18,229✔
2685
      lj_record_stop(J, LJ_TRLINK_INTERP, 0);
396✔
2686
    }
2687
  } else {  /* Root trace. */
2688
    J->cur.root = 0;
6,002✔
2689
    J->cur.startins = *J->pc;
6,002✔
2690
    J->pc = rec_setup_root(J);
6,002✔
2691
    /* Note: the loop instruction itself is recorded at the end and not
2692
    ** at the start! So snapshot #0 needs to point to the *next* instruction.
2693
    */
2694
    lj_snap_add(J);
6,002✔
2695
    if (bc_op(J->cur.startins) == BC_FORL)
6,002✔
2696
      rec_for_loop(J, J->pc-1, &J->scev, 1);
2,487✔
2697
    else if (bc_op(J->cur.startins) == BC_ITERC)
3,515✔
2698
      J->startpc = NULL;
3✔
2699
    if (1 + J->pt->framesize >= LJ_MAX_JSLOTS)
6,002✔
2700
      lj_trace_err(J, LJ_TRERR_STACKOV);
1✔
2701
  }
2702
#if LJ_HASPROFILE
2703
  J->prev_pt = NULL;
24,230✔
2704
  J->prev_line = -1;
24,230✔
2705
#endif
2706
#ifdef LUAJIT_ENABLE_CHECKHOOK
2707
  /* Regularly check for instruction/line hooks from compiled code and
2708
  ** exit to the interpreter if the hooks are set.
2709
  **
2710
  ** This is a compile-time option and disabled by default, since the
2711
  ** hook checks may be quite expensive in tight loops.
2712
  **
2713
  ** Note this is only useful if hooks are *not* set most of the time.
2714
  ** Use this only if you want to *asynchronously* interrupt the execution.
2715
  **
2716
  ** You can set the instruction hook via lua_sethook() with a count of 1
2717
  ** from a signal handler or another native thread. Please have a look
2718
  ** at the first few functions in luajit.c for an example (Ctrl-C handler).
2719
  */
2720
  {
2721
    TRef tr = emitir(IRT(IR_XLOAD, IRT_U8),
2722
                     lj_ir_kptr(J, &J2G(J)->hookmask), IRXLOAD_VOLATILE);
2723
    tr = emitir(IRTI(IR_BAND), tr, lj_ir_kint(J, (LUA_MASKLINE|LUA_MASKCOUNT)));
2724
    emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, 0));
2725
  }
2726
#endif
2727
}
24,230✔
2728

2729
#undef IR
2730
#undef emitir_raw
2731
#undef emitir
2732

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