use khash for pic->syms
This commit is contained in:
		
							parent
							
								
									03a649ed23
								
							
						
					
					
						commit
						0fb87449fc
					
				| 
						 | 
				
			
			@ -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);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue