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

tarantool / luajit / 12298038079

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

push

github

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

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

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

5673 of 6014 branches covered (94.33%)

Branch coverage included in aggregate %.

21609 of 23357 relevant lines covered (92.52%)

868792.21 hits per line

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

96.29
/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)
81,483✔
188
{
189
  /* Caller may set IRT_GUARD in t. */
190
  TRef ref = emitir_raw(IRT(IR_SLOAD, t), (int32_t)J->baseslot+slot, mode);
162,966✔
191
  J->base[slot] = ref;
81,483✔
192
  return ref;
81,483✔
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)
176,594✔
197
{
198
  IRType t = itype2irt(&J->L->base[slot]);
176,594✔
199
  TRef ref = emitir_raw(IRTG(IR_SLOAD, t), (int32_t)J->baseslot+slot,
176,594✔
200
                        IRSLOAD_TYPECHECK);
201
  if (irtype_ispri(t)) ref = TREF_PRI(t);  /* Canonicalize primitive refs. */
176,594✔
202
  J->base[slot] = ref;
176,594✔
203
  return ref;
176,594✔
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)
744,351✔
211
{
212
  if (J->base[-1-LJ_FR2])
744,351✔
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");
78,372✔
216
  return sloadt(J, -1-LJ_FR2, IRT_FUNC, IRSLOAD_READONLY);
78,372✔
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)
366,581✔
226
{
227
  int diff = !lj_obj_equal(av, bv);
366,581✔
228
  if (!tref_isk2(a, b)) {  /* Shortcut, also handles primitives. */
366,581✔
229
    IRType ta = tref_isinteger(a) ? IRT_INT : tref_type(a);
366,580✔
230
    IRType tb = tref_isinteger(b) ? IRT_INT : tref_type(b);
366,580✔
231
    if (ta != tb) {
366,580✔
232
      /* Widen mixed number/int comparisons to number/number comparison. */
233
      if (ta == IRT_INT && tb == IRT_NUM) {
340,759✔
234
        a = emitir(IRTN(IR_CONV), a, IRCONV_NUM_INT);
3✔
235
        ta = IRT_NUM;
3✔
236
      } else if (ta == IRT_NUM && tb == IRT_INT) {
340,756✔
237
        b = emitir(IRTN(IR_CONV), b, IRCONV_NUM_INT);
161✔
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,842✔
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)
684,581✔
249
{
250
  if (tvisgcv(o))
684,581✔
251
    return lj_ir_kgc(J, gcV(o), itype2irt(o));
622,079✔
252
  else if (tvisint(o))
62,502✔
253
    return lj_ir_kint(J, intV(o));
254
  else if (tvisnum(o))
62,502✔
255
    return lj_ir_knumint(J, numV(o));
62,502✔
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,595✔
273
{
274
  BCReg s;
11,595✔
275
  if (LJ_DUALNUM) return;
11,595✔
276
  for (s = J->baseslot+J->maxslot-1; s >= 1; s--) {
184,727✔
277
    TRef tr = J->slot[s];
173,133✔
278
    if (tref_isinteger(tr)) {
173,133✔
279
      IRIns *ir = IR(tref_ref(tr));
20,890✔
280
      if (!(ir->o == IR_SLOAD && (ir->op2 & IRSLOAD_READONLY)))
20,890✔
281
        J->slot[s] = emitir(IRTN(IR_CONV), tr, IRCONV_NUM_INT);
20,812✔
282
    }
283
  }
284
}
285

286
/* Stop recording. */
287
void lj_record_stop(jit_State *J, TraceLink linktype, TraceNo lnk)
13,327✔
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);
13,327✔
294
  J->cur.linktype = (uint8_t)linktype;
13,327✔
295
  J->cur.link = (uint16_t)lnk;
13,327✔
296
  /* Looping back at the same stack level? */
297
  if (lnk == J->cur.traceno && J->framedepth + J->retdepth == 0) {
13,327✔
298
    if ((J->flags & JIT_F_OPT_LOOP))  /* Shall we try to create a loop? */
2,445✔
299
      goto nocanon;  /* Do not canonicalize or we lose the narrowing. */
1,732✔
300
    if (J->cur.root)  /* Otherwise ensure we always link to the root trace. */
713✔
301
      J->cur.link = J->cur.root;
1✔
302
  }
303
  canonicalize_slots(J);
11,595✔
304
nocanon:
13,326✔
305
  /* Note: all loop ops must set J->pc to the following instruction! */
306
  lj_snap_add(J);  /* Add loop snapshot. */
13,326✔
307
  J->needsnap = 0;
13,324✔
308
  J->mergesnap = 1;  /* In case recording continues. */
13,324✔
309
}
13,324✔
310

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

643
#if LJ_HASPROFILE
644

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

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

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

686
#endif
687

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

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

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

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

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

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

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

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

962
/* -- Metamethod handling ------------------------------------------------- */
963

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

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

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

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

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

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

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

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

1223
/* -- Indexed access ------------------------------------------------------ */
1224

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

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

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

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

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

1402
/* Determine whether a key is NOT one of the fast metamethod names. */
1403
static int nommstr(jit_State *J, TRef key)
218,395✔
1404
{
1405
  if (tref_isstr(key)) {
218,395✔
1406
    if (tref_isk(key)) {
215,348✔
1407
      GCstr *str = ir_kstr(IR(tref_ref(key)));
215,335✔
1408
      uint32_t mm;
215,335✔
1409
      for (mm = 0; mm <= MM_FAST; mm++)
1,507,340✔
1410
        if (mmname_str(J2G(J), mm) == str)
1,292,006✔
1411
          return 0;  /* MUST be one the fast metamethod names. */
1412
    } else {
1413
      return 0;  /* Variable string key MAY be a metamethod name. */
1414
    }
1415
  }
1416
  return 1;  /* CANNOT be a metamethod name. */
1417
}
1418

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

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

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

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

1477
  if (ix->val == 0) {  /* Indexed load */
1,062,957✔
1478
    IRType t = itype2irt(oldv);
844,550✔
1479
    TRef res;
844,550✔
1480
    if (oldv == niltvg(J2G(J))) {
844,550✔
1481
      emitir(IRTG(IR_EQ, IRT_PGC), xref, lj_ir_kkptr(J, niltvg(J2G(J))));
32,616✔
1482
      res = TREF_NIL;
32,616✔
1483
    } else {
1484
      res = emitir(IRTG(loadop, t), xref, 0);
811,934✔
1485
    }
1486
    if (tref_ref(res) < rbref) {  /* HREFK + load forwarded? */
844,550✔
1487
      lj_ir_rollback(J, rbref);  /* Rollback to eliminate hmask guard. */
377,886✔
1488
      J->guardemit = rbguard;
377,886✔
1489
    }
1490
    if (t == IRT_NIL && ix->idxchain && lj_record_mm_lookup(J, ix, MM_index))
844,550✔
1491
      goto handlemm;
24,010✔
1492
    if (irtype_ispri(t)) res = TREF_PRI(t);  /* Canonicalize primitives. */
820,540✔
1493
    return res;
820,540✔
1494
  } else {  /* Indexed store. */
1495
    GCtab *mt = tabref(tabV(&ix->tabv)->metatable);
218,407✔
1496
    int keybarrier = tref_isgcv(ix->key) && !tref_isnil(ix->val);
218,407✔
1497
    if (tref_ref(xref) < rbref) {  /* HREFK forwarded? */
218,407✔
1498
      lj_ir_rollback(J, rbref);  /* Rollback to eliminate hmask guard. */
24,558✔
1499
      J->guardemit = rbguard;
24,558✔
1500
    }
1501
    if (tvisnil(oldv)) {  /* Previous value was nil? */
218,407✔
1502
      /* Need to duplicate the hasmm check for the early guards. */
1503
      int hasmm = 0;
10,404✔
1504
      if (ix->idxchain && mt) {
10,404✔
1505
        cTValue *mo = lj_tab_getstr(mt, mmname_str(J2G(J), MM_newindex));
40✔
1506
        hasmm = mo && !tvisnil(mo);
40✔
1507
      }
1508
      if (hasmm)
12✔
1509
        emitir(IRTG(loadop, IRT_NIL), xref, 0);  /* Guard for nil value. */
12✔
1510
      else if (xrefop == IR_HREF)
10,392✔
1511
        emitir(IRTG(oldv == niltvg(J2G(J)) ? IR_EQ : IR_NE, IRT_PGC),
8,113✔
1512
               xref, lj_ir_kkptr(J, niltvg(J2G(J))));
1513
      if (ix->idxchain && lj_record_mm_lookup(J, ix, MM_newindex)) {
10,404✔
1514
        lj_assertJ(hasmm, "inconsistent metamethod handling");
12✔
1515
        goto handlemm;
12✔
1516
      }
1517
      lj_assertJ(!hasmm, "inconsistent metamethod handling");
10,392✔
1518
      if (oldv == niltvg(J2G(J))) {  /* Need to insert a new key. */
10,392✔
1519
        TRef key = ix->key;
8,513✔
1520
        if (tref_isinteger(key)) {  /* NEWREF needs a TValue as a key. */
8,513✔
1521
          key = emitir(IRTN(IR_CONV), key, IRCONV_NUM_INT);
134✔
1522
        } else if (tref_isnum(key)) {
8,379✔
1523
          if (tref_isk(key)) {
72✔
1524
            if (tvismzero(&ix->keyv))
2✔
1525
              key = lj_ir_knum_zero(J);  /* Canonicalize -0.0 to +0.0. */
2✔
1526
          } else {
1527
            emitir(IRTG(IR_EQ, IRT_NUM), key, key);  /* Check for !NaN. */
70✔
1528
          }
1529
        }
1530
        xref = emitir(IRT(IR_NEWREF, IRT_PGC), ix->tab, key);
8,513✔
1531
        keybarrier = 0;  /* NEWREF already takes care of the key barrier. */
8,513✔
1532
#ifdef LUAJIT_ENABLE_TABLE_BUMP
1533
        if ((J->flags & JIT_F_OPT_SINK))  /* Avoid a separate flag. */
1534
          rec_idx_bump(J, ix);
1535
#endif
1536
      }
1537
    } else if (!lj_opt_fwd_wasnonnil(J, loadop, tref_ref(xref))) {
208,003✔
1538
      /* Cannot derive that the previous value was non-nil, must do checks. */
1539
      if (xrefop == IR_HREF)  /* Guard against store to niltv. */
181,511✔
1540
        emitir(IRTG(IR_NE, IRT_PGC), xref, lj_ir_kkptr(J, niltvg(J2G(J))));
28✔
1541
      if (ix->idxchain) {  /* Metamethod lookup required? */
181,511✔
1542
        /* A check for NULL metatable is cheaper (hoistable) than a load. */
1543
        if (!mt) {
181,502✔
1544
          TRef mtref = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_TAB_META);
181,483✔
1545
          emitir(IRTG(IR_EQ, IRT_TAB), mtref, lj_ir_knull(J, IRT_TAB));
181,483✔
1546
        } else {
1547
          IRType t = itype2irt(oldv);
19✔
1548
          emitir(IRTG(loadop, t), xref, 0);  /* Guard for non-nil value. */
19✔
1549
        }
1550
      }
1551
    } else {
1552
      keybarrier = 0;  /* Previous non-nil value kept the key alive. */
1553
    }
1554
    /* Convert int to number before storing. */
1555
    if (!LJ_DUALNUM && tref_isinteger(ix->val))
218,395✔
1556
      ix->val = emitir(IRTN(IR_CONV), ix->val, IRCONV_NUM_INT);
2,394✔
1557
    emitir(IRT(loadop+IRDELTA_L2S, tref_type(ix->val)), xref, ix->val);
218,395✔
1558
    if (keybarrier || tref_isgcv(ix->val))
218,395✔
1559
      emitir(IRT(IR_TBAR, IRT_NIL), ix->tab, 0);
187,896✔
1560
    /* Invalidate neg. metamethod cache for stores with certain string keys. */
1561
    if (!nommstr(J, ix->key)) {
433,730✔
1562
      TRef fref = emitir(IRT(IR_FREF, IRT_PGC), ix->tab, IRFL_TAB_NOMM);
14✔
1563
      emitir(IRT(IR_FSTORE, IRT_U8), fref, lj_ir_kint(J, 0));
14✔
1564
    }
1565
    J->needsnap = 1;
218,395✔
1566
    return 0;
218,395✔
1567
  }
1568
}
1569

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

1595
/* -- Upvalue access ------------------------------------------------------ */
1596

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

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

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

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

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

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

1772
/* Record entry to a Lua function. */
1773
static void rec_func_lua(jit_State *J)
91,256✔
1774
{
1775
  rec_func_setup(J);
91,256✔
1776
  check_call_unroll(J, 0);
91,256✔
1777
}
91,199✔
1778

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

1800
/* -- Vararg handling ----------------------------------------------------- */
1801

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

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

1924
/* -- Record allocations -------------------------------------------------- */
1925

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

1941
/* -- Concatenation ------------------------------------------------------- */
1942

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

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

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

2007
/* -- Record bytecode ops ------------------------------------------------- */
2008

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

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

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

2049
  /* Perform post-processing action before recording the next instruction. */
2050
  if (LJ_UNLIKELY(J->postproc != LJ_POST_NONE)) {
5,458,059✔
2051
    switch (J->postproc) {
244,832✔
2052
    case LJ_POST_FIXCOMP:  /* Fixup comparison. */
17,811✔
2053
      pc = (const BCIns *)(uintptr_t)J2G(J)->tmptv.u64;
17,811✔
2054
      rec_comp_fixup(J, pc, (!tvistruecond(&J2G(J)->tmptv2) ^ (bc_op(*pc)&1)));
17,811✔
2055
      /* fallthrough */
2056
    case LJ_POST_FIXGUARD:  /* Fixup and emit pending guard. */
25,624✔
2057
    case LJ_POST_FIXGUARDSNAP:  /* Fixup and emit pending guard and snapshot. */
2058
      if (!tvistruecond(&J2G(J)->tmptv2)) {
25,624✔
2059
        J->fold.ins.o ^= 1;  /* Flip guard to opposite. */
7,810✔
2060
        if (J->postproc == LJ_POST_FIXGUARDSNAP) {
7,810✔
2061
          SnapShot *snap = &J->cur.snap[J->cur.nsnap-1];
1✔
2062
          J->cur.snapmap[snap->mapofs+snap->nent-1]--;  /* False -> true. */
1✔
2063
        }
2064
      }
2065
      lj_opt_fold(J);  /* Emit pending guard. */
25,624✔
2066
      /* fallthrough */
2067
    case LJ_POST_FIXBOOL:
25,638✔
2068
      if (!tvistruecond(&J2G(J)->tmptv2)) {
25,638✔
2069
        BCReg s;
7,816✔
2070
        TValue *tv = J->L->base;
7,816✔
2071
        for (s = 0; s < J->maxslot; s++)  /* Fixup stack slot (if any). */
39,223✔
2072
          if (J->base[s] == TREF_TRUE && tvisfalse(&tv[s])) {
31,415✔
2073
            J->base[s] = TREF_FALSE;
8✔
2074
            break;
8✔
2075
          }
2076
      }
2077
      break;
2078
    case LJ_POST_FIXCONST:
2✔
2079
      {
2080
        BCReg s;
2✔
2081
        TValue *tv = J->L->base;
2✔
2082
        for (s = 0; s < J->maxslot; s++)  /* Constify stack slots (if any). */
18✔
2083
          if (J->base[s] == TREF_NIL && !tvisnil(&tv[s]))
16✔
2084
            J->base[s] = lj_record_constify(J, &tv[s]);
2✔
2085
      }
2086
      break;
2087
    case LJ_POST_FFRETRY:  /* Suppress recording of retried fast function. */
219,192✔
2088
      if (bc_op(*J->pc) >= BC__MAX)
219,192✔
2089
        return;
21✔
2090
      break;
2091
    default: lj_assertJ(0, "bad post-processing mode"); break;
2092
    }
2093
    J->postproc = LJ_POST_NONE;
244,829✔
2094
  }
