summaryrefslogtreecommitdiffhomepage
path: root/src/codegen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen.c')
-rw-r--r--src/codegen.c55
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