Merge branch 'refactor-codegen3'

This commit is contained in:
Yuichi Nishiwaki 2014-03-22 20:00:23 +09:00
commit 14eba8f92d
3 changed files with 87 additions and 58 deletions

View File

@ -61,8 +61,8 @@ struct pic_code {
struct pic_irep {
PIC_OBJECT_HEADER
pic_code *code;
int argc, localc;
unsigned *cv_tbl, cv_num;
int argc, localc, capturec;
unsigned *cv_tbl;
bool varg;
struct pic_irep **irep;
pic_value *pool;
@ -188,9 +188,9 @@ pic_dump_irep(struct pic_irep *irep)
unsigned i;
printf("## irep %p\n", (void *)irep);
printf("[clen = %zd, argc = %d, localc = %d]\n", irep->clen, irep->argc, irep->localc);
printf(":: cv_num = %d\n", irep->cv_num);
for (i = 0; i < irep->cv_num; ++i) {
printf("[clen = %zd, argc = %d, localc = %d, capturec = %d]\n", irep->clen, irep->argc, irep->localc, irep->capturec);
printf(":: cv_tbl\n");
for (i = 0; i < (unsigned)irep->capturec; ++i) {
printf(": %d -> %d\n", irep->cv_tbl[i], i);
}
for (i = 0; i < irep->clen; ++i) {

View File

@ -774,9 +774,8 @@ pic_analyze(pic_state *pic, pic_value obj)
typedef struct resolver_scope {
int depth;
bool varg;
int argc, localc;
int argc, localc, capturec;
xhash *cvs, *lvs;
unsigned cv_num;
struct resolver_scope *up;
} resolver_scope;
@ -818,11 +817,11 @@ destroy_resolver_state(resolver_state *state)
}
static void
push_resolver_scope(resolver_state *state, pic_value args, pic_value locals, bool varg, pic_value closes)
push_resolver_scope(resolver_state *state, pic_value args, pic_value locals, bool varg, pic_value captures)
{
pic_state *pic = state->pic;
resolver_scope *scope;
int i, c;
int i;
scope = (resolver_scope *)pic_alloc(pic, sizeof(resolver_scope));
scope->up = state->scope;
@ -831,6 +830,7 @@ push_resolver_scope(resolver_state *state, pic_value args, pic_value locals, boo
scope->cvs = xh_new_int();
scope->argc = pic_length(pic, args) + 1;
scope->localc = pic_length(pic, locals);
scope->capturec = pic_length(pic, captures);
scope->varg = varg;
/* arguments */
@ -844,9 +844,8 @@ push_resolver_scope(resolver_state *state, pic_value args, pic_value locals, boo
}
/* closed variables */
scope->cv_num = 0;
for (i = 0, c = pic_length(pic, closes); i < c; ++i) {
xh_put_int(scope->cvs, pic_sym(pic_list_ref(pic, closes, i)), scope->cv_num++);
for (i = 0; i < scope->capturec; ++i) {
xh_put_int(scope->cvs, pic_sym(pic_list_ref(pic, captures, i)), i);
}
state->scope = scope;
@ -1018,10 +1017,10 @@ pic_resolve(pic_state *pic, pic_value obj)
typedef struct codegen_context {
bool varg;
/* rest args variable is counted by localc */
int argc, localc;
/* rest args variable is counted as a local */
xvect args, locals, captures;
/* closed variable table */
unsigned *cv_tbl, cv_num;
unsigned *cv_tbl;
/* actual bit code sequence */
pic_code *code;
size_t clen, ccapa;
@ -1045,7 +1044,6 @@ typedef struct codegen_state {
pic_sym sGREF, sCREF, sLREF;
pic_sym sCALL, sTAILCALL, sRETURN;
pic_sym sCALL_WITH_VALUES, sTAILCALL_WITH_VALUES;
unsigned *cv_tbl, cv_num;
} codegen_state;
static void push_codegen_context(codegen_state *, pic_value, pic_value, bool, pic_value);
@ -1087,48 +1085,73 @@ destroy_codegen_state(codegen_state *state)
}
static void
push_codegen_context(codegen_state *state, pic_value args, pic_value locals, bool varg, pic_value closes)
create_cv_table(pic_state *pic, codegen_context *cxt)
{
pic_state *pic = state->pic;
codegen_context *cxt;
int i, c;
xhash *vars;
size_t i;
xhash *regs;
pic_sym *var;
size_t offset;
cxt = (codegen_context *)pic_alloc(pic, sizeof(codegen_context));
cxt->up = state->cxt;
cxt->argc = pic_length(pic, args) + 1;
cxt->localc = pic_length(pic, locals);
cxt->varg = varg;
regs = xh_new_int();
/* number local variables */
vars = xh_new_int();
for (i = 1; i < cxt->argc; ++i) {
xh_put_int(vars, pic_sym(pic_list_ref(pic, args, i - 1)), i);
offset = 1;
for (i = 0; i < cxt->args.size; ++i) {
var = xv_get(&cxt->args, i);
xh_put_int(regs, *var, i + offset);
}
for (i = 0; i < cxt->localc; ++i) {
xh_put_int(vars, pic_sym(pic_list_ref(pic, locals, i)), cxt->argc + i);
offset += i;
for (i = 0; i < cxt->locals.size; ++i) {
var = xv_get(&cxt->locals, i);
xh_put_int(regs, *var, i + offset);
}
/* closed variables */
cxt->cv_tbl = NULL;
cxt->cv_num = 0;
for (i = 0, c = pic_length(pic, closes); i < c; ++i) {
i = cxt->cv_num++;
cxt->cv_tbl = (unsigned *)pic_realloc(pic, cxt->cv_tbl, sizeof(unsigned) * cxt->cv_num);
cxt->cv_tbl[i] = xh_get_int(vars, pic_sym(pic_list_ref(pic, closes, i)))->val;
cxt->cv_tbl = pic_calloc(pic, cxt->captures.size, sizeof(unsigned));
for (i = 0; i < cxt->captures.size; ++i) {
var = xv_get(&cxt->captures, i);
cxt->cv_tbl[i] = xh_get_int(regs, *var)->val;
}
xh_destroy(vars);
xh_destroy(regs);
}
cxt->code = (pic_code *)pic_calloc(pic, PIC_ISEQ_SIZE, sizeof(pic_code));
static void
push_codegen_context(codegen_state *state, pic_value args, pic_value locals, bool varg, pic_value captures)
{
pic_state *pic = state->pic;
codegen_context *cxt;
pic_value var;
cxt = (codegen_context *)pic_alloc(pic, sizeof(codegen_context));
cxt->up = state->cxt;
cxt->varg = varg;
xv_init(&cxt->args, sizeof(pic_sym));
xv_init(&cxt->locals, sizeof(pic_sym));
xv_init(&cxt->captures, sizeof(pic_sym));
pic_for_each (var, args) {
xv_push(&cxt->args, &pic_sym(var));
}
pic_for_each (var, locals) {
xv_push(&cxt->locals, &pic_sym(var));
}
pic_for_each (var, captures) {
xv_push(&cxt->captures, &pic_sym(var));
}
create_cv_table(pic, cxt);
cxt->code = pic_calloc(pic, PIC_ISEQ_SIZE, sizeof(pic_code));
cxt->clen = 0;
cxt->ccapa = PIC_ISEQ_SIZE;
cxt->irep = (struct pic_irep **)pic_calloc(pic, PIC_IREP_SIZE, sizeof(struct pic_irep *));
cxt->irep = pic_calloc(pic, PIC_IREP_SIZE, sizeof(struct pic_irep *));
cxt->ilen = 0;
cxt->icapa = PIC_IREP_SIZE;
cxt->pool = (pic_value *)pic_calloc(pic, PIC_POOL_SIZE, sizeof(pic_value));
cxt->pool = pic_calloc(pic, PIC_POOL_SIZE, sizeof(pic_value));
cxt->plen = 0;
cxt->pcapa = PIC_POOL_SIZE;
@ -1145,10 +1168,10 @@ pop_codegen_context(codegen_state *state)
/* create irep */
irep = (struct pic_irep *)pic_obj_alloc(pic, sizeof(struct pic_irep), PIC_TT_IREP);
irep->varg = state->cxt->varg;
irep->argc = state->cxt->argc;
irep->localc = state->cxt->localc;
irep->argc = state->cxt->args.size + 1;
irep->localc = state->cxt->locals.size;
irep->capturec = state->cxt->captures.size;
irep->cv_tbl = state->cxt->cv_tbl;
irep->cv_num = state->cxt->cv_num;
irep->code = pic_realloc(pic, state->cxt->code, sizeof(pic_code) * state->cxt->clen);
irep->clen = state->cxt->clen;
irep->irep = pic_realloc(pic, state->cxt->irep, sizeof(struct pic_irep *) * state->cxt->ilen);
@ -1156,6 +1179,11 @@ pop_codegen_context(codegen_state *state)
irep->pool = pic_realloc(pic, state->cxt->pool, sizeof(pic_value) * state->cxt->plen);
irep->plen = state->cxt->plen;
/* finalize */
xv_destroy(&cxt->args);
xv_destroy(&cxt->locals);
xv_destroy(&cxt->captures);
/* destroy context */
cxt = cxt->up;
pic_free(pic, state->cxt);
@ -1230,7 +1258,7 @@ codegen(codegen_state *state, pic_value obj)
if (cxt->ilen >= cxt->icapa) {
cxt->icapa *= 2;
cxt->irep = (struct pic_irep **)pic_realloc(pic, cxt->irep, sizeof(struct pic_irep *) * cxt->icapa);
cxt->irep = pic_realloc(pic, cxt->irep, sizeof(struct pic_irep *) * cxt->icapa);
}
k = cxt->ilen++;
cxt->code[cxt->clen].insn = OP_LAMBDA;
@ -1303,7 +1331,7 @@ codegen(codegen_state *state, pic_value obj)
default:
if (cxt->plen >= cxt->pcapa) {
cxt->pcapa *= 2;
cxt->pool = (pic_value *)pic_realloc(pic, cxt->pool, sizeof(pic_value) * cxt->pcapa);
cxt->pool = pic_realloc(pic, cxt->pool, sizeof(pic_value) * cxt->pcapa);
}
pidx = cxt->plen++;
cxt->pool[pidx] = obj;

View File

@ -677,27 +677,28 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value argv)
goto L_RET;
}
else {
struct pic_irep *irep = proc->u.irep;
int i;
pic_value rest;
if (ci->argc != proc->u.irep->argc) {
if (! (proc->u.irep->varg && ci->argc >= proc->u.irep->argc)) {
pic_errorf(pic, "wrong number of arguments (%d for %d%s)", ci->argc - 1, proc->u.irep->argc - 1, (proc->u.irep->varg ? "+" : ""));
if (ci->argc != irep->argc) {
if (! (irep->varg && ci->argc >= irep->argc)) {
pic_errorf(pic, "wrong number of arguments (%d for %d%s)", ci->argc - 1, irep->argc - 1, (irep->varg ? "+" : ""));
}
}
/* prepare rest args */
if (proc->u.irep->varg) {
if (irep->varg) {
rest = pic_nil_value();
for (i = 0; i < ci->argc - proc->u.irep->argc; ++i) {
for (i = 0; i < ci->argc - irep->argc; ++i) {
pic_gc_protect(pic, v = POP());
rest = pic_cons(pic, v, rest);
}
PUSH(rest);
}
/* prepare local variable area */
if (proc->u.irep->localc > 0) {
int l = proc->u.irep->localc;
if (proc->u.irep->varg) {
if (irep->localc > 0) {
int l = irep->localc;
if (irep->varg) {
--l;
}
for (i = 0; i < l; ++i) {
@ -708,13 +709,13 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value argv)
/* prepare env */
ci->env = (struct pic_env *)pic_obj_alloc(pic, sizeof(struct pic_env), PIC_TT_ENV);
ci->env->up = proc->env;
ci->env->valuec = proc->u.irep->cv_num;
ci->env->values = (pic_value *)pic_calloc(pic, ci->env->valuec, sizeof(pic_value));
ci->env->valuec = irep->capturec;
ci->env->values = pic_calloc(pic, ci->env->valuec, sizeof(pic_value));
for (i = 0; i < ci->env->valuec; ++i) {
ci->env->values[i] = ci->fp[proc->u.irep->cv_tbl[i]];
ci->env->values[i] = ci->fp[irep->cv_tbl[i]];
}
pic->ip = proc->u.irep->code;
pic->ip = irep->code;
pic_gc_arena_restore(pic, ai);
JUMP;
}