2 ** codegen.c - mruby code generator
4 ** See Copyright Notice in mruby.h
11 #include "mruby/compile.h"
12 #include "mruby/proc.h"
13 #include "mruby/numeric.h"
14 #include "mruby/string.h"
15 #include "mruby/debug.h"
20 typedef mrb_ast_node node
;
21 typedef struct mrb_parser_state parser_state
;
33 int pc1
, pc2
, pc3
, acc
;
35 struct loopinfo
*prev
;
38 typedef struct scope
{
53 struct loopinfo
*loop
;
72 uint16_t filename_index
;
76 static codegen_scope
* scope_new(mrb_state
*mrb
, codegen_scope
*prev
, node
*lv
);
77 static void scope_finish(codegen_scope
*s
);
78 static struct loopinfo
*loop_push(codegen_scope
*s
, enum looptype t
);
79 static void loop_break(codegen_scope
*s
, node
*tree
);
80 static void loop_pop(codegen_scope
*s
, int val
);
82 static void gen_assignment(codegen_scope
*s
, node
*node
, int sp
, int val
);
83 static void gen_vmassignment(codegen_scope
*s
, node
*tree
, int rhs
, int val
);
85 static void codegen(codegen_scope
*s
, node
*tree
, int val
);
88 codegen_error(codegen_scope
*s
, const char *message
)
92 codegen_scope
*tmp
= s
->prev
;
93 mrb_pool_close(s
->mpool
);
97 if (s
->filename
&& s
->lineno
) {
98 fprintf(stderr
, "codegen error:%s:%d: %s\n", s
->filename
, s
->lineno
, message
);
101 fprintf(stderr
, "codegen error: %s\n", message
);
108 codegen_palloc(codegen_scope
*s
, size_t len
)
110 void *p
= mrb_pool_alloc(s
->mpool
, len
);
112 if (!p
) codegen_error(s
, "pool memory allocation");
117 codegen_malloc(codegen_scope
*s
, size_t len
)
119 void *p
= mrb_malloc_simple(s
->mrb
, len
);
121 if (!p
) codegen_error(s
, "mrb_malloc");
126 codegen_realloc(codegen_scope
*s
, void *p
, size_t len
)
128 p
= mrb_realloc_simple(s
->mrb
, p
, len
);
130 if (!p
&& len
> 0) codegen_error(s
, "mrb_realloc");
135 new_label(codegen_scope
*s
)
137 s
->lastlabel
= s
->pc
;
142 genop(codegen_scope
*s
, mrb_code i
)
144 if (s
->pc
== s
->icapa
) {
146 s
->iseq
= (mrb_code
*)codegen_realloc(s
, s
->iseq
, sizeof(mrb_code
)*s
->icapa
);
148 s
->lines
= (uint16_t*)codegen_realloc(s
, s
->lines
, sizeof(short)*s
->icapa
);
149 s
->irep
->lines
= s
->lines
;
154 s
->lines
[s
->pc
] = s
->lineno
;
163 genop_peep(codegen_scope
*s
, mrb_code i
, int val
)
165 /* peephole optimization */
166 if (s
->lastlabel
!= s
->pc
&& s
->pc
> 0) {
167 mrb_code i0
= s
->iseq
[s
->pc
-1];
168 int c1
= GET_OPCODE(i
);
169 int c0
= GET_OPCODE(i0
);
173 if (GETARG_A(i
) == GETARG_B(i
)) {
174 /* skip useless OP_MOVE */
180 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i
) == GETARG_B(i0
) && GETARG_A(i
) >= s
->nlocals
) {
181 /* skip swapping OP_MOVE */
184 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i0
) >= s
->nlocals
) {
185 s
->iseq
[s
->pc
-1] = MKOP_AB(OP_MOVE
, GETARG_A(i
), GETARG_B(i0
));
190 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i0
) >= s
->nlocals
) {
191 s
->iseq
[s
->pc
-1] = MKOP_AsBx(OP_LOADI
, GETARG_A(i
), GETARG_sBx(i0
));
200 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i0
) >= s
->nlocals
) {
201 s
->iseq
[s
->pc
-1] = MKOP_ABC(c0
, GETARG_A(i
), GETARG_B(i0
), GETARG_C(i0
));
213 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i0
) >= s
->nlocals
) {
214 s
->iseq
[s
->pc
-1] = MKOP_ABx(c0
, GETARG_A(i
), GETARG_Bx(i0
));
219 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i0
) >= s
->nlocals
) {
220 s
->iseq
[s
->pc
-1] = MKOP_AB(c0
, GETARG_A(i
), GETARG_B(i0
));
229 if (GETARG_B(i
) == GETARG_A(i0
) && GETARG_A(i0
) >= s
->nlocals
) {
230 s
->iseq
[s
->pc
-1] = MKOP_A(c0
, GETARG_A(i
));
245 if (GETARG_A(i
) == GETARG_A(i0
)) {
246 s
->iseq
[s
->pc
-1] = MKOP_ABx(c1
, GETARG_B(i0
), GETARG_Bx(i
));
254 if (GETARG_A(i
) == GETARG_A(i0
)) {
255 s
->iseq
[s
->pc
-1] = MKOP_ABC(c1
, GETARG_B(i0
), GETARG_B(i
), GETARG_C(i
));
262 s
->iseq
[s
->pc
-1] = MKOP_A(OP_EPOP
, GETARG_A(i0
)+GETARG_A(i
));
267 if (c0
== OP_POPERR
) {
268 s
->iseq
[s
->pc
-1] = MKOP_A(OP_POPERR
, GETARG_A(i0
)+GETARG_A(i
));
277 s
->iseq
[s
->pc
-1] = MKOP_AB(OP_RETURN
, GETARG_B(i0
), OP_R_NORMAL
);
286 genop_peep(s
, i0
, NOVAL
);
287 i0
= s
->iseq
[s
->pc
-1];
288 genop(s
, MKOP_AB(OP_RETURN
, GETARG_A(i0
), OP_R_NORMAL
));
292 if (GETARG_B(i
) == OP_R_NORMAL
&& GETARG_A(i
) == GETARG_A(i0
)) {
293 s
->iseq
[s
->pc
-1] = MKOP_ABC(OP_TAILCALL
, GETARG_A(i0
), GETARG_B(i0
), GETARG_C(i0
));
304 if (c0
== OP_LOADI
) {
305 int c
= GETARG_sBx(i0
);
307 if (c1
== OP_SUB
) c
= -c
;
308 if (c
> 127 || c
< -127) break;
310 s
->iseq
[s
->pc
-1] = MKOP_ABC(OP_ADDI
, GETARG_A(i
), GETARG_B(i
), c
);
312 s
->iseq
[s
->pc
-1] = MKOP_ABC(OP_SUBI
, GETARG_A(i
), GETARG_B(i
), -c
);
316 if (c0
== OP_STRING
) {
317 int i
= GETARG_Bx(i0
);
319 if (mrb_type(s
->irep
->pool
[i
]) == MRB_TT_STRING
&&
320 RSTRING_LEN(s
->irep
->pool
[i
]) == 0) {
334 scope_error(codegen_scope
*s
)
340 dispatch(codegen_scope
*s
, int pc
)
342 int diff
= s
->pc
- pc
;
343 mrb_code i
= s
->iseq
[pc
];
344 int c
= GET_OPCODE(i
);
346 s
->lastlabel
= s
->pc
;
355 fprintf(stderr
, "bug: dispatch on non JMP op\n");
360 s
->iseq
[pc
] = MKOP_AsBx(c
, GETARG_A(i
), diff
);
364 dispatch_linked(codegen_scope
*s
, int pc
)
379 #define nregs_update do {if (s->sp > s->nregs) s->nregs = s->sp;} while (0)
381 push_(codegen_scope
*s
)
384 codegen_error(s
, "too complex expression");
390 #define push() push_(s)
391 #define pop_(s) ((s)->sp--)
392 #define pop() pop_(s)
393 #define pop_n(n) (s->sp-=(n))
394 #define cursp() (s->sp)
397 new_lit(codegen_scope
*s
, mrb_value val
)
402 switch (mrb_type(val
)) {
404 for (i
=0; i
<s
->irep
->plen
; i
++) {
406 pv
= &s
->irep
->pool
[i
];
408 if (mrb_type(*pv
) != MRB_TT_STRING
) continue;
409 if ((len
= RSTRING_LEN(*pv
)) != RSTRING_LEN(val
)) continue;
410 if (memcmp(RSTRING_PTR(*pv
), RSTRING_PTR(val
), len
) == 0)
415 for (i
=0; i
<s
->irep
->plen
; i
++) {
416 pv
= &s
->irep
->pool
[i
];
417 if (mrb_type(*pv
) != MRB_TT_FLOAT
) continue;
418 if (mrb_float(*pv
) == mrb_float(val
)) return i
;
422 for (i
=0; i
<s
->irep
->plen
; i
++) {
423 pv
= &s
->irep
->pool
[i
];
424 if (!mrb_fixnum_p(*pv
)) continue;
425 if (mrb_fixnum(*pv
) == mrb_fixnum(val
)) return i
;
429 /* should not happen */
433 if (s
->irep
->plen
== s
->pcapa
) {
435 s
->irep
->pool
= (mrb_value
*)codegen_realloc(s
, s
->irep
->pool
, sizeof(mrb_value
)*s
->pcapa
);
438 pv
= &s
->irep
->pool
[s
->irep
->plen
];
441 switch (mrb_type(val
)) {
443 *pv
= mrb_str_pool(s
->mrb
, val
);
447 #ifdef MRB_WORD_BOXING
448 *pv
= mrb_float_pool(s
->mrb
, mrb_float(val
));
456 /* should not happen */
463 new_msym(codegen_scope
*s
, mrb_sym sym
)
468 if (len
> 256) len
= 256;
469 for (i
=0; i
<len
; i
++) {
470 if (s
->irep
->syms
[i
] == sym
) return i
;
471 if (s
->irep
->syms
[i
] == 0) break;
474 codegen_error(s
, "too many symbols (max 256)");
476 s
->irep
->syms
[i
] = sym
;
477 if (i
== s
->irep
->slen
) s
->irep
->slen
++;
482 new_sym(codegen_scope
*s
, mrb_sym sym
)
486 for (i
=0; i
<s
->irep
->slen
; i
++) {
487 if (s
->irep
->syms
[i
] == sym
) return i
;
489 if (s
->irep
->slen
> 125 && s
->irep
->slen
< 256) {
490 s
->irep
->syms
= (mrb_sym
*)codegen_realloc(s
, s
->irep
->syms
, sizeof(mrb_sym
)*65536);
491 for (i
= 0; i
< 256 - s
->irep
->slen
; i
++) {
492 static const mrb_sym mrb_sym_zero
= { 0 };
493 s
->irep
->syms
[i
+ s
->irep
->slen
] = mrb_sym_zero
;
497 s
->irep
->syms
[s
->irep
->slen
] = sym
;
498 return s
->irep
->slen
++;
513 #define sym(x) ((mrb_sym)(intptr_t)(x))
514 #define lv_name(lv) sym((lv)->car)
516 lv_idx(codegen_scope
*s
, mrb_sym id
)
522 if (lv_name(lv
) == id
) return n
;
530 for_body(codegen_scope
*s
, node
*tree
)
532 codegen_scope
*prev
= s
;
539 codegen(s
, tree
->cdr
->car
, VAL
);
540 // generate loop-block
541 s
= scope_new(s
->mrb
, s
, tree
->car
);
543 lp
= loop_push(s
, LOOP_FOR
);
544 lp
->pc1
= new_label(s
);
546 // generate loop variable
548 if (n2
->car
&& !n2
->car
->cdr
&& !n2
->cdr
) {
549 genop(s
, MKOP_Ax(OP_ENTER
, 0x40000));
550 gen_assignment(s
, n2
->car
->car
, 1, NOVAL
);
553 genop(s
, MKOP_Ax(OP_ENTER
, 0x40000));
554 gen_vmassignment(s
, n2
, 1, VAL
);
556 codegen(s
, tree
->cdr
->cdr
->car
, VAL
);
559 c
= s
->iseq
[s
->pc
-1];
560 if (GET_OPCODE(c
) != OP_RETURN
|| GETARG_B(c
) != OP_R_NORMAL
|| s
->pc
== s
->lastlabel
)
561 genop_peep(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_NORMAL
), NOVAL
);
566 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), s
->irep
->rlen
-1, OP_L_BLOCK
));
568 idx
= new_msym(s
, mrb_intern_lit(s
->mrb
, "each"));
569 genop(s
, MKOP_ABC(OP_SENDB
, cursp(), idx
, 0));
573 lambda_body(codegen_scope
*s
, node
*tree
, int blk
)
576 codegen_scope
*parent
= s
;
577 s
= scope_new(s
->mrb
, s
, tree
->car
);
581 struct loopinfo
*lp
= loop_push(s
, LOOP_BLOCK
);
582 lp
->pc1
= new_label(s
);
587 int ma
, oa
, ra
, pa
, ka
, kd
, ba
;
591 ma
= node_len(tree
->car
->car
);
596 oa
= node_len(tree
->car
->cdr
->car
);
597 ra
= tree
->car
->cdr
->cdr
->car
? 1 : 0;
598 pa
= node_len(tree
->car
->cdr
->cdr
->cdr
->car
);
600 ba
= tree
->car
->cdr
->cdr
->cdr
->cdr
? 1 : 0;
602 a
= ((mrb_aspec
)(ma
& 0x1f) << 18)
603 | ((mrb_aspec
)(oa
& 0x1f) << 13)
609 s
->ainfo
= (((ma
+oa
) & 0x3f) << 6) /* (12bits = 6:1:5) */
612 genop(s
, MKOP_Ax(OP_ENTER
, a
));
614 for (i
=0; i
<oa
; i
++) {
616 genop(s
, MKOP_sBx(OP_JMP
, 0));
619 genop(s
, MKOP_sBx(OP_JMP
, 0));
621 opt
= tree
->car
->cdr
->car
;
627 codegen(s
, opt
->car
->cdr
, VAL
);
628 idx
= lv_idx(s
, (mrb_sym
)(intptr_t)opt
->car
->car
);
630 genop_peep(s
, MKOP_AB(OP_MOVE
, idx
, cursp()), NOVAL
);
638 codegen(s
, tree
->cdr
->car
, VAL
);
641 c
= s
->iseq
[s
->pc
-1];
642 if (GET_OPCODE(c
) != OP_RETURN
|| GETARG_B(c
) != OP_R_NORMAL
|| s
->pc
== s
->lastlabel
) {
644 genop(s
, MKOP_A(OP_LOADNIL
, 0));
645 genop(s
, MKOP_AB(OP_RETURN
, 0, OP_R_NORMAL
));
648 genop_peep(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_NORMAL
), NOVAL
);
656 return parent
->irep
->rlen
- 1;
660 scope_body(codegen_scope
*s
, node
*tree
, int val
)
662 codegen_scope
*scope
= scope_new(s
->mrb
, s
, tree
->car
);
664 codegen(scope
, tree
->cdr
, VAL
);
666 genop(scope
, MKOP_A(OP_STOP
, 0));
669 genop(scope
, MKOP_AB(OP_RETURN
, 0, OP_R_NORMAL
));
672 if (scope
->nregs
== 0) {
673 genop(scope
, MKOP_A(OP_LOADNIL
, 0));
674 genop(scope
, MKOP_AB(OP_RETURN
, 0, OP_R_NORMAL
));
677 genop_peep(scope
, MKOP_AB(OP_RETURN
, scope
->sp
-1, OP_R_NORMAL
), NOVAL
);
682 /* should not happen */
685 return s
->irep
->rlen
- 1;
692 if ((intptr_t)t
->car
->car
== NODE_SPLAT
) return FALSE
;
699 attrsym(codegen_scope
*s
, mrb_sym a
)
705 name
= mrb_sym2name_len(s
->mrb
, a
, &len
);
706 name2
= (char *)codegen_palloc(s
, len
+1);
707 memcpy(name2
, name
, len
);
711 return mrb_intern(s
->mrb
, name2
, len
+1);
715 gen_values(codegen_scope
*s
, node
*t
, int val
)
721 is_splat
= (intptr_t)t
->car
->car
== NODE_SPLAT
; // splat mode
722 if (n
>= 127 || is_splat
) {
725 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), cursp(), n
));
727 codegen(s
, t
->car
, VAL
);
730 genop(s
, MKOP_AB(OP_ARYCAT
, cursp(), cursp()+1));
733 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), cursp()+1));
738 codegen(s
, t
->car
, VAL
);
740 if ((intptr_t)t
->car
->car
== NODE_SPLAT
) {
741 genop(s
, MKOP_AB(OP_ARYCAT
, cursp(), cursp()+1));
744 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), cursp()+1));
750 codegen(s
, t
->car
->cdr
, NOVAL
);
753 codegen(s
, t
->car
, NOVAL
);
759 // normal (no splat) mode
760 codegen(s
, t
->car
, val
);
767 #define CALL_MAXARGS 127
770 gen_call(codegen_scope
*s
, node
*tree
, mrb_sym name
, int sp
, int val
)
772 mrb_sym sym
= name
? name
: sym(tree
->cdr
->car
);
774 int n
= 0, noop
= 0, sendv
= 0, blk
= 0;
776 codegen(s
, tree
->car
, VAL
); /* receiver */
777 idx
= new_msym(s
, sym
);
778 tree
= tree
->cdr
->cdr
->car
;
780 n
= gen_values(s
, tree
->car
, VAL
);
782 n
= noop
= sendv
= 1;
789 genop(s
, MKOP_AB(OP_ARYPUSH
, cursp(), sp
));
793 genop(s
, MKOP_AB(OP_MOVE
, cursp(), sp
));
798 if (tree
&& tree
->cdr
) {
800 codegen(s
, tree
->cdr
, VAL
);
809 const char *name
= mrb_sym2name_len(s
->mrb
, sym
, &len
);
811 if (!noop
&& len
== 1 && name
[0] == '+') {
812 genop_peep(s
, MKOP_ABC(OP_ADD
, cursp(), idx
, n
), val
);
814 else if (!noop
&& len
== 1 && name
[0] == '-') {
815 genop_peep(s
, MKOP_ABC(OP_SUB
, cursp(), idx
, n
), val
);
817 else if (!noop
&& len
== 1 && name
[0] == '*') {
818 genop(s
, MKOP_ABC(OP_MUL
, cursp(), idx
, n
));
820 else if (!noop
&& len
== 1 && name
[0] == '/') {
821 genop(s
, MKOP_ABC(OP_DIV
, cursp(), idx
, n
));
823 else if (!noop
&& len
== 1 && name
[0] == '<') {
824 genop(s
, MKOP_ABC(OP_LT
, cursp(), idx
, n
));
826 else if (!noop
&& len
== 2 && name
[0] == '<' && name
[1] == '=') {
827 genop(s
, MKOP_ABC(OP_LE
, cursp(), idx
, n
));
829 else if (!noop
&& len
== 1 && name
[0] == '>') {
830 genop(s
, MKOP_ABC(OP_GT
, cursp(), idx
, n
));
832 else if (!noop
&& len
== 2 && name
[0] == '>' && name
[1] == '=') {
833 genop(s
, MKOP_ABC(OP_GE
, cursp(), idx
, n
));
835 else if (!noop
&& len
== 2 && name
[0] == '=' && name
[1] == '=') {
836 genop(s
, MKOP_ABC(OP_EQ
, cursp(), idx
, n
));
839 if (sendv
) n
= CALL_MAXARGS
;
840 if (blk
> 0) { /* no block */
841 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, n
));
844 genop(s
, MKOP_ABC(OP_SENDB
, cursp(), idx
, n
));
854 gen_assignment(codegen_scope
*s
, node
*node
, int sp
, int val
)
857 int type
= (intptr_t)node
->car
;
860 switch ((intptr_t)type
) {
862 idx
= new_sym(s
, sym(node
));
863 genop_peep(s
, MKOP_ABx(OP_SETGLOBAL
, sp
, idx
), val
);
866 idx
= lv_idx(s
, sym(node
));
869 genop_peep(s
, MKOP_AB(OP_MOVE
, idx
, sp
), val
);
875 codegen_scope
*up
= s
->prev
;
878 idx
= lv_idx(up
, sym(node
));
880 genop_peep(s
, MKOP_ABC(OP_SETUPVAR
, sp
, idx
, lv
), val
);
889 idx
= new_sym(s
, sym(node
));
890 genop_peep(s
, MKOP_ABx(OP_SETIV
, sp
, idx
), val
);
893 idx
= new_sym(s
, sym(node
));
894 genop_peep(s
, MKOP_ABx(OP_SETCV
, sp
, idx
), val
);
897 idx
= new_sym(s
, sym(node
));
898 genop_peep(s
, MKOP_ABx(OP_SETCONST
, sp
, idx
), val
);
901 idx
= new_sym(s
, sym(node
->cdr
));
902 genop_peep(s
, MKOP_AB(OP_MOVE
, cursp(), sp
), NOVAL
);
904 codegen(s
, node
->car
, VAL
);
906 genop_peep(s
, MKOP_ABx(OP_SETMCNST
, cursp(), idx
), val
);
911 gen_call(s
, node
, attrsym(s
, sym(node
->cdr
->car
)), sp
, NOVAL
);
914 genop_peep(s
, MKOP_AB(OP_MOVE
, cursp(), sp
), val
);
920 printf("unknown lhs %d\n", type
);
928 gen_vmassignment(codegen_scope
*s
, node
*tree
, int rhs
, int val
)
933 if (tree
->car
) { /* pre */
937 genop(s
, MKOP_ABC(OP_AREF
, cursp(), rhs
, n
));
938 gen_assignment(s
, t
->car
, cursp(), NOVAL
);
945 if (t
->cdr
) { /* post count */
953 genop(s
, MKOP_AB(OP_MOVE
, cursp(), rhs
));
957 genop(s
, MKOP_ABC(OP_APOST
, cursp(), n
, post
));
959 if (t
->car
) { /* rest */
960 gen_assignment(s
, t
->car
, cursp(), NOVAL
);
962 if (t
->cdr
&& t
->cdr
->car
) {
965 gen_assignment(s
, t
->car
, cursp()+n
, NOVAL
);
977 gen_send_intern(codegen_scope
*s
)
980 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "intern")), 0));
984 gen_literal_array(codegen_scope
*s
, node
*tree
, int sym
, int val
)
990 switch ((intptr_t)tree
->car
->car
) {
992 if ((tree
->cdr
== NULL
) && ((intptr_t)tree
->car
->cdr
->cdr
== 0))
996 codegen(s
, tree
->car
, VAL
);
1000 case NODE_LITERAL_DELIM
:
1011 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
1023 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), cursp(), i
));
1028 switch ((intptr_t)tree
->car
->car
) {
1029 case NODE_BEGIN
: case NODE_BLOCK
:
1030 codegen(s
, tree
->car
, NOVAL
);
1038 raise_error(codegen_scope
*s
, const char *msg
)
1040 int idx
= new_lit(s
, mrb_str_new_cstr(s
->mrb
, msg
));
1042 genop(s
, MKOP_ABx(OP_ERR
, 1, idx
));
1046 readint_float(codegen_scope
*s
, const char *p
, int base
)
1048 const char *e
= p
+ strlen(p
);
1055 c
= tolower((unsigned char)c
);
1056 for (n
=0; n
<base
; n
++) {
1057 if (mrb_digitmap
[n
] == c
) {
1064 codegen_error(s
, "malformed readint input");
1072 readint_mrb_int(codegen_scope
*s
, const char *p
, int base
, int neg
, int *overflow
)
1074 const char *e
= p
+ strlen(p
);
1081 c
= tolower((unsigned char)c
);
1082 for (n
=0; n
<base
; n
++) {
1083 if (mrb_digitmap
[n
] == c
) {
1088 codegen_error(s
, "malformed readint input");
1092 if ((MRB_INT_MIN
+ n
)/base
> result
) {
1100 if ((MRB_INT_MAX
- n
)/base
< result
) {
1114 codegen(codegen_scope
*s
, node
*tree
, int val
)
1120 if (s
->irep
&& s
->pc
> 0 && s
->filename_index
!= tree
->filename_index
) {
1121 s
->irep
->filename
= mrb_parser_get_filename(s
->parser
, s
->filename_index
);
1122 mrb_debug_info_append_file(s
->mrb
, s
->irep
, s
->debug_start_pos
, s
->pc
);
1123 s
->debug_start_pos
= s
->pc
;
1124 s
->filename_index
= tree
->filename_index
;
1125 s
->filename
= mrb_parser_get_filename(s
->parser
, tree
->filename_index
);
1128 nt
= (intptr_t)tree
->car
;
1129 s
->lineno
= tree
->lineno
;
1134 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1138 codegen(s
, tree
->car
, tree
->cdr
? NOVAL
: val
);
1145 int onerr
, noexc
, exend
, pos1
, pos2
, tmp
;
1146 struct loopinfo
*lp
;
1148 onerr
= new_label(s
);
1149 genop(s
, MKOP_Bx(OP_ONERR
, 0));
1150 lp
= loop_push(s
, LOOP_BEGIN
);
1153 codegen(s
, tree
->car
, val
);
1156 lp
->type
= LOOP_RESCUE
;
1157 noexc
= new_label(s
);
1158 genop(s
, MKOP_Bx(OP_JMP
, 0));
1164 node
*n2
= tree
->car
;
1167 genop(s
, MKOP_A(OP_RESCUE
, exc
));
1173 if (pos1
) dispatch(s
, pos1
);
1177 codegen(s
, n4
->car
, VAL
);
1180 genop(s
, MKOP_ABx(OP_GETCONST
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "StandardError"))));
1183 genop(s
, MKOP_AB(OP_MOVE
, cursp(), exc
));
1185 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "===")), 1));
1187 genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), pos2
));
1193 pos1
= new_label(s
);
1194 genop(s
, MKOP_sBx(OP_JMP
, 0));
1195 dispatch_linked(s
, pos2
);
1199 gen_assignment(s
, n3
->cdr
->car
, exc
, NOVAL
);
1201 if (n3
->cdr
->cdr
->car
) {
1202 codegen(s
, n3
->cdr
->cdr
->car
, val
);
1206 genop(s
, MKOP_sBx(OP_JMP
, exend
));
1213 genop(s
, MKOP_A(OP_RAISE
, exc
));
1219 genop(s
, MKOP_A(OP_POPERR
, 1));
1221 codegen(s
, tree
->car
, val
);
1226 dispatch_linked(s
, exend
);
1236 genop(s
, MKOP_Bx(OP_EPUSH
, 0));
1238 codegen(s
, tree
->car
, val
);
1239 idx
= scope_body(s
, tree
->cdr
, NOVAL
);
1240 s
->iseq
[epush
] = MKOP_Bx(OP_EPUSH
, idx
);
1242 genop_peep(s
, MKOP_A(OP_EPOP
, 1), NOVAL
);
1248 int idx
= lambda_body(s
, tree
, 1);
1250 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), idx
, OP_L_LAMBDA
));
1257 int idx
= lambda_body(s
, tree
, 1);
1259 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), idx
, OP_L_BLOCK
));
1267 node
*e
= tree
->cdr
->cdr
->car
;
1269 codegen(s
, tree
->car
, VAL
);
1271 pos1
= new_label(s
);
1272 genop(s
, MKOP_AsBx(OP_JMPNOT
, cursp(), 0));
1274 codegen(s
, tree
->cdr
->car
, val
);
1275 if (val
&& !(tree
->cdr
->car
)) {
1276 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1281 pos2
= new_label(s
);
1282 genop(s
, MKOP_sBx(OP_JMP
, 0));
1290 pos2
= new_label(s
);
1291 genop(s
, MKOP_sBx(OP_JMP
, 0));
1293 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1308 codegen(s
, tree
->car
, VAL
);
1311 genop(s
, MKOP_AsBx(OP_JMPNOT
, cursp(), 0));
1312 codegen(s
, tree
->cdr
, val
);
1321 codegen(s
, tree
->car
, VAL
);
1324 genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), 0));
1325 codegen(s
, tree
->cdr
, val
);
1332 struct loopinfo
*lp
= loop_push(s
, LOOP_NORMAL
);
1334 lp
->pc1
= new_label(s
);
1335 genop(s
, MKOP_sBx(OP_JMP
, 0));
1336 lp
->pc2
= new_label(s
);
1337 codegen(s
, tree
->cdr
, NOVAL
);
1338 dispatch(s
, lp
->pc1
);
1339 codegen(s
, tree
->car
, VAL
);
1341 genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), lp
->pc2
- s
->pc
));
1349 struct loopinfo
*lp
= loop_push(s
, LOOP_NORMAL
);
1351 lp
->pc1
= new_label(s
);
1352 genop(s
, MKOP_sBx(OP_JMP
, 0));
1353 lp
->pc2
= new_label(s
);
1354 codegen(s
, tree
->cdr
, NOVAL
);
1355 dispatch(s
, lp
->pc1
);
1356 codegen(s
, tree
->car
, VAL
);
1358 genop(s
, MKOP_AsBx(OP_JMPNOT
, cursp(), lp
->pc2
- s
->pc
));
1372 int pos1
, pos2
, pos3
, tmp
;
1378 codegen(s
, tree
->car
, VAL
);
1385 codegen(s
, n
->car
, VAL
);
1387 genop(s
, MKOP_AB(OP_MOVE
, cursp(), head
));
1389 if ((intptr_t)n
->car
->car
== NODE_SPLAT
) {
1390 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "__case_eqq")), 1));
1393 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "===")), 1));
1400 genop(s
, MKOP_AsBx(OP_JMPIF
, cursp(), pos2
));
1404 if (tree
->car
->car
) {
1405 pos1
= new_label(s
);
1406 genop(s
, MKOP_sBx(OP_JMP
, 0));
1407 dispatch_linked(s
, pos2
);
1409 codegen(s
, tree
->car
->cdr
, val
);
1412 genop(s
, MKOP_sBx(OP_JMP
, pos3
));
1414 if (pos1
) dispatch(s
, pos1
);
1419 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1420 if (pos3
) dispatch_linked(s
, pos3
);
1422 genop(s
, MKOP_AB(OP_MOVE
, cursp(), pos
));
1426 dispatch_linked(s
, pos3
);
1432 scope_body(s
, tree
, NOVAL
);
1437 gen_call(s
, tree
, 0, 0, val
);
1441 codegen(s
, tree
->car
, val
);
1442 codegen(s
, tree
->cdr
, val
);
1445 genop(s
, MKOP_ABC(OP_RANGE
, cursp(), cursp(), 0));
1451 codegen(s
, tree
->car
, val
);
1452 codegen(s
, tree
->cdr
, val
);
1455 genop(s
, MKOP_ABC(OP_RANGE
, cursp(), cursp(), 1));
1462 int sym
= new_sym(s
, sym(tree
->cdr
));
1464 codegen(s
, tree
->car
, VAL
);
1466 genop(s
, MKOP_ABx(OP_GETMCNST
, cursp(), sym
));
1473 int sym
= new_sym(s
, sym(tree
));
1475 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
1476 genop(s
, MKOP_ABx(OP_GETMCNST
, cursp(), sym
));
1485 n
= gen_values(s
, tree
, val
);
1489 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), cursp(), n
));
1504 codegen(s
, tree
->car
->car
, val
);
1505 codegen(s
, tree
->car
->cdr
, val
);
1511 genop(s
, MKOP_ABC(OP_HASH
, cursp(), cursp(), len
));
1519 int idx
= new_msym(s
, mrb_intern_lit(s
->mrb
, "to_a"));
1521 codegen(s
, tree
, VAL
);
1523 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, 0));
1529 codegen(s
, tree
->cdr
, VAL
);
1531 gen_assignment(s
, tree
->car
, cursp(), val
);
1536 int len
= 0, n
= 0, post
= 0;
1537 node
*t
= tree
->cdr
, *p
;
1540 if ((intptr_t)t
->car
== NODE_ARRAY
&& nosplat(t
->cdr
)) {
1544 codegen(s
, t
->car
, VAL
);
1549 if (tree
->car
) { /* pre */
1553 gen_assignment(s
, t
->car
, rhs
+n
, NOVAL
);
1560 if (t
->cdr
) { /* post count */
1567 if (t
->car
) { /* rest (len - pre - post) */
1568 int rn
= len
- post
- n
;
1570 genop(s
, MKOP_ABC(OP_ARRAY
, cursp(), rhs
+n
, rn
));
1571 gen_assignment(s
, t
->car
, cursp(), NOVAL
);
1574 if (t
->cdr
&& t
->cdr
->car
) {
1577 gen_assignment(s
, t
->car
, rhs
+n
, NOVAL
);
1585 genop(s
, MKOP_ABC(OP_ARRAY
, rhs
, rhs
, len
));
1592 gen_vmassignment(s
, tree
->car
, rhs
, val
);
1599 mrb_sym sym
= sym(tree
->cdr
->car
);
1601 const char *name
= mrb_sym2name_len(s
->mrb
, sym
, &len
);
1604 codegen(s
, tree
->car
, VAL
);
1606 ((name
[0] == '|' && name
[1] == '|') ||
1607 (name
[0] == '&' && name
[1] == '&'))) {
1612 genop(s
, MKOP_AsBx(name
[0] == '|' ? OP_JMPIF
: OP_JMPNOT
, cursp(), 0));
1613 codegen(s
, tree
->cdr
->cdr
->car
, VAL
);
1615 gen_assignment(s
, tree
->car
, cursp(), val
);
1619 codegen(s
, tree
->cdr
->cdr
->car
, VAL
);
1622 idx
= new_msym(s
, sym
);
1623 if (len
== 1 && name
[0] == '+') {
1624 genop_peep(s
, MKOP_ABC(OP_ADD
, cursp(), idx
, 1), val
);
1626 else if (len
== 1 && name
[0] == '-') {
1627 genop_peep(s
, MKOP_ABC(OP_SUB
, cursp(), idx
, 1), val
);
1629 else if (len
== 1 && name
[0] == '*') {
1630 genop(s
, MKOP_ABC(OP_MUL
, cursp(), idx
, 1));
1632 else if (len
== 1 && name
[0] == '/') {
1633 genop(s
, MKOP_ABC(OP_DIV
, cursp(), idx
, 1));
1635 else if (len
== 1 && name
[0] == '<') {
1636 genop(s
, MKOP_ABC(OP_LT
, cursp(), idx
, 1));
1638 else if (len
== 2 && name
[0] == '<' && name
[1] == '=') {
1639 genop(s
, MKOP_ABC(OP_LE
, cursp(), idx
, 1));
1641 else if (len
== 1 && name
[0] == '>') {
1642 genop(s
, MKOP_ABC(OP_GT
, cursp(), idx
, 1));
1644 else if (len
== 2 && name
[0] == '>' && name
[1] == '=') {
1645 genop(s
, MKOP_ABC(OP_GE
, cursp(), idx
, 1));
1648 genop(s
, MKOP_ABC(OP_SEND
, cursp(), idx
, 1));
1651 gen_assignment(s
, tree
->car
, cursp(), val
);
1656 int n
= 0, noop
= 0, sendv
= 0;
1658 push(); /* room for receiver */
1660 node
*args
= tree
->car
;
1662 n
= gen_values(s
, args
, VAL
);
1664 n
= noop
= sendv
= 1;
1669 if (tree
&& tree
->cdr
) {
1670 codegen(s
, tree
->cdr
, VAL
);
1674 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1677 if (sendv
) n
= CALL_MAXARGS
;
1678 genop(s
, MKOP_ABC(OP_SUPER
, cursp(), 0, n
));
1685 codegen_scope
*s2
= s
;
1686 int lv
= 0, ainfo
= 0;
1688 push(); /* room for receiver */
1689 while (!s2
->mscope
) {
1694 if (s2
) ainfo
= s2
->ainfo
;
1695 genop(s
, MKOP_ABx(OP_ARGARY
, cursp(), (ainfo
<<4)|(lv
& 0xf)));
1696 if (tree
&& tree
->cdr
) {
1698 codegen(s
, tree
->cdr
, VAL
);
1702 genop(s
, MKOP_ABC(OP_SUPER
, cursp(), 0, CALL_MAXARGS
));
1709 codegen(s
, tree
, VAL
);
1713 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1716 genop(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_RETURN
));
1719 genop_peep(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_NORMAL
), NOVAL
);
1726 codegen_scope
*s2
= s
;
1727 int lv
= 0, ainfo
= 0;
1728 int n
= 0, sendv
= 0;
1730 while (!s2
->mscope
) {
1735 if (s2
) ainfo
= s2
->ainfo
;
1736 genop(s
, MKOP_ABx(OP_BLKPUSH
, cursp(), (ainfo
<<4)|(lv
& 0xf)));
1739 n
= gen_values(s
, tree
, VAL
);
1746 if (sendv
) n
= CALL_MAXARGS
;
1747 genop(s
, MKOP_ABC(OP_SEND
, cursp(), new_msym(s
, mrb_intern_lit(s
->mrb
, "call")), n
));
1753 loop_break(s
, tree
);
1759 raise_error(s
, "unexpected next");
1761 else if (s
->loop
->type
== LOOP_NORMAL
) {
1762 if (s
->ensure_level
> s
->loop
->ensure_level
) {
1763 genop_peep(s
, MKOP_A(OP_EPOP
, s
->ensure_level
- s
->loop
->ensure_level
), NOVAL
);
1765 codegen(s
, tree
, NOVAL
);
1766 genop(s
, MKOP_sBx(OP_JMP
, s
->loop
->pc1
- s
->pc
));
1770 codegen(s
, tree
, VAL
);
1774 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
1776 genop_peep(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_NORMAL
), NOVAL
);
1783 raise_error(s
, "unexpected redo");
1786 if (s
->ensure_level
> s
->loop
->ensure_level
) {
1787 genop_peep(s
, MKOP_A(OP_EPOP
, s
->ensure_level
- s
->loop
->ensure_level
), NOVAL
);
1789 genop(s
, MKOP_sBx(OP_JMP
, s
->loop
->pc2
- s
->pc
));
1795 const char *msg
= "unexpected retry";
1798 raise_error(s
, msg
);
1801 struct loopinfo
*lp
= s
->loop
;
1804 while (lp
&& lp
->type
!= LOOP_RESCUE
) {
1805 if (lp
->type
== LOOP_BEGIN
) {
1811 raise_error(s
, msg
);
1816 genop_peep(s
, MKOP_A(OP_POPERR
, 1), NOVAL
);
1819 if (s
->ensure_level
> lp
->ensure_level
) {
1820 genop_peep(s
, MKOP_A(OP_EPOP
, s
->ensure_level
- lp
->ensure_level
), NOVAL
);
1822 genop(s
, MKOP_sBx(OP_JMP
, lp
->pc1
- s
->pc
));
1830 int idx
= lv_idx(s
, sym(tree
));
1833 genop(s
, MKOP_AB(OP_MOVE
, cursp(), idx
));
1837 codegen_scope
*up
= s
->prev
;
1840 idx
= lv_idx(up
, sym(tree
));
1842 genop(s
, MKOP_ABC(OP_GETUPVAR
, cursp(), idx
, lv
));
1855 int sym
= new_sym(s
, sym(tree
));
1857 genop(s
, MKOP_ABx(OP_GETGLOBAL
, cursp(), sym
));
1864 int sym
= new_sym(s
, sym(tree
));
1866 genop(s
, MKOP_ABx(OP_GETIV
, cursp(), sym
));
1873 int sym
= new_sym(s
, sym(tree
));
1875 genop(s
, MKOP_ABx(OP_GETCV
, cursp(), sym
));
1882 int sym
= new_sym(s
, sym(tree
));
1884 genop(s
, MKOP_ABx(OP_GETCONST
, cursp(), sym
));
1890 codegen(s
, tree
, VAL
);
1895 char buf
[2] = { '$' };
1899 buf
[1] = (char)(intptr_t)tree
;
1900 str
= mrb_str_new(s
->mrb
, buf
, 2);
1901 sym
= new_sym(s
, mrb_intern_str(s
->mrb
, str
));
1902 genop(s
, MKOP_ABx(OP_GETGLOBAL
, cursp(), sym
));
1910 mrb_state
*mrb
= s
->mrb
;
1911 mrb_value fix
= mrb_fixnum_value((intptr_t)tree
);
1912 mrb_value str
= mrb_str_buf_new(mrb
, 4);
1914 mrb_str_buf_cat(mrb
, str
, "$", 1);
1915 mrb_str_buf_append(mrb
, str
, mrb_fixnum_to_str(mrb
, fix
, 10));
1916 sym
= new_sym(s
, mrb_intern_str(mrb
, str
));
1917 genop(s
, MKOP_ABx(OP_GETGLOBAL
, cursp(), sym
));
1923 // should not happen
1926 case NODE_BLOCK_ARG
:
1927 codegen(s
, tree
, VAL
);
1932 char *p
= (char*)tree
->car
;
1933 int base
= (intptr_t)tree
->cdr
->car
;
1938 i
= readint_mrb_int(s
, p
, base
, FALSE
, &overflow
);
1940 double f
= readint_float(s
, p
, base
);
1941 int off
= new_lit(s
, mrb_float_value(s
->mrb
, f
));
1943 genop(s
, MKOP_ABx(OP_LOADL
, cursp(), off
));
1946 if (i
< MAXARG_sBx
&& i
> -MAXARG_sBx
) {
1947 co
= MKOP_AsBx(OP_LOADI
, cursp(), i
);
1950 int off
= new_lit(s
, mrb_fixnum_value(i
));
1951 co
= MKOP_ABx(OP_LOADL
, cursp(), off
);
1961 char *p
= (char*)tree
;
1962 mrb_float f
= str_to_mrb_float(p
);
1963 int off
= new_lit(s
, mrb_float_value(s
->mrb
, f
));
1965 genop(s
, MKOP_ABx(OP_LOADL
, cursp(), off
));
1972 nt
= (intptr_t)tree
->car
;
1977 char *p
= (char*)tree
;
1978 mrb_float f
= str_to_mrb_float(p
);
1979 int off
= new_lit(s
, mrb_float_value(s
->mrb
, -f
));
1981 genop(s
, MKOP_ABx(OP_LOADL
, cursp(), off
));
1988 char *p
= (char*)tree
->car
;
1989 int base
= (intptr_t)tree
->cdr
->car
;
1994 i
= readint_mrb_int(s
, p
, base
, TRUE
, &overflow
);
1996 double f
= readint_float(s
, p
, base
);
1997 int off
= new_lit(s
, mrb_float_value(s
->mrb
, -f
));
1999 genop(s
, MKOP_ABx(OP_LOADL
, cursp(), off
));
2002 if (i
< MAXARG_sBx
&& i
> -MAXARG_sBx
) {
2003 co
= MKOP_AsBx(OP_LOADI
, cursp(), i
);
2006 int off
= new_lit(s
, mrb_fixnum_value(i
));
2007 co
= MKOP_ABx(OP_LOADL
, cursp(), off
);
2017 int sym
= new_msym(s
, mrb_intern_lit(s
->mrb
, "-"));
2019 genop(s
, MKOP_ABx(OP_LOADI
, cursp(), 0));
2021 codegen(s
, tree
, VAL
);
2023 genop(s
, MKOP_ABC(OP_SUB
, cursp(), sym
, 2));
2032 char *p
= (char*)tree
->car
;
2033 size_t len
= (intptr_t)tree
->cdr
;
2034 int ai
= mrb_gc_arena_save(s
->mrb
);
2035 int off
= new_lit(s
, mrb_str_new(s
->mrb
, p
, len
));
2037 mrb_gc_arena_restore(s
->mrb
, ai
);
2038 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2044 tree
= ((struct mrb_parser_heredoc_info
*)tree
)->doc
;
2050 codegen(s
, n
->car
, VAL
);
2053 codegen(s
, n
->car
, VAL
);
2055 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
2064 if ((intptr_t)n
->car
->car
!= NODE_STR
) {
2065 codegen(s
, n
->car
, NOVAL
);
2073 gen_literal_array(s
, tree
, FALSE
, val
);
2077 gen_literal_array(s
, tree
, TRUE
, val
);
2082 char *p
= (char*)tree
->car
;
2083 size_t len
= (intptr_t)tree
->cdr
;
2084 int ai
= mrb_gc_arena_save(s
->mrb
);
2085 int sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "Kernel"));
2086 int off
= new_lit(s
, mrb_str_new(s
->mrb
, p
, len
));
2088 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
2089 genop(s
, MKOP_ABx(OP_GETMCNST
, cursp(), sym
));
2091 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2093 sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "`"));
2094 genop(s
, MKOP_ABC(OP_SEND
, cursp(), sym
, 1));
2095 mrb_gc_arena_restore(s
->mrb
, ai
);
2102 char *p1
= (char*)tree
->car
;
2103 char *p2
= (char*)tree
->cdr
;
2104 int ai
= mrb_gc_arena_save(s
->mrb
);
2105 int sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, REGEXP_CLASS
));
2106 int off
= new_lit(s
, mrb_str_new(s
->mrb
, p1
, strlen(p1
)));
2109 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
2110 genop(s
, MKOP_ABx(OP_GETMCNST
, cursp(), sym
));
2112 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2115 off
= new_lit(s
, mrb_str_new(s
->mrb
, p2
, strlen(p2
)));
2116 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2121 sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "compile"));
2122 genop(s
, MKOP_ABC(OP_SEND
, cursp(), sym
, argc
));
2123 mrb_gc_arena_restore(s
->mrb
, ai
);
2130 node
*n
= tree
->car
;
2131 int ai
= mrb_gc_arena_save(s
->mrb
);
2132 int sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, REGEXP_CLASS
));
2137 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
2138 genop(s
, MKOP_ABx(OP_GETMCNST
, cursp(), sym
));
2140 codegen(s
, n
->car
, VAL
);
2143 codegen(s
, n
->car
, VAL
);
2145 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
2152 off
= new_lit(s
, mrb_str_new(s
->mrb
, p
, strlen(p
)));
2153 codegen(s
, tree
->car
, VAL
);
2154 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2156 genop_peep(s
, MKOP_AB(OP_STRCAT
, cursp(), cursp()+1), VAL
);
2159 char *p2
= (char*)n
->cdr
;
2163 off
= new_lit(s
, mrb_str_new(s
->mrb
, p2
, strlen(p2
)));
2164 genop(s
, MKOP_ABx(OP_STRING
, cursp(), off
));
2169 sym
= new_sym(s
, mrb_intern_lit(s
->mrb
, "compile"));
2170 genop(s
, MKOP_ABC(OP_SEND
, cursp(), sym
, argc
));
2171 mrb_gc_arena_restore(s
->mrb
, ai
);
2175 node
*n
= tree
->car
;
2178 if ((intptr_t)n
->car
->car
!= NODE_STR
) {
2179 codegen(s
, n
->car
, NOVAL
);
2188 int sym
= new_sym(s
, sym(tree
));
2190 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), sym
));
2196 codegen(s
, tree
, val
);
2204 genop(s
, MKOP_A(OP_LOADSELF
, cursp()));
2211 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2218 genop(s
, MKOP_A(OP_LOADT
, cursp()));
2225 genop(s
, MKOP_A(OP_LOADF
, cursp()));
2232 int a
= new_msym(s
, sym(tree
->car
));
2233 int b
= new_msym(s
, sym(tree
->cdr
));
2234 int c
= new_msym(s
, mrb_intern_lit(s
->mrb
,"alias_method"));
2236 genop(s
, MKOP_A(OP_TCLASS
, cursp()));
2238 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), a
));
2240 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), b
));
2242 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2244 genop(s
, MKOP_ABC(OP_SEND
, cursp(), c
, 2));
2253 int undef
= new_msym(s
, mrb_intern_lit(s
->mrb
, "undef_method"));
2257 genop(s
, MKOP_A(OP_TCLASS
, cursp()));
2260 int symbol
= new_msym(s
, sym(t
->car
));
2261 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), symbol
));
2267 genop(s
, MKOP_ABC(OP_SEND
, cursp(), undef
, num
));
2278 if (tree
->car
->car
== (node
*)0) {
2279 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2282 else if (tree
->car
->car
== (node
*)1) {
2283 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
2287 codegen(s
, tree
->car
->car
, VAL
);
2289 if (tree
->cdr
->car
) {
2290 codegen(s
, tree
->cdr
->car
, VAL
);
2293 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2297 idx
= new_msym(s
, sym(tree
->car
->cdr
));
2298 genop(s
, MKOP_AB(OP_CLASS
, cursp(), idx
));
2299 idx
= scope_body(s
, tree
->cdr
->cdr
->car
, val
);
2300 genop(s
, MKOP_ABx(OP_EXEC
, cursp(), idx
));
2311 if (tree
->car
->car
== (node
*)0) {
2312 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2315 else if (tree
->car
->car
== (node
*)1) {
2316 genop(s
, MKOP_A(OP_OCLASS
, cursp()));
2320 codegen(s
, tree
->car
->car
, VAL
);
2323 idx
= new_msym(s
, sym(tree
->car
->cdr
));
2324 genop(s
, MKOP_AB(OP_MODULE
, cursp(), idx
));
2325 idx
= scope_body(s
, tree
->cdr
->car
, val
);
2326 genop(s
, MKOP_ABx(OP_EXEC
, cursp(), idx
));
2337 codegen(s
, tree
->car
, VAL
);
2339 genop(s
, MKOP_AB(OP_SCLASS
, cursp(), cursp()));
2340 idx
= scope_body(s
, tree
->cdr
->car
, val
);
2341 genop(s
, MKOP_ABx(OP_EXEC
, cursp(), idx
));
2350 int sym
= new_msym(s
, sym(tree
->car
));
2351 int idx
= lambda_body(s
, tree
->cdr
, 0);
2353 genop(s
, MKOP_A(OP_TCLASS
, cursp()));
2355 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), idx
, OP_L_METHOD
));
2357 genop(s
, MKOP_AB(OP_METHOD
, cursp(), sym
));
2359 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), sym
));
2367 node
*recv
= tree
->car
;
2368 int sym
= new_msym(s
, sym(tree
->cdr
->car
));
2369 int idx
= lambda_body(s
, tree
->cdr
->cdr
, 0);
2371 codegen(s
, recv
, VAL
);
2373 genop(s
, MKOP_AB(OP_SCLASS
, cursp(), cursp()));
2375 genop(s
, MKOP_Abc(OP_LAMBDA
, cursp(), idx
, OP_L_METHOD
));
2377 genop(s
, MKOP_AB(OP_METHOD
, cursp(), sym
));
2379 genop(s
, MKOP_ABx(OP_LOADSYM
, cursp(), sym
));
2386 codegen(s
, tree
, NOVAL
);
2395 scope_add_irep(codegen_scope
*s
, mrb_irep
*irep
)
2397 if (s
->irep
== NULL
) {
2401 if (s
->irep
->rlen
== s
->rcapa
) {
2403 s
->irep
->reps
= (mrb_irep
**)codegen_realloc(s
, s
->irep
->reps
, sizeof(mrb_irep
*)*s
->rcapa
);
2405 s
->irep
->reps
[s
->irep
->rlen
] = irep
;
2409 static codegen_scope
*
2410 scope_new(mrb_state
*mrb
, codegen_scope
*prev
, node
*lv
)
2412 static const codegen_scope codegen_scope_zero
= { 0 };
2413 mrb_pool
*pool
= mrb_pool_open(mrb
);
2414 codegen_scope
*p
= (codegen_scope
*)mrb_pool_alloc(pool
, sizeof(codegen_scope
));
2417 *p
= codegen_scope_zero
;
2420 if (!prev
) return p
;
2425 p
->irep
= mrb_add_irep(mrb
);
2426 scope_add_irep(prev
, p
->irep
);
2429 p
->irep
->reps
= (mrb_irep
**)mrb_malloc(mrb
, sizeof(mrb_irep
*)*p
->rcapa
);
2432 p
->iseq
= (mrb_code
*)mrb_malloc(mrb
, sizeof(mrb_code
)*p
->icapa
);
2433 p
->irep
->iseq
= p
->iseq
;
2436 p
->irep
->pool
= (mrb_value
*)mrb_malloc(mrb
, sizeof(mrb_value
)*p
->pcapa
);
2440 p
->irep
->syms
= (mrb_sym
*)mrb_malloc(mrb
, sizeof(mrb_sym
)*p
->scapa
);
2444 p
->sp
+= node_len(lv
)+1; /* add self */
2446 p
->ai
= mrb_gc_arena_save(mrb
);
2448 p
->filename
= prev
->filename
;
2450 p
->lines
= (uint16_t*)mrb_malloc(mrb
, sizeof(short)*p
->icapa
);
2452 p
->lineno
= prev
->lineno
;
2455 p
->debug_start_pos
= 0;
2457 mrb_debug_info_alloc(mrb
, p
->irep
);
2458 p
->irep
->filename
= p
->filename
;
2459 p
->irep
->lines
= p
->lines
;
2462 p
->irep
->debug_info
= NULL
;
2464 p
->parser
= prev
->parser
;
2465 p
->filename_index
= prev
->filename_index
;
2471 scope_finish(codegen_scope
*s
)
2473 mrb_state
*mrb
= s
->mrb
;
2474 mrb_irep
*irep
= s
->irep
;
2480 irep
->iseq
= (mrb_code
*)codegen_realloc(s
, s
->iseq
, sizeof(mrb_code
)*s
->pc
);
2483 irep
->lines
= (uint16_t *)codegen_realloc(s
, s
->lines
, sizeof(uint16_t)*s
->pc
);
2489 irep
->pool
= (mrb_value
*)codegen_realloc(s
, irep
->pool
, sizeof(mrb_value
)*irep
->plen
);
2490 irep
->syms
= (mrb_sym
*)codegen_realloc(s
, irep
->syms
, sizeof(mrb_sym
)*irep
->slen
);
2491 irep
->reps
= (mrb_irep
**)codegen_realloc(s
, irep
->reps
, sizeof(mrb_irep
*)*irep
->rlen
);
2493 s
->irep
->filename
= mrb_parser_get_filename(s
->parser
, s
->filename_index
);
2494 mrb_debug_info_append_file(mrb
, s
->irep
, s
->debug_start_pos
, s
->pc
);
2496 fname_len
= strlen(s
->filename
);
2497 fname
= codegen_malloc(s
, fname_len
+ 1);
2498 memcpy(fname
, s
->filename
, fname_len
);
2499 fname
[fname_len
] = '\0';
2500 irep
->filename
= fname
;
2503 irep
->nlocals
= s
->nlocals
;
2504 irep
->nregs
= s
->nregs
;
2506 mrb_gc_arena_restore(mrb
, s
->ai
);
2507 mrb_pool_close(s
->mpool
);
2510 static struct loopinfo
*
2511 loop_push(codegen_scope
*s
, enum looptype t
)
2513 struct loopinfo
*p
= (struct loopinfo
*)codegen_palloc(s
, sizeof(struct loopinfo
));
2516 p
->pc1
= p
->pc2
= p
->pc3
= 0;
2518 p
->ensure_level
= s
->ensure_level
;
2526 loop_break(codegen_scope
*s
, node
*tree
)
2529 codegen(s
, tree
, NOVAL
);
2530 raise_error(s
, "unexpected break");
2533 struct loopinfo
*loop
;
2536 codegen(s
, tree
, VAL
);
2541 while (loop
->type
== LOOP_BEGIN
) {
2542 genop_peep(s
, MKOP_A(OP_POPERR
, 1), NOVAL
);
2545 while (loop
->type
== LOOP_RESCUE
) {
2548 if (loop
->type
== LOOP_NORMAL
) {
2551 if (s
->ensure_level
> s
->loop
->ensure_level
) {
2552 genop_peep(s
, MKOP_A(OP_EPOP
, s
->ensure_level
- s
->loop
->ensure_level
), NOVAL
);
2555 genop_peep(s
, MKOP_AB(OP_MOVE
, loop
->acc
, cursp()), NOVAL
);
2558 genop(s
, MKOP_sBx(OP_JMP
, loop
->pc3
));
2562 genop(s
, MKOP_AB(OP_RETURN
, cursp(), OP_R_BREAK
));
2568 loop_pop(codegen_scope
*s
, int val
)
2571 genop(s
, MKOP_A(OP_LOADNIL
, cursp()));
2573 dispatch_linked(s
, s
->loop
->pc3
);
2574 s
->loop
= s
->loop
->prev
;
2579 codedump(mrb_state
*mrb
, mrb_irep
*irep
)
2587 printf("irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d\n", irep
,
2588 irep
->nregs
, irep
->nlocals
, (int)irep
->plen
, (int)irep
->slen
, (int)irep
->rlen
);
2589 for (i
=0; i
<irep
->ilen
; i
++) {
2590 ai
= mrb_gc_arena_save(mrb
);
2593 switch (GET_OPCODE(c
)) {
2598 printf("OP_MOVE\tR%d\tR%d\n", GETARG_A(c
), GETARG_B(c
));
2601 printf("OP_LOADL\tR%d\tL(%d)\n", GETARG_A(c
), GETARG_Bx(c
));
2604 printf("OP_LOADI\tR%d\t%d\n", GETARG_A(c
), GETARG_sBx(c
));
2607 printf("OP_LOADSYM\tR%d\t:%s\n", GETARG_A(c
),
2608 mrb_sym2name(mrb
, irep
->syms
[GETARG_Bx(c
)]));
2611 printf("OP_LOADNIL\tR%d\n", GETARG_A(c
));
2614 printf("OP_LOADSELF\tR%d\n", GETARG_A(c
));
2617 printf("OP_LOADT\tR%d\n", GETARG_A(c
));
2620 printf("OP_LOADF\tR%d\n", GETARG_A(c
));
2623 printf("OP_GETGLOBAL\tR%d\t:%s\n", GETARG_A(c
),
2624 mrb_sym2name(mrb
, irep
->syms
[GETARG_Bx(c
)]));
2627 printf("OP_SETGLOBAL\t:%s\tR%d\n",
2628 mrb_sym2name(mrb
, irep
->syms
[GETARG_Bx(c
)]),
2632 printf("OP_GETCONST\tR%d\t:%s\n", GETARG_A(c
),
2633 mrb_sym2name(mrb
, irep
->syms
[GETARG_Bx(c
)]));
2636 printf("OP_SETCONST\t:%s\tR%d\n",
2637 mrb_sym2name(mrb
, irep
->syms
[GETARG_Bx(c
)]),
2641 printf("OP_GETMCNST\tR%d\tR%d::%s\n", GETARG_A(c
), GETARG_A(c
),
2642 mrb_sym2name(mrb
, irep
->syms
[GETARG_Bx(c
)]));
2645 printf("OP_SETMCNST\tR%d::%s\tR%d\n", GETARG_A(c
)+1,
2646 mrb_sym2name(mrb
, irep
->syms
[GETARG_Bx(c
)]),
2650 printf("OP_GETIV\tR%d\t%s\n", GETARG_A(c
),
2651 mrb_sym2name(mrb
, irep
->syms
[GETARG_Bx(c
)]));
2654 printf("OP_SETIV\t%s\tR%d\n",
2655 mrb_sym2name(mrb
, irep
->syms
[GETARG_Bx(c
)]),
2659 printf("OP_GETUPVAR\tR%d\t%d\t%d\n",
2660 GETARG_A(c
), GETARG_B(c
), GETARG_C(c
));
2663 printf("OP_SETUPVAR\tR%d\t%d\t%d\n",
2664 GETARG_A(c
), GETARG_B(c
), GETARG_C(c
));
2667 printf("OP_GETCV\tR%d\t%s\n", GETARG_A(c
),
2668 mrb_sym2name(mrb
, irep
->syms
[GETARG_Bx(c
)]));
2671 printf("OP_SETCV\t%s\tR%d\n",
2672 mrb_sym2name(mrb
, irep
->syms
[GETARG_Bx(c
)]),
2676 printf("OP_JMP\t\t%03d\n", i
+GETARG_sBx(c
));
2679 printf("OP_JMPIF\tR%d\t%03d\n", GETARG_A(c
), i
+GETARG_sBx(c
));
2682 printf("OP_JMPNOT\tR%d\t%03d\n", GETARG_A(c
), i
+GETARG_sBx(c
));
2685 printf("OP_SEND\tR%d\t:%s\t%d\n", GETARG_A(c
),
2686 mrb_sym2name(mrb
, irep
->syms
[GETARG_B(c
)]),
2690 printf("OP_SENDB\tR%d\t:%s\t%d\n", GETARG_A(c
),
2691 mrb_sym2name(mrb
, irep
->syms
[GETARG_B(c
)]),
2695 printf("OP_TAILCALL\tR%d\t:%s\t%d\n", GETARG_A(c
),
2696 mrb_sym2name(mrb
, irep
->syms
[GETARG_B(c
)]),
2700 printf("OP_SUPER\tR%d\t%d\n", GETARG_A(c
),
2704 printf("OP_ARGARY\tR%d\t%d:%d:%d:%d\n", GETARG_A(c
),
2705 (GETARG_Bx(c
)>>10)&0x3f,
2706 (GETARG_Bx(c
)>>9)&0x1,
2707 (GETARG_Bx(c
)>>4)&0x1f,
2708 (GETARG_Bx(c
)>>0)&0xf);
2712 printf("OP_ENTER\t%d:%d:%d:%d:%d:%d:%d\n",
2713 (GETARG_Ax(c
)>>18)&0x1f,
2714 (GETARG_Ax(c
)>>13)&0x1f,
2715 (GETARG_Ax(c
)>>12)&0x1,
2716 (GETARG_Ax(c
)>>7)&0x1f,
2717 (GETARG_Ax(c
)>>2)&0x1f,
2718 (GETARG_Ax(c
)>>1)&0x1,
2719 GETARG_Ax(c
) & 0x1);
2722 printf("OP_RETURN\tR%d", GETARG_A(c
));
2723 switch (GETARG_B(c
)) {
2725 printf("\n"); break;
2727 printf("\treturn\n"); break;
2729 printf("\tbreak\n"); break;
2731 printf("\tbroken\n"); break;
2736 printf("OP_BLKPUSH\tR%d\t%d:%d:%d:%d\n", GETARG_A(c
),
2737 (GETARG_Bx(c
)>>10)&0x3f,
2738 (GETARG_Bx(c
)>>9)&0x1,
2739 (GETARG_Bx(c
)>>4)&0x1f,
2740 (GETARG_Bx(c
)>>0)&0xf);
2744 printf("OP_LAMBDA\tR%d\tI(%+d)\t%d\n", GETARG_A(c
), GETARG_b(c
), GETARG_c(c
));
2747 printf("OP_RANGE\tR%d\tR%d\t%d\n", GETARG_A(c
), GETARG_B(c
), GETARG_C(c
));
2750 printf("OP_METHOD\tR%d\t:%s\n", GETARG_A(c
),
2751 mrb_sym2name(mrb
, irep
->syms
[GETARG_B(c
)]));
2755 printf("OP_ADD\tR%d\t:%s\t%d\n", GETARG_A(c
),
2756 mrb_sym2name(mrb
, irep
->syms
[GETARG_B(c
)]),
2760 printf("OP_ADDI\tR%d\t:%s\t%d\n", GETARG_A(c
),
2761 mrb_sym2name(mrb
, irep
->syms
[GETARG_B(c
)]),
2765 printf("OP_SUB\tR%d\t:%s\t%d\n", GETARG_A(c
),
2766 mrb_sym2name(mrb
, irep
->syms
[GETARG_B(c
)]),
2770 printf("OP_SUBI\tR%d\t:%s\t%d\n", GETARG_A(c
),
2771 mrb_sym2name(mrb
, irep
->syms
[GETARG_B(c
)]),
2775 printf("OP_MUL\tR%d\t:%s\t%d\n", GETARG_A(c
),
2776 mrb_sym2name(mrb
, irep
->syms
[GETARG_B(c
)]),
2780 printf("OP_DIV\tR%d\t:%s\t%d\n", GETARG_A(c
),
2781 mrb_sym2name(mrb
, irep
->syms
[GETARG_B(c
)]),
2785 printf("OP_LT\tR%d\t:%s\t%d\n", GETARG_A(c
),
2786 mrb_sym2name(mrb
, irep
->syms
[GETARG_B(c
)]),
2790 printf("OP_LE\tR%d\t:%s\t%d\n", GETARG_A(c
),
2791 mrb_sym2name(mrb
, irep
->syms
[GETARG_B(c
)]),
2795 printf("OP_GT\tR%d\t:%s\t%d\n", GETARG_A(c
),
2796 mrb_sym2name(mrb
, irep
->syms
[GETARG_B(c
)]),
2800 printf("OP_GE\tR%d\t:%s\t%d\n", GETARG_A(c
),
2801 mrb_sym2name(mrb
, irep
->syms
[GETARG_B(c
)]),
2805 printf("OP_EQ\tR%d\t:%s\t%d\n", GETARG_A(c
),
2806 mrb_sym2name(mrb
, irep
->syms
[GETARG_B(c
)]),
2811 printf("OP_STOP\n");
2815 printf("OP_ARRAY\tR%d\tR%d\t%d\n", GETARG_A(c
), GETARG_B(c
), GETARG_C(c
));
2818 printf("OP_ARYCAT\tR%d\tR%d\n", GETARG_A(c
), GETARG_B(c
));
2821 printf("OP_ARYPUSH\tR%d\tR%d\n", GETARG_A(c
), GETARG_B(c
));
2824 printf("OP_AREF\tR%d\tR%d\t%d\n", GETARG_A(c
), GETARG_B(c
), GETARG_C(c
));
2827 printf("OP_APOST\tR%d\t%d\t%d\n", GETARG_A(c
), GETARG_B(c
), GETARG_C(c
));
2831 mrb_value v
= irep
->pool
[GETARG_Bx(c
)];
2832 mrb_value s
= mrb_str_dump(mrb
, mrb_str_new(mrb
, RSTRING_PTR(v
), RSTRING_LEN(v
)));
2833 printf("OP_STRING\tR%d\t%s\n", GETARG_A(c
), RSTRING_PTR(s
));
2837 printf("OP_STRCAT\tR%d\tR%d\n", GETARG_A(c
), GETARG_B(c
));
2840 printf("OP_HASH\tR%d\tR%d\t%d\n", GETARG_A(c
), GETARG_B(c
), GETARG_C(c
));
2844 printf("OP_OCLASS\tR%d\n", GETARG_A(c
));
2847 printf("OP_CLASS\tR%d\t:%s\n", GETARG_A(c
),
2848 mrb_sym2name(mrb
, irep
->syms
[GETARG_B(c
)]));
2851 printf("OP_MODULE\tR%d\t:%s\n", GETARG_A(c
),
2852 mrb_sym2name(mrb
, irep
->syms
[GETARG_B(c
)]));
2855 printf("OP_EXEC\tR%d\tI(%+d)\n", GETARG_A(c
), GETARG_Bx(c
));
2858 printf("OP_SCLASS\tR%d\tR%d\n", GETARG_A(c
), GETARG_B(c
));
2861 printf("OP_TCLASS\tR%d\n", GETARG_A(c
));
2864 printf("OP_ERR\tL(%d)\n", GETARG_Bx(c
));
2867 printf("OP_EPUSH\t:I(%+d)\n", GETARG_Bx(c
));
2870 printf("OP_ONERR\t%03d\n", i
+GETARG_sBx(c
));
2873 printf("OP_RESCUE\tR%d\n", GETARG_A(c
));
2876 printf("OP_RAISE\tR%d\n", GETARG_A(c
));
2879 printf("OP_POPERR\t%d\n", GETARG_A(c
));
2882 printf("OP_EPOP\t%d\n", GETARG_A(c
));
2886 printf("OP_unknown %d\t%d\t%d\t%d\n", GET_OPCODE(c
),
2887 GETARG_A(c
), GETARG_B(c
), GETARG_C(c
));
2890 mrb_gc_arena_restore(mrb
, ai
);
2897 codedump_recur(mrb_state
*mrb
, mrb_irep
*irep
)
2901 codedump(mrb
, irep
);
2902 for (i
=0; i
<irep
->rlen
; i
++) {
2903 codedump_recur(mrb
, irep
->reps
[i
]);
2908 codedump_all(mrb_state
*mrb
, struct RProc
*proc
)
2910 codedump_recur(mrb
, proc
->body
.irep
);
2914 mrb_generate_code(mrb_state
*mrb
, parser_state
*p
)
2916 codegen_scope
*scope
= scope_new(mrb
, 0, 0);
2924 scope
->filename
= p
->filename
;
2925 scope
->filename_index
= p
->current_filename_index
;
2926 if (setjmp(scope
->jmp
) == 0) {
2928 codegen(scope
, p
->tree
, NOVAL
);
2929 proc
= mrb_proc_new(mrb
, scope
->irep
);
2930 mrb_irep_decref(mrb
, scope
->irep
);
2931 mrb_pool_close(scope
->mpool
);
2935 if (scope
->filename
== scope
->irep
->filename
) {
2936 scope
->irep
->filename
= NULL
;
2938 mrb_irep_decref(mrb
, scope
->irep
);
2939 mrb_pool_close(scope
->mpool
);