add irep->syms

This commit is contained in:
Yuichi Nishiwaki 2015-01-19 01:29:00 +09:00
parent cabae2767b
commit 1b510e982e
4 changed files with 65 additions and 18 deletions

View File

@ -884,6 +884,9 @@ typedef struct codegen_context {
/* constant object pool */ /* constant object pool */
pic_value *pool; pic_value *pool;
size_t plen, pcapa; size_t plen, pcapa;
/* symbol pool */
pic_sym *syms;
size_t slen, scapa;
struct codegen_context *up; struct codegen_context *up;
} codegen_context; } codegen_context;
@ -1024,6 +1027,10 @@ push_codegen_context(codegen_state *state, pic_value name, pic_value args, pic_v
cxt->plen = 0; cxt->plen = 0;
cxt->pcapa = PIC_POOL_SIZE; cxt->pcapa = PIC_POOL_SIZE;
cxt->syms = pic_calloc(pic, PIC_POOL_SIZE, sizeof(pic_value));
cxt->slen = 0;
cxt->scapa = PIC_POOL_SIZE;
state->cxt = cxt; state->cxt = cxt;
create_activation(cxt); create_activation(cxt);
@ -1049,6 +1056,8 @@ pop_codegen_context(codegen_state *state)
irep->ilen = state->cxt->ilen; irep->ilen = state->cxt->ilen;
irep->pool = pic_realloc(pic, state->cxt->pool, sizeof(pic_value) * state->cxt->plen); irep->pool = pic_realloc(pic, state->cxt->pool, sizeof(pic_value) * state->cxt->plen);
irep->plen = state->cxt->plen; irep->plen = state->cxt->plen;
irep->syms = pic_realloc(pic, state->cxt->syms, sizeof(pic_sym) * state->cxt->slen);
irep->slen = state->cxt->slen;
/* finalize */ /* finalize */
xv_destroy(&cxt->args); xv_destroy(&cxt->args);
@ -1104,6 +1113,26 @@ index_local(codegen_state *state, pic_sym sym)
return -1; return -1;
} }
static int
index_symbol(codegen_state *state, pic_sym sym)
{
pic_state *pic = state->pic;
codegen_context *cxt = state->cxt;
size_t i;
for (i = 0; i < cxt->slen; ++i) {
if (cxt->syms[i] == sym) {
return i;
}
}
if (cxt->slen >= cxt->scapa) {
cxt->scapa *= 2;
cxt->syms = pic_realloc(pic, cxt->syms, sizeof(pic_sym) * cxt->scapa);
}
cxt->syms[cxt->slen++] = sym;
return i;
}
static struct pic_irep *codegen_lambda(codegen_state *, pic_value); static struct pic_irep *codegen_lambda(codegen_state *, pic_value);
static void static void
@ -1116,7 +1145,7 @@ codegen(codegen_state *state, pic_value obj)
sym = pic_sym(pic_car(pic, obj)); sym = pic_sym(pic_car(pic, obj));
if (sym == state->sGREF) { if (sym == state->sGREF) {
cxt->code[cxt->clen].insn = OP_GREF; cxt->code[cxt->clen].insn = OP_GREF;
cxt->code[cxt->clen].u.i = pic_sym(pic_list_ref(pic, obj, 1)); cxt->code[cxt->clen].u.i = index_symbol(state, pic_sym(pic_list_ref(pic, obj, 1)));
cxt->clen++; cxt->clen++;
return; return;
} else if (sym == state->sCREF) { } else if (sym == state->sCREF) {
@ -1156,7 +1185,7 @@ codegen(codegen_state *state, pic_value obj)
type = pic_sym(pic_list_ref(pic, var, 0)); type = pic_sym(pic_list_ref(pic, var, 0));
if (type == state->sGREF) { if (type == state->sGREF) {
cxt->code[cxt->clen].insn = OP_GSET; cxt->code[cxt->clen].insn = OP_GSET;
cxt->code[cxt->clen].u.i = pic_int(pic_list_ref(pic, var, 1)); cxt->code[cxt->clen].u.i = index_symbol(state, pic_sym(pic_list_ref(pic, var, 1)));
cxt->clen++; cxt->clen++;
cxt->code[cxt->clen].insn = OP_PUSHNONE; cxt->code[cxt->clen].insn = OP_PUSHNONE;
cxt->clen++; cxt->clen++;

View File

@ -644,6 +644,7 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
pic_free(pic, irep->code); pic_free(pic, irep->code);
pic_free(pic, irep->irep); pic_free(pic, irep->irep);
pic_free(pic, irep->pool); pic_free(pic, irep->pool);
pic_free(pic, irep->syms);
break; break;
} }
case PIC_TT_DATA: { case PIC_TT_DATA: {

View File

@ -68,7 +68,8 @@ struct pic_irep {
bool varg; bool varg;
struct pic_irep **irep; struct pic_irep **irep;
pic_value *pool; pic_value *pool;
size_t clen, ilen, plen; pic_sym *syms;
size_t clen, ilen, plen, slen;
}; };
pic_value pic_analyze(pic_state *, pic_value); pic_value pic_analyze(pic_state *, pic_value);

View File

@ -550,6 +550,23 @@ pic_vm_tear_off(pic_state *pic)
} }
} }
static struct pic_irep *
vm_get_irep(pic_state *pic)
{
pic_value self;
struct pic_irep *irep;
self = pic->ci->fp[0];
if (! pic_proc_p(self)) {
pic_errorf(pic, "logic flaw");
}
irep = pic_proc_ptr(self)->u.irep;
if (! pic_proc_irep_p(pic_proc_ptr(self))) {
pic_errorf(pic, "logic flaw");
}
return irep;
}
pic_value pic_value
pic_apply0(pic_state *pic, struct pic_proc *proc) pic_apply0(pic_state *pic, struct pic_proc *proc)
{ {
@ -688,7 +705,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
&&L_OP_GREF, &&L_OP_GSET, &&L_OP_LREF, &&L_OP_LSET, &&L_OP_CREF, &&L_OP_CSET, &&L_OP_GREF, &&L_OP_GSET, &&L_OP_LREF, &&L_OP_LSET, &&L_OP_CREF, &&L_OP_CSET,
&&L_OP_JMP, &&L_OP_JMPIF, &&L_OP_NOT, &&L_OP_CALL, &&L_OP_TAILCALL, &&L_OP_RET, &&L_OP_JMP, &&L_OP_JMPIF, &&L_OP_NOT, &&L_OP_CALL, &&L_OP_TAILCALL, &&L_OP_RET,
&&L_OP_LAMBDA, &&L_OP_CONS, &&L_OP_CAR, &&L_OP_CDR, &&L_OP_NILP, &&L_OP_LAMBDA, &&L_OP_CONS, &&L_OP_CAR, &&L_OP_CDR, &&L_OP_NILP,
&&L_OP_SYMBOL_P, &&L_OP_PAIR_P, &&L_OP_SYMBOL_P, &&L_OP_PAIR_P,
&&L_OP_ADD, &&L_OP_SUB, &&L_OP_MUL, &&L_OP_DIV, &&L_OP_MINUS, &&L_OP_ADD, &&L_OP_SUB, &&L_OP_MUL, &&L_OP_DIV, &&L_OP_MINUS,
&&L_OP_EQ, &&L_OP_LT, &&L_OP_LE, &&L_OP_STOP &&L_OP_EQ, &&L_OP_LT, &&L_OP_LE, &&L_OP_STOP
}; };
@ -751,32 +768,31 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
NEXT; NEXT;
} }
CASE(OP_PUSHCONST) { CASE(OP_PUSHCONST) {
pic_value self; struct pic_irep *irep = vm_get_irep(pic);
struct pic_irep *irep;
self = pic->ci->fp[0];
if (! pic_proc_p(self)) {
pic_errorf(pic, "logic flaw");
}
irep = pic_proc_ptr(self)->u.irep;
if (! pic_proc_irep_p(pic_proc_ptr(self))) {
pic_errorf(pic, "logic flaw");
}
PUSH(irep->pool[c.u.i]); PUSH(irep->pool[c.u.i]);
NEXT; NEXT;
} }
CASE(OP_GREF) { CASE(OP_GREF) {
if (! pic_dict_has(pic, pic->globals, c.u.i)) { struct pic_irep *irep = vm_get_irep(pic);
pic_errorf(pic, "logic flaw; reference to uninitialized global variable: %s", pic_symbol_name(pic, c.u.i)); pic_sym sym;
sym = irep->syms[c.u.i];
if (! pic_dict_has(pic, pic->globals, sym)) {
pic_errorf(pic, "logic flaw; reference to uninitialized global variable: %s", pic_symbol_name(pic, sym));
} }
PUSH(pic_dict_ref(pic, pic->globals, c.u.i)); PUSH(pic_dict_ref(pic, pic->globals, sym));
NEXT; NEXT;
} }
CASE(OP_GSET) { CASE(OP_GSET) {
struct pic_irep *irep = vm_get_irep(pic);
pic_sym sym;
pic_value val; pic_value val;
sym = irep->syms[c.u.i];
val = POP(); val = POP();
pic_dict_set(pic, pic->globals, c.u.i, val); pic_dict_set(pic, pic->globals, sym, val);
NEXT; NEXT;
} }
CASE(OP_LREF) { CASE(OP_LREF) {