diff --git a/include/mruby/internal.h b/include/mruby/internal.h index 779f258df..8b04166e4 100644 --- a/include/mruby/internal.h +++ b/include/mruby/internal.h @@ -188,6 +188,7 @@ mrb_int mrb_bint_cmp(mrb_state *mrb, mrb_value x, mrb_value y); void mrb_gc_free_bint(mrb_state *mrb, struct RBasic *x); void mrb_bint_copy(mrb_state *mrb, mrb_value x, mrb_value y); size_t mrb_bint_memsize(mrb_value x); +mrb_value mrb_bint_hash(mrb_state *mrb, mrb_value x); #endif #endif /* MRUBY_INTERNAL_H */ diff --git a/mrbgems/mruby-bigint/core/bigint.c b/mrbgems/mruby-bigint/core/bigint.c index 750940c7c..d5ff04aa5 100644 --- a/mrbgems/mruby-bigint/core/bigint.c +++ b/mrbgems/mruby-bigint/core/bigint.c @@ -1538,3 +1538,12 @@ mrb_bint_memsize(mrb_value x) struct RBigint *b = RBIGINT(x); return b->mp.sz * sizeof(mp_limb); } + +mrb_value +mrb_bint_hash(mrb_state *mrb, mrb_value x) +{ + struct RBigint *b = RBIGINT(x); + uint32_t hash = mrb_byte_hash((uint8_t*)b->mp.p, b->mp.sz); + hash = mrb_byte_hash_step((uint8_t*)&b->mp.sn, sizeof(b->mp.sn), hash); + return mrb_int_value(mrb, hash); +} diff --git a/src/kernel.c b/src/kernel.c index 54c08bdac..45a6b69d4 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -249,6 +249,11 @@ mrb_obj_frozen(mrb_state *mrb, mrb_value self) static mrb_value mrb_obj_hash(mrb_state *mrb, mrb_value self) { +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(self)) { + return mrb_bint_hash(mrb, self); + } +#endif return mrb_int_value(mrb, mrb_obj_id(self)); }