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