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

tarantool / luajit / 9593251616

20 Jun 2024 07:14AM UTC coverage: 92.646% (+0.02%) from 92.624%
9593251616

push

github

Buristan
cmake: fix warning about minimum required version

Since CMake 3.27 compatibility with versions of CMake older than
3.5 is deprecated [1]. CMake produces an annoying warning on the
configuration stage:

| CMake Deprecation Warning at src/CMakeLists.txt:7 (cmake_minimum_required):
|  Compatibility with CMake < 3.5 will be removed from a future version of
|  CMake.

We cannot bump a minimum required CMake version without bumping it in
the Tarantool build system. However, we can set a <policy_max>
(introduced in CMake 3.12, see [1]) and suppress a warning. <policy_max>
means that this CMake version is known to work properly and will not
result in any build errors right away for higher versions.

Note that the current CMake minimum required version in Tarantool is
equal to 2.8, but <policy_max> is introduced in CMake 3.12 [1].
However, according to [1] it is not a problem because if CMake is "older
than 3.12, the extra ... dots will be seen as version component
separators, resulting in the ...<max> part being ignored and preserving
the pre-3.12 behavior of basing policies on <min>".

<policy_max> is set to 3.18 because compatibility with versions of CMake
older than 2.8.12 is deprecated. Calls to
cmake_minimum_required(VERSION) that do not specify at least 2.8.12 as
their policy version (optionally via ...<max>) will produce a
deprecation warning in CMake 3.19 and above [2]. Compatibility with
2.8.12 is needed for CMP0002 [3], see commit 049e296ee114 ("test: run
LuaJIT tests via CMake").

1. https://cmake.org/cmake/help/latest/command/cmake_minimum_required.html
2. https://cmake.org/cmake/help/latest/command/cmake_minimum_required.html#policy-settings
3. https://cmake.org/cmake/help/latest/policy/CMP0002.html

5665 of 6021 branches covered (94.09%)

Branch coverage included in aggregate %.

21621 of 23431 relevant lines covered (92.28%)

2937993.42 hits per line

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

96.36
/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)
104,898✔
188
{
189
  /* Caller may set IRT_GUARD in t. */
190
  TRef ref = emitir_raw(IRT(IR_SLOAD, t), (int32_t)J->baseslot+slot, mode);
209,796✔
191
  J->base[slot] = ref;
104,898✔
192
  return ref;
104,898✔
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)
228,570✔
197
{
198
  IRType t = itype2irt(&J->L->base[slot]);
228,570✔
199
  TRef ref = emitir_raw(IRTG(IR_SLOAD, t), (int32_t)J->baseslot+slot,
228,570✔
200
                        IRSLOAD_TYPECHECK);
201
  if (irtype_ispri(t)) ref = TREF_PRI(t);  /* Canonicalize primitive refs. */
228,570✔
202
  J->base[slot] = ref;
228,570✔
203
  return ref;
228,570✔
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)
940,776✔
211
{
212
  if (J->base[-1-LJ_FR2])
940,776✔
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");
102,055✔
216
  return sloadt(J, -1-LJ_FR2, IRT_FUNC, IRSLOAD_READONLY);
102,055✔
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)
476,321✔
226
{
227
  int diff = !lj_obj_equal(av, bv);
476,321✔
228
  if (!tref_isk2(a, b)) {  /* Shortcut, also handles primitives. */
476,321✔
229
    IRType ta = tref_isinteger(a) ? IRT_INT : tref_type(a);
476,321✔
230
    IRType tb = tref_isinteger(b) ? IRT_INT : tref_type(b);
476,321✔
231
    if (ta != tb) {
476,321✔
232
      /* Widen mixed number/int comparisons to number/number comparison. */
233
      if (ta == IRT_INT && tb == IRT_NUM) {
446,358✔
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) {
446,355✔
237
        b = emitir(IRTN(IR_CONV), b, IRCONV_NUM_INT);
153✔
238
      } else {
239
        return 2;  /* Two different types are never equal. */
240
      }
241
    }
242
    emitir(IRTG(diff ? IR_NE : IR_EQ, ta), a, b);
42,050✔
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)
872,077✔
249
{
250
  if (tvisgcv(o))
872,077✔
251
    return lj_ir_kgc(J, gcV(o), itype2irt(o));
803,677✔
252
  else if (tvisint(o))
68,400✔
253
    return lj_ir_kint(J, intV(o));
254
  else if (tvisnum(o))
68,400✔
255
    return lj_ir_knumint(J, numV(o));
68,399✔
256
  else if (tvisbool(o))
1✔
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)
14,164✔
273
{
274
  BCReg s;
14,164✔
275
  if (LJ_DUALNUM) return;
14,164✔
276
  for (s = J->baseslot+J->maxslot-1; s >= 1; s--) {
228,719✔
277
    TRef tr = J->slot[s];
214,556✔
278
    if (tref_isinteger(tr)) {
214,556✔
279
      IRIns *ir = IR(tref_ref(tr));
27,248✔
280
      if (!(ir->o == IR_SLOAD && (ir->op2 & IRSLOAD_READONLY)))
27,248✔
281
        J->slot[s] = emitir(IRTN(IR_CONV), tr, IRCONV_NUM_INT);
27,171✔
282
    }
283
  }
284
}
285

286
/* Stop recording. */
287
void lj_record_stop(jit_State *J, TraceLink linktype, TraceNo lnk)
15,739✔
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);
15,739✔
294
  J->cur.linktype = (uint8_t)linktype;
15,739✔
295
  J->cur.link = (uint16_t)lnk;
15,739✔
296
  /* Looping back at the same stack level? */
297
  if (lnk == J->cur.traceno && J->framedepth + J->retdepth == 0) {
15,739✔
298
    if ((J->flags & JIT_F_OPT_LOOP))  /* Shall we try to create a loop? */
2,287✔
299
      goto nocanon;  /* Do not canonicalize or we lose the narrowing. */
1,575✔
300
    if (J->cur.root)  /* Otherwise ensure we always link to the root trace. */
712✔
301
      J->cur.link = J->cur.root;
1✔
302
  }
303
  canonicalize_slots(J);
14,164✔
304
nocanon:
15,738✔
305
  /* Note: all loop ops must set J->pc to the following instruction! */
306
  lj_snap_add(J);  /* Add loop snapshot. */
15,738✔
307
  J->needsnap = 0;
15,736✔
308
  J->mergesnap = 1;  /* In case recording continues. */
