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

tarantool / luajit / 30088298194

24 Jul 2026 11:03AM UTC coverage: 93.169% (-0.1%) from 93.267%
30088298194

push

github

Buristan
ARM: Make hard-float tobit conversions match JIT backend behavior.

Reported by Peter Cawley.

(cherry picked from commit 32a683d22)

On the ARM architecture, the `tobit()` function incorrectly truncates
instead of rounding to the nearest integer. This leads to inconsistency
between various VMs (comparing to x86/x64, for example) and between the
ARM VM and JIT.

This patch uses an addition of 2^52 + 2^51 constant to the given
argument to convert it to the nearest integer value. After reading the
lowest 32 bits of the register, we get the expected result.

The test is the same as for the previous commit.

Sergey Kaplun:
* added the description for the problem

Part of tarantool/tarantool#12880

5732 of 6058 branches covered (94.62%)

Branch coverage included in aggregate %.

21859 of 23556 relevant lines covered (92.8%)

3972253.7 hits per line

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

96.66
/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)
78,523✔
188
{
189
  /* Caller may set IRT_GUARD in t. */
190
  TRef ref = emitir_raw(IRT(IR_SLOAD, t), (int32_t)J->baseslot+slot, mode);
157,046✔
191
  J->base[slot] = ref;
78,523✔
192
  return ref;
78,523✔
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)
168,014✔
197
{
198
  IRType t = itype2irt(&J->L->base[slot]);
168,014✔
199
  TRef ref = emitir_raw(IRTG(IR_SLOAD, t), (int32_t)J->baseslot+slot,
168,014✔
200
                        IRSLOAD_TYPECHECK);
201
  if (irtype_ispri(t)) ref = TREF_PRI(t);  /* Canonicalize primitive refs. */
168,014✔
202
  J->base[slot] = ref;
168,014✔
203
  return ref;
168,014✔
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)
709,430✔
211
{
212
  if (J->base[-1-LJ_FR2])
709,430✔
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");
73,389✔
216
  return sloadt(J, -1-LJ_FR2, IRT_FUNC, IRSLOAD_READONLY);
73,389✔
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)
344,914✔
226
{
227
  int diff = !lj_obj_equal(av, bv);
344,914✔
228
  if (!tref_isk2(a, b)) {  /* Shortcut, also handles primitives. */
344,914✔
229
    IRType ta = tref_isinteger(a) ? IRT_INT : tref_type(a);
344,914✔
230
    IRType tb = tref_isinteger(b) ? IRT_INT : tref_type(b);
344,914✔
231
    if (ta != tb) {
344,914✔
232
      /* Widen mixed number/int comparisons to number/number comparison. */
233
      if (ta == IRT_INT && tb == IRT_NUM) {
319,085✔
234
        a = emitir(IRTN(IR_CONV), a, IRCONV_NUM_INT);
4✔
235
        ta = IRT_NUM;
4✔
236
      } else if (ta == IRT_NUM && tb == IRT_INT) {
319,081✔
237
        b = emitir(IRTN(IR_CONV), b, IRCONV_NUM_INT);
187✔
238
      } else {
239
        return 2;  /* Two different types are never equal. */
240
      }
241
    }
242
    emitir(IRTG(diff ? IR_NE : IR_EQ, ta), a, b);
35,593✔
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)
649,959✔
249
{
250
  if (tvisgcv(o))
649,959✔
251
    return lj_ir_kgc(J, gcV(o), itype2irt(o));
585,708✔
252
  else if (tvisint(o))
64,251✔
253
    return lj_ir_kint(J, intV(o));
254
  else if (tvisnum(o))
64,251✔
255
    return lj_ir_knumint(J, numV(o));
64,251✔
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)
11,030✔
273
{
274
  BCReg s;
11,030✔
275
  if (LJ_DUALNUM) return;
11,030✔
276
  for (s = J->baseslot+J->maxslot-1; s >= 1; s--) {
175,179✔
277
    TRef tr = J->slot[s];
164,150✔
278
    if (tref_isinteger(tr)) {
164,150✔
279
      IRIns *ir = IR(tref_ref(tr));
19,349✔
280
      if (!(ir->o == IR_SLOAD && (ir->op2 & IRSLOAD_READONLY)))
19,349✔
281
        J->slot[s] = emitir(IRTN(IR_CONV), tr, IRCONV_NUM_INT);
19,270✔
282
    }
283
  }
284
}
285

286
/* Stop recording. */
287
void lj_record_stop(jit_State *J, TraceLink linktype, TraceNo lnk)
14,738✔
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);
14,738✔
294
  J->cur.linktype = (uint8_t)linktype;
14,738✔
295
  J->cur.link = (uint16_t)lnk;
14,738✔
296
  /* Looping back at the same stack level? */
297
  if (lnk == J->cur.traceno && J->framedepth + J->retdepth == 0) {
14,738✔
298
    if ((J->flags & JIT_F_OPT_LOOP))  /* Shall we try to create a loop? */
4,423✔
299
      goto nocanon;  /* Do not canonicalize or we lose the narrowing. */
3,708✔
300
    if (J->cur.root)  /* Otherwise ensure we always link to the root trace. */
715✔
301
      J->cur.link = J->cur.root;
1✔
302
  }
303
  canonicalize_slots(J);
11,030✔
304
nocanon:
14,737✔
305
  /* Note: all loop ops must set J->pc to the following instruction! */
306
  lj_snap_add(J);  /* Add loop snapshot. */
14,737✔
307
  J->needsnap = 0;
14,735✔
308
  J->mergesnap = 1;  /* In case recording continues. */
14,735✔
309
}
14,735✔
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)
15,447✔
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);
15,447✔
320
  for (pc = endpc-1; pc > startpc; pc--) {
31,641✔
321
    BCIns ins = *pc;
31,641✔
322
    BCOp op = bc_op(ins);
31,641✔
323
    /* First try to find the last instruction that stores to this slot. */
324
    if (bcmode_a(op) == BCMbase && bc_a(ins) <= slot) {
31,641✔
325
      return 0;  /* Multiple results, e.g. from a CALL or KNIL. */
326
    } else if (bcmode_a(op) == BCMdst && bc_a(ins) == slot) {
31,620✔
327
      if (op == BC_KSHORT || op == BC_KNUM) {  /* Found const. initializer. */
15,426✔
328
        /* Now try to verify there's no forward jump across it. */
329
        const BCIns *kpc = pc;
516,842✔
330
        for (; pc > startpc; pc--)
516,842✔
331
          if (bc_op(*pc) == BC_JMP) {
501,800✔
332
            const BCIns *target = pc+bc_j(*pc)+1;
43,405✔
333
            if (target > kpc && target <= endpc)
43,405✔
334
              return 0;  /* Conditional assignment. */
335
          }
336
        if (op == BC_KSHORT) {
15,042✔
337
          int32_t k = (int32_t)(int16_t)bc_d(ins);
14,935✔
338
          return t == IRT_INT ? lj_ir_kint(J, k) : lj_ir_knum(J, (lua_Number)k);
14,935✔
339
        } else {
340
          cTValue *tv = proto_knumtv(J->pt, bc_d(ins));
107✔
341
          if (t == IRT_INT) {
107✔
342
            int32_t k = numberVint(tv);
83✔
343
            if (tvisint(tv) || numV(tv) == (lua_Number)k)  /* -0 is ok here. */
83✔
344
              return lj_ir_kint(J, k);
79✔
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)
5,134✔
359
{
360
  int conv = (tvisint(&J->L->base[slot]) != (t==IRT_INT)) ? IRSLOAD_CONVERT : 0;
5,134✔
361
  return sloadt(J, (int32_t)slot,
15,402✔
362
                t + (((mode & IRSLOAD_TYPECHECK) ||
5,134✔
363
                      (conv && t == IRT_INT && !(mode >> 16))) ?
5,134✔
364
                     IRT_GUARD : 0),
5,134✔
365
                mode + conv);
366
}
367

368
/* Convert FORI argument to expected target type. */
369
static TRef fori_conv(jit_State *J, TRef tr, IRType t)
2,490✔
370
{
371
  if (t == IRT_INT) {
2,490✔
372
    if (!tref_isinteger(tr))
1,778✔
373
      return emitir(IRTGI(IR_CONV), tr, IRCONV_INT_NUM|IRCONV_CHECK);
10✔
374
  } else {
375
    if (!tref_isnum(tr))
712✔
376
      return emitir(IRTN(IR_CONV), tr, IRCONV_NUM_INT);
407✔
377
  }
378
  return tr;
379
}
380

381
/* Peek before FORI to find a const initializer. Otherwise load from slot. */
382
static TRef fori_arg(jit_State *J, const BCIns *fori, BCReg slot,
11,186✔
383
                     IRType t, int mode)
384
{
385
  TRef tr = J->base[slot];
11,186✔
386
  if (tr) {
11,186✔
387
    tr = fori_conv(J, tr, t);
1,332✔
388
  } else {
389
    tr = find_kinit(J, fori, slot, t);
9,854✔
390
    if (!tr)
9,854✔
391
      tr = fori_load(J, slot, t, mode);
317✔
392
  }
393
  return tr;
11,186✔
394
}
395

396
/* Return the direction of the FOR loop iterator.
397
** It's important to exactly reproduce the semantics of the interpreter.
398
*/
399
static int rec_for_direction(cTValue *o)
11,612✔
400
{
401
  return (tvisint(o) ? intV(o) : (int32_t)o->u32.hi) >= 0;
11,612✔
402
}
403

404
/* Simulate the runtime behavior of the FOR loop iterator. */
405
static LoopEvent rec_for_iter(IROp *op, cTValue *o, int isforl)
5,633✔
406
{
407
  lua_Number stopv = numberVnum(&o[FORL_STOP]);
5,633✔
408
  lua_Number idxv = numberVnum(&o[FORL_IDX]);
5,633✔
409
  lua_Number stepv = numberVnum(&o[FORL_STEP]);
5,633✔
410
  if (isforl)
5,633✔
411
    idxv += stepv;
5,247✔
412
  if (rec_for_direction(&o[FORL_STEP])) {
5,633✔
413
    if (idxv <= stopv) {
5,569✔
414
      *op = IR_LE;
5,395✔
415
      return idxv + 2*stepv > stopv ? LOOPEV_ENTERLO : LOOPEV_ENTER;
5,395✔
416
    }
417
    *op = IR_GT; return LOOPEV_LEAVE;
174✔
418
  } else {
419
    if (stopv <= idxv) {
64✔
420
      *op = IR_GE;
63✔
421
      return idxv + 2*stepv < stopv ? LOOPEV_ENTERLO : LOOPEV_ENTER;
63✔
422
    }
423
    *op = IR_LT; return LOOPEV_LEAVE;
1✔
424
  }
425
}
426

427
/* Record checks for FOR loop overflow and step direction. */
428
static void rec_for_check(jit_State *J, IRType t, int dir,
5,979✔
429
                          TRef stop, TRef step, int init)
430
{
431
  if (!tref_isk(step)) {
5,979✔
432
    /* Non-constant step: need a guard for the direction. */
433
    TRef zero = (t == IRT_INT) ? lj_ir_kint(J, 0) : lj_ir_knum_zero(J);
270✔
434
    emitir(IRTG(dir ? IR_GE : IR_LT, t), step, zero);
271✔
435
    /* Add hoistable overflow checks for a narrowed FORL index. */
436
    if (init && t == IRT_INT) {
270✔
437
      if (tref_isk(stop)) {
9✔
438
        /* Constant stop: optimize check away or to a range check for step. */
439
        int32_t k = IR(tref_ref(stop))->i;
2✔
440
        if (dir) {
2✔
441
          if (k > 0)
2✔
442
            emitir(IRTGI(IR_LE), step, lj_ir_kint(J, (int32_t)0x7fffffff-k));
2✔
443
        } else {
444
          if (k < 0)
×
445
            emitir(IRTGI(IR_GE), step, lj_ir_kint(J, (int32_t)0x80000000-k));
×
446
        }
447
      } else {
448
        /* Stop+step variable: need full overflow check. */
449
        TRef tr = emitir(IRTGI(IR_ADDOV), step, stop);
7✔
450
        emitir(IRTI(IR_USE), tr, 0);  /* ADDOV is weak. Avoid dead result. */
7✔
451
      }
452
    }
453
  } else if (init && t == IRT_INT && !tref_isk(stop)) {
5,709✔
454
    /* Constant step: optimize overflow check to a range check for stop. */
455
    int32_t k = IR(tref_ref(step))->i;
284✔
456
    k = (int32_t)(dir ? 0x7fffffff : 0x80000000) - k;
284✔
457
    emitir(IRTGI(dir ? IR_LE : IR_GE), stop, lj_ir_kint(J, k));
315✔
458
  }
459
}
5,979✔
460

461
/* Record a FORL instruction. */
462
static void rec_for_loop(jit_State *J, const BCIns *fori, ScEvEntry *scev,
5,593✔
463
                         int init)
464
{
465
  BCReg ra = bc_a(*fori);
5,593✔
466
  cTValue *tv = &J->L->base[ra];
5,593✔
467
  TRef idx = J->base[ra+FORL_IDX];
5,593✔
468
  IRType t = idx ? tref_type(idx) :
5,593✔
469
             (init || LJ_DUALNUM) ? lj_opt_narrow_forl(J, tv) : IRT_NUM;
4,817✔
470
  int mode = IRSLOAD_INHERIT +
5,593✔
471
    ((!LJ_DUALNUM || tvisint(tv) == (t == IRT_INT)) ? IRSLOAD_READONLY : 0);
472
  TRef stop = fori_arg(J, fori, ra+FORL_STOP, t, mode);
5,593✔
473
  TRef step = fori_arg(J, fori, ra+FORL_STEP, t, mode);
5,593✔
474
  int tc, dir = rec_for_direction(&tv[FORL_STEP]);
5,593✔
475
  lj_assertJ(bc_op(*fori) == BC_FORI || bc_op(*fori) == BC_JFORI,
5,593✔
476
             "bad bytecode %d instead of FORI/JFORI", bc_op(*fori));
477
  scev->t.irt = t;
5,593✔
478
  scev->dir = dir;
5,593✔
479
  scev->stop = tref_ref(stop);
5,593✔
480
  scev->step = tref_ref(step);
5,593✔
481
  rec_for_check(J, t, dir, stop, step, init);
5,593✔
482
  scev->start = tref_ref(find_kinit(J, fori, ra+FORL_IDX, IRT_INT));
5,593✔
483
  tc = (LJ_DUALNUM &&
5,593✔
484
        !(scev->start && irref_isk(scev->stop) && irref_isk(scev->step) &&
485
          tvisint(&tv[FORL_IDX]) == (t == IRT_INT))) ?
486
        IRSLOAD_TYPECHECK : 0;
487
  if (tc) {
5,593✔
488
    J->base[ra+FORL_STOP] = stop;
489
    J->base[ra+FORL_STEP] = step;
490
  }
491
  if (!idx)
5,593✔
492
    idx = fori_load(J, ra+FORL_IDX, t,
4,817✔
493
                    IRSLOAD_INHERIT + tc + (J->scev.start << 16));
4,817✔
494
  if (!init)
5,593✔
495
    J->base[ra+FORL_IDX] = idx = emitir(IRT(IR_ADD, t), idx, step);
914✔
496
  J->base[ra+FORL_EXT] = idx;
5,593✔
497
  scev->idx = tref_ref(idx);
5,593✔
498
  setmref(scev->pc, fori);
5,593✔
499
  J->maxslot = ra+FORL_EXT+1;
5,593✔
500
}
5,593✔
501

502
/* Record FORL/JFORL or FORI/JFORI. */
503
static LoopEvent rec_for(jit_State *J, const BCIns *fori, int isforl)
5,640✔
504
{
505
  BCReg ra = bc_a(*fori);
5,640✔
506
  TValue *tv = &J->L->base[ra];
5,640✔
507
  TRef *tr = &J->base[ra];
5,640✔
508
  IROp op;
5,640✔
509
  LoopEvent ev;
5,640✔
510
  TRef stop;
5,640✔
511
  IRType t;
5,640✔
512
  /* Avoid semantic mismatches and always failing guards. */
513
  if ((tvisnum(&tv[FORL_IDX]) && tvisnan(&tv[FORL_IDX])) ||
5,640✔
514
      (tvisnum(&tv[FORL_STOP]) && tvisnan(&tv[FORL_STOP])) ||
5,638✔
515
      (tvisnum(&tv[FORL_STEP]) && tvisnan(&tv[FORL_STEP])) ||
5,637✔
516
      tvismzero(&tv[FORL_STEP]))
517
    lj_trace_err(J, LJ_TRERR_GFAIL);
6✔
518
  if (isforl) {  /* Handle FORL/JFORL opcodes. */
5,634✔
519
    TRef idx = tr[FORL_IDX];
5,247✔
520
    if (mref(J->scev.pc, const BCIns) == fori && tref_ref(idx) == J->scev.idx) {
5,247✔
521
      t = J->scev.t.irt;
4,333✔
522
      stop = J->scev.stop;
4,333✔
523
      idx = emitir(IRT(IR_ADD, t), idx, J->scev.step);
4,333✔
524
      tr[FORL_EXT] = tr[FORL_IDX] = idx;
4,333✔
525
    } else {
526
      ScEvEntry scev;
914✔
527
      rec_for_loop(J, fori, &scev, 0);
914✔
528
      t = scev.t.irt;
914✔
529
      stop = scev.stop;
914✔
530
    }
531
  } else {  /* Handle FORI/JFORI opcodes. */
532
    BCReg i;
387✔
533
    lj_meta_for(J->L, tv);
387✔
534
    t = (LJ_DUALNUM || tref_isint(tr[FORL_IDX])) ? lj_opt_narrow_forl(J, tv) :
386✔
535
                                                   IRT_NUM;
536
    for (i = FORL_IDX; i <= FORL_STEP; i++) {
1,544✔
537
      if (!tr[i]) sload(J, ra+i);
1,158✔
538
      lj_assertJ(tref_isnumber_str(tr[i]), "bad FORI argument type");
1,158✔
539
      if (tref_isstr(tr[i]))
1,158✔
540
        tr[i] = emitir(IRTG(IR_STRTO, IRT_NUM), tr[i], 0);
1✔
541
      tr[i] = fori_conv(J, tr[i], t);
1,158✔
542
    }
543
    tr[FORL_EXT] = tr[FORL_IDX];
386✔
544
    stop = tr[FORL_STOP];
386✔
545
    rec_for_check(J, t, rec_for_direction(&tv[FORL_STEP]),
386✔
546
                  stop, tr[FORL_STEP], 1);
547
  }
548

549
  ev = rec_for_iter(&op, tv, isforl);
5,633✔
550
  if (ev == LOOPEV_LEAVE) {
5,633✔
551
    J->maxslot = ra+FORL_EXT+1;
175✔
552
    J->pc = fori+1;
175✔
553
  } else {
554
    J->maxslot = ra;
5,458✔
555
    J->pc = fori+bc_j(*fori)+1;
5,458✔
556
  }
557
  lj_snap_add(J);
5,633✔
558

559
  emitir(IRTG(op, t), tr[FORL_IDX], stop);
5,633✔
560

561
  if (ev == LOOPEV_LEAVE) {
5,633✔
562
    J->maxslot = ra;
175✔
563
    J->pc = fori+bc_j(*fori)+1;
175✔
564
  } else {
565
    J->maxslot = ra+FORL_EXT+1;
5,458✔
566
    J->pc = fori+1;
5,458✔
567
  }
568
  J->needsnap = 1;
5,633✔
569
  return ev;
5,633✔
570
}
571

572
/* Record ITERL/JITERL. */
573
static LoopEvent rec_iterl(jit_State *J, const BCIns iterins)
120✔
574
{
575
  BCReg ra = bc_a(iterins);
120✔
576
  if (!tref_isnil(getslot(J, ra))) {  /* Looping back? */
120✔
577
    J->base[ra-1] = J->base[ra];  /* Copy result of ITERC to control var. */
93✔
578
    J->maxslot = ra-1+bc_b(J->pc[-1]);
93✔
579
    J->pc += bc_j(iterins)+1;
93✔
580
    return LOOPEV_ENTER;
93✔
581
  } else {
582
    J->maxslot = ra-3;
27✔
583
    J->pc++;
27✔
584
    return LOOPEV_LEAVE;
27✔
585
  }
586
}
587

588
/* Record LOOP/JLOOP. Now, that was easy. */
589
static LoopEvent rec_loop(jit_State *J, BCReg ra, int skip)
24,104✔
590
{
591
  if (ra < J->maxslot) J->maxslot = ra;
15,116✔
592
  J->pc += skip;
24,104✔
593
  return LOOPEV_ENTER;
24,104✔
594
}
595

596
/* Check if a loop repeatedly failed to trace because it didn't loop back. */
597
static int innerloopleft(jit_State *J, const BCIns *pc)
598
{
599
  ptrdiff_t i;
600
  for (i = 0; i < PENALTY_SLOTS; i++)
11,302✔
601
    if (mref(J->penalty[i].pc, const BCIns) == pc) {
11,133✔
602
      if ((J->penalty[i].reason == LJ_TRERR_LLEAVE ||
27✔
603
           J->penalty[i].reason == LJ_TRERR_LINNER) &&
27✔
604
          J->penalty[i].val >= 2*PENALTY_MIN)
27✔
605
        return 1;
606
      break;
607
    }
608
  return 0;
609
}
610

611
/* Handle the case when an interpreted loop op is hit. */
612
static void rec_loop_interp(jit_State *J, const BCIns *pc, LoopEvent ev)
22,676✔
613
{
614
  if (J->parent == 0 && J->exitno == 0) {
22,676✔
615
    if (pc == J->startpc && J->framedepth + J->retdepth == 0) {
4,477✔
616
      /* Same loop? */
617
      if (ev == LOOPEV_LEAVE)  /* Must loop back to form a root trace. */
4,274✔
618
        lj_trace_err(J, LJ_TRERR_LLEAVE);
37✔
619
      lj_record_stop(J, LJ_TRLINK_LOOP, J->cur.traceno);  /* Looping trace. */
4,237✔
620
    } else if (ev != LOOPEV_LEAVE) {  /* Entering inner loop? */
203✔
621
      /* It's usually better to abort here and wait until the inner loop
622
      ** is traced. But if the inner loop repeatedly didn't loop back,
623
      ** this indicates a low trip count. In this case try unrolling
624
      ** an inner loop even in a root trace. But it's better to be a bit
625
      ** more conservative here and only do it for very short loops.
626
      */
627
      if (bc_j(*pc) != -1 && !innerloopleft(J, pc))
197✔
628
        lj_trace_err(J, LJ_TRERR_LINNER);  /* Root trace hit an inner loop. */
175✔
629
      if ((ev != LOOPEV_ENTERLO &&
22✔
630
           J->loopref && J->cur.nins - J->loopref > 24) || --J->loopunroll < 0)
22✔
631
        lj_trace_err(J, LJ_TRERR_LUNROLL);  /* Limit loop unrolling. */
3✔
632
      J->loopref = J->cur.nins;
19✔
633
    }
634
  } else if (ev != LOOPEV_LEAVE) {  /* Side trace enters an inner loop. */
18,199✔
635
    J->loopref = J->cur.nins;
18,068✔
636
    if (--J->loopunroll < 0)
18,068✔
637
      lj_trace_err(J, LJ_TRERR_LUNROLL);  /* Limit loop unrolling. */
×
638
  }  /* Side trace continues across a loop that's left or not entered. */
639
}
22,461✔
640

641
/* Handle the case when an already compiled loop op is hit. */
642
static void rec_loop_jit(jit_State *J, TraceNo lnk, LoopEvent ev)
6,795✔
643
{
644
  if (J->parent == 0 && J->exitno == 0) {  /* Root trace hit an inner loop. */
6,795✔
645
    /* Better let the inner loop spawn a side trace back here. */
646
    lj_trace_err(J, LJ_TRERR_LINNER);
304✔
647
  } else if (ev != LOOPEV_LEAVE) {  /* Side trace enters a compiled loop. */
6,491✔
648
    J->instunroll = 0;  /* Cannot continue across a compiled loop op. */
6,465✔
649
    if (J->pc == J->startpc && J->framedepth + J->retdepth == 0)
6,465✔
650
      lj_record_stop(J, LJ_TRLINK_LOOP, J->cur.traceno);  /* Form extra loop. */
181✔
651
    else
652
      lj_record_stop(J, LJ_TRLINK_ROOT, lnk);  /* Link to the loop. */
6,284✔
653
  }  /* Side trace continues across a loop that's left or not entered. */
654
}
6,491✔
655

656
/* -- Record profiler hook checks ----------------------------------------- */
657

658
#if LJ_HASPROFILE
659

660
/* Need to insert profiler hook check? */
661
static int rec_profile_need(jit_State *J, GCproto *pt, const BCIns *pc)
7✔
662
{
663
  GCproto *ppt;
7✔
664
  lj_assertJ(J->prof_mode == 'f' || J->prof_mode == 'l',
7✔
665
             "bad profiler mode %c", J->prof_mode);
666
  if (!pt)
7✔
667
    return 0;
668
  ppt = J->prev_pt;
6✔
669
  J->prev_pt = pt;
6✔
670
  if (pt != ppt && ppt) {
6✔
671
    J->prev_line = -1;
×
672
    return 1;
×
673
  }
674
  if (J->prof_mode == 'l') {
6✔
675
    BCLine line = lj_debug_line(pt, proto_bcpos(pt, pc));
4✔
676
    BCLine pline = J->prev_line;
4✔
677
    J->prev_line = line;
4✔
678
    if (pline != line)
4✔
679
      return 1;
1✔
680
  }
681
  return 0;
682
}
683

684
static void rec_profile_ins(jit_State *J, const BCIns *pc)
5,200,646✔
685
{
686
  if (J->prof_mode && rec_profile_need(J, J->pt, pc)) {
5,200,646✔
687
    emitir(IRTG(IR_PROF, IRT_NIL), 0, 0);
1✔
688
    lj_snap_add(J);
1✔
689
  }
690
}
5,200,646✔
691

692
static void rec_profile_ret(jit_State *J)
508,812✔
693
{
694
  if (J->prof_mode == 'f') {
508,812✔
695
    emitir(IRTG(IR_PROF, IRT_NIL), 0, 0);
×
696
    J->prev_pt = NULL;
×
697
    lj_snap_add(J);
×
698
  }
699
}
508,812✔
700

701
#endif
702

703
/* -- Record calls and returns -------------------------------------------- */
704

705
/* Specialize to the runtime value of the called function or its prototype. */
706
static TRef rec_call_specialize(jit_State *J, GCfunc *fn, TRef tr)
753,001✔
707
{
708
  TRef kfunc;
753,001✔
709
  if (isluafunc(fn)) {
753,001✔
710
    GCproto *pt = funcproto(fn);
508,425✔
711
    /* Too many closures created? Probably not a monomorphic function. */
712
    if (pt->flags >= PROTO_CLC_POLY) {  /* Specialize to prototype instead. */
508,425✔
713
      TRef trpt = emitir(IRT(IR_FLOAD, IRT_PGC), tr, IRFL_FUNC_PC);
25✔
714
      emitir(IRTG(IR_EQ, IRT_PGC), trpt, lj_ir_kptr(J, proto_bc(pt)));
25✔
715
      (void)lj_ir_kgc(J, obj2gco(pt), IRT_PROTO);  /* Prevent GC of proto. */
25✔
716
      return tr;
25✔
717
    }
718
  } else {
719
    /* Don't specialize to non-monomorphic builtins. */
720
    switch (fn->c.ffid) {
244,576✔
721
    case FF_coroutine_wrap_aux:
112✔
722
    case FF_string_gmatch_aux:
723
      /* NYI: io_file_iter doesn't have an ffid, yet. */
724
      {  /* Specialize to the ffid. */
725
        TRef trid = emitir(IRT(IR_FLOAD, IRT_U8), tr, IRFL_FUNC_FFID);
112✔
726
        emitir(IRTG(IR_EQ, IRT_INT), trid, lj_ir_kint(J, fn->c.ffid));
112✔
727
      }
728
      return tr;
112✔
729
    default:
730
      /* NYI: don't specialize to non-monomorphic C functions. */
731
      break;
732
    }
733
  }
734
  /* Otherwise specialize to the function (closure) value itself. */
735
  kfunc = lj_ir_kfunc(J, fn);
752,864✔
736
  emitir(IRTG(IR_EQ, IRT_FUNC), tr, kfunc);
752,864✔
737
  return kfunc;
752,864✔
738
}
739

740
/* Record call setup. */
741
static void rec_call_setup(jit_State *J, BCReg func, ptrdiff_t nargs)
753,010✔
742
{
743
  RecordIndex ix;
753,010✔
744
  TValue *functv = &J->L->base[func];
753,010✔
745
  TRef kfunc, *fbase = &J->base[func];
753,010✔
746
  ptrdiff_t i;
753,010✔
747
  (void)getslot(J, func); /* Ensure func has a reference. */
753,010✔
748
  for (i = 1; i <= nargs; i++)
1,830,529✔
749
    (void)getslot(J, func+LJ_FR2+i);  /* Ensure all args have a reference. */
1,077,519✔
750
  if (!tref_isfunc(fbase[0])) {  /* Resolve __call metamethod. */
753,010✔
751
    ix.tab = fbase[0];
7,514✔
752
    copyTV(J->L, &ix.tabv, functv);
7,514✔
753
    if (!lj_record_mm_lookup(J, &ix, MM_call) || !tref_isfunc(ix.mobj))
7,514✔
754
      lj_trace_err(J, LJ_TRERR_NOMM);
9✔
755
    for (i = ++nargs; i > LJ_FR2; i--)  /* Shift arguments up. */
15,111✔
756
      fbase[i+LJ_FR2] = fbase[i+LJ_FR2-1];
7,606✔
757
#if LJ_FR2
758
    fbase[2] = fbase[0];
7,505✔
759
#endif
760
    fbase[0] = ix.mobj;  /* Replace function. */
7,505✔
761
    functv = &ix.mobjv;
7,505✔
762
  }
763
  kfunc = rec_call_specialize(J, funcV(functv), fbase[0]);
753,001✔
764
#if LJ_FR2
765
  fbase[0] = kfunc;
753,001✔
766
  fbase[1] = TREF_FRAME;
753,001✔
767
#else
768
  fbase[0] = kfunc | TREF_FRAME;
769
#endif
770
  J->maxslot = (BCReg)nargs;
753,001✔
771
}
753,001✔
772

773
/* Record call. */
774
void lj_record_call(jit_State *J, BCReg func, ptrdiff_t nargs)
687,810✔
775
{
776
  rec_call_setup(J, func, nargs);
687,810✔
777
  /* Bump frame. */
778
  J->framedepth++;
687,801✔
779
  J->base += func+1+LJ_FR2;
687,801✔
780
  J->baseslot += func+1+LJ_FR2;
687,801✔
781
  if (J->baseslot + J->maxslot >= LJ_MAX_JSLOTS)
687,801✔
782
    lj_trace_err(J, LJ_TRERR_STACKOV);
1✔
783
}
687,800✔
784

785
/* Record tail call. */
786
void lj_record_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs)
65,200✔
787
{
788
  rec_call_setup(J, func, nargs);
65,200✔
789
  if (frame_isvarg(J->L->base - 1)) {
65,200✔
790
    BCReg cbase = (BCReg)frame_delta(J->L->base - 1);
5✔
791
    if (--J->framedepth < 0)
5✔
792
      lj_trace_err(J, LJ_TRERR_NYIRETL);
×
793
    J->baseslot -= (BCReg)cbase;
5✔
794
    J->base -= cbase;
5✔
795
    func += cbase;
5✔
796
  }
797
  /* Move func + args down. */
798
  if (LJ_FR2 && J->baseslot == 2)
65,200✔
799
    J->base[func+1] = TREF_FRAME;
63,118✔
800
  memmove(&J->base[-1-LJ_FR2], &J->base[func], sizeof(TRef)*(J->maxslot+1+LJ_FR2));
65,200✔
801
  /* Note: the new TREF_FRAME is now at J->base[-1] (even for slot #0). */
802
  /* Tailcalls can form a loop, so count towards the loop unroll limit. */
803
  if (++J->tailcalled > J->loopunroll)
65,200✔
804
    lj_trace_err(J, LJ_TRERR_LUNROLL);
1,434✔
805
}
63,766✔
806

807
/* Check unroll limits for down-recursion. */
808
static int check_downrec_unroll(jit_State *J, GCproto *pt)
36✔
809
{
810
  IRRef ptref;
36✔
811
  for (ptref = J->chain[IR_KGC]; ptref; ptref = IR(ptref)->prev)
75✔
812
    if (ir_kgc(IR(ptref)) == obj2gco(pt)) {
40✔
813
      int count = 0;
1✔
814
      IRRef ref;
1✔
815
      for (ref = J->chain[IR_RETF]; ref; ref = IR(ref)->prev)
2✔
816
        if (IR(ref)->op1 == ptref)
1✔
817
          count++;
1✔
818
      if (count) {
1✔
819
        if (J->pc == J->startpc) {
1✔
820
          if (count + J->tailcalled > J->param[JIT_P_recunroll])
×
821
            return 1;
822
        } else {
823
          lj_trace_err(J, LJ_TRERR_DOWNREC);
1✔
824
        }
825
      }
826
    }
827
  return 0;
828
}
829

830
static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot);
831

832
/* Record return. */
833
void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
751,408✔
834
{
835
  TValue *frame = J->L->base - 1;
751,408✔
836
  ptrdiff_t i;
751,408✔
837
  BCReg baseadj = 0;
751,408✔
838
  for (i = 0; i < gotresults; i++)
1,445,380✔
839
    (void)getslot(J, rbase+i);  /* Ensure all results have a reference. */
693,972✔
840
  while (frame_ispcall(frame)) {  /* Immediately resolve pcall() returns. */
751,437✔
841
    BCReg cbase = (BCReg)frame_delta(frame);
43✔
842
    if (--J->framedepth <= 0)
43✔
843
      lj_trace_err(J, LJ_TRERR_NYIRETL);
14✔
844
    lj_assertJ(J->baseslot > 1+LJ_FR2, "bad baseslot for return");
29✔
845
    gotresults++;
29✔
846
    baseadj += cbase;
29✔
847
    rbase += cbase;
29✔
848
    J->baseslot -= (BCReg)cbase;
29✔
849
    J->base -= cbase;
29✔
850
    J->base[--rbase] = TREF_TRUE;  /* Prepend true to results. */
29✔
851
    frame = frame_prevd(frame);
29✔
852
    J->needsnap = 1;  /* Stop catching on-trace errors. */
29✔
853
  }
854
  /* Return to lower frame via interpreter for unhandled cases. */
855
  if (J->framedepth == 0 && J->pt && bc_isret(bc_op(*J->pc)) &&
751,394✔
856
       (!frame_islua(frame) ||
77,338✔
857
        (J->parent == 0 && J->exitno == 0 &&
77,279✔
858
         !bc_isret(bc_op(J->cur.startins))))) {
666✔
859
    /* NYI: specialize to frame type and return directly, not via RET*. */
860
    for (i = 0; i < (ptrdiff_t)rbase; i++)
1,832✔
861
      J->base[i] = 0;  /* Purge dead slots. */
1,108✔
862
    J->maxslot = rbase + (BCReg)gotresults;
724✔
863
    lj_record_stop(J, LJ_TRLINK_RETURN, 0);  /* Return to interpreter. */
724✔
864
    return;
724✔
865
  }
866
  if (frame_isvarg(frame)) {
750,670✔
867
    BCReg cbase = (BCReg)frame_delta(frame);
131✔
868
    if (--J->framedepth < 0)  /* NYI: return of vararg func to lower frame. */
131✔
869
      lj_trace_err(J, LJ_TRERR_NYIRETL);
×
870
    lj_assertJ(J->baseslot > 1+LJ_FR2, "bad baseslot for return");
131✔
871
    baseadj += cbase;
131✔
872
    rbase += cbase;
131✔
873
    J->baseslot -= (BCReg)cbase;
131✔
874
    J->base -= cbase;
131✔
875
    frame = frame_prevd(frame);
131✔
876
  }
877
  if (frame_islua(frame)) {  /* Return to Lua frame. */
750,670✔
878
    BCIns callins = *(frame_pc(frame)-1);
660,197✔
879
    ptrdiff_t nresults = bc_b(callins) ? (ptrdiff_t)bc_b(callins)-1 :gotresults;
660,197✔
880
    BCReg cbase = bc_a(callins);
660,197✔
881
    GCproto *pt = funcproto(frame_func(frame - (cbase+1+LJ_FR2)));
660,197✔
882
    if ((pt->flags & PROTO_NOJIT))
660,197✔
883
      lj_trace_err(J, LJ_TRERR_CJITOFF);
×
884
    if (J->framedepth == 0 && J->pt && frame == J->L->base - 1) {
660,197✔
885
      if (!J->cur.root && check_downrec_unroll(J, pt)) {
76,614✔
886
        J->maxslot = (BCReg)(rbase + gotresults);
×
887
        lj_snap_purge(J);
×
888
        lj_record_stop(J, LJ_TRLINK_DOWNREC, J->cur.traceno);  /* Down-rec. */
×
889
        return;
×
890
      }
891
      lj_snap_add(J);
76,613✔
892
    }
893
    for (i = 0; i < nresults; i++)  /* Adjust results. */
1,224,644✔
894
      J->base[i-1-LJ_FR2] = i < gotresults ? J->base[rbase+i] : TREF_NIL;
564,448✔
895
    J->maxslot = cbase+(BCReg)nresults;
660,196✔
896
    if (J->framedepth > 0) {  /* Return to a frame that is part of the trace. */
660,196✔
897
      J->framedepth--;
583,197✔
898
      lj_assertJ(J->baseslot > cbase+1+LJ_FR2, "bad baseslot for return");
583,197✔
899
      J->baseslot -= cbase+1+LJ_FR2;
583,197✔
900
      J->base -= cbase+1+LJ_FR2;
583,197✔
901
    } else if (J->parent == 0 && J->exitno == 0 &&
76,999✔
902
               !bc_isret(bc_op(J->cur.startins))) {
31✔
903
      /* Return to lower frame would leave the loop in a root trace. */
904
      lj_trace_err(J, LJ_TRERR_LLEAVE);
30✔
905
    } else if (J->needsnap) {  /* Tailcalled to ff with side-effects. */
76,969✔
906
      lj_trace_err(J, LJ_TRERR_NYIRETL);  /* No way to insert snapshot here. */
×
907
    } else if (1 + pt->framesize >= LJ_MAX_JSLOTS ||
76,969✔
908
               J->baseslot + J->maxslot >= LJ_MAX_JSLOTS) {
76,968✔
909
      lj_trace_err(J, LJ_TRERR_STACKOV);
2✔
910
    } else {  /* Return to lower frame. Guard for the target we return to. */
911
      TRef trpt = lj_ir_kgc(J, obj2gco(pt), IRT_PROTO);
76,967✔
912
      TRef trpc = lj_ir_kptr(J, (void *)frame_pc(frame));
76,967✔
913
      emitir(IRTG(IR_RETF, IRT_PGC), trpt, trpc);
76,967✔
914
      J->retdepth++;
76,967✔
915
      J->needsnap = 1;
76,967✔
916
      J->scev.idx = REF_NIL;
76,967✔
917
      lj_assertJ(J->baseslot == 1+LJ_FR2, "bad baseslot for return");
76,967✔
918
      /* Shift result slots up and clear the slots of the new frame below. */
919
      memmove(J->base + cbase, J->base-1-LJ_FR2, sizeof(TRef)*nresults);
76,967✔
920
      memset(J->base-1-LJ_FR2, 0, sizeof(TRef)*(cbase+1+LJ_FR2));
76,967✔
921
    }
922
  } else if (frame_iscont(frame)) {  /* Return to continuation frame. */
90,473✔
923
    ASMFunction cont = frame_contf(frame);
90,473✔
924
    BCReg cbase = (BCReg)frame_delta(frame);
90,473✔
925
    if ((J->framedepth -= 2) < 0)
90,473✔
926
      lj_trace_err(J, LJ_TRERR_NYIRETL);
5✔
927
    J->baseslot -= (BCReg)cbase;
90,468✔
928
    J->base -= cbase;
90,468✔
929
    J->maxslot = cbase-(2<<LJ_FR2);
90,468✔
930
    if (cont == lj_cont_ra) {
90,468✔
931
      /* Copy result to destination slot. */
932
      BCReg dst = bc_a(*(frame_contpc(frame)-1));
64,720✔
933
      J->base[dst] = gotresults ? J->base[cbase+rbase] : TREF_NIL;
64,720✔
934
      if (dst >= J->maxslot) {
64,720✔
935
        J->maxslot = dst+1;
×
936
      }
937
    } else if (cont == lj_cont_nop) {
25,748✔
938
      /* Nothing to do here. */
939
    } else if (cont == lj_cont_cat) {
25,591✔
940
      BCReg bslot = bc_b(*(frame_contpc(frame)-1));
13✔
941
      TRef tr = gotresults ? J->base[cbase+rbase] : TREF_NIL;
13✔
942
      if (bslot != J->maxslot) {  /* Concatenate the remainder. */
13✔
943
        /* Simulate lower frame and result. */
944
        TValue *b = J->L->base - baseadj, save;
7✔
945
        /* Can't handle MM_concat + CALLT + fast func side-effects. */
946
        if (J->postproc != LJ_POST_NONE)
7✔
947
          lj_trace_err(J, LJ_TRERR_NYIRETL);
1✔
948
        J->base[J->maxslot] = tr;
6✔
949
        copyTV(J->L, &save, b-(2<<LJ_FR2));
6✔
950
        if (gotresults)
6✔
951
          copyTV(J->L, b-(2<<LJ_FR2), b+rbase);
6✔
952
        else
953
          setnilV(b-(2<<LJ_FR2));
×
954
        J->L->base = b - cbase;
6✔
955
        tr = rec_cat(J, bslot, cbase-(2<<LJ_FR2));
6✔
956
        b = J->L->base + cbase;  /* Undo. */
6✔
957
        J->L->base = b + baseadj;
6✔
958
        copyTV(J->L, b-(2<<LJ_FR2), &save);
6✔
959
      }
960
      if (tr >= 0xffffff00) {
12✔
961
        lj_err_throw(J->L, -(int32_t)tr);  /* Propagate errors. */
2✔
962
      } else if (tr) {  /* Store final result. */
10✔
963
        BCReg dst = bc_a(*(frame_contpc(frame)-1));
6✔
964
        J->base[dst] = tr;
6✔
965
        if (dst >= J->maxslot) {
6✔
966
          J->maxslot = dst+1;
×
967
        }
968
      }  /* Otherwise continue with another __concat call. */
969
    } else {
970
      /* Result type already specialized. */
971
      lj_assertJ(cont == lj_cont_condf || cont == lj_cont_condt,
972
                 "bad continuation type");
973
    }
974
  } else {
975
    lj_trace_err(J, LJ_TRERR_NYIRETL);  /* NYI: handle return to C frame. */
×
976
  }
977
  lj_assertJ(J->baseslot >= 1+LJ_FR2, "bad baseslot for return");
751,353✔
978
}
979

980
/* -- Metamethod handling ------------------------------------------------- */
981

982
/* Prepare to record call to metamethod. */
983
static BCReg rec_mm_prep(jit_State *J, ASMFunction cont)
90,492✔
984
{
985
  BCReg s, top = cont == lj_cont_cat ? J->maxslot : curr_proto(J->L)->framesize;
90,492✔
986
#if LJ_FR2
987
  J->base[top] = lj_ir_k64(J, IR_KNUM, u64ptr(contptr(cont)));
90,492✔
988
  J->base[top+1] = TREF_CONT;
90,492✔
989
#else
990
  J->base[top] = lj_ir_kptr(J, contptr(cont)) | TREF_CONT;
991
#endif
992
  J->framedepth++;
90,492✔
993
  for (s = J->maxslot; s < top; s++)
429,139✔
994
    J->base[s] = 0;  /* Clear frame gap to avoid resurrecting previous refs. */
338,647✔
995
  return top+1+LJ_FR2;
90,492✔
996
}
997

998
/* Record metamethod lookup. */
999
int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm)
142,891✔
1000
{
1001
  RecordIndex mix;
142,891✔
1002
  GCtab *mt;
142,891✔
1003
  if (tref_istab(ix->tab)) {
142,891✔
1004
    mt = tabref(tabV(&ix->tabv)->metatable);
44,541✔
1005
    mix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_TAB_META);
44,541✔
1006
  } else if (tref_isudata(ix->tab)) {
98,350✔
1007
    int udtype = udataV(&ix->tabv)->udtype;
7,438✔
1008
    mt = tabref(udataV(&ix->tabv)->metatable);
7,438✔
1009
    /* The metatables of special userdata objects are treated as immutable. */
1010
    if (udtype > UDTYPE_IO_FILE) {
7,438✔
1011
      cTValue *mo;
7,430✔
1012
      if (LJ_HASFFI && udtype == UDTYPE_FFI_CLIB) {
7,430✔
1013
        /* Specialize to the C library namespace object. */
1014
        emitir(IRTG(IR_EQ, IRT_PGC), ix->tab, lj_ir_kptr(J, udataV(&ix->tabv)));
7,430✔
1015
      } else {
1016
        /* Specialize to the type of userdata. */
1017
        TRef tr = emitir(IRT(IR_FLOAD, IRT_U8), ix->tab, IRFL_UDATA_UDTYPE);
×
1018
        emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, udtype));
×
1019
      }
1020
  immutable_mt:
97,853✔
1021
      mo = lj_tab_getstr(mt, mmname_str(J2G(J), mm));
97,853✔
1022
      if (!mo || tvisnil(mo))
97,853✔
1023
        return 0;  /* No metamethod. */
1024
      /* Treat metamethod or index table as immutable, too. */
1025
      if (!(tvisfunc(mo) || tvistab(mo)))
97,853✔
1026
        lj_trace_err(J, LJ_TRERR_BADTYPE);
×
1027
      copyTV(J->L, &ix->mobjv, mo);
97,853✔
1028
      ix->mobj = lj_ir_kgc(J, gcV(mo), tvisfunc(mo) ? IRT_FUNC : IRT_TAB);
97,853✔
1029
      ix->mtv = mt;
97,853✔
1030
      ix->mt = TREF_NIL;  /* Dummy value for comparison semantics. */
97,853✔
1031
      return 1;  /* Got metamethod or index table. */
97,853✔
1032
    }
