Working up until registerNatives()
This commit is contained in:
parent
5bc0d813e5
commit
3282694b32
4 changed files with 268 additions and 58 deletions
|
@ -55,6 +55,13 @@ impl HeapArea {
|
|||
self.memory_used += self.object_area.fill_byte_cache(class_store);
|
||||
}
|
||||
|
||||
pub fn make_primitive_byte_array(&mut self, capacity: usize, class_store: &ClassStore) -> ObjectReference {
|
||||
let (array_ref, size) = self.object_area.make_primitive_byte_array(capacity, class_store);
|
||||
self.memory_used += size;
|
||||
|
||||
array_ref
|
||||
}
|
||||
|
||||
pub fn make_handmade_string(&mut self, s: &String, class_store: &ClassStore) -> ObjectReference {
|
||||
let utf16_bytes = {
|
||||
let utf16 = s.encode_utf16();
|
||||
|
@ -127,8 +134,29 @@ impl ObjectArea {
|
|||
self.byte_object_cache[byte as usize]
|
||||
}
|
||||
|
||||
fn make_primitive_byte_array(&mut self, capacity: usize, class_store: &ClassStore) -> (ObjectReference, usize) {
|
||||
// make new type desc
|
||||
let array_type_desc = AbstractTypeDescription {
|
||||
array_level: 1,
|
||||
kind: AbstractTypeKind::Byte(),
|
||||
};
|
||||
|
||||
let array_class_ref = class_store.get_array_class_ref(&array_type_desc).unwrap();
|
||||
|
||||
let array_size = capacity * std::mem::size_of::<u8>() + std::mem::size_of::<ByteArray>();
|
||||
|
||||
let array_object = ByteArray {
|
||||
class_ref: array_class_ref,
|
||||
content: vec![0_u8; capacity].into(),
|
||||
};
|
||||
|
||||
let array_ref = self.store_entry(CompartmentEntry::ByteArray(array_object));
|
||||
|
||||
(array_ref, array_size)
|
||||
}
|
||||
|
||||
fn make_empty_array(&mut self, class_store: &ClassStore, element_type_desc: AbstractTypeDescription, capacity: usize) -> (ObjectReference, usize) {
|
||||
//
|
||||
|
||||
// make new type desc
|
||||
let array_type_desc = AbstractTypeDescription {
|
||||
array_level: 1 + element_type_desc.array_level,
|
||||
|
@ -137,14 +165,14 @@ impl ObjectArea {
|
|||
|
||||
let array_class_ref = class_store.get_array_class_ref(&array_type_desc).unwrap();
|
||||
|
||||
let array_object = HeapArray {
|
||||
let array_object = ReferenceArray {
|
||||
class_ref: array_class_ref,
|
||||
content: vec![ObjectReference::NULL; capacity].into_boxed_slice(),
|
||||
};
|
||||
|
||||
let array_size = std::mem::size_of::<HeapArray>() + std::mem::size_of::<ObjectReference>() * array_object.content.len();
|
||||
let array_size = std::mem::size_of::<ReferenceArray>() + std::mem::size_of::<ObjectReference>() * array_object.content.len();
|
||||
|
||||
let array_object_ref = self.store_entry(CompartmentEntry::Array(array_object));
|
||||
let array_object_ref = self.store_entry(CompartmentEntry::ReferenceArray(array_object));
|
||||
|
||||
self.memory_used += array_size;
|
||||
|
||||
|
@ -159,13 +187,13 @@ impl ObjectArea {
|
|||
let (array_object_ref, array_size) = self.make_empty_array(class_store, array_element_type_desc, elements.len());
|
||||
|
||||
for (index, element) in elements.iter().enumerate() {
|
||||
self.set_array_element(array_object_ref, index, *element);
|
||||
self.set_array_element(array_object_ref, index, FieldValue::Reference(*element));
|
||||
}
|
||||
|
||||
return (array_object_ref, array_size);
|
||||
}
|
||||
|
||||
pub fn make(&mut self, class_store: &ClassStore, target_class_index: usize) -> (ObjectReference, usize) {
|
||||
fn make(&mut self, class_store: &ClassStore, target_class_index: usize) -> (ObjectReference, usize) {
|
||||
let fields: Vec<_> = ClassFieldIterator::new(target_class_index, class_store)
|
||||
.filter(|f| ! (f.access_flags & FieldAccessFlag::Static))
|
||||
.map(|f| ObjectField { value: FieldValue::default_for(&f.descriptor) })
|
||||
|
@ -210,7 +238,7 @@ impl ObjectArea {
|
|||
fn get_reference_class_ref(&self, reference: ObjectReference, class_store: &ClassStore) -> ObjectReference {
|
||||
match self.get_entry(reference) {
|
||||
CompartmentEntry::Object(o) => class_store.get_class_objectref_from_index(o.class_index),
|
||||
CompartmentEntry::Array(a) => a.class_ref,
|
||||
CompartmentEntry::ReferenceArray(a) => a.class_ref,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
@ -230,7 +258,7 @@ impl ObjectArea {
|
|||
return ObjectReference(object_index + (DEFAULT_COMPARTMENT_CAPACITY * (compartment_index as u32 + 1)));
|
||||
}
|
||||
|
||||
fn get_entry(&self, reference: ObjectReference) -> &CompartmentEntry {
|
||||
pub fn get_entry(&self, reference: ObjectReference) -> &CompartmentEntry {
|
||||
let index = reference.0;
|
||||
let compartment_index: u32 = (index / DEFAULT_COMPARTMENT_CAPACITY) - 1;
|
||||
let object_index: u32 = index % DEFAULT_COMPARTMENT_CAPACITY;
|
||||
|
@ -255,7 +283,7 @@ impl ObjectArea {
|
|||
pub fn get_array_length(&self, reference: ObjectReference) -> usize {
|
||||
// TODO: Throw errors
|
||||
let array = match self.get_entry(reference) {
|
||||
CompartmentEntry::Array(a) => a,
|
||||
CompartmentEntry::ReferenceArray(a) => a,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
|
@ -265,7 +293,7 @@ impl ObjectArea {
|
|||
pub fn get_array_element(&self, array_ref: ObjectReference, element_index: i32) -> ObjectReference {
|
||||
// TODO: Throw errors
|
||||
let array = match self.get_entry(array_ref) {
|
||||
CompartmentEntry::Array(a) => a,
|
||||
CompartmentEntry::ReferenceArray(a) => a,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
|
@ -301,15 +329,21 @@ impl ObjectArea {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_array_element(&mut self, array_reference: ObjectReference, index: usize, element: ObjectReference) {
|
||||
let array = match self.get_entry_mut(array_reference) {
|
||||
CompartmentEntry::Array(a) => a,
|
||||
pub fn set_array_element(&mut self, array_reference: ObjectReference, index: usize, element: FieldValue) {
|
||||
match self.get_entry_mut(array_reference) {
|
||||
CompartmentEntry::ReferenceArray(array) => {
|
||||
let array_element = array.content.get_mut(index).unwrap();
|
||||
|
||||
*array_element = match element { FieldValue::Reference(r) => r, _ => unreachable!() } ;
|
||||
},
|
||||
CompartmentEntry::ByteArray(array) => {
|
||||
let array_element = array.content.get_mut(index).unwrap();
|
||||
|
||||
*array_element = match element { FieldValue::Byte(b) => b, _ => unreachable!() } ;
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let array_element = array.content.get_mut(index).unwrap();
|
||||
|
||||
*array_element = element;
|
||||
}
|
||||
|
||||
pub fn set_object_field(&mut self, reference: ObjectReference, field_name: &str, value: FieldValue, accessing_class_idx: usize, class_store: &ClassStore) -> Result<(), Error> {
|
||||
|
@ -392,7 +426,8 @@ impl ObjectCompartment {
|
|||
},
|
||||
|
||||
CompartmentEntry::Object(_) => unreachable!(),
|
||||
CompartmentEntry::Array(_) => unreachable!(),
|
||||
CompartmentEntry::ReferenceArray(_) => unreachable!(),
|
||||
CompartmentEntry::ByteArray(_) => unreachable!(),
|
||||
}
|
||||
|
||||
*self.objects.get_mut(compartment_index).unwrap() = object;
|
||||
|
@ -420,13 +455,20 @@ impl DebugTrait for ObjectCompartment {
|
|||
#[derive(Debug)]
|
||||
pub enum CompartmentEntry {
|
||||
Object(HeapObject),
|
||||
Array(HeapArray),
|
||||
ReferenceArray(ReferenceArray),
|
||||
ByteArray(ByteArray),
|
||||
EmptyNext(usize),
|
||||
EmptyTail(), // last empty value
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct HeapArray {
|
||||
pub struct ByteArray {
|
||||
class_ref: ObjectReference,
|
||||
content: Box<[u8]>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ReferenceArray {
|
||||
class_ref: ObjectReference,
|
||||
content: Box<[ObjectReference]>,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue