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

nickg / nvc / 13738584171

08 Mar 2025 12:57PM UTC coverage: 92.236% (-0.05%) from 92.281%
13738584171

push

github

nickg
Add a simple pointer provenance tracking scheme

52 of 53 new or added lines in 3 files covered. (98.11%)

230 existing lines in 7 files now uncovered.

68028 of 73754 relevant lines covered (92.24%)

433200.43 hits per line

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

88.25
/src/jit/jit-interp.c
1
//
2
//  Copyright (C) 2022-2024  Nick Gasson
3
//
4
//  This program is free software: you can redistribute it and/or modify
5
//  it under the terms of the GNU General Public License as published by
6
//  the Free Software Foundation, either version 3 of the License, or
7
//  (at your option) any later version.
8
//
9
//  This program is distributed in the hope that it will be useful,
10
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
//  GNU General Public License for more details.
13
//
14
//  You should have received a copy of the GNU General Public License
15
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
//
17

18
#include "util.h"
19
#include "array.h"
20
#include "common.h"
21
#include "diag.h"
22
#include "jit/jit-exits.h"
23
#include "jit/jit-priv.h"
24
#include "jit/jit-ffi.h"
25
#include "rt/mspace.h"
26
#include "tree.h"
27
#include "type.h"
28

29
#include <assert.h>
30
#include <ctype.h>
31
#include <inttypes.h>
32
#include <math.h>
33
#include <stdlib.h>
34
#include <string.h>
35

36
typedef struct _jit_interp {
37
   jit_scalar_t  *args;
38
   jit_scalar_t  *regs;
39
   unsigned       nargs;
40
   unsigned       pc;
41
   jit_func_t    *func;
42
   unsigned char *frame;
43
   unsigned       flags;
44
   mspace_t      *mspace;
45
   jit_anchor_t  *anchor;
46
   tlab_t        *tlab;
47
} jit_interp_t;
48

49
#ifdef DEBUG
50
#define JIT_ASSERT(expr) do {                                      \
51
      if (unlikely(!(expr))) {                                     \
52
         interp_dump(state);                                       \
53
         fatal_trace("assertion '%s' failed", #expr);              \
54
      }                                                            \
55
   } while (0)
56
#define CANNOT_HANDLE(value) do {                                  \
57
      interp_dump(state);                                          \
58
      fatal_trace("cannot handle value kind %d", value.kind);      \
59
   } while (0)
60
#else
61
#define JIT_ASSERT(expr)
62
#define CANNOT_HANDLE(value) __builtin_unreachable()
63
#endif
64

65
#define FOR_EACH_SIZE(sz, macro) do {                   \
66
      assert((sz) != JIT_SZ_UNSPEC);                    \
67
      switch ((sz)) {                                   \
68
      case JIT_SZ_8: macro(int8_t); break;              \
69
      case JIT_SZ_16: macro(int16_t); break;            \
70
      case JIT_SZ_32: macro(int32_t); break;            \
71
      case JIT_SZ_64: macro(int64_t); break;            \
72
      default: break;                                   \
73
      }                                                 \
74
   } while (0)
75

UNCOV
76
static void interp_dump_reg(jit_interp_t *state, int64_t ival)
×
77
{
UNCOV
78
   printf("%"PRIx64, ival);
×
79
   if ((ival >= -256 && ival < 0) || (ival >= 10 && ival < 256))
×
80
      printf(" (%"PRIi64")\n", ival);
×
81
   else if (ival >= (intptr_t)state->func->cpool
×
82
            && ival < (intptr_t)state->func->cpool + state->func->cpoolsz) {
×
83
      printf(" ==> cpool pointer\n");
×
84
      jit_hexdump((void *)(intptr_t)ival, 8, 8, NULL, "\t\t\t");
×
85
   }
86
   else {
UNCOV
87
      size_t size;
×
88
      void *base;
×
89
      if ((base = mspace_find(state->mspace, (void *)(intptr_t)ival, &size))) {
×
90
         if (size == 0)
×
91
            color_printf("$!red$ ==> bad mspace object$$\n");
×
92
         else {
UNCOV
93
            printf(" ==> %zu byte mspace object\n", size);
×
94
            jit_hexdump(base, size, 8, (void *)(intptr_t)ival, "\t\t\t");
×
95
         }
96
      }
97
      else
UNCOV
98
         printf("\n");
×
99
   }
UNCOV
100
}
×
101

UNCOV
102
static void interp_dump(jit_interp_t *state)
×
103
{
UNCOV
104
   jit_dump_with_mark(state->func, state->pc - 1, false);
×
105

UNCOV
106
   printf("Arguments:\n");
×
107
   for (int i = 0; i < state->nargs; i++) {
×
108
      printf("\tA%d\t", i);
×
109
      interp_dump_reg(state, state->args[i].integer);
×
110
   }
111

UNCOV
112
   printf("\nRegisters:\n");
×
113
   for (int i = 0; i < state->func->nregs; i++) {
×
114
      printf("\tR%d\t", i);
×
115
      interp_dump_reg(state, state->regs[i].integer);
×
116
   }
117

UNCOV
118
   printf("\nFlags: %c\n", state->flags ? 'T' : 'F');
×
119

UNCOV
120
   if (state->func->framesz > 0) {
×
121
      printf("\nFrame:\n");
×
122
      jit_hexdump(state->frame, state->func->framesz, 16, NULL, "\t");
×
123
   }
124

UNCOV
125
   if (state->func->cpoolsz > 0) {
×
126
      printf("\nConstant pool:\n");
×
127
      jit_hexdump(state->func->cpool, state->func->cpoolsz, 16, NULL, "\t");
×
128
   }
129

UNCOV
130
   printf("\n");
×
131
   fflush(stdout);
×
132
}
×
133

134
__attribute__((always_inline))
135
static inline int64_t interp_get_int(jit_interp_t *state, jit_value_t value)
220,125,293✔
136
{
137
   switch (value.kind) {
220,125,293✔
138
   case JIT_VALUE_REG:
170,794,222✔
139
      JIT_ASSERT(value.reg < state->func->nregs);
170,794,222✔
140
      return state->regs[value.reg].integer;
170,794,222✔
141
   case JIT_VALUE_INT64:
49,331,071✔
142
   case JIT_VALUE_DOUBLE:
143
   case JIT_ADDR_ABS:
144
      return value.int64;
49,331,071✔
UNCOV
145
   default:
×
146
      CANNOT_HANDLE(value);
×
147
   }
148
}
149

