diff --git a/ristretto_vm/src/intrinsic_methods/java/lang/class.rs b/ristretto_vm/src/intrinsic_methods/java/lang/class.rs index 5d35b31d..54e52719 100644 --- a/ristretto_vm/src/intrinsic_methods/java/lang/class.rs +++ b/ristretto_vm/src/intrinsic_methods/java/lang/class.rs @@ -1017,10 +1017,17 @@ pub(crate) async fn is_primitive( #[intrinsic_method("java/lang/Class.isRecord0()Z", GreaterThanOrEqual(JAVA_17))] #[async_recursion(?Send)] pub(crate) async fn is_record_0( - _thread: Arc, - _parameters: Parameters, + thread: Arc, + mut parameters: Parameters, ) -> Result> { - todo!("java.lang.Class.isRecord0()Z") + let value = parameters.pop()?; + let class = get_class(&thread, &value).await?; + let Some(parent_class) = class.parent()? else { + return Ok(Some(Value::from(false))); + }; + let parent_class_name = parent_class.name(); + let is_record = parent_class_name == "java/lang/Record"; + Ok(Some(Value::from(is_record))) } #[intrinsic_method("java/lang/Class.registerNatives()V", Any)] @@ -1704,7 +1711,7 @@ mod tests { #[tokio::test] async fn test_is_array() -> Result<()> { let (_vm, thread) = crate::test::thread().await?; - let class: Arc = thread.class("[int").await?; + let class = thread.class("[int").await?; let object = class.to_object(&thread).await?; let parameters = Parameters::new(vec![object]); let result = is_array(thread, parameters).await?; @@ -1715,7 +1722,7 @@ mod tests { #[tokio::test] async fn test_is_array_false() -> Result<()> { let (_vm, thread) = crate::test::thread().await?; - let class: Arc = thread.class("int").await?; + let class = thread.class("int").await?; let object = class.to_object(&thread).await?; let parameters = Parameters::new(vec![object]); let result = is_array(thread, parameters).await?; @@ -1799,7 +1806,7 @@ mod tests { #[tokio::test] async fn test_is_interface() -> Result<()> { let (_vm, thread) = crate::test::thread().await?; - let class: Arc = thread.class("java.lang.Cloneable").await?; + let class = thread.class("java.lang.Cloneable").await?; let object = class.to_object(&thread).await?; let parameters = Parameters::new(vec![object]); let result = is_interface(thread, parameters).await?; @@ -1810,7 +1817,7 @@ mod tests { #[tokio::test] async fn test_is_interface_false() -> Result<()> { let (_vm, thread) = crate::test::thread().await?; - let class: Arc = thread.class("java.lang.Integer").await?; + let class = thread.class("java.lang.Integer").await?; let object = class.to_object(&thread).await?; let parameters = Parameters::new(vec![object]); let result = is_interface(thread, parameters).await?; @@ -1821,7 +1828,7 @@ mod tests { #[tokio::test] async fn test_is_primitive() -> Result<()> { let (_vm, thread) = crate::test::thread().await?; - let class: Arc = thread.class("int").await?; + let class = thread.class("int").await?; let object = class.to_object(&thread).await?; let parameters = Parameters::new(vec![object]); let result = is_primitive(thread, parameters).await?; @@ -1832,7 +1839,7 @@ mod tests { #[tokio::test] async fn test_is_primitive_false() -> Result<()> { let (_vm, thread) = crate::test::thread().await?; - let class: Arc = thread.class("java.lang.Integer").await?; + let class = thread.class("java.lang.Integer").await?; let object = class.to_object(&thread).await?; let parameters = Parameters::new(vec![object]); let result = is_primitive(thread, parameters).await?; @@ -1841,10 +1848,14 @@ mod tests { } #[tokio::test] - #[should_panic(expected = "not yet implemented: java.lang.Class.isRecord0()Z")] - async fn test_is_record_0() { - let (_vm, thread) = crate::test::thread().await.expect("thread"); - let _ = is_record_0(thread, Parameters::default()).await; + async fn test_is_record_0_false() -> Result<()> { + let (_vm, thread) = crate::test::thread().await?; + let class = thread.class("java.lang.Integer").await?; + let object = class.to_object(&thread).await?; + let parameters = Parameters::new(vec![object]); + let result = is_record_0(thread, parameters).await?; + assert_eq!(result, Some(Value::from(false))); + Ok(()) } #[tokio::test] diff --git a/ristretto_vm/src/intrinsic_methods/jdk/internal/misc/unsafe.rs b/ristretto_vm/src/intrinsic_methods/jdk/internal/misc/unsafe.rs index 7e353d75..b4b3c4ce 100644 --- a/ristretto_vm/src/intrinsic_methods/jdk/internal/misc/unsafe.rs +++ b/ristretto_vm/src/intrinsic_methods/jdk/internal/misc/unsafe.rs @@ -7,7 +7,7 @@ use crate::thread::Thread; use async_recursion::async_recursion; use ristretto_classfile::VersionSpecification::{Between, Equal, GreaterThan, GreaterThanOrEqual}; use ristretto_classfile::{BaseType, FieldAccessFlags, JAVA_11, JAVA_17}; -use ristretto_classloader::{Class, Reference, Value}; +use ristretto_classloader::{Reference, Value}; use ristretto_macros::intrinsic_method; use std::sync::Arc; use zerocopy::transmute_ref; @@ -83,7 +83,7 @@ pub(crate) async fn array_index_scale_0( mut parameters: Parameters, ) -> Result> { let object = parameters.pop()?; - let class: Arc = get_class(&thread, &object).await?; + let class = get_class(&thread, &object).await?; let class_name = class.name(); let scale = match class_name { "[Z" => BOOLEAN_SIZE, // boolean diff --git a/tests/record/reflection/ignore.txt b/tests/record/reflection/ignore.txt index 12c4ee40..615d8224 100644 --- a/tests/record/reflection/ignore.txt +++ b/tests/record/reflection/ignore.txt @@ -1 +1 @@ -not yet implemented: java.lang.Class.isRecord0()Z +not yet implemented: java.lang.Class.getRecordComponents0()[Ljava/lang/reflect/RecordComponent; diff --git a/tests/reflection/records/ignore.txt b/tests/reflection/records/ignore.txt index 12c4ee40..615d8224 100644 --- a/tests/reflection/records/ignore.txt +++ b/tests/reflection/records/ignore.txt @@ -1 +1 @@ -not yet implemented: java.lang.Class.isRecord0()Z +not yet implemented: java.lang.Class.getRecordComponents0()[Ljava/lang/reflect/RecordComponent;