Skip to content

Commit 3fbdfb3

Browse files
Merge pull request #460 from theseus-rs/fix-object-hashcode
fix: correct java/lang/Object.hashCode()I
2 parents 3bd7598 + 4c7bbcf commit 3fbdfb3

File tree

7 files changed

+248
-176
lines changed

7 files changed

+248
-176
lines changed

Cargo.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ristretto_classloader/src/concurrent_vec.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,12 @@ impl<T: Clone + Debug + PartialEq> ConcurrentVec<T> {
177177
Ok(vec.clone())
178178
}
179179

180+
/// Returns hash code implementation based on memory address.
181+
#[must_use]
182+
pub fn hash_code(&self) -> usize {
183+
Arc::as_ptr(&self.inner).cast::<Vec<RwLock<T>>>() as usize
184+
}
185+
180186
/// Check if two concurrent vectors point to the same memory location.
181187
#[must_use]
182188
pub fn ptr_eq(&self, other: &Self) -> bool {
@@ -386,6 +392,14 @@ mod tests {
386392
Ok(())
387393
}
388394

395+
#[test]
396+
fn test_hash_code() {
397+
let vec1 = ConcurrentVec::from(vec![1]);
398+
let vec2 = ConcurrentVec::from(vec![1]);
399+
assert_ne!(0, vec1.hash_code());
400+
assert_ne!(vec1.hash_code(), vec2.hash_code());
401+
}
402+
389403
#[test]
390404
fn test_ptr_eq() -> Result<()> {
391405
let vec1 = ConcurrentVec::new();

ristretto_classloader/src/object.rs

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,12 @@ impl Object {
313313
true
314314
}
315315

316+
/// Returns hash code implementation based on memory address.
317+
#[must_use]
318+
pub fn hash_code(&self) -> usize {
319+
Arc::as_ptr(&self.values).cast::<Vec<Value>>() as usize
320+
}
321+
316322
/// Check if two references point to the same memory location.
317323
#[must_use]
318324
pub fn ptr_eq(&self, other: &Self) -> bool {
@@ -665,17 +671,15 @@ mod tests {
665671

666672
#[tokio::test]
667673
async fn test_instance_of() -> Result<()> {
668-
let class_name = "java.lang.Object";
669-
let class = load_class(class_name).await?;
674+
let class = load_class("java.lang.Object").await?;
670675
let object = Object::new(class.clone())?;
671676
assert!(object.instance_of(&class)?);
672677
Ok(())
673678
}
674679

675680
#[tokio::test]
676681
async fn test_clone() -> Result<()> {
677-
let class_name = "java.lang.Integer";
678-
let class = load_class(class_name).await?;
682+
let class = load_class("java.lang.Integer").await?;
679683
let object = Object::new(class)?;
680684
object.set_value("value", Value::Int(1))?;
681685
let clone = object.clone();
@@ -687,17 +691,20 @@ mod tests {
687691
}
688692

689693
#[tokio::test]
690-
async fn test_object_ptr_eq() -> Result<()> {
691-
let class_name = "java.lang.Object";
692-
let class = load_class(class_name).await?;
693-
let object1 = Object {
694-
class: class.clone(),
695-
values: Arc::new(vec![]),
696-
};
697-
let object2 = Object {
698-
class: class.clone(),
699-
values: Arc::new(vec![]),
700-
};
694+
async fn test_hash_code() -> Result<()> {
695+
let class = load_class("java.lang.Object").await?;
696+
let object1 = Object::new(class.clone())?;
697+
let object2 = Object::new(class)?;
698+
assert_ne!(0, object1.hash_code());
699+
assert_ne!(object1.hash_code(), object2.hash_code());
700+
Ok(())
701+
}
702+
703+
#[tokio::test]
704+
async fn test_ptr_eq() -> Result<()> {
705+
let class = load_class("java.lang.Object").await?;
706+
let object1 = Object::new(class.clone())?;
707+
let object2 = Object::new(class)?;
701708
let object3 = object1.clone();
702709
assert!(object1.ptr_eq(&object1));
703710
assert!(!object1.ptr_eq(&object2));
@@ -707,8 +714,7 @@ mod tests {
707714

708715
#[tokio::test]
709716
async fn test_deep_clone() -> Result<()> {
710-
let class_name = "java.lang.Integer";
711-
let class = load_class(class_name).await?;
717+
let class = load_class("java.lang.Integer").await?;
712718
let object = Object::new(class)?;
713719
object.set_value("value", Value::Int(1))?;
714720
let clone = object.deep_clone()?;
@@ -721,8 +727,7 @@ mod tests {
721727

722728
#[tokio::test]
723729
async fn test_debug() -> Result<()> {
724-
let class_name = "java.lang.Integer";
725-
let class = load_class(class_name).await?;
730+
let class = load_class("java.lang.Integer").await?;
726731
let object = Object::new(class)?;
727732
object.set_value("value", Value::Int(42))?;
728733
assert_eq!(
@@ -734,8 +739,7 @@ mod tests {
734739

735740
#[tokio::test]
736741
async fn test_eq_same_references() -> Result<()> {
737-
let class_name = "java.lang.Integer";
738-
let class = load_class(class_name).await?;
742+
let class = load_class("java.lang.Integer").await?;
739743
let object = Object::new(class)?;
740744
object.set_value("value", Value::Int(42))?;
741745
assert_eq!(object, object);
@@ -744,8 +748,7 @@ mod tests {
744748

745749
#[tokio::test]
746750
async fn test_eq_different_references() -> Result<()> {
747-
let class_name = "java.lang.Integer";
748-
let class = load_class(class_name).await?;
751+
let class = load_class("java.lang.Integer").await?;
749752
let object1 = Object::new(class.clone())?;
750753
object1.set_value("value", Value::Int(42))?;
751754
let object2 = Object::new(class)?;
@@ -756,8 +759,7 @@ mod tests {
756759

757760
#[tokio::test]
758761
async fn test_eq_not_equal() -> Result<()> {
759-
let class_name = "java.lang.Integer";
760-
let class = load_class(class_name).await?;
762+
let class = load_class("java.lang.Integer").await?;
761763
let object1 = Object::new(class.clone())?;
762764
object1.set_value("value", Value::Int(3))?;
763765
let object2 = Object::new(class)?;
@@ -864,8 +866,7 @@ mod tests {
864866
let string_value = Value::from(string_bytes);
865867
string_object.set_value("value", string_value)?;
866868

867-
let class_name = "java.lang.Class";
868-
let class = load_class(class_name).await?;
869+
let class = load_class("java.lang.Class").await?;
869870
let object = Object::new(class)?;
870871
object.set_value("name", Value::from(string_object))?;
871872
assert_eq!("Class(java.lang.Integer)", object.to_string());
@@ -874,8 +875,7 @@ mod tests {
874875

875876
#[tokio::test]
876877
async fn test_to_string() -> Result<()> {
877-
let class_name = "java.lang.Object";
878-
let class = load_class(class_name).await?;
878+
let class = load_class("java.lang.Object").await?;
879879
let object = Object::new(class)?;
880880
assert_eq!("Object(class java/lang/Object)", object.to_string());
881881
Ok(())
@@ -1115,8 +1115,7 @@ mod tests {
11151115

11161116
#[tokio::test]
11171117
async fn test_try_into_class() -> Result<()> {
1118-
let class_name = "java.lang.Integer";
1119-
let class = load_class(class_name).await?;
1118+
let class = load_class("java.lang.Integer").await?;
11201119
let object = Object::new(class)?;
11211120
object.set_value("value", Value::Int(42))?;
11221121
let value: Arc<Class> = object.try_into()?;

0 commit comments

Comments
 (0)