From 1b510e982ec9d9838f4ee9741fecce63c5ab004b Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Mon, 19 Jan 2015 01:29:00 +0900 Subject: [PATCH] add irep->syms --- extlib/benz/codegen.c | 33 ++++++++++++++++++++-- extlib/benz/gc.c | 1 + extlib/benz/include/picrin/irep.h | 3 +- extlib/benz/vm.c | 46 +++++++++++++++++++++---------- 4 files changed, 65 insertions(+), 18 deletions(-) diff --git a/extlib/benz/codegen.c b/extlib/benz/codegen.c index f3d34730..f488d898 100644 --- a/extlib/benz/codegen.c +++ b/extlib/benz/codegen.c @@ -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++; diff --git a/extlib/benz/gc.c b/extlib/benz/gc.c index 9c005479..15b0f59a 100644 --- a/extlib/benz/gc.c +++ b/extlib/benz/gc.c @@ -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: { diff --git a/extlib/benz/include/picrin/irep.h b/extlib/benz/include/picrin/irep.h index 5b10628a..70597a71 100644 --- a/extlib/benz/include/picrin/irep.h +++ b/extlib/benz/include/picrin/irep.h @@ -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); diff --git a/extlib/benz/vm.c b/extlib/benz/vm.c index 0e5bc7fd..db54e0ba 100644 --- a/extlib/benz/vm.c +++ b/extlib/benz/vm.c @@ -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) {