2095

2096
  /* Need snapshot before recording next bytecode (e.g. after a store). */
2097
  if (J->needsnap) {
5,458,056✔
2098
    J->needsnap = 0;
835,569✔
2099
    lj_snap_purge(J);
835,569✔
2100
    lj_snap_add(J);
835,569✔
2101
    J->mergesnap = 1;
835,569✔
2102
  }
2103

2104
  /* Skip some bytecodes. */
2105
  if (LJ_UNLIKELY(J->bcskip > 0)) {
5,458,056✔
2106
    J->bcskip--;
18✔
2107
    return;
18✔
2108
  }
2109

2110
  /* Record only closed loops for root traces. */
2111
  pc = J->pc;
5,458,038✔
2112
  if (J->framedepth == 0 &&
5,458,038✔
2113
     (MSize)((char *)pc - (char *)J->bc_min) >= J->bc_extent)
1,670,765✔
2114
    lj_trace_err(J, LJ_TRERR_LLEAVE);
495✔
2115

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

2121
#if LJ_HASPROFILE
2122
  rec_profile_ins(J, pc);
5,457,543✔
2123
#endif
2124

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

2130
  lbase = J->L->base;
5,457,543✔
2131
  ins = *pc;
5,457,543✔
2132
  op = bc_op(ins);
5,457,543✔
2133
  ra = bc_a(ins);
5,457,543✔
2134
  ix.val = 0;
5,457,543✔
2135
  switch (bcmode_a(op)) {
5,457,543✔
2136
  case BCMvar:
781,093✔
2137
    copyTV(J->L, rav, &lbase[ra]); ix.val = ra = getslot(J, ra); break;
781,093✔
2138
  default: break;  /* Handled later. */
2139
  }
2140
  rb = bc_b(ins);
5,457,543✔
2141
  rc = bc_c(ins);
5,457,543✔
2142
  switch (bcmode_b(op)) {
5,457,543✔
2143
  case BCMnone: rb = 0; rc = bc_d(ins); break;  /* Upgrade rc to 'rd'. */
3,529,906✔
2144
  case BCMvar:
1,297,337✔
2145
    copyTV(J->L, rbv, &lbase[rb]); ix.tab = rb = getslot(J, rb); break;
1,297,337✔
2146
  default: break;  /* Handled later. */
2147
  }
2148
  switch (bcmode_c(op)) {
5,457,543✔
2149
  case BCMvar:
818,448✔
2150
    copyTV(J->L, rcv, &lbase[rc]); ix.key = rc = getslot(J, rc); break;
818,448✔
2151
  case BCMpri: setpriV(rcv, ~rc); ix.key = rc = TREF_PRI(IRT_NIL+rc); break;
402,135✔
2152
  case BCMnum: { cTValue *tv = proto_knumtv(J->pt, rc);
120,071✔
2153
    copyTV(J->L, rcv, tv); ix.key = rc = tvisint(tv) ? lj_ir_kint(J, intV(tv)) :
120,071✔
2154
    lj_ir_knumint(J, numV(tv)); } break;
120,071✔
2155
  case BCMstr: { GCstr *s = gco2str(proto_kgc(J->pt, ~(ptrdiff_t)rc));
1,038,755✔
2156
    setstrV(J->L, rcv, s); ix.key = rc = lj_ir_kstr(J, s); } break;
1,038,755✔
2157
  default: break;  /* Handled later. */
2158
  }
