Char arrays

This commit is contained in:
vegowotenks 2024-09-10 12:26:05 +02:00
parent 6610b09c16
commit c6e4ecec3d
6 changed files with 407 additions and 55 deletions

View file

@ -76,10 +76,11 @@ impl HeapArea {
byte_buffer
};
let byte_object_refs = utf16_bytes.iter().map(|byte| self.object_area.cached_byte_object(*byte)).collect();
let byte_array_ref = self.make_array(class_store, byte_object_refs);
let byte_array_ref = self.make_primitive_byte_array(utf16_bytes.len(), class_store);
for (index, byte) in utf16_bytes.iter().enumerate() {
self.object_area.set_array_element(byte_array_ref, index, FieldValue::Byte(*byte));
}
let string_class_index = class_store.class_idx_from_name(&String::from("java/lang/String")).unwrap();
let string_ref = self.make_object(class_store, string_class_index);
@ -88,9 +89,15 @@ impl HeapArea {
const UTF16_CODER: u8 = 1; // TODO: I don't like this
self.object_area.set_object_field(string_ref, "coder", FieldValue::Byte(UTF16_CODER), string_class_index, class_store).unwrap();
string_ref
string_ref
}
pub fn make_primitive_char_array(&mut self, array_capacity: usize, class_store: &ClassStore) -> ObjectReference {
let (array_ref, size) = self.object_area.make_primitive_char_array(array_capacity, class_store);
self.memory_used += size;
array_ref
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
@ -214,8 +221,7 @@ impl ObjectArea {
return (object_ref, object_size);
}
pub fn get_reference_native_class_name<'a>(&self, reference: ObjectReference, class_store: &'a ClassStore) -> &'a String {
let class_ref = self.get_reference_class_ref(reference, class_store);
pub fn get_class_ref_native_class_name<'a>(&self, class_ref: ObjectReference, class_store: &'a ClassStore) -> &'a String {
let class_data_ref = match self.get_object_field(class_ref, "classData", self.get_object_class_index(class_ref), class_store).unwrap() {
FieldValue::Reference(r) => r,
_ => unreachable!(),
@ -228,6 +234,11 @@ impl ObjectArea {
return class_store.get_native_class_name(native_name_index as usize);
}
pub fn get_reference_native_class_name<'a>(&self, reference: ObjectReference, class_store: &'a ClassStore) -> &'a String {
let class_ref = self.get_reference_class_ref(reference, class_store);
self.get_class_ref_native_class_name(class_ref, class_store)
}
pub fn get_object_class_index(&self, reference: ObjectReference) -> usize {
match self.get_entry(reference) {
CompartmentEntry::Object(o) => o.class_index,
@ -282,22 +293,26 @@ impl ObjectArea {
pub fn get_array_length(&self, reference: ObjectReference) -> usize {
// TODO: Throw errors
let array = match self.get_entry(reference) {
CompartmentEntry::ReferenceArray(a) => a,
match self.get_entry(reference) {
CompartmentEntry::ReferenceArray(a) => a.content.len(),
CompartmentEntry::ByteArray(b) => b.content.len(),
_ => unreachable!(),
};
array.content.len()
}
}
pub fn get_array_element(&self, array_ref: ObjectReference, element_index: i32) -> ObjectReference {
pub fn get_array_element(&self, array_ref: ObjectReference, element_index: i32) -> FieldValue {
// TODO: Throw errors
let array = match self.get_entry(array_ref) {
CompartmentEntry::ReferenceArray(a) => a,
match self.get_entry(array_ref) {
CompartmentEntry::ReferenceArray(array) => {
let element = array.content[element_index as usize];
FieldValue::Reference(element)
}
CompartmentEntry::ByteArray(array) => {
let element = array.content[element_index as usize];
FieldValue::Byte(element)
}
_ => unreachable!(),
};
array.content[element_index as usize]
}
}
pub fn get_object_field(&self, reference: ObjectReference, field_name: &str, accessing_class_idx: usize, class_store: &ClassStore) -> Result<FieldValue, Error> {
@ -387,6 +402,27 @@ impl ObjectArea {
)))
}
}
fn make_primitive_char_array(&mut self, array_capacity: usize, class_store: &ClassStore) -> (ObjectReference, usize) {
// make new type desc
let array_type_desc = AbstractTypeDescription {
array_level: 1,
kind: AbstractTypeKind::Char(),
};
let array_class_ref = class_store.get_array_class_ref(&array_type_desc).unwrap();
let array_size = array_capacity * std::mem::size_of::<u8>() + std::mem::size_of::<ByteArray>();
let array_object = CharArray {
class_ref: array_class_ref,
content: vec![0; array_capacity].into(),
};
let array_ref = self.store_entry(CompartmentEntry::CharArray(array_object));
(array_ref, array_size)
}
}
pub struct ObjectCompartment {
@ -428,6 +464,7 @@ impl ObjectCompartment {
CompartmentEntry::Object(_) => unreachable!(),
CompartmentEntry::ReferenceArray(_) => unreachable!(),
CompartmentEntry::ByteArray(_) => unreachable!(),
CompartmentEntry::CharArray(_) => unreachable!(),
}
*self.objects.get_mut(compartment_index).unwrap() = object;
@ -457,10 +494,17 @@ pub enum CompartmentEntry {
Object(HeapObject),
ReferenceArray(ReferenceArray),
ByteArray(ByteArray),
CharArray(CharArray),
EmptyNext(usize),
EmptyTail(), // last empty value
}
#[derive(Debug)]
pub struct CharArray {
class_ref: ObjectReference,
content: Box<[u16]>,
}
#[derive(Debug)]
pub struct ByteArray {
class_ref: ObjectReference,