15,736✔
309
}
15,736✔
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)
8,308✔
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);
8,308✔
320
  for (pc = endpc-1; pc > startpc; pc--) {
16,874✔
321
    BCIns ins = *pc;
16,874✔
322
    BCOp op = bc_op(ins);
16,874✔
323
    /* First try to find the last instruction that stores to this slot. */
324
    if (bcmode_a(op) == BCMbase && bc_a(ins) <= slot) {
16,874✔
325
      return 0;  /* Multiple results, e.g. from a CALL or KNIL. */
326
    } else if (bcmode_a(op) == BCMdst && bc_a(ins) == slot) {
16,859✔
327
      if (op == BC_KSHORT || op == BC_KNUM) {  /* Found const. initializer. */
8,293✔
328
        /* Now try to verify there's no forward jump across it. */
329
        const BCIns *kpc = pc;
492,954✔
330
        for (; pc > startpc; pc--)
492,954✔
331
          if (bc_op(*pc) == BC_JMP) {
484,976✔
332
            const BCIns *target = pc+bc_j(*pc)+1;
44,638✔
333
            if (target > kpc && target <= endpc)
44,638✔
334
              return 0;  /* Conditional assignment. */
335
          }
336
        if (op == BC_KSHORT) {
7,978✔
337
          int32_t k = (int32_t)(int16_t)bc_d(ins);
7,882✔
338
          return t == IRT_INT ? lj_ir_kint(J, k) : lj_ir_knum(J, (lua_Number)k);
7,882✔
339
        } else {
340
          cTValue *tv = proto_knumtv(J->pt, bc_d(ins));
96✔
341
          if (t == IRT_INT) {
96✔
342
            int32_t k = numberVint(tv);
76✔
343
            if (tvisint(tv) || numV(tv) == (lua_Number)k)  /* -0 is ok here. */
76✔
344
              return lj_ir_kint(J, k);
72✔
345
            return 0;  /* Type mismatch. */
346
          } else {
347
            return lj_ir_knum(J, numberVnum(tv));
20✔
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)
2,843✔
359
{
360
  int conv = (tvisint(&J->L->base[slot]) != (t==IRT_INT)) ? IRSLOAD_CONVERT : 0;
2,843✔
361
  return sloadt(J, (int32_t)slot,
8,529✔
362
                t + (((mode & IRSLOAD_TYPECHECK) ||
2,843✔
363
                      (conv && t == IRT_INT && !(mode >> 16))) ?
2,843✔
364
                     IRT_GUARD : 0),
2,843✔
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,
5,876✔
370
                     IRType t, int mode)
371
{
372
  TRef tr = J->base[slot];
5,876✔
373
  if (!tr) {
5,876✔
374
    tr = find_kinit(J, fori, slot, t);
5,370✔
375
    if (!tr)
5,370✔
376
      tr = fori_load(J, slot, t, mode);
254✔
377
  }
378
  return tr;
5,876✔
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,056✔
385
{
386
  return (tvisint(o) ? intV(o) : (int32_t)o->u32.hi) >= 0;
6,056✔
387
}
388

389
/* Simulate the runtime behavior of the FOR loop iterator. */
390
static LoopEvent rec_for_iter(IROp *op, cTValue *o, int isforl)
2,876✔
391
{
392
  lua_Number stopv = numberVnum(&o[FORL_STOP]);
2,876✔
393
  lua_Number idxv = numberVnum(&o[FORL_IDX]);
2,876✔
394
  lua_Number stepv = numberVnum(&o[FORL_STEP]);
2,876✔
395
  if (isforl)
2,876✔
396
    idxv += stepv;
2,634✔
397
  if (rec_for_direction(&o[FORL_STEP])) {
2,876✔
398
    if (idxv <= stopv) {
2,795✔
399
      *op = IR_LE;
2,733✔
400
      return idxv + 2*stepv > stopv ? LOOPEV_ENTERLO : LOOPEV_ENTER;
2,733✔
401
    }
402
    *op = IR_GT; return LOOPEV_LEAVE;
62✔
403
  } else {
404
    if (stopv <= idxv) {
81✔
405
      *op = IR_GE;
80✔
406
      return idxv + 2*stepv < stopv ? LOOPEV_ENTERLO : LOOPEV_ENTER;
80✔
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,180✔
414
                          TRef stop, TRef step, int init)
415
{
416
  if (!tref_isk(step)) {
3,180✔
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);
214✔
419
    emitir(IRTG(dir ? IR_GE : IR_LT, t), step, zero);
215✔
420
    /* Add hoistable overflow checks for a narrowed FORL index. */
421
    if (init && t == IRT_INT) {
214✔
422
      if (tref_isk(stop)) {
7✔
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);
5✔
435
        emitir(IRTI(IR_USE), tr, 0);  /* ADDOV is weak. Avoid dead result. */
5✔
436
      }
437
    }
438
  } else if (init && t == IRT_INT && !tref_isk(stop)) {
2,966✔
439
    /* Constant step: optimize overflow check to a range check for stop. */
440
    int32_t k = IR(tref_ref(step))->i;
231✔
441
    k = (int32_t)(dir ? 0x7fffffff : 0x80000000) - k;
231✔
442
    emitir(IRTGI(dir ? IR_LE : IR_GE), stop, lj_ir_kint(J, k));
263✔
443
  }
444
}
3,180✔
445

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

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

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

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

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

557
/* Record ITERL/JITERL. */
558
static LoopEvent rec_iterl(jit_State *J, const BCIns iterins)
107✔
559
{
560
  BCReg ra = bc_a(iterins);
107✔
561
  if (!tref_isnil(getslot(J, ra))) {  /* Looping back? */
107✔
562
    J->base[ra-1] = J->base[ra];  /* Copy result of ITERC to control var. */
81✔
563
    J->maxslot = ra-1+bc_b(J->pc[-1]);
81✔
564
    J->pc += bc_j(iterins)+1;
81✔
565
    return LOOPEV_ENTER;
81✔
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)
28,569✔
575
{
576
  if (ra < J->maxslot) J->maxslot = ra;
17,182✔
577
  J->pc += skip;
28,569✔
578
  return LOOPEV_ENTER;
28,569✔
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++)
9,870✔
586
    if (mref(J->penalty[i].pc, const BCIns) == pc) {
9,721✔
587
      if ((J->penalty[i].reason == LJ_TRERR_LLEAVE ||
17✔
588
           J->penalty[i].reason == LJ_TRERR_LINNER) &&
17✔
589
          J->penalty[i].val >= 2*PENALTY_MIN)
17✔
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)
21,700✔
598
{
599
  if (J->parent == 0 && J->exitno == 0) {
21,700✔
600
    if (pc == J->startpc && J->framedepth + J->retdepth == 0) {
2,308✔
601
      /* Same loop? */
602
      if (ev == LOOPEV_LEAVE)  /* Must loop back to form a root trace. */
2,138✔
603
        lj_trace_err(J, LJ_TRERR_LLEAVE);
34✔
604
      lj_record_stop(J, LJ_TRLINK_LOOP, J->cur.traceno);  /* Looping trace. */
2,104✔
605
    } else if (ev != LOOPEV_LEAVE) {  /* Entering inner loop? */
170✔
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))
167✔
613
        lj_trace_err(J, LJ_TRERR_LINNER);  /* Root trace hit an inner loop. */
158✔
614
      if ((ev != LOOPEV_ENTERLO &&
9✔
615
           J->loopref && J->cur.nins - J->loopref > 24) || --J->loopunroll < 0)
9✔
616
        lj_trace_err(J, LJ_TRERR_LUNROLL);  /* Limit loop unrolling. */
1✔
617
      J->loopref = J->cur.nins;
8✔
618
    }
619
  } else if (ev != LOOPEV_LEAVE) {  /* Side trace enters an inner loop. */
19,392✔
620
    J->loopref = J->cur.nins;
19,367✔
621
    if (--J->loopunroll < 0)
19,367✔
622
      lj_trace_err(J, LJ_TRERR_LUNROLL);  /* Limit loop unrolling. */
2✔
623
  }  /* Side trace continues across a loop that's left or not entered. */
624
}
21,505✔
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)
9,610✔
628
{
629
  if (J->parent == 0 && J->exitno == 0) {  /* Root trace hit an inner loop. */
9,610✔
630
    /* Better let the inner loop spawn a side trace back here. */
631
    lj_trace_err(J, LJ_TRERR_LINNER);
457✔
632
  } else if (ev != LOOPEV_LEAVE) {  /* Side trace enters a compiled loop. */
9,153✔
633
    J->instunroll = 0;  /* Cannot continue across a compiled loop op. */
9,128✔
634
    if (J->pc == J->startpc && J->framedepth + J->retdepth == 0)
9,128✔
635
      lj_record_stop(J, LJ_TRLINK_LOOP, J->cur.traceno);  /* Form extra loop. */
178✔
636
    else
637
      lj_record_stop(J, LJ_TRLINK_ROOT, lnk);  /* Link to the loop. */
8,950✔
638
  }  /* Side trace continues across a loop that's left or not entered. */
639
}
9,153✔
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)
6,895,326✔
670
{
671
  if (J->prof_mode && rec_profile_need(J, J->pt, pc)) {
6,895,326✔
672
    emitir(IRTG(IR_PROF, IRT_NIL), 0, 0);
1✔
673
    lj_snap_add(J);
1✔
674
  }
675
}
6,895,326✔
676

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

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

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

770
/* Record tail call. */
771
void lj_record_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs)
91,471✔
772
{
773
  rec_call_setup(J, func, nargs);
91,471✔
774
  if (frame_isvarg(J->L->base - 1)) {
91,471✔
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)
91,471✔
784
    J->base[func+1] = TREF_FRAME;
89,581✔
785
  memmove(&J->base[-1-LJ_FR2], &J->base[func], sizeof(TRef)*(J->maxslot+1+LJ_FR2));
91,471✔
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)
91,471✔
789
    lj_trace_err(J, LJ_TRERR_LUNROLL);
1,310✔
790
}
90,161✔
791

792
/* Check unroll limits for down-recursion. */
793
static int check_downrec_unroll(jit_State *J, GCproto *pt)
32✔
794
{
795
  IRRef ptref;
32✔
796
  for (ptref = J->chain[IR_KGC]; ptref; ptref = IR(ptref)->prev)
86✔
797
    if (ir_kgc(IR(ptref)) == obj2gco(pt)) {
55✔
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)
993,677✔
819
{
820
  TValue *frame = J->L->base - 1;
993,677✔
821
  ptrdiff_t i;
993,677✔
822
  BCReg baseadj = 0;
993,677✔
823
  for (i = 0; i < gotresults; i++)
1,901,363✔
824
    (void)getslot(J, rbase+i);  /* Ensure all results have a reference. */
907,686✔
825
  while (frame_ispcall(frame)) {  /* Immediately resolve pcall() returns. */
993,708✔
826
    BCReg cbase = (BCReg)frame_delta(frame);
48✔
827
    if (--J->framedepth <= 0)
48✔
828
      lj_trace_err(J, LJ_TRERR_NYIRETL);
17✔
829
    lj_assertJ(J->baseslot > 1+LJ_FR2, "bad baseslot for return");
31✔
830
    gotresults++;
31✔
831
    baseadj += cbase;
31✔
832
    rbase += cbase;
31✔
833
    J->baseslot -= (BCReg)cbase;
31✔
834
    J->base -= cbase;
31✔
835
    J->base[--rbase] = TREF_TRUE;  /* Prepend true to results. */
31✔
836
    frame = frame_prevd(frame);
31✔
837
    J->needsnap = 1;  /* Stop catching on-trace errors. */
31✔
838
  }
839
  /* Return to lower frame via interpreter for unhandled cases. */
840
  if (J->framedepth == 0 && J->pt && bc_isret(bc_op(*J->pc)) &&
993,660✔
841
       (!frame_islua(frame) ||
108,243✔
842
        (J->parent == 0 && J->exitno == 0 &&
108,188✔
843
         !bc_isret(bc_op(J->cur.startins))))) {
877✔
844
    /* NYI: specialize to frame type and return directly, not via RET*. */
845
    for (i = 0; i < (ptrdiff_t)rbase; i++)
1,982✔
846
      J->base[i] = 0;  /* Purge dead slots. */
1,051✔
847
    J->maxslot = rbase + (BCReg)gotresults;
931✔
848
    lj_record_stop(J, LJ_TRLINK_RETURN, 0);  /* Return to interpreter. */
931✔
849
    return;
931✔
850
  }
851
  if (frame_isvarg(frame)) {
992,729✔
852
    BCReg cbase = (BCReg)frame_delta(frame);
27✔
853
    if (--J->framedepth < 0)  /* NYI: return of vararg func to lower frame. */
27✔
854
      lj_trace_err(J, LJ_TRERR_NYIRETL);
×
855
    lj_assertJ(J->baseslot > 1+LJ_FR2, "bad baseslot for return");
27✔
856
    baseadj += cbase;
27✔
857
    rbase += cbase;
27✔
858
    J->baseslot -= (BCReg)cbase;
27✔
859
    J->base -= cbase;
27✔
860
    frame = frame_prevd(frame);
27✔
861
  }
862
  if (frame_islua(frame)) {  /* Return to Lua frame. */
992,729✔
863
    BCIns callins = *(frame_pc(frame)-1);
893,790✔
864
    ptrdiff_t nresults = bc_b(callins) ? (ptrdiff_t)bc_b(callins)-1 :gotresults;
893,790✔
865
    BCReg cbase = bc_a(callins);
893,790✔
866
    GCproto *pt = funcproto(frame_func(frame - (cbase+1+LJ_FR2)));
893,790✔
867
    if ((pt->flags & PROTO_NOJIT))
893,790✔
868
      lj_trace_err(J, LJ_TRERR_CJITOFF);
×
869
    if (J->framedepth == 0 && J->pt && frame == J->L->base - 1) {
893,790✔
870
      if (!J->cur.root && check_downrec_unroll(J, pt)) {
107,312✔
871
        J->maxslot = (BCReg)(rbase + gotresults);
×
872
        lj_snap_purge(J);
×
873
        lj_record_stop(J, LJ_TRLINK_DOWNREC, J->cur.traceno);  /* Down-rec. */
×
874
        return;
×
875
      }
876
      lj_snap_add(J);
107,311✔
877
    }
878
    for (i = 0; i < nresults; i++)  /* Adjust results. */
1,659,319✔
879
      J->base[i-1-LJ_FR2] = i < gotresults ? J->base[rbase+i] : TREF_NIL;
765,530✔
880
    J->maxslot = cbase+(BCReg)nresults;
893,789✔
881
    if (J->framedepth > 0) {  /* Return to a frame that is part of the trace. */
893,789✔
882
      J->framedepth--;
786,038✔
883
      lj_assertJ(J->baseslot > cbase+1+LJ_FR2, "bad baseslot for return");
786,038✔
884
      J->baseslot -= cbase+1+LJ_FR2;
786,038✔
885
      J->base -= cbase+1+LJ_FR2;
786,038✔
886
    } else if (J->parent == 0 && J->exitno == 0 &&
107,751✔
887
               !bc_isret(bc_op(J->cur.startins))) {
17✔
888
      /* Return to lower frame would leave the loop in a root trace. */
889
      lj_trace_err(J, LJ_TRERR_LLEAVE);
16✔
890
    } else if (J->needsnap) {  /* Tailcalled to ff with side-effects. */
107,735✔
891
      lj_trace_err(J, LJ_TRERR_NYIRETL);  /* No way to insert snapshot here. */
×
892
    } else if (1 + pt->framesize >= LJ_MAX_JSLOTS) {
107,735✔
893
      lj_trace_err(J, LJ_TRERR_STACKOV);
1✔
894
    } else {  /* Return to lower frame. Guard for the target we return to. */
895
      TRef trpt = lj_ir_kgc(J, obj2gco(pt), IRT_PROTO);
107,734✔
896
      TRef trpc = lj_ir_kptr(J, (void *)frame_pc(frame));
107,734✔
897
      emitir(IRTG(IR_RETF, IRT_PGC), trpt, trpc);
107,734✔
898
      J->retdepth++;
107,734✔
899
      J->needsnap = 1;
107,734✔
900
      lj_assertJ(J->baseslot == 1+LJ_FR2, "bad baseslot for return");
107,734✔
901
      /* Shift result slots up and clear the slots of the new frame below. */
902
      memmove(J->base + cbase, J->base-1-LJ_FR2, sizeof(TRef)*nresults);
107,734✔
903
      memset(J->base-1-LJ_FR2, 0, sizeof(TRef)*(cbase+1+LJ_FR2));
107,734✔
904
    }
905
  } else if (frame_iscont(frame)) {  /* Return to continuation frame. */
98,939✔
906
    ASMFunction cont = frame_contf(frame);
98,939✔
907
    BCReg cbase = (BCReg)frame_delta(frame);
98,939✔
908
    if ((J->framedepth -= 2) < 0)
98,939✔
909
      lj_trace_err(J, LJ_TRERR_NYIRETL);
4✔
910
    J->baseslot -= (BCReg)cbase;
98,935✔
911
    J->base -= cbase;
98,935✔
912
    J->maxslot = cbase-(2<<LJ_FR2);
98,935✔
913
    if (cont == lj_cont_ra) {
98,935✔
914
      /* Copy result to destination slot. */
915
      BCReg dst = bc_a(*(frame_contpc(frame)-1));
68,912✔
916
      J->base[dst] = gotresults ? J->base[cbase+rbase] : TREF_NIL;
68,912✔
917
      if (dst >= J->maxslot) {
68,912✔
918
        J->maxslot = dst+1;
×
919
      }
920
    } else if (cont == lj_cont_nop) {
30,023✔
921
      /* Nothing to do here. */
922
    } else if (cont == lj_cont_cat) {
29,879✔
923
      BCReg bslot = bc_b(*(frame_contpc(frame)-1));
11✔
924
      TRef tr = gotresults ? J->base[cbase+rbase] : TREF_NIL;
11✔
925
      if (bslot != J->maxslot) {  /* Concatenate the remainder. */
11✔
926
        /* Simulate lower frame and result. */
927
        TValue *b = J->L->base - baseadj, save;
5✔
928
        /* Can't handle MM_concat + CALLT + fast func side-effects. */
929
        if (J->postproc != LJ_POST_NONE)
5✔
930
          lj_trace_err(J, LJ_TRERR_NYIRETL);
1✔
931
        J->base[J->maxslot] = tr;
4✔
932
        copyTV(J->L, &save, b-(2<<LJ_FR2));
4✔
933
        if (gotresults)
4✔
934
          copyTV(J->L, b-(2<<LJ_FR2), b+rbase);
4✔
935
        else
936
          setnilV(b-(2<<LJ_FR2));
×
937
        J->L->base = b - cbase;
4✔
938
        tr = rec_cat(J, bslot, cbase-(2<<LJ_FR2));
4✔
939
        b = J->L->base + cbase;  /* Undo. */
4✔
940
        J->L->base = b + baseadj;
4✔
941
        copyTV(J->L, b-(2<<LJ_FR2), &save);
4✔
942
      }
943
      if (tr) {  /* Store final result. */
10✔
944
        BCReg dst = bc_a(*(frame_contpc(frame)-1));
6✔
945
        J->base[dst] = tr;
6✔
946
        if (dst >= J->maxslot) {
6✔
947
          J->maxslot = dst+1;
×
948
        }
949
      }  /* Otherwise continue with another __concat call. */
950
    } else {
951
      /* Result type already specialized. */
952
      lj_assertJ(cont == lj_cont_condf || cont == lj_cont_condt,
953
                 "bad continuation type");
954
    }
955
  } else {
956
    lj_trace_err(J, LJ_TRERR_NYIRETL);  /* NYI: handle return to C frame. */
×
957
  }
958
  lj_assertJ(J->baseslot >= 1+LJ_FR2, "bad baseslot for return");
993,637✔
959
}
960

961
/* -- Metamethod handling ------------------------------------------------- */
962

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

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

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

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

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

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

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

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

1222
/* -- Indexed access ------------------------------------------------------ */
1223

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

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

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

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

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

1401
/* Determine whether a key is NOT one of the fast metamethod names. */
1402
static int nommstr(jit_State *J, TRef key)
266,541✔
1403
{
1404
  if (tref_isstr(key)) {
266,541✔
1405
    if (tref_isk(key)) {
263,548✔
1406
      GCstr *str = ir_kstr(IR(tref_ref(key)));
263,535✔
1407
      uint32_t mm;
263,535✔
1408
      for (mm = 0; mm <= MM_FAST; mm++)
1,844,745✔
1409
        if (mmname_str(J2G(J), mm) == str)
1,581,210✔
1410
          return 0;  /* MUST be one the fast metamethod names. */
1411
    } else {
1412
      return 0;  /* Variable string key MAY be a metamethod name. */
1413
    }
1414
  }
1415
  return 1;  /* CANNOT be a metamethod name. */
1416
}
1417

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

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

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

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

1476
  if (ix->val == 0) {  /* Indexed load */
1,329,329✔
1477
    IRType t = itype2irt(oldv);
1,062,778✔
1478
    TRef res;
1,062,778✔
1479
    if (oldv == niltvg(J2G(J))) {
1,062,778✔
1480
      emitir(IRTG(IR_EQ, IRT_PGC), xref, lj_ir_kkptr(J, niltvg(J2G(J))));
41,152✔
1481
      res = TREF_NIL;
41,152✔
1482
    } else {
1483
      res = emitir(IRTG(loadop, t), xref, 0);
1,021,626✔
1484
    }
1485
    if (tref_ref(res) < rbref) {  /* HREFK + load forwarded? */
1,062,778✔
1486
      lj_ir_rollback(J, rbref);  /* Rollback to eliminate hmask guard. */
472,648✔
1487
      J->guardemit = rbguard;
472,648✔
1488
    }
1489
    if (t == IRT_NIL && ix->idxchain && lj_record_mm_lookup(J, ix, MM_index))
1,062,778✔
1490
      goto handlemm;
30,449✔
1491
    if (irtype_ispri(t)) res = TREF_PRI(t);  /* Canonicalize primitives. */
1,032,329✔
1492
    return res;
1,032,329✔
1493
  } else {  /* Indexed store. */
1494
    GCtab *mt = tabref(tabV(&ix->tabv)->metatable);
266,551✔
1495
    int keybarrier = tref_isgcv(ix->key) && !tref_isnil(ix->val);
266,551✔
1496
    if (tref_ref(xref) < rbref) {  /* HREFK forwarded? */
266,551✔
1497
      lj_ir_rollback(J, rbref);  /* Rollback to eliminate hmask guard. */
27,995✔
1498
      J->guardemit = rbguard;
27,995✔
1499
    }
1500
    if (tvisnil(oldv)) {  /* Previous value was nil? */
266,551✔
1501
      /* Need to duplicate the hasmm check for the early guards. */
1502
      int hasmm = 0;
10,681✔
1503
      if (ix->idxchain && mt) {
10,681✔
1504
        cTValue *mo = lj_tab_getstr(mt, mmname_str(J2G(J), MM_newindex));
33✔
1505
        hasmm = mo && !tvisnil(mo);
33✔
1506
      }
1507
      if (hasmm)
10✔
1508
        emitir(IRTG(loadop, IRT_NIL), xref, 0);  /* Guard for nil value. */
10✔
1509
      else if (xrefop == IR_HREF)
10,671✔
1510
        emitir(IRTG(oldv == niltvg(J2G(J)) ? IR_EQ : IR_NE, IRT_PGC),
8,220✔
1511
               xref, lj_ir_kkptr(J, niltvg(J2G(J))));
1512
      if (ix->idxchain && lj_record_mm_lookup(J, ix, MM_newindex)) {
10,681✔
1513
        lj_assertJ(hasmm, "inconsistent metamethod handling");
10✔
1514
        goto handlemm;
10✔
1515
      }
1516
      lj_assertJ(!hasmm, "inconsistent metamethod handling");
10,671✔
1517
      if (oldv == niltvg(J2G(J))) {  /* Need to insert a new key. */
10,671✔
1518
        TRef key = ix->key;
8,622✔
1519
        if (tref_isinteger(key)) {  /* NEWREF needs a TValue as a key. */
8,622✔
1520
          key = emitir(IRTN(IR_CONV), key, IRCONV_NUM_INT);
128✔
1521
        } else if (tref_isnum(key)) {
8,494✔
1522
          if (tref_isk(key)) {
71✔
1523
            if (tvismzero(&ix->keyv))
2✔
1524
              key = lj_ir_knum_zero(J);  /* Canonicalize -0.0 to +0.0. */
2✔
1525
          } else {
1526
            emitir(IRTG(IR_EQ, IRT_NUM), key, key);  /* Check for !NaN. */
69✔
1527
          }
1528
        }
1529
        xref = emitir(IRT(IR_NEWREF, IRT_PGC), ix->tab, key);
8,622✔
1530
        keybarrier = 0;  /* NEWREF already takes care of the key barrier. */
8,622✔
1531
#ifdef LUAJIT_ENABLE_TABLE_BUMP
1532
        if ((J->flags & JIT_F_OPT_SINK))  /* Avoid a separate flag. */
1533
          rec_idx_bump(J, ix);
1534
#endif
1535
      }
1536
    } else if (!lj_opt_fwd_wasnonnil(J, loadop, tref_ref(xref))) {
255,870✔
1537
      /* Cannot derive that the previous value was non-nil, must do checks. */
1538
      if (xrefop == IR_HREF)  /* Guard against store to niltv. */
226,010✔
1539
        emitir(IRTG(IR_NE, IRT_PGC), xref, lj_ir_kkptr(J, niltvg(J2G(J))));
29✔
1540
      if (ix->idxchain) {  /* Metamethod lookup required? */
226,010✔
1541
        /* A check for NULL metatable is cheaper (hoistable) than a load. */
1542
        if (!mt) {
226,001✔
1543
          TRef mtref = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_TAB_META);
225,983✔
1544
          emitir(IRTG(IR_EQ, IRT_TAB), mtref, lj_ir_knull(J, IRT_TAB));
225,983✔
1545
        } else {
1546
          IRType t = itype2irt(oldv);
18✔
1547
          emitir(IRTG(loadop, t), xref, 0);  /* Guard for non-nil value. */
18✔
1548
        }
1549
      }
1550
    } else {
1551
      keybarrier = 0;  /* Previous non-nil value kept the key alive. */
1552
    }
1553
    /* Convert int to number before storing. */
1554
    if (!LJ_DUALNUM && tref_isinteger(ix->val))
266,541✔
1555
      ix->val = emitir(IRTN(IR_CONV), ix->val, IRCONV_NUM_INT);
2,790✔
1556
    emitir(IRT(loadop+IRDELTA_L2S, tref_type(ix->val)), xref, ix->val);
266,541✔
1557
    if (keybarrier || tref_isgcv(ix->val))
266,541✔
1558
      emitir(IRT(IR_TBAR, IRT_NIL), ix->tab, 0);
233,456✔
1559
    /* Invalidate neg. metamethod cache for stores with certain string keys. */
1560
    if (!nommstr(J, ix->key)) {
530,076✔
1561
      TRef fref = emitir(IRT(IR_FREF, IRT_PGC), ix->tab, IRFL_TAB_NOMM);
13✔
1562
      emitir(IRT(IR_FSTORE, IRT_U8), fref, lj_ir_kint(J, 0));
13✔
1563
    }
1564
    J->needsnap = 1;
266,541✔
1565
    return 0;
266,541✔
1566
  }
1567
}
1568

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

1594
/* -- Upvalue access ------------------------------------------------------ */
1595

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

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

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

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

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

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

1771
/* Record entry to a Lua function. */
1772
static void rec_func_lua(jit_State *J)
109,503✔
1773
{
1774
  rec_func_setup(J);
109,503✔
1775
  check_call_unroll(J, 0);
109,503✔
1776
}
109,441✔
1777

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

1799
/* -- Vararg handling ----------------------------------------------------- */
1800

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

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

1920
/* -- Record allocations -------------------------------------------------- */
1921

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

1937
/* -- Concatenation ------------------------------------------------------- */
1938

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

1985
/* -- Record bytecode ops ------------------------------------------------- */
1986

1987
/* Prepare for comparison. */
1988
static void rec_comp_prep(jit_State *J)
663,550✔
1989
{
1990
  /* Prevent merging with snapshot #0 (GC exit) since we fixup the PC. */
1991
  if (J->cur.nsnap == 1 && J->cur.snap[0].ref == J->cur.nins)
663,550✔
1992
    emitir_raw(IRT(IR_NOP, IRT_NIL), 0, 0);
300✔
1993
  lj_snap_add(J);
663,550✔
1994
}
663,550✔
1995

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

2017
/* Record the next bytecode instruction (_before_ it's executed). */
2018
void lj_record_ins(jit_State *J)
6,895,839✔
2019
{
2020
  cTValue *lbase;
6,895,839✔
2021
  RecordIndex ix;
6,895,839✔
2022
  const BCIns *pc;
6,895,839✔
2023
  BCIns ins;
6,895,839✔
2024
  BCOp op;
6,895,839✔
2025
  TRef ra, rb, rc;
6,895,839✔
2026

2027
  /* Perform post-processing action before recording the next instruction. */
2028
  if (LJ_UNLIKELY(J->postproc != LJ_POST_NONE)) {
6,895,839✔
2029
    switch (J->postproc) {
288,143✔
2030
    case LJ_POST_FIXCOMP:  /* Fixup comparison. */
19,858✔
2031
      pc = (const BCIns *)(uintptr_t)J2G(J)->tmptv.u64;
19,858✔
2032
      rec_comp_fixup(J, pc, (!tvistruecond(&J2G(J)->tmptv2) ^ (bc_op(*pc)&1)));
19,858✔
2033
      /* fallthrough */
2034
    case LJ_POST_FIXGUARD:  /* Fixup and emit pending guard. */
29,816✔
2035
    case LJ_POST_FIXGUARDSNAP:  /* Fixup and emit pending guard and snapshot. */
2036
      if (!tvistruecond(&J2G(J)->tmptv2)) {
29,816✔
2037
        J->fold.ins.o ^= 1;  /* Flip guard to opposite. */
9,955✔
2038
        if (J->postproc == LJ_POST_FIXGUARDSNAP) {
9,955✔
2039
          SnapShot *snap = &J->cur.snap[J->cur.nsnap-1];
1✔
2040
          J->cur.snapmap[snap->mapofs+snap->nent-1]--;  /* False -> true. */
1✔
2041
        }
2042
      }
2043
      lj_opt_fold(J);  /* Emit pending guard. */
29,816✔
2044
      /* fallthrough */
2045
    case LJ_POST_FIXBOOL:
29,830✔
2046
      if (!tvistruecond(&J2G(J)->tmptv2)) {
29,830✔
2047
        BCReg s;
9,961✔
2048
        TValue *tv = J->L->base;
9,961✔
2049
        for (s = 0; s < J->maxslot; s++)  /* Fixup stack slot (if any). */
49,934✔
2050
          if (J->base[s] == TREF_TRUE && tvisfalse(&tv[s])) {
39,981✔
2051
            J->base[s] = TREF_FALSE;
8✔
2052
            break;
8✔
2053
          }
2054
      }
2055
      break;
2056
    case LJ_POST_FIXCONST:
1✔
2057
      {
2058
        BCReg s;
1✔
2059
        TValue *tv = J->L->base;
1✔
2060
        for (s = 0; s < J->maxslot; s++)  /* Constify stack slots (if any). */
13✔
2061
          if (J->base[s] == TREF_NIL && !tvisnil(&tv[s]))
12✔
2062
            J->base[s] = lj_record_constify(J, &tv[s]);
1✔
2063
      }
2064
      break;
2065
    case LJ_POST_FFRETRY:  /* Suppress recording of retried fast function. */
258,312✔
2066
      if (bc_op(*J->pc) >= BC__MAX)
258,312✔
2067
        return;
19✔
2068
      break;
2069
    default: lj_assertJ(0, "bad post-processing mode"); break;
2070
    }
2071
    J->postproc = LJ_POST_NONE;
288,140✔
2072
  }
2073

2074
  /* Need snapshot before recording next bytecode (e.g. after a store). */
2075
  if (J->needsnap) {
6,895,836✔
2076
    J->needsnap = 0;
1,068,188✔
2077
    if (J->pt) lj_snap_purge(J);
1,068,188✔
2078
    lj_snap_add(J);
1,068,188✔
2079
    J->mergesnap = 1;
1,068,188✔
2080
  }
2081

2082
  /* Skip some bytecodes. */
2083
  if (LJ_UNLIKELY(J->bcskip > 0)) {
6,895,836✔
2084
    J->bcskip--;
16✔
2085
    return;
16✔
2086
  }
2087

2088
  /* Record only closed loops for root traces. */
2089
  pc = J->pc;
6,895,820✔
2090
  if (J->framedepth == 0 &&
6,895,820✔
2091
     (MSize)((char *)pc - (char *)J->bc_min) >= J->bc_extent)
2,135,092✔
2092
    lj_trace_err(J, LJ_TRERR_LLEAVE);
494✔
2093

2094
#ifdef LUA_USE_ASSERT
2095
  rec_check_slots(J);
2096
  rec_check_ir(J);
2097
#endif
2098

2099
#if LJ_HASPROFILE
2100
  rec_profile_ins(J, pc);
6,895,326✔
2101
#endif
2102

2103
  /* Keep a copy of the runtime values of var/num/str operands. */
2104
#define rav        (&ix.valv)
2105
#define rbv        (&ix.tabv)
2106
#define rcv        (&ix.keyv)
2107

2108
  lbase = J->L->base;
6,895,326✔
2109
  ins = *pc;
6,895,326✔
2110
  op = bc_op(ins);
6,895,326✔
2111
  ra = bc_a(ins);
6,895,326✔
2112
  ix.val = 0;
6,895,326✔
2113
  switch (bcmode_a(op)) {
6,895,326✔
2114
  case BCMvar:
993,098✔
2115
    copyTV(J->L, rav, &lbase[ra]); ix.val = ra = getslot(J, ra); break;
993,098✔
2116
  default: break;  /* Handled later. */
2117
  }
2118
  rb = bc_b(ins);
6,895,326✔
2119
  rc = bc_c(ins);
6,895,326✔
2120
  switch (bcmode_b(op)) {
6,895,326✔
2121
  case BCMnone: rb = 0; rc = bc_d(ins); break;  /* Upgrade rc to 'rd'. */
4,488,665✔
2122
  case BCMvar:
1,602,273✔
2123
    copyTV(J->L, rbv, &lbase[rb]); ix.tab = rb = getslot(J, rb); break;
1,602,273✔
2124
  default: break;  /* Handled later. */
2125
  }
2126
  switch (bcmode_c(op)) {
6,895,326✔
2127
  case BCMvar:
1,010,730✔
2128
    copyTV(J->L, rcv, &lbase[rc]); ix.key = rc = getslot(J, rc); break;
1,010,730✔
2129
  case BCMpri: setpriV(rcv, ~rc); ix.key = rc = TREF_PRI(IRT_NIL+rc); break;
518,459✔
2130
  case BCMnum: { cTValue *tv = proto_knumtv(J->pt, rc);
149,192✔
2131
    copyTV(J->L, rcv, tv); ix.key = rc = tvisint(tv) ? lj_ir_kint(J, intV(tv)) :
149,192✔
2132
    lj_ir_knumint(J, numV(tv)); } break;
149,192✔
2133
  case BCMstr: { GCstr *s = gco2str(proto_kgc(J->pt, ~(ptrdiff_t)rc));
1,294,581✔
2134
    setstrV(J->L, rcv, s); ix.key = rc = lj_ir_kstr(J, s); } break;
1,294,581✔
2135
  default: break;  /* Handled later. */
2136
  }
2137

2138
  switch (op) {
6,895,326✔
2139

2140
  /* -- Comparison ops ---------------------------------------------------- */
2141

2142
  case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
228,211✔
2143
#if LJ_HASFFI
2144
    if (tref_iscdata(ra) || tref_iscdata(rc)) {
228,211✔
2145
      rec_mm_comp_cdata(J, &ix, op, ((int)op & 2) ? MM_le : MM_lt);
19,839✔
2146
      break;
19,839✔
2147
    }
2148
#endif
2149
    /* Emit nothing for two numeric or string consts. */
2150
    if (!(tref_isk2(ra,rc) && tref_isnumber_str(ra) && tref_isnumber_str(rc))) {
208,372✔
2151
      IRType ta = tref_isinteger(ra) ? IRT_INT : tref_type(ra);
187,231✔
2152
      IRType tc = tref_isinteger(rc) ? IRT_INT : tref_type(rc);
187,231✔
2153
      int irop;
187,231✔
2154
      if (ta != tc) {
187,231✔
2155
        /* Widen mixed number/int comparisons to number/number comparison. */
2156
        if (ta == IRT_INT && tc == IRT_NUM) {
180,131✔
2157
          ra = emitir(IRTN(IR_CONV), ra, IRCONV_NUM_INT);
91,059✔
2158
          ta = IRT_NUM;
91,059✔
2159
        } else if (ta == IRT_NUM && tc == IRT_INT) {
89,072✔
2160
          rc = emitir(IRTN(IR_CONV), rc, IRCONV_NUM_INT);
89,072✔
2161
        } else if (LJ_52) {
×
2162
          ta = IRT_NIL;  /* Force metamethod for different types. */
2163
        } else if (!((ta == IRT_FALSE || ta == IRT_TRUE) &&
×
2164
                     (tc == IRT_FALSE || tc == IRT_TRUE))) {
×
2165
          break;  /* Interpreter will throw for two different types. */
2166
        }
2167
      }
2168
      rec_comp_prep(J);
187,231✔
2169
      irop = (int)op - (int)BC_ISLT + (int)IR_LT;
187,231✔
2170
      if (ta == IRT_NUM) {
187,231✔
2171
        if ((irop & 1)) irop ^= 4;  /* ISGE/ISGT are unordered. */
187,104✔
2172
        if (!lj_ir_numcmp(numberVnum(rav), numberVnum(rcv), (IROp)irop))
187,104✔
2173
          irop ^= 5;
179,562✔
2174
      } else if (ta == IRT_INT) {
127✔
2175
        if (!lj_ir_numcmp(numberVnum(rav), numberVnum(rcv), (IROp)irop))
76✔
2176
          irop ^= 1;
20✔
2177
      } else if (ta == IRT_STR) {
51✔
2178
        if (!lj_ir_strcmp(strV(rav), strV(rcv), (IROp)irop)) irop ^= 1;
2✔
2179
        ra = lj_ir_call(J, IRCALL_lj_str_cmp, ra, rc);
2✔
2180
        rc = lj_ir_kint(J, 0);
2✔
2181
        ta = IRT_INT;
2✔
2182
      } else {
2183
        rec_mm_comp(J, &ix, (int)op);
49✔
2184
        break;
49✔
2185
      }
2186
      emitir(IRTG(irop, ta), ra, rc);
187,182✔
2187
      rec_comp_fixup(J, J->pc, ((int)op ^ irop) & 1);
187,182✔
2188
    }
2189
    break;
2190

2191
  case BC_ISEQV: case BC_ISNEV:
498,210✔
2192
  case BC_ISEQS: case BC_ISNES:
2193
  case BC_ISEQN: case BC_ISNEN:
2194
  case BC_ISEQP: case BC_ISNEP:
2195
#if LJ_HASFFI
2196
    if (tref_iscdata(ra) || tref_iscdata(rc)) {
498,210✔
2197
      rec_mm_comp_cdata(J, &ix, op, MM_eq);
9,971✔
2198
      break;
9,971✔
2199
    }
2200
#endif
2201
    /* Emit nothing for two non-table, non-udata consts. */
2202
    if (!(tref_isk2(ra, rc) && !(tref_istab(ra) || tref_isudata(ra)))) {
488,239✔
2203
      int diff;
476,319✔
2204
      rec_comp_prep(J);
476,319✔
2205
      diff = lj_record_objcmp(J, ra, rc, rav, rcv);
476,319✔
2206
      if (diff == 2 || !(tref_istab(ra) || tref_isudata(ra)))
476,319✔
2207
        rec_comp_fixup(J, J->pc, ((int)op & 1) == !diff);
476,267✔
2208
      else if (diff == 1)  /* Only check __eq if different, but same type. */
52✔
2209
        rec_mm_equal(J, &ix, (int)op);
10✔
2210
    }
2211
    break;
2212

2213
  /* -- Unary test and copy ops ------------------------------------------- */
2214

2215
  case BC_ISTC: case BC_ISFC:
195✔
2216
    if ((op & 1) == tref_istruecond(rc))
195✔
2217
      rc = 0;  /* Don't store if condition is not true. */
171✔
2218
    /* fallthrough */
2219
  case BC_IST: case BC_ISF:  /* Type specialization suffices. */
2220
    if (bc_a(pc[1]) < J->maxslot)
50,400✔
2221
      J->maxslot = bc_a(pc[1]);  /* Shrink used slots. */
29,711✔
2222
    break;
2223

2224
  case BC_ISTYPE: case BC_ISNUM:
2225
    /* These coercions need to correspond with lj_meta_istype(). */
2226
    if (LJ_DUALNUM && rc == ~LJ_TNUMX+1)
15✔
2227
      ra = lj_opt_narrow_toint(J, ra);
2228
    else if (rc == ~LJ_TNUMX+2)
15✔
2229
      ra = lj_ir_tonum(J, ra);
2✔
2230
    else if (rc == ~LJ_TSTR+1)
13✔
2231
      ra = lj_ir_tostr(J, ra);
6✔
2232
    /* else: type specialization suffices. */
2233
    J->base[bc_a(ins)] = ra;
15✔
2234
    break;
15✔
2235

2236
  /* -- Unary ops --------------------------------------------------------- */
2237

2238
  case BC_NOT:
4✔
2239
    /* Type specialization already forces const result. */
2240
    rc = tref_istruecond(rc) ? TREF_FALSE : TREF_TRUE;
4✔
2241
    break;
2242

2243
  case BC_LEN:
59✔
2244
    if (tref_isstr(rc))
59✔
2245
      rc = emitir(IRTI(IR_FLOAD), rc, IRFL_STR_LEN);
7✔
2246
    else if (!LJ_52 && tref_istab(rc))
52✔
2247
      rc = lj_ir_call(J, IRCALL_lj_tab_len, rc);
50✔
2248
    else
2249
      rc = rec_mm_len(J, rc, rcv);
2✔
2250
    break;
2251

2252
  /* -- Arithmetic ops ---------------------------------------------------- */
2253

2254
  case BC_UNM:
24✔
2255
    if (tref_isnumber_str(rc)) {
24✔
2256
      rc = lj_opt_narrow_unm(J, rc, rcv);
21✔
2257
    } else {
2258
      ix.tab = rc;
3✔
2259
      copyTV(J->L, &ix.tabv, rcv);
3✔
2260
      rc = rec_mm_arith(J, &ix, MM_unm);
3✔
2261
    }
2262
    break;
2263

2264
  case BC_ADDNV: case BC_SUBNV: case BC_MULNV: case BC_DIVNV: case BC_MODNV:
96,376✔
2265
    /* Swap rb/rc and rbv/rcv. rav is temp. */
2266
    ix.tab = rc; ix.key = rc = rb; rb = ix.tab;
96,376✔
2267
    copyTV(J->L, rav, rbv);
96,376✔
2268
    copyTV(J->L, rbv, rcv);
96,376✔
2269
    copyTV(J->L, rcv, rav);
96,376✔
2270
    if (op == BC_MODNV)
96,376✔
2271
      goto recmod;
1✔
2272
    /* fallthrough */
2273
  case BC_ADDVN: case BC_SUBVN: case BC_MULVN: case BC_DIVVN:
2274
  case BC_ADDVV: case BC_SUBVV: case BC_MULVV: case BC_DIVVV: {
2275
    MMS mm = bcmode_mm(op);
299,559✔
2276
    if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
299,559✔
2277
      rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv,
260,570✔
2278
                               (int)mm - (int)MM_add + (int)IR_ADD);
260,570✔
2279
    else
2280
      rc = rec_mm_arith(J, &ix, mm);
38,989✔
2281
    break;
2282
    }
2283

2284
  case BC_MODVN: case BC_MODVV:
2285
  recmod:
68✔
2286
    if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
68✔
2287
      rc = lj_opt_narrow_mod(J, rb, rc, rbv, rcv);
63✔
2288
    else
2289
      rc = rec_mm_arith(J, &ix, MM_mod);
5✔
2290
    break;
2291

2292
  case BC_POW:
9,699✔
2293
    if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
9,699✔
2294
      rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv, IR_POW);