1033
    mix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_UDATA_META);
8✔
1034
  } else {
1035
    /* Specialize to base metatable. Must flush mcode in lua_setmetatable(). */
1036
    mt = tabref(basemt_obj(J2G(J), &ix->tabv));
90,912✔
1037
    if (mt == NULL) {
90,912✔
1038
      ix->mt = TREF_NIL;
172✔
1039
      return 0;  /* No metamethod. */
172✔
1040
    }
1041
    /* The cdata metatable is treated as immutable. */
1042
    if (LJ_HASFFI && tref_iscdata(ix->tab)) goto immutable_mt;
90,740✔
1043
#if LJ_GC64
1044
    /* TODO: fix ARM32 asm_fload(), so we can use this for all archs. */
1045
    ix->mt = mix.tab = lj_ir_ggfload(J, IRT_TAB,
630✔
1046
      GG_OFS(g.gcroot[GCROOT_BASEMT+itypemap(&ix->tabv)]));
313✔
1047
#else
1048
    ix->mt = mix.tab = lj_ir_ktab(J, mt);
1049
#endif
1050
    goto nocheck;
317✔
1051
  }
1052
  ix->mt = mt ? mix.tab : TREF_NIL;
44,549✔
1053
  emitir(IRTG(mt ? IR_NE : IR_EQ, IRT_TAB), mix.tab, lj_ir_knull(J, IRT_TAB));
66,112✔
1054
nocheck:
44,866✔
1055
  if (mt) {
44,866✔
1056
    GCstr *mmstr = mmname_str(J2G(J), mm);
23,303✔
1057
    cTValue *mo = lj_tab_getstr(mt, mmstr);
23,303✔
1058
    if (mo && !tvisnil(mo))
23,303✔
1059
      copyTV(J->L, &ix->mobjv, mo);
23,196✔
1060
    ix->mtv = mt;
23,303✔
1061
    settabV(J->L, &mix.tabv, mt);
23,303✔
1062
    setstrV(J->L, &mix.keyv, mmstr);
23,303✔
1063
    mix.key = lj_ir_kstr(J, mmstr);
23,303✔
1064
    mix.val = 0;
23,303✔
1065
    mix.idxchain = 0;
23,303✔
1066
    ix->mobj = lj_record_idx(J, &mix);
23,303✔
1067
    return !tref_isnil(ix->mobj);  /* 1 if metamethod found, 0 if not. */
23,303✔
1068
  }
1069
  return 0;  /* No metamethod. */
1070
}
1071

1072
/* Record call to arithmetic metamethod. */
1073
static TRef rec_mm_arith(jit_State *J, RecordIndex *ix, MMS mm)
39,071✔
1074
{
1075
  /* Set up metamethod call first to save ix->tab and ix->tabv. */
1076
  BCReg func = rec_mm_prep(J, mm == MM_concat ? lj_cont_cat : lj_cont_ra);
78,128✔
1077
  TRef *base = J->base + func;
39,071✔
1078
  TValue *basev = J->L->base + func;
39,071✔
1079
  base[1+LJ_FR2] = ix->tab; base[2+LJ_FR2] = ix->key;
39,071✔
1080
  copyTV(J->L, basev+1+LJ_FR2, &ix->tabv);
39,071✔
1081
  copyTV(J->L, basev+2+LJ_FR2, &ix->keyv);
39,071✔
1082
  if (!lj_record_mm_lookup(J, ix, mm)) {  /* Lookup mm on 1st operand. */
39,071✔
1083
    if (mm != MM_unm) {
20✔
1084
      ix->tab = ix->key;
20✔
1085
      copyTV(J->L, &ix->tabv, &ix->keyv);
20✔
1086
      if (lj_record_mm_lookup(J, ix, mm))  /* Lookup mm on 2nd operand. */
20✔
1087
        goto ok;
19✔
1088
    }
1089
    lj_trace_err(J, LJ_TRERR_NOMM);
1✔
1090
  }
1091
ok:
39,051✔
1092
  base[0] = ix->mobj;
39,070✔
1093
#if LJ_FR2
1094
  base[1] = 0;
39,070✔
1095
#endif
1096
  copyTV(J->L, basev+0, &ix->mobjv);
39,070✔
1097
  lj_record_call(J, func, 2);
39,070✔
1098
  return 0;  /* No result yet. */
39,069✔
1099
}
1100

1101
/* Record call to __len metamethod. */
1102
static TRef rec_mm_len(jit_State *J, TRef tr, TValue *tv)
1103
{
1104
  RecordIndex ix;
1105
  ix.tab = tr;
1106
  copyTV(J->L, &ix.tabv, tv);
1107
  if (lj_record_mm_lookup(J, &ix, MM_len)) {
1108
    BCReg func = rec_mm_prep(J, lj_cont_ra);
1109
    TRef *base = J->base + func;
1110
    TValue *basev = J->L->base + func;
1111
    base[0] = ix.mobj; copyTV(J->L, basev+0, &ix.mobjv);
1112
    base += LJ_FR2;
1113
    basev += LJ_FR2;
1114
    base[1] = tr; copyTV(J->L, basev+1, tv);
1115
#if LJ_52
1116
    base[2] = tr; copyTV(J->L, basev+2, tv);
1117
#else
1118
    base[2] = TREF_NIL; setnilV(basev+2);
1119
#endif
1120
    lj_record_call(J, func, 2);
1121
  } else {
1122
    if (LJ_52 && tref_istab(tr))
1123
      return lj_ir_call(J, IRCALL_lj_tab_len, tr);
1124
    lj_trace_err(J, LJ_TRERR_NOMM);
1125
  }
1126
  return 0;  /* No result yet. */
1127
}
1128

