diff --git a/build.rs b/build.rs deleted file mode 100644 index 47ba13d..0000000 --- a/build.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::env; -use std::path::PathBuf; - -fn main() { - println!("cargo:rerun-if-changed=classfile_constants.h"); - - let bindings = bindgen::Builder::default() - .header("data/java/base/jmod/include/classfile_constants.h") - .rustified_enum(".*") - .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) - .generate() - .expect("Unable to generate bindings"); - - let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); - bindings - .write_to_file(out_path.join("bindings.rs")) - .expect("Couldn't write bindings!"); -} \ No newline at end of file diff --git a/src/class_file.rs b/src/class_file/class_file.rs similarity index 99% rename from src/class_file.rs rename to src/class_file/class_file.rs index 6104ffc..355e7a9 100644 --- a/src/class_file.rs +++ b/src/class_file/class_file.rs @@ -448,7 +448,7 @@ pub(crate) struct Bytecode { pub code: Vec, } -type CONSTANT_POOL = [CpInfo]; + pub trait ConstantPoolExt { fn get_constant(&self, index: u16) -> Option<&CpInfo>; @@ -566,16 +566,6 @@ impl ConstantPoolExt for [CpInfo] { } } -struct ConstantPool<'a>(&'a [CpInfo]); - -impl Deref for ConstantPool { - type Target = [CpInfo]; - - fn deref(&self) -> &Self::Target { - self.0 - } -} - #[derive(Debug)] pub struct MethodData { diff --git a/src/class_file/constant_pool.rs b/src/class_file/constant_pool.rs new file mode 100644 index 0000000..8cac1b2 --- /dev/null +++ b/src/class_file/constant_pool.rs @@ -0,0 +1,117 @@ +use std::ops::Deref; +use crate::class_file::{ConstantClassInfo, ConstantFieldrefInfo, ConstantNameAndTypeInfo, ConstantPoolExt, CpInfo, FieldData, FieldInfo, MethodData, MethodInfo}; +use crate::{FieldType, MethodDescriptor}; + +struct ConstantPool<'a>(&'a [CpInfo]); + +impl Deref for ConstantPool<'_> { + type Target = [CpInfo]; + + fn deref(&self) -> &Self::Target { + self.0 + } +} + +impl ConstantPool<'_> { + fn get_constant(&self, index: u16) -> Option<&CpInfo> { + let mut current_index = 1u16; + for entry in self { + if current_index == index { + return Some(entry); + } + current_index += match entry { + CpInfo::Long(_) | CpInfo::Double(_) => 2, + _ => 1, + }; + } + None + } + + fn get_string(&self, index: u16) -> Result { + let cp_entry = self.get_constant(index).ok_or(())?; + match cp_entry { + CpInfo::Utf8(data) => { + String::from_utf8(data.bytes.clone()).map_err(|e| ()) + }, + _ => Err(()), + } + } + + fn get_field(&self, index: u16) -> Result<&ConstantFieldrefInfo, ()> { + let cp_entry = self.get_constant(index).ok_or(())?; + match cp_entry { + CpInfo::FieldRef(data) => Ok(data), + _ => Err(()), + } + } + + fn get_class(&self, index: u16) -> Result<&ConstantClassInfo, ()> { + let cp_entry = self.get_constant(index).ok_or(())?; + match cp_entry { + CpInfo::Class(data) => Ok(data), + _ => Err(()), + } + } + fn get_name_and_type(&self, index: u16) -> Result<&ConstantNameAndTypeInfo, ()> { + let cp_entry = self.get_constant(index).ok_or(())?; + match cp_entry { + CpInfo::NameAndType(data) => Ok(data), + _ => Err(()), + } + } + + fn resolve_field(&self, index: u16) -> Result { + if let Some(CpInfo::FieldRef(fr)) = self.get_constant(index) { + let class = self.get_class(fr.class_index)?; + let class = self.get_string(class.name_index)?; + let name_and_type = self.get_name_and_type(fr.name_and_type_index)?; + let name = self.get_string(name_and_type.name_index)?; + let desc = self.get_string(name_and_type.descriptor_index)?; + let desc = FieldType::parse(&desc)?; + Ok(FieldData { + class, + name, + desc, + }) + } else { Err(()) } + } + + fn resolve_method_ref(&self, index: u16) -> Result { + if let Some(CpInfo::MethodRef(mr)) = self.get_constant(index) { + let class = self.get_class(mr.class_index)?; + let class = self.get_string(class.name_index)?; + let name_and_type = self.get_name_and_type(mr.name_and_type_index)?; + let name = self.get_string(name_and_type.name_index)?; + let desc = self.get_string(name_and_type.descriptor_index)?; + let desc = MethodDescriptor::parse(&desc)?; + Ok(MethodData { + class, + name, + desc, + }) + } else { Err(()) } + } + + // (name, desc) + fn resolve_method_info(&self, method: &MethodInfo) -> Result { + let desc = self.get_string(method.descriptor_index)?; + let desc = MethodDescriptor::parse(&desc)?; + let name = self.get_string(method.name_index)?; + Ok(MethodData { + class: "".to_string(), + name, + desc, + }) + } + + fn resolve_field_info(&self, field: &FieldInfo) -> Result { + let desc = self.get_string(field.descriptor_index)?; + let desc = FieldType::parse(&desc)?; + let name = self.get_string(field.name_index)?; + Ok(FieldData { + class: "".to_string(), + name, + desc, + }) + } +} \ No newline at end of file diff --git a/src/class_file/mod.rs b/src/class_file/mod.rs new file mode 100644 index 0000000..68b97eb --- /dev/null +++ b/src/class_file/mod.rs @@ -0,0 +1,6 @@ +pub mod class_file; +pub mod constant_pool; + +// Re-export items if you want them accessible directly from class_file:: +pub use class_file::*; // optional +// pub use constant_pool::*; // optional \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 64aedf1..a259c53 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,7 +11,6 @@ use itertools::Itertools; use vm::Vm; use crate::attributes::{Attribute, CodeAttribute, Ops}; use crate::class_file::{Bytecode, ClassFile, ClassFlags, ConstantPoolExt, CpInfo, FieldFlags, MethodFlags}; -use crate::JVM_ACC::*; use crate::object::Object; use crate::thread::VmThread;