150
__attribute__((always_inline))
151
static inline double interp_get_real(jit_interp_t *state, jit_value_t value)
112,208✔
152
{
153
   switch (value.kind) {
112,208✔
154
   case JIT_VALUE_REG:
92,001✔
155
      JIT_ASSERT(value.reg < state->func->nregs);
92,001✔
156
      return state->regs[value.reg].real;
92,001✔
157
   case JIT_VALUE_INT64:
20,207✔
158
   case JIT_VALUE_DOUBLE:
159
      return value.dval;
20,207✔
UNCOV
160
   default:
×
161
      CANNOT_HANDLE(value);
×
162
   }
163
}
164

165
__attribute__((always_inline))
166
static inline void *interp_get_pointer(jit_interp_t *state, jit_value_t value)
38,729,313✔
167
{
168
   switch (value.kind) {
38,729,313✔
169
   case JIT_VALUE_REG:
11,339✔
170
      JIT_ASSERT(value.reg < state->func->nregs);
11,339✔
171
      return state->regs[value.reg].pointer;
11,339✔
172
   case JIT_ADDR_CPOOL:
171,718✔
173
      JIT_ASSERT(value.int64 >= 0 && value.int64 <= state->func->cpoolsz);
171,718✔
174
      return state->func->cpool + value.int64;
171,718✔
175
   case JIT_ADDR_REG:
38,545,541✔
176
      JIT_ASSERT(value.reg < state->func->nregs);
38,545,541✔
177
      return state->regs[value.reg].pointer + value.disp;
38,545,541✔
UNCOV
178
   case JIT_ADDR_ABS:
×
179
      return (void *)(intptr_t)value.int64;
×
180
   case JIT_ADDR_COVER:
715✔
181
      return jit_get_cover_ptr(state->func->jit, value);
715✔
UNCOV
182
   default:
×
183
      CANNOT_HANDLE(value);
×
184
   }
185
}
186

187
__attribute__((always_inline))
188
static inline jit_scalar_t interp_get_scalar(jit_interp_t *state,
35,747,884✔
189
                                             jit_value_t value)
190
{
191
   switch (value.kind) {
35,747,884✔
192
   case JIT_VALUE_REG:
25,802,414✔
193
      JIT_ASSERT(value.reg < state->func->nregs);
25,802,414✔
194
      return state->regs[value.reg];
25,802,414✔
195
   case JIT_VALUE_INT64:
9,542,624✔
196
      return (jit_scalar_t){ .integer = value.int64 };
9,542,624✔
197
   case JIT_VALUE_DOUBLE:
20,292✔
198
      return (jit_scalar_t){ .real = value.dval };
20,292✔
UNCOV
199
   case JIT_VALUE_LABEL:
×
200
      return (jit_scalar_t){ .integer = value.label };
×
201
   case JIT_VALUE_HANDLE:
5,206✔
202
      return (jit_scalar_t){ .integer = value.handle };
5,206✔
203
   case JIT_VALUE_LOCUS:
52,872✔
204
      return (jit_scalar_t){ .pointer = value.locus };
52,872✔
205
   case JIT_ADDR_CPOOL:
2,380✔
206
      JIT_ASSERT(value.int64 >= 0 && value.int64 <= state->func->cpoolsz);
2,380✔
207
      return (jit_scalar_t){ .pointer = state->func->cpool + value.int64 };
2,380✔
208
   case JIT_ADDR_REG:
179,111✔
209
      JIT_ASSERT(value.reg < state->func->nregs);
179,111✔
210
      return (jit_scalar_t){
179,111✔
211
         .pointer = state->regs[value.reg].pointer + value.disp
179,111✔
212
      };
213
   case JIT_ADDR_ABS:
142,985✔
214
      return (jit_scalar_t){ .pointer = (void *)(intptr_t)value.int64 };
142,985✔
UNCOV
215
   case JIT_ADDR_COVER:
×
216
      return (jit_scalar_t){
×
217
         .pointer = jit_get_cover_ptr(state->func->jit, value)
×
218
      };
UNCOV
219
   default:
×
220
      CANNOT_HANDLE(value);
×
221
   }
222
}
223

224
static void interp_recv(jit_interp_t *state, jit_ir_t *ir)
3,878,096✔
225
{
226
   JIT_ASSERT(ir->arg1.kind == JIT_VALUE_INT64);
3,878,096✔
227
   const int nth = ir->arg1.int64;
3,878,096✔
228

229
   JIT_ASSERT(nth < JIT_MAX_ARGS);
3,878,096✔
230
   state->regs[ir->result] = state->args[nth];
3,878,096✔
231
   state->nargs = MAX(state->nargs, nth + 1);
3,878,096✔
232
}
3,878,096✔
233

234
static void interp_send(jit_interp_t *state, jit_ir_t *ir)
16,184,455✔
235
{
236
   JIT_ASSERT(ir->arg1.kind == JIT_VALUE_INT64);
16,184,455✔
237
   const int nth = ir->arg1.int64;
16,184,455✔
238

239
   JIT_ASSERT(nth < JIT_MAX_ARGS);
16,184,455✔
240
   state->args[nth] = interp_get_scalar(state, ir->arg2);
16,184,455✔
241
   state->nargs = MAX(state->nargs, nth + 1);
16,184,455✔
242
}
16,184,455✔
243

244
static void interp_and(jit_interp_t *state, jit_ir_t *ir)
5,238✔
245
{
246
   const int64_t arg1 = interp_get_int(state, ir->arg1);
5,238✔
247
   const int64_t arg2 = interp_get_int(state, ir->arg2);
5,238✔
248

249
   state->regs[ir->result].integer = arg1 & arg2;
5,238✔
250
}
5,238✔
251

252
static void interp_or(jit_interp_t *state, jit_ir_t *ir)
1,106✔
253
{
254
   const int64_t arg1 = interp_get_int(state, ir->arg1);
1,106✔
255
   const int64_t arg2 = interp_get_int(state, ir->arg2);
1,106✔
256

257
   state->regs[ir->result].integer = arg1 | arg2;
1,106✔
258
}
1,106✔
259

260
static void interp_xor(jit_interp_t *state, jit_ir_t *ir)
3,295,135✔
261
{
262
   const int64_t arg1 = interp_get_int(state, ir->arg1);
3,295,135✔
263
   const int64_t arg2 = interp_get_int(state, ir->arg2);
3,295,135✔
264

265
   state->regs[ir->result].integer = arg1 ^ arg2;
3,295,135✔
266
}
3,295,135✔
267

268
static void interp_mul(jit_interp_t *state, jit_ir_t *ir)
2,477,910✔
269
{
270
   const int64_t arg1 = interp_get_int(state, ir->arg1);
2,477,910✔
271
   const int64_t arg2 = interp_get_int(state, ir->arg2);
2,477,910✔
272

273
   if (ir->cc == JIT_CC_O) {
2,477,910✔
274
      int overflow = 0;
1,593✔
275

276
#define MUL_OVERFLOW(type) do {                                 \
277
         type i1 = arg1, i2 = arg2, i0;                         \
278
         overflow = __builtin_mul_overflow(i1, i2, &i0);        \
279
         state->regs[ir->result].integer = i0;                  \
280
      } while (0)
281

282
      FOR_EACH_SIZE(ir->size, MUL_OVERFLOW);
1,593✔
283

284
      state->flags = overflow;
1,593✔
285
   }
286
   else if (ir->cc == JIT_CC_C) {
2,476,317✔
287
      int overflow = 0;
4✔
288

289
#define UMUL_OVERFLOW(type) do {                                \
290
         u##type i1 = arg1, i2 = arg2, i0;                      \
291
         overflow = __builtin_mul_overflow(i1, i2, &i0);        \
292
         state->regs[ir->result].integer = i0;                  \
293
      } while (0)
294

295
      FOR_EACH_SIZE(ir->size, UMUL_OVERFLOW);
4✔
296

297
      state->flags = overflow;
4✔
298
   }
299
   else
300
      state->regs[ir->result].integer = arg1 * arg2;
2,476,313✔
301
}
2,477,910✔
302

303
static void interp_fmul(jit_interp_t *state, jit_ir_t *ir)
1,994✔
304
{
305
   const double arg1 = interp_get_real(state, ir->arg1);
1,994✔
306
   const double arg2 = interp_get_real(state, ir->arg2);
1,994✔
307

308
   state->regs[ir->result].real = arg1 * arg2;
1,994✔
309
}
1,994✔
310

311
static void interp_div(jit_interp_t *state, jit_ir_t *ir)
62,291✔
312
{
313
   const int64_t arg1 = interp_get_int(state, ir->arg1);
62,291✔
314
   const int64_t arg2 = interp_get_int(state, ir->arg2);
62,291✔
315

316
   state->regs[ir->result].integer = arg1 / arg2;
62,291✔
317
}
62,291✔
318

319
static void interp_fdiv(jit_interp_t *state, jit_ir_t *ir)
2,232✔
320
{
321
   const double arg1 = interp_get_real(state, ir->arg1);
2,232✔
322
   const double arg2 = interp_get_real(state, ir->arg2);
2,232✔
323

324
   state->regs[ir->result].real = arg1 / arg2;
2,232✔
325
}
2,232✔
326

327
static void interp_sub(jit_interp_t *state, jit_ir_t *ir)
14,512,818✔
328
{
329
   const int64_t arg1 = interp_get_int(state, ir->arg1);
14,512,818✔
330
   const int64_t arg2 = interp_get_int(state, ir->arg2);
14,512,818✔
331

332
   if (ir->cc == JIT_CC_O) {
14,512,818✔
333
      int overflow = 0;
1,019✔
334

335
#define SUB_OVERFLOW(type) do {                                 \
336
         type i1 = arg1, i2 = arg2, i0;                         \
337
         overflow = __builtin_sub_overflow(i1, i2, &i0);        \
338
         state->regs[ir->result].integer = i0;                  \
339
      } while (0)
340

341
      FOR_EACH_SIZE(ir->size, SUB_OVERFLOW);
1,019✔
342

343
      state->flags = overflow;
1,019✔
344
   }
345
   else if (ir->cc == JIT_CC_C) {
14,511,799✔
346
      int overflow = 0;
3✔
347

348
#define USUB_OVERFLOW(type) do {                                \
349
         u##type i1 = arg1, i2 = arg2, i0;                      \
350
         overflow = __builtin_sub_overflow(i1, i2, &i0);        \
351
         state->regs[ir->result].integer = i0;                  \
352
      } while (0)
353

354
      FOR_EACH_SIZE(ir->size, USUB_OVERFLOW);
3✔
355

356
      state->flags = overflow;
3✔
357
   }
358
   else
359
      state->regs[ir->result].integer = arg1 - arg2;
14,511,796✔
360
}
14,512,818✔
361

362
static void interp_fsub(jit_interp_t *state, jit_ir_t *ir)
2,263✔
363
{
364
   const double arg1 = interp_get_real(state, ir->arg1);
2,263✔
365
   const double arg2 = interp_get_real(state, ir->arg2);
2,263✔
366

367
   state->regs[ir->result].real = arg1 - arg2;
2,263✔
368
}
2,263✔
369

370
static void interp_add(jit_interp_t *state, jit_ir_t *ir)
36,327,162✔
371
{
372
   const int64_t arg1 = interp_get_int(state, ir->arg1);
36,327,162✔
373
   const int64_t arg2 = interp_get_int(state, ir->arg2);
36,327,162✔
374

375
   if (ir->cc == JIT_CC_O) {
36,327,162✔
376
      int overflow = 0;
1,105,432✔
377

378
#define ADD_OVERFLOW(type) do {                                 \
379
         type i1 = arg1, i2 = arg2, i0;                         \
380
         overflow = __builtin_add_overflow(i1, i2, &i0);        \
381
         state->regs[ir->result].integer = i0;                  \
382
      } while (0)
383

384
      FOR_EACH_SIZE(ir->size, ADD_OVERFLOW);
1,105,432✔
385

386
      state->flags = overflow;
1,105,432✔
387
   }
388
   else if (ir->cc == JIT_CC_C) {
35,221,730✔
389
      int overflow = 0;
4✔
390

391
#define UADD_OVERFLOW(type) do {                                \
392
         u##type i1 = arg1, i2 = arg2, i0;                      \
393
         overflow = __builtin_add_overflow(i1, i2, &i0);        \
394
         state->regs[ir->result].integer = i0;                  \
395
      } while (0)
396

397
      FOR_EACH_SIZE(ir->size, UADD_OVERFLOW);
4✔
398

399
      state->flags = overflow;
4✔
400
   }
401
   else
402
      state->regs[ir->result].integer = arg1 + arg2;
35,221,726✔
403
}
36,327,162✔
404

405
static void interp_fadd(jit_interp_t *state, jit_ir_t *ir)
1,120✔
406
{
407
   const double arg1 = interp_get_real(state, ir->arg1);
1,120✔
408
   const double arg2 = interp_get_real(state, ir->arg2);
1,120✔
409

410
   state->regs[ir->result].real = arg1 + arg2;
1,120✔
411
}
1,120✔
412

413
static void interp_shl(jit_interp_t *state, jit_ir_t *ir)
4,715,331✔
414
{
415
   const int64_t arg1 = interp_get_int(state, ir->arg1);
4,715,331✔
416
   const int64_t arg2 = interp_get_int(state, ir->arg2);
4,715,331✔
417

418
   state->regs[ir->result].integer = arg1 << arg2;
4,715,331✔
419
}
4,715,331✔
420

