diff options
Diffstat (limited to 'src/codegen.c')
| -rw-r--r-- | src/codegen.c | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/src/codegen.c b/src/codegen.c index ff7e87c28..6f564586c 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -330,7 +330,7 @@ genop_peep(codegen_scope *s, mrb_code i, int val) if (c1 == OP_SUB) c = -c; if (c > 127 || c < -127) break; - if (0 <= c) + if (0 <= c) s->iseq[s->pc-1] = MKOP_ABC(OP_ADDI, GETARG_A(i), GETARG_B(i), c); else s->iseq[s->pc-1] = MKOP_ABC(OP_SUBI, GETARG_A(i), GETARG_B(i), -c); @@ -410,9 +410,27 @@ new_lit(codegen_scope *s, mrb_value val) { int i; - for (i=0; i<s->irep->plen; i++) { - if (mrb_obj_equal(s->mrb, s->irep->pool[i], val)) return i; + + switch (mrb_type(val)) { + case MRB_TT_STRING: + for (i=0; i<s->irep->plen; i++) { + mrb_value pv = s->irep->pool[i]; + mrb_int len; + + if (mrb_type(pv) != MRB_TT_STRING) continue; + if ((len = RSTRING_LEN(pv)) != RSTRING_LEN(val)) continue; + if (memcmp(RSTRING_PTR(pv), RSTRING_PTR(val), len) == 0) + return i; + } + break; + case MRB_TT_FLOAT: + default: + for (i=0; i<s->irep->plen; i++) { + if (mrb_obj_equal(s->mrb, s->irep->pool[i], val)) return i; + } + break; } + if (s->irep->plen == s->pcapa) { s->pcapa *= 2; s->irep->pool = (mrb_value *)codegen_realloc(s, s->irep->pool, sizeof(mrb_value)*s->pcapa); @@ -1161,7 +1179,7 @@ codegen(codegen_scope *s, node *tree, int val) if (e) { if (val) pop(); pos2 = new_label(s); - genop(s, MKOP_sBx(OP_JMP, 0)); + genop(s, MKOP_sBx(OP_JMP, 0)); dispatch(s, pos1); codegen(s, e, val); dispatch(s, pos2); @@ -1902,6 +1920,11 @@ codegen(codegen_scope *s, node *tree, int val) } break; + case NODE_HEREDOC: + /*if(tree == NULL){printf("heredoc error 1\n");exit(11);}*/ + tree = ((struct mrb_parser_heredoc_info *)tree)->doc; + /*if(tree == NULL){printf("heredoc error 2\n");exit(12);}*/ + /* fall through */ case NODE_DSTR: if (val) { node *n = tree; @@ -1951,7 +1974,7 @@ codegen(codegen_scope *s, node *tree, int val) pop(); sym = new_sym(s, mrb_intern(s->mrb, "compile")); genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc)); - mrb_gc_arena_restore(s->mrb, ai); + mrb_gc_arena_restore(s->mrb, ai); push(); } break; @@ -1979,16 +2002,16 @@ codegen(codegen_scope *s, node *tree, int val) } n = tree->cdr->cdr; if (n->car) { - p = (char*)n->car; - off = new_lit(s, mrb_str_new(s->mrb, p, strlen(p))); - codegen(s, tree->car, VAL); - genop(s, MKOP_ABx(OP_STRING, cursp(), off)); - pop(); - genop(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1)); + p = (char*)n->car; + off = new_lit(s, mrb_str_new(s->mrb, p, strlen(p))); + codegen(s, tree->car, VAL); + genop(s, MKOP_ABx(OP_STRING, cursp(), off)); + pop(); + genop(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1)); } if (n->cdr) { - char *p2 = (char*)n->cdr; - int off; + char *p2 = (char*)n->cdr; + int off; push(); off = new_lit(s, mrb_str_new(s->mrb, p2, strlen(p2))); @@ -1999,7 +2022,7 @@ codegen(codegen_scope *s, node *tree, int val) pop(); sym = new_sym(s, mrb_intern(s->mrb, "compile")); genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc)); - mrb_gc_arena_restore(s->mrb, ai); + mrb_gc_arena_restore(s->mrb, ai); push(); } else { @@ -2370,13 +2393,14 @@ codedump(mrb_state *mrb, int n) { #ifdef ENABLE_STDIO mrb_irep *irep = mrb->irep[n]; - int i; + int i, ai; mrb_code c; if (!irep) return; printf("irep %d nregs=%d nlocals=%d pools=%d syms=%d\n", n, irep->nregs, irep->nlocals, irep->plen, irep->slen); for (i=0; i<irep->ilen; i++) { + ai = mrb_gc_arena_save(mrb); printf("%03d ", i); c = irep->iseq[i]; switch (GET_OPCODE(c)) { @@ -2677,6 +2701,7 @@ codedump(mrb_state *mrb, int n) GETARG_A(c), GETARG_B(c), GETARG_C(c)); break; } + mrb_gc_arena_restore(mrb, ai); } printf("\n"); #endif |
