use khash for pic->syms

This commit is contained in:
Yuichi Nishiwaki 2015-06-25 07:05:41 +09:00
parent 03a649ed23
commit 0fb87449fc
4 changed files with 36 additions and 22 deletions

View File

@ -741,16 +741,19 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
static void
gc_sweep_symbols(pic_state *pic)
{
xh_entry *it;
char *cstr;
khash_t(s) *h = &pic->syms;
khiter_t it;
pic_sym *sym;
const char *cstr;
for (it = xh_begin(&pic->syms); it != NULL; it = xh_next(it)) {
if (! gc_obj_is_marked((struct pic_object *)xh_val(it, pic_sym *))) {
cstr = xh_key(it, char *);
xh_del_str(&pic->syms, cstr);
pic_free(pic, cstr);
for (it = kh_begin(h); it != kh_end(h); ++it) {
if (! kh_exist(h, it))
continue;
sym = kh_val(h, it);
if (! gc_obj_is_marked((struct pic_object *)sym)) {
cstr = kh_key(h, it);
kh_del(s, h, it);
pic_free(pic, (void *)cstr);
}
}
}

View File

@ -48,6 +48,8 @@ typedef struct pic_state pic_state;
#include "picrin/read.h"
#include "picrin/gc.h"
KHASH_DECLARE(s, const char *, pic_sym *);
typedef struct pic_checkpoint {
PIC_OBJECT_HEADER
struct pic_proc *in;
@ -125,7 +127,7 @@ struct pic_state {
pic_value features;
xhash syms; /* name to symbol */
khash_t(s) syms; /* name to symbol */
int ucnt;
struct pic_dict *globals;
struct pic_dict *macros;

View File

@ -224,7 +224,7 @@ pic_open(int argc, char *argv[], char **envp, pic_allocf allocf)
pic->regs = NULL;
/* symbol table */
xh_init_str(&pic->syms, sizeof(pic_sym *));
kh_init(s, &pic->syms);
/* unique symbol count */
pic->ucnt = 0;
@ -399,13 +399,17 @@ pic_open(int argc, char *argv[], char **envp, pic_allocf allocf)
void
pic_close(pic_state *pic)
{
xh_entry *it;
khash_t(s) *h = &pic->syms;
khiter_t it;
pic_allocf allocf = pic->allocf;
/* free symbol names */
for (it = xh_begin(&pic->syms); it != NULL; it = xh_next(it)) {
allocf(xh_key(it, char *), 0);
/* free all symbols */
for (it = kh_begin(h); it != kh_end(h); ++it) {
if (kh_exist(h, it)) {
allocf((void *)kh_key(h, it), 0);
}
}
kh_clear(s, h);
/* clear out root objects */
pic->sp = pic->stbase;
@ -416,7 +420,6 @@ pic_close(pic_state *pic)
pic->globals = NULL;
pic->macros = NULL;
pic->attrs = NULL;
xh_clear(&pic->syms);
pic->features = pic_nil_value();
pic->libs = pic_nil_value();
@ -438,7 +441,7 @@ pic_close(pic_state *pic)
allocf(pic->xpbase, 0);
/* free global stacks */
xh_destroy(&pic->syms);
kh_destroy(s, h);
/* free GC arena */
allocf(pic->arena, 0);

View File

@ -4,6 +4,8 @@
#include "picrin.h"
KHASH_DEFINE(s, const char *, pic_sym *, kh_str_hash_func, kh_str_hash_equal)
static pic_sym *
pic_make_symbol(pic_state *pic, pic_str *str)
{
@ -17,22 +19,26 @@ pic_make_symbol(pic_state *pic, pic_str *str)
pic_sym *
pic_intern(pic_state *pic, pic_str *str)
{
xh_entry *e;
khash_t(s) *h = &pic->syms;
pic_sym *sym;
char *cstr;
khiter_t it;
int ret;
e = xh_get_str(&pic->syms, pic_str_cstr(pic, str));
if (e) {
sym = xh_val(e, pic_sym *);
it = kh_put(s, h, pic_str_cstr(pic, str), &ret);
if (ret == 0) { /* if exists */
sym = kh_val(h, it);
pic_gc_protect(pic, pic_obj_value(sym));
return sym;
}
cstr = pic_malloc(pic, pic_str_len(str) + 1);
strcpy(cstr, pic_str_cstr(pic, str));
kh_key(h, it) = cstr;
sym = pic_make_symbol(pic, str);
xh_put_str(&pic->syms, cstr, &sym);
kh_val(h, it) = sym;
return sym;
}