- Timestamp:
- Jan 21, 2018, 12:10:09 AM (6 years ago)
- Location:
- EcnlProtoTool/trunk/mruby-1.3.0
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/core/codegen.c
r321 r331 9 9 #include <stdlib.h> 10 10 #include <string.h> 11 #include "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"11 #include <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> 17 17 #include "node.h" 18 #include "mruby/opcode.h" 19 #include "mruby/re.h" 20 #include "mruby/throw.h" 18 #include <mruby/opcode.h> 19 #include <mruby/re.h> 20 #include <mruby/throw.h> 21 22 #ifndef MRB_CODEGEN_LEVEL_MAX 23 #define MRB_CODEGEN_LEVEL_MAX 1024 24 #endif 21 25 22 26 typedef mrb_ast_node node; … … 74 78 uint16_t filename_index; 75 79 parser_state* parser; 80 81 int rlev; /* recursion levels */ 76 82 } codegen_scope; 77 83 … … 94 100 while (s->prev) { 95 101 codegen_scope *tmp = s->prev; 102 mrb_free(s->mrb, s->iseq); 96 103 mrb_pool_close(s->mpool); 97 104 s = tmp; 98 105 } 99 #ifndef M BB_DISABLE_STDIO106 #ifndef MRB_DISABLE_STDIO 100 107 if (s->filename && s->lineno) { 101 108 fprintf(stderr, "codegen error:%s:%d: %s\n", s->filename, s->lineno, message); … … 340 347 } 341 348 } 349 if (c0 == OP_LOADNIL) { 350 if (GETARG_B(i) == GETARG_A(i0)) { 351 s->pc--; 352 return 0; 353 } 354 } 342 355 break; 343 356 case OP_JMPIF: … … 381 394 scope_error(s); 382 395 break; 396 } 397 if (diff > MAXARG_sBx) { 398 codegen_error(s, "too distant jump address"); 383 399 } 384 400 s->iseq[pc] = MKOP_AsBx(c, GETARG_A(i), diff); … … 495 511 } 496 512 497 static inline int 513 /* method symbols should be fit in 9 bits */ 514 #define MAXMSYMLEN 512 515 /* maximum symbol numbers */ 516 #define MAXSYMLEN 65536 517 518 static int 498 519 new_msym(codegen_scope *s, mrb_sym sym) 499 520 { … … 503 524 504 525 len = s->irep->slen; 505 if (len > 256) len = 256;526 if (len > MAXMSYMLEN) len = MAXMSYMLEN; 506 527 for (i=0; i<len; i++) { 507 528 if (s->irep->syms[i] == sym) return i; 508 529 if (s->irep->syms[i] == 0) break; 509 530 } 510 if (i == 256) {511 codegen_error(s, "too many symbols (max 256)");531 if (i == MAXMSYMLEN) { 532 codegen_error(s, "too many symbols (max " MRB_STRINGIZE(MAXMSYMLEN) ")"); 512 533 } 513 534 s->irep->syms[i] = sym; … … 516 537 } 517 538 518 static in line int539 static int 519 540 new_sym(codegen_scope *s, mrb_sym sym) 520 541 { … … 524 545 if (s->irep->syms[i] == sym) return i; 525 546 } 526 if (s->irep->slen > 125 && s->irep->slen < 256) { 527 s->irep->syms = (mrb_sym *)codegen_realloc(s, s->irep->syms, sizeof(mrb_sym)*65536); 528 for (i = 0; i < 256 - s->irep->slen; i++) { 547 if (s->irep->slen == MAXSYMLEN) { 548 codegen_error(s, "too many symbols (max " MRB_STRINGIZE(MAXSYMLEN) ")"); 549 } 550 551 if (s->irep->slen > MAXMSYMLEN/2 && s->scapa == MAXMSYMLEN) { 552 s->scapa = MAXSYMLEN; 553 s->irep->syms = (mrb_sym *)codegen_realloc(s, s->irep->syms, sizeof(mrb_sym)*MAXSYMLEN); 554 for (i = s->irep->slen; i < MAXMSYMLEN; i++) { 529 555 static const mrb_sym mrb_sym_zero = { 0 }; 530 s->irep->syms[i + s->irep->slen] = mrb_sym_zero;531 } 532 s->irep->slen = 256;556 s->irep->syms[i] = mrb_sym_zero; 557 } 558 s->irep->slen = MAXMSYMLEN; 533 559 } 534 560 s->irep->syms[s->irep->slen] = sym; … … 583 609 push(); /* push for a block parameter */ 584 610 585 lp = loop_push(s, LOOP_FOR);586 lp->pc1 = new_label(s);587 588 611 /* generate loop variable */ 589 612 n2 = tree->car; … … 595 618 gen_vmassignment(s, n2, 1, VAL); 596 619 } 620 /* construct loop */ 621 lp = loop_push(s, LOOP_FOR); 622 lp->pc2 = new_label(s); 623 624 /* loop body */ 597 625 codegen(s, tree->cdr->cdr->car, VAL); 598 626 pop(); … … 645 673 ba = tree->car->cdr->cdr->cdr->cdr ? 1 : 0; 646 674 675 if (ma > 0x1f || oa > 0x1f || pa > 0x1f || ka > 0x1f) { 676 codegen_error(s, "too many formal arguments"); 677 } 647 678 a = ((mrb_aspec)(ma & 0x1f) << 18) 648 679 | ((mrb_aspec)(oa & 0x1f) << 13) … … 765 796 } 766 797 798 #define CALL_MAXARGS 127 799 767 800 static int 768 gen_values(codegen_scope *s, node *t, int val )801 gen_values(codegen_scope *s, node *t, int val, int extra) 769 802 { 770 803 int n = 0; … … 773 806 while (t) { 774 807 is_splat = (intptr_t)t->car->car == NODE_SPLAT; /* splat mode */ 775 if (n >= 127 || is_splat) { 808 if ( 809 n+extra >= CALL_MAXARGS - 1 /* need to subtract one because vm.c expects an array if n == CALL_MAXARGS */ 810 || is_splat) { 776 811 if (val) { 777 pop_n(n); 778 genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n)); 779 push(); 780 codegen(s, t->car, VAL); 781 pop(); pop(); 782 if (is_splat) { 783 genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1)); 812 if (is_splat && n == 0 && (intptr_t)t->car->cdr->car == NODE_ARRAY) { 813 codegen(s, t->car->cdr, VAL); 814 pop(); 784 815 } 785 816 else { 786 genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); 817 pop_n(n); 818 genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n)); 819 push(); 820 codegen(s, t->car, VAL); 821 pop(); pop(); 822 if (is_splat) { 823 genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1)); 824 } 825 else { 826 genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); 827 } 787 828 } 788 829 t = t->cdr; … … 801 842 } 802 843 else { 803 codegen(s, t->car->cdr, NOVAL);804 t = t->cdr;805 844 while (t) { 806 845 codegen(s, t->car, NOVAL); … … 818 857 } 819 858 820 #define CALL_MAXARGS 127821 822 859 static void 823 gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val )860 gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) 824 861 { 825 862 mrb_sym sym = name ? name : sym(tree->cdr->car); 826 int idx ;863 int idx, skip = 0; 827 864 int n = 0, noop = 0, sendv = 0, blk = 0; 828 865 829 866 codegen(s, tree->car, VAL); /* receiver */ 867 if (safe) { 868 int recv = cursp()-1; 869 genop(s, MKOP_A(OP_LOADNIL, cursp())); 870 push(); 871 genop(s, MKOP_AB(OP_MOVE, cursp(), recv)); 872 push(); pop(); /* space for a block */ 873 pop(); 874 idx = new_msym(s, mrb_intern_lit(s->mrb, "==")); 875 genop(s, MKOP_ABC(OP_EQ, cursp(), idx, 1)); 876 skip = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), 0)); 877 } 830 878 idx = new_msym(s, sym); 831 879 tree = tree->cdr->cdr->car; 832 880 if (tree) { 833 n = gen_values(s, tree->car, VAL );881 n = gen_values(s, tree->car, VAL, sp?1:0); 834 882 if (n < 0) { 835 883 n = noop = sendv = 1; … … 863 911 const char *symname = mrb_sym2name_len(s->mrb, sym, &symlen); 864 912 865 if (!noop && symlen == 1 && symname[0] == '+' ) {913 if (!noop && symlen == 1 && symname[0] == '+' && n == 1) { 866 914 genop_peep(s, MKOP_ABC(OP_ADD, cursp(), idx, n), val); 867 915 } 868 else if (!noop && symlen == 1 && symname[0] == '-' ) {916 else if (!noop && symlen == 1 && symname[0] == '-' && n == 1) { 869 917 genop_peep(s, MKOP_ABC(OP_SUB, cursp(), idx, n), val); 870 918 } 871 else if (!noop && symlen == 1 && symname[0] == '*' ) {919 else if (!noop && symlen == 1 && symname[0] == '*' && n == 1) { 872 920 genop(s, MKOP_ABC(OP_MUL, cursp(), idx, n)); 873 921 } 874 else if (!noop && symlen == 1 && symname[0] == '/' ) {922 else if (!noop && symlen == 1 && symname[0] == '/' && n == 1) { 875 923 genop(s, MKOP_ABC(OP_DIV, cursp(), idx, n)); 876 924 } 877 else if (!noop && symlen == 1 && symname[0] == '<' ) {925 else if (!noop && symlen == 1 && symname[0] == '<' && n == 1) { 878 926 genop(s, MKOP_ABC(OP_LT, cursp(), idx, n)); 879 927 } 880 else if (!noop && symlen == 2 && symname[0] == '<' && symname[1] == '=' ) {928 else if (!noop && symlen == 2 && symname[0] == '<' && symname[1] == '=' && n == 1) { 881 929 genop(s, MKOP_ABC(OP_LE, cursp(), idx, n)); 882 930 } 883 else if (!noop && symlen == 1 && symname[0] == '>' ) {931 else if (!noop && symlen == 1 && symname[0] == '>' && n == 1) { 884 932 genop(s, MKOP_ABC(OP_GT, cursp(), idx, n)); 885 933 } 886 else if (!noop && symlen == 2 && symname[0] == '>' && symname[1] == '=' ) {934 else if (!noop && symlen == 2 && symname[0] == '>' && symname[1] == '=' && n == 1) { 887 935 genop(s, MKOP_ABC(OP_GE, cursp(), idx, n)); 888 936 } 889 else if (!noop && symlen == 2 && symname[0] == '=' && symname[1] == '=' ) {937 else if (!noop && symlen == 2 && symname[0] == '=' && symname[1] == '=' && n == 1) { 890 938 genop(s, MKOP_ABC(OP_EQ, cursp(), idx, n)); 891 939 } … … 900 948 } 901 949 } 950 if (safe) { 951 dispatch(s, skip); 952 } 902 953 if (val) { 903 954 push(); … … 912 963 913 964 tree = tree->cdr; 914 switch ( (intptr_t)type) {965 switch (type) { 915 966 case NODE_GVAR: 916 967 idx = new_sym(s, sym(tree)); … … 962 1013 963 1014 case NODE_CALL: 1015 case NODE_SCALL: 964 1016 push(); 965 gen_call(s, tree, attrsym(s, sym(tree->cdr->car)), sp, NOVAL); 1017 gen_call(s, tree, attrsym(s, sym(tree->cdr->car)), sp, NOVAL, 1018 type == NODE_SCALL); 966 1019 pop(); 967 1020 if (val) { … … 980 1033 default: 981 1034 #ifndef MRB_DISABLE_STDIO 982 printf("unknown lhs %d\n", type);1035 fprintf(stderr, "unknown lhs %d\n", type); 983 1036 #endif 984 1037 break; … … 1033 1086 } 1034 1087 } 1035 push(); 1088 if (!val) { 1089 push(); 1090 } 1036 1091 } 1037 1092 } … … 1176 1231 1177 1232 static void 1233 gen_retval(codegen_scope *s, node *tree) 1234 { 1235 if ((intptr_t)tree->car == NODE_SPLAT) { 1236 genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), 0)); 1237 push(); 1238 codegen(s, tree, VAL); 1239 pop(); pop(); 1240 genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1)); 1241 } 1242 else { 1243 codegen(s, tree, VAL); 1244 pop(); 1245 } 1246 } 1247 1248 static void 1178 1249 codegen(codegen_scope *s, node *tree, int val) 1179 1250 { 1180 1251 int nt; 1181 1182 if (!tree) return; 1183 1252 int rlev = s->rlev; 1253 1254 if (!tree) { 1255 if (val) { 1256 genop(s, MKOP_A(OP_LOADNIL, cursp())); 1257 push(); 1258 } 1259 return; 1260 } 1261 1262 s->rlev++; 1263 if (s->rlev > MRB_CODEGEN_LEVEL_MAX) { 1264 codegen_error(s, "too complex expression"); 1265 } 1184 1266 if (s->irep && s->filename_index != tree->filename_index) { 1185 1267 s->irep->filename = mrb_parser_get_filename(s->parser, s->filename_index); … … 1210 1292 struct loopinfo *lp; 1211 1293 1294 if (tree->car == NULL) goto exit; 1212 1295 onerr = genop(s, MKOP_Bx(OP_ONERR, 0)); 1213 1296 lp = loop_push(s, LOOP_BEGIN); 1214 1297 lp->pc1 = onerr; 1215 if (tree->car) { 1216 codegen(s, tree->car, val); 1217 if (val) pop(); 1218 } 1298 codegen(s, tree->car, VAL); 1299 pop(); 1219 1300 lp->type = LOOP_RESCUE; 1220 1301 noexc = genop(s, MKOP_Bx(OP_JMP, 0)); … … 1227 1308 int exc = cursp(); 1228 1309 1229 genop(s, MKOP_A (OP_RESCUE, exc));1310 genop(s, MKOP_ABC(OP_RESCUE, exc, 0, 0)); 1230 1311 push(); 1231 1312 while (n2) { … … 1236 1317 pos2 = 0; 1237 1318 do { 1238 if (n4 ) {1319 if (n4 && n4->car && (intptr_t)n4->car->car == NODE_SPLAT) { 1239 1320 codegen(s, n4->car, VAL); 1240 } 1241 else { 1242 genop(s, MKOP_ABx(OP_GETCONST, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "StandardError")))); 1243 push(); 1244 } 1245 genop(s, MKOP_AB(OP_MOVE, cursp(), exc)); 1246 pop(); 1247 if (n4 && n4->car && (intptr_t)n4->car->car == NODE_SPLAT) { 1321 genop(s, MKOP_AB(OP_MOVE, cursp(), exc)); 1322 pop(); 1248 1323 genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1)); 1249 1324 } 1250 1325 else { 1251 genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "===")), 1)); 1326 if (n4) { 1327 codegen(s, n4->car, VAL); 1328 } 1329 else { 1330 genop(s, MKOP_ABx(OP_GETCONST, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "StandardError")))); 1331 push(); 1332 } 1333 pop(); 1334 genop(s, MKOP_ABC(OP_RESCUE, exc, cursp(), 1)); 1252 1335 } 1253 1336 tmp = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2)); … … 1294 1377 1295 1378 case NODE_ENSURE: 1296 { 1379 if (!tree->cdr || !tree->cdr->cdr || 1380 ((intptr_t)tree->cdr->cdr->car == NODE_BEGIN && 1381 tree->cdr->cdr->cdr)) { 1297 1382 int idx; 1298 1383 int epush = s->pc; … … 1306 1391 genop_peep(s, MKOP_A(OP_EPOP, 1), NOVAL); 1307 1392 } 1393 else { /* empty ensure ignored */ 1394 codegen(s, tree->car, val); 1395 } 1308 1396 break; 1309 1397 1310 1398 case NODE_LAMBDA: 1311 {1399 if (val) { 1312 1400 int idx = lambda_body(s, tree, 1); 1313 1401 … … 1318 1406 1319 1407 case NODE_BLOCK: 1320 {1408 if (val) { 1321 1409 int idx = lambda_body(s, tree, 1); 1322 1410 … … 1331 1419 node *e = tree->cdr->cdr->car; 1332 1420 1421 if (!tree->car) { 1422 codegen(s, e, val); 1423 goto exit; 1424 } 1333 1425 switch ((intptr_t)tree->car->car) { 1334 1426 case NODE_TRUE: … … 1336 1428 case NODE_STR: 1337 1429 codegen(s, tree->cdr->car, val); 1338 return;1430 goto exit; 1339 1431 case NODE_FALSE: 1340 1432 case NODE_NIL: 1341 1433 codegen(s, e, val); 1342 return;1434 goto exit; 1343 1435 } 1344 1436 codegen(s, tree->car, VAL); … … 1347 1439 1348 1440 codegen(s, tree->cdr->car, val); 1349 if (val && !(tree->cdr->car)) {1350 genop(s, MKOP_A(OP_LOADNIL, cursp()));1351 push();1352 }1353 1441 if (e) { 1354 1442 if (val) pop(); … … 1485 1573 if (pos3) dispatch_linked(s, pos3); 1486 1574 if (head) pop(); 1487 genop(s, MKOP_AB(OP_MOVE, cursp(), pos)); 1575 if (cursp() != pos) { 1576 genop(s, MKOP_AB(OP_MOVE, cursp(), pos)); 1577 } 1488 1578 push(); 1489 1579 } … … 1505 1595 case NODE_FCALL: 1506 1596 case NODE_CALL: 1507 gen_call(s, tree, 0, 0, val); 1597 gen_call(s, tree, 0, 0, val, 0); 1598 break; 1599 case NODE_SCALL: 1600 gen_call(s, tree, 0, 0, val, 1); 1508 1601 break; 1509 1602 … … 1553 1646 int n; 1554 1647 1555 n = gen_values(s, tree, val );1648 n = gen_values(s, tree, val, 0); 1556 1649 if (n >= 0) { 1557 1650 if (val) { … … 1602 1695 1603 1696 case NODE_SPLAT: 1604 codegen(s, tree, VAL);1697 codegen(s, tree, val); 1605 1698 break; 1606 1699 … … 1617 1710 int rhs = cursp(); 1618 1711 1619 if ((intptr_t)t->car == NODE_ARRAY && nosplat(t->cdr)) {1712 if ((intptr_t)t->car == NODE_ARRAY && t->cdr && nosplat(t->cdr)) { 1620 1713 /* fixed rhs */ 1621 1714 t = t->cdr; … … 1630 1723 n = 0; 1631 1724 while (t) { 1632 gen_assignment(s, t->car, rhs+n, NOVAL); 1633 n++; 1725 if (n < len) { 1726 gen_assignment(s, t->car, rhs+n, NOVAL); 1727 n++; 1728 } 1729 else { 1730 genop(s, MKOP_A(OP_LOADNIL, rhs+n)); 1731 gen_assignment(s, t->car, rhs+n, NOVAL); 1732 } 1634 1733 t = t->cdr; 1635 1734 } … … 1688 1787 mrb_int len; 1689 1788 const char *name = mrb_sym2name_len(s->mrb, sym, &len); 1690 int idx; 1691 1692 codegen(s, tree->car, VAL); 1789 int idx, callargs = -1, vsp = -1; 1790 1791 if ((len == 2 && name[0] == '|' && name[1] == '|') && 1792 ((intptr_t)tree->car->car == NODE_CONST || 1793 (intptr_t)tree->car->car == NODE_CVAR)) { 1794 int onerr, noexc, exc; 1795 struct loopinfo *lp; 1796 1797 onerr = genop(s, MKOP_Bx(OP_ONERR, 0)); 1798 lp = loop_push(s, LOOP_BEGIN); 1799 lp->pc1 = onerr; 1800 exc = cursp(); 1801 codegen(s, tree->car, VAL); 1802 lp->type = LOOP_RESCUE; 1803 genop(s, MKOP_A(OP_POPERR, 1)); 1804 noexc = genop(s, MKOP_Bx(OP_JMP, 0)); 1805 dispatch(s, onerr); 1806 genop(s, MKOP_ABC(OP_RESCUE, exc, 0, 0)); 1807 genop(s, MKOP_A(OP_LOADF, exc)); 1808 dispatch(s, noexc); 1809 loop_pop(s, NOVAL); 1810 } 1811 else if ((intptr_t)tree->car->car == NODE_CALL) { 1812 node *n = tree->car->cdr; 1813 1814 if (val) { 1815 vsp = cursp(); 1816 push(); 1817 } 1818 codegen(s, n->car, VAL); /* receiver */ 1819 idx = new_msym(s, sym(n->cdr->car)); 1820 if (n->cdr->cdr->car) { 1821 int base = cursp()-1; 1822 int nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 1); 1823 1824 /* copy receiver and arguments */ 1825 if (nargs >= 0) { 1826 int i; 1827 1828 genop(s, MKOP_AB(OP_MOVE, cursp(), base)); 1829 for (i=0; i<nargs; i++) { 1830 genop(s, MKOP_AB(OP_MOVE, cursp()+i+1, base+i+1)); 1831 } 1832 push_n(nargs+1); 1833 pop_n(nargs+1); 1834 callargs = nargs; 1835 } 1836 else { 1837 /* varargs */ 1838 push(); 1839 genop(s, MKOP_AB(OP_MOVE, cursp(), base)); 1840 genop(s, MKOP_AB(OP_MOVE, cursp()+1, base+1)); 1841 callargs = CALL_MAXARGS; 1842 } 1843 genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs)); 1844 } 1845 else { 1846 genop(s, MKOP_AB(OP_MOVE, cursp(), cursp()-1)); 1847 genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 0)); 1848 callargs = 0; 1849 } 1850 push(); 1851 } 1852 else { 1853 codegen(s, tree->car, VAL); 1854 } 1693 1855 if (len == 2 && 1694 1856 ((name[0] == '|' && name[1] == '|') || … … 1697 1859 1698 1860 pop(); 1699 pos = genop_peep(s, MKOP_AsBx(name[0] == '|' ? OP_JMPIF : OP_JMPNOT, cursp(), 0), NOVAL); 1861 if (val) { 1862 if (vsp >= 0) { 1863 genop(s, MKOP_AB(OP_MOVE, vsp, cursp())); 1864 } 1865 pos = genop(s, MKOP_AsBx(name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0)); 1866 } 1867 else { 1868 pos = genop_peep(s, MKOP_AsBx(name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0), NOVAL); 1869 } 1700 1870 codegen(s, tree->cdr->cdr->car, VAL); 1701 1871 pop(); 1702 gen_assignment(s, tree->car, cursp(), val); 1872 if (val && vsp >= 0) { 1873 genop(s, MKOP_AB(OP_MOVE, vsp, cursp())); 1874 } 1875 if ((intptr_t)tree->car->car == NODE_CALL) { 1876 mrb_sym m = sym(tree->car->cdr->cdr->car); 1877 mrb_sym m2 = attrsym(s, m); 1878 1879 idx = new_msym(s, m2); 1880 pop(); 1881 if (callargs == CALL_MAXARGS) { 1882 genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); 1883 pop(); 1884 genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs)); 1885 } 1886 else { 1887 pop_n(callargs); 1888 genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs+1)); 1889 } 1890 } 1891 else { 1892 gen_assignment(s, tree->car, cursp(), val); 1893 } 1703 1894 dispatch(s, pos); 1704 break;1895 goto exit; 1705 1896 } 1706 1897 codegen(s, tree->cdr->cdr->car, VAL); … … 1736 1927 genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 1)); 1737 1928 } 1738 } 1739 gen_assignment(s, tree->car, cursp(), val); 1929 if (callargs < 0) { 1930 gen_assignment(s, tree->car, cursp(), val); 1931 } 1932 else { 1933 if (val && vsp >= 0) { 1934 genop(s, MKOP_AB(OP_MOVE, vsp, cursp())); 1935 } 1936 if (callargs == CALL_MAXARGS) { 1937 pop(); 1938 genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); 1939 } 1940 else { 1941 pop_n(callargs); 1942 callargs++; 1943 } 1944 pop(); 1945 idx = new_msym(s, attrsym(s,sym(tree->car->cdr->cdr->car))); 1946 genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs)); 1947 } 1948 } 1740 1949 break; 1741 1950 1742 1951 case NODE_SUPER: 1743 1952 { 1953 codegen_scope *s2 = s; 1954 int lv = 0; 1744 1955 int n = 0, noop = 0, sendv = 0; 1745 1956 1746 1957 push(); /* room for receiver */ 1958 while (!s2->mscope) { 1959 lv++; 1960 s2 = s2->prev; 1961 if (!s2) break; 1962 } 1963 genop(s, MKOP_ABx(OP_ARGARY, cursp(), (lv & 0xf))); 1964 push(); push(); /* ARGARY pushes two values */ 1965 pop(); pop(); 1747 1966 if (tree) { 1748 1967 node *args = tree->car; 1749 1968 if (args) { 1750 n = gen_values(s, args, VAL );1969 n = gen_values(s, args, VAL, 0); 1751 1970 if (n < 0) { 1752 1971 n = noop = sendv = 1; … … 1796 2015 case NODE_RETURN: 1797 2016 if (tree) { 1798 codegen(s, tree, VAL); 1799 pop(); 2017 gen_retval(s, tree); 1800 2018 } 1801 2019 else { … … 1823 2041 } 1824 2042 if (s2) ainfo = s2->ainfo; 1825 genop(s, MKOP_ABx(OP_BLKPUSH, cursp(), (ainfo<<4)|(lv & 0xf)));1826 2043 push(); 1827 2044 if (tree) { 1828 n = gen_values(s, tree, VAL );2045 n = gen_values(s, tree, VAL, 0); 1829 2046 if (n < 0) { 1830 2047 n = sendv = 1; … … 1833 2050 } 1834 2051 pop_n(n+1); 2052 genop(s, MKOP_ABx(OP_BLKPUSH, cursp(), (ainfo<<4)|(lv & 0xf))); 1835 2053 if (sendv) n = CALL_MAXARGS; 1836 2054 genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "call")), n)); … … 1869 2087 1870 2088 case NODE_REDO: 1871 if (!s->loop ) {2089 if (!s->loop || s->loop->type == LOOP_BEGIN || s->loop->type == LOOP_RESCUE) { 1872 2090 raise_error(s, "unexpected redo"); 1873 2091 } … … 1878 2096 genop(s, MKOP_sBx(OP_JMP, s->loop->pc2 - s->pc)); 1879 2097 } 2098 if (val) push(); 1880 2099 break; 1881 2100 … … 1912 2131 } 1913 2132 } 2133 if (val) push(); 1914 2134 } 1915 2135 break; … … 1984 2204 case NODE_BACK_REF: 1985 2205 if (val) { 1986 char buf[2] = { '$' }; 2206 char buf[3]; 2207 int sym; 2208 2209 buf[0] = '$'; 2210 buf[1] = (char)(intptr_t)tree; 2211 buf[2] = 0; 2212 sym = new_sym(s, mrb_intern_cstr(s->mrb, buf)); 2213 genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym)); 2214 push(); 2215 } 2216 break; 2217 2218 case NODE_NTH_REF: 2219 if (val) { 2220 mrb_state *mrb = s->mrb; 1987 2221 mrb_value str; 1988 2222 int sym; 1989 2223 1990 buf[1] = (char)(intptr_t)tree; 1991 str = mrb_str_new(s->mrb, buf, 2); 1992 sym = new_sym(s, mrb_intern_str(s->mrb, str)); 1993 genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym)); 1994 push(); 1995 } 1996 break; 1997 1998 case NODE_NTH_REF: 1999 if (val) { 2000 int sym; 2001 mrb_state *mrb = s->mrb; 2002 mrb_value fix = mrb_fixnum_value((intptr_t)tree); 2003 mrb_value str = mrb_str_buf_new(mrb, 4); 2004 2005 mrb_str_cat_lit(mrb, str, "$"); 2006 mrb_str_cat_str(mrb, str, mrb_fixnum_to_str(mrb, fix, 10)); 2224 str = mrb_format(mrb, "$%S", mrb_fixnum_value((mrb_int)(intptr_t)tree)); 2007 2225 sym = new_sym(s, mrb_intern_str(mrb, str)); 2008 2226 genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym)); … … 2051 2269 if (val) { 2052 2270 char *p = (char*)tree; 2053 mrb_float f = str_to_mrb_float(p);2271 mrb_float f = mrb_float_read(p, NULL); 2054 2272 int off = new_lit(s, mrb_float_value(s->mrb, f)); 2055 2273 … … 2065 2283 switch (nt) { 2066 2284 case NODE_FLOAT: 2067 {2285 if (val) { 2068 2286 char *p = (char*)tree; 2069 mrb_float f = str_to_mrb_float(p);2287 mrb_float f = mrb_float_read(p, NULL); 2070 2288 int off = new_lit(s, mrb_float_value(s->mrb, -f)); 2071 2289 … … 2076 2294 2077 2295 case NODE_INT: 2078 {2296 if (val) { 2079 2297 char *p = (char*)tree->car; 2080 2298 int base = (intptr_t)tree->cdr->car; … … 2105 2323 2106 2324 default: 2107 {2325 if (val) { 2108 2326 int sym = new_msym(s, mrb_intern_lit(s->mrb, "-")); 2109 2327 … … 2113 2331 pop(); pop(); 2114 2332 genop(s, MKOP_ABC(OP_SUB, cursp(), sym, 2)); 2333 } 2334 else { 2335 codegen(s, tree, NOVAL); 2115 2336 } 2116 2337 break; … … 2139 2360 node *n = tree; 2140 2361 2141 if (!n) break; 2362 if (!n) { 2363 genop(s, MKOP_A(OP_LOADNIL, cursp())); 2364 push(); 2365 break; 2366 } 2142 2367 codegen(s, n->car, VAL); 2143 2368 n = n->cdr; … … 2176 2401 int sym = new_sym(s, mrb_intern_lit(s->mrb, "Kernel")); 2177 2402 2178 if (val == NOVAL) { push(); } 2179 genop(s, MKOP_A(OP_OCLASS, cursp())); 2180 genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym)); 2403 genop(s, MKOP_A(OP_LOADSELF, cursp())); 2181 2404 push(); 2182 2405 codegen(s, tree->car, VAL); … … 2193 2416 n = n->cdr; 2194 2417 } 2195 p op();2196 pop ();2418 push(); /* for block */ 2419 pop_n(3); 2197 2420 sym = new_sym(s, mrb_intern_lit(s->mrb, "`")); 2198 2421 genop(s, MKOP_ABC(OP_SEND, cursp(), sym, 1)); 2199 if (val == NOVAL) { pop(); } 2200 else { push(); } 2422 if (val) push(); 2201 2423 mrb_gc_arena_restore(s->mrb, ai); 2202 2424 } … … 2208 2430 size_t len = (intptr_t)tree->cdr; 2209 2431 int ai = mrb_gc_arena_save(s->mrb); 2210 int sym = new_sym(s, mrb_intern_lit(s->mrb, "Kernel"));2211 2432 int off = new_lit(s, mrb_str_new(s->mrb, p, len)); 2212 2213 if (val == NOVAL) { push(); } 2214 genop(s, MKOP_A(OP_OCLASS, cursp())); 2215 genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym)); 2433 int sym; 2434 2435 genop(s, MKOP_A(OP_LOADSELF, cursp())); 2216 2436 push(); 2217 2437 genop(s, MKOP_ABx(OP_STRING, cursp(), off)); 2218 pop(); 2438 push(); push(); 2439 pop_n(3); 2219 2440 sym = new_sym(s, mrb_intern_lit(s->mrb, "`")); 2220 2441 genop(s, MKOP_ABC(OP_SEND, cursp(), sym, 1)); 2221 if (val == NOVAL) { pop(); } 2222 else { push(); } 2442 if (val) push(); 2223 2443 mrb_gc_arena_restore(s->mrb, ai); 2224 2444 } … … 2244 2464 off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); 2245 2465 genop(s, MKOP_ABx(OP_STRING, cursp(), off)); 2246 } else { 2466 } 2467 else { 2247 2468 genop(s, MKOP_A(OP_LOADNIL, cursp())); 2248 2469 } … … 2295 2516 genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL); 2296 2517 } 2297 if (n->cdr ) {2298 char *p2 = (char*)n->cdr ;2518 if (n->cdr->car) { 2519 char *p2 = (char*)n->cdr->car; 2299 2520 2300 2521 push(); … … 2302 2523 genop(s, MKOP_ABx(OP_STRING, cursp(), off)); 2303 2524 argc++; 2304 pop(); 2305 } 2306 pop(); 2525 } 2526 if (n->cdr->cdr) { 2527 char *p2 = (char*)n->cdr->cdr; 2528 2529 push(); 2530 off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); 2531 genop(s, MKOP_ABx(OP_STRING, cursp(), off)); 2532 argc++; 2533 } 2534 pop_n(argc); 2307 2535 sym = new_sym(s, mrb_intern_lit(s->mrb, "compile")); 2308 2536 genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc)); … … 2379 2607 push(); 2380 2608 genop(s, MKOP_A(OP_LOADNIL, cursp())); 2381 pop_n(3); 2609 push(); 2610 pop_n(4); 2382 2611 genop(s, MKOP_ABC(OP_SEND, cursp(), c, 2)); 2383 2612 if (val) { … … 2396 2625 push(); 2397 2626 while (t) { 2398 int symbol = new_msym(s, sym(t->car)); 2627 int symbol; 2628 if (num >= CALL_MAXARGS - 1) { 2629 pop_n(num); 2630 genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), num)); 2631 while (t) { 2632 symbol = new_msym(s, sym(t->car)); 2633 push(); 2634 genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol)); 2635 pop(); 2636 genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); 2637 t = t->cdr; 2638 } 2639 num = CALL_MAXARGS; 2640 break; 2641 } 2642 symbol = new_msym(s, sym(t->car)); 2399 2643 genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol)); 2400 2644 push(); … … 2402 2646 num++; 2403 2647 } 2404 pop_n(num + 1); 2648 pop(); 2649 if (num < CALL_MAXARGS) { 2650 pop_n(num); 2651 } 2405 2652 genop(s, MKOP_ABC(OP_SEND, cursp(), undef, num)); 2406 2653 if (val) { … … 2529 2776 break; 2530 2777 } 2778 exit: 2779 s->rlev = rlev; 2531 2780 } 2532 2781 … … 2570 2819 p->icapa = 1024; 2571 2820 p->iseq = (mrb_code*)mrb_malloc(mrb, sizeof(mrb_code)*p->icapa); 2572 p->irep->iseq = p->iseq;2821 p->irep->iseq = NULL; 2573 2822 2574 2823 p->pcapa = 32; … … 2576 2825 p->irep->plen = 0; 2577 2826 2578 p->scapa = 256;2827 p->scapa = MAXMSYMLEN; 2579 2828 p->irep->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*p->scapa); 2580 2829 p->irep->slen = 0; … … 2620 2869 p->filename_index = prev->filename_index; 2621 2870 2871 p->rlev = prev->rlev+1; 2872 2622 2873 return p; 2623 2874 } … … 2646 2897 irep->reps = (mrb_irep**)codegen_realloc(s, irep->reps, sizeof(mrb_irep*)*irep->rlen); 2647 2898 if (s->filename) { 2648 s->irep->filename = mrb_parser_get_filename(s->parser, s->filename_index);2649 mrb_debug_info_append_file(mrb, s->irep, s->debug_start_pos, s->pc);2899 irep->filename = mrb_parser_get_filename(s->parser, s->filename_index); 2900 mrb_debug_info_append_file(mrb, irep, s->debug_start_pos, s->pc); 2650 2901 2651 2902 fname_len = strlen(s->filename); … … 2654 2905 fname[fname_len] = '\0'; 2655 2906 irep->filename = fname; 2907 irep->own_filename = TRUE; 2656 2908 } 2657 2909 … … 2689 2941 2690 2942 if (tree) { 2691 codegen(s, tree, VAL); 2692 pop(); 2943 gen_retval(s, tree); 2693 2944 } 2694 2945 … … 2702 2953 } 2703 2954 if (!loop) { 2704 codegen_error(s, "unexpected break"); 2955 raise_error(s, "unexpected break"); 2956 return; 2705 2957 } 2706 2958 … … 2718 2970 } 2719 2971 else { 2972 if (!tree) { 2973 genop(s, MKOP_A(OP_LOADNIL, cursp())); 2974 } 2720 2975 genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_BREAK)); 2721 2976 } … … 2726 2981 loop_pop(codegen_scope *s, int val) 2727 2982 { 2983 dispatch_linked(s, s->loop->pc3); 2728 2984 if (val) { 2729 2985 genop(s, MKOP_A(OP_LOADNIL, cursp())); 2730 2986 } 2731 dispatch_linked(s, s->loop->pc3);2732 2987 s->loop = s->loop->prev; 2733 2988 if (val) push(); … … 2739 2994 codegen_scope *scope = scope_new(mrb, 0, 0); 2740 2995 struct RProc *proc; 2996 struct mrb_jmpbuf *prev_jmp = mrb->jmp; 2741 2997 2742 2998 if (!scope) { … … 2749 3005 2750 3006 MRB_TRY(&scope->jmp) { 3007 mrb->jmp = &scope->jmp; 2751 3008 /* prepare irep */ 2752 3009 codegen(scope, p->tree, NOVAL); … … 2754 3011 mrb_irep_decref(mrb, scope->irep); 2755 3012 mrb_pool_close(scope->mpool); 3013 proc->c = NULL; 3014 mrb->jmp = prev_jmp; 2756 3015 return proc; 2757 3016 } 2758 3017 MRB_CATCH(&scope->jmp) { 2759 if (scope->filename == scope->irep->filename) {2760 scope->irep->filename = NULL;2761 }2762 3018 mrb_irep_decref(mrb, scope->irep); 2763 3019 mrb_pool_close(scope->mpool); 3020 mrb->jmp = prev_jmp; 2764 3021 return NULL; 2765 3022 }
Note:
See TracChangeset
for help on using the changeset viewer.