9,693✔
2295
    else
2296
      rc = rec_mm_arith(J, &ix, MM_pow);
6✔
2297
    break;
2298

2299
  /* -- Miscellaneous ops ------------------------------------------------- */
2300

2301
  case BC_CAT:
277✔
2302
    rc = rec_cat(J, rb, rc);
277✔
2303
    break;
277✔
2304

2305
  /* -- Constant and move ops --------------------------------------------- */
2306

2307
  case BC_MOV:
486,525✔
2308
    /* Clear gap of method call to avoid resurrecting previous refs. */
2309
    if (ra > J->maxslot) {
486,525✔
2310
#if LJ_FR2
2311
      memset(J->base + J->maxslot, 0, (ra - J->maxslot) * sizeof(TRef));
369,669✔
2312
#else
2313
      J->base[ra-1] = 0;
2314
#endif
2315
    }
2316
    break;
2317
  case BC_KSTR: case BC_KNUM: case BC_KPRI:
2318
    break;
2319
  case BC_KSHORT:
245,817✔
2320
    rc = lj_ir_kint(J, (int32_t)(int16_t)rc);
245,817✔
2321
    break;
245,817✔
2322
  case BC_KNIL:
14✔
2323
    if (LJ_FR2 && ra > J->maxslot)
14✔
2324
      J->base[ra-1] = 0;