1129
/* Call a comparison metamethod. */
1130
static void rec_mm_callcomp(jit_State *J, RecordIndex *ix, int op)
25,580✔
1131
{
1132
  BCReg func = rec_mm_prep(J, (op&1) ? lj_cont_condf : lj_cont_condt);
33,052✔
1133
  TRef *base = J->base + func + LJ_FR2;
25,580✔
1134
  TValue *tv = J->L->base + func + LJ_FR2;
25,580✔
1135
  base[-LJ_FR2] = ix->mobj; base[1] = ix->val; base[2] = ix->key;
25,580✔
1136
  copyTV(J->L, tv-LJ_FR2, &ix->mobjv);
25,580✔
1137
  copyTV(J->L, tv+1, &ix->valv);
25,580✔
1138
  copyTV(J->L, tv+2, &ix->keyv);
25,580✔
1139
  lj_record_call(J, func, 2);
25,580✔
1140
}
25,580✔
1141

1142
/* Record call to equality comparison metamethod (for tab and udata only). */
1143
static void rec_mm_equal(jit_State *J, RecordIndex *ix, int op)
10✔
1144
{
1145
  ix->tab = ix->val;
10✔
1146
  copyTV(J->L, &ix->tabv, &ix->valv);
10✔
1147
  if (lj_record_mm_lookup(J, ix, MM_eq)) {  /* Lookup mm on 1st operand. */
10✔
1148
    cTValue *bv;
9✔
1149
    TRef mo1 = ix->mobj;
9✔
1150
    TValue mo1v;
9✔
1151
    copyTV(J->L, &mo1v, &ix->mobjv);
9✔
1152
    /* Avoid the 2nd lookup and the objcmp if the metatables are equal. */
1153
    bv = &ix->keyv;
9✔
1154
    if (tvistab(bv) && tabref(tabV(bv)->metatable) == ix->mtv) {
18✔
1155
      TRef mt2 = emitir(IRT(IR_FLOAD, IRT_TAB), ix->key, IRFL_TAB_META);
9✔
1156
      emitir(IRTG(IR_EQ, IRT_TAB), mt2, ix->mt);
9✔
1157
    } else if (tvisudata(bv) && tabref(udataV(bv)->metatable) == ix->mtv) {
×
1158
      TRef mt2 = emitir(IRT(IR_FLOAD, IRT_TAB), ix->key, IRFL_UDATA_META);
×
1159
      emitir(IRTG(IR_EQ, IRT_TAB), mt2, ix->mt);
×
1160
    } else {  /* Lookup metamethod on 2nd operand and compare both. */
1161
      ix->tab = ix->key;
×
1162
      copyTV(J->L, &ix->tabv, bv);
×
1163
      if (!lj_record_mm_lookup(J, ix, MM_eq) ||
×
1164
          lj_record_objcmp(J, mo1, ix->mobj, &mo1v, &ix->mobjv))
×
1165
        return;
×
1166
    }
1167
    rec_mm_callcomp(J, ix, op);
9✔
1168
  }
1169
}
1170

1171
/* Record call to ordered comparison metamethods (for arbitrary objects). */
1172
static void rec_mm_comp(jit_State *J, RecordIndex *ix, int op)
49✔
1173
{
1174
  ix->tab = ix->val;
49✔
1175
  copyTV(J->L, &ix->tabv, &ix->valv);
49✔
1176
  while (1) {
67✔
1177
    MMS mm = (op & 2) ? MM_le : MM_lt;  /* Try __le + __lt or only __lt. */
58✔
1178
#if LJ_52
1179
    if (!lj_record_mm_lookup(J, ix, mm)) {  /* Lookup mm on 1st operand. */
1180
      ix->tab = ix->key;
1181
      copyTV(J->L, &ix->tabv, &ix->keyv);
1182
      if (!lj_record_mm_lookup(J, ix, mm))  /* Lookup mm on 2nd operand. */
1183
        goto nomatch;
1184
    }
1185
    rec_mm_callcomp(J, ix, op);
1186
    return;
1187
#else
1188
    if (lj_record_mm_lookup(J, ix, mm)) {  /* Lookup mm on 1st operand. */
58✔
1189
      cTValue *bv;
49✔
1190
      TRef mo1 = ix->mobj;
49✔
1191
      TValue mo1v;
49✔
1192
      copyTV(J->L, &mo1v, &ix->mobjv);
49✔
1193
      /* Avoid the 2nd lookup and the objcmp if the metatables are equal. */
1194
      bv = &ix->keyv;
49✔
1195
      if (tvistab(bv) && tabref(tabV(bv)->metatable) == ix->mtv) {
98✔
1196
        TRef mt2 = emitir(IRT(IR_FLOAD, IRT_TAB), ix->key, IRFL_TAB_META);
49✔
1197
        emitir(IRTG(IR_EQ, IRT_TAB), mt2, ix->mt);
49✔
1198
      } else if (tvisudata(bv) && tabref(udataV(bv)->metatable) == ix->mtv) {
×
1199
        TRef mt2 = emitir(IRT(IR_FLOAD, IRT_TAB), ix->key, IRFL_UDATA_META);
×
1200
        emitir(IRTG(IR_EQ, IRT_TAB), mt2, ix->mt);
×
1201
      } else {  /* Lookup metamethod on 2nd operand and compare both. */
1202
        ix->tab = ix->key;
×
1203
        copyTV(J->L, &ix->tabv, bv);
×
1204
        if (!lj_record_mm_lookup(J, ix, mm) ||
×
1205
            lj_record_objcmp(J, mo1, ix->mobj, &mo1v, &ix->mobjv))
×
1206
          goto nomatch;
×
1207
      }
1208
      rec_mm_callcomp(J, ix, op);
49✔
1209
      return;
49✔
1210
    }
1211
#endif
1212
  nomatch:
9✔
1213
    /* Lookup failed. Retry with  __lt and swapped operands. */
1214
    if (!(op & 2)) break;  /* Already at __lt. Interpreter will throw. */
9✔
1215
    ix->tab = ix->key; ix->key = ix->val; ix->val = ix->tab;
9✔
1216
    copyTV(J->L, &ix->tabv, &ix->keyv);
9✔
1217
    copyTV(J->L, &ix->keyv, &ix->valv);
9✔
1218
    copyTV(J->L, &ix->valv, &ix->tabv);
9✔
1219
    op ^= 3;
9✔
1220
  }
1221
}
1222

1223
#if LJ_HASFFI
1224
/* Setup call to cdata comparison metamethod. */
1225
static void rec_mm_comp_cdata(jit_State *J, RecordIndex *ix, int op, MMS mm)
25,522✔
1226
{
1227
  lj_snap_add(J);
25,522✔
1228
  if (tref_iscdata(ix->val)) {
25,522✔
1229
    ix->tab = ix->val;
55✔
1230
    copyTV(J->L, &ix->tabv, &ix->valv);
55✔
1231
  } else {
1232
    lj_assertJ(tref_iscdata(ix->key), "cdata expected");
25,467✔
1233
    ix->tab = ix->key;
25,467✔
1234
    copyTV(J->L, &ix->tabv, &ix->keyv);
25,467✔
1235
  }
1236
  lj_record_mm_lookup(J, ix, mm);
25,522✔
1237
  rec_mm_callcomp(J, ix, op);
25,522✔
1238
}
25,522✔
1239
#endif
1240

1241
/* -- Indexed access ------------------------------------------------------ */
1242

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

1309
/* Record bounds-check. */
1310
static void rec_idx_abc(jit_State *J, TRef asizeref, TRef ikey, uint32_t asize)
5,450✔
1311
{
1312
  /* Try to emit invariant bounds checks. */
1313
  if ((J->flags & (JIT_F_OPT_LOOP|JIT_F_OPT_ABC)) ==
5,450✔
1314
      (JIT_F_OPT_LOOP|JIT_F_OPT_ABC)) {
1315
    IRRef ref = tref_ref(ikey);
5,439✔
1316
    IRIns *ir = IR(ref);
5,439✔
1317
    int32_t ofs = 0;
5,439✔
1318
    IRRef ofsref = 0;
5,439✔
1319
    /* Handle constant offsets. */
1320
    if (ir->o == IR_ADD && irref_isk(ir->op2)) {
5,439✔
1321
      ofsref = ir->op2;
187✔
1322
      ofs = IR(ofsref)->i;
187✔
1323
      ref = ir->op1;
187✔
1324
      ir = IR(ref);
187✔
1325
    }
1326
    /* Got scalar evolution analysis results for this reference? */
1327
    if (ref == J->scev.idx) {
5,439✔
1328
      int32_t stop;
3,767✔
1329
      lj_assertJ(irt_isint(J->scev.t) && ir->o == IR_SLOAD,
3,767✔
1330
                 "only int SCEV supported");
1331
      stop = numberVint(&(J->L->base - J->baseslot)[ir->op1 + FORL_STOP]);
3,767✔
1332
      /* Runtime value for stop of loop is within bounds? */
1333
      if ((uint64_t)stop + ofs < (uint64_t)asize) {
3,767✔
1334
        /* Emit invariant bounds check for stop. */
1335
        uint32_t abc = IRTG(IR_ABC, tref_isk(asizeref) ? IRT_U32 : IRT_P32);
171✔
1336
        emitir(abc, asizeref, ofs == 0 ? J->scev.stop :
171✔
1337
               emitir(IRTI(IR_ADD), J->scev.stop, ofsref));
1338
        /* Emit invariant bounds check for start, if not const or negative. */
1339
        if (!(J->scev.dir && J->scev.start &&
171✔
1340
              (int64_t)IR(J->scev.start)->i + ofs >= 0))
160✔
1341
          emitir(abc, asizeref, ikey);
11✔
1342
        return;
171✔
1343
      }
1344
    }
1345
  }
1346
  emitir(IRTGI(IR_ABC), asizeref, ikey);  /* Emit regular bounds check. */
5,279✔
1347
}
1348

1349
/* Record indexed key lookup. */
1350
static TRef rec_idx_key(jit_State *J, RecordIndex *ix, IRRef *rbref,
1,015,520✔
1351
                        IRType1 *rbguard)
1352
{
1353
  TRef key;
1,015,520✔
1354
  GCtab *t = tabV(&ix->tabv);
1,015,520✔
1355
  ix->oldv = lj_tab_get(J->L, t, &ix->keyv);  /* Lookup previous value. */
1,015,520✔
1356
  *rbref = 0;
1,015,520✔
1357
  rbguard->irt = 0;
1,015,520✔
1358

1359
  /* Integer keys are looked up in the array part first. */
1360
  key = ix->key;
1,015,520✔
1361
  if (tref_isnumber(key)) {
1,015,520✔
1362
    int32_t k = numberVint(&ix->keyv);
20,728✔
1363
    if (!tvisint(&ix->keyv) && numV(&ix->keyv) != (lua_Number)k)
20,728✔
1364
      k = LJ_MAX_ASIZE;
91✔
1365
    if ((MSize)k < LJ_MAX_ASIZE) {  /* Potential array key? */
20,728✔
1366
      TRef ikey = lj_opt_narrow_index(J, key);
20,606✔
1367
      TRef asizeref = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_ASIZE);
20,606✔
1368
      if ((MSize)k < t->asize) {  /* Currently an array key? */
20,606✔
1369
        TRef arrayref;
5,446✔
1370
        rec_idx_abc(J, asizeref, ikey, t->asize);
5,446✔
1371
        arrayref = emitir(IRT(IR_FLOAD, IRT_PGC), ix->tab, IRFL_TAB_ARRAY);
5,446✔
1372
        return emitir(IRT(IR_AREF, IRT_PGC), arrayref, ikey);
5,446✔
1373
      } else {  /* Currently not in array (may be an array extension)? */
1374
        emitir(IRTGI(IR_ULE), asizeref, ikey);  /* Inv. bounds check. */
15,160✔
1375
        if (k == 0 && tref_isk(key))
15,160✔
1376
          key = lj_ir_knum_zero(J);  /* Canonicalize 0 or +-0.0 to +0.0. */
4✔
1377
        /* And continue with the hash lookup. */
1378
      }
1379
    } else if (!tref_isk(key)) {
122✔
1380
      /* We can rule out const numbers which failed the integerness test
1381
      ** above. But all other numbers are potential array keys.
1382
      */
1383
      if (t->asize == 0) {  /* True sparse tables have an empty array part. */
122✔
1384
        /* Guard that the array part stays empty. */
1385
        TRef tmp = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_ASIZE);
114✔
1386
        emitir(IRTGI(IR_EQ), tmp, lj_ir_kint(J, 0));
114✔
1387
      } else {
1388
        lj_trace_err(J, LJ_TRERR_NYITMIX);
8✔
1389
      }
1390
    }
1391
  }
1392

1393
  /* Otherwise the key is located in the hash part. */
1394
  if (t->hmask == 0) {  /* Shortcut for empty hash part. */
1,010,066✔
1395
    /* Guard that the hash part stays empty. */
1396
    TRef tmp = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_HMASK);
507✔
1397
    emitir(IRTGI(IR_EQ), tmp, lj_ir_kint(J, 0));
507✔
1398
    return lj_ir_kkptr(J, niltvg(J2G(J)));
507✔
1399
  }
1400
  if (tref_isinteger(key))  /* Hash keys are based on numbers, not ints. */
1,009,559✔
1401
    key = emitir(IRTN(IR_CONV), key, IRCONV_NUM_INT);
15,009✔
1402
  if (tref_isk(key)) {
1,009,559✔
1403
    /* Optimize lookup of constant hash keys. */
1404
    GCSize hslot = (GCSize)((char *)ix->oldv-(char *)&noderef(t->node)[0].val);
994,381✔
1405
    if (hslot <= t->hmask*(GCSize)sizeof(Node) &&
994,381✔
1406
        hslot <= 65535*(GCSize)sizeof(Node)) {
1407
      TRef node, kslot, hm;
955,220✔
1408
      *rbref = J->cur.nins;  /* Mark possible rollback point. */
955,220✔
1409
      *rbguard = J->guardemit;
955,220✔
1410
      hm = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_HMASK);
955,220✔
1411
      emitir(IRTGI(IR_EQ), hm, lj_ir_kint(J, (int32_t)t->hmask));
955,220✔
1412
      node = emitir(IRT(IR_FLOAD, IRT_PGC), ix->tab, IRFL_TAB_NODE);
955,220✔
1413
      kslot = lj_ir_kslot(J, key, (IRRef)(hslot / sizeof(Node)));
955,220✔
1414
      return emitir(IRTG(IR_HREFK, IRT_PGC), node, kslot);
955,220✔
1415
    }
1416
  }
1417
  /* Fall back to a regular hash lookup. */
1418
  return emitir(IRT(IR_HREF, IRT_PGC), ix->tab, key);
54,339✔
1419
}
1420

1421
/* Determine whether a key is NOT one of the fast metamethod names. */
1422
static int nommstr(jit_State *J, TRef key)
211,879✔
1423
{
1424
  if (tref_isstr(key)) {
211,879✔
1425
    if (tref_isk(key)) {
208,731✔
1426
      GCstr *str = ir_kstr(IR(tref_ref(key)));
208,718✔
1427
      uint32_t mm;
208,718✔
1428
      for (mm = 0; mm <= MM_FAST; mm++)
1,461,026✔
1429
        if (mmname_str(J2G(J), mm) == str)
1,252,308✔
1430
          return 0;  /* MUST be one the fast metamethod names. */
1431
    } else {
1432
      return 0;  /* Variable string key MAY be a metamethod name. */
1433
    }
1434
  }
1435
  return 1;  /* CANNOT be a metamethod name. */
1436
}
1437

1438
/* Record indexed load/store. */
1439
TRef lj_record_idx(jit_State *J, RecordIndex *ix)
1,018,600✔
1440
{
1441
  TRef xref;
1,018,600✔
1442
  IROp xrefop, loadop;
1,018,600✔
1443
  IRRef rbref;
1,018,600✔
1444
  IRType1 rbguard;
1,018,600✔
1445
  cTValue *oldv;
1,018,600✔
1446

1447
  while (!tref_istab(ix->tab)) { /* Handle non-table lookup. */
1,041,648✔
1448
    /* Never call raw lj_record_idx() on non-table. */
1449
    lj_assertJ(ix->idxchain != 0, "bad usage");
26,126✔
1450
    if (!lj_record_mm_lookup(J, ix, ix->val ? MM_newindex : MM_index))
26,126✔
1451
      lj_trace_err(J, LJ_TRERR_NOMM);
×
1452
  handlemm:
26,126✔
1453
    if (tref_isfunc(ix->mobj)) {  /* Handle metamethod call. */
48,887✔
1454
      BCReg func = rec_mm_prep(J, ix->val ? lj_cont_nop : lj_cont_ra);
51,510✔
1455
      TRef *base = J->base + func + LJ_FR2;
25,839✔
1456
      TValue *tv = J->L->base + func + LJ_FR2;
25,839✔
1457
      base[-LJ_FR2] = ix->mobj; base[1] = ix->tab; base[2] = ix->key;
25,839✔
1458
      setfuncV(J->L, tv-LJ_FR2, funcV(&ix->mobjv));
25,839✔
1459
      copyTV(J->L, tv+1, &ix->tabv);
25,839✔
1460
      copyTV(J->L, tv+2, &ix->keyv);
25,839✔
1461
      if (ix->val) {
25,839✔
1462
        base[3] = ix->val;
168✔
1463
        copyTV(J->L, tv+3, &ix->valv);
168✔
1464
        lj_record_call(J, func, 3);  /* mobj(tab, key, val) */
168✔
1465
        return 0;
168✔
1466
      } else {
1467
        lj_record_call(J, func, 2);  /* res = mobj(tab, key) */
25,671✔
1468
        return 0;  /* No result yet. */
25,671✔
1469
      }
1470
    }
1471
    /* Otherwise retry lookup with metaobject. */
1472
    ix->tab = ix->mobj;
23,048✔
1473
    copyTV(J->L, &ix->tabv, &ix->mobjv);
23,048✔
1474
    if (--ix->idxchain == 0)
23,048✔
1475
      lj_trace_err(J, LJ_TRERR_IDXLOOP);
×
1476
  }
1477

1478
  /* First catch nil and NaN keys for tables. */
1479
  if (tvisnil(&ix->keyv) || (tvisnum(&ix->keyv) && tvisnan(&ix->keyv))) {
1,015,522✔
1480
    if (ix->val)  /* Better fail early. */
2✔
1481
      lj_trace_err(J, LJ_TRERR_STORENN);
2✔
1482
    if (tref_isk(ix->key)) {
×
1483
      if (ix->idxchain && lj_record_mm_lookup(J, ix, MM_index))
×
1484
        goto handlemm;
×
1485
      return TREF_NIL;
×
1486
    }
1487
  }
1488

1489
  /* Record the key lookup. */
1490
  xref = rec_idx_key(J, ix, &rbref, &rbguard);
1,015,520✔
1491
  xrefop = IR(tref_ref(xref))->o;
1,015,512✔
1492
  loadop = xrefop == IR_AREF ? IR_ALOAD : IR_HLOAD;
1,015,512✔
1493
  /* The lj_meta_tset() inconsistency is gone, but better play safe. */
1494
  oldv = xrefop == IR_KKPTR ? (cTValue *)ir_kptr(IR(tref_ref(xref))) : ix->oldv;
1,015,512✔
1495

1496
  if (ix->val == 0) {  /* Indexed load */
1,015,512✔
1497
    IRType t = itype2irt(oldv);
803,612✔
1498
    TRef res;
803,612✔
1499
    if (oldv == niltvg(J2G(J))) {
803,612✔
1500
      emitir(IRTG(IR_EQ, IRT_PGC), xref, lj_ir_kkptr(J, niltvg(J2G(J))));
30,481✔
1501
      res = TREF_NIL;
30,481✔
1502
    } else {
1503
      res = emitir(IRTG(loadop, t), xref, 0);
773,131✔
1504
    }
1505
    if (tref_ref(res) < rbref) {  /* HREFK + load forwarded? */
803,612✔
1506
      lj_ir_rollback(J, rbref);  /* Rollback to eliminate hmask guard. */
362,296✔
1507
      J->guardemit = rbguard;
362,296✔
1508
    }
1509
    if (t == IRT_NIL && ix->idxchain && lj_record_mm_lookup(J, ix, MM_index))
803,612✔
1510
      goto handlemm;
22,740✔
1511
    if (irtype_ispri(t)) res = TREF_PRI(t);  /* Canonicalize primitives. */
780,872✔
1512
    return res;
780,872✔
1513
  } else {  /* Indexed store. */
1514
    GCtab *mt = tabref(tabV(&ix->tabv)->metatable);
211,900✔
1515
    int keybarrier = tref_isgcv(ix->key) && !tref_isnil(ix->val);
211,900✔
1516
    if (tref_ref(xref) < rbref) {  /* HREFK forwarded? */
211,900✔
1517
      lj_ir_rollback(J, rbref);  /* Rollback to eliminate hmask guard. */
24,884✔
1518
      J->guardemit = rbguard;
24,884✔
1519
    }
1520
    if (tvisnil(oldv)) {  /* Previous value was nil? */
211,900✔
1521
      /* Need to duplicate the hasmm check for the early guards. */
1522
      int hasmm = 0;
11,203✔
1523
      if (ix->idxchain && mt) {
11,203✔
1524
        cTValue *mo = lj_tab_getstr(mt, mmname_str(J2G(J), MM_newindex));
59✔
1525
        hasmm = mo && !tvisnil(mo);
59✔
1526
      }
1527
      if (hasmm)
21✔
1528
        emitir(IRTG(loadop, IRT_NIL), xref, 0);  /* Guard for nil value. */
21✔
1529
      else if (xrefop == IR_HREF)
11,182✔
1530
        emitir(IRTG(oldv == niltvg(J2G(J)) ? IR_EQ : IR_NE, IRT_PGC),
8,821✔
1531
               xref, lj_ir_kkptr(J, niltvg(J2G(J))));
1532
      if (ix->idxchain && lj_record_mm_lookup(J, ix, MM_newindex)) {
11,203✔
1533
        lj_assertJ(hasmm, "inconsistent metamethod handling");
21✔
1534
        goto handlemm;
21✔
1535
      }
1536
      lj_assertJ(!hasmm, "inconsistent metamethod handling");
11,182✔
1537
      if (oldv == niltvg(J2G(J))) {  /* Need to insert a new key. */
11,182✔
1538
        TRef key = ix->key;
9,288✔
1539
        if (tref_isinteger(key)) {  /* NEWREF needs a TValue as a key. */
9,288✔
1540
          key = emitir(IRTN(IR_CONV), key, IRCONV_NUM_INT);
130✔
1541
        } else if (tref_isnum(key)) {
9,158✔
1542
          if (tref_isk(key)) {
69✔
1543
            if (tvismzero(&ix->keyv))
2✔
1544
              key = lj_ir_knum_zero(J);  /* Canonicalize -0.0 to +0.0. */
2✔
1545
          } else {
1546
            emitir(IRTG(IR_EQ, IRT_NUM), key, key);  /* Check for !NaN. */
67✔
1547
          }
1548
        }
1549
        xref = emitir(IRT(IR_NEWREF, IRT_PGC), ix->tab, key);
9,288✔
1550
        keybarrier = 0;  /* NEWREF already takes care of the key barrier. */
9,288✔
1551
#ifdef LUAJIT_ENABLE_TABLE_BUMP
1552
        if ((J->flags & JIT_F_OPT_SINK))  /* Avoid a separate flag. */
1553
          rec_idx_bump(J, ix);
1554
#endif
1555
      }
1556
    } else if (!lj_opt_fwd_wasnonnil(J, loadop, tref_ref(xref))) {
200,697✔
1557
      /* Cannot derive that the previous value was non-nil, must do checks. */
1558
      if (xrefop == IR_HREF)  /* Guard against store to niltv. */
173,921✔
1559
        emitir(IRTG(IR_NE, IRT_PGC), xref, lj_ir_kkptr(J, niltvg(J2G(J))));
28✔
1560
      if (ix->idxchain) {  /* Metamethod lookup required? */
173,921✔
1561
        /* A check for NULL metatable is cheaper (hoistable) than a load. */
1562
        if (!mt) {
173,912✔
1563
          TRef mtref = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_TAB_META);
173,896✔
1564
          emitir(IRTG(IR_EQ, IRT_TAB), mtref, lj_ir_knull(J, IRT_TAB));
173,896✔
1565
        } else {
1566
          IRType t = itype2irt(oldv);
16✔
1567
          emitir(IRTG(loadop, t), xref, 0);  /* Guard for non-nil value. */
16✔
1568
        }
1569
      }
1570
    } else {
1571
      keybarrier = 0;  /* Previous non-nil value kept the key alive. */
1572
    }
1573
    /* Convert int to number before storing. */
1574
    if (!LJ_DUALNUM && tref_isinteger(ix->val))
211,879✔
1575
      ix->val = emitir(IRTN(IR_CONV), ix->val, IRCONV_NUM_INT);
4,452✔
1576
    emitir(IRT(loadop+IRDELTA_L2S, tref_type(ix->val)), xref, ix->val);
211,879✔
1577
    if (keybarrier || tref_isgcv(ix->val))
211,879✔
1578
      emitir(IRT(IR_TBAR, IRT_NIL), ix->tab, 0);
180,142✔
1579
    /* Invalidate neg. metamethod cache for stores with certain string keys. */
1580
    if (!nommstr(J, ix->key)) {
420,597✔
1581
      TRef fref = emitir(IRT(IR_FREF, IRT_PGC), ix->tab, IRFL_TAB_NOMM);
13✔
1582
      emitir(IRT(IR_FSTORE, IRT_U8), fref, lj_ir_kint(J, 0));
13✔
1583
    }
1584
    J->needsnap = 1;
211,879✔
1585
    return 0;
211,879✔
1586
  }
1587
}
1588

1589
static void rec_tsetm(jit_State *J, BCReg ra, BCReg rn, int32_t i)
5✔
1590
{
1591
  RecordIndex ix;
5✔
1592
  cTValue *basev = J->L->base;
5✔
1593
  GCtab *t = tabV(&basev[ra-1]);
5✔
1594
  settabV(J->L, &ix.tabv, t);
5✔
1595
  ix.tab = getslot(J, ra-1);
5✔
1596
  ix.idxchain = 0;
5✔
1597
#ifdef LUAJIT_ENABLE_TABLE_BUMP
1598
  if ((J->flags & JIT_F_OPT_SINK)) {
1599
    if (t->asize < i+rn-ra)
1600
      lj_tab_reasize(J->L, t, i+rn-ra);
1601
    setnilV(&ix.keyv);
1602
    rec_idx_bump(J, &ix);
1603
  }
1604
#endif
1605
  for (; ra < rn; i++, ra++) {
14✔
1606
    setintV(&ix.keyv, i);
9✔
1607
    ix.key = lj_ir_kint(J, i);
9✔
1608
    copyTV(J->L, &ix.valv, &basev[ra]);
9✔
1609
    ix.val = getslot(J, ra);
9✔
1610
    lj_record_idx(J, &ix);
9✔
1611
  }
1612
}
5✔
1613

1614
/* -- Upvalue access ------------------------------------------------------ */
1615

1616
/* Check whether upvalue is immutable and ok to constify. */
1617
static int rec_upvalue_constify(jit_State *J, GCupval *uvp)
1618
{
1619
  if (uvp->immutable) {
1620
    cTValue *o = uvval(uvp);
1621
    /* Don't constify objects that may retain large amounts of memory. */
1622
#if LJ_HASFFI
1623
    if (tviscdata(o)) {
1624
      GCcdata *cd = cdataV(o);
1625
      if (!cdataisv(cd) && !(cd->marked & LJ_GC_CDATA_FIN)) {
1626
        CType *ct = ctype_raw(ctype_ctsG(J2G(J)), cd->ctypeid);
1627
        if (!ctype_hassize(ct->info) || ct->size <= 16)
1628
          return 1;
1629
      }
1630
      return 0;
1631
    }
1632
#else
1633
    UNUSED(J);
1634
#endif
1635
    if (!(tvistab(o) || tvisudata(o) || tvisthread(o)))
1636
      return 1;
1637
  }
1638
  return 0;
1639
}
1640

1641
/* Record upvalue load/store. */
1642
static TRef rec_upvalue(jit_State *J, uint32_t uv, TRef val)
704,409✔
1643
{
1644
  GCupval *uvp = &gcref(J->fn->l.uvptr[uv])->uv;
704,409✔
1645
  TRef fn = getcurrf(J);
704,409✔
1646
  IRRef uref;
704,409✔
1647
  int needbarrier = 0;
704,409✔
1648
  if (rec_upvalue_constify(J, uvp)) {  /* Try to constify immutable upvalue. */
704,409✔
1649
    TRef tr, kfunc;
650,048✔
1650
    lj_assertJ(val == 0, "bad usage");
650,048✔
1651
    if (!tref_isk(fn)) {  /* Late specialization of current function. */
650,048✔
1652
      if (J->pt->flags >= PROTO_CLC_POLY)
70,772✔
1653
        goto noconstify;
94✔
1654
      kfunc = lj_ir_kfunc(J, J->fn);
70,678✔
1655
      emitir(IRTG(IR_EQ, IRT_FUNC), fn, kfunc);
70,678✔
1656
#if LJ_FR2
1657
      J->base[-2] = kfunc;
70,678✔
1658
#else
1659
      J->base[-1] = kfunc | TREF_FRAME;
1660
#endif
1661
      fn = kfunc;
70,678✔
1662
    }
1663
    tr = lj_record_constify(J, uvval(uvp));
649,954✔
1664
    if (tr)
649,954✔
1665
      return tr;
1666
  }
1667
noconstify:
54,361✔
1668
  /* Note: this effectively limits LJ_MAX_UPVAL to 127. */
1669
  uv = (uv << 8) | (hashrot(uvp->dhash, uvp->dhash + HASH_BIAS) & 0xff);
54,455✔
1670
  if (!uvp->closed) {
54,455✔
1671
    uref = tref_ref(emitir(IRTG(IR_UREFO, IRT_PGC), fn, uv));
587✔
1672
    /* In current stack? */
1673
    if (uvval(uvp) >= tvref(J->L->stack) &&
587✔
1674
        uvval(uvp) < tvref(J->L->maxstack)) {
582✔
1675
      int32_t slot = (int32_t)(uvval(uvp) - (J->L->base - J->baseslot));
546✔
1676
      if (slot >= 0) {  /* Aliases an SSA slot? */
546✔
1677
        emitir(IRTG(IR_EQ, IRT_PGC),
232✔
1678
               REF_BASE,
1679
               emitir(IRT(IR_ADD, IRT_PGC), uref,
1680
                      lj_ir_kint(J, (slot - 1 - LJ_FR2) * -8)));
1681
        slot -= (int32_t)J->baseslot;  /* Note: slot number may be negative! */
232✔
1682
        if (val == 0) {
232✔
1683
          return getslot(J, slot);
113✔
1684
        } else {
1685
          J->base[slot] = val;
119✔
1686
          if (slot >= (int32_t)J->maxslot) J->maxslot = (BCReg)(slot+1);
119✔
1687
          return 0;
119✔
1688
        }
1689
      }
1690
    }
1691
    emitir(IRTG(IR_UGT, IRT_PGC),
355✔
1692
           emitir(IRT(IR_SUB, IRT_PGC), uref, REF_BASE),
1693
           lj_ir_kint(J, (J->baseslot + J->maxslot) * 8));
1694
  } else {
1695
    needbarrier = 1;
53,868✔
1696
    uref = tref_ref(emitir(IRTG(IR_UREFC, IRT_PGC), fn, uv));
53,868✔
1697
  }
1698
  if (val == 0) {  /* Upvalue load */
54,223✔
1699
    IRType t = itype2irt(uvval(uvp));
54,134✔
1700
    TRef res = emitir(IRTG(IR_ULOAD, t), uref, 0);
54,134✔
1701
    if (irtype_ispri(t)) res = TREF_PRI(t);  /* Canonicalize primitive refs. */
54,134✔
1702
    return res;
54,134✔
1703
  } else {  /* Upvalue store. */
1704
    /* Convert int to number before storing. */
1705
    if (!LJ_DUALNUM && tref_isinteger(val))
89✔
1706
      val = emitir(IRTN(IR_CONV), val, IRCONV_NUM_INT);
16✔
1707
    emitir(IRT(IR_USTORE, tref_type(val)), uref, val);
89✔
1708
    if (needbarrier && tref_isgcv(val))
89✔
1709
      emitir(IRT(IR_OBAR, IRT_NIL), uref, val);
4✔
1710
    J->needsnap = 1;
89✔
1711
    return 0;
89✔
1712
  }
1713
}
1714

1715
/* -- Record calls to Lua functions --------------------------------------- */
1716

