mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
modified to use irep->reps to reference child ireps. preparation for
removing irep array from mrb_state. note that instructions OP_LAMBDA, OP_EXEC and OP_EPUSH are incompatible, and dumped mrb format has changed.
This commit is contained in:
+50
-37
@@ -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]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user