2 ** codegen.c - mruby code generator
4 ** See Copyright Notice in mruby.h
12 #include <mruby/compile.h>
13 #include <mruby/proc.h>
14 #include <mruby/numeric.h>
15 #include <mruby/string.h>
16 #include <mruby/debug.h>
18 #include <mruby/opcode.h>
20 #include <mruby/throw.h>
22 #ifndef MRB_CODEGEN_LEVEL_MAX
23 #define MRB_CODEGEN_LEVEL_MAX 1024
26 typedef mrb_ast_node node
;
27 typedef struct mrb_parser_state parser_state
;
39 int pc1
, pc2
, pc3
, acc
;
41 struct loopinfo
*prev
;
44 typedef struct scope
{
47 struct mrb_jmpbuf jmp
;
59 struct loopinfo
*loop
;
69 int pcapa
, scapa
, rcapa
;
76 uint16_t filename_index
;
79 int rlev
; /* recursion levels */
82 static codegen_scope
* scope_new(mrb_state
*mrb
, codegen_scope
*prev
, node
*lv
);
83 static void scope_finish(codegen_scope
*s
);
84 static struct loopinfo
*loop_push(codegen_scope
*s
, enum looptype t
);
85 static void loop_break(codegen_scope
*s
, node
*tree
);
86 static void loop_pop(codegen_scope
*s
, int val
);
88 static void gen_assignment(codegen_scope
*s
, node
*tree
, int sp
, int val
);
89 static void gen_vmassignment(codegen_scope
*s
, node
*tree
, int rhs
, int val
);
91 static void codegen(codegen_scope
*s
, node
*tree
, int val
);
92 static void raise_error(codegen_scope
*s
, const char *msg
);
95 codegen_error(codegen_scope
*s
, const char *message
)
99 codegen_scope
*tmp
= s
->prev
;
100 mrb_free(s
->mrb
, s
->iseq
);
101 mrb_pool_close(s
->mpool
);
104 #ifndef MRB_DISABLE_STDIO
105 if (s
->filename
&& s
->lineno
) {
106 fprintf(stderr
, "codegen error:%s:%d: %s\n", s
->filename
, s
->lineno
, message
);
109 fprintf(stderr
, "codegen error: %s\n", message
);
116 codegen_palloc(codegen_scope
*s
, size_t len
)
118 void *p
= mrb_pool_alloc(s
->mpool
, len
);
120 if (!p
) codegen_error(s
, "pool memory allocation");
125 codegen_malloc(codegen_scope
*s
, size_t len
)
127 void *p
= mrb_malloc_simple(s
->mrb
, len
);
129 if (!p
) codegen_error(s
, "mrb_malloc");
134 codegen_realloc(codegen_scope
*s
, void *p
, size_t len
)
136 p
= mrb_realloc_simple(s
->mrb
, p
, len
);
138 if (!p
&& len
> 0) codegen_error(s
, "mrb_realloc");
143 new_label(codegen_scope
*s
)
145 s
->lastlabel
= s
->pc
;
150 genop(codegen_scope
*s
, mrb_code i
)
152 if (s
->pc
== s
->icapa
) {
154 s
->iseq
= (mrb_code
*)codegen_realloc(s
, s
->iseq
, sizeof(mrb_code
)*s
->icapa
);
156 s
->lines
= (uint16_t*)codegen_realloc(s
, s
->lines
, sizeof(short)*s
->icapa
);
157 s
->irep
->lines
= s
->lines
;
162 s
->lines
[s
->pc
] = s
->lineno
;
171 no_optimize(codegen_scope
*s
)
173 if (s
&& s
->parser
&& s
->parser
->no_optimize
)
179 genop_peep(codegen_scope
*s
, mrb_code i
, int val
)
181 /* peephole optimization */
182 if (!no_optimize(s
) && s
->lastlabel
!= s
->pc
&& s
->pc
> 0) {
183 mrb_code i0
= s
->iseq
[s
->pc
-1];
184 int c1
= GET_OPCODE(i
);
185 int c0
= GET_OPCODE(i0
);
189 if (GETARG_A(i
) == GETARG_B(i
)) {
190 /* skip useless OP_MOVE */
196 if (GETARG_A(i
) == GETARG_A(i0
)) {
197 /* skip overriden OP_MOVE */
201 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i
) == GETARG_B(i0
)) {
202 /* skip swapping OP_MOVE */
205 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i0
) >= s
->nlocals
) {
207 return genop_peep(s
, MKOP_AB(OP_MOVE
, GETARG_A(i
), GETARG_B(i0
)), val
);
211 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i0
) >= s
->nlocals
) {
212 s
->iseq
[s
->pc
-1] = MKOP_AsBx(OP_LOADI
, GETARG_A(i
), GETARG_sBx(i0
));
221 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i0
) >= s
->nlocals
) {
222 s
->iseq
[s
->pc
-1] = MKOP_ABC(c0
, GETARG_A(i
), GETARG_B(i0
), GETARG_C(i0
));
234 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i0
) >= s
->nlocals
) {
235 s
->iseq
[s
->pc
-1] = MKOP_ABx(c0
, GETARG_A(i
), GETARG_Bx(i0
));
240 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i0
) >= s
->nlocals
) {
241 s
->iseq
[s
->pc
-1] = MKOP_AB(c0
, GETARG_A(i
), GETARG_B(i0
));
250 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i0
) >= s
->nlocals
) {
251 s
->iseq
[s
->pc
-1] = MKOP_A(c0
, GETARG_A(i
));
266 if (GETARG_A(i
) == GETARG_A(i0
)) {
267 s
->iseq
[s
->pc
-1] = MKOP_ABx(c1
, GETARG_B(i0
), GETARG_Bx(i
));
275 if (GETARG_A(i
) == GETARG_A(i0
)) {
276 s
->iseq
[s
->pc
-1] = MKOP_ABC(c1
, GETARG_B(i0
), GETARG_B(i
), GETARG_C(i
));
283 s
->iseq
[s
->pc
-1] = MKOP_A(OP_EPOP
, GETARG_A(i0
)+GETARG_A(i
));
288 if (c0
== OP_POPERR
) {
289 s
->iseq
[s
->pc
-1] = MKOP_A(OP_POPERR
, GETARG_A(i0
)+GETARG_A(i
));
298 if (GETARG_A(i0
) >= s
->nlocals
) {
299 s
->iseq
[s
->pc
-1] = MKOP_AB(OP_RETURN
, GETARG_B(i0
), OP_R_NORMAL
);
310 genop_peep(s
, i0
, NOVAL
);
311 i0
= s
->iseq
[s
->pc
-1];
312 return genop(s
, MKOP_AB(OP_RETURN
, GETARG_A(i0
), OP_R_NORMAL
));
315 if (GETARG_B(i
) == OP_R_NORMAL
&& GETARG_A(i
) == GETARG_A(i0
)) {
316 s
->iseq
[s
->pc
-1] = MKOP_ABC(OP_TAILCALL
, GETARG_A(i0
), GETARG_B(i0
), GETARG_C(i0
));
327 if (c0
== OP_LOADI
) {
328 int c
= GETARG_sBx(i0
);
330 if (c1
== OP_SUB
) c
= -c
;
331 if (c
> 127 || c
< -127) break;
333 s
->iseq
[s
->pc
-1] = MKOP_ABC(OP_ADDI
, GETARG_A(i
), GETARG_B(i
), c
);
335 s
->iseq
[s
->pc
-1] = MKOP_ABC(OP_SUBI
, GETARG_A(i
), GETARG_B(i
), -c
);
339 if (c0
== OP_STRING
) {
340 mrb_value v
= s
->irep
->pool
[GETARG_Bx(i0
)];
342 if (mrb_string_p(v
) && RSTRING_LEN(v
) == 0) {
347 if (c0
== OP_LOADNIL
) {
348 if (GETARG_B(i
) == GETARG_A(i0
)) {
356 if (c0
== OP_MOVE
&& GETARG_A(i
) == GETARG_A(i0
)) {
357 s
->iseq
[s
->pc
-1] = MKOP_AsBx(c1
, GETARG_B(i0
), GETARG_sBx(i
));
369 scope_error(codegen_scope
*s
)
375 dispatch(codegen_scope
*s
, int pc
)
377 int diff
= s
->pc
- pc
;
378 mrb_code i
= s
->iseq
[pc
];
379 int c
= GET_OPCODE(i
);
381 s
->lastlabel
= s
->pc
;
389 #ifndef MRB_DISABLE_STDIO
390 fprintf(stderr
, "bug: dispatch on non JMP op\n");
395 if (diff
> MAXARG_sBx
) {
396 codegen_error(s
, "too distant jump address");
398 s
->iseq
[pc
] = MKOP_AsBx(c
, GETARG_A(i
), diff
);
402 dispatch_linked(codegen_scope
*s
, int pc
)
417 #define nregs_update do {if (s->sp > s->nregs) s->nregs = s->sp;} while (0)
419 push_(codegen_scope
*s
)
422 codegen_error(s
, "too complex expression");
429 push_n_(codegen_scope
*s
, int n
)
432 codegen_error(s
, "too complex expression");
438 #define push() push_(s)
439 #define push_n(n) push_n_(s,n)
440 #define pop_(s) ((s)->sp--)
441 #define pop() pop_(s)
442 #define pop_n(n) (s->sp-=(n))
443 #define cursp() (s->sp)
446 new_lit(codegen_scope
*s
, mrb_value val
)
451 switch (mrb_type(val
)) {
453 for (i
=0; i
<s
->irep
->plen
; i
++) {
455 pv
= &s
->irep
->pool
[i
];
457 if (mrb_type(*pv
) != MRB_TT_STRING
) continue;
458 if ((len
= RSTRING_LEN(*pv
)) != RSTRING_LEN(val
)) continue;
459 if (memcmp(RSTRING_PTR(*pv
), RSTRING_PTR(val
), len
) == 0)
464 for (i
=0; i
<s
->irep
->plen
; i
++) {
465 pv
= &s
->irep
->pool
[i
];
466 if (mrb_type(*pv
) != MRB_TT_FLOAT
) continue;
467 if (mrb_float(*pv
) == mrb_float(val
)) return i
;
471 for (i
=0; i
<s
->irep
->plen
; i
++) {
472 pv
= &s
->irep
->pool
[i
];
473 if (!mrb_fixnum_p(*pv
)) continue;
474 if (mrb_fixnum(*pv
) == mrb_fixnum(val
)) return i
;
478 /* should not happen */
482 if (s
->irep
->plen
== s
->pcapa
) {
484 s
->irep
->pool
= (mrb_value
*)codegen_realloc(s
, s
->irep
->pool
, sizeof(mrb_value
)*s
->pcapa
);
487 pv
= &s
->irep
->pool
[s
->irep
->plen
];
490 switch (mrb_type(val
)) {
492 *pv
= mrb_str_pool(s
->mrb
, val
);
496 #ifdef MRB_WORD_BOXING
497 *pv
= mrb_float_pool(s
->mrb
, mrb_float(val
));
505 /* should not happen */
511 /* method symbols should be fit in 9 bits */
512 #define MAXMSYMLEN 512
513 /* maximum symbol numbers */
514 #define MAXSYMLEN 65536
517 new_msym(codegen_scope
*s
, mrb_sym sym
)
524 if (len
> MAXMSYMLEN
) len
= MAXMSYMLEN
;
525 for (i
=0; i
<len
; i
++) {
526 if (s
->irep
->syms
[i
] == sym
) return i
;
527 if (s
->irep
->syms
[i
] == 0) break;
529 if (i
== MAXMSYMLEN
) {
530 codegen_error(s
, "too many symbols (max " MRB_STRINGIZE(MAXMSYMLEN
) ")");
532 s
->irep
->syms
[i
] = sym
;
533 if (i
== s
->irep
->slen
) s
->irep
->slen
++;
538 new_sym(codegen_scope
*s
, mrb_sym sym
)
542 for (i
=0; i
<s
->irep
->slen
; i
++) {
543 if (s
->irep
->syms
[i
] == sym
) return i
;
545 if (s
->irep
->slen
== MAXSYMLEN
) {
546 codegen_error(s
, "too many symbols (max " MRB_STRINGIZE(MAXSYMLEN
) ")");
549 if (s
->irep
->slen
> MAXMSYMLEN
/2 && s
->scapa
== MAXMSYMLEN
) {
550 s
->scapa
= MAXSYMLEN
;
551 s
->irep
->syms
= (mrb_sym
*)codegen_realloc(s
, s
->irep
->syms
, sizeof(mrb_sym
)*MAXSYMLEN
);
552 for (i
= s
->irep
->slen
; i
< MAXMSYMLEN
; i
++) {
553 static const mrb_sym mrb_sym_zero
= { 0 };
554 s
->irep
->syms
[i
] = mrb_sym_zero
;
556 s
->irep
->slen
= MAXMSYMLEN
;
558 s
->irep
->syms
[s
->irep
->slen
] = sym
;
559 return s
->irep
->slen
++;
574 #define nsym(x) ((mrb_sym)(intptr_t)(x))
575 #define lv_name(lv) nsym((lv)->car)
577 lv_idx(codegen_scope
*s
, mrb_sym id
)
583 if (lv_name(lv
) == id
) return n
;
591 for_body(codegen_scope
*s
, node
*tree
)
593 codegen_scope
*prev
= s
;
599 /* generate receiver */
600 codegen(s
, tree
->cdr
->car
, VAL
);
601 /* generate loop-block */
602 s
= scope_new(s
->mrb
, s
, NULL
);
604 raise_error(prev
, "unexpected scope");
607 push(); /* push for a block parameter */
609 /* generate loop variable */
611 genop(s
, MKOP_Ax(OP_ENTER
, 0x40000));
612 if (n2
->car
&& !n2
->car
->cdr
&& !n2
->cdr
) {
613 gen_assignment(s
, n2
->car
->car
, 1, NOVAL
);
616 gen_vmassignment(s
, n2
, 1, VAL
);
619 lp
= loop_push(s
, LOOP_FOR
);
620 lp
->pc2
= new_label(s
);
623 codegen(s
, tree
->cdr
->cdr
->car
, VAL
);
626 c
= s
->iseq
[s
->pc
-1];
627 if (GET_OPCODE(c
) != OP_RETURN
|| GETARG_B(c
) != OP_R_NORMAL
|| s
->pc
== s
->lastlabel
)
628 genop_peep(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_NORMAL
), NOVAL
);
633 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), s
->irep
->rlen
-1, OP_L_BLOCK
));
634 push();pop(); /* space for a block */
636 idx
= new_msym(s
, mrb_intern_lit(s
->mrb
, "each"));
637 genop(s
, MKOP_ABC(OP_SENDB
, cursp(), idx
, 0));
641 lambda_body(codegen_scope
*s
, node
*tree
, int blk
)
644 codegen_scope
*parent
= s
;
645 s
= scope_new(s
->mrb
, s
, tree
->car
);
647 raise_error(parent
, "unexpected scope");
653 struct loopinfo
*lp
= loop_push(s
, LOOP_BLOCK
);
654 lp
->pc1
= new_label(s
);
659 int ma
, oa
, ra
, pa
, ka
, kd
, ba
;
663 ma
= node_len(tree
->car
->car
);
668 oa
= node_len(tree
->car
->cdr
->car
);
669 ra
= tree
->car
->cdr
->cdr
->car
? 1 : 0;
670 pa
= node_len(tree
->car
->cdr
->cdr
->cdr
->car
);
672 ba
= tree
->car
->cdr
->cdr
->cdr
->cdr
? 1 : 0;
674 if (ma
> 0x1f || oa
> 0x1f || pa
> 0x1f || ka
> 0x1f) {
675 codegen_error(s
, "too many formal arguments");
677 a
= ((mrb_aspec
)(ma
& 0x1f) << 18)
678 | ((mrb_aspec
)(oa
& 0x1f) << 13)
684 s
->ainfo
= (((ma
+oa
) & 0x3f) << 6) /* (12bits = 6:1:5) */
687 genop(s
, MKOP_Ax(OP_ENTER
, a
));
689 for (i
=0; i
<oa
; i
++) {
691 genop(s
, MKOP_sBx(OP_JMP
, 0));
694 genop(s
, MKOP_sBx(OP_JMP
, 0));
696 opt
= tree
->car
->cdr
->car
;
702 codegen(s
, opt
->car
->cdr
, VAL
);
703 idx
= lv_idx(s
, nsym(opt
->car
->car
));
705 genop_peep(s
, MKOP_AB(OP_MOVE
, idx
, cursp()), NOVAL
);
713 codegen(s
, tree
->cdr
->car
, VAL
);
716 c
= s
->iseq
[s
->pc
-1];
717 if (GET_OPCODE(c
) != OP_RETURN
|| GETARG_B(c
) != OP_R_NORMAL
|| s
->pc
== s
->lastlabel
) {
719 genop(s
, MKOP_A(OP_LOADNIL
, 0));
720 genop(s
, MKOP_AB(OP_RETURN
, 0, OP_R_NORMAL
));
723 genop_peep(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_NORMAL
), NOVAL
);
731 return parent
->irep
->rlen
- 1;
735 scope_body(codegen_scope
*s
, node
*tree
, int val
)
737 codegen_scope
*scope
= scope_new(s
->mrb
, s
, tree
->car
);
739 raise_error(s
, "unexpected scope");
742 codegen(scope
, tree
->cdr
, VAL
);
744 genop(scope
, MKOP_A(OP_STOP
, 0));
747 genop(scope
, MKOP_AB(OP_RETURN
, 0, OP_R_NORMAL
));
750 if (scope
->nregs
== 0) {
751 genop(scope
, MKOP_A(OP_LOADNIL
, 0));
752 genop(scope
, MKOP_AB(OP_RETURN
, 0, OP_R_NORMAL
));
755 genop_peep(scope
, MKOP_AB(OP_RETURN
, scope
->sp
-1, OP_R_NORMAL
), NOVAL
);
760 /* should not happen */
763 return s
->irep
->rlen
- 1;
766 #define nint(x) ((int)(intptr_t)(x))
767 #define nchar(x) ((char)(intptr_t)(x))
773 if (nint(t
->car
->car
) == NODE_SPLAT
) return FALSE
;
780 attrsym(codegen_scope
*s
, mrb_sym a
)
786 name
= mrb_sym2name_len(s
->mrb
, a
, &len
);
787 name2
= (char *)codegen_palloc(s
,
792 mrb_assert_int_fit(mrb_int
, len
, size_t, SIZE_MAX
);
793 memcpy(name2
, name
, (size_t)len
);
797 return mrb_intern(s
->mrb
, name2
, len
+1);
800 #define CALL_MAXARGS 127
803 gen_values(codegen_scope
*s
, node
*t
, int val
, int extra
)
809 is_splat
= nint(t
->car
->car
) == NODE_SPLAT
; /* splat mode */
811 n
+extra
>= CALL_MAXARGS
- 1 /* need to subtract one because vm.c expects an array if n == CALL_MAXARGS */
814 if (is_splat
&& n
== 0 && nint(t
->car
->cdr
->car
) == NODE_ARRAY
) {
815 codegen(s
, t
->car
->cdr
, VAL
);
820 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), cursp(), n
));
822 codegen(s
, t
->car
, VAL
);
825 genop(s
, MKOP_AB(OP_ARYCAT
, cursp(), cursp()+1));
828 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), cursp()+1));
834 codegen(s
, t
->car
, VAL
);
836 if (nint(t
->car
->car
) == NODE_SPLAT
) {
837 genop(s
, MKOP_AB(OP_ARYCAT
, cursp(), cursp()+1));
840 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), cursp()+1));
847 codegen(s
, t
->car
, NOVAL
);
853 /* normal (no splat) mode */
854 codegen(s
, t
->car
, val
);
862 gen_call(codegen_scope
*s
, node
*tree
, mrb_sym name
, int sp
, int val
, int safe
)
864 mrb_sym sym
= name
? name
: nsym(tree
->cdr
->car
);
866 int n
= 0, noop
= 0, sendv
= 0, blk
= 0;
868 codegen(s
, tree
->car
, VAL
); /* receiver */
870 int recv
= cursp()-1;
871 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
873 genop(s
, MKOP_AB(OP_MOVE
, cursp(), recv
));
874 push_n(2); pop_n(2); /* space for one arg and a block */
876 idx
= new_msym(s
, mrb_intern_lit(s
->mrb
, "=="));
877 genop(s
, MKOP_ABC(OP_EQ
, cursp(), idx
, 1));
878 skip
= genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), 0));
880 idx
= new_msym(s
, sym
);
881 tree
= tree
->cdr
->cdr
->car
;
883 n
= gen_values(s
, tree
->car
, VAL
, sp
?1:0);
885 n
= noop
= sendv
= 1;
892 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), sp
));
896 genop(s
, MKOP_AB(OP_MOVE
, cursp(), sp
));
901 if (tree
&& tree
->cdr
) {
903 codegen(s
, tree
->cdr
, VAL
);
913 const char *symname
= mrb_sym2name_len(s
->mrb
, sym
, &symlen
);
915 if (!noop
&& symlen
== 1 && symname
[0] == '+' && n
== 1) {
916 genop_peep(s
, MKOP_ABC(OP_ADD
, cursp(), idx
, n
), val
);
918 else if (!noop
&& symlen
== 1 && symname
[0] == '-' && n
== 1) {
919 genop_peep(s
, MKOP_ABC(OP_SUB
, cursp(), idx
, n
), val
);
921 else if (!noop
&& symlen
== 1 && symname
[0] == '*' && n
== 1) {
922 genop(s
, MKOP_ABC(OP_MUL
, cursp(), idx
, n
));
924 else if (!noop
&& symlen
== 1 && symname
[0] == '/' && n
== 1) {
925 genop(s
, MKOP_ABC(OP_DIV
, cursp(), idx
, n
));
927 else if (!noop
&& symlen
== 1 && symname
[0] == '<' && n
== 1) {
928 genop(s
, MKOP_ABC(OP_LT
, cursp(), idx
, n
));
930 else if (!noop
&& symlen
== 2 && symname
[0] == '<' && symname
[1] == '=' && n
== 1) {
931 genop(s
, MKOP_ABC(OP_LE
, cursp(), idx
, n
));
933 else if (!noop
&& symlen
== 1 && symname
[0] == '>' && n
== 1) {
934 genop(s
, MKOP_ABC(OP_GT
, cursp(), idx
, n
));
936 else if (!noop
&& symlen
== 2 && symname
[0] == '>' && symname
[1] == '=' && n
== 1) {
937 genop(s
, MKOP_ABC(OP_GE
, cursp(), idx
, n
));
939 else if (!noop
&& symlen
== 2 && symname
[0] == '=' && symname
[1] == '=' && n
== 1) {
940 genop(s
, MKOP_ABC(OP_EQ
, cursp(), idx
, n
));
943 if (sendv
) n
= CALL_MAXARGS
;
944 if (blk
> 0) { /* no block */
945 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, n
));
948 genop(s
, MKOP_ABC(OP_SENDB
, cursp(), idx
, n
));
961 gen_assignment(codegen_scope
*s
, node
*tree
, int sp
, int val
)
964 int type
= nint(tree
->car
);
969 idx
= new_sym(s
, nsym(tree
));
970 genop_peep(s
, MKOP_ABx(OP_SETGLOBAL
, sp
, idx
), val
);
973 idx
= lv_idx(s
, nsym(tree
));
976 genop_peep(s
, MKOP_AB(OP_MOVE
, idx
, sp
), val
);
982 codegen_scope
*up
= s
->prev
;
985 idx
= lv_idx(up
, nsym(tree
));
987 genop_peep(s
, MKOP_ABC(OP_SETUPVAR
, sp
, idx
, lv
), val
);
996 idx
= new_sym(s
, nsym(tree
));
997 genop_peep(s
, MKOP_ABx(OP_SETIV
, sp
, idx
), val
);
1000 idx
= new_sym(s
, nsym(tree
));
1001 genop_peep(s
, MKOP_ABx(OP_SETCV
, sp
, idx
), val
);
1004 idx
= new_sym(s
, nsym(tree
));
1005 genop_peep(s
, MKOP_ABx(OP_SETCONST
, sp
, idx
), val
);
1008 idx
= new_sym(s
, nsym(tree
->cdr
));
1009 genop_peep(s
, MKOP_AB(OP_MOVE
, cursp(), sp
), NOVAL
);
1011 codegen(s
, tree
->car
, VAL
);
1013 genop_peep(s
, MKOP_ABx(OP_SETMCNST
, cursp(), idx
), val
);
1019 gen_call(s
, tree
, attrsym(s
, nsym(tree
->cdr
->car
)), sp
, NOVAL
,
1020 type
== NODE_SCALL
);
1023 genop_peep(s
, MKOP_AB(OP_MOVE
, cursp(), sp
), val
);
1028 gen_vmassignment(s
, tree
->car
, sp
, val
);
1031 /* splat without assignment */
1036 #ifndef MRB_DISABLE_STDIO
1037 fprintf(stderr
, "unknown lhs %d\n", type
);
1045 gen_vmassignment(codegen_scope
*s
, node
*tree
, int rhs
, int val
)
1047 int n
= 0, post
= 0;
1050 if (tree
->car
) { /* pre */
1054 genop(s
, MKOP_ABC(OP_AREF
, cursp(), rhs
, n
));
1055 gen_assignment(s
, t
->car
, cursp(), NOVAL
);
1062 if (t
->cdr
) { /* post count */
1070 genop(s
, MKOP_AB(OP_MOVE
, cursp(), rhs
));
1077 genop(s
, MKOP_ABC(OP_APOST
, cursp(), n
, post
));
1079 if (t
->car
) { /* rest */
1080 gen_assignment(s
, t
->car
, cursp(), NOVAL
);
1082 if (t
->cdr
&& t
->cdr
->car
) {
1085 gen_assignment(s
, t
->car
, cursp()+n
, NOVAL
);
1097 gen_send_intern(codegen_scope
*s
)
1099 push();pop(); /* space for a block */
1101 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "intern")), 0));
1105 gen_literal_array(codegen_scope
*s
, node
*tree
, mrb_bool sym
, int val
)
1111 switch (nint(tree
->car
->car
)) {
1113 if ((tree
->cdr
== NULL
) && (nint(tree
->car
->cdr
->cdr
) == 0))
1117 codegen(s
, tree
->car
, VAL
);
1121 case NODE_LITERAL_DELIM
:
1132 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
1144 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), cursp(), i
));
1149 switch (nint(tree
->car
->car
)) {
1150 case NODE_BEGIN
: case NODE_BLOCK
:
1151 codegen(s
, tree
->car
, NOVAL
);
1159 raise_error(codegen_scope
*s
, const char *msg
)
1161 int idx
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, msg
));
1163 genop(s
, MKOP_ABx(OP_ERR
, 1, idx
));
1167 readint_float(codegen_scope
*s
, const char *p
, int base
)
1169 const char *e
= p
+ strlen(p
);
1176 c
= tolower((unsigned char)c
);
1177 for (n
=0; n
<base
; n
++) {
1178 if (mrb_digitmap
[n
] == c
) {
1185 codegen_error(s
, "malformed readint input");
1193 readint_mrb_int(codegen_scope
*s
, const char *p
, int base
, mrb_bool neg
, mrb_bool
*overflow
)
1195 const char *e
= p
+ strlen(p
);
1199 mrb_assert(base
>= 2 && base
<= 36);
1203 c
= tolower((unsigned char)c
);
1204 for (n
=0; n
<base
; n
++) {
1205 if (mrb_digitmap
[n
] == c
) {
1210 codegen_error(s
, "malformed readint input");
1214 if ((MRB_INT_MIN
+ n
)/base
> result
) {
1222 if ((MRB_INT_MAX
- n
)/base
< result
) {
1236 gen_retval(codegen_scope
*s
, node
*tree
)
1238 if (nint(tree
->car
) == NODE_SPLAT
) {
1239 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), cursp(), 0));
1241 codegen(s
, tree
, VAL
);
1243 genop(s
, MKOP_AB(OP_ARYCAT
, cursp(), cursp()+1));
1246 codegen(s
, tree
, VAL
);
1252 codegen(codegen_scope
*s
, node
*tree
, int val
)
1259 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1266 if (s
->rlev
> MRB_CODEGEN_LEVEL_MAX
) {
1267 codegen_error(s
, "too complex expression");
1269 if (s
->irep
&& s
->filename_index
!= tree
->filename_index
) {
1270 s
->irep
->filename
= mrb_parser_get_filename(s
->parser
, s
->filename_index
);
1271 mrb_debug_info_append_file(s
->mrb
, s
->irep
, s
->debug_start_pos
, s
->pc
);
1272 s
->debug_start_pos
= s
->pc
;
1273 s
->filename_index
= tree
->filename_index
;
1274 s
->filename
= mrb_parser_get_filename(s
->parser
, tree
->filename_index
);
1277 nt
= nint(tree
->car
);
1278 s
->lineno
= tree
->lineno
;
1283 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1287 codegen(s
, tree
->car
, tree
->cdr
? NOVAL
: val
);
1294 int onerr
, noexc
, exend
, pos1
, pos2
, tmp
;
1295 struct loopinfo
*lp
;
1297 if (tree
->car
== NULL
) goto exit
;
1298 onerr
= genop(s
, MKOP_Bx(OP_ONERR
, 0));
1299 lp
= loop_push(s
, LOOP_BEGIN
);
1301 codegen(s
, tree
->car
, VAL
);
1303 lp
->type
= LOOP_RESCUE
;
1304 noexc
= genop(s
, MKOP_Bx(OP_JMP
, 0));
1310 node
*n2
= tree
->car
;
1313 genop(s
, MKOP_ABC(OP_RESCUE
, exc
, 0, 0));
1319 if (pos1
) dispatch(s
, pos1
);
1322 if (n4
&& n4
->car
&& nint(n4
->car
->car
) == NODE_SPLAT
) {
1323 codegen(s
, n4
->car
, VAL
);
1324 genop(s
, MKOP_AB(OP_MOVE
, cursp(), exc
));
1325 push_n(2); pop_n(2); /* space for one arg and a block */
1327 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "__case_eqq")), 1));
1331 codegen(s
, n4
->car
, VAL
);
1334 genop(s
, MKOP_ABx(OP_GETCONST
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "StandardError"))));
1338 genop(s
, MKOP_ABC(OP_RESCUE
, exc
, cursp(), 1));
1340 tmp
= genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), pos2
));
1346 pos1
= genop(s
, MKOP_sBx(OP_JMP
, 0));
1347 dispatch_linked(s
, pos2
);
1351 gen_assignment(s
, n3
->cdr
->car
, exc
, NOVAL
);
1353 if (n3
->cdr
->cdr
->car
) {
1354 codegen(s
, n3
->cdr
->cdr
->car
, val
);
1357 tmp
= genop(s
, MKOP_sBx(OP_JMP
, exend
));
1364 genop(s
, MKOP_A(OP_RAISE
, exc
));
1370 genop(s
, MKOP_A(OP_POPERR
, 1));
1372 codegen(s
, tree
->car
, val
);
1377 dispatch_linked(s
, exend
);
1383 if (!tree
->cdr
|| !tree
->cdr
->cdr
||
1384 (nint(tree
->cdr
->cdr
->car
) == NODE_BEGIN
&&
1385 tree
->cdr
->cdr
->cdr
)) {
1389 genop(s
, MKOP_Bx(OP_EPUSH
, 0));
1391 codegen(s
, tree
->car
, val
);
1392 idx
= scope_body(s
, tree
->cdr
, NOVAL
);
1393 s
->iseq
[epush
] = MKOP_Bx(OP_EPUSH
, idx
);
1395 genop_peep(s
, MKOP_A(OP_EPOP
, 1), NOVAL
);
1397 else { /* empty ensure ignored */
1398 codegen(s
, tree
->car
, val
);
1404 int idx
= lambda_body(s
, tree
, 1);
1406 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), idx
, OP_L_LAMBDA
));
1413 int idx
= lambda_body(s
, tree
, 1);
1415 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), idx
, OP_L_BLOCK
));
1423 node
*e
= tree
->cdr
->cdr
->car
;
1429 switch (nint(tree
->car
->car
)) {
1433 codegen(s
, tree
->cdr
->car
, val
);
1440 codegen(s
, tree
->car
, VAL
);
1442 pos1
= genop_peep(s
, MKOP_AsBx(OP_JMPNOT
, cursp(), 0), NOVAL
);
1444 codegen(s
, tree
->cdr
->car
, val
);
1447 pos2
= genop(s
, MKOP_sBx(OP_JMP
, 0));
1455 pos2
= genop(s
, MKOP_sBx(OP_JMP
, 0));
1457 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1472 codegen(s
, tree
->car
, VAL
);
1474 pos
= genop(s
, MKOP_AsBx(OP_JMPNOT
, cursp(), 0));
1475 codegen(s
, tree
->cdr
, val
);
1484 codegen(s
, tree
->car
, VAL
);
1486 pos
= genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), 0));
1487 codegen(s
, tree
->cdr
, val
);
1494 struct loopinfo
*lp
= loop_push(s
, LOOP_NORMAL
);
1496 lp
->pc1
= genop(s
, MKOP_sBx(OP_JMP
, 0));
1497 lp
->pc2
= new_label(s
);
1498 codegen(s
, tree
->cdr
, NOVAL
);
1499 dispatch(s
, lp
->pc1
);
1500 codegen(s
, tree
->car
, VAL
);
1502 genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), lp
->pc2
- s
->pc
));
1510 struct loopinfo
*lp
= loop_push(s
, LOOP_NORMAL
);
1512 lp
->pc1
= genop(s
, MKOP_sBx(OP_JMP
, 0));
1513 lp
->pc2
= new_label(s
);
1514 codegen(s
, tree
->cdr
, NOVAL
);
1515 dispatch(s
, lp
->pc1
);
1516 codegen(s
, tree
->car
, VAL
);
1518 genop(s
, MKOP_AsBx(OP_JMPNOT
, cursp(), lp
->pc2
- s
->pc
));
1532 int pos1
, pos2
, pos3
, tmp
;
1538 codegen(s
, tree
->car
, VAL
);
1545 codegen(s
, n
->car
, VAL
);
1547 genop(s
, MKOP_AB(OP_MOVE
, cursp(), head
));
1548 push_n(2); pop_n(2); /* space for one arg and a block */
1550 if (nint(n
->car
->car
) == NODE_SPLAT
) {
1551 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "__case_eqq")), 1));
1554 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "===")), 1));
1560 tmp
= genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), pos2
));
1564 if (tree
->car
->car
) {
1565 pos1
= genop(s
, MKOP_sBx(OP_JMP
, 0));
1566 dispatch_linked(s
, pos2
);
1568 codegen(s
, tree
->car
->cdr
, val
);
1570 tmp
= genop(s
, MKOP_sBx(OP_JMP
, pos3
));
1572 if (pos1
) dispatch(s
, pos1
);
1577 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1578 if (pos3
) dispatch_linked(s
, pos3
);
1580 if (cursp() != pos
) {
1581 genop(s
, MKOP_AB(OP_MOVE
, cursp(), pos
));
1587 dispatch_linked(s
, pos3
);
1597 scope_body(s
, tree
, NOVAL
);
1602 gen_call(s
, tree
, 0, 0, val
, 0);
1605 gen_call(s
, tree
, 0, 0, val
, 1);
1609 codegen(s
, tree
->car
, val
);
1610 codegen(s
, tree
->cdr
, val
);
1613 genop(s
, MKOP_ABC(OP_RANGE
, cursp(), cursp(), FALSE
));
1619 codegen(s
, tree
->car
, val
);
1620 codegen(s
, tree
->cdr
, val
);
1623 genop(s
, MKOP_ABC(OP_RANGE
, cursp(), cursp(), TRUE
));
1630 int sym
= new_sym(s
, nsym(tree
->cdr
));
1632 codegen(s
, tree
->car
, VAL
);
1634 genop(s
, MKOP_ABx(OP_GETMCNST
, cursp(), sym
));
1641 int sym
= new_sym(s
, nsym(tree
));
1643 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
1644 genop(s
, MKOP_ABx(OP_GETMCNST
, cursp(), sym
));
1653 n
= gen_values(s
, tree
, val
, 0);
1657 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), cursp(), n
));
1670 mrb_bool update
= FALSE
;
1673 codegen(s
, tree
->car
->car
, val
);
1674 codegen(s
, tree
->car
->cdr
, val
);
1677 if (val
&& len
== 126) {
1679 genop(s
, MKOP_ABC(OP_HASH
, cursp(), cursp(), len
));
1682 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "__update")), 1));
1691 genop(s
, MKOP_ABC(OP_HASH
, cursp(), cursp(), len
));
1694 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "__update")), 1));
1702 codegen(s
, tree
, val
);
1706 codegen(s
, tree
->cdr
, VAL
);
1708 gen_assignment(s
, tree
->car
, cursp(), val
);
1713 int len
= 0, n
= 0, post
= 0;
1714 node
*t
= tree
->cdr
, *p
;
1717 if (nint(t
->car
) == NODE_ARRAY
&& t
->cdr
&& nosplat(t
->cdr
)) {
1721 codegen(s
, t
->car
, VAL
);
1726 if (tree
->car
) { /* pre */
1731 gen_assignment(s
, t
->car
, rhs
+n
, NOVAL
);
1735 genop(s
, MKOP_A(OP_LOADNIL
, rhs
+n
));
1736 gen_assignment(s
, t
->car
, rhs
+n
, NOVAL
);
1743 if (t
->cdr
) { /* post count */
1750 if (t
->car
) { /* rest (len - pre - post) */
1753 if (len
< post
+ n
) {
1757 rn
= len
- post
- n
;
1759 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), rhs
+n
, rn
));
1760 gen_assignment(s
, t
->car
, cursp(), NOVAL
);
1763 if (t
->cdr
&& t
->cdr
->car
) {
1766 gen_assignment(s
, t
->car
, rhs
+n
, NOVAL
);
1774 genop(s
, MKOP_ABC(OP_ARRAY
, rhs
, rhs
, len
));
1781 gen_vmassignment(s
, tree
->car
, rhs
, val
);
1791 mrb_sym sym
= nsym(tree
->cdr
->car
);
1793 const char *name
= mrb_sym2name_len(s
->mrb
, sym
, &len
);
1794 int idx
, callargs
= -1, vsp
= -1;
1796 if ((len
== 2 && name
[0] == '|' && name
[1] == '|') &&
1797 (nint(tree
->car
->car
) == NODE_CONST
||
1798 nint(tree
->car
->car
) == NODE_CVAR
)) {
1799 int onerr
, noexc
, exc
;
1800 struct loopinfo
*lp
;
1802 onerr
= genop(s
, MKOP_Bx(OP_ONERR
, 0));
1803 lp
= loop_push(s
, LOOP_BEGIN
);
1806 codegen(s
, tree
->car
, VAL
);
1807 lp
->type
= LOOP_RESCUE
;
1808 genop(s
, MKOP_A(OP_POPERR
, 1));
1809 noexc
= genop(s
, MKOP_Bx(OP_JMP
, 0));
1811 genop(s
, MKOP_ABC(OP_RESCUE
, exc
, 0, 0));
1812 genop(s
, MKOP_A(OP_LOADF
, exc
));
1816 else if (nint(tree
->car
->car
) == NODE_CALL
) {
1817 node
*n
= tree
->car
->cdr
;
1818 int base
, i
, nargs
= 0;
1825 codegen(s
, n
->car
, VAL
); /* receiver */
1826 idx
= new_msym(s
, nsym(n
->cdr
->car
));
1828 if (n
->cdr
->cdr
->car
) {
1829 nargs
= gen_values(s
, n
->cdr
->cdr
->car
->car
, VAL
, 1);
1833 else { /* varargs */
1836 callargs
= CALL_MAXARGS
;
1839 /* copy receiver and arguments */
1840 genop(s
, MKOP_AB(OP_MOVE
, cursp(), base
));
1841 for (i
=0; i
<nargs
; i
++) {
1842 genop(s
, MKOP_AB(OP_MOVE
, cursp()+i
+1, base
+i
+1));
1844 push_n(nargs
+1);pop_n(nargs
+1);
1845 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, callargs
));
1849 codegen(s
, tree
->car
, VAL
);
1852 ((name
[0] == '|' && name
[1] == '|') ||
1853 (name
[0] == '&' && name
[1] == '&'))) {
1859 genop(s
, MKOP_AB(OP_MOVE
, vsp
, cursp()));
1861 pos
= genop(s
, MKOP_AsBx(name
[0]=='|'?OP_JMPIF
:OP_JMPNOT
, cursp(), 0));
1864 pos
= genop_peep(s
, MKOP_AsBx(name
[0]=='|'?OP_JMPIF
:OP_JMPNOT
, cursp(), 0), NOVAL
);
1866 codegen(s
, tree
->cdr
->cdr
->car
, VAL
);
1868 if (val
&& vsp
>= 0) {
1869 genop(s
, MKOP_AB(OP_MOVE
, vsp
, cursp()));
1871 if (nint(tree
->car
->car
) == NODE_CALL
) {
1872 if (callargs
== CALL_MAXARGS
) {
1874 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), cursp()+1));
1881 idx
= new_msym(s
, attrsym(s
, nsym(tree
->car
->cdr
->cdr
->car
)));
1882 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, callargs
));
1885 gen_assignment(s
, tree
->car
, cursp(), val
);
1890 codegen(s
, tree
->cdr
->cdr
->car
, VAL
);
1894 idx
= new_msym(s
, sym
);
1895 if (len
== 1 && name
[0] == '+') {
1896 genop_peep(s
, MKOP_ABC(OP_ADD
, cursp(), idx
, 1), val
);
1898 else if (len
== 1 && name
[0] == '-') {
1899 genop_peep(s
, MKOP_ABC(OP_SUB
, cursp(), idx
, 1), val
);
1901 else if (len
== 1 && name
[0] == '*') {
1902 genop(s
, MKOP_ABC(OP_MUL
, cursp(), idx
, 1));
1904 else if (len
== 1 && name
[0] == '/') {
1905 genop(s
, MKOP_ABC(OP_DIV
, cursp(), idx
, 1));
1907 else if (len
== 1 && name
[0] == '<') {
1908 genop(s
, MKOP_ABC(OP_LT
, cursp(), idx
, 1));
1910 else if (len
== 2 && name
[0] == '<' && name
[1] == '=') {
1911 genop(s
, MKOP_ABC(OP_LE
, cursp(), idx
, 1));
1913 else if (len
== 1 && name
[0] == '>') {
1914 genop(s
, MKOP_ABC(OP_GT
, cursp(), idx
, 1));
1916 else if (len
== 2 && name
[0] == '>' && name
[1] == '=') {
1917 genop(s
, MKOP_ABC(OP_GE
, cursp(), idx
, 1));
1920 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, 1));
1923 gen_assignment(s
, tree
->car
, cursp(), val
);
1926 if (val
&& vsp
>= 0) {
1927 genop(s
, MKOP_AB(OP_MOVE
, vsp
, cursp()));
1929 if (callargs
== CALL_MAXARGS
) {
1931 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), cursp()+1));
1938 idx
= new_msym(s
, attrsym(s
,nsym(tree
->car
->cdr
->cdr
->car
)));
1939 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, callargs
));
1946 codegen_scope
*s2
= s
;
1948 int n
= 0, noop
= 0, sendv
= 0;
1950 push(); /* room for receiver */
1951 while (!s2
->mscope
) {
1956 genop(s
, MKOP_ABx(OP_ARGARY
, cursp(), (lv
& 0xf)));
1957 push(); push(); /* ARGARY pushes two values */
1960 node
*args
= tree
->car
;
1962 n
= gen_values(s
, args
, VAL
, 0);
1964 n
= noop
= sendv
= 1;
1969 if (tree
&& tree
->cdr
) {
1970 codegen(s
, tree
->cdr
, VAL
);
1974 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1978 if (sendv
) n
= CALL_MAXARGS
;
1979 genop(s
, MKOP_ABC(OP_SUPER
, cursp(), 0, n
));
1986 codegen_scope
*s2
= s
;
1987 int lv
= 0, ainfo
= 0;
1989 push(); /* room for receiver */
1990 while (!s2
->mscope
) {
1995 if (s2
) ainfo
= s2
->ainfo
;
1996 genop(s
, MKOP_ABx(OP_ARGARY
, cursp(), (ainfo
<<4)|(lv
& 0xf)));
1997 push(); push(); pop(); /* ARGARY pushes two values */
1998 if (tree
&& tree
->cdr
) {
1999 codegen(s
, tree
->cdr
, VAL
);
2003 genop(s
, MKOP_ABC(OP_SUPER
, cursp(), 0, CALL_MAXARGS
));
2010 gen_retval(s
, tree
);
2013 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2016 genop(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_RETURN
));
2019 genop_peep(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_NORMAL
), NOVAL
);
2026 codegen_scope
*s2
= s
;
2027 int lv
= 0, ainfo
= 0;
2028 int n
= 0, sendv
= 0;
2030 while (!s2
->mscope
) {
2035 if (s2
) ainfo
= s2
->ainfo
;
2038 n
= gen_values(s
, tree
, VAL
, 0);
2044 push();pop(); /* space for a block */
2046 genop(s
, MKOP_ABx(OP_BLKPUSH
, cursp(), (ainfo
<<4)|(lv
& 0xf)));
2047 if (sendv
) n
= CALL_MAXARGS
;
2048 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "call")), n
));
2054 loop_break(s
, tree
);
2060 raise_error(s
, "unexpected next");
2062 else if (s
->loop
->type
== LOOP_NORMAL
) {
2063 if (s
->ensure_level
> s
->loop
->ensure_level
) {
2064 genop_peep(s
, MKOP_A(OP_EPOP
, s
->ensure_level
- s
->loop
->ensure_level
), NOVAL
);
2066 codegen(s
, tree
, NOVAL
);
2067 genop(s
, MKOP_sBx(OP_JMP
, s
->loop
->pc1
- s
->pc
));
2071 codegen(s
, tree
, VAL
);
2075 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2077 genop_peep(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_NORMAL
), NOVAL
);
2083 if (!s
->loop
|| s
->loop
->type
== LOOP_BEGIN
|| s
->loop
->type
== LOOP_RESCUE
) {
2084 raise_error(s
, "unexpected redo");
2087 if (s
->ensure_level
> s
->loop
->ensure_level
) {
2088 genop_peep(s
, MKOP_A(OP_EPOP
, s
->ensure_level
- s
->loop
->ensure_level
), NOVAL
);
2090 genop(s
, MKOP_sBx(OP_JMP
, s
->loop
->pc2
- s
->pc
));
2097 const char *msg
= "unexpected retry";
2100 raise_error(s
, msg
);
2103 struct loopinfo
*lp
= s
->loop
;
2106 while (lp
&& lp
->type
!= LOOP_RESCUE
) {
2107 if (lp
->type
== LOOP_BEGIN
) {
2113 raise_error(s
, msg
);
2117 genop_peep(s
, MKOP_A(OP_POPERR
, n
), NOVAL
);
2119 if (s
->ensure_level
> lp
->ensure_level
) {
2120 genop_peep(s
, MKOP_A(OP_EPOP
, s
->ensure_level
- lp
->ensure_level
), NOVAL
);
2122 genop(s
, MKOP_sBx(OP_JMP
, lp
->pc1
- s
->pc
));
2131 int idx
= lv_idx(s
, nsym(tree
));
2134 genop_peep(s
, MKOP_AB(OP_MOVE
, cursp(), idx
), NOVAL
);
2138 codegen_scope
*up
= s
->prev
;
2141 idx
= lv_idx(up
, nsym(tree
));
2143 genop(s
, MKOP_ABC(OP_GETUPVAR
, cursp(), idx
, lv
));
2156 int sym
= new_sym(s
, nsym(tree
));
2158 genop(s
, MKOP_ABx(OP_GETGLOBAL
, cursp(), sym
));
2165 int sym
= new_sym(s
, nsym(tree
));
2167 genop(s
, MKOP_ABx(OP_GETIV
, cursp(), sym
));
2174 int sym
= new_sym(s
, nsym(tree
));
2176 genop(s
, MKOP_ABx(OP_GETCV
, cursp(), sym
));
2183 int sym
= new_sym(s
, nsym(tree
));
2185 genop(s
, MKOP_ABx(OP_GETCONST
, cursp(), sym
));
2193 codegen(s
, tree
, VAL
);
2202 buf
[1] = nchar(tree
);
2204 sym
= new_sym(s
, mrb_intern_cstr(s
->mrb
, buf
));
2205 genop(s
, MKOP_ABx(OP_GETGLOBAL
, cursp(), sym
));
2212 mrb_state
*mrb
= s
->mrb
;
2216 str
= mrb_format(mrb
, "$%S", mrb_fixnum_value(nint(tree
)));
2217 sym
= new_sym(s
, mrb_intern_str(mrb
, str
));
2218 genop(s
, MKOP_ABx(OP_GETGLOBAL
, cursp(), sym
));
2224 /* should not happen */
2227 case NODE_BLOCK_ARG
:
2228 codegen(s
, tree
, VAL
);
2233 char *p
= (char*)tree
->car
;
2234 int base
= nint(tree
->cdr
->car
);
2239 i
= readint_mrb_int(s
, p
, base
, FALSE
, &overflow
);
2241 double f
= readint_float(s
, p
, base
);
2242 int off
= new_lit(s
, mrb_float_value(s
->mrb
, f
));
2244 genop(s
, MKOP_ABx(OP_LOADL
, cursp(), off
));
2247 if (i
< MAXARG_sBx
&& i
> -MAXARG_sBx
) {
2248 co
= MKOP_AsBx(OP_LOADI
, cursp(), i
);
2251 int off
= new_lit(s
, mrb_fixnum_value(i
));
2252 co
= MKOP_ABx(OP_LOADL
, cursp(), off
);
2262 char *p
= (char*)tree
;
2263 mrb_float f
= mrb_float_read(p
, NULL
);
2264 int off
= new_lit(s
, mrb_float_value(s
->mrb
, f
));
2266 genop(s
, MKOP_ABx(OP_LOADL
, cursp(), off
));
2273 nt
= nint(tree
->car
);
2278 char *p
= (char*)tree
;
2279 mrb_float f
= mrb_float_read(p
, NULL
);
2280 int off
= new_lit(s
, mrb_float_value(s
->mrb
, -f
));
2282 genop(s
, MKOP_ABx(OP_LOADL
, cursp(), off
));
2289 char *p
= (char*)tree
->car
;
2290 int base
= nint(tree
->cdr
->car
);
2295 i
= readint_mrb_int(s
, p
, base
, TRUE
, &overflow
);
2297 double f
= readint_float(s
, p
, base
);
2298 int off
= new_lit(s
, mrb_float_value(s
->mrb
, -f
));
2300 genop(s
, MKOP_ABx(OP_LOADL
, cursp(), off
));
2303 if (i
< MAXARG_sBx
&& i
> -MAXARG_sBx
) {
2304 co
= MKOP_AsBx(OP_LOADI
, cursp(), i
);
2307 int off
= new_lit(s
, mrb_fixnum_value(i
));
2308 co
= MKOP_ABx(OP_LOADL
, cursp(), off
);
2318 int sym
= new_msym(s
, mrb_intern_lit(s
->mrb
, "-"));
2320 genop(s
, MKOP_ABx(OP_LOADI
, cursp(), 0));
2322 codegen(s
, tree
, VAL
);
2324 genop(s
, MKOP_ABC(OP_SUB
, cursp(), sym
, 2));
2327 codegen(s
, tree
, NOVAL
);
2336 char *p
= (char*)tree
->car
;
2337 size_t len
= (intptr_t)tree
->cdr
;
2338 int ai
= mrb_gc_arena_save(s
->mrb
);
2339 int off
= new_lit(s
, mrb_str_new(s
->mrb
, p
, len
));
2341 mrb_gc_arena_restore(s
->mrb
, ai
);
2342 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2348 tree
= ((struct mrb_parser_heredoc_info
*)tree
)->doc
;
2355 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2359 codegen(s
, n
->car
, VAL
);
2362 codegen(s
, n
->car
, VAL
);
2364 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
2373 if (nint(n
->car
->car
) != NODE_STR
) {
2374 codegen(s
, n
->car
, NOVAL
);
2382 gen_literal_array(s
, tree
, FALSE
, val
);
2386 gen_literal_array(s
, tree
, TRUE
, val
);
2392 int ai
= mrb_gc_arena_save(s
->mrb
);
2393 int sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "Kernel"));
2395 genop(s
, MKOP_A(OP_LOADSELF
, cursp()));
2397 codegen(s
, tree
->car
, VAL
);
2400 if (nint(n
->car
->car
) == NODE_XSTR
) {
2401 n
->car
->car
= (struct mrb_ast_node
*)(intptr_t)NODE_STR
;
2402 mrb_assert(!n
->cdr
); /* must be the end */
2404 codegen(s
, n
->car
, VAL
);
2406 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
2410 push(); /* for block */
2412 sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "`"));
2413 genop(s
, MKOP_ABC(OP_SEND
, cursp(), sym
, 1));
2415 mrb_gc_arena_restore(s
->mrb
, ai
);
2421 char *p
= (char*)tree
->car
;
2422 size_t len
= (intptr_t)tree
->cdr
;
2423 int ai
= mrb_gc_arena_save(s
->mrb
);
2424 int off
= new_lit(s
, mrb_str_new(s
->mrb
, p
, len
));
2427 genop(s
, MKOP_A(OP_LOADSELF
, cursp()));
2429 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2432 sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "`"));
2433 genop(s
, MKOP_ABC(OP_SEND
, cursp(), sym
, 1));
2435 mrb_gc_arena_restore(s
->mrb
, ai
);
2441 char *p1
= (char*)tree
->car
;
2442 char *p2
= (char*)tree
->cdr
->car
;
2443 char *p3
= (char*)tree
->cdr
->cdr
;
2444 int ai
= mrb_gc_arena_save(s
->mrb
);
2445 int sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, REGEXP_CLASS
));
2446 int off
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, p1
));
2449 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
2450 genop(s
, MKOP_ABx(OP_GETMCNST
, cursp(), sym
));
2452 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2456 off
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, p2
));
2457 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2460 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2465 off
= new_lit(s
, mrb_str_new(s
->mrb
, p3
, 1));
2466 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2473 sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "compile"));
2474 genop(s
, MKOP_ABC(OP_SEND
, cursp(), sym
, argc
));
2475 mrb_gc_arena_restore(s
->mrb
, ai
);
2482 node
*n
= tree
->car
;
2483 int ai
= mrb_gc_arena_save(s
->mrb
);
2484 int sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, REGEXP_CLASS
));
2489 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
2490 genop(s
, MKOP_ABx(OP_GETMCNST
, cursp(), sym
));
2492 codegen(s
, n
->car
, VAL
);
2495 codegen(s
, n
->car
, VAL
);
2497 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
2504 off
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, p
));
2505 codegen(s
, tree
->car
, VAL
);
2506 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2508 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
2511 char *p2
= (char*)n
->cdr
->car
;
2514 off
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, p2
));
2515 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2519 char *p2
= (char*)n
->cdr
->cdr
;
2522 off
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, p2
));
2523 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2527 sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "compile"));
2528 genop(s
, MKOP_ABC(OP_SEND
, cursp(), sym
, argc
));
2529 mrb_gc_arena_restore(s
->mrb
, ai
);
2533 node
*n
= tree
->car
;
2536 if (nint(n
->car
->car
) != NODE_STR
) {
2537 codegen(s
, n
->car
, NOVAL
);
2546 int sym
= new_sym(s
, nsym(tree
));
2548 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), sym
));
2554 codegen(s
, tree
, val
);
2562 genop(s
, MKOP_A(OP_LOADSELF
, cursp()));
2569 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2576 genop(s
, MKOP_A(OP_LOADT
, cursp()));
2583 genop(s
, MKOP_A(OP_LOADF
, cursp()));
2590 int a
= new_msym(s
, nsym(tree
->car
));
2591 int b
= new_msym(s
, nsym(tree
->cdr
));
2592 int c
= new_msym(s
, mrb_intern_lit(s
->mrb
, "alias_method"));
2594 genop(s
, MKOP_A(OP_TCLASS
, cursp()));
2596 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), a
));
2598 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), b
));
2600 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2601 push(); /* space for a block */
2603 genop(s
, MKOP_ABC(OP_SEND
, cursp(), c
, 2));
2612 int undef
= new_msym(s
, mrb_intern_lit(s
->mrb
, "undef_method"));
2616 genop(s
, MKOP_A(OP_TCLASS
, cursp()));
2620 if (num
>= CALL_MAXARGS
- 1) {
2622 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), cursp(), num
));
2624 symbol
= new_msym(s
, nsym(t
->car
));
2626 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), symbol
));
2628 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), cursp()+1));
2634 symbol
= new_msym(s
, nsym(t
->car
));
2635 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), symbol
));
2640 push();pop(); /* space for a block */
2642 if (num
< CALL_MAXARGS
) {
2645 genop(s
, MKOP_ABC(OP_SEND
, cursp(), undef
, num
));
2656 if (tree
->car
->car
== (node
*)0) {
2657 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2660 else if (tree
->car
->car
== (node
*)1) {
2661 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
2665 codegen(s
, tree
->car
->car
, VAL
);
2667 if (tree
->cdr
->car
) {
2668 codegen(s
, tree
->cdr
->car
, VAL
);
2671 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2675 idx
= new_msym(s
, nsym(tree
->car
->cdr
));
2676 genop(s
, MKOP_AB(OP_CLASS
, cursp(), idx
));
2677 idx
= scope_body(s
, tree
->cdr
->cdr
->car
, val
);
2678 genop(s
, MKOP_ABx(OP_EXEC
, cursp(), idx
));
2689 if (tree
->car
->car
== (node
*)0) {
2690 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2693 else if (tree
->car
->car
== (node
*)1) {
2694 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
2698 codegen(s
, tree
->car
->car
, VAL
);
2701 idx
= new_msym(s
, nsym(tree
->car
->cdr
));
2702 genop(s
, MKOP_AB(OP_MODULE
, cursp(), idx
));
2703 idx
= scope_body(s
, tree
->cdr
->car
, val
);
2704 genop(s
, MKOP_ABx(OP_EXEC
, cursp(), idx
));
2715 codegen(s
, tree
->car
, VAL
);
2717 genop(s
, MKOP_AB(OP_SCLASS
, cursp(), cursp()));
2718 idx
= scope_body(s
, tree
->cdr
->car
, val
);
2719 genop(s
, MKOP_ABx(OP_EXEC
, cursp(), idx
));
2728 int sym
= new_msym(s
, nsym(tree
->car
));
2729 int idx
= lambda_body(s
, tree
->cdr
, 0);
2731 genop(s
, MKOP_A(OP_TCLASS
, cursp()));
2733 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), idx
, OP_L_METHOD
));
2736 genop(s
, MKOP_AB(OP_METHOD
, cursp(), sym
));
2738 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), sym
));
2746 node
*recv
= tree
->car
;
2747 int sym
= new_msym(s
, nsym(tree
->cdr
->car
));
2748 int idx
= lambda_body(s
, tree
->cdr
->cdr
, 0);
2750 codegen(s
, recv
, VAL
);
2752 genop(s
, MKOP_AB(OP_SCLASS
, cursp(), cursp()));
2754 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), idx
, OP_L_METHOD
));
2756 genop(s
, MKOP_AB(OP_METHOD
, cursp(), sym
));
2758 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), sym
));
2765 codegen(s
, tree
, NOVAL
);
2776 scope_add_irep(codegen_scope
*s
, mrb_irep
*irep
)
2778 if (s
->irep
== NULL
) {
2782 if (s
->irep
->rlen
== s
->rcapa
) {
2784 s
->irep
->reps
= (mrb_irep
**)codegen_realloc(s
, s
->irep
->reps
, sizeof(mrb_irep
*)*s
->rcapa
);
2786 s
->irep
->reps
[s
->irep
->rlen
] = irep
;
2790 static codegen_scope
*
2791 scope_new(mrb_state
*mrb
, codegen_scope
*prev
, node
*lv
)
2793 static const codegen_scope codegen_scope_zero
= { 0 };
2794 mrb_pool
*pool
= mrb_pool_open(mrb
);
2795 codegen_scope
*p
= (codegen_scope
*)mrb_pool_alloc(pool
, sizeof(codegen_scope
));
2797 if (!p
) return NULL
;
2798 *p
= codegen_scope_zero
;
2801 if (!prev
) return p
;
2806 p
->irep
= mrb_add_irep(mrb
);
2807 scope_add_irep(prev
, p
->irep
);
2810 p
->irep
->reps
= (mrb_irep
**)mrb_malloc(mrb
, sizeof(mrb_irep
*)*p
->rcapa
);
2813 p
->iseq
= (mrb_code
*)mrb_malloc(mrb
, sizeof(mrb_code
)*p
->icapa
);
2814 p
->irep
->iseq
= NULL
;
2817 p
->irep
->pool
= (mrb_value
*)mrb_malloc(mrb
, sizeof(mrb_value
)*p
->pcapa
);
2820 p
->scapa
= MAXMSYMLEN
;
2821 p
->irep
->syms
= (mrb_sym
*)mrb_malloc(mrb
, sizeof(mrb_sym
)*p
->scapa
);
2825 p
->sp
+= node_len(lv
)+1; /* add self */
2831 p
->irep
->lv
= (struct mrb_locals
*)mrb_malloc(mrb
, sizeof(struct mrb_locals
) * (p
->nlocals
- 1));
2832 for (i
=0, n
=lv
; n
; i
++,n
=n
->cdr
) {
2833 p
->irep
->lv
[i
].name
= lv_name(n
);
2835 p
->irep
->lv
[i
].r
= lv_idx(p
, lv_name(n
));
2838 p
->irep
->lv
[i
].r
= 0;
2841 mrb_assert(i
+ 1 == p
->nlocals
);
2843 p
->ai
= mrb_gc_arena_save(mrb
);
2845 p
->filename
= prev
->filename
;
2847 p
->lines
= (uint16_t*)mrb_malloc(mrb
, sizeof(short)*p
->icapa
);
2849 p
->lineno
= prev
->lineno
;
2852 p
->debug_start_pos
= 0;
2854 mrb_debug_info_alloc(mrb
, p
->irep
);
2855 p
->irep
->filename
= p
->filename
;
2856 p
->irep
->lines
= p
->lines
;
2859 p
->irep
->debug_info
= NULL
;
2861 p
->parser
= prev
->parser
;
2862 p
->filename_index
= prev
->filename_index
;
2864 p
->rlev
= prev
->rlev
+1;
2870 scope_finish(codegen_scope
*s
)
2872 mrb_state
*mrb
= s
->mrb
;
2873 mrb_irep
*irep
= s
->irep
;
2879 irep
->iseq
= (mrb_code
*)codegen_realloc(s
, s
->iseq
, sizeof(mrb_code
)*s
->pc
);
2882 irep
->lines
= (uint16_t *)codegen_realloc(s
, s
->lines
, sizeof(uint16_t)*s
->pc
);
2888 irep
->pool
= (mrb_value
*)codegen_realloc(s
, irep
->pool
, sizeof(mrb_value
)*irep
->plen
);
2889 irep
->syms
= (mrb_sym
*)codegen_realloc(s
, irep
->syms
, sizeof(mrb_sym
)*irep
->slen
);
2890 irep
->reps
= (mrb_irep
**)codegen_realloc(s
, irep
->reps
, sizeof(mrb_irep
*)*irep
->rlen
);
2892 irep
->filename
= mrb_parser_get_filename(s
->parser
, s
->filename_index
);
2893 mrb_debug_info_append_file(mrb
, irep
, s
->debug_start_pos
, s
->pc
);
2895 fname_len
= strlen(s
->filename
);
2896 fname
= (char*)codegen_malloc(s
, fname_len
+ 1);
2897 memcpy(fname
, s
->filename
, fname_len
);
2898 fname
[fname_len
] = '\0';
2899 irep
->filename
= fname
;
2900 irep
->own_filename
= TRUE
;
2903 irep
->nlocals
= s
->nlocals
;
2904 irep
->nregs
= s
->nregs
;
2906 mrb_gc_arena_restore(mrb
, s
->ai
);
2907 mrb_pool_close(s
->mpool
);
2910 static struct loopinfo
*
2911 loop_push(codegen_scope
*s
, enum looptype t
)
2913 struct loopinfo
*p
= (struct loopinfo
*)codegen_palloc(s
, sizeof(struct loopinfo
));
2916 p
->pc1
= p
->pc2
= p
->pc3
= 0;
2918 p
->ensure_level
= s
->ensure_level
;
2926 loop_break(codegen_scope
*s
, node
*tree
)
2929 codegen(s
, tree
, NOVAL
);
2930 raise_error(s
, "unexpected break");
2933 struct loopinfo
*loop
;
2937 gen_retval(s
, tree
);
2942 if (loop
->type
== LOOP_BEGIN
) {
2946 else if (loop
->type
== LOOP_RESCUE
) {
2954 raise_error(s
, "unexpected break");
2958 genop_peep(s
, MKOP_A(OP_POPERR
, n
), NOVAL
);
2961 if (loop
->type
== LOOP_NORMAL
) {
2964 if (s
->ensure_level
> s
->loop
->ensure_level
) {
2965 genop_peep(s
, MKOP_A(OP_EPOP
, s
->ensure_level
- s
->loop
->ensure_level
), NOVAL
);
2968 genop_peep(s
, MKOP_AB(OP_MOVE
, loop
->acc
, cursp()), NOVAL
);
2970 tmp
= genop(s
, MKOP_sBx(OP_JMP
, loop
->pc3
));
2975 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2977 genop(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_BREAK
));
2983 loop_pop(codegen_scope
*s
, int val
)
2986 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2988 dispatch_linked(s
, s
->loop
->pc3
);
2989 s
->loop
= s
->loop
->prev
;
2993 MRB_API
struct RProc
*
2994 mrb_generate_code(mrb_state
*mrb
, parser_state
*p
)
2996 codegen_scope
*scope
= scope_new(mrb
, 0, 0);
2998 struct mrb_jmpbuf
*prev_jmp
= mrb
->jmp
;
3005 scope
->filename
= p
->filename
;
3006 scope
->filename_index
= p
->current_filename_index
;
3008 MRB_TRY(&scope
->jmp
) {
3009 mrb
->jmp
= &scope
->jmp
;
3011 codegen(scope
, p
->tree
, NOVAL
);
3012 proc
= mrb_proc_new(mrb
, scope
->irep
);
3013 mrb_irep_decref(mrb
, scope
->irep
);
3014 mrb_pool_close(scope
->mpool
);
3016 mrb
->jmp
= prev_jmp
;
3019 MRB_CATCH(&scope
->jmp
) {
3020 mrb_irep_decref(mrb
, scope
->irep
);
3021 mrb_pool_close(scope
->mpool
);
3022 mrb
->jmp
= prev_jmp
;
3025 MRB_END_EXC(&scope
->jmp
);