1✔
2325
    while (ra <= rc)
623✔
2326
      J->base[ra++] = TREF_NIL;
609✔
2327
    if (rc >= J->maxslot) J->maxslot = rc+1;
14✔
2328
    break;
2329
#if LJ_HASFFI
2330
  case BC_KCDATA:
49✔
2331
    rc = lj_ir_kgc(J, proto_kgc(J->pt, ~(ptrdiff_t)rc), IRT_CDATA);
49✔
2332
    break;
49✔
2333
#endif
2334

2335
  /* -- Upvalue and function ops ------------------------------------------ */
2336

2337
  case BC_UGET:
935,588✔
2338
    rc = rec_upvalue(J, rc, 0);
935,588✔
2339
    break;
935,588✔
2340
  case BC_USETV: case BC_USETS: case BC_USETN: case BC_USETP:
188✔
2341
    rec_upvalue(J, ra, rc);
188✔
2342
    break;
188✔
2343

2344
  /* -- Table ops --------------------------------------------------------- */
2345

2346
  case BC_GGET: case BC_GSET:
5,000✔
2347
    settabV(J->L, &ix.tabv, tabref(J->fn->l.env));
5,000✔
2348
    ix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), getcurrf(J), IRFL_FUNC_ENV);
5,000✔
2349
    ix.idxchain = LJ_MAX_IDXCHAIN;
