diff --git a/include/picrin.h b/include/picrin.h index 4c6d63b3..94fc9648 100644 --- a/include/picrin.h +++ b/include/picrin.h @@ -87,9 +87,6 @@ typedef struct { pic_value lib_tbl; struct pic_lib *lib; - pic_value *pool; - size_t plen, pcapa; - jmp_buf *jmp; const char *errmsg; diff --git a/include/picrin/irep.h b/include/picrin/irep.h index 857948b8..3238694c 100644 --- a/include/picrin/irep.h +++ b/include/picrin/irep.h @@ -65,7 +65,8 @@ struct pic_irep { unsigned *cv_tbl, cv_num; bool varg; struct pic_irep **irep; - size_t clen, ilen; + pic_value *pool; + size_t clen, ilen, plen; }; void pic_dump_irep(pic_state *, struct pic_irep *); diff --git a/src/codegen.c b/src/codegen.c index a45599a0..091593c0 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -33,6 +33,7 @@ new_irep(pic_state *pic) irep->localc = -1; irep->varg = false; irep->irep = NULL; + irep->pool = NULL; return irep; } @@ -44,7 +45,7 @@ typedef struct codegen_scope { bool varg; /* local variables are 1-indexed, 0 is reserved for the callee */ struct xhash *local_tbl; - /* rest args variable is counted at localc */ + /* rest args variable is counted by localc */ size_t argc, localc; /* if local var i is captured, then dirty_flags[i] == 1 */ int *dirty_flags; @@ -54,6 +55,9 @@ typedef struct codegen_scope { /* child ireps */ struct pic_irep **irep; size_t ilen, icapa; + /* constant object pool */ + pic_value *pool; + size_t plen, pcapa; struct codegen_scope *up; } codegen_scope; @@ -76,6 +80,9 @@ new_global_scope(pic_state *pic) scope->irep = (struct pic_irep **)pic_calloc(pic, PIC_IREP_SIZE, sizeof(struct pic_irep *)); scope->ilen = 0; scope->icapa = PIC_IREP_SIZE; + scope->pool = (pic_value *)pic_calloc(pic, PIC_POOL_SIZE, sizeof(pic_value)); + scope->plen = 0; + scope->pcapa = PIC_POOL_SIZE; return scope; } @@ -122,6 +129,10 @@ new_local_scope(pic_state *pic, pic_value args, codegen_scope *scope) new_scope->ilen = 0; new_scope->icapa = PIC_IREP_SIZE; + new_scope->pool = (pic_value *)pic_calloc(pic, PIC_POOL_SIZE, sizeof(pic_value)); + new_scope->plen = 0; + new_scope->pcapa = PIC_POOL_SIZE; + return new_scope; } @@ -446,11 +457,11 @@ codegen(codegen_state *state, pic_value obj, bool tailpos) pic_error(pic, "syntax error"); } - pidx = pic->plen++; - if (pidx >= pic->pcapa) { + pidx = scope->plen++; + if (pidx >= scope->pcapa) { pic_abort(pic, "constant pool overflow"); } - pic->pool[pidx] = pic_car(pic, pic_cdr(pic, obj)); + scope->pool[pidx] = pic_car(pic, pic_cdr(pic, obj)); scope->code[scope->clen].insn = OP_PUSHCONST; scope->code[scope->clen].u.i = pidx; scope->clen++; @@ -682,11 +693,11 @@ codegen(codegen_state *state, pic_value obj, bool tailpos) case PIC_TT_VECTOR: case PIC_TT_BLOB: { int pidx; - pidx = pic->plen++; - if (pidx >= pic->pcapa) { + pidx = scope->plen++; + if (pidx >= scope->pcapa) { pic_abort(pic, "constant pool overflow"); } - pic->pool[pidx] = obj; + scope->pool[pidx] = obj; scope->code[scope->clen].insn = OP_PUSHCONST; scope->code[scope->clen].u.i = pidx; scope->clen++; @@ -855,6 +866,8 @@ codegen_lambda(codegen_state *state, pic_value obj) irep->clen = state->scope->clen; irep->irep = pic_realloc(pic, state->scope->irep, sizeof(struct pic_irep *) * state->scope->ilen); irep->ilen = state->scope->ilen; + irep->pool = pic_realloc(pic, state->scope->pool, sizeof(pic_value) * state->scope->plen); + irep->plen = state->scope->plen; /* fixup local references */ for (i = 0; i < irep->clen; ++i) { @@ -947,6 +960,8 @@ pic_codegen(pic_state *pic, pic_value obj) irep->clen = state->scope->clen; irep->irep = pic_realloc(pic, state->scope->irep, sizeof(struct pic_irep *) * state->scope->ilen); irep->ilen = state->scope->ilen; + irep->pool = pic_realloc(pic, state->scope->pool, sizeof(pic_value) * state->scope->plen); + irep->plen = state->scope->plen; irep->cv_num = 0; irep->cv_tbl = NULL; @@ -1046,9 +1061,7 @@ print_code(pic_state *pic, struct pic_code c) printf("OP_PUSHCHAR\t%c\n", c.u.c); break; case OP_PUSHCONST: - printf("OP_PUSHCONST\t"); - pic_debug(pic, pic->pool[c.u.i]); - puts(""); + printf("OP_PUSHCONST\t%d\n", c.u.i); break; case OP_GREF: printf("OP_GREF\t%i\n", c.u.i); diff --git a/src/gc.c b/src/gc.c index 73252a15..fc4937de 100644 --- a/src/gc.c +++ b/src/gc.c @@ -438,6 +438,9 @@ gc_mark_object(pic_state *pic, struct pic_object *obj) for (i = 0; i < irep->ilen; ++i) { gc_mark_object(pic, (struct pic_object *)irep->irep[i]); } + for (i = 0; i < irep->plen; ++i) { + gc_mark(pic, irep->pool[i]); + } break; } case PIC_TT_NIL: @@ -501,11 +504,6 @@ gc_mark_phase(pic_state *pic) gc_mark(pic, pic->globals[i]); } - /* pool */ - for (i = 0; i < pic->plen; ++i) { - gc_mark(pic, pic->pool[i]); - } - /* library table */ gc_mark(pic, pic->lib_tbl); } @@ -584,6 +582,7 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj) pic_free(pic, irep->code); pic_free(pic, irep->cv_tbl); pic_free(pic, irep->irep); + pic_free(pic, irep->pool); break; } case PIC_TT_NIL: diff --git a/src/state.c b/src/state.c index 6a0182c1..a7b987e8 100644 --- a/src/state.c +++ b/src/state.c @@ -69,11 +69,6 @@ pic_open(int argc, char *argv[], char **envp) pic->lib_tbl = pic_nil_value(); pic->lib = NULL; - /* pool */ - pic->pool = (pic_value *)calloc(PIC_POOL_SIZE, sizeof(pic_value)); - pic->plen = 0; - pic->pcapa = PIC_POOL_SIZE; - /* error handling */ pic->jmp = NULL; pic->errmsg = NULL; @@ -124,11 +119,9 @@ pic_close(pic_state *pic) free(pic->cibase); free(pic->rescue); free(pic->globals); - free(pic->pool); pic->glen = 0; pic->rlen = 0; - pic->plen = 0; pic->arena_idx = 0; pic->lib_tbl = pic_undef_value(); diff --git a/src/vm.c b/src/vm.c index e90e4948..74b134d6 100644 --- a/src/vm.c +++ b/src/vm.c @@ -472,7 +472,18 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value argv) NEXT; } CASE(OP_PUSHCONST) { - PUSH(pic->pool[c.u.i]); + pic_value self; + struct pic_irep *irep; + + self = pic->ci->fp[0]; + if (! pic_proc_p(self)) { + pic_error(pic, "logic flaw"); + } + irep = pic_proc_ptr(self)->u.irep; + if (pic_proc_cfunc_p(self)) { + pic_error(pic, "logic flaw"); + } + PUSH(irep->pool[c.u.i]); NEXT; } CASE(OP_GREF) {