Coverage Report

Created: 2026-08-26 07:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mruby/src/codedump.c
Line
Count
Source
1
#include <mruby.h>
2
#include <mruby/irep.h>
3
#include <mruby/debug.h>
4
#include <mruby/opcode.h>
5
#include <mruby/string.h>
6
#include <mruby/proc.h>
7
#include <mruby/dump.h>
8
#include <mruby/internal.h>
9
10
#ifndef MRB_NO_STDIO
11
static mrb_bool
12
print_r_p(mrb_state *mrb, const mrb_irep *irep, size_t n)
13
0
{
14
0
  if (n == 0) return FALSE;
15
0
  if (!irep->lv) return FALSE;
16
0
  if (n >= irep->nlocals) return FALSE;
17
0
  if (!irep->lv[n-1]) return FALSE;
18
0
  return TRUE;
19
0
}
20
21
static void
22
print_r(mrb_state *mrb, const mrb_irep *irep, size_t n, FILE *out)
23
0
{
24
0
  if (n == 0) return;
25
0
  if (n >= irep->nlocals) return;
26
0
  if (!irep->lv[n-1]) return;
27
0
  fprintf(out, " R%d:%s", (int)n, mrb_sym_dump(mrb, irep->lv[n-1]));
28
0
}
29
30
static void
31
print_lv_a(mrb_state *mrb, const mrb_irep *irep, uint16_t a, FILE *out)
32
0
{
33
0
  if (print_r_p(mrb, irep, a)) {
34
0
    fprintf(out, "\t;");
35
0
    print_r(mrb, irep, a, out);
36
0
  }
37
0
  fprintf(out, "\n");
38
0
}
39
40
static void
41
print_lv_ab(mrb_state *mrb, const mrb_irep *irep, uint16_t a, uint16_t b, FILE *out)
42
0
{
43
0
  if (print_r_p(mrb, irep, a) || print_r_p(mrb, irep, b)) {
44
0
    fprintf(out, "\t;");
45
0
    print_r(mrb, irep, a, out);
46
0
    print_r(mrb, irep, b, out);
47
0
  }
48
0
  fprintf(out, "\n");
49
0
}
50
51
static void
52
print_header(mrb_state *mrb, const mrb_irep *irep, ptrdiff_t i, FILE *out)
53
0
{
54
0
  int32_t line;
55
56
0
  mrb_assert(i <= UINT32_MAX);
57
0
  line = mrb_debug_get_line(mrb, irep, (uint32_t)i);
58
0
  if (line < 0) {
59
0
    fprintf(out, "      ");
60
0
  }
61
0
  else {
62
0
    fprintf(out, "%5d ", line);
63
0
  }
64
65
0
  fprintf(out, "%03d ", (int)i);
66
0
}
67
68
static void
69
print_args(uint16_t i, FILE *out)
70
0
{
71
0
  mrb_assert(i <= 255);
72
0
  uint8_t n = i&0xf;
73
0
  uint8_t nk = (i>>4)&0xf;
74
75
0
  if (n == 15) {
76
0
    fprintf(out, "n=*");
77
0
  }
78
0
  else {
79
0
    fprintf(out, "n=%d", n);
80
0
  }
81
0
  if (nk > 0) {
82
0
    fprintf(out, "|");
83
0
    if (nk == 15) {
84
0
      fprintf(out, "nk=*");
85
0
    }
86
0
    else {
87
0
      fprintf(out, "nk=%d", nk);
88
0
    }
89
0
  }
90
0
  fprintf(out, "\n");
91
0
}
92
93
0
#define CASE(insn,ops) case insn: FETCH_ ## ops (); L_ ## insn
94
95
static void
96
codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out)
97
0
{
98
0
  const char *file = NULL;
99
100
0
  if (!irep) return;
101
0
  fprintf(out, "irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d ilen=%d\n", (void*)irep,
102
0
          irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen, (int)irep->rlen, (int)irep->ilen);
103
104
0
  if (irep->lv) {
105
0
    int head = FALSE;
106
107
0
    for (int i = 1; i < irep->nlocals; i++) {
108
0
      char const *s = mrb_sym_dump(mrb, irep->lv[i - 1]);
109
0
      if (s) {
110
0
        if (!head) {
111
0
          head = TRUE;
112
0
          fprintf(out, "local variable names:\n");
113
0
        }
114
0
        fprintf(out, "  R%d:%s\n", i, s);
115
0
      }
116
0
    }
117
0
  }
118
119
0
  if (irep->clen > 0) {
120
0
    const struct mrb_irep_catch_handler *e = mrb_irep_catch_handler_table(irep);
121
122
0
    for (int i = irep->clen; i > 0; i--,e++) {
123
0
      uint32_t begin = mrb_irep_catch_handler_unpack(e->begin);
124
0
      uint32_t end = mrb_irep_catch_handler_unpack(e->end);
125
0
      uint32_t target = mrb_irep_catch_handler_unpack(e->target);
126
0
      char buf[20];
127
0
      const char *type;
128
129
0
      switch (e->type) {
130
0
        case MRB_CATCH_RESCUE:
131
0
          type = "rescue";
132
0
          break;
133
0
        case MRB_CATCH_ENSURE:
134
0
          type = "ensure";
135
0
          break;
136
0
        default:
137
0
          buf[0] = '\0';
138
0
          snprintf(buf, sizeof(buf), "0x%02x <unknown>", (int)e->type);
139
0
          type = buf;
140
0
          break;
141
0
      }
142
0
      fprintf(out, "catch type: %-8s begin: %04" PRIu32 " end: %04" PRIu32 " target: %04" PRIu32 "\n", type, begin, end, target);
143
0
    }
144
0
  }
145
146
0
  const mrb_code *pc = irep->iseq;
147
0
  const mrb_code *pcend = pc + irep->ilen;
148
0
  while (pc < pcend) {
149
0
    uint32_t a;
150
0
    uint16_t b;
151
0
    uint16_t c;
152
0
    mrb_code ins;
153
154
0
    int ai = mrb_gc_arena_save(mrb);
155
0
    ptrdiff_t i = pc - irep->iseq;
156
157
0
    const char *next_file = mrb_debug_get_filename(mrb, irep, (uint32_t)i);
158
0
    if (next_file && file != next_file) {
159
0
      fprintf(out, "file: %s\n", next_file);
160
0
      file = next_file;
161
0
    }
162
0
    print_header(mrb, irep, i, out);
163
0
    ins = READ_B();
164
0
    switch (ins) {
165
0
    CASE(OP_NOP, Z):
166
0
      fprintf(out, "NOP\n");
167
0
      break;
168
0
    CASE(OP_MOVE, BB):
169
0
      fprintf(out, "MOVE\t\tR%d\tR%d", a, b);
170
0
      print_lv_ab(mrb, irep, a, b, out);
171
0
      break;
172
173
0
    CASE(OP_LOADL, BB):
174
0
      switch (irep->pool[b].tt) {
175
0
#ifndef MRB_NO_FLOAT
176
0
      case IREP_TT_FLOAT:
177
0
        fprintf(out, "LOADL\t\tR%d\tL[%d]\t; %f", a, b, (double)irep->pool[b].u.f);
178
0
        break;
179
0
#endif
180
0
      case IREP_TT_INT32:
181
0
        fprintf(out, "LOADL\t\tR%d\tL[%d]\t; %" PRId32, a, b, irep->pool[b].u.i32);
182
0
        break;
183
0
#ifdef MRB_64BIT
184
0
      case IREP_TT_INT64:
185
0
        fprintf(out, "LOADL\t\tR%d\tL[%d]\t; %" PRId64, a, b, irep->pool[b].u.i64);
186
0
        break;
187
0
#endif
188
0
      default:
189
0
        fprintf(out, "LOADL\t\tR%d\tL[%d]", a, b);
190
0
        break;
191
0
      }
192
0
      print_lv_a(mrb, irep, a, out);
193
0
      break;
194
0
    CASE(OP_LOADI8, BB):
195
0
      fprintf(out, "LOADI8\tR%d\t%d", a, b);
196
0
      print_lv_a(mrb, irep, a, out);
197
0
      break;
198
0
    CASE(OP_LOADINEG, BB):
199
0
      fprintf(out, "LOADINEG\tR%d\t-%d", a, b);
200
0
      print_lv_a(mrb, irep, a, out);
201
0
      break;
202
0
    CASE(OP_LOADI16, BS):
203
0
      fprintf(out, "LOADI16\tR%d\t%d", a, (int)(int16_t)b);
204
0
      print_lv_a(mrb, irep, a, out);
205
0
      break;
206
0
    CASE(OP_LOADI32, BSS):
207
0
      fprintf(out, "LOADI32\tR%d\t%d", a, (int32_t)(((uint32_t)b<<16)+c));
208
0
      print_lv_a(mrb, irep, a, out);
209
0
      break;
210
0
    CASE(OP_LOADI__1, B):
211
0
      fprintf(out, "LOADI__1\tR%d\t(-1)", a);
212
0
      print_lv_a(mrb, irep, a, out);
213
0
      break;
214
0
    CASE(OP_LOADI_0, B): goto L_LOADI;
215
0
    CASE(OP_LOADI_1, B): goto L_LOADI;
216
0
    CASE(OP_LOADI_2, B): goto L_LOADI;
217
0
    CASE(OP_LOADI_3, B): goto L_LOADI;
218
0
    CASE(OP_LOADI_4, B): goto L_LOADI;
219
0
    CASE(OP_LOADI_5, B): goto L_LOADI;
220
0
    CASE(OP_LOADI_6, B): goto L_LOADI;
221
0
    CASE(OP_LOADI_7, B):
222
0
    L_LOADI:
223
0
      b = ins-(int)OP_LOADI_0;
224
0
      fprintf(out, "LOADI_%d\tR%d\t(%d)", b, a, b);
225
0
      print_lv_a(mrb, irep, a, out);
226
0
      break;
227
0
    CASE(OP_LOADSYM, BB):
228
0
      fprintf(out, "LOADSYM\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
229
0
      print_lv_a(mrb, irep, a, out);
230
0
      break;
231
0
    CASE(OP_LOADNIL, B):
232
0
      fprintf(out, "LOADNIL\tR%d\t(nil)", a);
233
0
      print_lv_a(mrb, irep, a, out);
234
0
      break;
235
0
    CASE(OP_LOADSELF, B):
236
0
      fprintf(out, "LOADSELF\tR%d\t(R0)", a);
237
0
      print_lv_a(mrb, irep, a, out);
238
0
      break;
239
0
    CASE(OP_LOADTRUE, B):
240
0
      fprintf(out, "LOADTRUE\tR%d\t(true)", a);
241
0
      print_lv_a(mrb, irep, a, out);
242
0
      break;
243
0
    CASE(OP_LOADFALSE, B):
244
0
      fprintf(out, "LOADFALSE\tR%d\t(false)", a);
245
0
      print_lv_a(mrb, irep, a, out);
246
0
      break;
247
0
    CASE(OP_GETGV, BB):
248
0
      fprintf(out, "GETGV\t\tR%d\t%s", a, mrb_sym_dump(mrb, irep->syms[b]));
249
0
      print_lv_a(mrb, irep, a, out);
250
0
      break;
251
0
    CASE(OP_SETGV, BB):
252
0
      fprintf(out, "SETGV\t\t%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a);
253
0
      print_lv_a(mrb, irep, a, out);
254
0
      break;
255
0
    CASE(OP_GETSV, BB):
256
0
      fprintf(out, "GETSV\t\tR%d\t%s", a, mrb_sym_dump(mrb, irep->syms[b]));
257
0
      print_lv_a(mrb, irep, a, out);
258
0
      break;
259
0
    CASE(OP_SETSV, BB):
260
0
      fprintf(out, "SETSV\t\t%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a);
261
0
      print_lv_a(mrb, irep, a, out);
262
0
      break;
263
0
    CASE(OP_GETCONST, BB):
264
0
      fprintf(out, "GETCONST\tR%d\t%s", a, mrb_sym_dump(mrb, irep->syms[b]));
265
0
      print_lv_a(mrb, irep, a, out);
266
0
      break;
267
0
    CASE(OP_SETCONST, BB):
268
0
      fprintf(out, "SETCONST\t%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a);
269
0
      print_lv_a(mrb, irep, a, out);
270
0
      break;
271
0
    CASE(OP_GETMCNST, BB):
272
0
      fprintf(out, "GETMCNST\tR%d\t(R%d)::%s", a, a, mrb_sym_dump(mrb, irep->syms[b]));
273
0
      print_lv_a(mrb, irep, a, out);
274
0
      break;
275
0
    CASE(OP_SETMCNST, BB):
276
0
      fprintf(out, "SETMCNST\t(R%d)::%s\tR%d", a+1, mrb_sym_dump(mrb, irep->syms[b]), a);
277
0
      print_lv_a(mrb, irep, a, out);
278
0
      break;
279
0
    CASE(OP_GETIV, BB):
280
0
      fprintf(out, "GETIV\t\tR%d\t%s", a, mrb_sym_dump(mrb, irep->syms[b]));
281
0
      print_lv_a(mrb, irep, a, out);
282
0
      break;
283
0
    CASE(OP_SETIV, BB):
284
0
      fprintf(out, "SETIV\t\t%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a);
285
0
      print_lv_a(mrb, irep, a, out);
286
0
      break;
287
0
    CASE(OP_GETUPVAR, BBB):
288
0
      fprintf(out, "GETUPVAR\tR%d\t%d\t%d", a, b, c);
289
0
      print_lv_a(mrb, irep, a, out);
290
0
      break;
291
0
    CASE(OP_SETUPVAR, BBB):
292
0
      fprintf(out, "SETUPVAR\tR%d\t%d\t%d", a, b, c);
293
0
      print_lv_a(mrb, irep, a, out);
294
0
      break;
295
0
    CASE(OP_GETCV, BB):
296
0
      fprintf(out, "GETCV\t\tR%d\t%s", a, mrb_sym_dump(mrb, irep->syms[b]));
297
0
      print_lv_a(mrb, irep, a, out);
298
0
      break;
299
0
    CASE(OP_SETCV, BB):
300
0
      fprintf(out, "SETCV\t\t%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a);
301
0
      print_lv_a(mrb, irep, a, out);
302
0
      break;
303
0
    CASE(OP_GETIDX, B):
304
0
      fprintf(out, "GETIDX\tR%d\t(R%d)\n", a, a+1);
305
0
      break;
306
0
    CASE(OP_GETIDX0, BB):
307
0
      fprintf(out, "GETIDX0\tR%d\tR%d[0]\n", a, b);
308
0
      break;
309
0
    CASE(OP_SETIDX, B):
310
0
      fprintf(out, "SETIDX\tR%d\t(R%d)\t(R%d)\n", a, a+1, a+2);
311
0
      break;
312
0
    CASE(OP_JMP, S):
313
0
      i = pc - irep->iseq;
314
0
      fprintf(out, "JMP\t\t%03d\n", (int)i+(int16_t)a);
315
0
      break;
316
0
    CASE(OP_JMPUW, S):
317
0
      i = pc - irep->iseq;
318
0
      fprintf(out, "JMPUW\t\t%03d\n", (int)i+(int16_t)a);
319
0
      break;
320
0
    CASE(OP_JMPIF, BS):
321
0
      i = pc - irep->iseq;
322
0
      fprintf(out, "JMPIF\t\tR%d\t%03d", a, (int)i+(int16_t)b);
323
0
      print_lv_a(mrb, irep, a, out);
324
0
      break;
325
0
    CASE(OP_JMPNOT, BS):
326
0
      i = pc - irep->iseq;
327
0
      fprintf(out, "JMPNOT\tR%d\t%03d", a, (int)i+(int16_t)b);
328
0
      print_lv_a(mrb, irep, a, out);
329
0
      break;
330
0
    CASE(OP_JMPNIL, BS):
331
0
      i = pc - irep->iseq;
332
0
      fprintf(out, "JMPNIL\tR%d\t%03d", a, (int)i+(int16_t)b);
333
0
      print_lv_a(mrb, irep, a, out);
334
0
      break;
335
0
    CASE(OP_SSEND, BBB):
336
0
      fprintf(out, "SSEND\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
337
0
      print_args(c, out);
338
0
      break;
339
0
    CASE(OP_SSEND0, BB):
340
0
      fprintf(out, "SSEND0\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b]));
341
0
      break;
342
0
    CASE(OP_SSENDB, BBB):
343
0
      fprintf(out, "SSENDB\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
344
0
      print_args(c, out);
345
0
      break;
346
0
    CASE(OP_SEND, BBB):
347
0
      fprintf(out, "SEND\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
348
0
      print_args(c, out);
349
0
      break;
350
0
    CASE(OP_SEND0, BB):
351
0
      fprintf(out, "SEND0\t\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b]));
352
0
      break;
353
0
    CASE(OP_SENDB, BBB):
354
0
      fprintf(out, "SENDB\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
355
0
      print_args(c, out);
356
0
      break;
357
0
    CASE(OP_CALL, Z):
358
0
      fprintf(out, "CALL\n");
359
0
      break;
360
0
    CASE(OP_BLKCALL, BB):
361
0
      fprintf(out, "BLKCALL\t\tR%d\t%d\n", a, b);
362
0
      break;
363
0
    CASE(OP_SUPER, BB):
364
0
      fprintf(out, "SUPER\t\tR%d\t", a);
365
0
      print_args(b, out);
366
0
      break;
367
0
    CASE(OP_ARGARY, BS):
368
0
      fprintf(out, "ARGARY\tR%d\t%d:%d:%d:%d (%d)", a,
369
0
             (b>>11)&0x3f,
370
0
             (b>>10)&0x1,
371
0
             (b>>5)&0x1f,
372
0
             (b>>4)&0x1,
373
0
             (b>>0)&0xf);
374
0
      print_lv_a(mrb, irep, a, out);
375
0
      break;
376
0
    CASE(OP_ENTER, W):
377
0
      fprintf(out, "ENTER\t\t%d:%d:%d:%d:%d:%d:%d:%d (0x%x)\n",
378
0
              MRB_ASPEC_REQ(a),
379
0
              MRB_ASPEC_OPT(a),
380
0
              MRB_ASPEC_REST(a),
381
0
              MRB_ASPEC_POST(a),
382
0
              MRB_ASPEC_KEY(a),
383
0
              MRB_ASPEC_KDICT(a),
384
0
              MRB_ASPEC_BLOCK(a),
385
0
              MRB_ASPEC_NOBLOCK(a), a);
386
0
      break;
387
0
    CASE(OP_KEY_P, BB):
388
0
      fprintf(out, "KEY_P\t\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
389
0
      print_lv_a(mrb, irep, a, out);
390
0
      break;
391
0
    CASE(OP_KEYEND, Z):
392
0
      fprintf(out, "KEYEND\n");
393
0
      break;
394
0
    CASE(OP_KARG, BB):
395
0
      fprintf(out, "KARG\t\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
396
0
      print_lv_a(mrb, irep, a, out);
397
0
      break;
398
0
    CASE(OP_RETURN, B):
399
0
      fprintf(out, "RETURN\tR%d\t", a);
400
0
      print_lv_a(mrb, irep, a, out);
401
0
      break;
402
0
    CASE(OP_RETURN_BLK, B):
403
0
      fprintf(out, "RETURN_BLK\tR%d\t", a);
404
0
      print_lv_a(mrb, irep, a, out);
405
0
      break;
406
0
    CASE(OP_RETSELF, Z):
407
0
      fprintf(out, "RETSELF\n");
408
0
      break;
409
0
    CASE(OP_RETNIL, Z):
410
0
      fprintf(out, "RETNIL\n");
411
0
      break;
412
0
    CASE(OP_RETTRUE, Z):
413
0
      fprintf(out, "RETTRUE\n");
414
0
      break;
415
0
    CASE(OP_RETFALSE, Z):
416
0
      fprintf(out, "RETFALSE\n");
417
0
      break;
418
0
    CASE(OP_BREAK, B):
419
0
      fprintf(out, "BREAK\t\tR%d\t", a);
420
0
      print_lv_a(mrb, irep, a, out);
421
0
      break;
422
0
    CASE(OP_BLKPUSH, BS):
423
0
      fprintf(out, "BLKPUSH\tR%d\t%d:%d:%d:%d (%d)", a,
424
0
             (b>>11)&0x3f,
425
0
             (b>>10)&0x1,
426
0
             (b>>5)&0x1f,
427
0
             (b>>4)&0x1,
428
0
             (b>>0)&0xf);
429
0
      print_lv_a(mrb, irep, a, out);
430
0
      break;
431
0
    CASE(OP_LAMBDA, BB):
432
0
      fprintf(out, "LAMBDA\tR%d\tI[%d]\n", a, b);
433
0
      break;
434
0
    CASE(OP_BLOCK, BB):
435
0
      fprintf(out, "BLOCK\t\tR%d\tI[%d]\n", a, b);
436
0
      break;
437
0
    CASE(OP_METHOD, BB):
438
0
      fprintf(out, "METHOD\tR%d\tI[%d]\n", a, b);
439
0
      break;
440
0
    CASE(OP_RANGE_INC, B):
441
0
      fprintf(out, "RANGE_INC\tR%d\n", a);
442
0
      break;
443
0
    CASE(OP_RANGE_EXC, B):
444
0
      fprintf(out, "RANGE_EXC\tR%d\n", a);
445
0
      break;
446
0
    CASE(OP_DEF, BB):
447
0
      fprintf(out, "DEF\t\tR%d\t:%s\t(R%d)\n", a, mrb_sym_dump(mrb, irep->syms[b]),a+1);
448
0
      break;
449
0
    CASE(OP_TDEF, BBB):
450
0
      fprintf(out, "TDEF\t\tR%d\t:%s\tI[%d]\n", a, mrb_sym_dump(mrb, irep->syms[b]), c);
451
0
      break;
452
0
    CASE(OP_SDEF, BBB):
453
0
      fprintf(out, "SDEF\t\tR%d\t:%s\tI[%d]\n", a, mrb_sym_dump(mrb, irep->syms[b]), c);
454
0
      break;
455
0
    CASE(OP_UNDEF, B):
456
0
      fprintf(out, "UNDEF\t\t:%s\n", mrb_sym_dump(mrb, irep->syms[a]));
457
0
      break;
458
0
    CASE(OP_ALIAS, BB):
459
0
      fprintf(out, "ALIAS\t\t:%s\t%s\n", mrb_sym_dump(mrb, irep->syms[a]), mrb_sym_dump(mrb, irep->syms[b]));
460
0
      break;
461
0
    CASE(OP_ADD, B):
462
0
      fprintf(out, "ADD\t\tR%d\t(R%d)\n", a, a+1);
463
0
      break;
464
0
    CASE(OP_ADDI, BB):
465
0
      fprintf(out, "ADDI\t\tR%d\t%d", a, b);
466
0
      print_lv_a(mrb, irep, a, out);
467
0
      break;
468
0
    CASE(OP_SUB, B):
469
0
      fprintf(out, "SUB\t\tR%d\t(R%d)\n", a, a+1);
470
0
      break;
471
0
    CASE(OP_SUBI, BB):
472
0
      fprintf(out, "SUBI\t\tR%d\t%d", a, b);
473
0
      print_lv_a(mrb, irep, a, out);
474
0
      break;
475
0
    CASE(OP_ADDILV, BBB):
476
0
      fprintf(out, "ADDILV\tR%d\tR%d\t%d", a, b, c);
477
0
      print_lv_a(mrb, irep, a, out);
478
0
      break;
479
0
    CASE(OP_SUBILV, BBB):
480
0
      fprintf(out, "SUBILV\tR%d\tR%d\t%d", a, b, c);
481
0
      print_lv_a(mrb, irep, a, out);
482
0
      break;
483
0
    CASE(OP_MUL, B):
484
0
      fprintf(out, "MUL\t\tR%d\t(R%d)\n", a, a+1);
485
0
      break;
486
0
    CASE(OP_DIV, B):
487
0
      fprintf(out, "DIV\t\tR%d\t(R%d)\n", a, a+1);
488
0
      break;
489
0
    CASE(OP_LT, B):
490
0
      fprintf(out, "LT\t\tR%d\t(R%d)\n", a, a+1);
491
0
      break;
492
0
    CASE(OP_LE, B):
493
0
      fprintf(out, "LE\t\tR%d\t(R%d)\n", a, a+1);
494
0
      break;
495
0
    CASE(OP_GT, B):
496
0
      fprintf(out, "GT\t\tR%d\t(R%d)\n", a, a+1);
497
0
      break;
498
0
    CASE(OP_GE, B):
499
0
      fprintf(out, "GE\t\tR%d\t(R%d)\n", a, a+1);
500
0
      break;
501
0
    CASE(OP_EQ, B):
502
0
      fprintf(out, "EQ\t\tR%d\t(R%d)\n", a, a+1);
503
0
      break;
504
0
    CASE(OP_ARRAY, BB):
505
0
      fprintf(out, "ARRAY\t\tR%d\t%d", a, b);
506
0
      print_lv_a(mrb, irep, a, out);
507
0
      break;
508
0
    CASE(OP_ARRAY2, BBB):
509
0
      fprintf(out, "ARRAY\t\tR%d\tR%d\t%d", a, b, c);
510
0
      print_lv_ab(mrb, irep, a, b, out);
511
0
      break;
512
0
    CASE(OP_ARYCAT, B):
513
0
      fprintf(out, "ARYCAT\tR%d\t(R%d)", a, a+1);
514
0
      print_lv_a(mrb, irep, a, out);
515
0
      break;
516
0
    CASE(OP_ARYPUSH, BB):
517
0
      fprintf(out, "ARYPUSH\tR%d\t%d", a, b);
518
0
      print_lv_a(mrb, irep, a, out);
519
0
      break;
520
0
    CASE(OP_ARYSPLAT, B):
521
0
      fprintf(out, "ARYSPLAT\tR%d", a);
522
0
      print_lv_a(mrb, irep, a, out);
523
0
      break;
524
0
    CASE(OP_AREF, BBB):
525
0
      fprintf(out, "AREF\t\tR%d\tR%d\t%d", a, b, c);
526
0
      print_lv_ab(mrb, irep, a, b, out);
527
0
      break;
528
0
    CASE(OP_ASET, BBB):
529
0
      fprintf(out, "ASET\t\tR%d\tR%d\t%d", a, b, c);
530
0
      print_lv_ab(mrb, irep, a, b, out);
531
0
      break;
532
0
    CASE(OP_APOST, BBB):
533
0
      fprintf(out, "APOST\t\tR%d\t%d\t%d", a, b, c);
534
0
      print_lv_a(mrb, irep, a, out);
535
0
      break;
536
0
    CASE(OP_INTERN, B):
537
0
      fprintf(out, "INTERN\tR%d\t", a);
538
0
      print_lv_a(mrb, irep, a, out);
539
0
      break;
540
0
    CASE(OP_SYMBOL, BB):
541
0
      mrb_assert((irep->pool[b].tt&IREP_TT_NFLAG)==0);
542
0
      fprintf(out, "SYMBOL\tR%d\tL[%d]\t; %s", a, b, irep->pool[b].u.str);
543
0
      print_lv_a(mrb, irep, a, out);
544
0
      break;
545
0
    CASE(OP_STRING, BB):
546
0
      mrb_assert((irep->pool[b].tt&IREP_TT_NFLAG)==0);
547
0
      fprintf(out, "STRING\tR%d\tL[%d]", a, b);
548
0
      if (irep->pool[b].u.str[0]) {
549
0
        fprintf(out, "\t; %s", irep->pool[b].u.str);
550
0
      }
551
0
      print_lv_a(mrb, irep, a, out);
552
0
      break;
553
0
    CASE(OP_STRCAT, B):
554
0
      fprintf(out, "STRCAT\tR%d\t(R%d)", a, a+1);
555
0
      print_lv_a(mrb, irep, a, out);
556
0
      break;
557
0
    CASE(OP_HASH, BB):
558
0
      fprintf(out, "HASH\t\tR%d\t%d", a, b);
559
0
      print_lv_a(mrb, irep, a, out);
560
0
      break;
561
0
    CASE(OP_HASHADD, BB):
562
0
      fprintf(out, "HASHADD\tR%d\t%d", a, b);
563
0
      print_lv_a(mrb, irep, a, out);
564
0
      break;
565
0
    CASE(OP_HASHCAT, B):
566
0
      fprintf(out, "HASHCAT\tR%d\t(R%d)", a, a+1);
567
0
      print_lv_a(mrb, irep, a, out);
568
0
      break;
569
570
0
    CASE(OP_OCLASS, B):
571
0
      fprintf(out, "OCLASS\tR%d\t", a);
572
0
      print_lv_a(mrb, irep, a, out);
573
0
      break;
574
0
    CASE(OP_CLASS, BB):
575
0
      fprintf(out, "CLASS\t\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
576
0
      print_lv_a(mrb, irep, a, out);
577
0
      break;
578
0
    CASE(OP_MODULE, BB):
579
0
      fprintf(out, "MODULE\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b]));
580
0
      print_lv_a(mrb, irep, a, out);
581
0
      break;
582
0
    CASE(OP_EXEC, BB):
583
0
      fprintf(out, "EXEC\t\tR%d\tI[%d]", a, b);
584
0
      print_lv_a(mrb, irep, a, out);
585
0
      break;
586
0
    CASE(OP_SCLASS, B):
587
0
      fprintf(out, "SCLASS\tR%d", a);
588
0
      print_lv_a(mrb, irep, a, out);
589
0
      break;
590
0
    CASE(OP_TCLASS, B):
591
0
      fprintf(out, "TCLASS\tR%d\t", a);
592
0
      print_lv_a(mrb, irep, a, out);
593
0
      break;
594
0
    CASE(OP_ERR, B):
595
0
      if ((irep->pool[a].tt & IREP_TT_NFLAG) == 0) {
596
0
        fprintf(out, "ERR\t\t%s\n", irep->pool[a].u.str);
597
0
      }
598
0
      else {
599
0
        fprintf(out, "ERR\tL[%d]\n", a);
600
0
      }
601
0
      break;
602
0
    CASE(OP_EXCEPT, B):
603
0
      fprintf(out, "EXCEPT\tR%d\t", a);
604
0
      print_lv_a(mrb, irep, a, out);
605
0
      break;
606
0
    CASE(OP_RESCUE, BB):
607
0
      fprintf(out, "RESCUE\tR%d\tR%d", a, b);
608
0
      print_lv_ab(mrb, irep, a, b, out);
609
0
      break;
610
0
    CASE(OP_RAISEIF, B):
611
0
      fprintf(out, "RAISEIF\tR%d\t", a);
612
0
      print_lv_a(mrb, irep, a, out);
613
0
      break;
614
0
    CASE(OP_MATCHERR, B):
615
0
      fprintf(out, "MATCHERR\tR%d\n", a);
616
0
      break;
617
618
0
    CASE(OP_DEBUG, BBB):
619
0
      fprintf(out, "DEBUG\t\t%d\t%d\t%d\n", a, b, c);
620
0
      break;
621
622
0
    CASE(OP_STOP, Z):
623
0
      fprintf(out, "STOP\n");
624
0
      break;
625
626
0
    CASE(OP_EXT1, Z):
627
0
      fprintf(out, "EXT1\n");
628
0
      print_header(mrb, irep, pc-irep->iseq, out);
629
0
      ins = READ_B();
630
0
      switch (ins) {
631
0
#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _1 (); goto L_OP_ ## i;
632
0
#include <mruby/ops.h>
633
0
#undef OPCODE
634
0
      }
635
0
      break;
636
0
    CASE(OP_EXT2, Z):
637
0
      fprintf(out, "EXT2\n");
638
0
      print_header(mrb, irep, pc-irep->iseq, out);
639
0
      ins = READ_B();
640
0
      switch (ins) {
641
0
#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _2 (); goto L_OP_ ## i;
642
0
#include <mruby/ops.h>
643
0
#undef OPCODE
644
0
      }
645
0
      break;
646
0
    CASE(OP_EXT3, Z):
647
0
      fprintf(out, "EXT3\n");
648
0
      print_header(mrb, irep, pc-irep->iseq, out);
649
0
      ins = READ_B();
650
0
      switch (ins) {
651
0
#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _3 (); goto L_OP_ ## i;
652
0
#include <mruby/ops.h>
653
0
#undef OPCODE
654
0
      }
655
0
      break;
656
657
0
    default:
658
0
      fprintf(out, "unknown_op (0x%x)\n", ins);
659
0
      break;
660
0
    }
661
0
    mrb_gc_arena_restore(mrb, ai);
662
0
  }
663
0
  fprintf(out, "\n");
664
0
}
665
666
static void
667
codedump_recur(mrb_state *mrb, const mrb_irep *irep, FILE *out)
668
0
{
669
0
  codedump(mrb, irep, out);
670
0
  if (irep->reps) {
671
0
    for (int i=0; i<irep->rlen; i++) {
672
0
      codedump_recur(mrb, irep->reps[i], out);
673
0
    }
674
0
  }
675
0
}
676
677
void
678
mrb_codedump_all_file(mrb_state *mrb, struct RProc *proc, FILE *out)
679
0
{
680
0
  codedump_recur(mrb, proc->body.irep, out);
681
0
  fflush(out);
682
0
}
683
684
#endif
685
686
void
687
mrb_codedump_all(mrb_state *mrb, struct RProc *proc)
688
0
{
689
0
#ifndef MRB_NO_STDIO
690
  mrb_codedump_all_file(mrb, proc, stdout);
691
0
#endif
692
0
}
693
#undef CASE