5,000✔
2350
    rc = lj_record_idx(J, &ix);
5,000✔
2351
    break;
5,000✔
2352

2353
  case BC_TGETB: case BC_TSETB:
584✔
2354
    setintV(&ix.keyv, (int32_t)rc);
584✔
2355
    ix.key = lj_ir_kint(J, (int32_t)rc);
584✔
2356
    /* fallthrough */
2357
  case BC_TGETV: case BC_TGETS: case BC_TSETV: case BC_TSETS:
1,292,921✔
2358
    ix.idxchain = LJ_MAX_IDXCHAIN;
1,292,921✔
2359
    rc = lj_record_idx(J, &ix);
1,292,921✔
2360
    break;
1,292,921✔
2361
  case BC_TGETR: case BC_TSETR:
26✔
2362
    ix.idxchain = 0;
26✔
2363
    rc = lj_record_idx(J, &ix);
26✔
2364
    break;
26✔
2365

2366
  case BC_TSETM:
5✔
2367
    rec_tsetm(J, ra, (BCReg)(J->L->top - J->L->base), (int32_t)rcv->u32.lo);
5✔
2368
    J->maxslot = ra;  /* The table slot at ra-1 is the highest used slot. */
5✔
2369
    break;
5✔
2370

2371
  case BC_TNEW:
2372
    rc = rec_tnew(J, rc);
541✔
2373
    break;
541✔
2374
  case BC_TDUP:
497✔
2375
    rc = emitir(IRTG(IR_TDUP, IRT_TAB),
497✔
2376
                lj_ir_ktab(J, gco2tab(proto_kgc(J->pt, ~(ptrdiff_t)rc))), 0);
2377
#ifdef LUAJIT_ENABLE_TABLE_BUMP
2378
    J->rbchash[(rc & (RBCHASH_SLOTS-1))].ref = tref_ref(rc);
2379
    setmref(J->rbchash[(rc & (RBCHASH_SLOTS-1))].pc, pc);
2380
    setgcref(J->rbchash[(rc & (RBCHASH_SLOTS-1))].pt, obj2gco(J->pt));
2381
#endif
2382
    break;
497✔
2383

2384
  /* -- Calls and vararg handling ----------------------------------------- */
2385

2386
  case BC_ITERC:
108✔
2387
    J->base[ra] = getslot(J, ra-3);
108✔
2388
    J->base[ra+1+LJ_FR2] = getslot(J, ra-2);
108✔
2389
    J->base[ra+2+LJ_FR2] = getslot(J, ra-1);
108✔
2390
    { /* Do the actual copy now because lj_record_call needs the values. */
2391
      TValue *b = &J->L->base[ra];
108✔
2392
      copyTV(J->L, b, b-3);
108✔
2393
      copyTV(J->L, b+1+LJ_FR2, b-2);
108✔
2394
      copyTV(J->L, b+2+LJ_FR2, b-1);
108✔
2395
    }
2396
    lj_record_call(J, ra, (ptrdiff_t)rc-1);
108✔
2397
    break;
108✔
2398

2399
  /* L->top is set to L->base+ra+rc+NARGS-1+1. See lj_dispatch_ins(). */
2400
  case BC_CALLM:
106,018✔
2401
    rc = (BCReg)(J->L->top - J->L->base) - ra - LJ_FR2;
106,018✔
2402
    /* fallthrough */
2403
  case BC_CALL:
803,961✔
2404
    lj_record_call(J, ra, (ptrdiff_t)rc-1);
803,961✔
2405
    break;
803,961✔
2406

2407
  case BC_CALLMT:
12✔
2408
    rc = (BCReg)(J->L->top - J->L->base) - ra - LJ_FR2;
12✔
2409
    /* fallthrough */
2410
  case BC_CALLT:
91,468✔
2411
    lj_record_tailcall(J, ra, (ptrdiff_t)rc-1);
91,468✔
2412
    break;
91,468✔
2413

2414
  case BC_VARG:
42✔
2415
    rec_varg(J, ra, (ptrdiff_t)rb-1);
