diff --git a/vm/src/obj/objint.rs b/vm/src/obj/objint.rs index 403fd08ef..9c1ccf921 100644 --- a/vm/src/obj/objint.rs +++ b/vm/src/obj/objint.rs @@ -1,5 +1,4 @@ use std::fmt; -use std::hash::{Hash, Hasher}; use num_bigint::{BigInt, Sign}; use num_integer::Integer; @@ -7,6 +6,7 @@ use num_traits::{One, Pow, Signed, ToPrimitive, Zero}; use crate::format::FormatSpec; use crate::function::{KwArgs, OptionalArg, PyFuncArgs}; +use crate::pyhash; use crate::pyobject::{ IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol, @@ -400,10 +400,11 @@ impl PyInt { } #[pymethod(name = "__hash__")] - fn hash(&self, _vm: &VirtualMachine) -> u64 { - let mut hasher = std::collections::hash_map::DefaultHasher::new(); - self.value.hash(&mut hasher); - hasher.finish() + pub fn hash(&self, _vm: &VirtualMachine) -> pyhash::PyHash { + match self.value.to_i64() { + Some(value) => (value % pyhash::MODULUS as i64), + None => (&self.value % pyhash::MODULUS).to_i64().unwrap(), + } } #[pymethod(name = "__abs__")] diff --git a/vm/src/vm.rs b/vm/src/vm.rs index eab6fca8c..6cd1165db 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -23,13 +23,14 @@ use crate::obj::objcode::PyCodeRef; use crate::obj::objdict::PyDictRef; use crate::obj::objfunction::{PyFunction, PyMethod}; use crate::obj::objgenerator::PyGenerator; -use crate::obj::objint; +use crate::obj::objint::PyInt; use crate::obj::objiter; use crate::obj::objsequence; use crate::obj::objstr::{PyString, PyStringRef}; use crate::obj::objtuple::PyTupleRef; use crate::obj::objtype; use crate::obj::objtype::PyClassRef; +use crate::pyhash; use crate::pyobject::{ IdProtocol, ItemProtocol, PyContext, PyObjectRef, PyResult, PyValue, TryFromObject, TryIntoRef, TypeProtocol, @@ -37,7 +38,6 @@ use crate::pyobject::{ use crate::stdlib; use crate::sysmodule; use num_bigint::BigInt; -use num_traits::ToPrimitive; // use objects::objects; @@ -914,14 +914,10 @@ impl VirtualMachine { }) } - pub fn _hash(&self, obj: &PyObjectRef) -> PyResult { - const PRIME: usize = 0x1fff_ffff_ffff_ffff; + pub fn _hash(&self, obj: &PyObjectRef) -> PyResult { let hash_obj = self.call_method(obj, "__hash__", vec![])?; if objtype::isinstance(&hash_obj, &self.ctx.int_type()) { - let hash_int = objint::get_value(&hash_obj); - Ok(hash_int - .to_usize() - .unwrap_or_else(|| (hash_int % PRIME).to_usize().unwrap())) + Ok(hash_obj.payload::().unwrap().hash(self)) } else { Err(self.new_type_error("__hash__ method should return an integer".to_string())) }