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
));
635 idx
= new_msym(s
, mrb_intern_lit(s
->mrb
, "each"));
636 genop(s
, MKOP_ABC(OP_SENDB
, cursp(), idx
, 0));
640 lambda_body(codegen_scope
*s
, node
*tree
, int blk
)
643 codegen_scope
*parent
= s
;
644 s
= scope_new(s
->mrb
, s
, tree
->car
);
646 raise_error(parent
, "unexpected scope");
652 struct loopinfo
*lp
= loop_push(s
, LOOP_BLOCK
);
653 lp
->pc1
= new_label(s
);
658 int ma
, oa
, ra
, pa
, ka
, kd
, ba
;
662 ma
= node_len(tree
->car
->car
);
667 oa
= node_len(tree
->car
->cdr
->car
);
668 ra
= tree
->car
->cdr
->cdr
->car
? 1 : 0;
669 pa
= node_len(tree
->car
->cdr
->cdr
->cdr
->car
);
671 ba
= tree
->car
->cdr
->cdr
->cdr
->cdr
? 1 : 0;
673 if (ma
> 0x1f || oa
> 0x1f || pa
> 0x1f || ka
> 0x1f) {
674 codegen_error(s
, "too many formal arguments");
676 a
= ((mrb_aspec
)(ma
& 0x1f) << 18)
677 | ((mrb_aspec
)(oa
& 0x1f) << 13)
683 s
->ainfo
= (((ma
+oa
) & 0x3f) << 6) /* (12bits = 6:1:5) */
686 genop(s
, MKOP_Ax(OP_ENTER
, a
));
688 for (i
=0; i
<oa
; i
++) {
690 genop(s
, MKOP_sBx(OP_JMP
, 0));
693 genop(s
, MKOP_sBx(OP_JMP
, 0));
695 opt
= tree
->car
->cdr
->car
;
701 codegen(s
, opt
->car
->cdr
, VAL
);
702 idx
= lv_idx(s
, nsym(opt
->car
->car
));
704 genop_peep(s
, MKOP_AB(OP_MOVE
, idx
, cursp()), NOVAL
);
712 codegen(s
, tree
->cdr
->car
, VAL
);
715 c
= s
->iseq
[s
->pc
-1];
716 if (GET_OPCODE(c
) != OP_RETURN
|| GETARG_B(c
) != OP_R_NORMAL
|| s
->pc
== s
->lastlabel
) {
718 genop(s
, MKOP_A(OP_LOADNIL
, 0));
719 genop(s
, MKOP_AB(OP_RETURN
, 0, OP_R_NORMAL
));
722 genop_peep(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_NORMAL
), NOVAL
);
730 return parent
->irep
->rlen
- 1;
734 scope_body(codegen_scope
*s
, node
*tree
, int val
)
736 codegen_scope
*scope
= scope_new(s
->mrb
, s
, tree
->car
);
738 raise_error(s
, "unexpected scope");
741 codegen(scope
, tree
->cdr
, VAL
);
743 genop(scope
, MKOP_A(OP_STOP
, 0));
746 genop(scope
, MKOP_AB(OP_RETURN
, 0, OP_R_NORMAL
));
749 if (scope
->nregs
== 0) {
750 genop(scope
, MKOP_A(OP_LOADNIL
, 0));
751 genop(scope
, MKOP_AB(OP_RETURN
, 0, OP_R_NORMAL
));
754 genop_peep(scope
, MKOP_AB(OP_RETURN
, scope
->sp
-1, OP_R_NORMAL
), NOVAL
);
759 /* should not happen */
762 return s
->irep
->rlen
- 1;
765 #define nint(x) ((int)(intptr_t)(x))
766 #define nchar(x) ((char)(intptr_t)(x))
772 if (nint(t
->car
->car
) == NODE_SPLAT
) return FALSE
;
779 attrsym(codegen_scope
*s
, mrb_sym a
)
785 name
= mrb_sym2name_len(s
->mrb
, a
, &len
);
786 name2
= (char *)codegen_palloc(s
,
791 mrb_assert_int_fit(mrb_int
, len
, size_t, SIZE_MAX
);
792 memcpy(name2
, name
, (size_t)len
);
796 return mrb_intern(s
->mrb
, name2
, len
+1);
799 #define CALL_MAXARGS 127
802 gen_values(codegen_scope
*s
, node
*t
, int val
, int extra
)
808 is_splat
= nint(t
->car
->car
) == NODE_SPLAT
; /* splat mode */
810 n
+extra
>= CALL_MAXARGS
- 1 /* need to subtract one because vm.c expects an array if n == CALL_MAXARGS */
813 if (is_splat
&& n
== 0 && nint(t
->car
->cdr
->car
) == NODE_ARRAY
) {
814 codegen(s
, t
->car
->cdr
, VAL
);
819 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), cursp(), n
));
821 codegen(s
, t
->car
, VAL
);
824 genop(s
, MKOP_AB(OP_ARYCAT
, cursp(), cursp()+1));
827 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), cursp()+1));
833 codegen(s
, t
->car
, VAL
);
835 if (nint(t
->car
->car
) == NODE_SPLAT
) {
836 genop(s
, MKOP_AB(OP_ARYCAT
, cursp(), cursp()+1));
839 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), cursp()+1));
846 codegen(s
, t
->car
, NOVAL
);
852 /* normal (no splat) mode */
853 codegen(s
, t
->car
, val
);
861 gen_call(codegen_scope
*s
, node
*tree
, mrb_sym name
, int sp
, int val
, int safe
)
863 mrb_sym sym
= name
? name
: nsym(tree
->cdr
->car
);
865 int n
= 0, noop
= 0, sendv
= 0, blk
= 0;
867 codegen(s
, tree
->car
, VAL
); /* receiver */
869 int recv
= cursp()-1;
870 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
872 genop(s
, MKOP_AB(OP_MOVE
, cursp(), recv
));
873 push_n(2); pop_n(2); /* space for one arg and a block */
875 idx
= new_msym(s
, mrb_intern_lit(s
->mrb
, "=="));
876 genop(s
, MKOP_ABC(OP_EQ
, cursp(), idx
, 1));
877 skip
= genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), 0));
879 idx
= new_msym(s
, sym
);
880 tree
= tree
->cdr
->cdr
->car
;
882 n
= gen_values(s
, tree
->car
, VAL
, sp
?1:0);
884 n
= noop
= sendv
= 1;
891 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), sp
));
895 genop(s
, MKOP_AB(OP_MOVE
, cursp(), sp
));
900 if (tree
&& tree
->cdr
) {
902 codegen(s
, tree
->cdr
, VAL
);
912 const char *symname
= mrb_sym2name_len(s
->mrb
, sym
, &symlen
);
914 if (!noop
&& symlen
== 1 && symname
[0] == '+' && n
== 1) {
915 genop_peep(s
, MKOP_ABC(OP_ADD
, cursp(), idx
, n
), val
);
917 else if (!noop
&& symlen
== 1 && symname
[0] == '-' && n
== 1) {
918 genop_peep(s
, MKOP_ABC(OP_SUB
, cursp(), idx
, n
), val
);
920 else if (!noop
&& symlen
== 1 && symname
[0] == '*' && n
== 1) {
921 genop(s
, MKOP_ABC(OP_MUL
, cursp(), idx
, n
));
923 else if (!noop
&& symlen
== 1 && symname
[0] == '/' && n
== 1) {
924 genop(s
, MKOP_ABC(OP_DIV
, cursp(), idx
, n
));
926 else if (!noop
&& symlen
== 1 && symname
[0] == '<' && n
== 1) {
927 genop(s
, MKOP_ABC(OP_LT
, cursp(), idx
, n
));
929 else if (!noop
&& symlen
== 2 && symname
[0] == '<' && symname
[1] == '=' && n
== 1) {
930 genop(s
, MKOP_ABC(OP_LE
, cursp(), idx
, n
));
932 else if (!noop
&& symlen
== 1 && symname
[0] == '>' && n
== 1) {
933 genop(s
, MKOP_ABC(OP_GT
, cursp(), idx
, n
));
935 else if (!noop
&& symlen
== 2 && symname
[0] == '>' && symname
[1] == '=' && n
== 1) {
936 genop(s
, MKOP_ABC(OP_GE
, cursp(), idx
, n
));
938 else if (!noop
&& symlen
== 2 && symname
[0] == '=' && symname
[1] == '=' && n
== 1) {
939 genop(s
, MKOP_ABC(OP_EQ
, cursp(), idx
, n
));
942 if (sendv
) n
= CALL_MAXARGS
;
943 if (blk
> 0) { /* no block */
944 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, n
));
947 genop(s
, MKOP_ABC(OP_SENDB
, cursp(), idx
, n
));
960 gen_assignment(codegen_scope
*s
, node
*tree
, int sp
, int val
)
963 int type
= nint(tree
->car
);
968 idx
= new_sym(s
, nsym(tree
));
969 genop_peep(s
, MKOP_ABx(OP_SETGLOBAL
, sp
, idx
), val
);
972 idx
= lv_idx(s
, nsym(tree
));
975 genop_peep(s
, MKOP_AB(OP_MOVE
, idx
, sp
), val
);
981 codegen_scope
*up
= s
->prev
;
984 idx
= lv_idx(up
, nsym(tree
));
986 genop_peep(s
, MKOP_ABC(OP_SETUPVAR
, sp
, idx
, lv
), val
);
995 idx
= new_sym(s
, nsym(tree
));
996 genop_peep(s
, MKOP_ABx(OP_SETIV
, sp
, idx
), val
);
999 idx
= new_sym(s
, nsym(tree
));
1000 genop_peep(s
, MKOP_ABx(OP_SETCV
, sp
, idx
), val
);
1003 idx
= new_sym(s
, nsym(tree
));
1004 genop_peep(s
, MKOP_ABx(OP_SETCONST
, sp
, idx
), val
);
1007 idx
= new_sym(s
, nsym(tree
->cdr
));
1008 genop_peep(s
, MKOP_AB(OP_MOVE
, cursp(), sp
), NOVAL
);
1010 codegen(s
, tree
->car
, VAL
);
1012 genop_peep(s
, MKOP_ABx(OP_SETMCNST
, cursp(), idx
), val
);
1018 gen_call(s
, tree
, attrsym(s
, nsym(tree
->cdr
->car
)), sp
, NOVAL
,
1019 type
== NODE_SCALL
);
1022 genop_peep(s
, MKOP_AB(OP_MOVE
, cursp(), sp
), val
);
1027 gen_vmassignment(s
, tree
->car
, sp
, val
);
1030 /* splat without assignment */
1035 #ifndef MRB_DISABLE_STDIO
1036 fprintf(stderr
, "unknown lhs %d\n", type
);
1044 gen_vmassignment(codegen_scope
*s
, node
*tree
, int rhs
, int val
)
1046 int n
= 0, post
= 0;
1049 if (tree
->car
) { /* pre */
1053 genop(s
, MKOP_ABC(OP_AREF
, cursp(), rhs
, n
));
1054 gen_assignment(s
, t
->car
, cursp(), NOVAL
);
1061 if (t
->cdr
) { /* post count */
1069 genop(s
, MKOP_AB(OP_MOVE
, cursp(), rhs
));
1076 genop(s
, MKOP_ABC(OP_APOST
, cursp(), n
, post
));
1078 if (t
->car
) { /* rest */
1079 gen_assignment(s
, t
->car
, cursp(), NOVAL
);
1081 if (t
->cdr
&& t
->cdr
->car
) {
1084 gen_assignment(s
, t
->car
, cursp()+n
, NOVAL
);
1096 gen_send_intern(codegen_scope
*s
)
1099 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "intern")), 0));
1103 gen_literal_array(codegen_scope
*s
, node
*tree
, mrb_bool sym
, int val
)
1109 switch (nint(tree
->car
->car
)) {
1111 if ((tree
->cdr
== NULL
) && (nint(tree
->car
->cdr
->cdr
) == 0))
1115 codegen(s
, tree
->car
, VAL
);
1119 case NODE_LITERAL_DELIM
:
1130 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
1142 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), cursp(), i
));
1147 switch (nint(tree
->car
->car
)) {
1148 case NODE_BEGIN
: case NODE_BLOCK
:
1149 codegen(s
, tree
->car
, NOVAL
);
1157 raise_error(codegen_scope
*s
, const char *msg
)
1159 int idx
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, msg
));
1161 genop(s
, MKOP_ABx(OP_ERR
, 1, idx
));
1165 readint_float(codegen_scope
*s
, const char *p
, int base
)
1167 const char *e
= p
+ strlen(p
);
1174 c
= tolower((unsigned char)c
);
1175 for (n
=0; n
<base
; n
++) {
1176 if (mrb_digitmap
[n
] == c
) {
1183 codegen_error(s
, "malformed readint input");
1191 readint_mrb_int(codegen_scope
*s
, const char *p
, int base
, mrb_bool neg
, mrb_bool
*overflow
)
1193 const char *e
= p
+ strlen(p
);
1197 mrb_assert(base
>= 2 && base
<= 36);
1201 c
= tolower((unsigned char)c
);
1202 for (n
=0; n
<base
; n
++) {
1203 if (mrb_digitmap
[n
] == c
) {
1208 codegen_error(s
, "malformed readint input");
1212 if ((MRB_INT_MIN
+ n
)/base
> result
) {
1220 if ((MRB_INT_MAX
- n
)/base
< result
) {
1234 gen_retval(codegen_scope
*s
, node
*tree
)
1236 if (nint(tree
->car
) == NODE_SPLAT
) {
1237 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), cursp(), 0));
1239 codegen(s
, tree
, VAL
);
1241 genop(s
, MKOP_AB(OP_ARYCAT
, cursp(), cursp()+1));
1244 codegen(s
, tree
, VAL
);
1250 codegen(codegen_scope
*s
, node
*tree
, int val
)
1257 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1264 if (s
->rlev
> MRB_CODEGEN_LEVEL_MAX
) {
1265 codegen_error(s
, "too complex expression");
1267 if (s
->irep
&& s
->filename_index
!= tree
->filename_index
) {
1268 s
->irep
->filename
= mrb_parser_get_filename(s
->parser
, s
->filename_index
);
1269 mrb_debug_info_append_file(s
->mrb
, s
->irep
, s
->debug_start_pos
, s
->pc
);
1270 s
->debug_start_pos
= s
->pc
;
1271 s
->filename_index
= tree
->filename_index
;
1272 s
->filename
= mrb_parser_get_filename(s
->parser
, tree
->filename_index
);
1275 nt
= nint(tree
->car
);
1276 s
->lineno
= tree
->lineno
;
1281 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1285 codegen(s
, tree
->car
, tree
->cdr
? NOVAL
: val
);
1292 int onerr
, noexc
, exend
, pos1
, pos2
, tmp
;
1293 struct loopinfo
*lp
;
1295 if (tree
->car
== NULL
) goto exit
;
1296 onerr
= genop(s
, MKOP_Bx(OP_ONERR
, 0));
1297 lp
= loop_push(s
, LOOP_BEGIN
);
1299 codegen(s
, tree
->car
, VAL
);
1301 lp
->type
= LOOP_RESCUE
;
1302 noexc
= genop(s
, MKOP_Bx(OP_JMP
, 0));
1308 node
*n2
= tree
->car
;
1311 genop(s
, MKOP_ABC(OP_RESCUE
, exc
, 0, 0));
1317 if (pos1
) dispatch(s
, pos1
);
1320 if (n4
&& n4
->car
&& nint(n4
->car
->car
) == NODE_SPLAT
) {
1321 codegen(s
, n4
->car
, VAL
);
1322 genop(s
, MKOP_AB(OP_MOVE
, cursp(), exc
));
1323 push_n(2); pop_n(3);
1324 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "__case_eqq")), 1));
1328 codegen(s
, n4
->car
, VAL
);
1331 genop(s
, MKOP_ABx(OP_GETCONST
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "StandardError"))));
1335 genop(s
, MKOP_ABC(OP_RESCUE
, exc
, cursp(), 1));
1337 tmp
= genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), pos2
));
1343 pos1
= genop(s
, MKOP_sBx(OP_JMP
, 0));
1344 dispatch_linked(s
, pos2
);
1348 gen_assignment(s
, n3
->cdr
->car
, exc
, NOVAL
);
1350 if (n3
->cdr
->cdr
->car
) {
1351 codegen(s
, n3
->cdr
->cdr
->car
, val
);
1354 tmp
= genop(s
, MKOP_sBx(OP_JMP
, exend
));
1361 genop(s
, MKOP_A(OP_RAISE
, exc
));
1367 genop(s
, MKOP_A(OP_POPERR
, 1));
1369 codegen(s
, tree
->car
, val
);
1374 dispatch_linked(s
, exend
);
1380 if (!tree
->cdr
|| !tree
->cdr
->cdr
||
1381 (nint(tree
->cdr
->cdr
->car
) == NODE_BEGIN
&&
1382 tree
->cdr
->cdr
->cdr
)) {
1386 genop(s
, MKOP_Bx(OP_EPUSH
, 0));
1388 codegen(s
, tree
->car
, val
);
1389 idx
= scope_body(s
, tree
->cdr
, NOVAL
);
1390 s
->iseq
[epush
] = MKOP_Bx(OP_EPUSH
, idx
);
1392 genop_peep(s
, MKOP_A(OP_EPOP
, 1), NOVAL
);
1394 else { /* empty ensure ignored */
1395 codegen(s
, tree
->car
, val
);
1401 int idx
= lambda_body(s
, tree
, 1);
1403 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), idx
, OP_L_LAMBDA
));
1410 int idx
= lambda_body(s
, tree
, 1);
1412 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), idx
, OP_L_BLOCK
));
1420 node
*e
= tree
->cdr
->cdr
->car
;
1426 switch (nint(tree
->car
->car
)) {
1430 codegen(s
, tree
->cdr
->car
, val
);
1437 codegen(s
, tree
->car
, VAL
);
1439 pos1
= genop_peep(s
, MKOP_AsBx(OP_JMPNOT
, cursp(), 0), NOVAL
);
1441 codegen(s
, tree
->cdr
->car
, val
);
1444 pos2
= genop(s
, MKOP_sBx(OP_JMP
, 0));
1452 pos2
= genop(s
, MKOP_sBx(OP_JMP
, 0));
1454 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1469 codegen(s
, tree
->car
, VAL
);
1471 pos
= genop(s
, MKOP_AsBx(OP_JMPNOT
, cursp(), 0));
1472 codegen(s
, tree
->cdr
, val
);
1481 codegen(s
, tree
->car
, VAL
);
1483 pos
= genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), 0));
1484 codegen(s
, tree
->cdr
, val
);
1491 struct loopinfo
*lp
= loop_push(s
, LOOP_NORMAL
);
1493 lp
->pc1
= genop(s
, MKOP_sBx(OP_JMP
, 0));
1494 lp
->pc2
= new_label(s
);
1495 codegen(s
, tree
->cdr
, NOVAL
);
1496 dispatch(s
, lp
->pc1
);
1497 codegen(s
, tree
->car
, VAL
);
1499 genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), lp
->pc2
- s
->pc
));
1507 struct loopinfo
*lp
= loop_push(s
, LOOP_NORMAL
);
1509 lp
->pc1
= genop(s
, MKOP_sBx(OP_JMP
, 0));
1510 lp
->pc2
= new_label(s
);
1511 codegen(s
, tree
->cdr
, NOVAL
);
1512 dispatch(s
, lp
->pc1
);
1513 codegen(s
, tree
->car
, VAL
);
1515 genop(s
, MKOP_AsBx(OP_JMPNOT
, cursp(), lp
->pc2
- s
->pc
));
1529 int pos1
, pos2
, pos3
, tmp
;
1535 codegen(s
, tree
->car
, VAL
);
1542 codegen(s
, n
->car
, VAL
);
1544 genop(s
, MKOP_AB(OP_MOVE
, cursp(), head
));
1545 push_n(2); pop_n(2); /* space for one arg and a block */
1547 if (nint(n
->car
->car
) == NODE_SPLAT
) {
1548 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "__case_eqq")), 1));
1551 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "===")), 1));
1557 tmp
= genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), pos2
));
1561 if (tree
->car
->car
) {
1562 pos1
= genop(s
, MKOP_sBx(OP_JMP
, 0));
1563 dispatch_linked(s
, pos2
);
1565 codegen(s
, tree
->car
->cdr
, val
);
1567 tmp
= genop(s
, MKOP_sBx(OP_JMP
, pos3
));
1569 if (pos1
) dispatch(s
, pos1
);
1574 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1575 if (pos3
) dispatch_linked(s
, pos3
);
1577 if (cursp() != pos
) {
1578 genop(s
, MKOP_AB(OP_MOVE
, cursp(), pos
));
1584 dispatch_linked(s
, pos3
);
1594 scope_body(s
, tree
, NOVAL
);
1599 gen_call(s
, tree
, 0, 0, val
, 0);
1602 gen_call(s
, tree
, 0, 0, val
, 1);
1606 codegen(s
, tree
->car
, val
);
1607 codegen(s
, tree
->cdr
, val
);
1610 genop(s
, MKOP_ABC(OP_RANGE
, cursp(), cursp(), FALSE
));
1616 codegen(s
, tree
->car
, val
);
1617 codegen(s
, tree
->cdr
, val
);
1620 genop(s
, MKOP_ABC(OP_RANGE
, cursp(), cursp(), TRUE
));
1627 int sym
= new_sym(s
, nsym(tree
->cdr
));
1629 codegen(s
, tree
->car
, VAL
);
1631 genop(s
, MKOP_ABx(OP_GETMCNST
, cursp(), sym
));
1638 int sym
= new_sym(s
, nsym(tree
));
1640 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
1641 genop(s
, MKOP_ABx(OP_GETMCNST
, cursp(), sym
));
1650 n
= gen_values(s
, tree
, val
, 0);
1654 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), cursp(), n
));
1667 mrb_bool update
= FALSE
;
1670 codegen(s
, tree
->car
->car
, val
);
1671 codegen(s
, tree
->car
->cdr
, val
);
1674 if (val
&& len
== 126) {
1676 genop(s
, MKOP_ABC(OP_HASH
, cursp(), cursp(), len
));
1679 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "__update")), 1));
1688 genop(s
, MKOP_ABC(OP_HASH
, cursp(), cursp(), len
));
1691 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "__update")), 1));
1699 codegen(s
, tree
, val
);
1703 codegen(s
, tree
->cdr
, VAL
);
1705 gen_assignment(s
, tree
->car
, cursp(), val
);
1710 int len
= 0, n
= 0, post
= 0;
1711 node
*t
= tree
->cdr
, *p
;
1714 if (nint(t
->car
) == NODE_ARRAY
&& t
->cdr
&& nosplat(t
->cdr
)) {
1718 codegen(s
, t
->car
, VAL
);
1723 if (tree
->car
) { /* pre */
1728 gen_assignment(s
, t
->car
, rhs
+n
, NOVAL
);
1732 genop(s
, MKOP_A(OP_LOADNIL
, rhs
+n
));
1733 gen_assignment(s
, t
->car
, rhs
+n
, NOVAL
);
1740 if (t
->cdr
) { /* post count */
1747 if (t
->car
) { /* rest (len - pre - post) */
1750 if (len
< post
+ n
) {
1754 rn
= len
- post
- n
;
1756 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), rhs
+n
, rn
));
1757 gen_assignment(s
, t
->car
, cursp(), NOVAL
);
1760 if (t
->cdr
&& t
->cdr
->car
) {
1763 gen_assignment(s
, t
->car
, rhs
+n
, NOVAL
);
1771 genop(s
, MKOP_ABC(OP_ARRAY
, rhs
, rhs
, len
));
1778 gen_vmassignment(s
, tree
->car
, rhs
, val
);
1788 mrb_sym sym
= nsym(tree
->cdr
->car
);
1790 const char *name
= mrb_sym2name_len(s
->mrb
, sym
, &len
);
1791 int idx
, callargs
= -1, vsp
= -1;
1793 if ((len
== 2 && name
[0] == '|' && name
[1] == '|') &&
1794 (nint(tree
->car
->car
) == NODE_CONST
||
1795 nint(tree
->car
->car
) == NODE_CVAR
)) {
1796 int onerr
, noexc
, exc
;
1797 struct loopinfo
*lp
;
1799 onerr
= genop(s
, MKOP_Bx(OP_ONERR
, 0));
1800 lp
= loop_push(s
, LOOP_BEGIN
);
1803 codegen(s
, tree
->car
, VAL
);
1804 lp
->type
= LOOP_RESCUE
;
1805 genop(s
, MKOP_A(OP_POPERR
, 1));
1806 noexc
= genop(s
, MKOP_Bx(OP_JMP
, 0));
1808 genop(s
, MKOP_ABC(OP_RESCUE
, exc
, 0, 0));
1809 genop(s
, MKOP_A(OP_LOADF
, exc
));
1813 else if (nint(tree
->car
->car
) == NODE_CALL
) {
1814 node
*n
= tree
->car
->cdr
;
1820 codegen(s
, n
->car
, VAL
); /* receiver */
1821 idx
= new_msym(s
, nsym(n
->cdr
->car
));
1822 if (n
->cdr
->cdr
->car
) {
1823 int base
= cursp()-1;
1824 int nargs
= gen_values(s
, n
->cdr
->cdr
->car
->car
, VAL
, 1);
1826 /* copy receiver and arguments */
1830 genop(s
, MKOP_AB(OP_MOVE
, cursp(), base
));
1831 for (i
=0; i
<nargs
; i
++) {
1832 genop(s
, MKOP_AB(OP_MOVE
, cursp()+i
+1, base
+i
+1));
1841 genop(s
, MKOP_AB(OP_MOVE
, cursp(), base
));
1842 genop(s
, MKOP_AB(OP_MOVE
, cursp()+1, base
+1));
1843 callargs
= CALL_MAXARGS
;
1845 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, callargs
));
1848 genop(s
, MKOP_AB(OP_MOVE
, cursp(), cursp()-1));
1849 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, 0));
1855 codegen(s
, tree
->car
, VAL
);
1858 ((name
[0] == '|' && name
[1] == '|') ||
1859 (name
[0] == '&' && name
[1] == '&'))) {
1865 genop(s
, MKOP_AB(OP_MOVE
, vsp
, cursp()));
1867 pos
= genop(s
, MKOP_AsBx(name
[0]=='|'?OP_JMPIF
:OP_JMPNOT
, cursp(), 0));
1870 pos
= genop_peep(s
, MKOP_AsBx(name
[0]=='|'?OP_JMPIF
:OP_JMPNOT
, cursp(), 0), NOVAL
);
1872 codegen(s
, tree
->cdr
->cdr
->car
, VAL
);
1874 if (val
&& vsp
>= 0) {
1875 genop(s
, MKOP_AB(OP_MOVE
, vsp
, cursp()));
1877 if (nint(tree
->car
->car
) == NODE_CALL
) {
1878 mrb_sym m
= nsym(tree
->car
->cdr
->cdr
->car
);
1879 mrb_sym m2
= attrsym(s
, m
);
1881 idx
= new_msym(s
, m2
);
1883 if (callargs
== CALL_MAXARGS
) {
1884 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), cursp()+1));
1886 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, callargs
));
1890 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, callargs
+1));
1894 gen_assignment(s
, tree
->car
, cursp(), val
);
1899 codegen(s
, tree
->cdr
->cdr
->car
, VAL
);
1903 idx
= new_msym(s
, sym
);
1904 if (len
== 1 && name
[0] == '+') {
1905 genop_peep(s
, MKOP_ABC(OP_ADD
, cursp(), idx
, 1), val
);
1907 else if (len
== 1 && name
[0] == '-') {
1908 genop_peep(s
, MKOP_ABC(OP_SUB
, cursp(), idx
, 1), val
);
1910 else if (len
== 1 && name
[0] == '*') {
1911 genop(s
, MKOP_ABC(OP_MUL
, cursp(), idx
, 1));
1913 else if (len
== 1 && name
[0] == '/') {
1914 genop(s
, MKOP_ABC(OP_DIV
, cursp(), idx
, 1));
1916 else if (len
== 1 && name
[0] == '<') {
1917 genop(s
, MKOP_ABC(OP_LT
, cursp(), idx
, 1));
1919 else if (len
== 2 && name
[0] == '<' && name
[1] == '=') {
1920 genop(s
, MKOP_ABC(OP_LE
, cursp(), idx
, 1));
1922 else if (len
== 1 && name
[0] == '>') {
1923 genop(s
, MKOP_ABC(OP_GT
, cursp(), idx
, 1));
1925 else if (len
== 2 && name
[0] == '>' && name
[1] == '=') {
1926 genop(s
, MKOP_ABC(OP_GE
, cursp(), idx
, 1));
1929 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, 1));
1932 gen_assignment(s
, tree
->car
, cursp(), val
);
1935 if (val
&& vsp
>= 0) {
1936 genop(s
, MKOP_AB(OP_MOVE
, vsp
, cursp()));
1938 if (callargs
== CALL_MAXARGS
) {
1940 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), cursp()+1));
1947 idx
= new_msym(s
, attrsym(s
,nsym(tree
->car
->cdr
->cdr
->car
)));
1948 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, callargs
));
1955 codegen_scope
*s2
= s
;
1957 int n
= 0, noop
= 0, sendv
= 0;
1959 push(); /* room for receiver */
1960 while (!s2
->mscope
) {
1965 genop(s
, MKOP_ABx(OP_ARGARY
, cursp(), (lv
& 0xf)));
1966 push(); push(); /* ARGARY pushes two values */
1969 node
*args
= tree
->car
;
1971 n
= gen_values(s
, args
, VAL
, 0);
1973 n
= noop
= sendv
= 1;
1978 if (tree
&& tree
->cdr
) {
1979 codegen(s
, tree
->cdr
, VAL
);
1983 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1987 if (sendv
) n
= CALL_MAXARGS
;
1988 genop(s
, MKOP_ABC(OP_SUPER
, cursp(), 0, n
));
1995 codegen_scope
*s2
= s
;
1996 int lv
= 0, ainfo
= 0;
1998 push(); /* room for receiver */
1999 while (!s2
->mscope
) {
2004 if (s2
) ainfo
= s2
->ainfo
;
2005 genop(s
, MKOP_ABx(OP_ARGARY
, cursp(), (ainfo
<<4)|(lv
& 0xf)));
2006 push(); push(); pop(); /* ARGARY pushes two values */
2007 if (tree
&& tree
->cdr
) {
2008 codegen(s
, tree
->cdr
, VAL
);
2012 genop(s
, MKOP_ABC(OP_SUPER
, cursp(), 0, CALL_MAXARGS
));
2019 gen_retval(s
, tree
);
2022 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2025 genop(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_RETURN
));
2028 genop_peep(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_NORMAL
), NOVAL
);
2035 codegen_scope
*s2
= s
;
2036 int lv
= 0, ainfo
= 0;
2037 int n
= 0, sendv
= 0;
2039 while (!s2
->mscope
) {
2044 if (s2
) ainfo
= s2
->ainfo
;
2047 n
= gen_values(s
, tree
, VAL
, 0);
2053 push();pop(); /* space for a block */
2055 genop(s
, MKOP_ABx(OP_BLKPUSH
, cursp(), (ainfo
<<4)|(lv
& 0xf)));
2056 if (sendv
) n
= CALL_MAXARGS
;
2057 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "call")), n
));
2063 loop_break(s
, tree
);
2069 raise_error(s
, "unexpected next");
2071 else if (s
->loop
->type
== LOOP_NORMAL
) {
2072 if (s
->ensure_level
> s
->loop
->ensure_level
) {
2073 genop_peep(s
, MKOP_A(OP_EPOP
, s
->ensure_level
- s
->loop
->ensure_level
), NOVAL
);
2075 codegen(s
, tree
, NOVAL
);
2076 genop(s
, MKOP_sBx(OP_JMP
, s
->loop
->pc1
- s
->pc
));
2080 codegen(s
, tree
, VAL
);
2084 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2086 genop_peep(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_NORMAL
), NOVAL
);
2092 if (!s
->loop
|| s
->loop
->type
== LOOP_BEGIN
|| s
->loop
->type
== LOOP_RESCUE
) {
2093 raise_error(s
, "unexpected redo");
2096 if (s
->ensure_level
> s
->loop
->ensure_level
) {
2097 genop_peep(s
, MKOP_A(OP_EPOP
, s
->ensure_level
- s
->loop
->ensure_level
), NOVAL
);
2099 genop(s
, MKOP_sBx(OP_JMP
, s
->loop
->pc2
- s
->pc
));
2106 const char *msg
= "unexpected retry";
2109 raise_error(s
, msg
);
2112 struct loopinfo
*lp
= s
->loop
;
2115 while (lp
&& lp
->type
!= LOOP_RESCUE
) {
2116 if (lp
->type
== LOOP_BEGIN
) {
2122 raise_error(s
, msg
);
2126 genop_peep(s
, MKOP_A(OP_POPERR
, n
), NOVAL
);
2128 if (s
->ensure_level
> lp
->ensure_level
) {
2129 genop_peep(s
, MKOP_A(OP_EPOP
, s
->ensure_level
- lp
->ensure_level
), NOVAL
);
2131 genop(s
, MKOP_sBx(OP_JMP
, lp
->pc1
- s
->pc
));
2140 int idx
= lv_idx(s
, nsym(tree
));
2143 genop_peep(s
, MKOP_AB(OP_MOVE
, cursp(), idx
), NOVAL
);
2147 codegen_scope
*up
= s
->prev
;
2150 idx
= lv_idx(up
, nsym(tree
));
2152 genop(s
, MKOP_ABC(OP_GETUPVAR
, cursp(), idx
, lv
));
2165 int sym
= new_sym(s
, nsym(tree
));
2167 genop(s
, MKOP_ABx(OP_GETGLOBAL
, cursp(), sym
));
2174 int sym
= new_sym(s
, nsym(tree
));
2176 genop(s
, MKOP_ABx(OP_GETIV
, cursp(), sym
));
2183 int sym
= new_sym(s
, nsym(tree
));
2185 genop(s
, MKOP_ABx(OP_GETCV
, cursp(), sym
));
2192 int sym
= new_sym(s
, nsym(tree
));
2194 genop(s
, MKOP_ABx(OP_GETCONST
, cursp(), sym
));
2202 codegen(s
, tree
, VAL
);
2211 buf
[1] = nchar(tree
);
2213 sym
= new_sym(s
, mrb_intern_cstr(s
->mrb
, buf
));
2214 genop(s
, MKOP_ABx(OP_GETGLOBAL
, cursp(), sym
));
2221 mrb_state
*mrb
= s
->mrb
;
2225 str
= mrb_format(mrb
, "$%S", mrb_fixnum_value(nint(tree
)));
2226 sym
= new_sym(s
, mrb_intern_str(mrb
, str
));
2227 genop(s
, MKOP_ABx(OP_GETGLOBAL
, cursp(), sym
));
2233 /* should not happen */
2236 case NODE_BLOCK_ARG
:
2237 codegen(s
, tree
, VAL
);
2242 char *p
= (char*)tree
->car
;
2243 int base
= nint(tree
->cdr
->car
);
2248 i
= readint_mrb_int(s
, p
, base
, FALSE
, &overflow
);
2250 double f
= readint_float(s
, p
, base
);
2251 int off
= new_lit(s
, mrb_float_value(s
->mrb
, f
));
2253 genop(s
, MKOP_ABx(OP_LOADL
, cursp(), off
));
2256 if (i
< MAXARG_sBx
&& i
> -MAXARG_sBx
) {
2257 co
= MKOP_AsBx(OP_LOADI
, cursp(), i
);
2260 int off
= new_lit(s
, mrb_fixnum_value(i
));
2261 co
= MKOP_ABx(OP_LOADL
, cursp(), off
);
2271 char *p
= (char*)tree
;
2272 mrb_float f
= mrb_float_read(p
, NULL
);
2273 int off
= new_lit(s
, mrb_float_value(s
->mrb
, f
));
2275 genop(s
, MKOP_ABx(OP_LOADL
, cursp(), off
));
2282 nt
= nint(tree
->car
);
2287 char *p
= (char*)tree
;
2288 mrb_float f
= mrb_float_read(p
, NULL
);
2289 int off
= new_lit(s
, mrb_float_value(s
->mrb
, -f
));
2291 genop(s
, MKOP_ABx(OP_LOADL
, cursp(), off
));
2298 char *p
= (char*)tree
->car
;
2299 int base
= nint(tree
->cdr
->car
);
2304 i
= readint_mrb_int(s
, p
, base
, TRUE
, &overflow
);
2306 double f
= readint_float(s
, p
, base
);
2307 int off
= new_lit(s
, mrb_float_value(s
->mrb
, -f
));
2309 genop(s
, MKOP_ABx(OP_LOADL
, cursp(), off
));
2312 if (i
< MAXARG_sBx
&& i
> -MAXARG_sBx
) {
2313 co
= MKOP_AsBx(OP_LOADI
, cursp(), i
);
2316 int off
= new_lit(s
, mrb_fixnum_value(i
));
2317 co
= MKOP_ABx(OP_LOADL
, cursp(), off
);
2327 int sym
= new_msym(s
, mrb_intern_lit(s
->mrb
, "-"));
2329 genop(s
, MKOP_ABx(OP_LOADI
, cursp(), 0));
2331 codegen(s
, tree
, VAL
);
2333 genop(s
, MKOP_ABC(OP_SUB
, cursp(), sym
, 2));
2336 codegen(s
, tree
, NOVAL
);
2345 char *p
= (char*)tree
->car
;
2346 size_t len
= (intptr_t)tree
->cdr
;
2347 int ai
= mrb_gc_arena_save(s
->mrb
);
2348 int off
= new_lit(s
, mrb_str_new(s
->mrb
, p
, len
));
2350 mrb_gc_arena_restore(s
->mrb
, ai
);
2351 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2357 tree
= ((struct mrb_parser_heredoc_info
*)tree
)->doc
;
2364 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2368 codegen(s
, n
->car
, VAL
);
2371 codegen(s
, n
->car
, VAL
);
2373 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
2382 if (nint(n
->car
->car
) != NODE_STR
) {
2383 codegen(s
, n
->car
, NOVAL
);
2391 gen_literal_array(s
, tree
, FALSE
, val
);
2395 gen_literal_array(s
, tree
, TRUE
, val
);
2401 int ai
= mrb_gc_arena_save(s
->mrb
);
2402 int sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "Kernel"));
2404 genop(s
, MKOP_A(OP_LOADSELF
, cursp()));
2406 codegen(s
, tree
->car
, VAL
);
2409 if (nint(n
->car
->car
) == NODE_XSTR
) {
2410 n
->car
->car
= (struct mrb_ast_node
*)(intptr_t)NODE_STR
;
2411 mrb_assert(!n
->cdr
); /* must be the end */
2413 codegen(s
, n
->car
, VAL
);
2415 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
2419 push(); /* for block */
2421 sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "`"));
2422 genop(s
, MKOP_ABC(OP_SEND
, cursp(), sym
, 1));
2424 mrb_gc_arena_restore(s
->mrb
, ai
);
2430 char *p
= (char*)tree
->car
;
2431 size_t len
= (intptr_t)tree
->cdr
;
2432 int ai
= mrb_gc_arena_save(s
->mrb
);
2433 int off
= new_lit(s
, mrb_str_new(s
->mrb
, p
, len
));
2436 genop(s
, MKOP_A(OP_LOADSELF
, cursp()));
2438 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2441 sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "`"));
2442 genop(s
, MKOP_ABC(OP_SEND
, cursp(), sym
, 1));
2444 mrb_gc_arena_restore(s
->mrb
, ai
);
2450 char *p1
= (char*)tree
->car
;
2451 char *p2
= (char*)tree
->cdr
->car
;
2452 char *p3
= (char*)tree
->cdr
->cdr
;
2453 int ai
= mrb_gc_arena_save(s
->mrb
);
2454 int sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, REGEXP_CLASS
));
2455 int off
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, p1
));
2458 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
2459 genop(s
, MKOP_ABx(OP_GETMCNST
, cursp(), sym
));
2461 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2465 off
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, p2
));
2466 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2469 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2474 off
= new_lit(s
, mrb_str_new(s
->mrb
, p3
, 1));
2475 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2482 sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "compile"));
2483 genop(s
, MKOP_ABC(OP_SEND
, cursp(), sym
, argc
));
2484 mrb_gc_arena_restore(s
->mrb
, ai
);
2491 node
*n
= tree
->car
;
2492 int ai
= mrb_gc_arena_save(s
->mrb
);
2493 int sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, REGEXP_CLASS
));
2498 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
2499 genop(s
, MKOP_ABx(OP_GETMCNST
, cursp(), sym
));
2501 codegen(s
, n
->car
, VAL
);
2504 codegen(s
, n
->car
, VAL
);
2506 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
2513 off
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, p
));
2514 codegen(s
, tree
->car
, VAL
);
2515 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2517 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
2520 char *p2
= (char*)n
->cdr
->car
;
2523 off
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, p2
));
2524 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2528 char *p2
= (char*)n
->cdr
->cdr
;
2531 off
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, p2
));
2532 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2536 sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "compile"));
2537 genop(s
, MKOP_ABC(OP_SEND
, cursp(), sym
, argc
));
2538 mrb_gc_arena_restore(s
->mrb
, ai
);
2542 node
*n
= tree
->car
;
2545 if (nint(n
->car
->car
) != NODE_STR
) {
2546 codegen(s
, n
->car
, NOVAL
);
2555 int sym
= new_sym(s
, nsym(tree
));
2557 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), sym
));
2563 codegen(s
, tree
, val
);
2571 genop(s
, MKOP_A(OP_LOADSELF
, cursp()));
2578 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2585 genop(s
, MKOP_A(OP_LOADT
, cursp()));
2592 genop(s
, MKOP_A(OP_LOADF
, cursp()));
2599 int a
= new_msym(s
, nsym(tree
->car
));
2600 int b
= new_msym(s
, nsym(tree
->cdr
));
2601 int c
= new_msym(s
, mrb_intern_lit(s
->mrb
, "alias_method"));
2603 genop(s
, MKOP_A(OP_TCLASS
, cursp()));
2605 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), a
));
2607 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), b
));
2609 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2612 genop(s
, MKOP_ABC(OP_SEND
, cursp(), c
, 2));
2621 int undef
= new_msym(s
, mrb_intern_lit(s
->mrb
, "undef_method"));
2625 genop(s
, MKOP_A(OP_TCLASS
, cursp()));
2629 if (num
>= CALL_MAXARGS
- 1) {
2631 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), cursp(), num
));
2633 symbol
= new_msym(s
, nsym(t
->car
));
2635 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), symbol
));
2637 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), cursp()+1));
2643 symbol
= new_msym(s
, nsym(t
->car
));
2644 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), symbol
));
2649 push();pop(); /* space for a block */
2651 if (num
< CALL_MAXARGS
) {
2654 genop(s
, MKOP_ABC(OP_SEND
, cursp(), undef
, num
));
2665 if (tree
->car
->car
== (node
*)0) {
2666 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2669 else if (tree
->car
->car
== (node
*)1) {
2670 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
2674 codegen(s
, tree
->car
->car
, VAL
);
2676 if (tree
->cdr
->car
) {
2677 codegen(s
, tree
->cdr
->car
, VAL
);
2680 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2684 idx
= new_msym(s
, nsym(tree
->car
->cdr
));
2685 genop(s
, MKOP_AB(OP_CLASS
, cursp(), idx
));
2686 idx
= scope_body(s
, tree
->cdr
->cdr
->car
, val
);
2687 genop(s
, MKOP_ABx(OP_EXEC
, cursp(), idx
));
2698 if (tree
->car
->car
== (node
*)0) {
2699 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2702 else if (tree
->car
->car
== (node
*)1) {
2703 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
2707 codegen(s
, tree
->car
->car
, VAL
);
2710 idx
= new_msym(s
, nsym(tree
->car
->cdr
));
2711 genop(s
, MKOP_AB(OP_MODULE
, cursp(), idx
));
2712 idx
= scope_body(s
, tree
->cdr
->car
, val
);
2713 genop(s
, MKOP_ABx(OP_EXEC
, cursp(), idx
));
2724 codegen(s
, tree
->car
, VAL
);
2726 genop(s
, MKOP_AB(OP_SCLASS
, cursp(), cursp()));
2727 idx
= scope_body(s
, tree
->cdr
->car
, val
);
2728 genop(s
, MKOP_ABx(OP_EXEC
, cursp(), idx
));
2737 int sym
= new_msym(s
, nsym(tree
->car
));
2738 int idx
= lambda_body(s
, tree
->cdr
, 0);
2740 genop(s
, MKOP_A(OP_TCLASS
, cursp()));
2742 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), idx
, OP_L_METHOD
));
2745 genop(s
, MKOP_AB(OP_METHOD
, cursp(), sym
));
2747 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), sym
));
2755 node
*recv
= tree
->car
;
2756 int sym
= new_msym(s
, nsym(tree
->cdr
->car
));
2757 int idx
= lambda_body(s
, tree
->cdr
->cdr
, 0);
2759 codegen(s
, recv
, VAL
);
2761 genop(s
, MKOP_AB(OP_SCLASS
, cursp(), cursp()));
2763 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), idx
, OP_L_METHOD
));
2765 genop(s
, MKOP_AB(OP_METHOD
, cursp(), sym
));
2767 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), sym
));
2774 codegen(s
, tree
, NOVAL
);
2785 scope_add_irep(codegen_scope
*s
, mrb_irep
*irep
)
2787 if (s
->irep
== NULL
) {
2791 if (s
->irep
->rlen
== s
->rcapa
) {
2793 s
->irep
->reps
= (mrb_irep
**)codegen_realloc(s
, s
->irep
->reps
, sizeof(mrb_irep
*)*s
->rcapa
);
2795 s
->irep
->reps
[s
->irep
->rlen
] = irep
;
2799 static codegen_scope
*
2800 scope_new(mrb_state
*mrb
, codegen_scope
*prev
, node
*lv
)
2802 static const codegen_scope codegen_scope_zero
= { 0 };
2803 mrb_pool
*pool
= mrb_pool_open(mrb
);
2804 codegen_scope
*p
= (codegen_scope
*)mrb_pool_alloc(pool
, sizeof(codegen_scope
));
2806 if (!p
) return NULL
;
2807 *p
= codegen_scope_zero
;
2810 if (!prev
) return p
;
2815 p
->irep
= mrb_add_irep(mrb
);
2816 scope_add_irep(prev
, p
->irep
);
2819 p
->irep
->reps
= (mrb_irep
**)mrb_malloc(mrb
, sizeof(mrb_irep
*)*p
->rcapa
);
2822 p
->iseq
= (mrb_code
*)mrb_malloc(mrb
, sizeof(mrb_code
)*p
->icapa
);
2823 p
->irep
->iseq
= NULL
;
2826 p
->irep
->pool
= (mrb_value
*)mrb_malloc(mrb
, sizeof(mrb_value
)*p
->pcapa
);
2829 p
->scapa
= MAXMSYMLEN
;
2830 p
->irep
->syms
= (mrb_sym
*)mrb_malloc(mrb
, sizeof(mrb_sym
)*p
->scapa
);
2834 p
->sp
+= node_len(lv
)+1; /* add self */
2840 p
->irep
->lv
= (struct mrb_locals
*)mrb_malloc(mrb
, sizeof(struct mrb_locals
) * (p
->nlocals
- 1));
2841 for (i
=0, n
=lv
; n
; i
++,n
=n
->cdr
) {
2842 p
->irep
->lv
[i
].name
= lv_name(n
);
2844 p
->irep
->lv
[i
].r
= lv_idx(p
, lv_name(n
));
2847 p
->irep
->lv
[i
].r
= 0;
2850 mrb_assert(i
+ 1 == p
->nlocals
);
2852 p
->ai
= mrb_gc_arena_save(mrb
);
2854 p
->filename
= prev
->filename
;
2856 p
->lines
= (uint16_t*)mrb_malloc(mrb
, sizeof(short)*p
->icapa
);
2858 p
->lineno
= prev
->lineno
;
2861 p
->debug_start_pos
= 0;
2863 mrb_debug_info_alloc(mrb
, p
->irep
);
2864 p
->irep
->filename
= p
->filename
;
2865 p
->irep
->lines
= p
->lines
;
2868 p
->irep
->debug_info
= NULL
;
2870 p
->parser
= prev
->parser
;
2871 p
->filename_index
= prev
->filename_index
;
2873 p
->rlev
= prev
->rlev
+1;
2879 scope_finish(codegen_scope
*s
)
2881 mrb_state
*mrb
= s
->mrb
;
2882 mrb_irep
*irep
= s
->irep
;
2888 irep
->iseq
= (mrb_code
*)codegen_realloc(s
, s
->iseq
, sizeof(mrb_code
)*s
->pc
);
2891 irep
->lines
= (uint16_t *)codegen_realloc(s
, s
->lines
, sizeof(uint16_t)*s
->pc
);
2897 irep
->pool
= (mrb_value
*)codegen_realloc(s
, irep
->pool
, sizeof(mrb_value
)*irep
->plen
);
2898 irep
->syms
= (mrb_sym
*)codegen_realloc(s
, irep
->syms
, sizeof(mrb_sym
)*irep
->slen
);
2899 irep
->reps
= (mrb_irep
**)codegen_realloc(s
, irep
->reps
, sizeof(mrb_irep
*)*irep
->rlen
);
2901 irep
->filename
= mrb_parser_get_filename(s
->parser
, s
->filename_index
);
2902 mrb_debug_info_append_file(mrb
, irep
, s
->debug_start_pos
, s
->pc
);
2904 fname_len
= strlen(s
->filename
);
2905 fname
= (char*)codegen_malloc(s
, fname_len
+ 1);
2906 memcpy(fname
, s
->filename
, fname_len
);
2907 fname
[fname_len
] = '\0';
2908 irep
->filename
= fname
;
2909 irep
->own_filename
= TRUE
;
2912 irep
->nlocals
= s
->nlocals
;
2913 irep
->nregs
= s
->nregs
;
2915 mrb_gc_arena_restore(mrb
, s
->ai
);
2916 mrb_pool_close(s
->mpool
);
2919 static struct loopinfo
*
2920 loop_push(codegen_scope
*s
, enum looptype t
)
2922 struct loopinfo
*p
= (struct loopinfo
*)codegen_palloc(s
, sizeof(struct loopinfo
));
2925 p
->pc1
= p
->pc2
= p
->pc3
= 0;
2927 p
->ensure_level
= s
->ensure_level
;
2935 loop_break(codegen_scope
*s
, node
*tree
)
2938 codegen(s
, tree
, NOVAL
);
2939 raise_error(s
, "unexpected break");
2942 struct loopinfo
*loop
;
2946 gen_retval(s
, tree
);
2951 if (loop
->type
== LOOP_BEGIN
) {
2955 else if (loop
->type
== LOOP_RESCUE
) {
2963 raise_error(s
, "unexpected break");
2967 genop_peep(s
, MKOP_A(OP_POPERR
, n
), NOVAL
);
2970 if (loop
->type
== LOOP_NORMAL
) {
2973 if (s
->ensure_level
> s
->loop
->ensure_level
) {
2974 genop_peep(s
, MKOP_A(OP_EPOP
, s
->ensure_level
- s
->loop
->ensure_level
), NOVAL
);
2977 genop_peep(s
, MKOP_AB(OP_MOVE
, loop
->acc
, cursp()), NOVAL
);
2979 tmp
= genop(s
, MKOP_sBx(OP_JMP
, loop
->pc3
));
2984 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2986 genop(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_BREAK
));
2992 loop_pop(codegen_scope
*s
, int val
)
2995 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2997 dispatch_linked(s
, s
->loop
->pc3
);
2998 s
->loop
= s
->loop
->prev
;
3002 MRB_API
struct RProc
*
3003 mrb_generate_code(mrb_state
*mrb
, parser_state
*p
)
3005 codegen_scope
*scope
= scope_new(mrb
, 0, 0);
3007 struct mrb_jmpbuf
*prev_jmp
= mrb
->jmp
;
3014 scope
->filename
= p
->filename
;
3015 scope
->filename_index
= p
->current_filename_index
;
3017 MRB_TRY(&scope
->jmp
) {
3018 mrb
->jmp
= &scope
->jmp
;
3020 codegen(scope
, p
->tree
, NOVAL
);
3021 proc
= mrb_proc_new(mrb
, scope
->irep
);
3022 mrb_irep_decref(mrb
, scope
->irep
);
3023 mrb_pool_close(scope
->mpool
);
3025 mrb
->jmp
= prev_jmp
;
3028 MRB_CATCH(&scope
->jmp
) {
3029 mrb_irep_decref(mrb
, scope
->irep
);
3030 mrb_pool_close(scope
->mpool
);
3031 mrb
->jmp
= prev_jmp
;
3034 MRB_END_EXC(&scope
->jmp
);