diff options
Diffstat (limited to 'src/codegen.c')
| -rw-r--r-- | src/codegen.c | 159 |
1 files changed, 90 insertions, 69 deletions
diff --git a/src/codegen.c b/src/codegen.c index 2072d278a..11273bf7e 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -26,7 +26,7 @@ enum looptype { LOOP_FOR, LOOP_BEGIN, LOOP_RESCUE, -} type; +}; struct loopinfo { enum looptype type; @@ -61,8 +61,8 @@ typedef struct scope { mrb_irep *irep; size_t pcapa; - int scapa; - int rcapa; + size_t scapa; + size_t rcapa; int nlocals; int nregs; @@ -89,10 +89,10 @@ codegen_error(codegen_scope *s, const char *message) { if (!s) return; while (s->prev) { + codegen_scope *tmp = s->prev; mrb_pool_close(s->mpool); - s = s->prev; + s = tmp; } - mrb_pool_close(s->mpool); #ifdef ENABLE_STDIO if (s->filename && s->lineno) { fprintf(stderr, "codegen error:%s:%d: %s\n", s->filename, s->lineno, message); @@ -113,19 +113,19 @@ codegen_palloc(codegen_scope *s, size_t len) return p; } -void* +static void* codegen_malloc(codegen_scope *s, size_t len) { - void *p = mrb_malloc(s->mrb, len); + void *p = mrb_malloc_simple(s->mrb, len); if (!p) codegen_error(s, "mrb_malloc"); return p; } -void* +static void* codegen_realloc(codegen_scope *s, void *p, size_t len) { - p = mrb_realloc(s->mrb, p, len); + p = mrb_realloc_simple(s->mrb, p, len); if (!p && len > 0) codegen_error(s, "mrb_realloc"); return p; @@ -316,8 +316,8 @@ genop_peep(codegen_scope *s, mrb_code i, int val) if (c0 == OP_STRING) { int i = GETARG_Bx(i0); - if (s->irep->pool[i].type == IREP_TT_STRING && - s->irep->pool[i].value.s->len == 0) { + if (mrb_type(s->irep->pool[i]) == MRB_TT_STRING && + RSTRING_LEN(s->irep->pool[i]) == 0) { s->pc--; return; } @@ -397,7 +397,7 @@ static inline int new_lit(codegen_scope *s, mrb_value val) { size_t i; - struct irep_pool *pv; + mrb_value *pv; switch (mrb_type(val)) { case MRB_TT_STRING: @@ -405,24 +405,24 @@ new_lit(codegen_scope *s, mrb_value val) mrb_int len; pv = &s->irep->pool[i]; - if (pv->type != IREP_TT_STRING) continue; - if ((len = pv->value.s->len) != RSTRING_LEN(val)) continue; - if (memcmp(pv->value.s->buf, RSTRING_PTR(val), len) == 0) + 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: for (i=0; i<s->irep->plen; i++) { pv = &s->irep->pool[i]; - if (pv->type != IREP_TT_FLOAT) continue; - if (pv->value.f == mrb_float(val)) return i; + if (mrb_type(*pv) != MRB_TT_FLOAT) continue; + if (mrb_float(*pv) == mrb_float(val)) return i; } break; case MRB_TT_FIXNUM: for (i=0; i<s->irep->plen; i++) { pv = &s->irep->pool[i]; - if (pv->type != IREP_TT_FIXNUM) continue; - if (pv->value.i == mrb_fixnum(val)) return i; + if (!mrb_fixnum_p(*pv)) continue; + if (mrb_fixnum(*pv) == mrb_fixnum(val)) return i; } break; default: @@ -432,7 +432,7 @@ new_lit(codegen_scope *s, mrb_value val) if (s->irep->plen == s->pcapa) { s->pcapa *= 2; - s->irep->pool = (struct irep_pool*)codegen_realloc(s, s->irep->pool, sizeof(struct irep_pool)*s->pcapa); + s->irep->pool = (mrb_value *)codegen_realloc(s, s->irep->pool, sizeof(mrb_value)*s->pcapa); } pv = &s->irep->pool[s->irep->plen]; @@ -440,19 +440,18 @@ new_lit(codegen_scope *s, mrb_value val) switch (mrb_type(val)) { case MRB_TT_STRING: - pv->type = IREP_TT_STRING; - pv->value.s = (struct irep_pool_string*)codegen_malloc(s, sizeof(struct irep_pool_string) + RSTRING_LEN(val)); - pv->value.s->len = RSTRING_LEN(val); - memcpy(pv->value.s->buf, RSTRING_PTR(val), RSTRING_LEN(val)); + *pv = mrb_str_pool(s->mrb, val); break; + case MRB_TT_FLOAT: - pv->type = IREP_TT_FLOAT; - pv->value.f = mrb_float(val); +#ifdef MRB_WORD_BOXING + *pv = mrb_float_pool(s->mrb, mrb_float(val)); break; +#endif case MRB_TT_FIXNUM: - pv->type = IREP_TT_FIXNUM; - pv->value.i = mrb_fixnum(val); + *pv = val; break; + default: /* should not happen */ break; @@ -566,7 +565,7 @@ for_body(codegen_scope *s, node *tree) s = prev; genop(s, MKOP_Abc(OP_LAMBDA, cursp(), s->irep->rlen-1, OP_L_BLOCK)); pop(); - idx = new_msym(s, mrb_intern2(s->mrb, "each", 4)); + idx = new_msym(s, mrb_intern_lit(s->mrb, "each")); genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, 0)); } @@ -658,7 +657,7 @@ lambda_body(codegen_scope *s, node *tree, int blk) } static int -scope_body(codegen_scope *s, node *tree) +scope_body(codegen_scope *s, node *tree, int val) { codegen_scope *scope = scope_new(s->mrb, s, tree->car); @@ -666,15 +665,16 @@ scope_body(codegen_scope *s, node *tree) if (!s->iseq) { genop(scope, MKOP_A(OP_STOP, 0)); } + else if (!val) { + genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); + } else { if (scope->nregs == 0) { genop(scope, MKOP_A(OP_LOADNIL, 0)); genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); } else { - pop(); - genop_peep(scope, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL); - push(); + genop_peep(scope, MKOP_AB(OP_RETURN, scope->sp-1, OP_R_NORMAL), NOVAL); } } scope_finish(scope); @@ -708,7 +708,7 @@ attrsym(codegen_scope *s, mrb_sym a) name2[len] = '='; name2[len+1] = '\0'; - return mrb_intern2(s->mrb, name2, len+1); + return mrb_intern(s->mrb, name2, len+1); } static int @@ -977,11 +977,11 @@ static void gen_send_intern(codegen_scope *s) { pop(); - genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern2(s->mrb, "intern", 6)), 0)); + genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "intern")), 0)); push(); } static void -gen_literal_array(codegen_scope *s, node *tree, int sym, int val) +gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) { if (val) { int i = 0, j = 0; @@ -1069,7 +1069,7 @@ readint_float(codegen_scope *s, const char *p, int base) } static mrb_int -readint_mrb_int(codegen_scope *s, const char *p, int base, int neg, int *overflow) +readint_mrb_int(codegen_scope *s, const char *p, int base, mrb_bool neg, mrb_bool *overflow) { const char *e = p + strlen(p); mrb_int result = 0; @@ -1177,12 +1177,12 @@ codegen(codegen_scope *s, node *tree, int val) codegen(s, n4->car, VAL); } else { - genop(s, MKOP_ABx(OP_GETCONST, cursp(), new_msym(s, mrb_intern2(s->mrb, "StandardError", 13)))); + genop(s, MKOP_ABx(OP_GETCONST, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "StandardError")))); push(); } genop(s, MKOP_AB(OP_MOVE, cursp(), exc)); pop(); - genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern2(s->mrb, "===", 3)), 1)); + genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "===")), 1)); tmp = new_label(s); genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2)); pos2 = tmp; @@ -1236,7 +1236,7 @@ codegen(codegen_scope *s, node *tree, int val) genop(s, MKOP_Bx(OP_EPUSH, 0)); s->ensure_level++; codegen(s, tree->car, val); - idx = scope_body(s, tree->cdr); + idx = scope_body(s, tree->cdr, NOVAL); s->iseq[epush] = MKOP_Bx(OP_EPUSH, idx); s->ensure_level--; genop_peep(s, MKOP_A(OP_EPOP, 1), NOVAL); @@ -1386,7 +1386,12 @@ codegen(codegen_scope *s, node *tree, int val) if (head) { genop(s, MKOP_AB(OP_MOVE, cursp(), head)); pop(); - genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern2(s->mrb, "===", 3)), 1)); + if ((intptr_t)n->car->car == NODE_SPLAT) { + genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1)); + } + else { + genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "===")), 1)); + } } else { pop(); @@ -1410,15 +1415,21 @@ codegen(codegen_scope *s, node *tree, int val) tree = tree->cdr; } if (val) { + int pos = cursp(); genop(s, MKOP_A(OP_LOADNIL, cursp())); + if (pos3) dispatch_linked(s, pos3); + pop(); + genop(s, MKOP_AB(OP_MOVE, cursp(), pos)); push(); } - if (pos3) dispatch_linked(s, pos3); + else if (pos3) { + dispatch_linked(s, pos3); + } } break; case NODE_SCOPE: - scope_body(s, tree); + scope_body(s, tree, NOVAL); break; case NODE_FCALL: @@ -1726,7 +1737,7 @@ codegen(codegen_scope *s, node *tree, int val) } pop_n(n+1); if (sendv) n = CALL_MAXARGS; - genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern2(s->mrb, "call", 4)), n)); + genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "call")), n)); if (val) push(); } break; @@ -1915,7 +1926,7 @@ codegen(codegen_scope *s, node *tree, int val) int base = (intptr_t)tree->cdr->car; mrb_int i; mrb_code co; - int overflow; + mrb_bool overflow; i = readint_mrb_int(s, p, base, FALSE, &overflow); if (overflow) { @@ -1971,7 +1982,7 @@ codegen(codegen_scope *s, node *tree, int val) int base = (intptr_t)tree->cdr->car; mrb_int i; mrb_code co; - int overflow; + mrb_bool overflow; i = readint_mrb_int(s, p, base, TRUE, &overflow); if (overflow) { @@ -1996,7 +2007,7 @@ codegen(codegen_scope *s, node *tree, int val) default: { - int sym = new_msym(s, mrb_intern2(s->mrb, "-", 1)); + int sym = new_msym(s, mrb_intern_lit(s->mrb, "-")); genop(s, MKOP_ABx(OP_LOADI, cursp(), 0)); push(); @@ -2064,7 +2075,7 @@ codegen(codegen_scope *s, node *tree, int val) char *p = (char*)tree->car; size_t len = (intptr_t)tree->cdr; int ai = mrb_gc_arena_save(s->mrb); - int sym = new_sym(s, mrb_intern2(s->mrb, "Kernel", 6)); + int sym = new_sym(s, mrb_intern_lit(s->mrb, "Kernel")); int off = new_lit(s, mrb_str_new(s->mrb, p, len)); genop(s, MKOP_A(OP_OCLASS, cursp())); @@ -2072,7 +2083,7 @@ codegen(codegen_scope *s, node *tree, int val) push(); genop(s, MKOP_ABx(OP_STRING, cursp(), off)); pop(); - sym = new_sym(s, mrb_intern2(s->mrb, "`", 1)); + sym = new_sym(s, mrb_intern_lit(s->mrb, "`")); genop(s, MKOP_ABC(OP_SEND, cursp(), sym, 1)); mrb_gc_arena_restore(s->mrb, ai); push(); @@ -2084,7 +2095,7 @@ codegen(codegen_scope *s, node *tree, int val) char *p1 = (char*)tree->car; char *p2 = (char*)tree->cdr; int ai = mrb_gc_arena_save(s->mrb); - int sym = new_sym(s, mrb_intern2(s->mrb, REGEXP_CLASS, REGEXP_CLASS_CSTR_LEN)); + int sym = new_sym(s, mrb_intern_lit(s->mrb, REGEXP_CLASS)); int off = new_lit(s, mrb_str_new(s->mrb, p1, strlen(p1))); int argc = 1; @@ -2100,7 +2111,7 @@ codegen(codegen_scope *s, node *tree, int val) pop(); } pop(); - sym = new_sym(s, mrb_intern2(s->mrb, "compile", 7)); + sym = new_sym(s, mrb_intern_lit(s->mrb, "compile")); genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc)); mrb_gc_arena_restore(s->mrb, ai); push(); @@ -2111,7 +2122,7 @@ codegen(codegen_scope *s, node *tree, int val) if (val) { node *n = tree->car; int ai = mrb_gc_arena_save(s->mrb); - int sym = new_sym(s, mrb_intern2(s->mrb, REGEXP_CLASS, REGEXP_CLASS_CSTR_LEN)); + int sym = new_sym(s, mrb_intern_lit(s->mrb, REGEXP_CLASS)); int argc = 1; int off; char *p; @@ -2148,7 +2159,7 @@ codegen(codegen_scope *s, node *tree, int val) pop(); } pop(); - sym = new_sym(s, mrb_intern2(s->mrb, "compile", 7)); + sym = new_sym(s, mrb_intern_lit(s->mrb, "compile")); genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc)); mrb_gc_arena_restore(s->mrb, ai); push(); @@ -2213,7 +2224,7 @@ codegen(codegen_scope *s, node *tree, int val) { int a = new_msym(s, sym(tree->car)); int b = new_msym(s, sym(tree->cdr)); - int c = new_msym(s, mrb_intern2(s->mrb, "alias_method", 12)); + int c = new_msym(s, mrb_intern_lit(s->mrb,"alias_method")); genop(s, MKOP_A(OP_TCLASS, cursp())); push(); @@ -2232,7 +2243,7 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_UNDEF: { - int undef = new_msym(s, mrb_intern2(s->mrb, "undef_method", 12)); + int undef = new_msym(s, mrb_intern_lit(s->mrb, "undef_method")); int num = 0; node *t = tree; @@ -2278,7 +2289,7 @@ codegen(codegen_scope *s, node *tree, int val) pop(); pop(); idx = new_msym(s, sym(tree->car->cdr)); genop(s, MKOP_AB(OP_CLASS, cursp(), idx)); - idx = scope_body(s, tree->cdr->cdr->car); + idx = scope_body(s, tree->cdr->cdr->car, val); genop(s, MKOP_ABx(OP_EXEC, cursp(), idx)); if (val) { push(); @@ -2304,7 +2315,7 @@ codegen(codegen_scope *s, node *tree, int val) pop(); idx = new_msym(s, sym(tree->car->cdr)); genop(s, MKOP_AB(OP_MODULE, cursp(), idx)); - idx = scope_body(s, tree->cdr->car); + idx = scope_body(s, tree->cdr->car, val); genop(s, MKOP_ABx(OP_EXEC, cursp(), idx)); if (val) { push(); @@ -2319,7 +2330,7 @@ codegen(codegen_scope *s, node *tree, int val) codegen(s, tree->car, VAL); pop(); genop(s, MKOP_AB(OP_SCLASS, cursp(), cursp())); - idx = scope_body(s, tree->cdr->car); + idx = scope_body(s, tree->cdr->car, val); genop(s, MKOP_ABx(OP_EXEC, cursp(), idx)); if (val) { push(); @@ -2412,13 +2423,14 @@ scope_new(mrb_state *mrb, codegen_scope *prev, node *lv) p->icapa = 1024; p->iseq = (mrb_code*)mrb_malloc(mrb, sizeof(mrb_code)*p->icapa); + p->irep->iseq = p->iseq; p->pcapa = 32; - p->irep->pool = (struct irep_pool*)mrb_malloc(mrb, sizeof(struct irep_pool)*p->pcapa); + p->irep->pool = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value)*p->pcapa); p->irep->plen = 0; p->scapa = 256; - p->irep->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*256); + p->irep->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*p->scapa); p->irep->slen = 0; p->lv = lv; @@ -2467,7 +2479,7 @@ scope_finish(codegen_scope *s) irep->lines = 0; } } - irep->pool = (struct irep_pool*)codegen_realloc(s, irep->pool, sizeof(struct irep_pool)*irep->plen); + irep->pool = (mrb_value*)codegen_realloc(s, irep->pool, sizeof(mrb_value)*irep->plen); irep->syms = (mrb_sym*)codegen_realloc(s, irep->syms, sizeof(mrb_sym)*irep->slen); irep->reps = (mrb_irep**)codegen_realloc(s, irep->reps, sizeof(mrb_irep*)*irep->rlen); if (s->filename) { @@ -2722,7 +2734,7 @@ codedump(mrb_state *mrb, mrb_irep *irep) break; case OP_LAMBDA: - printf("OP_LAMBDA\tR%d\tI(%+d)\t%d\n", GETARG_A(c), GETARG_b(c), GETARG_c(c)); + printf("OP_LAMBDA\tR%d\tI(%+d)\t%d\n", GETARG_A(c), GETARG_b(c)+1, GETARG_c(c)); break; case OP_RANGE: printf("OP_RANGE\tR%d\tR%d\t%d\n", GETARG_A(c), GETARG_B(c), GETARG_C(c)); @@ -2809,8 +2821,8 @@ codedump(mrb_state *mrb, mrb_irep *irep) break; case OP_STRING: { - struct irep_pool *pv = &irep->pool[GETARG_Bx(c)]; - mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, pv->value.s->buf, pv->value.s->len)); + mrb_value v = irep->pool[GETARG_Bx(c)]; + mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, RSTRING_PTR(v), RSTRING_LEN(v))); printf("OP_STRING\tR%d\t%s\n", GETARG_A(c), RSTRING_PTR(s)); } break; @@ -2833,7 +2845,7 @@ codedump(mrb_state *mrb, mrb_irep *irep) mrb_sym2name(mrb, irep->syms[GETARG_B(c)])); break; case OP_EXEC: - printf("OP_EXEC\tR%d\tI(%+d)\n", GETARG_A(c), GETARG_Bx(c)); + printf("OP_EXEC\tR%d\tI(%+d)\n", GETARG_A(c), GETARG_Bx(c)+1); break; case OP_SCLASS: printf("OP_SCLASS\tR%d\tR%d\n", GETARG_A(c), GETARG_B(c)); @@ -2842,10 +2854,14 @@ codedump(mrb_state *mrb, mrb_irep *irep) printf("OP_TCLASS\tR%d\n", GETARG_A(c)); break; case OP_ERR: - printf("OP_ERR\tL(%d)\n", GETARG_Bx(c)); + { + mrb_value v = irep->pool[GETARG_Bx(c)]; + mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, RSTRING_PTR(v), RSTRING_LEN(v))); + printf("OP_ERR\t%s\n", RSTRING_PTR(s)); + } break; case OP_EPUSH: - printf("OP_EPUSH\t:I(%+d)\n", GETARG_Bx(c)); + printf("OP_EPUSH\t:I(%+d)\n", GETARG_Bx(c)+1); break; case OP_ONERR: printf("OP_ONERR\t%03d\n", i+GETARG_sBx(c)); @@ -2886,9 +2902,9 @@ codedump_recur(mrb_state *mrb, mrb_irep *irep) } void -codedump_all(mrb_state *mrb, struct RProc *proc) +mrb_codedump_all(mrb_state *mrb, struct RProc *proc) { - return codedump_recur(mrb, proc->body.irep); + codedump_recur(mrb, proc->body.irep); } struct RProc* @@ -2913,6 +2929,11 @@ mrb_generate_code(mrb_state *mrb, parser_state *p) return proc; } else { + if (scope->filename == scope->irep->filename) { + scope->irep->filename = NULL; + } + mrb_irep_decref(mrb, scope->irep); + mrb_pool_close(scope->mpool); return NULL; } } |
