Skip to content

Commit 89bdc5d

Browse files
committed
Store java.lang.Class name as byte array and resolve ClassDefinition on demand
1 parent 9a4a05e commit 89bdc5d

2 files changed

Lines changed: 17 additions & 6 deletions

File tree

‎java_runtime/src/classes/java/lang/class.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl Class {
4242
),
4343
],
4444
fields: vec![
45-
JavaFieldProto::new("raw", "[B", Default::default()), // raw rust pointer of Box<dyn Class>
45+
JavaFieldProto::new("nameBytes", "[B", Default::default()),
4646
JavaFieldProto::new("classLoader", "Ljava/lang/ClassLoader;", Default::default()),
4747
],
4848
access_flags: Default::default(),

‎jvm/src/runtime/java_lang_class.rs‎

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
use alloc::boxed::Box;
22

3-
use crate::{Result, class_definition::ClassDefinition, class_instance::ClassInstance, jvm::Jvm};
3+
use crate::{Array, ClassInstanceRef, Result, class_definition::ClassDefinition, class_instance::ClassInstance, jvm::Jvm};
44

55
pub struct JavaLangClass;
66

77
impl JavaLangClass {
88
#[allow(clippy::borrowed_box)]
99
pub async fn to_rust_class(jvm: &Jvm, this: &Box<dyn ClassInstance>) -> Result<Box<dyn ClassDefinition>> {
10-
let rust_class = jvm.get_rust_object_field(this, "raw").await?;
11-
12-
Ok(rust_class)
10+
let name_bytes: ClassInstanceRef<Array<i8>> = jvm.get_field(this, "nameBytes", "[B").await?;
11+
let len = jvm.array_length(&name_bytes).await?;
12+
let name_bytes_vec: alloc::vec::Vec<i8> = jvm.load_array(&name_bytes, 0, len).await?;
13+
let class_name = alloc::string::String::from_utf8(name_bytes_vec.iter().map(|&b| b as u8).collect()).unwrap_or_default();
14+
if let Some(class) = jvm.get_class(&class_name) {
15+
Ok(class.definition)
16+
} else {
17+
Err(jvm.exception("java/lang/NoClassDefFoundError", &class_name).await)
18+
}
1319
}
1420

1521
pub async fn from_rust_class(
@@ -19,7 +25,12 @@ impl JavaLangClass {
1925
) -> Result<Box<dyn ClassInstance>> {
2026
let mut java_class = jvm.new_class("java/lang/Class", "()V", ()).await?;
2127

22-
jvm.put_rust_object_field(&mut java_class, "raw", rust_class).await?;
28+
let class_name = rust_class.name();
29+
let mut name_bytes = jvm.instantiate_array("B", class_name.len()).await?;
30+
let bytes: alloc::vec::Vec<i8> = class_name.as_bytes().iter().map(|&b| b as i8).collect();
31+
jvm.store_array(&mut name_bytes, 0, bytes).await?;
32+
jvm.put_field(&mut java_class, "nameBytes", "[B", name_bytes).await?;
33+
2334
jvm.put_field(&mut java_class, "classLoader", "Ljava/lang/ClassLoader;", class_loader)
2435
.await?;
2536

0 commit comments

Comments
 (0)