2159

2160
  switch (op) {
5,457,543✔
2161

2162
  /* -- Comparison ops ---------------------------------------------------- */
2163

2164
  case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
178,615✔
2165
#if LJ_HASFFI
2166
    if (tref_iscdata(ra) || tref_iscdata(rc)) {
178,615✔
2167
      rec_mm_comp_cdata(J, &ix, op, ((int)op & 2) ? MM_le : MM_lt);
17,792✔
2168
      break;
17,792✔
2169
    }
2170
#endif
2171
    /* Emit nothing for two numeric or string consts. */
2172
    if (!(tref_isk2(ra,rc) && tref_isnumber_str(ra) && tref_isnumber_str(rc))) {
160,823✔
2173
      IRType ta = tref_isinteger(ra) ? IRT_INT : tref_type(ra);
142,048✔
2174
      IRType tc = tref_isinteger(rc) ? IRT_INT : tref_type(rc);
142,048✔
2175
      int irop;
142,048✔
2176
      if (ta != tc) {
142,048✔
2177
        /* Widen mixed number/int comparisons to number/number comparison. */
2178
        if (ta == IRT_INT && tc == IRT_NUM) {
136,464✔
2179
          ra = emitir(IRTN(IR_CONV), ra, IRCONV_NUM_INT);
69,086✔
2180
          ta = IRT_NUM;
69,086✔
2181
        } else if (ta == IRT_NUM && tc == IRT_INT) {
67,378✔
2182
          rc = emitir(IRTN(IR_CONV), rc, IRCONV_NUM_INT);
67,378✔
2183
        } else if (LJ_52) {
×
2184
          ta = IRT_NIL;  /* Force metamethod for different types. */
2185
        } else if (!((ta == IRT_FALSE || ta == IRT_TRUE) &&
×
2186
                     (tc == IRT_FALSE || tc == IRT_TRUE))) {
×
2187
          break;  /* Interpreter will throw for two different types. */
2188
        }
2189
      }
2190
      rec_comp_prep(J);
142,048✔
2191
      irop = (int)op - (int)BC_ISLT + (int)IR_LT;
142,048✔
2192
      if (ta == IRT_NUM) {
142,048✔
2193
        if ((irop & 1)) irop ^= 4;  /* ISGE/ISGT are unordered. */
141,915✔
2194
        if (!lj_ir_numcmp(numberVnum(rav), numberVnum(rcv), (IROp)irop))
141,915✔
2195
          irop ^= 5;
135,892✔
2196
      } else if (ta == IRT_INT) {
133✔
2197
        if (!lj_ir_numcmp(numberVnum(rav), numberVnum(rcv), (IROp)irop))
83✔
2198
          irop ^= 1;
21✔
2199
      } else if (ta == IRT_STR) {
50✔
2200
        if (!lj_ir_strcmp(strV(rav), strV(rcv), (IROp)irop)) irop ^= 1;
1✔
2201
        ra = lj_ir_call(J, IRCALL_lj_str_cmp, ra, rc);
1✔
2202
        rc = lj_ir_kint(J, 0);
1✔
2203
        ta = IRT_INT;
1✔
2204
      } else {
2205
        rec_mm_comp(J, &ix, (int)op);
49✔
2206
        break;
49✔
2207
      }
2208
      emitir(IRTG(irop, ta), ra, rc);
141,999✔
2209
      rec_comp_fixup(J, J->pc, ((int)op ^ irop) & 1);
141,999✔
2210
    }
2211
    break;
2212

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

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

2237
  case BC_ISTC: case BC_ISFC:
213✔
2238
    if ((op & 1) == tref_istruecond(rc))
213✔
2239
      rc = 0;  /* Don't store if condition is not true. */
187✔
2240
    /* fallthrough */
2241
  case BC_IST: case BC_ISF:  /* Type specialization suffices. */
2242
    if (bc_a(pc[1]) < J->maxslot)
41,998✔
2243
      J->maxslot = bc_a(pc[1]);  /* Shrink used slots. */
25,559✔
2244
    break;
2245

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

2258
  /* -- Unary ops --------------------------------------------------------- */
2259

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

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

2274
  /* -- Arithmetic ops ---------------------------------------------------- */
2275

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

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

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

2314
  case BC_POW:
9,839✔
2315
    if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
9,839✔
2316
      rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv, IR_POW);
