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 typedef mrb_ast_node node
;
23 typedef struct mrb_parser_state parser_state
;
35 int pc1
, pc2
, pc3
, acc
;
37 struct loopinfo
*prev
;
40 typedef struct scope
{
43 struct mrb_jmpbuf jmp
;
55 struct loopinfo
*loop
;
74 uint16_t filename_index
;
78 static codegen_scope
* scope_new(mrb_state
*mrb
, codegen_scope
*prev
, node
*lv
);
79 static void scope_finish(codegen_scope
*s
);
80 static struct loopinfo
*loop_push(codegen_scope
*s
, enum looptype t
);
81 static void loop_break(codegen_scope
*s
, node
*tree
);
82 static void loop_pop(codegen_scope
*s
, int val
);
84 static void gen_assignment(codegen_scope
*s
, node
*tree
, int sp
, int val
);
85 static void gen_vmassignment(codegen_scope
*s
, node
*tree
, int rhs
, int val
);
87 static void codegen(codegen_scope
*s
, node
*tree
, int val
);
88 static void raise_error(codegen_scope
*s
, const char *msg
);
91 codegen_error(codegen_scope
*s
, const char *message
)
95 codegen_scope
*tmp
= s
->prev
;
96 mrb_free(s
->mrb
, s
->iseq
);
97 mrb_pool_close(s
->mpool
);
100 #ifndef MRB_DISABLE_STDIO
101 if (s
->filename
&& s
->lineno
) {
102 fprintf(stderr
, "codegen error:%s:%d: %s\n", s
->filename
, s
->lineno
, message
);
105 fprintf(stderr
, "codegen error: %s\n", message
);
112 codegen_palloc(codegen_scope
*s
, size_t len
)
114 void *p
= mrb_pool_alloc(s
->mpool
, len
);
116 if (!p
) codegen_error(s
, "pool memory allocation");
121 codegen_malloc(codegen_scope
*s
, size_t len
)
123 void *p
= mrb_malloc_simple(s
->mrb
, len
);
125 if (!p
) codegen_error(s
, "mrb_malloc");
130 codegen_realloc(codegen_scope
*s
, void *p
, size_t len
)
132 p
= mrb_realloc_simple(s
->mrb
, p
, len
);
134 if (!p
&& len
> 0) codegen_error(s
, "mrb_realloc");
139 new_label(codegen_scope
*s
)
141 s
->lastlabel
= s
->pc
;
146 genop(codegen_scope
*s
, mrb_code i
)
148 if (s
->pc
== s
->icapa
) {
150 s
->iseq
= (mrb_code
*)codegen_realloc(s
, s
->iseq
, sizeof(mrb_code
)*s
->icapa
);
152 s
->lines
= (uint16_t*)codegen_realloc(s
, s
->lines
, sizeof(short)*s
->icapa
);
153 s
->irep
->lines
= s
->lines
;
158 s
->lines
[s
->pc
] = s
->lineno
;
167 no_optimize(codegen_scope
*s
)
169 if (s
&& s
->parser
&& s
->parser
->no_optimize
)
175 genop_peep(codegen_scope
*s
, mrb_code i
, int val
)
177 /* peephole optimization */
178 if (!no_optimize(s
) && s
->lastlabel
!= s
->pc
&& s
->pc
> 0) {
179 mrb_code i0
= s
->iseq
[s
->pc
-1];
180 int c1
= GET_OPCODE(i
);
181 int c0
= GET_OPCODE(i0
);
185 if (GETARG_A(i
) == GETARG_B(i
)) {
186 /* skip useless OP_MOVE */
192 if (GETARG_A(i
) == GETARG_A(i0
)) {
193 /* skip overriden OP_MOVE */
197 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i
) == GETARG_B(i0
)) {
198 /* skip swapping OP_MOVE */
201 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i0
) >= s
->nlocals
) {
203 return genop_peep(s
, MKOP_AB(OP_MOVE
, GETARG_A(i
), GETARG_B(i0
)), val
);
207 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i0
) >= s
->nlocals
) {
208 s
->iseq
[s
->pc
-1] = MKOP_AsBx(OP_LOADI
, GETARG_A(i
), GETARG_sBx(i0
));
217 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i0
) >= s
->nlocals
) {
218 s
->iseq
[s
->pc
-1] = MKOP_ABC(c0
, GETARG_A(i
), GETARG_B(i0
), GETARG_C(i0
));
230 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i0
) >= s
->nlocals
) {
231 s
->iseq
[s
->pc
-1] = MKOP_ABx(c0
, GETARG_A(i
), GETARG_Bx(i0
));
236 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i0
) >= s
->nlocals
) {
237 s
->iseq
[s
->pc
-1] = MKOP_AB(c0
, GETARG_A(i
), GETARG_B(i0
));
246 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i0
) >= s
->nlocals
) {
247 s
->iseq
[s
->pc
-1] = MKOP_A(c0
, GETARG_A(i
));
262 if (GETARG_A(i
) == GETARG_A(i0
)) {
263 s
->iseq
[s
->pc
-1] = MKOP_ABx(c1
, GETARG_B(i0
), GETARG_Bx(i
));
271 if (GETARG_A(i
) == GETARG_A(i0
)) {
272 s
->iseq
[s
->pc
-1] = MKOP_ABC(c1
, GETARG_B(i0
), GETARG_B(i
), GETARG_C(i
));
279 s
->iseq
[s
->pc
-1] = MKOP_A(OP_EPOP
, GETARG_A(i0
)+GETARG_A(i
));
284 if (c0
== OP_POPERR
) {
285 s
->iseq
[s
->pc
-1] = MKOP_A(OP_POPERR
, GETARG_A(i0
)+GETARG_A(i
));
294 if (GETARG_A(i0
) >= s
->nlocals
) {
295 s
->iseq
[s
->pc
-1] = MKOP_AB(OP_RETURN
, GETARG_B(i0
), OP_R_NORMAL
);
306 genop_peep(s
, i0
, NOVAL
);
307 i0
= s
->iseq
[s
->pc
-1];
308 return genop(s
, MKOP_AB(OP_RETURN
, GETARG_A(i0
), OP_R_NORMAL
));
311 if (GETARG_B(i
) == OP_R_NORMAL
&& GETARG_A(i
) == GETARG_A(i0
)) {
312 s
->iseq
[s
->pc
-1] = MKOP_ABC(OP_TAILCALL
, GETARG_A(i0
), GETARG_B(i0
), GETARG_C(i0
));
323 if (c0
== OP_LOADI
) {
324 int c
= GETARG_sBx(i0
);
326 if (c1
== OP_SUB
) c
= -c
;
327 if (c
> 127 || c
< -127) break;
329 s
->iseq
[s
->pc
-1] = MKOP_ABC(OP_ADDI
, GETARG_A(i
), GETARG_B(i
), c
);
331 s
->iseq
[s
->pc
-1] = MKOP_ABC(OP_SUBI
, GETARG_A(i
), GETARG_B(i
), -c
);
335 if (c0
== OP_STRING
) {
336 mrb_value v
= s
->irep
->pool
[GETARG_Bx(i0
)];
338 if (mrb_string_p(v
) && RSTRING_LEN(v
) == 0) {
343 if (c0
== OP_LOADNIL
) {
344 if (GETARG_B(i
) == GETARG_A(i0
)) {
352 if (c0
== OP_MOVE
&& GETARG_A(i
) == GETARG_A(i0
)) {
353 s
->iseq
[s
->pc
-1] = MKOP_AsBx(c1
, GETARG_B(i0
), GETARG_sBx(i
));
365 scope_error(codegen_scope
*s
)
371 dispatch(codegen_scope
*s
, int pc
)
373 int diff
= s
->pc
- pc
;
374 mrb_code i
= s
->iseq
[pc
];
375 int c
= GET_OPCODE(i
);
377 s
->lastlabel
= s
->pc
;
385 #ifndef MRB_DISABLE_STDIO
386 fprintf(stderr
, "bug: dispatch on non JMP op\n");
391 if (diff
> MAXARG_sBx
) {
392 codegen_error(s
, "too distant jump address");
394 s
->iseq
[pc
] = MKOP_AsBx(c
, GETARG_A(i
), diff
);
398 dispatch_linked(codegen_scope
*s
, int pc
)
413 #define nregs_update do {if (s->sp > s->nregs) s->nregs = s->sp;} while (0)
415 push_(codegen_scope
*s
)
418 codegen_error(s
, "too complex expression");
425 push_n_(codegen_scope
*s
, size_t n
)
428 codegen_error(s
, "too complex expression");
434 #define push() push_(s)
435 #define push_n(n) push_n_(s,n)
436 #define pop_(s) ((s)->sp--)
437 #define pop() pop_(s)
438 #define pop_n(n) (s->sp-=(n))
439 #define cursp() (s->sp)
442 new_lit(codegen_scope
*s
, mrb_value val
)
447 switch (mrb_type(val
)) {
449 for (i
=0; i
<s
->irep
->plen
; i
++) {
451 pv
= &s
->irep
->pool
[i
];
453 if (mrb_type(*pv
) != MRB_TT_STRING
) continue;
454 if ((len
= RSTRING_LEN(*pv
)) != RSTRING_LEN(val
)) continue;
455 if (memcmp(RSTRING_PTR(*pv
), RSTRING_PTR(val
), len
) == 0)
460 for (i
=0; i
<s
->irep
->plen
; i
++) {
461 pv
= &s
->irep
->pool
[i
];
462 if (mrb_type(*pv
) != MRB_TT_FLOAT
) continue;
463 if (mrb_float(*pv
) == mrb_float(val
)) return i
;
467 for (i
=0; i
<s
->irep
->plen
; i
++) {
468 pv
= &s
->irep
->pool
[i
];
469 if (!mrb_fixnum_p(*pv
)) continue;
470 if (mrb_fixnum(*pv
) == mrb_fixnum(val
)) return i
;
474 /* should not happen */
478 if (s
->irep
->plen
== s
->pcapa
) {
480 s
->irep
->pool
= (mrb_value
*)codegen_realloc(s
, s
->irep
->pool
, sizeof(mrb_value
)*s
->pcapa
);
483 pv
= &s
->irep
->pool
[s
->irep
->plen
];
486 switch (mrb_type(val
)) {
488 *pv
= mrb_str_pool(s
->mrb
, val
);
492 #ifdef MRB_WORD_BOXING
493 *pv
= mrb_float_pool(s
->mrb
, mrb_float(val
));
501 /* should not happen */
507 /* method symbols should be fit in 9 bits */
508 #define MAXMSYMLEN 512
509 /* maximum symbol numbers */
510 #define MAXSYMLEN 65536
513 new_msym(codegen_scope
*s
, mrb_sym sym
)
520 if (len
> MAXMSYMLEN
) len
= MAXMSYMLEN
;
521 for (i
=0; i
<len
; i
++) {
522 if (s
->irep
->syms
[i
] == sym
) return i
;
523 if (s
->irep
->syms
[i
] == 0) break;
525 if (i
== MAXMSYMLEN
) {
526 codegen_error(s
, "too many symbols (max " MRB_STRINGIZE(MAXMSYMLEN
) ")");
528 s
->irep
->syms
[i
] = sym
;
529 if (i
== s
->irep
->slen
) s
->irep
->slen
++;
534 new_sym(codegen_scope
*s
, mrb_sym sym
)
538 for (i
=0; i
<s
->irep
->slen
; i
++) {
539 if (s
->irep
->syms
[i
] == sym
) return i
;
541 if (s
->irep
->slen
== MAXSYMLEN
) {
542 codegen_error(s
, "too many symbols (max " MRB_STRINGIZE(MAXSYMLEN
) ")");
545 if (s
->irep
->slen
> MAXMSYMLEN
/2 && s
->scapa
== MAXMSYMLEN
) {
546 s
->scapa
= MAXSYMLEN
;
547 s
->irep
->syms
= (mrb_sym
*)codegen_realloc(s
, s
->irep
->syms
, sizeof(mrb_sym
)*MAXSYMLEN
);
548 for (i
= s
->irep
->slen
; i
< MAXMSYMLEN
; i
++) {
549 static const mrb_sym mrb_sym_zero
= { 0 };
550 s
->irep
->syms
[i
] = mrb_sym_zero
;
552 s
->irep
->slen
= MAXMSYMLEN
;
554 s
->irep
->syms
[s
->irep
->slen
] = sym
;
555 return s
->irep
->slen
++;
570 #define sym(x) ((mrb_sym)(intptr_t)(x))
571 #define lv_name(lv) sym((lv)->car)
573 lv_idx(codegen_scope
*s
, mrb_sym id
)
579 if (lv_name(lv
) == id
) return n
;
587 for_body(codegen_scope
*s
, node
*tree
)
589 codegen_scope
*prev
= s
;
595 /* generate receiver */
596 codegen(s
, tree
->cdr
->car
, VAL
);
597 /* generate loop-block */
598 s
= scope_new(s
->mrb
, s
, NULL
);
600 raise_error(prev
, "unexpected scope");
603 push(); /* push for a block parameter */
605 /* generate loop variable */
607 genop(s
, MKOP_Ax(OP_ENTER
, 0x40000));
608 if (n2
->car
&& !n2
->car
->cdr
&& !n2
->cdr
) {
609 gen_assignment(s
, n2
->car
->car
, 1, NOVAL
);
612 gen_vmassignment(s
, n2
, 1, VAL
);
615 lp
= loop_push(s
, LOOP_FOR
);
616 lp
->pc2
= new_label(s
);
619 codegen(s
, tree
->cdr
->cdr
->car
, VAL
);
622 c
= s
->iseq
[s
->pc
-1];
623 if (GET_OPCODE(c
) != OP_RETURN
|| GETARG_B(c
) != OP_R_NORMAL
|| s
->pc
== s
->lastlabel
)
624 genop_peep(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_NORMAL
), NOVAL
);
629 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), s
->irep
->rlen
-1, OP_L_BLOCK
));
631 idx
= new_msym(s
, mrb_intern_lit(s
->mrb
, "each"));
632 genop(s
, MKOP_ABC(OP_SENDB
, cursp(), idx
, 0));
636 lambda_body(codegen_scope
*s
, node
*tree
, int blk
)
639 codegen_scope
*parent
= s
;
640 s
= scope_new(s
->mrb
, s
, tree
->car
);
642 raise_error(parent
, "unexpected scope");
648 struct loopinfo
*lp
= loop_push(s
, LOOP_BLOCK
);
649 lp
->pc1
= new_label(s
);
654 int ma
, oa
, ra
, pa
, ka
, kd
, ba
;
658 ma
= node_len(tree
->car
->car
);
663 oa
= node_len(tree
->car
->cdr
->car
);
664 ra
= tree
->car
->cdr
->cdr
->car
? 1 : 0;
665 pa
= node_len(tree
->car
->cdr
->cdr
->cdr
->car
);
667 ba
= tree
->car
->cdr
->cdr
->cdr
->cdr
? 1 : 0;
669 if (ma
> 0x1f || oa
> 0x1f || pa
> 0x1f || ka
> 0x1f) {
670 codegen_error(s
, "too many formal arguments");
672 a
= ((mrb_aspec
)(ma
& 0x1f) << 18)
673 | ((mrb_aspec
)(oa
& 0x1f) << 13)
679 s
->ainfo
= (((ma
+oa
) & 0x3f) << 6) /* (12bits = 6:1:5) */
682 genop(s
, MKOP_Ax(OP_ENTER
, a
));
684 for (i
=0; i
<oa
; i
++) {
686 genop(s
, MKOP_sBx(OP_JMP
, 0));
689 genop(s
, MKOP_sBx(OP_JMP
, 0));
691 opt
= tree
->car
->cdr
->car
;
697 codegen(s
, opt
->car
->cdr
, VAL
);
698 idx
= lv_idx(s
, (mrb_sym
)(intptr_t)opt
->car
->car
);
700 genop_peep(s
, MKOP_AB(OP_MOVE
, idx
, cursp()), NOVAL
);
708 codegen(s
, tree
->cdr
->car
, VAL
);
711 c
= s
->iseq
[s
->pc
-1];
712 if (GET_OPCODE(c
) != OP_RETURN
|| GETARG_B(c
) != OP_R_NORMAL
|| s
->pc
== s
->lastlabel
) {
714 genop(s
, MKOP_A(OP_LOADNIL
, 0));
715 genop(s
, MKOP_AB(OP_RETURN
, 0, OP_R_NORMAL
));
718 genop_peep(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_NORMAL
), NOVAL
);
726 return parent
->irep
->rlen
- 1;
730 scope_body(codegen_scope
*s
, node
*tree
, int val
)
732 codegen_scope
*scope
= scope_new(s
->mrb
, s
, tree
->car
);
734 raise_error(s
, "unexpected scope");
737 codegen(scope
, tree
->cdr
, VAL
);
739 genop(scope
, MKOP_A(OP_STOP
, 0));
742 genop(scope
, MKOP_AB(OP_RETURN
, 0, OP_R_NORMAL
));
745 if (scope
->nregs
== 0) {
746 genop(scope
, MKOP_A(OP_LOADNIL
, 0));
747 genop(scope
, MKOP_AB(OP_RETURN
, 0, OP_R_NORMAL
));
750 genop_peep(scope
, MKOP_AB(OP_RETURN
, scope
->sp
-1, OP_R_NORMAL
), NOVAL
);
755 /* should not happen */
758 return s
->irep
->rlen
- 1;
765 if ((intptr_t)t
->car
->car
== NODE_SPLAT
) return FALSE
;
772 attrsym(codegen_scope
*s
, mrb_sym a
)
778 name
= mrb_sym2name_len(s
->mrb
, a
, &len
);
779 name2
= (char *)codegen_palloc(s
,
784 mrb_assert_int_fit(mrb_int
, len
, size_t, SIZE_MAX
);
785 memcpy(name2
, name
, (size_t)len
);
789 return mrb_intern(s
->mrb
, name2
, len
+1);
792 #define CALL_MAXARGS 127
795 gen_values(codegen_scope
*s
, node
*t
, int val
, int extra
)
801 is_splat
= (intptr_t)t
->car
->car
== NODE_SPLAT
; /* splat mode */
803 n
+extra
>= CALL_MAXARGS
- 1 /* need to subtract one because vm.c expects an array if n == CALL_MAXARGS */
806 if (is_splat
&& n
== 0 && (intptr_t)t
->car
->cdr
->car
== NODE_ARRAY
) {
807 codegen(s
, t
->car
->cdr
, VAL
);
812 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), cursp(), n
));
814 codegen(s
, t
->car
, VAL
);
817 genop(s
, MKOP_AB(OP_ARYCAT
, cursp(), cursp()+1));
820 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), cursp()+1));
826 codegen(s
, t
->car
, VAL
);
828 if ((intptr_t)t
->car
->car
== NODE_SPLAT
) {
829 genop(s
, MKOP_AB(OP_ARYCAT
, cursp(), cursp()+1));
832 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), cursp()+1));
839 codegen(s
, t
->car
, NOVAL
);
845 /* normal (no splat) mode */
846 codegen(s
, t
->car
, val
);
854 gen_call(codegen_scope
*s
, node
*tree
, mrb_sym name
, int sp
, int val
, int safe
)
856 mrb_sym sym
= name
? name
: sym(tree
->cdr
->car
);
858 int n
= 0, noop
= 0, sendv
= 0, blk
= 0;
860 codegen(s
, tree
->car
, VAL
); /* receiver */
862 int recv
= cursp()-1;
863 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
865 genop(s
, MKOP_AB(OP_MOVE
, cursp(), recv
));
866 push(); pop(); /* space for a block */
868 idx
= new_msym(s
, mrb_intern_lit(s
->mrb
, "=="));
869 genop(s
, MKOP_ABC(OP_EQ
, cursp(), idx
, 1));
870 skip
= genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), 0));
872 idx
= new_msym(s
, sym
);
873 tree
= tree
->cdr
->cdr
->car
;
875 n
= gen_values(s
, tree
->car
, VAL
, sp
?1:0);
877 n
= noop
= sendv
= 1;
884 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), sp
));
888 genop(s
, MKOP_AB(OP_MOVE
, cursp(), sp
));
893 if (tree
&& tree
->cdr
) {
895 codegen(s
, tree
->cdr
, VAL
);
905 const char *symname
= mrb_sym2name_len(s
->mrb
, sym
, &symlen
);
907 if (!noop
&& symlen
== 1 && symname
[0] == '+' && n
== 1) {
908 genop_peep(s
, MKOP_ABC(OP_ADD
, cursp(), idx
, n
), val
);
910 else if (!noop
&& symlen
== 1 && symname
[0] == '-' && n
== 1) {
911 genop_peep(s
, MKOP_ABC(OP_SUB
, cursp(), idx
, n
), val
);
913 else if (!noop
&& symlen
== 1 && symname
[0] == '*' && n
== 1) {
914 genop(s
, MKOP_ABC(OP_MUL
, cursp(), idx
, n
));
916 else if (!noop
&& symlen
== 1 && symname
[0] == '/' && n
== 1) {
917 genop(s
, MKOP_ABC(OP_DIV
, cursp(), idx
, n
));
919 else if (!noop
&& symlen
== 1 && symname
[0] == '<' && n
== 1) {
920 genop(s
, MKOP_ABC(OP_LT
, cursp(), idx
, n
));
922 else if (!noop
&& symlen
== 2 && symname
[0] == '<' && symname
[1] == '=' && n
== 1) {
923 genop(s
, MKOP_ABC(OP_LE
, cursp(), idx
, n
));
925 else if (!noop
&& symlen
== 1 && symname
[0] == '>' && n
== 1) {
926 genop(s
, MKOP_ABC(OP_GT
, cursp(), idx
, n
));
928 else if (!noop
&& symlen
== 2 && symname
[0] == '>' && symname
[1] == '=' && n
== 1) {
929 genop(s
, MKOP_ABC(OP_GE
, cursp(), idx
, n
));
931 else if (!noop
&& symlen
== 2 && symname
[0] == '=' && symname
[1] == '=' && n
== 1) {
932 genop(s
, MKOP_ABC(OP_EQ
, cursp(), idx
, n
));
935 if (sendv
) n
= CALL_MAXARGS
;
936 if (blk
> 0) { /* no block */
937 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, n
));
940 genop(s
, MKOP_ABC(OP_SENDB
, cursp(), idx
, n
));
953 gen_assignment(codegen_scope
*s
, node
*tree
, int sp
, int val
)
956 int type
= (intptr_t)tree
->car
;
959 switch ((intptr_t)type
) {
961 idx
= new_sym(s
, sym(tree
));
962 genop_peep(s
, MKOP_ABx(OP_SETGLOBAL
, sp
, idx
), val
);
965 idx
= lv_idx(s
, sym(tree
));
968 genop_peep(s
, MKOP_AB(OP_MOVE
, idx
, sp
), val
);
974 codegen_scope
*up
= s
->prev
;
977 idx
= lv_idx(up
, sym(tree
));
979 genop_peep(s
, MKOP_ABC(OP_SETUPVAR
, sp
, idx
, lv
), val
);
988 idx
= new_sym(s
, sym(tree
));
989 genop_peep(s
, MKOP_ABx(OP_SETIV
, sp
, idx
), val
);
992 idx
= new_sym(s
, sym(tree
));
993 genop_peep(s
, MKOP_ABx(OP_SETCV
, sp
, idx
), val
);
996 idx
= new_sym(s
, sym(tree
));
997 genop_peep(s
, MKOP_ABx(OP_SETCONST
, sp
, idx
), val
);
1000 idx
= new_sym(s
, sym(tree
->cdr
));
1001 genop_peep(s
, MKOP_AB(OP_MOVE
, cursp(), sp
), NOVAL
);
1003 codegen(s
, tree
->car
, VAL
);
1005 genop_peep(s
, MKOP_ABx(OP_SETMCNST
, cursp(), idx
), val
);
1010 gen_call(s
, tree
, attrsym(s
, sym(tree
->cdr
->car
)), sp
, NOVAL
, 0);
1013 genop_peep(s
, MKOP_AB(OP_MOVE
, cursp(), sp
), val
);
1018 gen_vmassignment(s
, tree
->car
, sp
, val
);
1021 /* splat without assignment */
1026 #ifndef MRB_DISABLE_STDIO
1027 fprintf(stderr
, "unknown lhs %d\n", type
);
1035 gen_vmassignment(codegen_scope
*s
, node
*tree
, int rhs
, int val
)
1037 int n
= 0, post
= 0;
1040 if (tree
->car
) { /* pre */
1044 genop(s
, MKOP_ABC(OP_AREF
, cursp(), rhs
, n
));
1045 gen_assignment(s
, t
->car
, cursp(), NOVAL
);
1052 if (t
->cdr
) { /* post count */
1060 genop(s
, MKOP_AB(OP_MOVE
, cursp(), rhs
));
1067 genop(s
, MKOP_ABC(OP_APOST
, cursp(), n
, post
));
1069 if (t
->car
) { /* rest */
1070 gen_assignment(s
, t
->car
, cursp(), NOVAL
);
1072 if (t
->cdr
&& t
->cdr
->car
) {
1075 gen_assignment(s
, t
->car
, cursp()+n
, NOVAL
);
1087 gen_send_intern(codegen_scope
*s
)
1090 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "intern")), 0));
1094 gen_literal_array(codegen_scope
*s
, node
*tree
, mrb_bool sym
, int val
)
1100 switch ((intptr_t)tree
->car
->car
) {
1102 if ((tree
->cdr
== NULL
) && ((intptr_t)tree
->car
->cdr
->cdr
== 0))
1106 codegen(s
, tree
->car
, VAL
);
1110 case NODE_LITERAL_DELIM
:
1121 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
1133 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), cursp(), i
));
1138 switch ((intptr_t)tree
->car
->car
) {
1139 case NODE_BEGIN
: case NODE_BLOCK
:
1140 codegen(s
, tree
->car
, NOVAL
);
1148 raise_error(codegen_scope
*s
, const char *msg
)
1150 int idx
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, msg
));
1152 genop(s
, MKOP_ABx(OP_ERR
, 1, idx
));
1156 readint_float(codegen_scope
*s
, const char *p
, int base
)
1158 const char *e
= p
+ strlen(p
);
1165 c
= tolower((unsigned char)c
);
1166 for (n
=0; n
<base
; n
++) {
1167 if (mrb_digitmap
[n
] == c
) {
1174 codegen_error(s
, "malformed readint input");
1182 readint_mrb_int(codegen_scope
*s
, const char *p
, int base
, mrb_bool neg
, mrb_bool
*overflow
)
1184 const char *e
= p
+ strlen(p
);
1188 mrb_assert(base
>= 2 && base
<= 36);
1192 c
= tolower((unsigned char)c
);
1193 for (n
=0; n
<base
; n
++) {
1194 if (mrb_digitmap
[n
] == c
) {
1199 codegen_error(s
, "malformed readint input");
1203 if ((MRB_INT_MIN
+ n
)/base
> result
) {
1211 if ((MRB_INT_MAX
- n
)/base
< result
) {
1225 gen_retval(codegen_scope
*s
, node
*tree
)
1227 if ((intptr_t)tree
->car
== NODE_SPLAT
) {
1228 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), cursp(), 0));
1230 codegen(s
, tree
, VAL
);
1232 genop(s
, MKOP_AB(OP_ARYCAT
, cursp(), cursp()+1));
1235 codegen(s
, tree
, VAL
);
1241 codegen(codegen_scope
*s
, node
*tree
, int val
)
1247 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1253 if (s
->irep
&& s
->filename_index
!= tree
->filename_index
) {
1254 s
->irep
->filename
= mrb_parser_get_filename(s
->parser
, s
->filename_index
);
1255 mrb_debug_info_append_file(s
->mrb
, s
->irep
, s
->debug_start_pos
, s
->pc
);
1256 s
->debug_start_pos
= s
->pc
;
1257 s
->filename_index
= tree
->filename_index
;
1258 s
->filename
= mrb_parser_get_filename(s
->parser
, tree
->filename_index
);
1261 nt
= (intptr_t)tree
->car
;
1262 s
->lineno
= tree
->lineno
;
1267 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1271 codegen(s
, tree
->car
, tree
->cdr
? NOVAL
: val
);
1278 int onerr
, noexc
, exend
, pos1
, pos2
, tmp
;
1279 struct loopinfo
*lp
;
1281 if (tree
->car
== NULL
) return;
1282 onerr
= genop(s
, MKOP_Bx(OP_ONERR
, 0));
1283 lp
= loop_push(s
, LOOP_BEGIN
);
1285 codegen(s
, tree
->car
, VAL
);
1287 lp
->type
= LOOP_RESCUE
;
1288 noexc
= genop(s
, MKOP_Bx(OP_JMP
, 0));
1294 node
*n2
= tree
->car
;
1297 genop(s
, MKOP_ABC(OP_RESCUE
, exc
, 0, 0));
1303 if (pos1
) dispatch(s
, pos1
);
1306 if (n4
&& n4
->car
&& (intptr_t)n4
->car
->car
== NODE_SPLAT
) {
1307 codegen(s
, n4
->car
, VAL
);
1308 genop(s
, MKOP_AB(OP_MOVE
, cursp(), exc
));
1310 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "__case_eqq")), 1));
1314 codegen(s
, n4
->car
, VAL
);
1317 genop(s
, MKOP_ABx(OP_GETCONST
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "StandardError"))));
1321 genop(s
, MKOP_ABC(OP_RESCUE
, exc
, cursp(), 1));
1323 tmp
= genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), pos2
));
1329 pos1
= genop(s
, MKOP_sBx(OP_JMP
, 0));
1330 dispatch_linked(s
, pos2
);
1334 gen_assignment(s
, n3
->cdr
->car
, exc
, NOVAL
);
1336 if (n3
->cdr
->cdr
->car
) {
1337 codegen(s
, n3
->cdr
->cdr
->car
, val
);
1340 tmp
= genop(s
, MKOP_sBx(OP_JMP
, exend
));
1347 genop(s
, MKOP_A(OP_RAISE
, exc
));
1353 genop(s
, MKOP_A(OP_POPERR
, 1));
1355 codegen(s
, tree
->car
, val
);
1360 dispatch_linked(s
, exend
);
1366 if (!tree
->cdr
|| !tree
->cdr
->cdr
||
1367 ((intptr_t)tree
->cdr
->cdr
->car
== NODE_BEGIN
&&
1368 tree
->cdr
->cdr
->cdr
)) {
1372 genop(s
, MKOP_Bx(OP_EPUSH
, 0));
1374 codegen(s
, tree
->car
, val
);
1375 idx
= scope_body(s
, tree
->cdr
, NOVAL
);
1376 s
->iseq
[epush
] = MKOP_Bx(OP_EPUSH
, idx
);
1378 genop_peep(s
, MKOP_A(OP_EPOP
, 1), NOVAL
);
1380 else { /* empty ensure ignored */
1381 codegen(s
, tree
->car
, val
);
1387 int idx
= lambda_body(s
, tree
, 1);
1389 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), idx
, OP_L_LAMBDA
));
1396 int idx
= lambda_body(s
, tree
, 1);
1398 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), idx
, OP_L_BLOCK
));
1406 node
*e
= tree
->cdr
->cdr
->car
;
1412 switch ((intptr_t)tree
->car
->car
) {
1416 codegen(s
, tree
->cdr
->car
, val
);
1423 codegen(s
, tree
->car
, VAL
);
1425 pos1
= genop_peep(s
, MKOP_AsBx(OP_JMPNOT
, cursp(), 0), NOVAL
);
1427 codegen(s
, tree
->cdr
->car
, val
);
1430 pos2
= genop(s
, MKOP_sBx(OP_JMP
, 0));
1438 pos2
= genop(s
, MKOP_sBx(OP_JMP
, 0));
1440 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1455 codegen(s
, tree
->car
, VAL
);
1457 pos
= genop(s
, MKOP_AsBx(OP_JMPNOT
, cursp(), 0));
1458 codegen(s
, tree
->cdr
, val
);
1467 codegen(s
, tree
->car
, VAL
);
1469 pos
= genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), 0));
1470 codegen(s
, tree
->cdr
, val
);
1477 struct loopinfo
*lp
= loop_push(s
, LOOP_NORMAL
);
1479 lp
->pc1
= genop(s
, MKOP_sBx(OP_JMP
, 0));
1480 lp
->pc2
= new_label(s
);
1481 codegen(s
, tree
->cdr
, NOVAL
);
1482 dispatch(s
, lp
->pc1
);
1483 codegen(s
, tree
->car
, VAL
);
1485 genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), lp
->pc2
- s
->pc
));
1493 struct loopinfo
*lp
= loop_push(s
, LOOP_NORMAL
);
1495 lp
->pc1
= genop(s
, MKOP_sBx(OP_JMP
, 0));
1496 lp
->pc2
= new_label(s
);
1497 codegen(s
, tree
->cdr
, NOVAL
);
1498 dispatch(s
, lp
->pc1
);
1499 codegen(s
, tree
->car
, VAL
);
1501 genop(s
, MKOP_AsBx(OP_JMPNOT
, cursp(), lp
->pc2
- s
->pc
));
1515 int pos1
, pos2
, pos3
, tmp
;
1521 codegen(s
, tree
->car
, VAL
);
1528 codegen(s
, n
->car
, VAL
);
1530 genop(s
, MKOP_AB(OP_MOVE
, cursp(), head
));
1532 if ((intptr_t)n
->car
->car
== NODE_SPLAT
) {
1533 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "__case_eqq")), 1));
1536 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "===")), 1));
1542 tmp
= genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), pos2
));
1546 if (tree
->car
->car
) {
1547 pos1
= genop(s
, MKOP_sBx(OP_JMP
, 0));
1548 dispatch_linked(s
, pos2
);
1550 codegen(s
, tree
->car
->cdr
, val
);
1552 tmp
= genop(s
, MKOP_sBx(OP_JMP
, pos3
));
1554 if (pos1
) dispatch(s
, pos1
);
1559 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1560 if (pos3
) dispatch_linked(s
, pos3
);
1562 if (cursp() != pos
) {
1563 genop(s
, MKOP_AB(OP_MOVE
, cursp(), pos
));
1569 dispatch_linked(s
, pos3
);
1579 scope_body(s
, tree
, NOVAL
);
1584 gen_call(s
, tree
, 0, 0, val
, 0);
1587 gen_call(s
, tree
, 0, 0, val
, 1);
1591 codegen(s
, tree
->car
, val
);
1592 codegen(s
, tree
->cdr
, val
);
1595 genop(s
, MKOP_ABC(OP_RANGE
, cursp(), cursp(), FALSE
));
1601 codegen(s
, tree
->car
, val
);
1602 codegen(s
, tree
->cdr
, val
);
1605 genop(s
, MKOP_ABC(OP_RANGE
, cursp(), cursp(), TRUE
));
1612 int sym
= new_sym(s
, sym(tree
->cdr
));
1614 codegen(s
, tree
->car
, VAL
);
1616 genop(s
, MKOP_ABx(OP_GETMCNST
, cursp(), sym
));
1623 int sym
= new_sym(s
, sym(tree
));
1625 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
1626 genop(s
, MKOP_ABx(OP_GETMCNST
, cursp(), sym
));
1635 n
= gen_values(s
, tree
, val
, 0);
1639 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), cursp(), n
));
1652 mrb_bool update
= FALSE
;
1655 codegen(s
, tree
->car
->car
, val
);
1656 codegen(s
, tree
->car
->cdr
, val
);
1659 if (val
&& len
== 126) {
1661 genop(s
, MKOP_ABC(OP_HASH
, cursp(), cursp(), len
));
1664 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "__update")), 1));
1673 genop(s
, MKOP_ABC(OP_HASH
, cursp(), cursp(), len
));
1676 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "__update")), 1));
1684 codegen(s
, tree
, val
);
1688 codegen(s
, tree
->cdr
, VAL
);
1690 gen_assignment(s
, tree
->car
, cursp(), val
);
1695 int len
= 0, n
= 0, post
= 0;
1696 node
*t
= tree
->cdr
, *p
;
1699 if ((intptr_t)t
->car
== NODE_ARRAY
&& t
->cdr
&& nosplat(t
->cdr
)) {
1703 codegen(s
, t
->car
, VAL
);
1708 if (tree
->car
) { /* pre */
1713 gen_assignment(s
, t
->car
, rhs
+n
, NOVAL
);
1717 genop(s
, MKOP_A(OP_LOADNIL
, rhs
+n
));
1718 gen_assignment(s
, t
->car
, rhs
+n
, NOVAL
);
1725 if (t
->cdr
) { /* post count */
1732 if (t
->car
) { /* rest (len - pre - post) */
1735 if (len
< post
+ n
) {
1739 rn
= len
- post
- n
;
1741 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), rhs
+n
, rn
));
1742 gen_assignment(s
, t
->car
, cursp(), NOVAL
);
1745 if (t
->cdr
&& t
->cdr
->car
) {
1748 gen_assignment(s
, t
->car
, rhs
+n
, NOVAL
);
1756 genop(s
, MKOP_ABC(OP_ARRAY
, rhs
, rhs
, len
));
1763 gen_vmassignment(s
, tree
->car
, rhs
, val
);
1773 mrb_sym sym
= sym(tree
->cdr
->car
);
1775 const char *name
= mrb_sym2name_len(s
->mrb
, sym
, &len
);
1776 int idx
, callargs
= -1, vsp
= -1;
1778 if ((len
== 2 && name
[0] == '|' && name
[1] == '|') &&
1779 ((intptr_t)tree
->car
->car
== NODE_CONST
||
1780 (intptr_t)tree
->car
->car
== NODE_CVAR
)) {
1781 int onerr
, noexc
, exc
;
1782 struct loopinfo
*lp
;
1784 onerr
= genop(s
, MKOP_Bx(OP_ONERR
, 0));
1785 lp
= loop_push(s
, LOOP_BEGIN
);
1788 codegen(s
, tree
->car
, VAL
);
1789 lp
->type
= LOOP_RESCUE
;
1790 genop(s
, MKOP_A(OP_POPERR
, 1));
1791 noexc
= genop(s
, MKOP_Bx(OP_JMP
, 0));
1793 genop(s
, MKOP_ABC(OP_RESCUE
, exc
, 0, 0));
1794 genop(s
, MKOP_A(OP_LOADF
, exc
));
1798 else if ((intptr_t)tree
->car
->car
== NODE_CALL
) {
1799 node
*n
= tree
->car
->cdr
;
1805 codegen(s
, n
->car
, VAL
); /* receiver */
1806 idx
= new_msym(s
, sym(n
->cdr
->car
));
1807 if (n
->cdr
->cdr
->car
) {
1808 int base
= cursp()-1;
1809 int nargs
= gen_values(s
, n
->cdr
->cdr
->car
->car
, VAL
, 1);
1811 /* copy receiver and arguments */
1815 genop(s
, MKOP_AB(OP_MOVE
, cursp(), base
));
1816 for (i
=0; i
<nargs
; i
++) {
1817 genop(s
, MKOP_AB(OP_MOVE
, cursp()+i
+1, base
+i
+1));
1826 genop(s
, MKOP_AB(OP_MOVE
, cursp(), base
));
1827 genop(s
, MKOP_AB(OP_MOVE
, cursp()+1, base
+1));
1828 callargs
= CALL_MAXARGS
;
1830 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, callargs
));
1833 genop(s
, MKOP_AB(OP_MOVE
, cursp(), cursp()-1));
1834 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, 0));
1840 codegen(s
, tree
->car
, VAL
);
1843 ((name
[0] == '|' && name
[1] == '|') ||
1844 (name
[0] == '&' && name
[1] == '&'))) {
1850 genop(s
, MKOP_AB(OP_MOVE
, vsp
, cursp()));
1852 pos
= genop(s
, MKOP_AsBx(name
[0]=='|'?OP_JMPIF
:OP_JMPNOT
, cursp(), 0));
1855 pos
= genop_peep(s
, MKOP_AsBx(name
[0]=='|'?OP_JMPIF
:OP_JMPNOT
, cursp(), 0), NOVAL
);
1857 codegen(s
, tree
->cdr
->cdr
->car
, VAL
);
1859 if (val
&& vsp
>= 0) {
1860 genop(s
, MKOP_AB(OP_MOVE
, vsp
, cursp()));
1862 if ((intptr_t)tree
->car
->car
== NODE_CALL
) {
1863 mrb_sym m
= sym(tree
->car
->cdr
->cdr
->car
);
1864 mrb_sym m2
= attrsym(s
, m
);
1866 idx
= new_msym(s
, m2
);
1868 if (callargs
== CALL_MAXARGS
) {
1869 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), cursp()+1));
1871 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, callargs
));
1875 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, callargs
+1));
1879 gen_assignment(s
, tree
->car
, cursp(), val
);
1884 codegen(s
, tree
->cdr
->cdr
->car
, VAL
);
1888 idx
= new_msym(s
, sym
);
1889 if (len
== 1 && name
[0] == '+') {
1890 genop_peep(s
, MKOP_ABC(OP_ADD
, cursp(), idx
, 1), val
);
1892 else if (len
== 1 && name
[0] == '-') {
1893 genop_peep(s
, MKOP_ABC(OP_SUB
, cursp(), idx
, 1), val
);
1895 else if (len
== 1 && name
[0] == '*') {
1896 genop(s
, MKOP_ABC(OP_MUL
, cursp(), idx
, 1));
1898 else if (len
== 1 && name
[0] == '/') {
1899 genop(s
, MKOP_ABC(OP_DIV
, cursp(), idx
, 1));
1901 else if (len
== 1 && name
[0] == '<') {
1902 genop(s
, MKOP_ABC(OP_LT
, cursp(), idx
, 1));
1904 else if (len
== 2 && name
[0] == '<' && name
[1] == '=') {
1905 genop(s
, MKOP_ABC(OP_LE
, cursp(), idx
, 1));
1907 else if (len
== 1 && name
[0] == '>') {
1908 genop(s
, MKOP_ABC(OP_GT
, cursp(), idx
, 1));
1910 else if (len
== 2 && name
[0] == '>' && name
[1] == '=') {
1911 genop(s
, MKOP_ABC(OP_GE
, cursp(), idx
, 1));
1914 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, 1));
1917 gen_assignment(s
, tree
->car
, cursp(), val
);
1920 if (val
&& vsp
>= 0) {
1921 genop(s
, MKOP_AB(OP_MOVE
, vsp
, cursp()));
1923 if (callargs
== CALL_MAXARGS
) {
1925 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), cursp()+1));
1932 idx
= new_msym(s
, attrsym(s
,sym(tree
->car
->cdr
->cdr
->car
)));
1933 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, callargs
));
1940 int n
= 0, noop
= 0, sendv
= 0;
1942 push(); /* room for receiver */
1944 node
*args
= tree
->car
;
1946 n
= gen_values(s
, args
, VAL
, 0);
1948 n
= noop
= sendv
= 1;
1953 if (tree
&& tree
->cdr
) {
1954 codegen(s
, tree
->cdr
, VAL
);
1958 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1962 if (sendv
) n
= CALL_MAXARGS
;
1963 genop(s
, MKOP_ABC(OP_SUPER
, cursp(), 0, n
));
1970 codegen_scope
*s2
= s
;
1971 int lv
= 0, ainfo
= 0;
1973 push(); /* room for receiver */
1974 while (!s2
->mscope
) {
1979 if (s2
) ainfo
= s2
->ainfo
;
1980 genop(s
, MKOP_ABx(OP_ARGARY
, cursp(), (ainfo
<<4)|(lv
& 0xf)));
1981 push(); push(); pop(); /* ARGARY pushes two values */
1982 if (tree
&& tree
->cdr
) {
1983 codegen(s
, tree
->cdr
, VAL
);
1987 genop(s
, MKOP_ABC(OP_SUPER
, cursp(), 0, CALL_MAXARGS
));
1994 gen_retval(s
, tree
);
1997 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2000 genop(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_RETURN
));
2003 genop_peep(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_NORMAL
), NOVAL
);
2010 codegen_scope
*s2
= s
;
2011 int lv
= 0, ainfo
= 0;
2012 int n
= 0, sendv
= 0;
2014 while (!s2
->mscope
) {
2019 if (s2
) ainfo
= s2
->ainfo
;
2022 n
= gen_values(s
, tree
, VAL
, 0);
2029 genop(s
, MKOP_ABx(OP_BLKPUSH
, cursp(), (ainfo
<<4)|(lv
& 0xf)));
2030 if (sendv
) n
= CALL_MAXARGS
;
2031 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "call")), n
));
2037 loop_break(s
, tree
);
2043 raise_error(s
, "unexpected next");
2045 else if (s
->loop
->type
== LOOP_NORMAL
) {
2046 if (s
->ensure_level
> s
->loop
->ensure_level
) {
2047 genop_peep(s
, MKOP_A(OP_EPOP
, s
->ensure_level
- s
->loop
->ensure_level
), NOVAL
);
2049 codegen(s
, tree
, NOVAL
);
2050 genop(s
, MKOP_sBx(OP_JMP
, s
->loop
->pc1
- s
->pc
));
2054 codegen(s
, tree
, VAL
);
2058 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2060 genop_peep(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_NORMAL
), NOVAL
);
2066 if (!s
->loop
|| s
->loop
->type
== LOOP_BEGIN
|| s
->loop
->type
== LOOP_RESCUE
) {
2067 raise_error(s
, "unexpected redo");
2070 if (s
->ensure_level
> s
->loop
->ensure_level
) {
2071 genop_peep(s
, MKOP_A(OP_EPOP
, s
->ensure_level
- s
->loop
->ensure_level
), NOVAL
);
2073 genop(s
, MKOP_sBx(OP_JMP
, s
->loop
->pc2
- s
->pc
));
2080 const char *msg
= "unexpected retry";
2083 raise_error(s
, msg
);
2086 struct loopinfo
*lp
= s
->loop
;
2089 while (lp
&& lp
->type
!= LOOP_RESCUE
) {
2090 if (lp
->type
== LOOP_BEGIN
) {
2096 raise_error(s
, msg
);
2101 genop_peep(s
, MKOP_A(OP_POPERR
, 1), NOVAL
);
2104 if (s
->ensure_level
> lp
->ensure_level
) {
2105 genop_peep(s
, MKOP_A(OP_EPOP
, s
->ensure_level
- lp
->ensure_level
), NOVAL
);
2107 genop(s
, MKOP_sBx(OP_JMP
, lp
->pc1
- s
->pc
));
2116 int idx
= lv_idx(s
, sym(tree
));
2119 genop_peep(s
, MKOP_AB(OP_MOVE
, cursp(), idx
), NOVAL
);
2123 codegen_scope
*up
= s
->prev
;
2126 idx
= lv_idx(up
, sym(tree
));
2128 genop(s
, MKOP_ABC(OP_GETUPVAR
, cursp(), idx
, lv
));
2141 int sym
= new_sym(s
, sym(tree
));
2143 genop(s
, MKOP_ABx(OP_GETGLOBAL
, cursp(), sym
));
2150 int sym
= new_sym(s
, sym(tree
));
2152 genop(s
, MKOP_ABx(OP_GETIV
, cursp(), sym
));
2159 int sym
= new_sym(s
, sym(tree
));
2161 genop(s
, MKOP_ABx(OP_GETCV
, cursp(), sym
));
2168 int sym
= new_sym(s
, sym(tree
));
2170 genop(s
, MKOP_ABx(OP_GETCONST
, cursp(), sym
));
2178 codegen(s
, tree
, VAL
);
2187 buf
[1] = (char)(intptr_t)tree
;
2189 sym
= new_sym(s
, mrb_intern_cstr(s
->mrb
, buf
));
2190 genop(s
, MKOP_ABx(OP_GETGLOBAL
, cursp(), sym
));
2197 mrb_state
*mrb
= s
->mrb
;
2201 str
= mrb_format(mrb
, "$%S", mrb_fixnum_value((mrb_int
)(intptr_t)tree
));
2202 sym
= new_sym(s
, mrb_intern_str(mrb
, str
));
2203 genop(s
, MKOP_ABx(OP_GETGLOBAL
, cursp(), sym
));
2209 /* should not happen */
2212 case NODE_BLOCK_ARG
:
2213 codegen(s
, tree
, VAL
);
2218 char *p
= (char*)tree
->car
;
2219 int base
= (intptr_t)tree
->cdr
->car
;
2224 i
= readint_mrb_int(s
, p
, base
, FALSE
, &overflow
);
2226 double f
= readint_float(s
, p
, base
);
2227 int off
= new_lit(s
, mrb_float_value(s
->mrb
, f
));
2229 genop(s
, MKOP_ABx(OP_LOADL
, cursp(), off
));
2232 if (i
< MAXARG_sBx
&& i
> -MAXARG_sBx
) {
2233 co
= MKOP_AsBx(OP_LOADI
, cursp(), i
);
2236 int off
= new_lit(s
, mrb_fixnum_value(i
));
2237 co
= MKOP_ABx(OP_LOADL
, cursp(), off
);
2247 char *p
= (char*)tree
;
2248 mrb_float f
= mrb_float_read(p
, NULL
);
2249 int off
= new_lit(s
, mrb_float_value(s
->mrb
, f
));
2251 genop(s
, MKOP_ABx(OP_LOADL
, cursp(), off
));
2258 nt
= (intptr_t)tree
->car
;
2263 char *p
= (char*)tree
;
2264 mrb_float f
= mrb_float_read(p
, NULL
);
2265 int off
= new_lit(s
, mrb_float_value(s
->mrb
, -f
));
2267 genop(s
, MKOP_ABx(OP_LOADL
, cursp(), off
));
2274 char *p
= (char*)tree
->car
;
2275 int base
= (intptr_t)tree
->cdr
->car
;
2280 i
= readint_mrb_int(s
, p
, base
, TRUE
, &overflow
);
2282 double f
= readint_float(s
, p
, base
);
2283 int off
= new_lit(s
, mrb_float_value(s
->mrb
, -f
));
2285 genop(s
, MKOP_ABx(OP_LOADL
, cursp(), off
));
2288 if (i
< MAXARG_sBx
&& i
> -MAXARG_sBx
) {
2289 co
= MKOP_AsBx(OP_LOADI
, cursp(), i
);
2292 int off
= new_lit(s
, mrb_fixnum_value(i
));
2293 co
= MKOP_ABx(OP_LOADL
, cursp(), off
);
2303 int sym
= new_msym(s
, mrb_intern_lit(s
->mrb
, "-"));
2305 genop(s
, MKOP_ABx(OP_LOADI
, cursp(), 0));
2307 codegen(s
, tree
, VAL
);
2309 genop(s
, MKOP_ABC(OP_SUB
, cursp(), sym
, 2));
2312 codegen(s
, tree
, NOVAL
);
2321 char *p
= (char*)tree
->car
;
2322 size_t len
= (intptr_t)tree
->cdr
;
2323 int ai
= mrb_gc_arena_save(s
->mrb
);
2324 int off
= new_lit(s
, mrb_str_new(s
->mrb
, p
, len
));
2326 mrb_gc_arena_restore(s
->mrb
, ai
);
2327 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2333 tree
= ((struct mrb_parser_heredoc_info
*)tree
)->doc
;
2340 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2344 codegen(s
, n
->car
, VAL
);
2347 codegen(s
, n
->car
, VAL
);
2349 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
2358 if ((intptr_t)n
->car
->car
!= NODE_STR
) {
2359 codegen(s
, n
->car
, NOVAL
);
2367 gen_literal_array(s
, tree
, FALSE
, val
);
2371 gen_literal_array(s
, tree
, TRUE
, val
);
2377 int ai
= mrb_gc_arena_save(s
->mrb
);
2378 int sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "Kernel"));
2380 genop(s
, MKOP_A(OP_LOADSELF
, cursp()));
2382 codegen(s
, tree
->car
, VAL
);
2385 if ((intptr_t)n
->car
->car
== NODE_XSTR
) {
2386 n
->car
->car
= (struct mrb_ast_node
*)(intptr_t)NODE_STR
;
2387 mrb_assert(!n
->cdr
); /* must be the end */
2389 codegen(s
, n
->car
, VAL
);
2391 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
2395 push(); /* for block */
2397 sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "`"));
2398 genop(s
, MKOP_ABC(OP_SEND
, cursp(), sym
, 1));
2400 mrb_gc_arena_restore(s
->mrb
, ai
);
2406 char *p
= (char*)tree
->car
;
2407 size_t len
= (intptr_t)tree
->cdr
;
2408 int ai
= mrb_gc_arena_save(s
->mrb
);
2409 int off
= new_lit(s
, mrb_str_new(s
->mrb
, p
, len
));
2412 genop(s
, MKOP_A(OP_LOADSELF
, cursp()));
2414 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2417 sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "`"));
2418 genop(s
, MKOP_ABC(OP_SEND
, cursp(), sym
, 1));
2420 mrb_gc_arena_restore(s
->mrb
, ai
);
2426 char *p1
= (char*)tree
->car
;
2427 char *p2
= (char*)tree
->cdr
->car
;
2428 char *p3
= (char*)tree
->cdr
->cdr
;
2429 int ai
= mrb_gc_arena_save(s
->mrb
);
2430 int sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, REGEXP_CLASS
));
2431 int off
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, p1
));
2434 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
2435 genop(s
, MKOP_ABx(OP_GETMCNST
, cursp(), sym
));
2437 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2441 off
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, p2
));
2442 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2445 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2450 off
= new_lit(s
, mrb_str_new(s
->mrb
, p3
, 1));
2451 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2458 sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "compile"));
2459 genop(s
, MKOP_ABC(OP_SEND
, cursp(), sym
, argc
));
2460 mrb_gc_arena_restore(s
->mrb
, ai
);
2467 node
*n
= tree
->car
;
2468 int ai
= mrb_gc_arena_save(s
->mrb
);
2469 int sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, REGEXP_CLASS
));
2474 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
2475 genop(s
, MKOP_ABx(OP_GETMCNST
, cursp(), sym
));
2477 codegen(s
, n
->car
, VAL
);
2480 codegen(s
, n
->car
, VAL
);
2482 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
2489 off
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, p
));
2490 codegen(s
, tree
->car
, VAL
);
2491 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2493 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
2496 char *p2
= (char*)n
->cdr
->car
;
2499 off
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, p2
));
2500 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2504 char *p2
= (char*)n
->cdr
->cdr
;
2507 off
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, p2
));
2508 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2512 sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "compile"));
2513 genop(s
, MKOP_ABC(OP_SEND
, cursp(), sym
, argc
));
2514 mrb_gc_arena_restore(s
->mrb
, ai
);
2518 node
*n
= tree
->car
;
2521 if ((intptr_t)n
->car
->car
!= NODE_STR
) {
2522 codegen(s
, n
->car
, NOVAL
);
2531 int sym
= new_sym(s
, sym(tree
));
2533 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), sym
));
2539 codegen(s
, tree
, val
);
2547 genop(s
, MKOP_A(OP_LOADSELF
, cursp()));
2554 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2561 genop(s
, MKOP_A(OP_LOADT
, cursp()));
2568 genop(s
, MKOP_A(OP_LOADF
, cursp()));
2575 int a
= new_msym(s
, sym(tree
->car
));
2576 int b
= new_msym(s
, sym(tree
->cdr
));
2577 int c
= new_msym(s
, mrb_intern_lit(s
->mrb
, "alias_method"));
2579 genop(s
, MKOP_A(OP_TCLASS
, cursp()));
2581 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), a
));
2583 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), b
));
2585 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2588 genop(s
, MKOP_ABC(OP_SEND
, cursp(), c
, 2));
2597 int undef
= new_msym(s
, mrb_intern_lit(s
->mrb
, "undef_method"));
2601 genop(s
, MKOP_A(OP_TCLASS
, cursp()));
2605 if (num
>= CALL_MAXARGS
- 1) {
2607 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), cursp(), num
));
2609 symbol
= new_msym(s
, sym(t
->car
));
2611 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), symbol
));
2613 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), cursp()+1));
2619 symbol
= new_msym(s
, sym(t
->car
));
2620 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), symbol
));
2626 if (num
< CALL_MAXARGS
) {
2629 genop(s
, MKOP_ABC(OP_SEND
, cursp(), undef
, num
));
2640 if (tree
->car
->car
== (node
*)0) {
2641 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2644 else if (tree
->car
->car
== (node
*)1) {
2645 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
2649 codegen(s
, tree
->car
->car
, VAL
);
2651 if (tree
->cdr
->car
) {
2652 codegen(s
, tree
->cdr
->car
, VAL
);
2655 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2659 idx
= new_msym(s
, sym(tree
->car
->cdr
));
2660 genop(s
, MKOP_AB(OP_CLASS
, cursp(), idx
));
2661 idx
= scope_body(s
, tree
->cdr
->cdr
->car
, val
);
2662 genop(s
, MKOP_ABx(OP_EXEC
, cursp(), idx
));
2673 if (tree
->car
->car
== (node
*)0) {
2674 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2677 else if (tree
->car
->car
== (node
*)1) {
2678 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
2682 codegen(s
, tree
->car
->car
, VAL
);
2685 idx
= new_msym(s
, sym(tree
->car
->cdr
));
2686 genop(s
, MKOP_AB(OP_MODULE
, cursp(), idx
));
2687 idx
= scope_body(s
, tree
->cdr
->car
, val
);
2688 genop(s
, MKOP_ABx(OP_EXEC
, cursp(), idx
));
2699 codegen(s
, tree
->car
, VAL
);
2701 genop(s
, MKOP_AB(OP_SCLASS
, cursp(), cursp()));
2702 idx
= scope_body(s
, tree
->cdr
->car
, val
);
2703 genop(s
, MKOP_ABx(OP_EXEC
, cursp(), idx
));
2712 int sym
= new_msym(s
, sym(tree
->car
));
2713 int idx
= lambda_body(s
, tree
->cdr
, 0);
2715 genop(s
, MKOP_A(OP_TCLASS
, cursp()));
2717 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), idx
, OP_L_METHOD
));
2720 genop(s
, MKOP_AB(OP_METHOD
, cursp(), sym
));
2722 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), sym
));
2730 node
*recv
= tree
->car
;
2731 int sym
= new_msym(s
, sym(tree
->cdr
->car
));
2732 int idx
= lambda_body(s
, tree
->cdr
->cdr
, 0);
2734 codegen(s
, recv
, VAL
);
2736 genop(s
, MKOP_AB(OP_SCLASS
, cursp(), cursp()));
2738 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), idx
, OP_L_METHOD
));
2740 genop(s
, MKOP_AB(OP_METHOD
, cursp(), sym
));
2742 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), sym
));
2749 codegen(s
, tree
, NOVAL
);
2758 scope_add_irep(codegen_scope
*s
, mrb_irep
*irep
)
2760 if (s
->irep
== NULL
) {
2764 if (s
->irep
->rlen
== s
->rcapa
) {
2766 s
->irep
->reps
= (mrb_irep
**)codegen_realloc(s
, s
->irep
->reps
, sizeof(mrb_irep
*)*s
->rcapa
);
2768 s
->irep
->reps
[s
->irep
->rlen
] = irep
;
2772 static codegen_scope
*
2773 scope_new(mrb_state
*mrb
, codegen_scope
*prev
, node
*lv
)
2775 static const codegen_scope codegen_scope_zero
= { 0 };
2776 mrb_pool
*pool
= mrb_pool_open(mrb
);
2777 codegen_scope
*p
= (codegen_scope
*)mrb_pool_alloc(pool
, sizeof(codegen_scope
));
2779 if (!p
) return NULL
;
2780 *p
= codegen_scope_zero
;
2783 if (!prev
) return p
;
2788 p
->irep
= mrb_add_irep(mrb
);
2789 scope_add_irep(prev
, p
->irep
);
2792 p
->irep
->reps
= (mrb_irep
**)mrb_malloc(mrb
, sizeof(mrb_irep
*)*p
->rcapa
);
2795 p
->iseq
= (mrb_code
*)mrb_malloc(mrb
, sizeof(mrb_code
)*p
->icapa
);
2796 p
->irep
->iseq
= NULL
;
2799 p
->irep
->pool
= (mrb_value
*)mrb_malloc(mrb
, sizeof(mrb_value
)*p
->pcapa
);
2802 p
->scapa
= MAXMSYMLEN
;
2803 p
->irep
->syms
= (mrb_sym
*)mrb_malloc(mrb
, sizeof(mrb_sym
)*p
->scapa
);
2807 p
->sp
+= node_len(lv
)+1; /* add self */
2813 p
->irep
->lv
= (struct mrb_locals
*)mrb_malloc(mrb
, sizeof(struct mrb_locals
) * (p
->nlocals
- 1));
2814 for (i
=0, n
=lv
; n
; i
++,n
=n
->cdr
) {
2815 p
->irep
->lv
[i
].name
= lv_name(n
);
2817 p
->irep
->lv
[i
].r
= lv_idx(p
, lv_name(n
));
2820 p
->irep
->lv
[i
].r
= 0;
2823 mrb_assert(i
+ 1 == p
->nlocals
);
2825 p
->ai
= mrb_gc_arena_save(mrb
);
2827 p
->filename
= prev
->filename
;
2829 p
->lines
= (uint16_t*)mrb_malloc(mrb
, sizeof(short)*p
->icapa
);
2831 p
->lineno
= prev
->lineno
;
2834 p
->debug_start_pos
= 0;
2836 mrb_debug_info_alloc(mrb
, p
->irep
);
2837 p
->irep
->filename
= p
->filename
;
2838 p
->irep
->lines
= p
->lines
;
2841 p
->irep
->debug_info
= NULL
;
2843 p
->parser
= prev
->parser
;
2844 p
->filename_index
= prev
->filename_index
;
2850 scope_finish(codegen_scope
*s
)
2852 mrb_state
*mrb
= s
->mrb
;
2853 mrb_irep
*irep
= s
->irep
;
2859 irep
->iseq
= (mrb_code
*)codegen_realloc(s
, s
->iseq
, sizeof(mrb_code
)*s
->pc
);
2862 irep
->lines
= (uint16_t *)codegen_realloc(s
, s
->lines
, sizeof(uint16_t)*s
->pc
);
2868 irep
->pool
= (mrb_value
*)codegen_realloc(s
, irep
->pool
, sizeof(mrb_value
)*irep
->plen
);
2869 irep
->syms
= (mrb_sym
*)codegen_realloc(s
, irep
->syms
, sizeof(mrb_sym
)*irep
->slen
);
2870 irep
->reps
= (mrb_irep
**)codegen_realloc(s
, irep
->reps
, sizeof(mrb_irep
*)*irep
->rlen
);
2872 irep
->filename
= mrb_parser_get_filename(s
->parser
, s
->filename_index
);
2873 mrb_debug_info_append_file(mrb
, irep
, s
->debug_start_pos
, s
->pc
);
2875 fname_len
= strlen(s
->filename
);
2876 fname
= (char*)codegen_malloc(s
, fname_len
+ 1);
2877 memcpy(fname
, s
->filename
, fname_len
);
2878 fname
[fname_len
] = '\0';
2879 irep
->filename
= fname
;
2880 irep
->own_filename
= TRUE
;
2883 irep
->nlocals
= s
->nlocals
;
2884 irep
->nregs
= s
->nregs
;
2886 mrb_gc_arena_restore(mrb
, s
->ai
);
2887 mrb_pool_close(s
->mpool
);
2890 static struct loopinfo
*
2891 loop_push(codegen_scope
*s
, enum looptype t
)
2893 struct loopinfo
*p
= (struct loopinfo
*)codegen_palloc(s
, sizeof(struct loopinfo
));
2896 p
->pc1
= p
->pc2
= p
->pc3
= 0;
2898 p
->ensure_level
= s
->ensure_level
;
2906 loop_break(codegen_scope
*s
, node
*tree
)
2909 codegen(s
, tree
, NOVAL
);
2910 raise_error(s
, "unexpected break");
2913 struct loopinfo
*loop
;
2916 gen_retval(s
, tree
);
2920 while (loop
&& loop
->type
== LOOP_BEGIN
) {
2921 genop_peep(s
, MKOP_A(OP_POPERR
, 1), NOVAL
);
2924 while (loop
&& loop
->type
== LOOP_RESCUE
) {
2928 raise_error(s
, "unexpected break");
2932 if (loop
->type
== LOOP_NORMAL
) {
2935 if (s
->ensure_level
> s
->loop
->ensure_level
) {
2936 genop_peep(s
, MKOP_A(OP_EPOP
, s
->ensure_level
- s
->loop
->ensure_level
), NOVAL
);
2939 genop_peep(s
, MKOP_AB(OP_MOVE
, loop
->acc
, cursp()), NOVAL
);
2941 tmp
= genop(s
, MKOP_sBx(OP_JMP
, loop
->pc3
));
2946 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2948 genop(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_BREAK
));
2954 loop_pop(codegen_scope
*s
, int val
)
2956 dispatch_linked(s
, s
->loop
->pc3
);
2958 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2960 s
->loop
= s
->loop
->prev
;
2964 MRB_API
struct RProc
*
2965 mrb_generate_code(mrb_state
*mrb
, parser_state
*p
)
2967 codegen_scope
*scope
= scope_new(mrb
, 0, 0);
2975 scope
->filename
= p
->filename
;
2976 scope
->filename_index
= p
->current_filename_index
;
2978 MRB_TRY(&scope
->jmp
) {
2980 codegen(scope
, p
->tree
, NOVAL
);
2981 proc
= mrb_proc_new(mrb
, scope
->irep
);
2982 mrb_irep_decref(mrb
, scope
->irep
);
2983 mrb_pool_close(scope
->mpool
);
2986 MRB_CATCH(&scope
->jmp
) {
2987 mrb_irep_decref(mrb
, scope
->irep
);
2988 mrb_pool_close(scope
->mpool
);
2991 MRB_END_EXC(&scope
->jmp
);