421
static void interp_asr(jit_interp_t *state, jit_ir_t *ir)
3,058,501✔
422
{
423
   const int64_t arg1 = interp_get_int(state, ir->arg1);
3,058,501✔
424
   const int64_t arg2 = interp_get_int(state, ir->arg2);
3,058,501✔
425

426
   state->regs[ir->result].integer = arg1 >> arg2;
3,058,501✔
427
}
3,058,501✔
428

429
static void interp_store(jit_interp_t *state, jit_ir_t *ir)
7,175,848✔
430
{
431
   jit_scalar_t arg1 = interp_get_scalar(state, ir->arg1);
7,175,848✔
432
   void *arg2 = interp_get_pointer(state, ir->arg2);
7,175,848✔
433

434
   JIT_ASSERT(ir->size != JIT_SZ_UNSPEC);
7,175,848✔
435
   JIT_ASSERT(arg2 != NULL);
7,175,848✔
436
   JIT_ASSERT((intptr_t)arg2 >= 4096);
7,175,848✔
437

438
   switch (ir->size) {
7,175,848✔
439
   case JIT_SZ_8:
4,401,751✔
440
      *(uint8_t *)arg2 = (uint8_t)arg1.integer;
4,401,751✔
441
      break;
4,401,751✔
442
   case JIT_SZ_16:
262✔
443
      *(uint16_t *)arg2 = (uint16_t)arg1.integer;
262✔
444
      break;
262✔
445
   case JIT_SZ_32:
1,394,774✔
446
      *(uint32_t *)arg2 = (uint32_t)arg1.integer;
1,394,774✔
447
      break;
1,394,774✔
448
   case JIT_SZ_64:
1,379,061✔
449
      *(uint64_t *)arg2 = arg1.integer;
1,379,061✔
450
      break;
1,379,061✔
451
   case JIT_SZ_UNSPEC:
452
      break;
453
   }
454
}
7,175,848✔
455

456
static void interp_uload(jit_interp_t *state, jit_ir_t *ir)
5,658,566✔
457
{
458
   void *arg1 = interp_get_pointer(state, ir->arg1);
5,658,566✔
459

460
   JIT_ASSERT(ir->size != JIT_SZ_UNSPEC);
5,658,566✔
461
   JIT_ASSERT(arg1 != NULL);
5,658,566✔
462
   JIT_ASSERT((intptr_t)arg1 >= 4096);
5,658,566✔
463

464
   switch (ir->size) {
5,658,566✔
465
   case JIT_SZ_8:
5,658,522✔
466
      state->regs[ir->result].integer = *(uint8_t *)arg1;
5,658,522✔
467
      break;
5,658,522✔
468
   case JIT_SZ_16:
5✔
469
      state->regs[ir->result].integer = *(uint16_t *)arg1;
5✔
470
      break;
5✔
471
   case JIT_SZ_32:
29✔
472
      state->regs[ir->result].integer = *(uint32_t *)arg1;
29✔
473
      break;
29✔
474
   case JIT_SZ_64:
10✔
475
      state->regs[ir->result].integer = *(uint64_t *)arg1;
10✔
476
      break;
10✔
477
   case JIT_SZ_UNSPEC:
478
      break;
479
   }
480
}
5,658,566✔
481

482
static void interp_load(jit_interp_t *state, jit_ir_t *ir)
22,715,411✔
483
{
484
   void *arg1 = interp_get_pointer(state, ir->arg1);
22,715,411✔
485

486
   JIT_ASSERT(ir->size != JIT_SZ_UNSPEC);
22,715,411✔
487
   JIT_ASSERT(arg1 != NULL);
22,715,411✔
488
   JIT_ASSERT((intptr_t)arg1 >= 4096);
22,715,411✔
489

490
   switch (ir->size) {
22,715,411✔
491
   case JIT_SZ_8:
6✔
492
      state->regs[ir->result].integer = *(int8_t *)arg1;
6✔
493
      break;
6✔
UNCOV
494
   case JIT_SZ_16:
×
495
      state->regs[ir->result].integer = *(int16_t *)arg1;
×
496
      break;
×
497
   case JIT_SZ_32:
4,057,668✔
498
      state->regs[ir->result].integer = *(int32_t *)arg1;
4,057,668✔
499
      break;
4,057,668✔
500
   case JIT_SZ_64:
18,657,737✔
501
      state->regs[ir->result].integer = *(int64_t *)arg1;
18,657,737✔
502
      break;
18,657,737✔
503
   case JIT_SZ_UNSPEC:
504
      break;
505
   }
506
}
22,715,411✔
507

508
static void interp_cmp(jit_interp_t *state, jit_ir_t *ir)
30,242,158✔
509
{
510
   const int64_t arg1 = interp_get_int(state, ir->arg1);
30,242,158✔
511
   const int64_t arg2 = interp_get_int(state, ir->arg2);
30,242,158✔
512

513
   switch (ir->cc) {
30,242,158✔
514
   case JIT_CC_EQ: state->flags = (arg1 == arg2); break;
9,159,960✔
515
   case JIT_CC_NE: state->flags = (arg1 != arg2); break;
5,112,140✔
516
   case JIT_CC_LT: state->flags = (arg1 < arg2); break;
11,115,643✔
517
   case JIT_CC_GT: state->flags = (arg1 > arg2); break;
27,314✔
518
   case JIT_CC_LE: state->flags = (arg1 <= arg2); break;
276✔
519
   case JIT_CC_GE: state->flags = (arg1 >= arg2); break;
4,826,825✔
UNCOV
520
   default: state->flags = 0; break;
×
521
   }
522
}
30,242,158✔
523

524
static void interp_ccmp(jit_interp_t *state, jit_ir_t *ir)
4,859,506✔
525
{
526
   const int64_t arg1 = interp_get_int(state, ir->arg1);
4,859,506✔
527
   const int64_t arg2 = interp_get_int(state, ir->arg2);
4,859,506✔
528

529
   switch (ir->cc) {
4,859,506✔
UNCOV
530
   case JIT_CC_EQ: state->flags &= (arg1 == arg2); break;
×
531
   case JIT_CC_NE: state->flags &= (arg1 != arg2); break;
×
532
   case JIT_CC_LT: state->flags &= (arg1 < arg2); break;
18,126✔
533
   case JIT_CC_GT: state->flags &= (arg1 > arg2); break;
15,424✔
534
   case JIT_CC_LE: state->flags &= (arg1 <= arg2); break;
4,825,956✔
UNCOV
535
   case JIT_CC_GE: state->flags &= (arg1 >= arg2); break;
×
536
   default: state->flags = 0; break;
×
537
   }
538
}
4,859,506✔
539

