Char arrays
This commit is contained in:
parent
6610b09c16
commit
c6e4ecec3d
6 changed files with 407 additions and 55 deletions
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue