embed constant pool into irep object

This commit is contained in:
Yuichi Nishiwaki 2014-01-18 22:32:41 +09:00
parent a0f27a68cd
commit 494989ff3e
6 changed files with 41 additions and 27 deletions

View File

@ -87,9 +87,6 @@ typedef struct {
pic_value lib_tbl; pic_value lib_tbl;
struct pic_lib *lib; struct pic_lib *lib;
pic_value *pool;
size_t plen, pcapa;
jmp_buf *jmp; jmp_buf *jmp;
const char *errmsg; const char *errmsg;

View File

@ -65,7 +65,8 @@ struct pic_irep {
unsigned *cv_tbl, cv_num; unsigned *cv_tbl, cv_num;
bool varg; bool varg;
struct pic_irep **irep; 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 *); void pic_dump_irep(pic_state *, struct pic_irep *);

View File

@ -33,6 +33,7 @@ new_irep(pic_state *pic)
irep->localc = -1; irep->localc = -1;
irep->varg = false; irep->varg = false;
irep->irep = NULL; irep->irep = NULL;
irep->pool = NULL;
return irep; return irep;
} }
@ -44,7 +45,7 @@ typedef struct codegen_scope {
bool varg; bool varg;
/* local variables are 1-indexed, 0 is reserved for the callee */ /* local variables are 1-indexed, 0 is reserved for the callee */
struct xhash *local_tbl; struct xhash *local_tbl;
/* rest args variable is counted at localc */ /* rest args variable is counted by localc */
size_t argc, localc; size_t argc, localc;
/* if local var i is captured, then dirty_flags[i] == 1 */ /* if local var i is captured, then dirty_flags[i] == 1 */
int *dirty_flags; int *dirty_flags;
@ -54,6 +55,9 @@ typedef struct codegen_scope {
/* child ireps */ /* child ireps */
struct pic_irep **irep; struct pic_irep **irep;
size_t ilen, icapa; size_t ilen, icapa;
/* constant object pool */
pic_value *pool;
size_t plen, pcapa;
struct codegen_scope *up; struct codegen_scope *up;
} codegen_scope; } 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->irep = (struct pic_irep **)pic_calloc(pic, PIC_IREP_SIZE, sizeof(struct pic_irep *));
scope->ilen = 0; scope->ilen = 0;
scope->icapa = PIC_IREP_SIZE; 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; return scope;
} }
@ -122,6 +129,10 @@ new_local_scope(pic_state *pic, pic_value args, codegen_scope *scope)
new_scope->ilen = 0; new_scope->ilen = 0;
new_scope->icapa = PIC_IREP_SIZE; 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; return new_scope;
} }
@ -446,11 +457,11 @@ codegen(codegen_state *state, pic_value obj, bool tailpos)
pic_error(pic, "syntax error"); pic_error(pic, "syntax error");
} }
pidx = pic->plen++; pidx = scope->plen++;
if (pidx >= pic->pcapa) { if (pidx >= scope->pcapa) {
pic_abort(pic, "constant pool overflow"); 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].insn = OP_PUSHCONST;
scope->code[scope->clen].u.i = pidx; scope->code[scope->clen].u.i = pidx;
scope->clen++; scope->clen++;
@ -682,11 +693,11 @@ codegen(codegen_state *state, pic_value obj, bool tailpos)
case PIC_TT_VECTOR: case PIC_TT_VECTOR:
case PIC_TT_BLOB: { case PIC_TT_BLOB: {
int pidx; int pidx;
pidx = pic->plen++; pidx = scope->plen++;
if (pidx >= pic->pcapa) { if (pidx >= scope->pcapa) {
pic_abort(pic, "constant pool overflow"); 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].insn = OP_PUSHCONST;
scope->code[scope->clen].u.i = pidx; scope->code[scope->clen].u.i = pidx;
scope->clen++; scope->clen++;
@ -855,6 +866,8 @@ codegen_lambda(codegen_state *state, pic_value obj)
irep->clen = state->scope->clen; irep->clen = state->scope->clen;
irep->irep = pic_realloc(pic, state->scope->irep, sizeof(struct pic_irep *) * state->scope->ilen); irep->irep = pic_realloc(pic, state->scope->irep, sizeof(struct pic_irep *) * state->scope->ilen);
irep->ilen = 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 */ /* fixup local references */
for (i = 0; i < irep->clen; ++i) { 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->clen = state->scope->clen;
irep->irep = pic_realloc(pic, state->scope->irep, sizeof(struct pic_irep *) * state->scope->ilen); irep->irep = pic_realloc(pic, state->scope->irep, sizeof(struct pic_irep *) * state->scope->ilen);
irep->ilen = 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_num = 0;
irep->cv_tbl = NULL; 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); printf("OP_PUSHCHAR\t%c\n", c.u.c);
break; break;
case OP_PUSHCONST: case OP_PUSHCONST:
printf("OP_PUSHCONST\t"); printf("OP_PUSHCONST\t%d\n", c.u.i);
pic_debug(pic, pic->pool[c.u.i]);
puts("");
break; break;
case OP_GREF: case OP_GREF:
printf("OP_GREF\t%i\n", c.u.i); printf("OP_GREF\t%i\n", c.u.i);

View File

@ -438,6 +438,9 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
for (i = 0; i < irep->ilen; ++i) { for (i = 0; i < irep->ilen; ++i) {
gc_mark_object(pic, (struct pic_object *)irep->irep[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; break;
} }
case PIC_TT_NIL: case PIC_TT_NIL:
@ -501,11 +504,6 @@ gc_mark_phase(pic_state *pic)
gc_mark(pic, pic->globals[i]); gc_mark(pic, pic->globals[i]);
} }
/* pool */
for (i = 0; i < pic->plen; ++i) {
gc_mark(pic, pic->pool[i]);
}
/* library table */ /* library table */
gc_mark(pic, pic->lib_tbl); 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->code);
pic_free(pic, irep->cv_tbl); pic_free(pic, irep->cv_tbl);
pic_free(pic, irep->irep); pic_free(pic, irep->irep);
pic_free(pic, irep->pool);
break; break;
} }
case PIC_TT_NIL: case PIC_TT_NIL:

View File

@ -69,11 +69,6 @@ pic_open(int argc, char *argv[], char **envp)
pic->lib_tbl = pic_nil_value(); pic->lib_tbl = pic_nil_value();
pic->lib = NULL; 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 */ /* error handling */
pic->jmp = NULL; pic->jmp = NULL;
pic->errmsg = NULL; pic->errmsg = NULL;
@ -124,11 +119,9 @@ pic_close(pic_state *pic)
free(pic->cibase); free(pic->cibase);
free(pic->rescue); free(pic->rescue);
free(pic->globals); free(pic->globals);
free(pic->pool);
pic->glen = 0; pic->glen = 0;
pic->rlen = 0; pic->rlen = 0;
pic->plen = 0;
pic->arena_idx = 0; pic->arena_idx = 0;
pic->lib_tbl = pic_undef_value(); pic->lib_tbl = pic_undef_value();

View File

@ -472,7 +472,18 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value argv)
NEXT; NEXT;
} }
CASE(OP_PUSHCONST) { 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; NEXT;
} }
CASE(OP_GREF) { CASE(OP_GREF) {