checkpoint2

This commit is contained in:
jtaylour 2025-11-12 08:57:37 +10:30
parent e39ae877a3
commit 475b0ea6a5
5 changed files with 124 additions and 30 deletions

View File

@ -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!");
}

View File

@ -448,7 +448,7 @@ pub(crate) struct Bytecode {
pub code: Vec<Ops>, pub code: Vec<Ops>,
} }
type CONSTANT_POOL = [CpInfo];
pub trait ConstantPoolExt { pub trait ConstantPoolExt {
fn get_constant(&self, index: u16) -> Option<&CpInfo>; 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)] #[derive(Debug)]
pub struct MethodData { pub struct MethodData {

View File

@ -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<String, ()> {
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<FieldData, ()> {
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<MethodData, ()> {
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<MethodData, ()> {
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<FieldData, ()> {
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,
})
}
}

6
src/class_file/mod.rs Normal file
View File

@ -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

View File

@ -11,7 +11,6 @@ use itertools::Itertools;
use vm::Vm; use vm::Vm;
use crate::attributes::{Attribute, CodeAttribute, Ops}; use crate::attributes::{Attribute, CodeAttribute, Ops};
use crate::class_file::{Bytecode, ClassFile, ClassFlags, ConstantPoolExt, CpInfo, FieldFlags, MethodFlags}; use crate::class_file::{Bytecode, ClassFile, ClassFlags, ConstantPoolExt, CpInfo, FieldFlags, MethodFlags};
use crate::JVM_ACC::*;
use crate::object::Object; use crate::object::Object;
use crate::thread::VmThread; use crate::thread::VmThread;