diff options
-rw-r--r-- | gc.c | 11 | ||||
-rw-r--r-- | hash.c | 40 | ||||
-rw-r--r-- | lib.c | 12 | ||||
-rw-r--r-- | lib.h | 12 |
4 files changed, 71 insertions, 4 deletions
@@ -244,7 +244,7 @@ val make_obj(void) static void finalize(val obj) { - switch (obj->t.type) { + switch (convert(type_t, obj->t.type)) { case NIL: case CONS: case CHR: @@ -280,6 +280,12 @@ static void finalize(val obj) case BGNUM: mp_clear(mp(obj)); return; + case BUF: + if (obj->b.size) { + free(obj->b.data); + obj->b.data = 0; + } + return; } assert (0 && "corrupt type field"); @@ -395,6 +401,9 @@ tail_call: case RNG: mark_obj(obj->rn.from); mark_obj_tail(obj->rn.to); + case BUF: + mark_obj(obj->b.len); + mark_obj_tail(obj->b.size); } assert (0 && "corrupt type field"); @@ -107,6 +107,44 @@ static unsigned long hash_c_str(const wchar_t *str) return h; } +static unsigned long hash_buf(const mem_t *ptr, cnum size) +{ + int count = hash_str_limit; + unsigned long h = 0; + + for (; size >= 4 && count--; size -= 4, ptr += 4) { + unsigned long el = (((unsigned long) ptr[0]) << 24 | + ((unsigned long) ptr[1]) << 16 | + ((unsigned long) ptr[2]) << 8 | + ((unsigned long) ptr[3])); + unsigned long g; + h = (h << 4) + el; + g = h & 0x7C000000; + h = h ^ (g >> 26) ^ g; + ptr += 4; + } + + if (count) { + unsigned long el = 0; + unsigned long g; + switch (size) { + case 0: + break; + case 3: + el = *ptr++; + case 2: + el = el << 8 | *ptr++; + case 1: + el = el << 8 | *ptr++; + h = (h << 4) + el; + g = h & 0x7C000000; + h = h ^ (g >> 26) ^ g; + ptr += 4; + } + } + return h; +} + static cnum hash_double(double n) { #ifdef HAVE_UINTPTR_T @@ -191,6 +229,8 @@ cnum equal_hash(val obj, int *count) case RNG: return (equal_hash(obj->rn.from, count) + 32 * (equal_hash(obj->rn.to, count) & (NUM_MAX / 16))) & NUM_MAX; + case BUF: + return hash_buf(obj->b.data, c_num(obj->b.len)); } internal_error("unhandled case in equal function"); @@ -85,7 +85,7 @@ val package_s, system_package_s, keyword_package_s, user_package_s; val null_s, t, cons_s, str_s, chr_s, fixnum_s, sym_s, pkg_s, fun_s, vec_s; val lit_s, stream_s, hash_s, hash_iter_s, lcons_s, lstr_s, cobj_s, cptr_s; val atom_s, integer_s, number_s, sequence_s, string_s; -val env_s, bignum_s, float_s, range_s, rcons_s; +val env_s, bignum_s, float_s, range_s, rcons_s, buf_s; val var_s, expr_s, regex_s, chset_s, set_s, cset_s, wild_s, oneplus_s; val nongreedy_s; val quote_s, qquote_s, unquote_s, splice_s; @@ -172,6 +172,7 @@ static val code2type(int code) case BGNUM: return bignum_s; case FLNUM: return float_s; case RNG: return range_s; + case BUF: return buf_s; } return nil; } @@ -2495,6 +2496,14 @@ val equal(val left, val right) return nil; } break; + case BUF: + if (type(right) == BUF) { + cnum ll = c_num(left->b.len); + cnum rl = c_num(right->b.len); + if (ll == rl && memcmp(left->b.data, right->b.data, ll) == 0) + return t; + } + break; case COBJ: if (left->co.ops->equalsub) { val lsub = left->co.ops->equalsub(left); @@ -9647,6 +9656,7 @@ static void obj_init(void) float_s = intern(lit("float"), user_package); range_s = intern(lit("range"), user_package); rcons_s = intern(lit("rcons"), user_package); + buf_s = intern(lit("buf"), user_package); var_s = intern(lit("var"), system_package); expr_s = intern(lit("expr"), system_package); regex_s = intern(lit("regex"), user_package); @@ -59,7 +59,7 @@ typedef int_ptr_t cnum; typedef enum type { NIL = TAG_PTR, NUM = TAG_NUM, CHR = TAG_CHR, LIT = TAG_LIT, CONS, STR, SYM, PKG, FUN, VEC, LCONS, LSTR, COBJ, ENV, - BGNUM, FLNUM, RNG, MAXTYPE = RNG + BGNUM, FLNUM, RNG, BUF, MAXTYPE = BUF /* If extending, check TYPE_SHIFT */ } type_t; @@ -279,6 +279,13 @@ struct range { val from, to; }; +struct buf { + obj_common; + mem_t *data; + val len; + val size; +}; + union obj { struct any t; struct cons c; @@ -295,6 +302,7 @@ union obj { struct bignum bn; struct flonum fl; struct range rn; + struct buf b; }; #if CONFIG_GEN_GC @@ -426,7 +434,7 @@ extern val null_s, t, cons_s, str_s, chr_s, fixnum_sl; extern val sym_s, pkg_s, fun_s, vec_s; extern val stream_s, hash_s, hash_iter_s, lcons_s, lstr_s, cobj_s, cptr_s; extern val atom_s, integer_s, number_s, sequence_s, string_s; -extern val env_s, bignum_s, float_s, range_s, rcons_s; +extern val env_s, bignum_s, float_s, range_s, rcons_s, buf_s; extern val var_s, expr_s, regex_s, chset_s, set_s, cset_s, wild_s, oneplus_s; extern val nongreedy_s; extern val quote_s, qquote_s, unquote_s, splice_s; |