9,833✔
2317
    else
2318
      rc = rec_mm_arith(J, &ix, MM_pow);
6✔
2319
    break;
2320

2321
  /* -- Miscellaneous ops ------------------------------------------------- */
2322

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

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

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

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

2361
  case BC_UGET:
739,288✔
2362
    rc = rec_upvalue(J, rc, 0);
739,288✔
2363
    break;
739,288✔
2364
  case BC_USETV: case BC_USETS: case BC_USETN: case BC_USETP:
200✔
2365
    rec_upvalue(J, ra, rc);
200✔
2366
    break;
200✔
2367

2368
  /* -- Table ops --------------------------------------------------------- */
2369

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

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

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

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

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

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

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

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

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

2442
  /* -- Returns ----------------------------------------------------------- */
2443

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

2455
  /* -- Loops and branches ------------------------------------------------ */
2456

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

2469
  case BC_FORL:
2,433✔
2470
    rec_loop_interp(J, pc, rec_for(J, pc+((ptrdiff_t)rc-BCBIAS_J), 1));
2,433✔
2471
    break;
2,433✔
2472
  case BC_ITERL:
50✔
2473
    rec_loop_interp(J, pc, rec_iterl(J, *pc));
50✔
2474
    break;
50✔
2475
  case BC_LOOP:
