99 fprintf(stderr,
"codegen error:%s:%d: %s\n", s->
filename, s->
lineno, message);
102 fprintf(stderr,
"codegen error: %s\n", message);
113 if (!p) codegen_error(s,
"pool memory allocation");
122 if (!p) codegen_error(s,
"mrb_malloc");
131 if (!p && len > 0) codegen_error(s,
"mrb_realloc");
287 genop_peep(s, i0,
NOVAL);
309 if (c > 127 || c < -127)
break;
343 int diff = s->
pc - pc;
356 fprintf(stderr,
"bug: dispatch on non JMP op\n");
380 #define nregs_update do {if (s->sp > s->nregs) s->nregs = s->sp;} while (0)
385 codegen_error(s,
"too complex expression");
391 #define push() push_(s)
392 #define pop_(s) ((s)->sp--)
393 #define pop() pop_(s)
394 #define pop_n(n) (s->sp-=(n))
395 #define cursp() (s->sp)
438 if (len > 256) len = 256;
439 for (i=0; i<len; i++) {
444 codegen_error(s,
"too many symbols (max 256)");
461 for (i = 0; i < 256 - s->
irep->
slen; i++) {
462 static const mrb_sym mrb_sym_zero = { 0 };
483 #define sym(x) ((mrb_sym)(intptr_t)(x))
484 #define lv_name(lv) sym((lv)->car)
492 if (
lv_name(lv) ==
id)
return n;
503 int idx, base = s->
idx;
511 s = scope_new(s->
mrb, s, tree->
car);
515 lp->
pc1 = new_label(s);
525 gen_vmassignment(s, n2, 1,
VAL);
546 int idx, base = s->
idx;
549 s = scope_new(s->
mrb, s, tree->
car);
555 lp->
pc1 = new_label(s);
560 int ma, oa, ra, pa, ka, kd, ba;
564 ma = node_len(tree->
car->
car);
582 s->
ainfo = (((ma+oa) & 0x3f) << 6)
587 for (i=0; i<oa; i++) {
637 int idx = scope->
idx;
639 codegen(scope, tree->
cdr,
VAL);
644 if (scope->
nregs == 0) {
675 name2 = (
char *)codegen_palloc(s, len+1);
676 memcpy(name2, name, len);
722 codegen(s, t->
car, val);
729 #define CALL_MAXARGS 127
736 int n = 0, noop = 0, sendv = 0, blk = 0;
738 codegen(s, tree->
car,
VAL);
739 idx = new_msym(s, sym);
742 n = gen_values(s, tree->
car,
VAL);
744 n = noop = sendv = 1;
760 if (tree && tree->
cdr) {
762 codegen(s, tree->
cdr,
VAL);
773 if (!noop && len == 1 && name[0] ==
'+') {
776 else if (!noop && len == 1 && name[0] ==
'-') {
779 else if (!noop && len == 1 && name[0] ==
'*') {
782 else if (!noop && len == 1 && name[0] ==
'/') {
785 else if (!noop && len == 1 && name[0] ==
'<') {
788 else if (!noop && len == 2 && name[0] ==
'<' && name[1] ==
'=') {
791 else if (!noop && len == 1 && name[0] ==
'>') {
794 else if (!noop && len == 2 && name[0] ==
'>' && name[1] ==
'=') {
797 else if (!noop && len == 2 && name[0] ==
'=' && name[1] ==
'=') {
819 int type = (intptr_t)node->
car;
822 switch ((intptr_t)
type) {
824 idx = new_sym(s,
sym(node));
828 idx = lv_idx(s,
sym(node));
840 idx = lv_idx(up,
sym(node));
851 idx = new_sym(s,
sym(node));
855 idx = new_sym(s,
sym(node));
859 idx = new_sym(s,
sym(node));
863 idx = new_sym(s,
sym(node->
cdr));
866 codegen(s, node->
car,
VAL);
882 printf(
"unknown lhs %d\n", type);
890 gen_vmassignment(
codegen_scope *s, node *tree,
int rhs,
int val)
946 gen_literal_array(
codegen_scope *s, node *tree,
int sym,
int val)
952 switch ((intptr_t)tree->
car->
car) {
954 if ((tree->
cdr == NULL) && ((intptr_t)tree->
car->
cdr->
cdr == 0))
958 codegen(s, tree->
car,
VAL);
990 switch ((intptr_t)tree->
car->
car) {
1010 const char *e = p + strlen(p);
1017 c = tolower((
unsigned char)c);
1018 for (n=0; n<base; n++) {
1026 codegen_error(s,
"malformed readint input");
1034 readint_mrb_int(
codegen_scope *s,
const char *p,
int base,
int neg,
int *overflow)
1036 const char *e = p + strlen(p);
1043 c = tolower((
unsigned char)c);
1044 for (n=0; n<base; n++) {
1050 codegen_error(s,
"malformed readint input");
1090 nt = (intptr_t)tree->
car;
1107 int onerr, noexc, exend, pos1, pos2, tmp;
1110 onerr = new_label(s);
1115 codegen(s, tree->
car, val);
1119 noexc = new_label(s);
1126 node *n2 = tree->
car;
1135 if (pos1) dispatch(s, pos1);
1139 codegen(s, n4->
car,
VAL);
1155 pos1 = new_label(s);
1157 dispatch_linked(s, pos2);
1183 codegen(s, tree->
car, val);
1188 dispatch_linked(s, exend);
1200 codegen(s, tree->
car, val);
1201 idx = scope_body(s, tree->
cdr);
1210 int idx = lambda_body(s, tree, 1);
1219 int idx = lambda_body(s, tree, 1);
1231 codegen(s, tree->
car,
VAL);
1233 pos1 = new_label(s);
1236 codegen(s, tree->
cdr->
car, val);
1237 if (val && !(tree->
cdr->
car)) {
1243 pos2 = new_label(s);
1252 pos2 = new_label(s);
1270 codegen(s, tree->
car,
VAL);
1274 codegen(s, tree->
cdr, val);
1283 codegen(s, tree->
car,
VAL);
1287 codegen(s, tree->
cdr, val);
1296 lp->
pc1 = new_label(s);
1298 lp->
pc2 = new_label(s);
1300 dispatch(s, lp->
pc1);
1301 codegen(s, tree->
car,
VAL);
1313 lp->
pc1 = new_label(s);
1315 lp->
pc2 = new_label(s);
1317 dispatch(s, lp->
pc1);
1318 codegen(s, tree->
car,
VAL);
1334 int pos1, pos2, pos3, tmp;
1340 codegen(s, tree->
car,
VAL);
1362 pos1 = new_label(s);
1364 dispatch_linked(s, pos2);
1366 codegen(s, tree->
car->
cdr, val);
1371 if (pos1) dispatch(s, pos1);
1378 if (pos3) dispatch_linked(s, pos3);
1383 scope_body(s, tree);
1388 gen_call(s, tree, 0, 0, val);
1392 codegen(s, tree->
car, val);
1393 codegen(s, tree->
cdr, val);
1402 codegen(s, tree->
car, val);
1403 codegen(s, tree->
cdr, val);
1413 int sym = new_sym(s,
sym(tree->
cdr));
1415 codegen(s, tree->
car,
VAL);
1424 int sym = new_sym(s,
sym(tree));
1436 n = gen_values(s, tree, val);
1455 codegen(s, tree->
car->
car, val);
1456 codegen(s, tree->
car->
cdr, val);
1469 codegen(s, tree,
VAL);
1473 codegen(s, tree->
cdr,
VAL);
1475 gen_assignment(s, tree->
car,
cursp(), val);
1480 int len = 0, n = 0, post = 0;
1481 node *t = tree->
cdr, *p;
1497 gen_assignment(s, t->
car, rhs+n,
NOVAL);
1512 int rn = len - post - n;
1521 gen_assignment(s, t->
car, rhs+n,
NOVAL);
1536 gen_vmassignment(s, tree->
car, rhs, val);
1548 codegen(s, tree->
car,
VAL);
1550 ((name[0] ==
'|' && name[1] ==
'|') ||
1551 (name[0] ==
'&' && name[1] ==
'&'))) {
1559 gen_assignment(s, tree->
car,
cursp(), val);
1566 idx = new_msym(s, sym);
1567 if (len == 1 && name[0] ==
'+') {
1570 else if (len == 1 && name[0] ==
'-') {
1573 else if (len == 1 && name[0] ==
'*') {
1576 else if (len == 1 && name[0] ==
'/') {
1579 else if (len == 1 && name[0] ==
'<') {
1582 else if (len == 2 && name[0] ==
'<' && name[1] ==
'=') {
1585 else if (len == 1 && name[0] ==
'>') {
1588 else if (len == 2 && name[0] ==
'>' && name[1] ==
'=') {
1595 gen_assignment(s, tree->
car,
cursp(), val);
1600 int n = 0, noop = 0, sendv = 0;
1604 node *args = tree->
car;
1606 n = gen_values(s, args,
VAL);
1608 n = noop = sendv = 1;
1613 if (tree && tree->
cdr) {
1614 codegen(s, tree->
cdr,
VAL);
1630 int lv = 0, ainfo = 0;
1638 if (s2) ainfo = s2->
ainfo;
1640 if (tree && tree->
cdr) {
1642 codegen(s, tree->
cdr,
VAL);
1653 codegen(s, tree,
VAL);
1671 int lv = 0, ainfo = 0;
1672 int n = 0, sendv = 0;
1679 if (s2) ainfo = s2->
ainfo;
1683 n = gen_values(s, tree,
VAL);
1697 loop_break(s, tree);
1703 raise_error(s,
"unexpected next");
1709 codegen(s, tree,
NOVAL);
1714 codegen(s, tree,
VAL);
1727 raise_error(s,
"unexpected redo");
1739 const char *msg =
"unexpected retry";
1742 raise_error(s, msg);
1755 raise_error(s, msg);
1774 int idx = lv_idx(s,
sym(tree));
1784 idx = lv_idx(up,
sym(tree));
1799 int sym = new_sym(s,
sym(tree));
1808 int sym = new_sym(s,
sym(tree));
1817 int sym = new_sym(s,
sym(tree));
1826 int sym = new_sym(s,
sym(tree));
1834 codegen(s, tree,
VAL);
1839 char buf[2] = {
'$' };
1843 buf[1] = (char)(intptr_t)tree;
1855 mrb_value fix = mrb_fixnum_value((intptr_t)tree);
1871 codegen(s, tree,
VAL);
1876 char *p = (
char*)tree->
car;
1877 int base = (intptr_t)tree->
cdr->
car;
1882 i = readint_mrb_int(s, p, base,
FALSE, &overflow);
1884 double f = readint_float(s, p, base);
1885 int off = new_lit(s, mrb_float_value(s->
mrb, f));
1894 int off = new_lit(s, mrb_fixnum_value(i));
1905 char *p = (
char*)tree;
1907 int off = new_lit(s, mrb_float_value(s->
mrb, f));
1916 nt = (intptr_t)tree->
car;
1921 char *p = (
char*)tree;
1923 int off = new_lit(s, mrb_float_value(s->
mrb, -f));
1932 char *p = (
char*)tree->
car;
1933 int base = (intptr_t)tree->
cdr->
car;
1938 i = readint_mrb_int(s, p, base,
TRUE, &overflow);
1940 double f = readint_float(s, p, base);
1941 int off = new_lit(s, mrb_float_value(s->
mrb, -f));
1950 int off = new_lit(s, mrb_fixnum_value(i));
1965 codegen(s, tree,
VAL);
1976 char *p = (
char*)tree->
car;
1977 size_t len = (intptr_t)tree->
cdr;
2017 gen_literal_array(s, tree,
FALSE, val);
2021 gen_literal_array(s, tree,
TRUE, val);
2026 char *p = (
char*)tree->
car;
2027 size_t len = (intptr_t)tree->
cdr;
2046 char *p1 = (
char*)tree->
car;
2047 char *p2 = (
char*)tree->
cdr;
2074 node *n = tree->
car;
2097 codegen(s, tree->
car,
VAL);
2103 char *p2 = (
char*)n->
cdr;
2119 node *n = tree->
car;
2132 int sym = new_sym(s,
sym(tree));
2140 codegen(s, tree, val);
2176 int a = new_msym(s,
sym(tree->
car));
2177 int b = new_msym(s,
sym(tree->
cdr));
2197 int undef = new_msym(s,
mrb_intern2(s->
mrb,
"undef_method", 12));
2204 int symbol = new_msym(s,
sym(t->
car));
2222 if (tree->
car->
car == (node*)0) {
2226 else if (tree->
car->
car == (node*)1) {
2243 idx = scope_body(s, tree->
cdr->
cdr->
car);
2255 if (tree->
car->
car == (node*)0) {
2259 else if (tree->
car->
car == (node*)1) {
2269 idx = scope_body(s, tree->
cdr->
car);
2281 codegen(s, tree->
car,
VAL);
2284 idx = scope_body(s, tree->
cdr->
car);
2294 int sym = new_msym(s,
sym(tree->
car));
2295 int idx = lambda_body(s, tree->
cdr, 0);
2311 node *recv = tree->
car;
2312 int sym = new_msym(s,
sym(tree->
cdr->
car));
2313 int idx = lambda_body(s, tree->
cdr->
cdr, 0);
2315 codegen(s, recv,
VAL);
2330 codegen(s, tree,
NOVAL);
2346 *p = codegen_scope_zero;
2349 if (!prev)
return p;
2369 p->
sp += node_len(lv)+1;
2422 memcpy(fname, s->
filename, fname_len);
2423 fname[fname_len] =
'\0';
2453 codegen(s, tree,
NOVAL);
2454 raise_error(s,
"unexpected break");
2460 codegen(s, tree,
VAL);
2497 dispatch_linked(s, s->
loop->
pc3);
2512 printf(
"irep %d nregs=%d nlocals=%d pools=%d syms=%d\n", n,
2514 for (i=0; i<irep->
ilen; i++) {
2532 printf(
"OP_LOADSYM\tR%d\t:%s\n",
GETARG_A(c),
2536 printf(
"OP_LOADNIL\tR%d\n",
GETARG_A(c));
2539 printf(
"OP_LOADSELF\tR%d\n",
GETARG_A(c));
2542 printf(
"OP_LOADT\tR%d\n",
GETARG_A(c));
2545 printf(
"OP_LOADF\tR%d\n",
GETARG_A(c));
2548 printf(
"OP_GETGLOBAL\tR%d\t:%s\n",
GETARG_A(c),
2552 printf(
"OP_SETGLOBAL\t:%s\tR%d\n",
2557 printf(
"OP_GETCONST\tR%d\t:%s\n",
GETARG_A(c),
2561 printf(
"OP_SETCONST\t:%s\tR%d\n",
2570 printf(
"OP_SETMCNST\tR%d::%s\tR%d\n",
GETARG_A(c)+1,
2575 printf(
"OP_GETIV\tR%d\t%s\n",
GETARG_A(c),
2579 printf(
"OP_SETIV\t%s\tR%d\n",
2584 printf(
"OP_GETUPVAR\tR%d\t%d\t%d\n",
2588 printf(
"OP_SETUPVAR\tR%d\t%d\t%d\n",
2592 printf(
"OP_GETCV\tR%d\t%s\n",
GETARG_A(c),
2596 printf(
"OP_SETCV\t%s\tR%d\n",
2610 printf(
"OP_SEND\tR%d\t:%s\t%d\n",
GETARG_A(c),
2615 printf(
"OP_SENDB\tR%d\t:%s\t%d\n",
GETARG_A(c),
2620 printf(
"OP_TAILCALL\tR%d\t:%s\t%d\n",
GETARG_A(c),
2625 printf(
"OP_SUPER\tR%d\t%d\n",
GETARG_A(c),
2629 printf(
"OP_ARGARY\tR%d\t%d:%d:%d:%d\n",
GETARG_A(c),
2637 printf(
"OP_ENTER\t%d:%d:%d:%d:%d:%d:%d\n",
2647 printf(
"OP_RETURN\tR%d",
GETARG_A(c));
2650 printf(
"\n");
break;
2652 printf(
"\treturn\n");
break;
2654 printf(
"\tbreak\n");
break;
2656 printf(
"\tbroken\n");
break;
2661 printf(
"OP_BLKPUSH\tR%d\t%d:%d:%d:%d\n",
GETARG_A(c),
2675 printf(
"OP_METHOD\tR%d\t:%s\n",
GETARG_A(c),
2680 printf(
"OP_ADD\tR%d\t:%s\t%d\n",
GETARG_A(c),
2685 printf(
"OP_ADDI\tR%d\t:%s\t%d\n",
GETARG_A(c),
2690 printf(
"OP_SUB\tR%d\t:%s\t%d\n",
GETARG_A(c),
2695 printf(
"OP_SUBI\tR%d\t:%s\t%d\n",
GETARG_A(c),
2700 printf(
"OP_MUL\tR%d\t:%s\t%d\n",
GETARG_A(c),
2705 printf(
"OP_DIV\tR%d\t:%s\t%d\n",
GETARG_A(c),
2710 printf(
"OP_LT\tR%d\t:%s\t%d\n",
GETARG_A(c),
2715 printf(
"OP_LE\tR%d\t:%s\t%d\n",
GETARG_A(c),
2720 printf(
"OP_GT\tR%d\t:%s\t%d\n",
GETARG_A(c),
2725 printf(
"OP_GE\tR%d\t:%s\t%d\n",
GETARG_A(c),
2730 printf(
"OP_EQ\tR%d\t:%s\t%d\n",
GETARG_A(c),
2736 printf(
"OP_STOP\n");
2770 printf(
"OP_OCLASS\tR%d\n",
GETARG_A(c));
2773 printf(
"OP_CLASS\tR%d\t:%s\n",
GETARG_A(c),
2777 printf(
"OP_MODULE\tR%d\t:%s\n",
GETARG_A(c),
2787 printf(
"OP_TCLASS\tR%d\n",
GETARG_A(c));
2790 printf(
"OP_ERR\tL(%d)\n",
GETARG_Bx(c));
2793 printf(
"OP_EPUSH\t:I(%d)\n", n+
GETARG_Bx(c));
2799 printf(
"OP_RESCUE\tR%d\n",
GETARG_A(c));
2802 printf(
"OP_RAISE\tR%d\n",
GETARG_A(c));
2805 printf(
"OP_POPERR\t%d\n",
GETARG_A(c));
2808 printf(
"OP_EPOP\t%d\n",
GETARG_A(c));
2812 printf(
"OP_unknown %d\t%d\t%d\t%d\n",
GET_OPCODE(c),
2827 for (i=start; i<mrb->
irep_len; i++) {
2843 if (setjmp(scope->
jmp) == 0) {
2860 n = codegen_start(mrb, p);
2861 if (n < 0)
return n;