Skip to content

Commit 6131e94

Browse files
Merge pull request #552 from theseus-rs/implement-class-isrecord
feat: implement java/lang/Class.isRecord0()Z
2 parents baa835c + f3e8bd3 commit 6131e94

File tree

4 files changed

+28
-17
lines changed

4 files changed

+28
-17
lines changed

ristretto_vm/src/intrinsic_methods/java/lang/class.rs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,10 +1017,17 @@ pub(crate) async fn is_primitive(
10171017
#[intrinsic_method("java/lang/Class.isRecord0()Z", GreaterThanOrEqual(JAVA_17))]
10181018
#[async_recursion(?Send)]
10191019
pub(crate) async fn is_record_0(
1020-
_thread: Arc<Thread>,
1021-
_parameters: Parameters,
1020+
thread: Arc<Thread>,
1021+
mut parameters: Parameters,
10221022
) -> Result<Option<Value>> {
1023-
todo!("java.lang.Class.isRecord0()Z")
1023+
let value = parameters.pop()?;
1024+
let class = get_class(&thread, &value).await?;
1025+
let Some(parent_class) = class.parent()? else {
1026+
return Ok(Some(Value::from(false)));
1027+
};
1028+
let parent_class_name = parent_class.name();
1029+
let is_record = parent_class_name == "java/lang/Record";
1030+
Ok(Some(Value::from(is_record)))
10241031
}
10251032

10261033
#[intrinsic_method("java/lang/Class.registerNatives()V", Any)]
@@ -1704,7 +1711,7 @@ mod tests {
17041711
#[tokio::test]
17051712
async fn test_is_array() -> Result<()> {
17061713
let (_vm, thread) = crate::test::thread().await?;
1707-
let class: Arc<Class> = thread.class("[int").await?;
1714+
let class = thread.class("[int").await?;
17081715
let object = class.to_object(&thread).await?;
17091716
let parameters = Parameters::new(vec![object]);
17101717
let result = is_array(thread, parameters).await?;
@@ -1715,7 +1722,7 @@ mod tests {
17151722
#[tokio::test]
17161723
async fn test_is_array_false() -> Result<()> {
17171724
let (_vm, thread) = crate::test::thread().await?;
1718-
let class: Arc<Class> = thread.class("int").await?;
1725+
let class = thread.class("int").await?;
17191726
let object = class.to_object(&thread).await?;
17201727
let parameters = Parameters::new(vec![object]);
17211728
let result = is_array(thread, parameters).await?;
@@ -1799,7 +1806,7 @@ mod tests {
17991806
#[tokio::test]
18001807
async fn test_is_interface() -> Result<()> {
18011808
let (_vm, thread) = crate::test::thread().await?;
1802-
let class: Arc<Class> = thread.class("java.lang.Cloneable").await?;
1809+
let class = thread.class("java.lang.Cloneable").await?;
18031810
let object = class.to_object(&thread).await?;
18041811
let parameters = Parameters::new(vec![object]);
18051812
let result = is_interface(thread, parameters).await?;
@@ -1810,7 +1817,7 @@ mod tests {
18101817
#[tokio::test]
18111818
async fn test_is_interface_false() -> Result<()> {
18121819
let (_vm, thread) = crate::test::thread().await?;
1813-
let class: Arc<Class> = thread.class("java.lang.Integer").await?;
1820+
let class = thread.class("java.lang.Integer").await?;
18141821
let object = class.to_object(&thread).await?;
18151822
let parameters = Parameters::new(vec![object]);
18161823
let result = is_interface(thread, parameters).await?;
@@ -1821,7 +1828,7 @@ mod tests {
18211828
#[tokio::test]
18221829
async fn test_is_primitive() -> Result<()> {
18231830
let (_vm, thread) = crate::test::thread().await?;
1824-
let class: Arc<Class> = thread.class("int").await?;
1831+
let class = thread.class("int").await?;
18251832
let object = class.to_object(&thread).await?;
18261833
let parameters = Parameters::new(vec![object]);
18271834
let result = is_primitive(thread, parameters).await?;
@@ -1832,7 +1839,7 @@ mod tests {
18321839
#[tokio::test]
18331840
async fn test_is_primitive_false() -> Result<()> {
18341841
let (_vm, thread) = crate::test::thread().await?;
1835-
let class: Arc<Class> = thread.class("java.lang.Integer").await?;
1842+
let class = thread.class("java.lang.Integer").await?;
18361843
let object = class.to_object(&thread).await?;
18371844
let parameters = Parameters::new(vec![object]);
18381845
let result = is_primitive(thread, parameters).await?;
@@ -1841,10 +1848,14 @@ mod tests {
18411848
}
18421849

18431850
#[tokio::test]
1844-
#[should_panic(expected = "not yet implemented: java.lang.Class.isRecord0()Z")]
1845-
async fn test_is_record_0() {
1846-
let (_vm, thread) = crate::test::thread().await.expect("thread");
1847-
let _ = is_record_0(thread, Parameters::default()).await;
1851+
async fn test_is_record_0_false() -> Result<()> {
1852+
let (_vm, thread) = crate::test::thread().await?;
1853+
let class = thread.class("java.lang.Integer").await?;
1854+
let object = class.to_object(&thread).await?;
1855+
let parameters = Parameters::new(vec![object]);
1856+
let result = is_record_0(thread, parameters).await?;
1857+
assert_eq!(result, Some(Value::from(false)));
1858+
Ok(())
18481859
}
18491860

18501861
#[tokio::test]

ristretto_vm/src/intrinsic_methods/jdk/internal/misc/unsafe.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::thread::Thread;
77
use async_recursion::async_recursion;
88
use ristretto_classfile::VersionSpecification::{Between, Equal, GreaterThan, GreaterThanOrEqual};
99
use ristretto_classfile::{BaseType, FieldAccessFlags, JAVA_11, JAVA_17};
10-
use ristretto_classloader::{Class, Reference, Value};
10+
use ristretto_classloader::{Reference, Value};
1111
use ristretto_macros::intrinsic_method;
1212
use std::sync::Arc;
1313
use zerocopy::transmute_ref;
@@ -83,7 +83,7 @@ pub(crate) async fn array_index_scale_0(
8383
mut parameters: Parameters,
8484
) -> Result<Option<Value>> {
8585
let object = parameters.pop()?;
86-
let class: Arc<Class> = get_class(&thread, &object).await?;
86+
let class = get_class(&thread, &object).await?;
8787
let class_name = class.name();
8888
let scale = match class_name {
8989
"[Z" => BOOLEAN_SIZE, // boolean

tests/record/reflection/ignore.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
not yet implemented: java.lang.Class.isRecord0()Z
1+
not yet implemented: java.lang.Class.getRecordComponents0()[Ljava/lang/reflect/RecordComponent;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
not yet implemented: java.lang.Class.isRecord0()Z
1+
not yet implemented: java.lang.Class.getRecordComponents0()[Ljava/lang/reflect/RecordComponent;

0 commit comments

Comments
 (0)