1717
/* Check unroll limits for calls. */
1718
static void check_call_unroll(jit_State *J, TraceNo lnk)
506,152✔
1719
{
1720
  cTValue *frame = J->L->base - 1;
506,152✔
1721
  void *pc = mref(frame_func(frame)->l.pc, void);
506,152✔
1722
  int32_t depth = J->framedepth;
506,152✔
1723
  int32_t count = 0;
506,152✔
1724
  if ((J->pt->flags & PROTO_VARARG)) depth--;  /* Vararg frame still missing. */
506,152✔
1725
  for (; depth > 0; depth--) {  /* Count frames with same prototype. */
1,282,722✔
1726
    if (frame_iscont(frame)) depth--;
776,570✔
1727
    frame = frame_prev(frame);
776,570✔
1728
    if (mref(frame_func(frame)->l.pc, void) == pc)
776,570✔
1729
      count++;
1,476✔
1730
  }
1731
  if (J->pc == J->startpc) {
506,152✔
1732
    if (count + J->tailcalled > J->param[JIT_P_recunroll]) {
310✔
1733
      J->pc++;
98✔
1734
      if (J->framedepth + J->retdepth == 0)
98✔
1735
        lj_record_stop(J, LJ_TRLINK_TAILREC, J->cur.traceno);  /* Tail-rec. */
5✔
1736
      else
1737
        lj_record_stop(J, LJ_TRLINK_UPREC, J->cur.traceno);  /* Up-recursion. */
93✔
1738
    }
1739
  } else {
1740
    if (count > J->param[JIT_P_callunroll]) {
505,842✔
1741
      if (lnk) {  /* Possible tail- or up-recursion. */
74✔
1742
        lj_trace_flush(J, lnk);  /* Flush trace that only returns. */
20✔
1743
        /* Set a small, pseudo-random hotcount for a quick retry of JFUNC*. */
1744
        hotcount_set(J2GG(J), J->pc+1, LJ_PRNG_BITS(J, 4));
20✔
1745
      }
1746
      lj_trace_err(J, LJ_TRERR_CUNROLL);
74✔
1747
    }
1748
  }
1749
}
506,078✔
1750

1751
/* Record Lua function setup. */
1752
static void rec_func_setup(jit_State *J)
508,416✔
1753
{
1754
  GCproto *pt = J->pt;
508,416✔
1755
  BCReg s, numparams = pt->numparams;
508,416✔
1756
  if ((pt->flags & PROTO_NOJIT))
508,416✔
1757
    lj_trace_err(J, LJ_TRERR_CJITOFF);
×
1758
  if (J->baseslot + pt->framesize >= LJ_MAX_JSLOTS)
508,416✔
1759
    lj_trace_err(J, LJ_TRERR_STACKOV);
2✔
1760
  /* Fill up missing parameters with nil. */
1761
  for (s = J->maxslot; s < numparams; s++)
508,804✔
1762
    J->base[s] = TREF_NIL;
390✔
1763
  /* The remaining slots should never be read before they are written. */
1764
  J->maxslot = numparams;
508,414✔
1765
}
508,414✔
1766

1767
/* Record Lua vararg function setup. */
1768
static void rec_func_vararg(jit_State *J)
221✔
1769
{
1770
  GCproto *pt = J->pt;
221✔
1771
  BCReg s, fixargs, vframe = J->maxslot+1+LJ_FR2;
221✔
1772
  lj_assertJ((pt->flags & PROTO_VARARG), "FUNCV in non-vararg function");
221✔
1773
  if (J->baseslot + vframe + pt->framesize >= LJ_MAX_JSLOTS)
221✔
1774
    lj_trace_err(J, LJ_TRERR_STACKOV);
×
1775
  J->base[vframe-1-LJ_FR2] = J->base[-1-LJ_FR2];  /* Copy function up. */
221✔
1776
#if LJ_FR2
1777
  J->base[vframe-1] = TREF_FRAME;
221✔
1778
#endif
1779
  /* Copy fixarg slots up and set their original slots to nil. */
1780
  fixargs = pt->numparams < J->maxslot ? pt->numparams : J->maxslot;
221✔
1781
  for (s = 0; s < fixargs; s++) {
257✔
1782
    J->base[vframe+s] = J->base[s];
36✔
1783
    J->base[s] = TREF_NIL;
36✔
1784
  }
1785
  J->maxslot = fixargs;
221✔
1786
  J->framedepth++;
221✔
1787
  J->base += vframe;
221✔
1788
  J->baseslot += vframe;
221✔
1789
}
221✔
1790

1791
/* Record entry to a Lua function. */
1792
static void rec_func_lua(jit_State *J)
96,213✔
1793
{
1794
  rec_func_setup(J);
96,213✔
1795
  check_call_unroll(J, 0);
96,211✔
1796
}
96,157✔
1797

1798
/* Record entry to an already compiled function. */
1799
static void rec_func_jit(jit_State *J, TraceNo lnk)
412,203✔
1800
{
1801
  GCtrace *T;
412,203✔
1802
  rec_func_setup(J);
412,203✔
1803
  T = traceref(J, lnk);
412,203✔
1804
  if (T->linktype == LJ_TRLINK_RETURN) {  /* Trace returns to interpreter? */
412,203✔
1805
    check_call_unroll(J, lnk);
409,941✔
1806
    /* Temporarily unpatch JFUNC* to continue recording across function. */
1807
    J->patchins = *J->pc;
409,921✔
1808
    J->patchpc = (BCIns *)J->pc;
409,921✔
1809
    *J->patchpc = T->startins;
409,921✔
1810
    return;
409,921✔
1811
  }
1812
  J->instunroll = 0;  /* Cannot continue across a compiled function. */
2,262✔
1813
  if (J->pc == J->startpc && J->framedepth + J->retdepth == 0)
2,262✔
1814
    lj_record_stop(J, LJ_TRLINK_TAILREC, J->cur.traceno);  /* Extra tail-rec. */
×
1815
  else
1816
    lj_record_stop(J, LJ_TRLINK_ROOT, lnk);  /* Link to the function. */
2,262✔
1817
}
1818

1819
/* -- Vararg handling ----------------------------------------------------- */
1820

1821
/* Detect y = select(x, ...) idiom. */
1822
static int select_detect(jit_State *J)
16✔
1823
{
1824
  BCIns ins = J->pc[1];
16✔
1825
  if (bc_op(ins) == BC_CALLM && bc_b(ins) == 2 && bc_c(ins) == 1) {
16✔
1826
    cTValue *func = &J->L->base[bc_a(ins)];
14✔
1827
    if (tvisfunc(func) && funcV(func)->c.ffid == FF_select) {
14✔
1828
      TRef kfunc = lj_ir_kfunc(J, funcV(func));
10✔
1829
      emitir(IRTG(IR_EQ, IRT_FUNC), getslot(J, bc_a(ins)), kfunc);
10✔
1830
      return 1;
10✔
1831
    }
1832
  }
1833
  return 0;
1834
}
1835

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

1943
/* -- Record allocations -------------------------------------------------- */
1944

1945
static TRef rec_tnew(jit_State *J, uint32_t ah)
637✔
1946
{
1947
  uint32_t asize = ah & 0x7ff;
637✔
1948
  uint32_t hbits = ah >> 11;
637✔
1949
  TRef tr;
637✔
1950
  if (asize == 0x7ff) asize = 0x801;
×
1951
  tr = emitir(IRTG(IR_TNEW, IRT_TAB), asize, hbits);
637✔
1952
#ifdef LUAJIT_ENABLE_TABLE_BUMP
1953
  J->rbchash[(tr & (RBCHASH_SLOTS-1))].ref = tref_ref(tr);
1954
  setmref(J->rbchash[(tr & (RBCHASH_SLOTS-1))].pc, J->pc);
1955
  setgcref(J->rbchash[(tr & (RBCHASH_SLOTS-1))].pt, obj2gco(J->pt));
1956
#endif
1957
  return tr;
637✔
1958
}
1959

1960
/* -- Concatenation ------------------------------------------------------- */
1961

1962
typedef struct RecCatDataCP {
1963
  TValue savetv[5+LJ_FR2];
1964
  jit_State *J;
1965
  BCReg baseslot, topslot;
1966
  TRef tr;
1967
} RecCatDataCP;
1968

1969
static TValue *rec_mm_concat_cp(lua_State *L, lua_CFunction dummy, void *ud)
297✔
1970
{
1971
  RecCatDataCP *rcd = (RecCatDataCP *)ud;
297✔
1972
  jit_State *J = rcd->J;
297✔
1973
  BCReg baseslot = rcd->baseslot, topslot = rcd->topslot;
297✔
1974
  TRef *top = &J->base[topslot];
297✔
1975
  BCReg s;
297✔
1976
  RecordIndex ix;
297✔
1977
  UNUSED(L); UNUSED(dummy);
297✔
1978
  lj_assertJ(baseslot < topslot, "bad CAT arg");
297✔
1979
  for (s = baseslot; s <= topslot; s++)
1,064✔
1980
    (void)getslot(J, s);  /* Ensure all arguments have a reference. */
767✔
1981
  if (tref_isnumber_str(top[0]) && tref_isnumber_str(top[-1])) {
297✔
1982
    TRef tr, hdr, *trp, *xbase, *base = &J->base[baseslot];
285✔
1983
    /* First convert numbers to strings. */
1984
    for (trp = top; trp >= base; trp--) {
1,019✔
1985
      if (tref_isnumber(*trp))
736✔
1986
        *trp = emitir(IRT(IR_TOSTR, IRT_STR), *trp,
43✔
1987
                      tref_isnum(*trp) ? IRTOSTR_NUM : IRTOSTR_INT);
1988
      else if (!tref_isstr(*trp))
693✔
1989
        break;
1990
    }
1991
    xbase = ++trp;
285✔
1992
    tr = hdr = emitir(IRT(IR_BUFHDR, IRT_PGC),
285✔
1993
                      lj_ir_kptr(J, &J2G(J)->tmpbuf), IRBUFHDR_RESET);
1994
    do {
734✔
1995
      tr = emitir(IRT(IR_BUFPUT, IRT_PGC), tr, *trp++);
734✔
1996
    } while (trp <= top);
733✔
1997
    tr = emitir(IRT(IR_BUFSTR, IRT_STR), tr, hdr);
284✔
1998
    J->maxslot = (BCReg)(xbase - J->base);
284✔
1999
    if (xbase == base) {
284✔
2000
      rcd->tr = tr;  /* Return simple concatenation result. */
282✔
2001
      return NULL;
282✔
2002
    }
2003
    /* Pass partial result. */
2004
    rcd->topslot = topslot = J->maxslot--;
2✔
2005
    /* Save updated range of slots. */
2006
    memcpy(rcd->savetv, &L->base[topslot-1], sizeof(rcd->savetv));
2✔
2007
    *xbase = tr;
2✔
2008
    top = xbase;
2✔
2009
    setstrV(J->L, &ix.keyv, &J2G(J)->strempty);  /* Simulate string result. */
2✔
2010
  } else {
2011
    J->maxslot = topslot-1;
12✔
2012
    copyTV(J->L, &ix.keyv, &J->L->base[topslot]);
12✔
2013
  }
2014
  copyTV(J->L, &ix.tabv, &J->L->base[topslot-1]);
14✔
2015
  ix.tab = top[-1];
14✔
2016
  ix.key = top[0];
14✔
2017
  rec_mm_arith(J, &ix, MM_concat);  /* Call __concat metamethod. */
14✔
2018
  rcd->tr = 0;  /* No result yet. */
13✔
2019
  return NULL;
13✔
2020
}
2021

2022
static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
297✔
2023
{
2024
  lua_State *L = J->L;
297✔
2025
  ptrdiff_t delta = L->top - L->base;
297✔
2026
  TValue errobj;
297✔
2027
  RecCatDataCP rcd;
297✔
2028
  int errcode;
297✔
2029
  rcd.J = J;
297✔
2030
  rcd.baseslot = baseslot;
297✔
2031
  rcd.topslot = topslot;
297✔
2032
  /* Save slots. */
2033
  memcpy(rcd.savetv, &L->base[topslot-1], sizeof(rcd.savetv));
297✔
2034
  errcode = lj_vm_cpcall(L, NULL, &rcd, rec_mm_concat_cp);
297✔
2035
  if (errcode) copyTV(L, &errobj, L->top-1);
297✔
2036
  /* Restore slots. */
2037
  memcpy(&L->base[rcd.topslot-1], rcd.savetv, sizeof(rcd.savetv));
297✔
2038
  if (errcode) {
297✔
2039
    L->top = L->base + delta;
2✔
2040
    copyTV(L, L->top++, &errobj);
2✔
2041
    return (TRef)(-errcode);
2✔
2042
  }
2043
  return rcd.tr;
295✔
2044
}
2045

2046
/* -- Record bytecode ops ------------------------------------------------- */
2047

2048
/* Prepare for comparison. */
2049
static void rec_comp_prep(jit_State *J)
476,388✔
2050
{
2051
  /* Prevent merging with snapshot #0 (GC exit) since we fixup the PC. */
2052
  if (J->cur.nsnap == 1 && J->cur.snap[0].ref == J->cur.nins)
476,388✔
2053
    emitir_raw(IRT(IR_NOP, IRT_NIL), 0, 0);
276✔
2054
  lj_snap_add(J);
476,388✔
2055
}
476,388✔
2056

2057
/* Fixup comparison. */
2058
static void rec_comp_fixup(jit_State *J, const BCIns *pc, int cond)
494,392✔
2059
{
2060
  BCIns jmpins = pc[1];
494,392✔
2061
  const BCIns *npc = pc + 2 + (cond ? bc_j(jmpins) : 0);
494,392✔
2062
  SnapShot *snap = &J->cur.snap[J->cur.nsnap-1];
494,392✔
2063
  /* Set PC to opposite target to avoid re-recording the comp. in side trace. */
2064
#if LJ_FR2
2065
  SnapEntry *flink = &J->cur.snapmap[snap->mapofs + snap->nent];
494,392✔
2066
  uint64_t pcbase;
494,392✔
2067
  memcpy(&pcbase, flink, sizeof(uint64_t));
494,392✔
2068
  pcbase = (pcbase & 0xff) | (u64ptr(npc) << 8);
494,392✔
2069
  memcpy(flink, &pcbase, sizeof(uint64_t));
494,392✔
2070
#else
2071
  J->cur.snapmap[snap->mapofs + snap->nent] = SNAP_MKPC(npc);
2072
#endif
2073
  J->needsnap = 1;
494,392✔
2074
  if (bc_a(jmpins) < J->maxslot) J->maxslot = bc_a(jmpins);
494,392✔
2075
  lj_snap_shrink(J);  /* Shrink last snapshot if possible. */
494,392✔
2076
}
494,392✔
2077

