I dont know, I changed things
This commit is contained in:
parent
43ceaa95bb
commit
3fd30b80b6
5 changed files with 98 additions and 10 deletions
|
@ -57,6 +57,7 @@ impl Bytecode {
|
||||||
0x32 => (Instruction::ArrayElement(), 1),
|
0x32 => (Instruction::ArrayElement(), 1),
|
||||||
0x33 => (Instruction::LoadFromBArray(), 1),
|
0x33 => (Instruction::LoadFromBArray(), 1),
|
||||||
0x36 => (Instruction::StoreLocalInt(self.bytes[offset+1]), 2),
|
0x36 => (Instruction::StoreLocalInt(self.bytes[offset+1]), 2),
|
||||||
|
0x37 => (Instruction::StoreLocalLong(self.bytes[offset+1]), 2),
|
||||||
0x38 => (Instruction::StoreLocalFloat(self.bytes[offset+1]), 2),
|
0x38 => (Instruction::StoreLocalFloat(self.bytes[offset+1]), 2),
|
||||||
0x3A => (Instruction::StoreLocalReference(self.bytes[offset+1]), 2),
|
0x3A => (Instruction::StoreLocalReference(self.bytes[offset+1]), 2),
|
||||||
0x3B => (Instruction::StoreLocalInt0(), 1),
|
0x3B => (Instruction::StoreLocalInt0(), 1),
|
||||||
|
@ -68,6 +69,7 @@ impl Bytecode {
|
||||||
0x4D => (Instruction::StoreLocalReference2(), 1),
|
0x4D => (Instruction::StoreLocalReference2(), 1),
|
||||||
0x4E => (Instruction::StoreLocalReference3(), 1),
|
0x4E => (Instruction::StoreLocalReference3(), 1),
|
||||||
|
|
||||||
|
0x4F => (Instruction::StoreIntoIArray(), 1),
|
||||||
0x53 => (Instruction::StoreIntoRArray(), 1),
|
0x53 => (Instruction::StoreIntoRArray(), 1),
|
||||||
0x54 => (Instruction::StoreIntoBArray(), 1),
|
0x54 => (Instruction::StoreIntoBArray(), 1),
|
||||||
0x55 => (Instruction::StoreIntoCArray(), 1),
|
0x55 => (Instruction::StoreIntoCArray(), 1),
|
||||||
|
@ -311,6 +313,7 @@ pub enum Instruction {
|
||||||
ArrayElement() = 0x32, // load element from array
|
ArrayElement() = 0x32, // load element from array
|
||||||
LoadFromBArray() = 0x33, // store into byte array
|
LoadFromBArray() = 0x33, // store into byte array
|
||||||
StoreLocalInt(u8) = 0x36, // store into indexed local variable
|
StoreLocalInt(u8) = 0x36, // store into indexed local variable
|
||||||
|
StoreLocalLong(u8) = 0x37, // store into indexed local variable
|
||||||
StoreLocalFloat(u8) = 0x38, // store into indexed local variable
|
StoreLocalFloat(u8) = 0x38, // store into indexed local variable
|
||||||
StoreLocalReference(u8) = 0x3A, // store into indexed local variable
|
StoreLocalReference(u8) = 0x3A, // store into indexed local variable
|
||||||
StoreLocalInt0() = 0x3B, // store int into local variable
|
StoreLocalInt0() = 0x3B, // store int into local variable
|
||||||
|
@ -322,6 +325,7 @@ pub enum Instruction {
|
||||||
StoreLocalReference2() = 0x4D, // store reference into local variable
|
StoreLocalReference2() = 0x4D, // store reference into local variable
|
||||||
StoreLocalReference3() = 0x4E, // store reference into local variable
|
StoreLocalReference3() = 0x4E, // store reference into local variable
|
||||||
|
|
||||||
|
StoreIntoIArray() = 0x4F, // store value into integer array
|
||||||
StoreIntoRArray() = 0x53, // store value into reference array
|
StoreIntoRArray() = 0x53, // store value into reference array
|
||||||
StoreIntoBArray() = 0x54, // store value into byte or boolean array
|
StoreIntoBArray() = 0x54, // store value into byte or boolean array
|
||||||
StoreIntoCArray() = 0x55, // store value into char array
|
StoreIntoCArray() = 0x55, // store value into char array
|
||||||
|
|
|
@ -98,6 +98,13 @@ impl HeapArea {
|
||||||
|
|
||||||
array_ref
|
array_ref
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn make_primitive_int_array(&mut self, array_capacity: usize, class_store: &ClassStore) -> ObjectReference {
|
||||||
|
let (array_ref, size) = self.object_area.make_primitive_int_array(array_capacity, class_store);
|
||||||
|
self.memory_used += size;
|
||||||
|
|
||||||
|
array_ref
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||||
|
@ -368,6 +375,11 @@ impl ObjectArea {
|
||||||
|
|
||||||
*array_element = match element { FieldValue::Char(c) => c, _ => unreachable!() } ;
|
*array_element = match element { FieldValue::Char(c) => c, _ => unreachable!() } ;
|
||||||
}
|
}
|
||||||
|
CompartmentEntry::IntArray(array) => {
|
||||||
|
let array_element = array.content.get_mut(index).unwrap();
|
||||||
|
|
||||||
|
*array_element = match element { FieldValue::Int(i) => i, _ => unreachable!() } ;
|
||||||
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -435,6 +447,27 @@ impl ObjectArea {
|
||||||
|
|
||||||
(array_ref, array_size)
|
(array_ref, array_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn make_primitive_int_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::Int(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let array_class_ref = class_store.get_array_class_ref(&array_type_desc).unwrap();
|
||||||
|
|
||||||
|
let array_size = array_capacity * std::mem::size_of::<i32>() + std::mem::size_of::<IntArray>();
|
||||||
|
|
||||||
|
let array_object = IntArray {
|
||||||
|
class_ref: array_class_ref,
|
||||||
|
content: vec![0; array_capacity].into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let array_ref = self.store_entry(CompartmentEntry::IntArray(array_object));
|
||||||
|
|
||||||
|
(array_ref, array_size)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ObjectCompartment {
|
pub struct ObjectCompartment {
|
||||||
|
@ -477,6 +510,7 @@ impl ObjectCompartment {
|
||||||
CompartmentEntry::ReferenceArray(_) => unreachable!(),
|
CompartmentEntry::ReferenceArray(_) => unreachable!(),
|
||||||
CompartmentEntry::ByteArray(_) => unreachable!(),
|
CompartmentEntry::ByteArray(_) => unreachable!(),
|
||||||
CompartmentEntry::CharArray(_) => unreachable!(),
|
CompartmentEntry::CharArray(_) => unreachable!(),
|
||||||
|
CompartmentEntry::IntArray(_) => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
*self.objects.get_mut(compartment_index).unwrap() = object;
|
*self.objects.get_mut(compartment_index).unwrap() = object;
|
||||||
|
@ -507,6 +541,7 @@ pub enum CompartmentEntry {
|
||||||
ReferenceArray(ReferenceArray),
|
ReferenceArray(ReferenceArray),
|
||||||
ByteArray(ByteArray),
|
ByteArray(ByteArray),
|
||||||
CharArray(CharArray),
|
CharArray(CharArray),
|
||||||
|
IntArray(IntArray),
|
||||||
EmptyNext(usize),
|
EmptyNext(usize),
|
||||||
EmptyTail(), // last empty value
|
EmptyTail(), // last empty value
|
||||||
}
|
}
|
||||||
|
@ -517,6 +552,12 @@ pub struct CharArray {
|
||||||
content: Box<[u16]>,
|
content: Box<[u16]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct IntArray {
|
||||||
|
class_ref: ObjectReference,
|
||||||
|
content: Box<[i32]>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ByteArray {
|
pub struct ByteArray {
|
||||||
class_ref: ObjectReference,
|
class_ref: ObjectReference,
|
||||||
|
|
58
src/jvm.rs
58
src/jvm.rs
|
@ -744,6 +744,16 @@ impl JVM {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Instruction::BranchIntGreaterThan(branch_offset) => {
|
||||||
|
let value_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
|
||||||
|
let value_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
|
||||||
|
|
||||||
|
if value_1 > value_2 {
|
||||||
|
frame.instruction_pointer -= offset as u32;
|
||||||
|
frame.instruction_pointer = if branch_offset < 0 { frame.instruction_pointer - branch_offset.abs() as u32} else { frame.instruction_pointer + branch_offset.abs() as u32};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Instruction::BranchIntInequality(branch_offset) => {
|
Instruction::BranchIntInequality(branch_offset) => {
|
||||||
let value_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
|
let value_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
|
||||||
let value_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
|
let value_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
|
||||||
|
@ -1208,11 +1218,20 @@ impl JVM {
|
||||||
return Ok(JVMCallbackOperation::InitClass(supplied_class_name.to_string()));
|
return Ok(JVMCallbackOperation::InitClass(supplied_class_name.to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let supplied_descriptor: MethodDescriptor = supplied_descriptor_string.try_into()?;
|
||||||
|
// TODO: Throw exception on fail
|
||||||
|
|
||||||
let (callee_class_file, callee_class_index) = self.class_store.get_class(supplied_class_name)?;
|
let (callee_class_file, callee_class_index) = self.class_store.get_class(supplied_class_name)?;
|
||||||
// TODO: Throw exception on fail
|
let (callee_class_index, callee_method_index, callee_method_info) = match ClassMethodIterator::new(callee_class_index, &self.class_store)
|
||||||
let callee_method_index = callee_class_file.find_method_index(supplied_method_name).unwrap();
|
.filter(|(_, _, minfo)| minfo.name == *supplied_method_name)
|
||||||
// TODO: Throw exception on fail
|
.filter(|(_, _, minfo)| minfo.descriptor == supplied_descriptor)
|
||||||
let callee_method_info = &callee_class_file.methods[callee_method_index];
|
.next() {
|
||||||
|
Some(m) => m,
|
||||||
|
None => {
|
||||||
|
// TODO: Throw exception
|
||||||
|
return Err(Error::RunTimeError(format!("InvokeStatic: Failed to find requested method '{}' with descriptor '{}' in the class '{}'", supplied_method_name, supplied_descriptor_string, supplied_class_name)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if ! (callee_method_info.access_flags & MethodAccessFlag::Static) {
|
if ! (callee_method_info.access_flags & MethodAccessFlag::Static) {
|
||||||
// TODO: Throw IncompatibleClassChangeError
|
// TODO: Throw IncompatibleClassChangeError
|
||||||
|
@ -1225,8 +1244,6 @@ impl JVM {
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let supplied_descriptor: MethodDescriptor = supplied_descriptor_string.try_into()?;
|
|
||||||
// TODO: Throw exception on fail
|
|
||||||
|
|
||||||
if supplied_descriptor != callee_method_info.descriptor {
|
if supplied_descriptor != callee_method_info.descriptor {
|
||||||
// TODO: Throw exception on fail
|
// TODO: Throw exception on fail
|
||||||
|
@ -1618,6 +1635,7 @@ impl JVM {
|
||||||
|
|
||||||
const CHAR: u8 = 5;
|
const CHAR: u8 = 5;
|
||||||
const BYTE: u8 = 8;
|
const BYTE: u8 = 8;
|
||||||
|
const INT: u8 = 10;
|
||||||
let array_ref = match array_type {
|
let array_ref = match array_type {
|
||||||
BYTE => {
|
BYTE => {
|
||||||
let array_ref = self.heap_area.make_primitive_byte_array(array_capacity as usize, &self.class_store);
|
let array_ref = self.heap_area.make_primitive_byte_array(array_capacity as usize, &self.class_store);
|
||||||
|
@ -1631,6 +1649,12 @@ impl JVM {
|
||||||
array_ref
|
array_ref
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INT => {
|
||||||
|
let array_ref = self.heap_area.make_primitive_int_array(array_capacity as usize, &self.class_store);
|
||||||
|
|
||||||
|
array_ref
|
||||||
|
}
|
||||||
|
|
||||||
_ => todo!()
|
_ => todo!()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1877,6 +1901,16 @@ impl JVM {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Instruction::StoreIntoIArray() => {
|
||||||
|
let value = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
|
||||||
|
let index = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
|
||||||
|
let array_ref = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?;
|
||||||
|
|
||||||
|
// TODO: Type checking
|
||||||
|
|
||||||
|
self.heap_area.object_area.set_array_element(array_ref, index as usize, FieldValue::Int(value));
|
||||||
|
}
|
||||||
|
|
||||||
Instruction::StoreIntoRArray() => {
|
Instruction::StoreIntoRArray() => {
|
||||||
let value = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?;
|
let value = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?;
|
||||||
let index = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
|
let index = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
|
||||||
|
@ -1926,6 +1960,14 @@ impl JVM {
|
||||||
wrap_stackframe_error(class, method, frame.store_local(3, StackValue::Int(int)))?;
|
wrap_stackframe_error(class, method, frame.store_local(3, StackValue::Int(int)))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Instruction::StoreLocalLong(index) => {
|
||||||
|
let long1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_long1(0))?;
|
||||||
|
let long0 = wrap_stackframe_error(class, method, frame.operand_stack.pop_long0(0))?;
|
||||||
|
|
||||||
|
wrap_stackframe_error(class, method, frame.store_local(index as u16, StackValue::Long0(long0)))?;
|
||||||
|
wrap_stackframe_error(class, method, frame.store_local(index as u16 + 1, StackValue::Long1(long1)))?;
|
||||||
|
}
|
||||||
|
|
||||||
Instruction::StoreLocalReference(index) => {
|
Instruction::StoreLocalReference(index) => {
|
||||||
let reference = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?;
|
let reference = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?;
|
||||||
|
|
||||||
|
@ -2043,12 +2085,12 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve
|
||||||
},
|
},
|
||||||
AbstractTypeKind::Char() => {
|
AbstractTypeKind::Char() => {
|
||||||
arguments.push_front(
|
arguments.push_front(
|
||||||
StackValue::Char(
|
StackValue::Int(
|
||||||
wrap_stackframe_error(
|
wrap_stackframe_error(
|
||||||
class,
|
class,
|
||||||
method,
|
method,
|
||||||
stack.pop_char(0)
|
stack.pop_char(0)
|
||||||
)?
|
)? as i32
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
|
@ -403,6 +403,7 @@ impl JdkInternalUtilSystemPropsRaw {
|
||||||
("user.script", ""),
|
("user.script", ""),
|
||||||
("user.country", "US"),
|
("user.country", "US"),
|
||||||
("user.variant", ""),
|
("user.variant", ""),
|
||||||
|
("sun.nio.MaxDirectMemorySize", "9223372036854775807"),
|
||||||
];
|
];
|
||||||
// TODO: Cross-Platform tmpdir
|
// TODO: Cross-Platform tmpdir
|
||||||
// TODO: locale detection
|
// TODO: locale detection
|
||||||
|
|
|
@ -153,8 +153,8 @@ impl OperandStack {
|
||||||
let value = self.stack[absolute_index];
|
let value = self.stack[absolute_index];
|
||||||
self.depth -= 1;
|
self.depth -= 1;
|
||||||
match value {
|
match value {
|
||||||
StackValue::Char(c) => Ok(c),
|
StackValue::Int(c) => Ok(c as u16),
|
||||||
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Char but found '{:?}'", index, value)))
|
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Int(Char) but found '{:?}'", index, value)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue