diff --git a/include/picrin.h b/include/picrin.h index 6f0184a8..3ddea47e 100644 --- a/include/picrin.h +++ b/include/picrin.h @@ -88,10 +88,7 @@ typedef struct { int sym_cnt; int uniq_sym_cnt; - xhash global_tbl; - pic_value *globals; - size_t glen, gcapa; - + xhash globals; xhash macros; pic_value lib_tbl; diff --git a/include/picrin/config.h b/include/picrin/config.h index 2acfe0ea..79b8fc3c 100644 --- a/include/picrin/config.h +++ b/include/picrin/config.h @@ -26,8 +26,6 @@ /* #define PIC_RESCUE_SIZE 30 */ -/* #define PIC_GLOBALS_SIZE 1024 */ - /* #define PIC_SYM_POOL_SIZE 128 */ /* #define PIC_IREP_SIZE 8 */ @@ -93,10 +91,6 @@ # define PIC_RESCUE_SIZE 30 #endif -#ifndef PIC_GLOBALS_SIZE -# define PIC_GLOBALS_SIZE 1024 -#endif - #ifndef PIC_SYM_POOL_SIZE # define PIC_SYM_POOL_SIZE 128 #endif diff --git a/src/codegen.c b/src/codegen.c index 1dc7e898..1c0c2c21 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -100,7 +100,7 @@ new_analyze_state(pic_state *pic) /* push initial scope */ push_scope(state, pic_nil_value()); - xh_begin(&it, &pic->global_tbl); + xh_begin(&it, &pic->globals); while (xh_next(&it)) { pic_sym sym = xh_key(it.e, pic_sym); xv_push(&state->scope->locals, &sym); @@ -291,20 +291,8 @@ static pic_value analyze_global_var(analyze_state *state, pic_sym sym) { pic_state *pic = state->pic; - xh_entry *e; - size_t i; - if ((e = xh_get_int(&pic->global_tbl, sym))) { - i = xh_val(e, size_t); - } - else { - i = pic->glen++; - if (i >= pic->gcapa) { - pic_error(pic, "global table overflow"); - } - xh_put_int(&pic->global_tbl, sym, &i); - } - return pic_list2(pic, pic_symbol_value(state->sGREF), pic_int_value(i)); + return pic_list2(pic, pic_symbol_value(state->sGREF), pic_sym_value(sym)); } static pic_value @@ -1096,7 +1084,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_int(pic_list_ref(pic, obj, 1)); + cxt->code[cxt->clen].u.i = pic_sym(pic_list_ref(pic, obj, 1)); cxt->clen++; return; } else if (sym == state->sCREF) { diff --git a/src/gc.c b/src/gc.c index bd907524..465704dd 100644 --- a/src/gc.c +++ b/src/gc.c @@ -575,8 +575,9 @@ gc_mark_phase(pic_state *pic) } /* global variables */ - for (i = 0; i < pic->glen; ++i) { - gc_mark(pic, pic->globals[i]); + xh_begin(&it, &pic->globals); + while (xh_next(&it)) { + gc_mark(pic, xh_val(it.e, pic_value)); } /* macro objects */ diff --git a/src/state.c b/src/state.c index 518d2ea4..d203f6a2 100644 --- a/src/state.c +++ b/src/state.c @@ -49,10 +49,7 @@ pic_open(int argc, char *argv[], char **envp) pic->uniq_sym_cnt = 0; /* global variables */ - xh_init_int(&pic->global_tbl, sizeof(size_t)); - pic->globals = (pic_value *)calloc(PIC_GLOBALS_SIZE, sizeof(pic_value)); - pic->glen = 0; - pic->gcapa = PIC_GLOBALS_SIZE; + xh_init_int(&pic->globals, sizeof(pic_value)); /* macros */ xh_init_int(&pic->macros, sizeof(struct pic_macro *)); @@ -164,7 +161,6 @@ pic_close(pic_state *pic) pic->ci = pic->cibase; pic->arena_idx = 0; pic->err = NULL; - pic->glen = 0; xh_clear(&pic->macros); pic->lib_tbl = pic_nil_value(); @@ -179,10 +175,9 @@ pic_close(pic_state *pic) free(pic->cibase); /* free global stacks */ - free(pic->globals); free(pic->try_jmps); xh_destroy(&pic->syms); - xh_destroy(&pic->global_tbl); + xh_destroy(&pic->globals); xh_destroy(&pic->macros); xh_destroy(&pic->rlabels); diff --git a/src/vm.c b/src/vm.c index 779ed138..1bf62fbe 100644 --- a/src/vm.c +++ b/src/vm.c @@ -387,79 +387,38 @@ pic_get_args(pic_state *pic, const char *format, ...) return i - 1; } -static size_t -global_ref(pic_state *pic, const char *name) -{ - xh_entry *e; - pic_sym sym, rename; - - sym = pic_intern_cstr(pic, name); - if (! pic_find_rename(pic, pic->lib->env, sym, &rename)) { - return SIZE_MAX; - } - if (! (e = xh_get_int(&pic->global_tbl, rename))) { - return SIZE_MAX; - } - return xh_val(e, size_t); -} - -static size_t -global_def(pic_state *pic, const char *name) -{ - pic_sym sym, rename; - size_t gidx; - - sym = pic_intern_cstr(pic, name); - if ((gidx = global_ref(pic, name)) != SIZE_MAX) { - pic_warn(pic, "redefining global"); - return gidx; - } - - /* register to the senv */ - rename = pic_add_rename(pic, pic->lib->env, sym); - - /* register to the global table */ - gidx = pic->glen++; - if (pic->glen >= pic->gcapa) { - pic_error(pic, "global table overflow"); - } - xh_put_int(&pic->global_tbl, rename, &gidx); - - return gidx; -} - void pic_define(pic_state *pic, const char *name, pic_value val) { + pic_sym sym, rename; + + sym = pic_intern_cstr(pic, name); + + if (! pic_find_rename(pic, pic->lib->env, sym, &rename)) { + rename = pic_add_rename(pic, pic->lib->env, sym); + } else { + pic_warn(pic, "redefining global"); + } + /* push to the global arena */ - pic->globals[global_def(pic, name)] = val; + xh_put_int(&pic->globals, rename, &val); /* export! */ - pic_export(pic, pic_intern_cstr(pic, name)); + pic_export(pic, sym); } pic_value pic_ref(pic_state *pic, const char *name) { - size_t gid; + pic_sym sym, rename; - gid = global_ref(pic, name); - if (gid == SIZE_MAX) { + sym = pic_intern_cstr(pic, name); + + if (! pic_find_rename(pic, pic->lib->env, sym, &rename)) { pic_errorf(pic, "symbol \"%s\" not defined", name); } - return pic->globals[gid]; -} -void -pic_set(pic_state *pic, const char *name, pic_value value) -{ - size_t gid; - - gid = global_ref(pic, name); - if (gid == SIZE_MAX) { - pic_error(pic, "symbol not defined"); - } - pic->globals[gid] = value; + return xh_val(xh_get_int(&pic->globals, rename), pic_value); } pic_value @@ -675,11 +634,19 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value argv) NEXT; } CASE(OP_GREF) { - PUSH(pic->globals[c.u.i]); + xh_entry *e; + + if ((e = xh_get_int(&pic->globals, c.u.i)) == NULL) { + pic_errorf(pic, "logic flaw; reference to uninitialized global variable: ~s", pic_symbol_name(pic, c.u.i)); + } + PUSH(xh_val(e, pic_value)); NEXT; } CASE(OP_GSET) { - pic->globals[c.u.i] = POP(); + pic_value val; + + val = POP(); + xh_put_int(&pic->globals, c.u.i, &val); NEXT; } CASE(OP_LREF) {