17,406✔
2476
    rec_loop_interp(J, pc, rec_loop(J, ra, 1));
17,406✔
2477
    break;
17,406✔
2478

2479
  case BC_JFORL:
383✔
2480
    rec_loop_jit(J, rc, rec_for(J, pc+bc_j(traceref(J, rc)->startins), 1));
383✔
2481
    break;
383✔
2482
  case BC_JITERL:
60✔
2483
    rec_loop_jit(J, rc, rec_iterl(J, traceref(J, rc)->startins));
60✔
2484
    break;
60✔
2485
  case BC_JLOOP:
6,907✔
2486
    rec_loop_jit(J, rc, rec_loop(J, ra,
13,814✔
2487
                                 !bc_isret(bc_op(traceref(J, rc)->startins))));
6,907✔
2488
    break;
6,907✔
2489

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

2498
  case BC_JMP:
86,482✔
2499
    if (ra < J->maxslot)
86,482✔
2500
      J->maxslot = ra;  /* Shrink used slots. */
78,023✔
2501
    break;
2502

2503
  /* -- Function headers -------------------------------------------------- */
2504

2505
  case BC_FUNCF:
2506
    rec_func_lua(J);
91,150✔
2507
    break;
2508
  case BC_JFUNCF:
450,892✔
2509
    rec_func_jit(J, rc);
450,892✔
2510
    break;
450,892✔
2511

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

2521
  case BC_FUNCC:
115,727✔
2522
  case BC_FUNCCW:
2523
    lj_ffrecord_func(J);
115,727✔
2524
    break;
115,727✔
2525

2526
  default:
129,537✔
2527
    if (op >= BC__MAX) {
129,537✔
2528
      lj_ffrecord_func(J);
129,537✔
2529
      break;
129,537✔
2530
    }
2531
    /* fallthrough */
2532
  case BC_ITERN:
2533
  case BC_ISNEXT:
2534
  case BC_UCLO:
2535
  case BC_FNEW:
2536
    setintV(&J->errinfo, (int32_t)op);
72✔
2537
    lj_trace_err_info(J, LJ_TRERR_NYIBC);
72✔
2538
    break;
5,455,382✔
2539
  }
2540

2541
  /* rc == 0 if we have no result yet, e.g. pending __index metamethod call. */
2542
  if (bcmode_a(op) == BCMdst && rc) {
5,455,382✔
2543
    J->base[ra] = rc;
2,427,620✔
2544
    if (ra >= J->maxslot) {
2,427,620✔
2545
#if LJ_FR2
2546
      if (ra > J->maxslot) J->base[ra-1] = 0;
1,928,152✔
2547
#endif
2548
      J->maxslot = ra+1;
1,928,152✔
2549
    }
2550
  }
2551

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

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

2562
/* -- Recording setup ----------------------------------------------------- */
2563

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

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

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

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

2641
  J->instunroll = J->param[JIT_P_instunroll];
16,796✔
2642
  J->loopunroll = J->param[JIT_P_loopunroll];
16,796✔
2643
  J->tailcalled = 0;
16,796✔
2644
  J->loopref = 0;
16,796✔
2645

2646
  J->bc_min = NULL;  /* Means no limit. */
16,796✔
2647
  J->bc_extent = ~(MSize)0;
16,796✔
2648

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

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

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

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

© 2025 Coveralls, Inc