540
static void interp_fcmp(jit_interp_t *state, jit_ir_t *ir)
38,223✔
541
{
542
   const double arg1 = interp_get_real(state, ir->arg1);
38,223✔
543
   const double arg2 = interp_get_real(state, ir->arg2);
38,223✔
544

545
   switch (ir->cc) {
38,223✔
546
   case JIT_CC_EQ: state->flags = (arg1 == arg2); break;
27,942✔
547
   case JIT_CC_NE: state->flags = (arg1 != arg2); break;
9✔
548
   case JIT_CC_LT: state->flags = (arg1 < arg2); break;
7,692✔
549
   case JIT_CC_GT: state->flags = (arg1 > arg2); break;
1,092✔
550
   case JIT_CC_LE: state->flags = (arg1 <= arg2); break;
19✔
551
   case JIT_CC_GE: state->flags = (arg1 >= arg2); break;
1,469✔
UNCOV
552
   default: state->flags = 0; break;
×
553
   }
554
}
38,223✔
555

556
static void interp_fccmp(jit_interp_t *state, jit_ir_t *ir)
1,416✔
557
{
558
   const double arg1 = interp_get_real(state, ir->arg1);
1,416✔
559
   const double arg2 = interp_get_real(state, ir->arg2);
1,416✔
560

561
   switch (ir->cc) {
1,416✔
UNCOV
562
   case JIT_CC_EQ: state->flags &= (arg1 == arg2); break;
×
563
   case JIT_CC_NE: state->flags &= (arg1 != arg2); break;
×
564
   case JIT_CC_LT: state->flags &= (arg1 < arg2); break;
×
565
   case JIT_CC_GT: state->flags &= (arg1 > arg2); break;
×
566
   case JIT_CC_LE: state->flags &= (arg1 <= arg2); break;
1,416✔
UNCOV
567
   case JIT_CC_GE: state->flags &= (arg1 >= arg2); break;
×
568
   default: state->flags = 0; break;
×
569
   }
570
}
1,416✔
571

572
static void interp_rem(jit_interp_t *state, jit_ir_t *ir)
66,226✔
573
{
574
   const int64_t x = interp_get_int(state, ir->arg1);
66,226✔
575
   const int64_t y = interp_get_int(state, ir->arg2);
66,226✔
576

577
   state->regs[ir->result].integer = x - (x / y) * y;
66,226✔
578
}
66,226✔
579

580
static void interp_clamp(jit_interp_t *state, jit_ir_t *ir)
244,841✔
581
{
582
   const int64_t value = interp_get_int(state, ir->arg1);
244,841✔
583

584
   state->regs[ir->result].integer = value < 0 ? 0 : value;
244,841✔
585
}
244,841✔
586

587
static void interp_cset(jit_interp_t *state, jit_ir_t *ir)
5,092,944✔
588
{
589
   state->regs[ir->result].integer = !!(state->flags);
5,092,944✔
590
}
5,092,944✔
591

592
static void interp_branch_to(jit_interp_t *state, jit_value_t label)
17,528,790✔
593
{
594
   JIT_ASSERT(label.kind == JIT_VALUE_LABEL);
17,528,790✔
595
   state->pc = label.label;
17,528,790✔
596
   JIT_ASSERT(state->pc < state->func->nirs);
17,528,790✔
597
}
17,528,790✔
598

599
static void interp_jump(jit_interp_t *state, jit_ir_t *ir)
23,552,094✔
600
{
601
   switch (ir->cc) {
23,552,094✔
602
   case JIT_CC_NONE:
7,333,419✔
603
      interp_branch_to(state, ir->arg1);
7,333,419✔
604
      break;
7,333,419✔
605
   case JIT_CC_T:
12,871,736✔
606
      if (state->flags)
12,871,736✔
607
         interp_branch_to(state, ir->arg1);
6,844,840✔
608
      break;
609
   case JIT_CC_F:
3,346,939✔
610
      if (!state->flags)
3,346,939✔
611
         interp_branch_to(state, ir->arg1);
3,314,787✔
612
      break;
UNCOV
613
   default:
×
614
      interp_dump(state);
×
615
      fatal_trace("unhandled jump condition code");
616
   }
617
}
23,552,094✔
618

UNCOV
619
static void interp_trap(jit_interp_t *state, jit_ir_t *ir)
×
620
{
UNCOV
621
   interp_dump(state);
×
622
   fatal_trace("executed trap opcode");
623
}
624

625
static void interp_call(jit_interp_t *state, jit_ir_t *ir)
2,286,463✔
626
{
627
   JIT_ASSERT(ir->arg1.kind == JIT_VALUE_HANDLE);
2,286,463✔
628

629
   state->anchor->irpos = ir - state->func->irbuf;
2,286,463✔
630

631
   if (ir->arg1.handle == JIT_HANDLE_INVALID) {
2,286,463✔
UNCOV
632
      jit_dump_with_mark(state->func, state->anchor->irpos, false);
×
633
      jit_msg(NULL, DIAG_FATAL, "missing definition for subprogram");
×
634
   }
635
   else {
636
      jit_func_t *f = jit_get_func(state->func->jit, ir->arg1.handle);
2,286,463✔
637
      jit_entry_fn_t entry = load_acquire(&f->entry);
2,286,463✔
638
      (*entry)(f, state->anchor, state->args, state->tlab);
2,286,463✔
639
   }
640
}
2,286,377✔
641

642
static void interp_mov(jit_interp_t *state, jit_ir_t *ir)
12,387,581✔
643
{
644
   state->regs[ir->result] = interp_get_scalar(state, ir->arg1);
12,387,581✔
645
}
12,387,581✔
646

647
static void interp_csel(jit_interp_t *state, jit_ir_t *ir)
19,722,876✔
648
{
649
   if (state->flags)
19,722,876✔
650
      state->regs[ir->result].integer = interp_get_int(state, ir->arg1);
19,822,614✔
651
   else
652
      state->regs[ir->result].integer = interp_get_int(state, ir->arg2);
19,623,138✔
653
}
19,722,876✔
654

655
static void interp_neg(jit_interp_t *state, jit_ir_t *ir)
251,502✔
656
{
657
   state->regs[ir->result].integer = -interp_get_int(state, ir->arg1);
251,502✔
658
}
251,502✔
659

660
static void interp_fneg(jit_interp_t *state, jit_ir_t *ir)
12,336✔
661
{
662
   state->regs[ir->result].real = -interp_get_real(state, ir->arg1);
12,336✔
663
}
12,336✔
664

665
static void interp_not(jit_interp_t *state, jit_ir_t *ir)
95,319✔
666
{
667
   state->regs[ir->result].integer = !interp_get_int(state, ir->arg1);
95,319✔
668
}
95,319✔
669

670
static void interp_scvtf(jit_interp_t *state, jit_ir_t *ir)
4,225✔
671
{
672
   state->regs[ir->result].real = interp_get_int(state, ir->arg1);
4,225✔
673
}
4,225✔
674

