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 */
pic_value *pool;
size_t plen, pcapa;
/* symbol pool */
pic_sym *syms;
size_t slen, scapa;
struct codegen_context *up;
} codegen_context;
@ -1024,6 +1027,10 @@ push_codegen_context(codegen_state *state, pic_value name, pic_value args, pic_v
cxt->plen = 0;
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;
create_activation(cxt);
@ -1049,6 +1056,8 @@ pop_codegen_context(codegen_state *state)
irep->ilen = state->cxt->ilen;
irep->pool = pic_realloc(pic, state->cxt->pool, sizeof(pic_value) * 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 */
xv_destroy(&cxt->args);
@ -1104,6 +1113,26 @@ index_local(codegen_state *state, pic_sym sym)
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 void
@ -1116,7 +1145,7 @@ codegen(codegen_state *state, pic_value obj)
sym = pic_sym(pic_car(pic, obj));
if (sym == state->sGREF) {
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++;
return;
} 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));
if (type == state->sGREF) {
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->code[cxt->clen].insn = OP_PUSHNONE;
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->irep);
pic_free(pic, irep->pool);
pic_free(pic, irep->syms);
break;
}
case PIC_TT_DATA: {

View File

@ -68,7 +68,8 @@ struct pic_irep {
bool varg;
struct pic_irep **irep;
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);

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_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_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_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_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;
}
CASE(OP_PUSHCONST) {
pic_value self;
struct pic_irep *irep;
struct pic_irep *irep = vm_get_irep(pic);
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]);
NEXT;
}
CASE(OP_GREF) {
if (! pic_dict_has(pic, pic->globals, c.u.i)) {
pic_errorf(pic, "logic flaw; reference to uninitialized global variable: %s", pic_symbol_name(pic, c.u.i));
struct pic_irep *irep = vm_get_irep(pic);
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;
}
CASE(OP_GSET) {
struct pic_irep *irep = vm_get_irep(pic);
pic_sym sym;
pic_value val;
sym = irep->syms[c.u.i];
val = POP();
pic_dict_set(pic, pic->globals, c.u.i, val);
pic_dict_set(pic, pic->globals, sym, val);
NEXT;
}
CASE(OP_LREF) {