42✔
2416
    break;
42✔
2417

2418
  /* -- Returns ----------------------------------------------------------- */
2419

2420
  case BC_RETM:
26✔
2421
    /* L->top is set to L->base+ra+rc+NRESULTS-1, see lj_dispatch_ins(). */
2422
    rc = (BCReg)(J->L->top - J->L->base) - ra + 1;
26✔
2423
    /* fallthrough */
2424
  case BC_RET: case BC_RET0: case BC_RET1:
705,511✔
2425
#if LJ_HASPROFILE
2426
    rec_profile_ret(J);
705,511✔
2427
#endif
2428
    lj_record_ret(J, ra, (ptrdiff_t)rc-1);
705,511✔
2429
    break;
705,511✔
2430

2431
  /* -- Loops and branches ------------------------------------------------ */
2432

2433
  case BC_FORI:
144✔
2434
    if (rec_for(J, pc, 0) != LOOPEV_LEAVE)
144✔
2435
      J->loopref = J->cur.nins;
144✔
2436
    break;
2437
  case BC_JFORI:
99✔
2438
    lj_assertJ(bc_op(pc[(ptrdiff_t)rc-BCBIAS_J]) == BC_JFORL,
99✔
2439
               "JFORI does not point to JFORL");
2440
    if (rec_for(J, pc, 0) != LOOPEV_LEAVE)  /* Link to existing loop. */
99✔
2441
      lj_record_stop(J, LJ_TRLINK_ROOT, bc_d(pc[(ptrdiff_t)rc-BCBIAS_J]));
96✔
2442
    /* Continue tracing if the loop is not entered. */
2443
    break;
2444

2445
  case BC_FORL:
2,260✔
2446
    rec_loop_interp(J, pc, rec_for(J, pc+((ptrdiff_t)rc-BCBIAS_J), 1));
2,260✔
2447
    break;
2,260✔
2448
  case BC_ITERL:
46✔
2449
    rec_loop_interp(J, pc, rec_iterl(J, *pc));
46✔
2450
    break;
46✔
2451
  case BC_LOOP:
19,394✔
2452
    rec_loop_interp(J, pc, rec_loop(J, ra, 1));
19,394✔
2453
    break;
19,394✔
2454

2455
  case BC_JFORL:
374✔
2456
    rec_loop_jit(J, rc, rec_for(J, pc+bc_j(traceref(J, rc)->startins), 1));
374✔
2457
    break;
374✔
2458
  case BC_JITERL:
61✔
2459
    rec_loop_jit(J, rc, rec_iterl(J, traceref(J, rc)->startins));
61✔
2460
    break;
61✔
2461
  case BC_JLOOP:
9,175✔
2462
    rec_loop_jit(J, rc, rec_loop(J, ra,
18,350✔
2463
                                 !bc_isret(bc_op(traceref(J, rc)->startins))));
9,175✔
2464
    break;
9,175✔
2465

2466
  case BC_IFORL:
2✔
2467
  case BC_IITERL:
2468
  case BC_ILOOP:
2469
  case BC_IFUNCF:
2470
  case BC_IFUNCV:
2471
    lj_trace_err(J, LJ_TRERR_BLACKL);
2✔
2472
    break;
113,072✔
2473

2474
  case BC_JMP:
113,072✔
2475
    if (ra < J->maxslot)
113,072✔
2476
      J->maxslot = ra;  /* Shrink used slots. */
102,484✔
2477
    break;
2478

2479
  /* -- Function headers -------------------------------------------------- */
2480

2481
  case BC_FUNCF:
2482
    rec_func_lua(J);
109,397✔
2483
    break;
2484
  case BC_JFUNCF:
595,187✔
2485
    rec_func_jit(J, rc);
595,187✔
2486
    break;
595,187✔
2487

2488
  case BC_FUNCV:
106✔
2489
    rec_func_vararg(J);
106✔
2490
    rec_func_lua(J);
106✔
2491
    break;
2492
  case BC_JFUNCV:
2493
    /* Cannot happen. No hotcall counting for varag funcs. */
2494
    lj_assertJ(0, "unsupported vararg hotcall");
2495
    break;
2496

2497
  case BC_FUNCC:
129,963✔
2498
  case BC_FUNCCW:
2499
    lj_ffrecord_func(J);
129,963✔
2500
    break;
129,963✔
2501

2502
  default:
158,558✔
2503
    if (op >= BC__MAX) {
158,558✔
2504
      lj_ffrecord_func(J);
158,558✔
2505
      break;
158,558✔
2506
    }
2507
    /* fallthrough */
2508
  case BC_ITERN:
2509
  case BC_ISNEXT:
2510
  case BC_UCLO:
2511
  case BC_FNEW:
2512
    setintV(&J->errinfo, (int32_t)op);
54✔
2513
    lj_trace_err_info(J, LJ_TRERR_NYIBC);
54✔
2514
    break;
6,893,061✔
2515
  }
2516

2517
  /* rc == 0 if we have no result yet, e.g. pending __index metamethod call. */
2518
  if (bcmode_a(op) == BCMdst && rc) {
6,893,061✔
2519
    J->base[ra] = rc;
3,043,741✔
2520
    if (ra >= J->maxslot) {
3,043,741✔
2521
#if LJ_FR2
2522
      if (ra > J->maxslot) J->base[ra-1] = 0;
2,469,428✔
2523
#endif
2524
      J->maxslot = ra+1;
2,469,428✔
2525
    }
2526
  }
2527

2528
#undef rav
2529
#undef rbv
2530
#undef rcv
2531

2532
  /* Limit the number of recorded IR instructions and constants. */
2533
  if (J->cur.nins > REF_FIRST+(IRRef)J->param[JIT_P_maxrecord] ||
6,893,061✔
2534
      J->cur.nk < REF_BIAS-(IRRef)J->param[JIT_P_maxirconst])
6,893,061✔
2535
    lj_trace_err(J, LJ_TRERR_TRACEOV);
2✔
2536
}
2537

2538
/* -- Recording setup ----------------------------------------------------- */
2539

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

2596
/* Setup for recording a new trace. */
2597
void lj_record_setup(jit_State *J)
19,273✔
2598
{
2599
  uint32_t i;
19,273✔
2600

2601
  /* Initialize state related to current trace. */
2602
  memset(J->slot, 0, sizeof(J->slot));
19,273✔
2603
  memset(J->chain, 0, sizeof(J->chain));
19,273✔
2604
#ifdef LUAJIT_ENABLE_TABLE_BUMP
2605
  memset(J->rbchash, 0, sizeof(J->rbchash));
2606
#endif
2607
  memset(J->bpropcache, 0, sizeof(J->bpropcache));
19,273✔
2608
  J->scev.idx = REF_NIL;
19,273✔
2609
  setmref(J->scev.pc, NULL);
19,273✔
2610

2611
  J->baseslot = 1+LJ_FR2;  /* Invoking function is at base[-1-LJ_FR2]. */
19,273✔
2612
  J->base = J->slot + J->baseslot;
19,273✔
2613
  J->maxslot = 0;
19,273✔
2614
  J->framedepth = 0;
19,273✔
2615
  J->retdepth = 0;
19,273✔
2616

2617
  J->instunroll = J->param[JIT_P_instunroll];
19,273✔
2618
  J->loopunroll = J->param[JIT_P_loopunroll];
19,273✔
2619
  J->tailcalled = 0;
19,273✔
2620
  J->loopref = 0;
19,273✔
2621

2622
  J->bc_min = NULL;  /* Means no limit. */
19,273✔
2623
  J->bc_extent = ~(MSize)0;
19,273✔
2624

2625
  /* Emit instructions for fixed references. Also triggers initial IR alloc. */
2626
  emitir_raw(IRT(IR_BASE, IRT_PGC), J->parent, J->exitno);
19,273✔
2627
  for (i = 0; i <= 2; i++) {
96,365✔
2628
    IRIns *ir = IR(REF_NIL-i);
57,819✔
2629
    ir->i = 0;
57,819✔
2630
    ir->t.irt = (uint8_t)(IRT_NIL+i);
57,819✔
2631
    ir->o = IR_KPRI;
57,819✔
2632
    ir->prev = 0;
57,819✔
2633
  }
2634
  J->cur.nk = REF_TRUE;
19,273✔
2635

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

2704
#undef IR
2705
#undef emitir_raw
2706
#undef emitir
2707

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