675
static void interp_fcvtns(jit_interp_t *state, jit_ir_t *ir)
3,046✔
676
{
677
   const double f = interp_get_real(state, ir->arg1);
3,046✔
678
   state->regs[ir->result].integer = (int64_t)(f + copysign(0.5, f));
3,046✔
679
}
3,046✔
680

681
static void interp_lea(jit_interp_t *state, jit_ir_t *ir)
1,783,967✔
682
{
683
   state->regs[ir->result].pointer = interp_get_pointer(state, ir->arg1);
1,783,967✔
684
}
1,783,967✔
685

686
static void interp_fexp(jit_interp_t *state, jit_ir_t *ir)
1,165✔
687
{
688
   const double x = interp_get_real(state, ir->arg1);
1,165✔
689
   const double y = interp_get_real(state, ir->arg2);
1,165✔
690

691
   state->regs[ir->result].real = pow(x, y);
1,165✔
692
}
1,165✔
693

694
static void interp_exp(jit_interp_t *state, jit_ir_t *ir)
110✔
695
{
696
   const int64_t x = interp_get_int(state, ir->arg1);
110✔
697
   const int64_t y = interp_get_int(state, ir->arg2);
110✔
698

699
   if (ir->cc == JIT_CC_O) {
110✔
700
      int overflow = 0, xo = 0;
103✔
701

702
#define EXP_OVERFLOW(type) do {                                         \
703
         type xt = x, yt = y, r = 1;                                    \
704
         while (yt) {                                                   \
705
            if (yt & 1)                                                 \
706
               overflow |= xo || __builtin_mul_overflow(r, xt, &r);     \
707
            yt >>= 1;                                                   \
708
            xo |= __builtin_mul_overflow(xt, xt, &xt);                  \
709
         }                                                              \
710
         state->regs[ir->result].integer = r;                           \
711
      } while (0)
712

713
      FOR_EACH_SIZE(ir->size, EXP_OVERFLOW);
367✔
714

715
      state->flags = overflow;
103✔
716
   }
717
   else if (ir->cc == JIT_CC_C) {
7✔
718
      int overflow = 0, xo = 0;
6✔
719

720
#define UEXP_OVERFLOW(type) do {                                        \
721
         u##type xt = x, yt = y, r = 1;                                 \
722
         while (yt) {                                                   \
723
            if (yt & 1)                                                 \
724
               overflow |= xo || __builtin_mul_overflow(r, xt, &r);     \
725
            yt >>= 1;                                                   \
726
            xo |= __builtin_mul_overflow(xt, xt, &xt);                  \
727
         }                                                              \
728
         state->regs[ir->result].integer = r;                           \
729
      } while (0)
730

731
      FOR_EACH_SIZE(ir->size, UEXP_OVERFLOW);
29✔
732

733
      state->flags = overflow;
6✔
734
   }
735
   else
736
      state->regs[ir->result].integer = ipow(x, y);
1✔
737
}
110✔
738

739
static void interp_copy(jit_interp_t *state, jit_ir_t *ir)
166,170✔
740
{
741
   const size_t count = state->regs[ir->result].integer;
166,170✔
742
   void *dest = interp_get_pointer(state, ir->arg1);
166,170✔
743
   const void *src = interp_get_pointer(state, ir->arg2);
166,170✔
744

745
   JIT_ASSERT((uintptr_t)dest >= 4096 || count == 0);
166,170✔
746
   JIT_ASSERT((uintptr_t)src >= 4096 || count == 0);
166,170✔
747
   JIT_ASSERT(dest + count <= src || src + count <= dest);
166,170✔
748

749
   memcpy(dest, src, count);
166,170✔
750
}
166,170✔
751

752
static void interp_move(jit_interp_t *state, jit_ir_t *ir)
474,637✔
753
{
754
   const size_t count = state->regs[ir->result].integer;
474,637✔
755
   void *dest = interp_get_pointer(state, ir->arg1);
474,637✔
756
   const void *src = interp_get_pointer(state, ir->arg2);
474,637✔
757

758
   JIT_ASSERT((uintptr_t)dest >= 4096 || count == 0);
474,637✔
759
   JIT_ASSERT((uintptr_t)src >= 4096 || count == 0);
474,637✔
760

761
   memmove(dest, src, count);
474,637✔
762
}
474,637✔
763

764
static void interp_bzero(jit_interp_t *state, jit_ir_t *ir)
1,013✔
765
{
766
   const size_t count = state->regs[ir->result].integer;
1,013✔
767
   void *dest = interp_get_pointer(state, ir->arg1);
1,013✔
768

769
   memset(dest, '\0', count);
1,013✔
770
}
1,013✔
771

772
static void interp_memset(jit_interp_t *state, jit_ir_t *ir)
100,840✔
773
{
774
   const size_t bytes = state->regs[ir->result].integer;
100,840✔
775
   void *dest = interp_get_pointer(state, ir->arg1);
100,840✔
776
   const uint64_t value = interp_get_int(state, ir->arg2);
100,840✔
777

778
   JIT_ASSERT(dest != NULL);
100,840✔
779

780
#define MEMSET_LOOP(type) do {                      \
781
      JIT_ASSERT(bytes % sizeof(type) == 0);        \
782
      type *eptr = dest + bytes;                    \
783
      for (type *p = dest; p < eptr; p++)           \
784
         *p = value;                                \
785
   } while (0)
786

787
   FOR_EACH_SIZE(ir->size, MEMSET_LOOP);
121,664,874✔
788
}
100,840✔
789

790
static void interp_galloc(jit_interp_t *state, jit_ir_t *ir)
216,541✔
791
{
792
   jit_thread_local_t *thread = jit_thread_local();
216,541✔
793
   thread->anchor = state->anchor;
216,541✔
794

795
   state->anchor->irpos = ir - state->func->irbuf;
216,541✔
796

797
   uint64_t bytes = interp_get_int(state, ir->arg1);
216,541✔
798

799
   if (bytes > UINT32_MAX)
216,541✔
800
      jit_msg(NULL, DIAG_FATAL, "attempting to allocate %"PRIu64" byte object "
1✔
801
              "which is larger than the maximum supported %u bytes",
802
              bytes, UINT32_MAX);
803
   else if (bytes == 0)
216,540✔
804
      bytes = 1;   // Never return a NULL pointer
805

806
   state->regs[ir->result].pointer = mspace_alloc(state->mspace, bytes);
216,540✔
807

808
   thread->anchor = NULL;
216,538✔
809
}
216,538✔
810