2078
/* Record the next bytecode instruction (_before_ it's executed). */
2079
void lj_record_ins(jit_State *J)
5,201,186✔
2080
{
2081
  cTValue *lbase;
5,201,186✔
2082
  RecordIndex ix;
5,201,186✔
2083
  const BCIns *pc;
5,201,186✔
2084
  BCIns ins;
5,201,186✔
2085
  BCOp op;
5,201,186✔
2086
  TRef ra, rb, rc;
5,201,186✔
2087

2088
  /* Perform post-processing action before recording the next instruction. */
2089
  if (LJ_UNLIKELY(J->postproc != LJ_POST_NONE)) {
5,201,186✔
2090
    switch (J->postproc) {
242,549✔
2091
    case LJ_POST_FIXCOMP:  /* Fixup comparison. */
18,109✔
2092
      pc = (const BCIns *)(uintptr_t)J2G(J)->tmptv.u64;
18,109✔
2093
      rec_comp_fixup(J, pc, (!tvistruecond(&J2G(J)->tmptv2) ^ (bc_op(*pc)&1)));
18,109✔
2094
      /* fallthrough */
2095
    case LJ_POST_FIXGUARD:  /* Fixup and emit pending guard. */
25,526✔
2096
    case LJ_POST_FIXGUARDSNAP:  /* Fixup and emit pending guard and snapshot. */
2097
      if (!tvistruecond(&J2G(J)->tmptv2)) {
25,526✔
2098
        J->fold.ins.o ^= 1;  /* Flip guard to opposite. */
7,412✔
2099
        if (J->postproc == LJ_POST_FIXGUARDSNAP) {
7,412✔
2100
          SnapShot *snap = &J->cur.snap[J->cur.nsnap-1];
1✔
2101
          J->cur.snapmap[snap->mapofs+snap->nent-1]--;  /* False -> true. */
1✔
2102
        }
2103
      }
2104
      lj_opt_fold(J);  /* Emit pending guard. */
25,526✔
2105
      /* fallthrough */
2106
    case LJ_POST_FIXBOOL:
25,540✔
2107
      if (!tvistruecond(&J2G(J)->tmptv2)) {
25,540✔
2108
        BCReg s;
7,418✔
2109
        TValue *tv = J->L->base;
7,418✔
2110
        for (s = 0; s < J->maxslot; s++)  /* Fixup stack slot (if any). */
37,254✔
2111
          if (J->base[s] == TREF_TRUE && tvisfalse(&tv[s])) {
29,844✔
2112
            J->base[s] = TREF_FALSE;
8✔
2113
            break;
8✔
2114
          }
2115
      }
2116
      break;
2117
    case LJ_POST_FIXCONST:
2✔
2118
      {
2119
        BCReg s;
2✔
2120
        TValue *tv = J->L->base;
2✔
2121
        for (s = 0; s < J->maxslot; s++)  /* Constify stack slots (if any). */
18✔
2122
          if (J->base[s] == TREF_NIL && !tvisnil(&tv[s]))
16✔
2123
            J->base[s] = lj_record_constify(J, &tv[s]);
2✔
2124
      }
2125
      break;
2126
    case LJ_POST_FFRETRY:  /* Suppress recording of retried fast function. */
217,007✔
2127
      if (bc_op(*J->pc) >= BC__MAX)
217,007✔
2128
        return;
23✔
2129
      break;
2130
    default: lj_assertJ(0, "bad post-processing mode"); break;
2131
    }
2132
    J->postproc = LJ_POST_NONE;
242,546✔
2133
  }
2134

2135
  /* Need snapshot before recording next bytecode (e.g. after a store). */
2136
  if (J->needsnap) {
5,201,183✔
2137
    J->needsnap = 0;
791,950✔
2138
    if (J->pt && bc_op(*J->pc) < BC_FUNCF) lj_snap_purge(J);
791,950✔
2139
    lj_snap_add(J);
791,950✔
2140
    J->mergesnap = 1;
791,950✔
2141
  }
2142

2143
  /* Skip some bytecodes. */
2144
  if (LJ_UNLIKELY(J->bcskip > 0)) {
5,201,183✔
2145
    J->bcskip--;
20✔
2146
    return;
20✔
2147
  }
2148

2149
  /* Record only closed loops for root traces. */
2150
  pc = J->pc;
5,201,163✔
2151
  if (J->framedepth == 0 &&
5,201,163✔
2152
     (MSize)((char *)pc - (char *)J->bc_min) >= J->bc_extent)
1,578,094✔
2153
    lj_trace_err(J, LJ_TRERR_LLEAVE);
517✔
2154

2155
#ifdef LUA_USE_ASSERT
2156
  rec_check_slots(J);
2157
  rec_check_ir(J);
2158
#endif
2159

2160
#if LJ_HASPROFILE
2161
  rec_profile_ins(J, pc);
5,200,646✔
2162
#endif
2163

2164
  /* Keep a copy of the runtime values of var/num/str operands. */
2165
#define rav        (&ix.valv)
2166
#define rbv        (&ix.tabv)
2167
#define rcv        (&ix.keyv)
2168

2169
  lbase = J->L->base;
5,200,646✔
2170
  ins = *pc;
5,200,646✔
2171
  op = bc_op(ins);
5,200,646✔
2172
  ra = bc_a(ins);
5,200,646✔
2173
  ix.val = 0;
5,200,646✔
2174
  switch (bcmode_a(op)) {
5,200,646✔
2175
  case BCMvar:
741,863✔
2176
    copyTV(J->L, rav, &lbase[ra]); ix.val = ra = getslot(J, ra); break;
741,863✔
2177
  default: break;  /* Handled later. */
2178
  }
2179
  rb = bc_b(ins);
5,200,646✔
2180
  rc = bc_c(ins);
5,200,646✔
2181
  switch (bcmode_b(op)) {
5,200,646✔
2182
  case BCMnone: rb = 0; rc = bc_d(ins); break;  /* Upgrade rc to 'rd'. */
3,355,818✔
2183
  case BCMvar:
1,247,136✔
2184
    copyTV(J->L, rbv, &lbase[rb]); ix.tab = rb = getslot(J, rb); break;
1,247,136✔
2185
  default: break;  /* Handled later. */
2186
  }
2187
  switch (bcmode_c(op)) {
5,200,646✔
2188
  case BCMvar:
787,263✔
2189
    copyTV(J->L, rcv, &lbase[rc]); ix.key = rc = getslot(J, rc); break;
787,263✔
2190
  case BCMpri: setpriV(rcv, ~rc); ix.key = rc = TREF_PRI(IRT_NIL+rc); break;
379,485✔
2191
  case BCMnum: { cTValue *tv = proto_knumtv(J->pt, rc);
115,464✔
2192
    copyTV(J->L, rcv, tv); ix.key = rc = tvisint(tv) ? lj_ir_kint(J, intV(tv)) :
115,464✔
2193
    lj_ir_knumint(J, numV(tv)); } break;
115,464✔
2194
  case BCMstr: { GCstr *s = gco2str(proto_kgc(J->pt, ~(ptrdiff_t)rc));
994,709✔
2195
    setstrV(J->L, rcv, s); ix.key = rc = lj_ir_kstr(J, s); } break;
994,709✔
2196
  default: break;  /* Handled later. */
2197
  }
2198

2199
  switch (op) {
5,200,646✔
2200

2201
  /* -- Comparison ops ---------------------------------------------------- */
2202

2203
  case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
168,776✔
2204
#if LJ_HASFFI
2205
    if (tref_iscdata(ra) || tref_iscdata(rc)) {
168,776✔
2206
      rec_mm_comp_cdata(J, &ix, op, ((int)op & 2) ? MM_le : MM_lt);
18,089✔
2207
      break;
18,089✔
2208
    }
2209
#endif
2210
    /* Emit nothing for two numeric or string consts. */
2211
    if (!(tref_isk2(ra,rc) && tref_isnumber_str(ra) && tref_isnumber_str(rc))) {
150,687✔
2212
      IRType ta = tref_isinteger(ra) ? IRT_INT : tref_type(ra);
131,479✔
2213
      IRType tc = tref_isinteger(rc) ? IRT_INT : tref_type(rc);
131,479✔
2214
      int irop;
131,479✔
2215
      if (ta != tc) {
131,479✔
2216
        /* Widen mixed number/int comparisons to number/number comparison. */
2217
        if (ta == IRT_INT && tc == IRT_NUM) {
126,662✔
2218
          ra = emitir(IRTN(IR_CONV), ra, IRCONV_NUM_INT);
64,066✔
2219
          ta = IRT_NUM;
64,066✔
2220
        } else if (ta == IRT_NUM && tc == IRT_INT) {
62,596✔
2221
          rc = emitir(IRTN(IR_CONV), rc, IRCONV_NUM_INT);
62,593✔
2222
        } else if (LJ_52) {
3✔
2223
          ta = IRT_NIL;  /* Force metamethod for different types. */
2224
        } else if (!((ta == IRT_FALSE || ta == IRT_TRUE) &&
3✔
2225
                     (tc == IRT_FALSE || tc == IRT_TRUE))) {
×
2226
          break;  /* Interpreter will throw for two different types. */
2227
        }
2228
      }
2229
      rec_comp_prep(J);
131,476✔
2230
      irop = (int)op - (int)BC_ISLT + (int)IR_LT;
131,476✔
2231
      if (ta == IRT_NUM) {
131,476✔
2232
        if ((irop & 1)) irop ^= 4;  /* ISGE/ISGT are unordered. */
131,349✔
2233
        if (!lj_ir_numcmp(numberVnum(rav), numberVnum(rcv), (IROp)irop))
131,349✔
2234
          irop ^= 5;
125,990✔
2235
      } else if (ta == IRT_INT) {
127✔
2236
        if (!lj_ir_numcmp(numberVnum(rav), numberVnum(rcv), (IROp)irop))
77✔
2237
          irop ^= 1;
20✔
2238
      } else if (ta == IRT_STR) {
50✔
2239
        if (!lj_ir_strcmp(strV(rav), strV(rcv), (IROp)irop)) irop ^= 1;
1✔
2240
        ra = lj_ir_call(J, IRCALL_lj_str_cmp, ra, rc);
1✔
2241
        rc = lj_ir_kint(J, 0);
1✔
2242
        ta = IRT_INT;
1✔
2243
      } else {
2244
        rec_mm_comp(J, &ix, (int)op);
49✔
2245
        break;
49✔
2246
      }
2247
      emitir(IRTG(irop, ta), ra, rc);
131,427✔
2248
      rec_comp_fixup(J, J->pc, ((int)op ^ irop) & 1);
131,427✔
2249
    }
2250
    break;
2251

2252
  case BC_ISEQV: case BC_ISNEV:
361,054✔
2253
  case BC_ISEQS: case BC_ISNES:
2254
  case BC_ISEQN: case BC_ISNEN:
2255
  case BC_ISEQP: case BC_ISNEP:
2256
#if LJ_HASFFI
2257
    if (tref_iscdata(ra) || tref_iscdata(rc)) {
361,054✔
2258
      rec_mm_comp_cdata(J, &ix, op, MM_eq);
7,433✔
2259
      break;
7,433✔
2260
    }
2261
#endif
2262
    /* Emit nothing for two non-table, non-udata consts. */
2263
    if (!(tref_isk2(ra, rc) && !(tref_istab(ra) || tref_isudata(ra)))) {
353,621✔
2264
      int diff;
344,912✔
2265
      rec_comp_prep(J);
344,912✔
2266
      diff = lj_record_objcmp(J, ra, rc, rav, rcv);
344,912✔
2267
      if (diff == 2 || !(tref_istab(ra) || tref_isudata(ra)))
344,912✔
2268
        rec_comp_fixup(J, J->pc, ((int)op & 1) == !diff);
344,856✔
2269
      else if (diff == 1)  /* Only check __eq if different, but same type. */
56✔
2270
        rec_mm_equal(J, &ix, (int)op);
10✔
2271
    }
2272
    break;
2273

2274
  /* -- Unary test and copy ops ------------------------------------------- */
2275

2276
  case BC_ISTC: case BC_ISFC:
244✔
2277
    if ((op & 1) == tref_istruecond(rc))
244✔
2278
      rc = 0;  /* Don't store if condition is not true. */
218✔
2279
    /* fallthrough */
2280
  case BC_IST: case BC_ISF:  /* Type specialization suffices. */
2281
    if (bc_a(pc[1]) < J->maxslot)
41,173✔
2282
      J->maxslot = bc_a(pc[1]);  /* Shrink used slots. */
25,502✔
2283
    break;
2284

2285
  case BC_ISTYPE: case BC_ISNUM:
2286
    /* These coercions need to correspond with lj_meta_istype(). */
2287
    if (LJ_DUALNUM && rc == ~LJ_TNUMX+1)
13✔
2288
      ra = lj_opt_narrow_toint(J, ra);
2289
    else if (rc == ~LJ_TNUMX+2)
13✔
2290
      ra = lj_ir_tonum(J, ra);
2✔
2291
    else if (rc == ~LJ_TSTR+1)
11✔
2292
      ra = lj_ir_tostr(J, ra);
6✔
2293
    /* else: type specialization suffices. */
2294
    J->base[bc_a(ins)] = ra;
13✔
2295
    break;
13✔
2296

2297
  /* -- Unary ops --------------------------------------------------------- */
2298

2299
  case BC_NOT:
4✔
2300
    /* Type specialization already forces const result. */
2301
    rc = tref_istruecond(rc) ? TREF_FALSE : TREF_TRUE;
4✔
2302
    break;
2303

2304
  case BC_LEN:
57✔
2305
    if (tref_isstr(rc))
57✔
2306
      rc = emitir(IRTI(IR_FLOAD), rc, IRFL_STR_LEN);
7✔
2307
    else if (!LJ_52 && tref_istab(rc))
50✔
2308
      rc = lj_ir_call(J, IRCALL_lj_tab_len, rc);
48✔
2309
    else
2310
      rc = rec_mm_len(J, rc, rcv);
2✔
2311
    break;
2312

2313
  /* -- Arithmetic ops ---------------------------------------------------- */
2314

2315
  case BC_UNM:
38✔
2316
    if (tref_isnumber_str(rc)) {
38✔
2317
      rc = lj_opt_narrow_unm(J, rc, rcv);
35✔
2318
    } else {
2319
      ix.tab = rc;
3✔
2320
      copyTV(J->L, &ix.tabv, rcv);
3✔
2321
      rc = rec_mm_arith(J, &ix, MM_unm);
3✔
2322
    }
2323
    break;
2324

2325
  case BC_ADDNV: case BC_SUBNV: case BC_MULNV: case BC_DIVNV: case BC_MODNV:
68,723✔
2326
    /* Swap rb/rc and rbv/rcv. rav is temp. */
2327
    ix.tab = rc; ix.key = rc = rb; rb = ix.tab;
68,723✔
2328
    copyTV(J->L, rav, rbv);
68,723✔
2329
    copyTV(J->L, rbv, rcv);
68,723✔
2330
    copyTV(J->L, rcv, rav);
68,723✔
2331
    if (op == BC_MODNV)
68,723✔
2332
      goto recmod;
2✔
2333
    /* fallthrough */
2334
  case BC_ADDVN: case BC_SUBVN: case BC_MULVN: case BC_DIVVN:
2335
  case BC_ADDVV: case BC_SUBVV: case BC_MULVV: case BC_DIVVV: {
2336
    MMS mm = bcmode_mm(op);
246,323✔
2337
    if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
246,323✔
2338
      rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv,
207,280✔
2339
                               (int)mm - (int)MM_add + (int)IR_ADD);
207,280✔
2340
    else
2341
      rc = rec_mm_arith(J, &ix, mm);
39,043✔
2342
    break;
2343
    }
2344

2345
  case BC_MODVN: case BC_MODVV:
2346
  recmod:
87✔
2347
    if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
87✔
2348
      rc = lj_opt_narrow_mod(J, rb, rc, rbv, rcv);
82✔
2349
    else
2350
      rc = rec_mm_arith(J, &ix, MM_mod);
5✔
2351
    break;
2352

2353
  case BC_POW:
10,604✔
2354
    if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
10,604✔
2355
      rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv, IR_POW);
10,598✔
2356
    else
2357
      rc = rec_mm_arith(J, &ix, MM_pow);
6✔
2358
    break;
2359

2360
  /* -- Miscellaneous ops ------------------------------------------------- */
2361

2362
  case BC_CAT:
291✔
2363
    rc = rec_cat(J, rb, rc);
291✔
2364
    if (rc >= 0xffffff00)
291✔
2365
      lj_err_throw(J->L, -(int32_t)rc);  /* Propagate errors. */
×
2366
    break;
2367

2368
  /* -- Constant and move ops --------------------------------------------- */
2369

2370
  case BC_MOV:
363,635✔
2371
    /* Clear gap of method call to avoid resurrecting previous refs. */
2372
    if (ra > J->maxslot) {
363,635✔
2373
#if LJ_FR2
2374
      memset(J->base + J->maxslot, 0, (ra - J->maxslot) * sizeof(TRef));
275,902✔
2375
#else
2376
      J->base[ra-1] = 0;
2377
#endif
2378
    }
2379
    break;
2380
  case BC_KSTR: case BC_KNUM: case BC_KPRI:
2381
    break;
2382
  case BC_KSHORT:
183,321✔
2383
    rc = lj_ir_kint(J, (int32_t)(int16_t)rc);
183,321✔
2384
    break;
183,321✔
2385
  case BC_KNIL:
21✔
2386
    if (LJ_FR2 && ra > J->maxslot)
21✔
2387
      J->base[ra-1] = 0;
1✔
2388
    while (ra <= rc)
1,207✔
2389
      J->base[ra++] = TREF_NIL;
1,186✔
2390
    if (rc >= J->maxslot) J->maxslot = rc+1;
21✔
2391
    break;
2392
#if LJ_HASFFI
2393
  case BC_KCDATA:
61✔
2394
    rc = lj_ir_kgc(J, proto_kgc(J->pt, ~(ptrdiff_t)rc), IRT_CDATA);
61✔
2395
    break;
61✔
2396
#endif
2397

2398
  /* -- Upvalue and function ops ------------------------------------------ */
2399

2400
  case BC_UGET:
704,201✔
2401
    rc = rec_upvalue(J, rc, 0);
704,201✔
2402
    break;
704,201✔
2403
  case BC_USETV: case BC_USETS: case BC_USETN: case BC_USETP:
208✔
2404
    rec_upvalue(J, ra, rc);
208✔
2405
    break;
208✔
2406

2407
  /* -- Table ops --------------------------------------------------------- */
2408

2409
  case BC_GGET: case BC_GSET:
5,021✔
2410
    settabV(J->L, &ix.tabv, tabref(J->fn->l.env));
5,021✔
2411
    ix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), getcurrf(J), IRFL_FUNC_ENV);
5,021✔
2412
    ix.idxchain = LJ_MAX_IDXCHAIN;
5,021✔
2413
    rc = lj_record_idx(J, &ix);
5,021✔
2414
    break;
5,021✔
2415

2416
  case BC_TGETB: case BC_TSETB:
778✔
2417
    setintV(&ix.keyv, (int32_t)rc);
778✔
2418
    ix.key = lj_ir_kint(J, (int32_t)rc);
778✔
2419
    /* fallthrough */
2420
  case BC_TGETV: case BC_TGETS: case BC_TSETV: case BC_TSETS:
990,096✔
2421
    ix.idxchain = LJ_MAX_IDXCHAIN;
990,096✔
2422
    rc = lj_record_idx(J, &ix);
990,096✔
2423
    break;
990,096✔
2424
  case BC_TGETR: case BC_TSETR:
26✔
2425
    ix.idxchain = 0;
26✔
2426
    rc = lj_record_idx(J, &ix);
26✔
2427
    break;
26✔
2428

2429
  case BC_TSETM:
5✔
2430
    rec_tsetm(J, ra, (BCReg)(J->L->top - J->L->base), (int32_t)rcv->u32.lo);
5✔
2431
    J->maxslot = ra;  /* The table slot at ra-1 is the highest used slot. */
5✔
2432
    break;
5✔
2433

2434
  case BC_TNEW:
2435
    rc = rec_tnew(J, rc);
637✔
2436
    break;
637✔
2437
  case BC_TDUP:
418✔
2438
    rc = emitir(IRTG(IR_TDUP, IRT_TAB),
418✔
2439
                lj_ir_ktab(J, gco2tab(proto_kgc(J->pt, ~(ptrdiff_t)rc))), 0);
2440
#ifdef LUAJIT_ENABLE_TABLE_BUMP
2441
    J->rbchash[(rc & (RBCHASH_SLOTS-1))].ref = tref_ref(rc);
2442
    setmref(J->rbchash[(rc & (RBCHASH_SLOTS-1))].pc, pc);
