use std::collections::HashMap; use crate::accessmasks::FieldAccessFlag; use crate::stackframe::StackValue; use crate::classfile::{ JavaClassFile, AbstractTypeDescription, MethodInfo }; #[derive(Debug)] pub struct HeapArea { pub memory_capacity: usize, pub memory_used: usize, pub object_area: ObjectArea, pub static_area: StaticArea, } impl HeapArea { pub fn new(memory_capacity: usize) -> Self { HeapArea { memory_capacity, memory_used: 0, object_area: ObjectArea::default(), static_area: StaticArea::default(), } } } pub type ObjectReference=u32; const DEFAULT_COMPARTMENT_CAPACITY: usize = u16::MAX as usize; #[derive(Default, Debug)] pub struct ObjectArea { compartments: Vec, } #[derive(Debug)] pub struct ObjectCompartment { objects: Box<[ObjectCompartmentEntry]>, first_free: usize, reserved_count: usize, } #[derive(Debug)] pub enum ObjectCompartmentEntry { Valid(HeapObject), Empty(usize), // next empty value } #[derive(Debug)] pub struct HeapObject { fields: Box<[ObjectField]>, } #[derive(Default, Debug)] pub struct StaticArea { static_objects: HashMap, } impl StaticArea { pub fn make(&mut self, class: &JavaClassFile, class_index: usize) { let mut fields = Vec::new(); for field in &class.fields { if field.access_flags & FieldAccessFlag::Static { fields.push( StaticField { name: field.name.clone(), type_description: field.descriptor.clone(), value: StackValue::default_for(field.descriptor), } ) } } let new_object = StaticObject { class_index, fields: fields.into_boxed_slice(), methods: Box::new([]), }; let _ = self.static_objects.insert(class.get_classname().unwrap(), new_object); } } #[derive(Debug)] pub struct StaticObject { pub class_index: usize, pub fields: Box<[StaticField]>, pub methods: Box<[MethodInfo]>, } #[derive(Debug)] pub struct StaticField { pub name: String, pub type_description: AbstractTypeDescription, pub value: StackValue, } #[derive(Debug)] pub struct ObjectField { pub type_description: AbstractTypeDescription, pub value: StackValue, }