811
static void interp_lalloc(jit_interp_t *state, jit_ir_t *ir)
164,335✔
812
{
813
   jit_thread_local_t *thread = jit_thread_local();
164,335✔
814
   thread->anchor = state->anchor;
164,335✔
815

816
   state->anchor->irpos = ir - state->func->irbuf;
164,335✔
817

818
   const size_t bytes = interp_get_int(state, ir->arg1);
164,335✔
819
   state->regs[ir->result].pointer = tlab_alloc(state->tlab, bytes);
164,335✔
820

821
   thread->anchor = NULL;
164,335✔
822
}
164,335✔
823

824
static void interp_salloc(jit_interp_t *state, jit_ir_t *ir)
7,531✔
825
{
826
   assert(ir->arg1.int64 + ir->arg2.int64 <= state->func->framesz);
7,531✔
827
   state->regs[ir->result].pointer = state->frame + ir->arg1.int64;
7,531✔
828
}
7,531✔
829

830
static void interp_exit(jit_interp_t *state, jit_ir_t *ir)
1,438,002✔
831
{
832
   state->anchor->irpos = ir - state->func->irbuf;
1,438,002✔
833
   __nvc_do_exit(ir->arg1.exit, state->anchor, state->args, state->tlab);
1,438,002✔
834
}
1,437,116✔
835

836
static void interp_getpriv(jit_interp_t *state, jit_ir_t *ir)
1,315,208✔
837
{
838
   JIT_ASSERT(ir->arg1.kind == JIT_VALUE_HANDLE);
1,315,208✔
839
   jit_func_t *f = jit_get_func(state->func->jit, ir->arg1.handle);
1,315,208✔
840
   void *ptr = load_acquire(jit_get_privdata_ptr(state->func->jit, f));
1,315,208✔
841
   state->regs[ir->result].pointer = ptr;
1,315,208✔
842
}
1,315,208✔
843

844
static void interp_putpriv(jit_interp_t *state, jit_ir_t *ir)
11,339✔
845
{
846
   JIT_ASSERT(ir->arg1.kind == JIT_VALUE_HANDLE);
11,339✔
847
   jit_func_t *f = jit_get_func(state->func->jit, ir->arg1.handle);
11,339✔
848
   void *ptr = interp_get_pointer(state, ir->arg2);
11,339✔
849
   store_release(jit_get_privdata_ptr(state->func->jit, f), ptr);
11,339✔
850
}
11,339✔
851

852
static void interp_case(jit_interp_t *state, jit_ir_t *ir)
77,115✔
853
{
854
   jit_scalar_t test = state->regs[ir->result];
77,115✔
855
   const int64_t cmp = interp_get_int(state, ir->arg1);
77,115✔
856

857
   if (test.integer == cmp)
77,115✔
858
      interp_branch_to(state, ir->arg2);
35,744✔
859
}
77,115✔
860

861
static void interp_trim(jit_interp_t *state, jit_ir_t *ir)
7,523✔
862
{
863
   assert(state->tlab->alloc >= state->anchor->watermark);
7,523✔
864
   state->tlab->alloc = state->anchor->watermark;
7,523✔
865
}
7,523✔
866

867
static void interp_reexec(jit_interp_t *state, jit_ir_t *ir)
125✔
868
{
869
   jit_entry_fn_t entry = load_acquire(&state->func->entry);
125✔
870
   (*entry)(state->func, state->anchor->caller, state->args, state->tlab);
125✔
871
}
125✔
872

873
static void interp_sadd(jit_interp_t *state, jit_ir_t *ir)
715✔
874
{
875
   const void *ptr = interp_get_pointer(state, ir->arg1);
715✔
876
   const int64_t addend = interp_get_int(state, ir->arg2);
715✔
877

878
#define SADD(type) do {                                         \
879
      u##type cur = *(u##type *)ptr;                            \
880
      *(u##type *)ptr = saturate_add(cur, addend);              \
881
   } while (0)
882

883
   FOR_EACH_SIZE(ir->size, SADD);
715✔
884
}
715✔
885