2443
    setgcref(J->rbchash[(rc & (RBCHASH_SLOTS-1))].pt, obj2gco(J->pt));
2444
#endif
2445
    break;
418✔
2446

2447
  /* -- Calls and vararg handling ----------------------------------------- */
2448

2449
  case BC_ITERC:
222✔
2450
    J->base[ra] = getslot(J, ra-3);
222✔
2451
    J->base[ra+1+LJ_FR2] = getslot(J, ra-2);
222✔
2452
    J->base[ra+2+LJ_FR2] = getslot(J, ra-1);
222✔
2453
    { /* Do the actual copy now because lj_record_call needs the values. */
2454
      TValue *b = &J->L->base[ra];
222✔
2455
      copyTV(J->L, b, b-3);
222✔
2456
      copyTV(J->L, b+1+LJ_FR2, b-2);
222✔
2457
      copyTV(J->L, b+2+LJ_FR2, b-1);
222✔
2458
    }
2459
    lj_record_call(J, ra, (ptrdiff_t)rc-1);
222✔
2460
    break;
222✔
2461

2462
  /* L->top is set to L->base+ra+rc+NARGS-1+1. See lj_dispatch_ins(). */
2463
  case BC_CALLM:
79,309✔
2464
    rc = (BCReg)(J->L->top - J->L->base) - ra - LJ_FR2;
79,309✔
2465
    /* fallthrough */
2466
  case BC_CALL:
597,031✔
2467
    lj_record_call(J, ra, (ptrdiff_t)rc-1);
597,031✔
2468
    break;
597,031✔
2469

2470
  case BC_CALLMT:
14✔
2471
    rc = (BCReg)(J->L->top - J->L->base) - ra - LJ_FR2;
14✔
2472
    /* fallthrough */
2473
  case BC_CALLT:
65,197✔
2474
    lj_record_tailcall(J, ra, (ptrdiff_t)rc-1);
65,197✔
2475
    break;
65,197✔
2476

2477
  case BC_VARG:
148✔
2478
    rec_varg(J, ra, (ptrdiff_t)rb-1);
148✔
2479
    break;
148✔
2480

2481
  /* -- Returns ----------------------------------------------------------- */
2482

2483
  case BC_RETM:
32✔
2484
    /* L->top is set to L->base+ra+rc+NRESULTS-1, see lj_dispatch_ins(). */
2485
    rc = (BCReg)(J->L->top - J->L->base) - ra + 1;
32✔
2486
    /* fallthrough */
2487
  case BC_RET: case BC_RET0: case BC_RET1:
508,812✔
2488
#if LJ_HASPROFILE
2489
    rec_profile_ret(J);
508,812✔
2490
#endif
2491
    lj_record_ret(J, ra, (ptrdiff_t)rc-1);
508,812✔
2492
    break;
508,812✔
2493

2494
  /* -- Loops and branches ------------------------------------------------ */
2495

2496
  case BC_FORI:
288✔
2497
    if (rec_for(J, pc, 0) != LOOPEV_LEAVE)
288✔
2498
      J->loopref = J->cur.nins;
282✔
2499
    break;
2500
  case BC_JFORI:
105✔
2501
    lj_assertJ(bc_op(pc[(ptrdiff_t)rc-BCBIAS_J]) == BC_JFORL,
105✔
2502
               "JFORI does not point to JFORL");
2503
    if (rec_for(J, pc, 0) != LOOPEV_LEAVE)  /* Link to existing loop. */
105✔
2504
      lj_record_stop(J, LJ_TRLINK_ROOT, bc_d(pc[(ptrdiff_t)rc-BCBIAS_J]));
102✔
2505
    /* Continue tracing if the loop is not entered. */
2506
    break;
2507

2508
  case BC_FORL:
4,859✔
2509
    rec_loop_interp(J, pc, rec_for(J, pc+((ptrdiff_t)rc-BCBIAS_J), 1));
4,859✔
2510
    break;
4,859✔
2511
  case BC_ITERL:
51✔
2512
    rec_loop_interp(J, pc, rec_iterl(J, *pc));
51✔
2513
    break;
51✔
2514
  case BC_LOOP:
17,766✔
2515
    rec_loop_interp(J, pc, rec_loop(J, ra, 1));
17,766✔
2516
    break;
17,766✔
2517

2518
  case BC_JFORL:
388✔
2519
    rec_loop_jit(J, rc, rec_for(J, pc+bc_j(traceref(J, rc)->startins), 1));
388✔
2520
    break;
388✔
2521
  case BC_JITERL:
69✔
2522
    rec_loop_jit(J, rc, rec_iterl(J, traceref(J, rc)->startins));
69✔
2523
    break;
69✔
2524
  case BC_JLOOP:
6,338✔
2525
    rec_loop_jit(J, rc, rec_loop(J, ra,
12,676✔
2526
                                 !bc_isret(bc_op(traceref(J, rc)->startins))));
6,338✔
2527
    break;
6,338✔
2528

2529
  case BC_IFORL:
2✔
2530
  case BC_IITERL:
2531
  case BC_ILOOP:
2532
  case BC_IFUNCF:
2533
  case BC_IFUNCV:
2534
    lj_trace_err(J, LJ_TRERR_BLACKL);
2✔
2535
    break;
81,062✔
2536

2537
  case BC_JMP:
81,062✔
2538
    if (ra < J->maxslot)
81,062✔
2539
      J->maxslot = ra;  /* Shrink used slots. */
73,003✔
2540
    break;
2541

2542
  /* -- Function headers -------------------------------------------------- */
2543

2544
  case BC_FUNCF:
2545
    rec_func_lua(J);
95,992✔
2546
    break;
2547
  case BC_JFUNCF:
412,203✔
2548
    rec_func_jit(J, rc);
412,203✔
2549
    break;
412,203✔
2550

2551
  case BC_FUNCV:
221✔
2552
    rec_func_vararg(J);
221✔
2553
    rec_func_lua(J);
221✔
2554
    break;
2555
  case BC_JFUNCV:
2556
    /* Cannot happen. No hotcall counting for varag funcs. */
2557
    lj_assertJ(0, "unsupported vararg hotcall");
2558
    break;
2559

2560
  case BC_FUNCC:
117,462✔
2561
  case BC_FUNCCW:
2562
    lj_ffrecord_func(J);
117,462✔
2563
    break;
117,462✔
2564

2565
  default:
125,694✔
2566
    if (op >= BC__MAX) {
125,694✔
2567
      lj_ffrecord_func(J);
125,694✔
2568
      break;
125,694✔
2569
    }
2570
    /* fallthrough */
2571
  case BC_ITERN:
2572
  case BC_ISNEXT:
2573
  case BC_UCLO:
2574
  case BC_FNEW:
2575
    setintV(&J->errinfo, (int32_t)op);
74✔
2576
    lj_trace_err_info(J, LJ_TRERR_NYIBC);
74✔
2577
    break;
5,198,392✔
2578
  }
2579

2580
  /* rc == 0 if we have no result yet, e.g. pending __index metamethod call. */
2581
  if (bcmode_a(op) == BCMdst && rc) {
5,198,392✔
2582
    J->base[ra] = rc;
2,318,679✔
2583
    if (ra >= J->maxslot) {
2,318,679✔
2584
#if LJ_FR2
2585
      if (ra > J->maxslot) J->base[ra-1] = 0;
1,822,943✔
2586
#endif
2587
      J->maxslot = ra+1;
1,822,943✔
2588
    }
2589
  }
2590

2591
#undef rav
2592
#undef rbv
2593
#undef rcv
2594

2595
  /* Limit the number of recorded IR instructions and constants. */
2596
  if (J->cur.nins > REF_FIRST+(IRRef)J->param[JIT_P_maxrecord] ||
5,198,392✔
2597
      J->cur.nk < REF_BIAS-(IRRef)J->param[JIT_P_maxirconst])
5,198,392✔
2598
    lj_trace_err(J, LJ_TRERR_TRACEOV);
2✔
2599
}
2600

2601
/* -- Recording setup ----------------------------------------------------- */
2602

2603
/* Setup recording for a root trace started by a hot loop. */
2604
static const BCIns *rec_setup_root(jit_State *J)
7,284✔
2605
{
2606
  /* Determine the next PC and the bytecode range for the loop. */
2607
  const BCIns *pcj, *pc = J->pc;
7,284✔
2608
  BCIns ins = *pc;
7,284✔
2609
  BCReg ra = bc_a(ins);
7,284✔
2610
  switch (bc_op(ins)) {
7,284✔
2611
  case BC_FORL:
4,486✔
2612
    J->bc_extent = (MSize)(-bc_j(ins))*sizeof(BCIns);
4,486✔
2613
    pc += 1+bc_j(ins);
4,486✔
2614
    J->bc_min = pc;
4,486✔
2615
    break;
4,486✔
2616
  case BC_ITERL:
48✔
2617
    lj_assertJ(bc_op(pc[-1]) == BC_ITERC, "no ITERC before ITERL");
48✔
2618
    J->maxslot = ra + bc_b(pc[-1]) - 1;
48✔
2619
    J->bc_extent = (MSize)(-bc_j(ins))*sizeof(BCIns);
48✔
2620
    pc += 1+bc_j(ins);
48✔
2621
    lj_assertJ(bc_op(pc[-1]) == BC_JMP, "ITERL does not point to JMP+1");
48✔
2622
    J->bc_min = pc;
48✔
2623
    break;
48✔
2624
  case BC_LOOP:
1,105✔
2625
    /* Only check BC range for real loops, but not for "repeat until true". */
2626
    pcj = pc + bc_j(ins);
1,105✔
2627
    ins = *pcj;
1,105✔
2628
    if (bc_op(ins) == BC_JMP && bc_j(ins) < 0) {
1,105✔
2629
      J->bc_min = pcj+1 + bc_j(ins);
1,102✔
2630
      J->bc_extent = (MSize)(-bc_j(ins))*sizeof(BCIns);
1,102✔
2631
    }
2632
    J->maxslot = ra;
1,105✔
2633
    pc++;
1,105✔
2634
    break;
1,105✔
2635
  case BC_RET:
1✔
2636
  case BC_RET0:
2637
  case BC_RET1:
2638
    /* No bytecode range check for down-recursive root traces. */
2639
    J->maxslot = ra + bc_d(ins) - 1;
1✔
2640
    break;
1✔
2641
  case BC_FUNCF:
1,524✔
2642
    /* No bytecode range check for root traces started by a hot call. */
2643
    J->maxslot = J->pt->numparams;
1,524✔
2644
    pc++;
1,524✔
2645
    break;
1,524✔
2646
  case BC_CALLM:
120✔
2647
  case BC_CALL:
2648
  case BC_ITERC:
2649
    /* No bytecode range check for stitched traces. */
2650
    pc++;
120✔
2651
    break;
120✔
2652
  default:
2653
    lj_assertJ(0, "bad root trace start bytecode %d", bc_op(ins));
2654
    break;
2655
  }
2656
  return pc;
7,284✔
2657
}
2658

2659
/* Setup for recording a new trace. */
2660
void lj_record_setup(jit_State *J)
18,320✔
2661
{
2662
  uint32_t i;
18,320✔
2663

2664
  /* Initialize state related to current trace. */
2665
  memset(J->slot, 0, sizeof(J->slot));
18,320✔
2666
  memset(J->chain, 0, sizeof(J->chain));
18,320✔
2667
#ifdef LUAJIT_ENABLE_TABLE_BUMP
2668
  memset(J->rbchash, 0, sizeof(J->rbchash));
2669
#endif
2670
  memset(J->bpropcache, 0, sizeof(J->bpropcache));
18,320✔
2671
  J->scev.idx = REF_NIL;
18,320✔
2672
  setmref(J->scev.pc, NULL);
18,320✔
2673

2674
  J->baseslot = 1+LJ_FR2;  /* Invoking function is at base[-1-LJ_FR2]. */
18,320✔
2675
  J->base = J->slot + J->baseslot;
18,320✔
2676
  J->maxslot = 0;
18,320✔
2677
  J->framedepth = 0;
18,320✔
2678
  J->retdepth = 0;
18,320✔
2679

2680
  J->instunroll = J->param[JIT_P_instunroll];
18,320✔
2681
  J->loopunroll = J->param[JIT_P_loopunroll];
18,320✔
2682
  J->tailcalled = 0;
18,320✔
2683
  J->loopref = 0;
18,320✔
2684

2685
  J->bc_min = NULL;  /* Means no limit. */
18,320✔
2686
  J->bc_extent = ~(MSize)0;
18,320✔
2687

2688
  /* Emit instructions for fixed references. Also triggers initial IR alloc. */
2689
  emitir_raw(IRT(IR_BASE, IRT_PGC), J->parent, J->exitno);
18,320✔
2690
  for (i = 0; i <= 2; i++) {
91,600✔
2691
    IRIns *ir = IR(REF_NIL-i);
54,960✔
2692
    ir->i = 0;
54,960✔
2693
    ir->t.irt = (uint8_t)(IRT_NIL+i);
54,960✔
2694
    ir->o = IR_KPRI;
54,960✔
2695
    ir->prev = 0;
54,960✔
2696
  }
2697
  J->cur.nk = REF_TRUE;
18,320✔
2698

2699
  J->startpc = J->pc;
18,320✔
2700
  setmref(J->cur.startpc, J->pc);
18,320✔
2701
  if (J->parent) {  /* Side trace. */
18,320✔
2702
    GCtrace *T = traceref(J, J->parent);
11,036✔
2703
    TraceNo root = T->root ? T->root : J->parent;
11,036✔
2704
    J->cur.root = (uint16_t)root;
11,036✔
2705
    J->cur.startins = BCINS_AD(BC_JMP, 0, 0);
11,036✔
2706
    /* Check whether we could at least potentially form an extra loop. */
2707
    if (J->exitno == 0 && T->snap[0].nent == 0) {
11,036✔
2708
      /* We can narrow a FORL for some side traces, too. */
2709
      if (J->pc > proto_bc(J->pt) && bc_op(J->pc[-1]) == BC_JFORI &&
1,607✔
2710
          bc_d(J->pc[bc_j(J->pc[-1])-1]) == root) {
193✔
2711
        lj_snap_add(J);
193✔
2712
        rec_for_loop(J, J->pc-1, &J->scev, 1);
193✔
2713
        goto sidecheck;
193✔
2714
      }
2715
    } else {
2716
      J->startpc = NULL;  /* Prevent forming an extra loop. */
9,429✔
2717
    }
2718
    lj_snap_replay(J, T);
10,843✔
2719
  sidecheck:
11,036✔
2720
    if (traceref(J, J->cur.root)->nchild >= J->param[JIT_P_maxside] ||
11,036✔
2721
        T->snap[J->exitno].count >= J->param[JIT_P_hotexit] +
11,035✔
2722
                                    J->param[JIT_P_tryside]) {
11,035✔
2723
      lj_record_stop(J, LJ_TRLINK_INTERP, 0);
425✔
2724
    }
2725
  } else {  /* Root trace. */
2726
    J->cur.root = 0;
7,284✔
2727
    J->cur.startins = *J->pc;
7,284✔
2728
    J->pc = rec_setup_root(J);
7,284✔
2729
    /* Note: the loop instruction itself is recorded at the end and not
2730
    ** at the start! So snapshot #0 needs to point to the *next* instruction.
2731
    */
2732
    lj_snap_add(J);
7,284✔
2733
    if (bc_op(J->cur.startins) == BC_FORL)
7,284✔
2734
      rec_for_loop(J, J->pc-1, &J->scev, 1);
4,486✔
2735
    else if (bc_op(J->cur.startins) == BC_ITERC)
2,798✔
2736
      J->startpc = NULL;
7✔
2737
    if (1 + J->pt->framesize >= LJ_MAX_JSLOTS)
7,284✔
2738
      lj_trace_err(J, LJ_TRERR_STACKOV);
1✔
2739
  }
2740
#if LJ_HASPROFILE
2741
  J->prev_pt = NULL;
18,319✔
2742
  J->prev_line = -1;
18,319✔
2743
#endif
2744
#ifdef LUAJIT_ENABLE_CHECKHOOK
2745
  /* Regularly check for instruction/line hooks from compiled code and
2746
  ** exit to the interpreter if the hooks are set.
2747
  **
2748
  ** This is a compile-time option and disabled by default, since the
2749
  ** hook checks may be quite expensive in tight loops.
2750
  **
2751
  ** Note this is only useful if hooks are *not* set most of the time.
2752
  ** Use this only if you want to *asynchronously* interrupt the execution.
2753
  **
2754
  ** You can set the instruction hook via lua_sethook() with a count of 1
2755
  ** from a signal handler or another native thread. Please have a look
2756
  ** at the first few functions in luajit.c for an example (Ctrl-C handler).
2757
  */
2758
  {
2759
    TRef tr = emitir(IRT(IR_XLOAD, IRT_U8),
2760
                     lj_ir_kptr(J, &J2G(J)->hookmask), IRXLOAD_VOLATILE);
2761
    tr = emitir(IRTI(IR_BAND), tr, lj_ir_kint(J, (LUA_MASKLINE|LUA_MASKCOUNT)));
2762
    emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, 0));
2763
  }
2764
#endif
2765
}
18,319✔
2766

2767
#undef IR
2768
#undef emitir_raw
2769
#undef emitir
2770

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

© 2026 Coveralls, Inc