diff options
Diffstat (limited to 'src/codegen.c')
| -rw-r--r-- | src/codegen.c | 87 |
1 files changed, 50 insertions, 37 deletions
diff --git a/src/codegen.c b/src/codegen.c index 548d8d8f8..2afcb340e 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -62,6 +62,7 @@ typedef struct scope { mrb_irep *irep; size_t pcapa; int scapa; + int rcapa; int nlocals; int nregs; @@ -498,7 +499,7 @@ static void for_body(codegen_scope *s, node *tree) { codegen_scope *prev = s; - int idx, base = s->irep->idx; + int idx; struct loopinfo *lp; node *n2; mrb_code c; @@ -507,7 +508,6 @@ for_body(codegen_scope *s, node *tree) codegen(s, tree->cdr->car, VAL); // generate loop-block s = scope_new(s->mrb, s, tree->car); - idx = s->irep->idx; lp = loop_push(s, LOOP_FOR); lp->pc1 = new_label(s); @@ -532,7 +532,7 @@ for_body(codegen_scope *s, node *tree) loop_pop(s, NOVAL); scope_finish(s); s = prev; - genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx - base, OP_L_BLOCK)); + 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)); genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, 0)); @@ -541,11 +541,9 @@ for_body(codegen_scope *s, node *tree) static int lambda_body(codegen_scope *s, node *tree, int blk) { - int idx, base = s->irep->idx; mrb_code c; - + codegen_scope *parent = s; s = scope_new(s->mrb, s, tree->car); - idx = s->irep->idx; s->mscope = !blk; if (blk) { @@ -624,15 +622,13 @@ lambda_body(codegen_scope *s, node *tree, int blk) loop_pop(s, NOVAL); } scope_finish(s); - - return idx - base; + return parent->irep->rlen - 1; } static int scope_body(codegen_scope *s, node *tree) { codegen_scope *scope = scope_new(s->mrb, s, tree->car); - int idx = scope->irep->idx; codegen(scope, tree->cdr, VAL); if (!s->iseq) { @@ -650,9 +646,11 @@ scope_body(codegen_scope *s, node *tree) } } scope_finish(scope); - if (s->irep) - return idx - s->irep->idx; - return 0; + if (!s->irep) { + /* should not happen */ + return 0; + } + return s->irep->rlen - 1; } static mrb_bool @@ -2343,6 +2341,21 @@ codegen(codegen_scope *s, node *tree, int val) } } +static void +scope_add_irep(codegen_scope *s, mrb_irep *irep) +{ + if (s->irep == NULL) { + s->irep = irep; + return; + } + if (s->irep->rlen == s->rcapa) { + s->rcapa *= 2; + s->irep->reps = (mrb_irep**)codegen_realloc(s, s->irep->reps, sizeof(mrb_irep*)*s->rcapa); + } + s->irep->reps[s->irep->rlen] = irep; + s->irep->rlen++; +} + static codegen_scope* scope_new(mrb_state *mrb, codegen_scope *prev, node *lv) { @@ -2360,6 +2373,10 @@ scope_new(mrb_state *mrb, codegen_scope *prev, node *lv) p->mscope = 0; p->irep = mrb_add_irep(mrb); + scope_add_irep(prev, p->irep); + + p->rcapa = 8; + p->irep->reps = (mrb_irep**)mrb_malloc(mrb, sizeof(mrb_irep*)*p->rcapa); p->icapa = 1024; p->iseq = (mrb_code*)mrb_malloc(mrb, sizeof(mrb_code)*p->icapa); @@ -2420,6 +2437,7 @@ scope_finish(codegen_scope *s) } 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) { s->irep->filename = mrb_parser_get_filename(s->parser, s->filename_index); mrb_debug_info_append_file(mrb, s->irep, s->debug_start_pos, s->pc); @@ -2515,8 +2533,8 @@ codedump(mrb_state *mrb, mrb_irep *irep) mrb_code c; if (!irep) return; - printf("irep %d nregs=%d nlocals=%d pools=%d syms=%d\n", irep->idx, - irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen); + printf("irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d\n", irep, + irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen, (int)irep->rlen); for (i=0; i<irep->ilen; i++) { ai = mrb_gc_arena_save(mrb); printf("%03d ", i); @@ -2784,7 +2802,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), irep->idx+GETARG_Bx(c)); + printf("OP_EXEC\tR%d\tI(%+d)\n", GETARG_A(c), GETARG_Bx(c)); break; case OP_SCLASS: printf("OP_SCLASS\tR%d\tR%d\n", GETARG_A(c), GETARG_B(c)); @@ -2796,7 +2814,7 @@ codedump(mrb_state *mrb, mrb_irep *irep) printf("OP_ERR\tL(%d)\n", GETARG_Bx(c)); break; case OP_EPUSH: - printf("OP_EPUSH\t:I(%d)\n", irep->idx+GETARG_Bx(c)); + printf("OP_EPUSH\t:I(%+d)\n", GETARG_Bx(c)); break; case OP_ONERR: printf("OP_ONERR\t%03d\n", i+GETARG_sBx(c)); @@ -2825,24 +2843,30 @@ codedump(mrb_state *mrb, mrb_irep *irep) #endif } -void -codedump_all(mrb_state *mrb, struct RProc *proc) +static void +codedump_recur(mrb_state *mrb, mrb_irep *irep) { size_t i; - mrb_irep *irep = proc->body.irep; - for (i=irep->idx; i<mrb->irep_len; i++) { - codedump(mrb, mrb->irep[i]); + codedump(mrb, irep); + for (i=0; i<irep->rlen; i++) { + codedump_recur(mrb, irep->reps[i]); } } -static int -codegen_start(mrb_state *mrb, parser_state *p) +void +codedump_all(mrb_state *mrb, struct RProc *proc) +{ + return codedump_recur(mrb, proc->body.irep); +} + +struct RProc* +mrb_generate_code(mrb_state *mrb, parser_state *p) { codegen_scope *scope = scope_new(mrb, 0, 0); if (!scope) { - return -1; + return NULL; } scope->mrb = mrb; scope->parser = p; @@ -2852,20 +2876,9 @@ codegen_start(mrb_state *mrb, parser_state *p) // prepare irep codegen(scope, p->tree, NOVAL); mrb_pool_close(scope->mpool); - return 0; + return mrb_proc_new(mrb, scope->irep); } else { - return -1; + return NULL; } } - -struct RProc* -mrb_generate_code(mrb_state *mrb, parser_state *p) -{ - int start = mrb->irep_len; - int n; - - n = codegen_start(mrb, p); - if (n < 0) return NULL; - return mrb_proc_new(mrb, mrb->irep[start]); -} |