886
static void interp_loop(jit_interp_t *state)
487,257✔
887
{
888
   for (;;) {
357,082,953✔
889
      JIT_ASSERT(state->pc < state->func->nirs);
357,082,953✔
890
      jit_ir_t *ir = &(state->func->irbuf[state->pc++]);
357,082,953✔
891
      switch (ir->op) {
357,082,953✔
892
      case J_RECV:
3,878,096✔
893
         interp_recv(state, ir);
3,878,096✔
894
         break;
3,878,096✔
895
      case J_SEND:
16,184,455✔
896
         interp_send(state, ir);
16,184,455✔
897
         break;
16,184,455✔
898
      case J_AND:
5,238✔
899
         interp_and(state, ir);
5,238✔
900
         break;
5,238✔
901
      case J_OR:
1,106✔
902
         interp_or(state, ir);
1,106✔
903
         break;
1,106✔
904
      case J_XOR:
3,295,135✔
905
         interp_xor(state, ir);
3,295,135✔
906
         break;
3,295,135✔
907
      case J_SUB:
14,512,818✔
908
         interp_sub(state, ir);
14,512,818✔
909
         break;
14,512,818✔
910
      case J_FSUB:
2,263✔
911
         interp_fsub(state, ir);
2,263✔
912
         break;
2,263✔
913
      case J_ADD:
36,327,162✔
914
         interp_add(state, ir);
36,327,162✔
915
         break;
36,327,162✔
916
      case J_FADD:
1,120✔
917
         interp_fadd(state, ir);
1,120✔
918
         break;
1,120✔
919
      case J_MUL:
2,477,910✔
920
         interp_mul(state, ir);
2,477,910✔
921
         break;
2,477,910✔
922
      case J_FMUL:
1,994✔
923
         interp_fmul(state, ir);
1,994✔
924
         break;
1,994✔
925
      case J_DIV:
62,291✔
926
         interp_div(state, ir);
62,291✔
927
         break;
62,291✔
928
      case J_FDIV:
2,232✔
929
         interp_fdiv(state, ir);
2,232✔
930
         break;
2,232✔
931
      case J_SHL:
4,715,331✔
932
         interp_shl(state, ir);
4,715,331✔
933
         break;
4,715,331✔
934
      case J_ASR:
3,058,501✔
935
         interp_asr(state, ir);
3,058,501✔
936
         break;
3,058,501✔
937
      case J_RET:
938
         return;
939
      case J_STORE:
7,175,848✔
940
         interp_store(state, ir);
7,175,848✔
941
         break;
7,175,848✔
942
      case J_ULOAD:
5,658,566✔
943
         interp_uload(state, ir);
5,658,566✔
944
         break;
5,658,566✔
945
      case J_LOAD:
22,715,411✔
946
         interp_load(state, ir);
22,715,411✔
947
         break;
22,715,411✔
948
      case J_CMP:
30,242,158✔
949
         interp_cmp(state, ir);
30,242,158✔
950
         break;
30,242,158✔
951
      case J_CCMP:
4,859,506✔
952
         interp_ccmp(state, ir);
4,859,506✔
953
         break;
4,859,506✔
954
      case J_FCMP:
38,223✔
955
         interp_fcmp(state, ir);
38,223✔
956
         break;
38,223✔
957
      case J_FCCMP:
1,416✔
958
         interp_fccmp(state, ir);
1,416✔
959
         break;
1,416✔
960
      case J_CSET:
5,092,944✔
961
         interp_cset(state, ir);
5,092,944✔
962
         break;
5,092,944✔
963
      case J_JUMP:
23,552,094✔
964
         interp_jump(state, ir);
23,552,094✔
965
         break;
23,552,094✔
UNCOV
966
      case J_TRAP:
×
967
         interp_trap(state, ir);
×
968
         break;
969
      case J_CALL:
2,286,463✔
970
         interp_call(state, ir);
2,286,463✔
971
         break;
2,286,463✔
972
      case J_MOV:
12,387,581✔
973
         interp_mov(state, ir);
12,387,581✔
974
         break;
12,387,581✔
975
      case J_CSEL:
19,722,876✔
976
         interp_csel(state, ir);
19,722,876✔
977
         break;
19,722,876✔
978
      case J_NEG:
251,502✔
979
         interp_neg(state, ir);
251,502✔
980
         break;
251,502✔
981
      case J_FNEG:
12,336✔
982
         interp_fneg(state, ir);
12,336✔
983
         break;
12,336✔
984
      case J_NOT:
95,319✔
985
         interp_not(state, ir);
95,319✔
986
         break;
95,319✔
987
      case J_SCVTF:
4,225✔
988
         interp_scvtf(state, ir);
4,225✔
989
         break;
4,225✔
990
      case J_FCVTNS:
3,046✔
991
         interp_fcvtns(state, ir);
3,046✔
992
         break;
3,046✔
993
      case J_LEA:
1,783,967✔
994
         interp_lea(state, ir);
1,783,967✔
995
         break;
1,783,967✔
996
      case J_REM:
66,226✔
997
         interp_rem(state, ir);
66,226✔
998
         break;
66,226✔
999
      case J_CLAMP:
244,841✔
1000
         interp_clamp(state, ir);
244,841✔
1001
         break;
244,841✔
1002
      case J_DEBUG:
1003
      case J_NOP:
1004
         break;
1005
      case MACRO_COPY:
166,170✔
1006
         interp_copy(state, ir);
166,170✔
1007
         break;
166,170✔
1008
      case MACRO_MOVE:
474,637✔
1009
         interp_move(state, ir);
474,637✔
1010
         break;
474,637✔
1011
      case MACRO_BZERO:
1,013✔
1012
         interp_bzero(state, ir);
1,013✔
1013
         break;
1,013✔
1014
      case MACRO_MEMSET:
100,840✔
1015
         interp_memset(state, ir);
100,840✔
1016
         break;
100,840✔
1017
      case MACRO_GALLOC:
216,541✔
1018
         interp_galloc(state, ir);
216,541✔
1019
         break;
216,541✔
1020
      case MACRO_LALLOC:
164,335✔
1021
         interp_lalloc(state, ir);
164,335✔
1022
         break;
164,335✔
1023
      case MACRO_SALLOC:
7,531✔
1024
         interp_salloc(state, ir);
7,531✔
1025
         break;
7,531✔
1026
      case MACRO_EXIT:
1,438,002✔
1027
         interp_exit(state, ir);
1,438,002✔
1028
         break;
1,438,002✔
1029
      case MACRO_FEXP:
1,165✔
1030
         interp_fexp(state, ir);
1,165✔
1031
         break;
1,165✔
1032
      case MACRO_EXP:
110✔
1033
         interp_exp(state, ir);
110✔
1034
         break;
110✔
1035
      case MACRO_GETPRIV:
1,315,208✔
1036
         interp_getpriv(state, ir);
1,315,208✔
1037
         break;
1,315,208✔
1038
      case MACRO_PUTPRIV:
11,339✔
1039
         interp_putpriv(state, ir);
11,339✔
1040
         break;
11,339✔
1041
      case MACRO_CASE:
77,115✔
1042
         interp_case(state, ir);
77,115✔
1043
         break;
77,115✔
1044
      case MACRO_TRIM:
7,523✔
1045
         interp_trim(state, ir);
7,523✔
1046
         break;
7,523✔
1047
      case MACRO_REEXEC:
125✔
1048
         interp_reexec(state, ir);
125✔
1049
         return;
125✔
1050
      case MACRO_SADD:
715✔
1051
         interp_sadd(state, ir);
715✔
1052
         break;
715✔
UNCOV
1053
      default:
×
1054
         interp_dump(state);
×
1055
         fatal_trace("cannot interpret opcode %s", jit_op_name(ir->op));
1056
      }
1057
   }
1058
}
1059

1060
void jit_interp(jit_func_t *f, jit_anchor_t *caller, jit_scalar_t *args,
487,261✔
1061
                tlab_t *tlab)
1062
{
487,261✔
1063
   jit_entry_fn_t entry = load_acquire(&f->entry);
487,261✔
1064
   if (unlikely(entry != jit_interp)) {
487,261✔
1065
      // Raced with a code generation thread installing a compiled
1066
      // version of this function
UNCOV
1067
      return (*entry)(f, caller, args, tlab);
×
1068
   }
1069

1070
   jit_fill_irbuf(f);
487,261✔
1071

1072
   if (f->next_tier && --(f->hotness) <= 0)
487,257✔
1073
      jit_tier_up(f);
7,902✔
1074

1075
   jit_anchor_t anchor = {
487,257✔
1076
      .caller    = caller,
1077
      .func      = f,
1078
      .watermark = tlab->alloc,
487,257✔
1079
   };
1080

1081
   // Using VLAs here as we need these allocated on the stack so the
1082
   // mspace GC can scan them
1083
   jit_scalar_t regs[f->nregs + 1];
487,257✔
1084
   unsigned char frame[f->framesz + 1];
487,257✔
1085

1086
#ifdef DEBUG
1087
   memset(regs, 0xde, sizeof(jit_scalar_t) * f->nregs);
487,257✔
1088
   memset(frame, 0xde, f->framesz);
487,257✔
1089
#endif
1090

1091
   jit_interp_t state = {
487,257✔
1092
      .args     = args,
1093
      .regs     = regs,
1094
      .nargs    = 0,
1095
      .pc       = 0,
1096
      .func     = f,
1097
      .frame    = frame,
1098
      .mspace   = jit_get_mspace(f->jit),
487,257✔
1099
      .anchor   = &anchor,
1100
      .tlab     = tlab,
1101
   };
1102

1103
   interp_loop(&state);
487,257✔
1104
}
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