diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/hash.c | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/src/hash.c b/src/hash.c index 6d176e80c..4a85fcec3 100644 --- a/src/hash.c +++ b/src/hash.c @@ -60,6 +60,7 @@ mrb_gc_mark_ht(mrb_state *mrb, struct RHash *hash) khiter_t k; khash_t(ht) *h = hash->ht; + if (!h) return; for (k = kh_begin(h); k != kh_end(h); k++) if (kh_exist(h, k)) { mrb_gc_mark_value(mrb, kh_key(h, k)); @@ -70,13 +71,14 @@ mrb_gc_mark_ht(mrb_state *mrb, struct RHash *hash) size_t mrb_gc_mark_ht_size(mrb_state *mrb, struct RHash *hash) { + if (!hash->ht) return 0; return kh_size(hash->ht)*2; } void mrb_gc_free_ht(mrb_state *mrb, struct RHash *hash) { - kh_destroy(ht, hash->ht); + if (hash->ht) kh_destroy(ht, hash->ht); } @@ -106,9 +108,11 @@ mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key) khash_t(ht) *h = RHASH_TBL(hash); khiter_t k; - k = kh_get(ht, h, key); - if (k != kh_end(h)) - return kh_value(h, k); + if (h) { + k = kh_get(ht, h, key); + if (k != kh_end(h)) + return kh_value(h, k); + } /* not found */ if (MRB_RHASH_PROCDEFAULT_P(hash)) { @@ -142,6 +146,7 @@ mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val) /* mr mrb_hash_modify(mrb, hash); h = RHASH_TBL(hash); + if (!h) h = RHASH_TBL(hash) = kh_init(ht, mrb); k = kh_get(ht, h, key); if (k == kh_end(h)) { /* expand */ @@ -167,11 +172,11 @@ mrb_hash_dup(mrb_state *mrb, mrb_value hash) khash_t(ht) *h, *ret_h; khiter_t k, ret_k; + h = RHASH_TBL(hash); ret = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class); ret->ht = kh_init(ht, mrb); - if (!RHASH_EMPTY_P(hash)) { - h = RHASH_TBL(hash); + if (kh_size(h) > 0) { ret_h = ret->ht; for (k = kh_begin(h); k != kh_end(h); k++) { @@ -196,7 +201,7 @@ mrb_hash_tbl(mrb_state *mrb, mrb_value hash) { khash_t(ht) *h = RHASH_TBL(hash); - if (!RHASH_TBL(hash)) { + if (!h) { RHASH_TBL(hash) = kh_init(ht, mrb); } return h; @@ -696,7 +701,7 @@ mrb_hash_clear(mrb_state *mrb, mrb_value hash) { khash_t(ht) *h = RHASH_TBL(hash); - kh_clear(ht, h); + if (h) kh_clear(ht, h); return hash; } @@ -813,13 +818,12 @@ static mrb_value mrb_hash_empty_p(mrb_state *mrb, mrb_value self) { khash_t(ht) *h = RHASH_TBL(self); - khiter_t k; + if (h) { - for (k = kh_begin(h); k != kh_end(h); k++) - if (kh_exist(h, k)) - return mrb_false_value(); + if (kh_size(h) == 0) + return mrb_true_value(); } - return mrb_true_value(); + return mrb_false_value(); } /* 15.2.13.4.11 */ @@ -934,8 +938,10 @@ inspect_hash(mrb_state *mrb, mrb_value hash, int recur) static mrb_value mrb_hash_inspect(mrb_state *mrb, mrb_value hash) { - if (RHASH_EMPTY_P(hash)) - return mrb_str_new_cstr(mrb, "{}"); + khash_t(ht) *h = RHASH_TBL(hash); + + if (!h || kh_size(h) == 0) + return mrb_str_new_cstr(mrb, "{}"); return inspect_hash(mrb, hash, 0); } @@ -1102,6 +1108,8 @@ mrb_hash_has_value(mrb_state *mrb, mrb_value hash) static mrb_value hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, int eql) { + khash_t(ht) *h1, *h2; + if (mrb_obj_equal(mrb, hash1, hash2)) return mrb_true_value(); if (mrb_type(hash2) != MRB_TT_HASH) { if (!mrb_respond_to(mrb, hash2, mrb_intern(mrb, "to_hash"))) { @@ -1112,10 +1120,15 @@ hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, int eql) else return mrb_fixnum_value(mrb_equal(mrb, hash2, hash1)); } - if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2)) return mrb_false_value(); + h1 = RHASH_TBL(hash1); + h2 = RHASH_TBL(hash2); + if (!h2) { + if (!h2) return mrb_true_value(); + return mrb_false_value(); + } + if (!h2) return mrb_false_value(); + if (kh_size(h1) != kh_size(h2)) return mrb_false_value(); else { - khash_t(ht) *h1 = RHASH_TBL(hash1); - khash_t(ht) *h2 = RHASH_TBL(hash2); khiter_t k1, k2; mrb_value key; |
