Refactor to StackValue
This commit is contained in:
parent
6c0fbd179a
commit
4ee673d5ff
4 changed files with 58 additions and 59 deletions
|
@ -1,7 +1,7 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::accessmasks::FieldAccessFlag;
|
use crate::accessmasks::FieldAccessFlag;
|
||||||
use crate::stackframe::Value;
|
use crate::stackframe::StackValue;
|
||||||
use crate::classfile::{ JavaClassFile, AbstractTypeDescription, MethodInfo };
|
use crate::classfile::{ JavaClassFile, AbstractTypeDescription, MethodInfo };
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -65,7 +65,7 @@ impl StaticArea {
|
||||||
StaticField {
|
StaticField {
|
||||||
name: field.name.clone(),
|
name: field.name.clone(),
|
||||||
type_description: field.descriptor.clone(),
|
type_description: field.descriptor.clone(),
|
||||||
value: Value::default_for(field.descriptor),
|
value: StackValue::default_for(field.descriptor),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -92,12 +92,11 @@ pub struct StaticObject {
|
||||||
pub struct StaticField {
|
pub struct StaticField {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub type_description: AbstractTypeDescription,
|
pub type_description: AbstractTypeDescription,
|
||||||
pub value: Value,
|
pub value: StackValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ObjectField {
|
pub struct ObjectField {
|
||||||
pub type_description: AbstractTypeDescription,
|
pub type_description: AbstractTypeDescription,
|
||||||
pub value: Value,
|
pub value: StackValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
52
src/jvm.rs
52
src/jvm.rs
|
@ -12,7 +12,7 @@ use crate::classstore::ClassStore;
|
||||||
use crate::constantpool::{ ConstantPoolInfo, ConstantClassInfo, ConstantUtf8Info, ConstantMethodRefInfo, ConstantNameAndTypeInfo};
|
use crate::constantpool::{ ConstantPoolInfo, ConstantClassInfo, ConstantUtf8Info, ConstantMethodRefInfo, ConstantNameAndTypeInfo};
|
||||||
use crate::heap_area::HeapArea;
|
use crate::heap_area::HeapArea;
|
||||||
use crate::stackframe;
|
use crate::stackframe;
|
||||||
use crate::stackframe::{ StackFrame, Value, OperandStack };
|
use crate::stackframe::{ StackFrame, StackValue, OperandStack };
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
@ -63,7 +63,7 @@ impl JVM {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn entrypoint(&mut self, class_name: &String, method_name: &String, arguments: &[Value]) -> Result<(), Error> {
|
pub fn entrypoint(&mut self, class_name: &String, method_name: &String, arguments: &[StackValue]) -> Result<(), Error> {
|
||||||
let entry_class = JavaClassFile {
|
let entry_class = JavaClassFile {
|
||||||
minor_version: 0,
|
minor_version: 0,
|
||||||
major_version: 0,
|
major_version: 0,
|
||||||
|
@ -184,7 +184,7 @@ impl JVM {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_invoke_static(&mut self, class_index: usize, method_name: &String, arguments: &[Value]) -> Result<(), Error> {
|
fn prepare_invoke_static(&mut self, class_index: usize, method_name: &String, arguments: &[StackValue]) -> Result<(), Error> {
|
||||||
|
|
||||||
let class_file = self.class_store.class_file_from_idx(class_index).unwrap();
|
let class_file = self.class_store.class_file_from_idx(class_index).unwrap();
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ impl JVM {
|
||||||
// sign extend into int
|
// sign extend into int
|
||||||
let i8_int = i8::from_be_bytes([byte]);
|
let i8_int = i8::from_be_bytes([byte]);
|
||||||
|
|
||||||
let frame_result = frame.operand_stack.push(Value::Int(i8_int as i32));
|
let frame_result = frame.operand_stack.push(StackValue::Int(i8_int as i32));
|
||||||
match frame_result {
|
match frame_result {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(err) => return Err(Error::StackFrameError(err, format!("in '{}', in class '{}'", method.name, class.get_classname().unwrap()))),
|
Err(err) => return Err(Error::StackFrameError(err, format!("in '{}', in class '{}'", method.name, class.get_classname().unwrap()))),
|
||||||
|
@ -306,11 +306,11 @@ impl JVM {
|
||||||
Instruction::MultiplyInt() => {
|
Instruction::MultiplyInt() => {
|
||||||
let factor_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
|
let factor_1 = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
|
||||||
let factor_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
|
let factor_2 = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
|
||||||
wrap_stackframe_error(class, method, frame.operand_stack.push(Value::Int(factor_1 * factor_2)))?;
|
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Int(factor_1 * factor_2)))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Instruction::PushConstInt5() => {
|
Instruction::PushConstInt5() => {
|
||||||
let frame_result = frame.operand_stack.push(Value::Int(5));
|
let frame_result = frame.operand_stack.push(StackValue::Int(5));
|
||||||
match frame_result {
|
match frame_result {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(err) => return Err(Error::StackFrameError(err, format!("in '{}', in class '{}'", method.name, class.get_classname().unwrap()))),
|
Err(err) => return Err(Error::StackFrameError(err, format!("in '{}', in class '{}'", method.name, class.get_classname().unwrap()))),
|
||||||
|
@ -328,7 +328,7 @@ impl JVM {
|
||||||
|
|
||||||
let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
|
let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
|
||||||
|
|
||||||
return Ok(JVMCallbackOperation::ReturnFrame(Value::Int(int)));
|
return Ok(JVMCallbackOperation::ReturnFrame(StackValue::Int(int)));
|
||||||
}
|
}
|
||||||
Instruction::ReturnVoid() => {
|
Instruction::ReturnVoid() => {
|
||||||
let expected_type = AbstractTypeDescription {
|
let expected_type = AbstractTypeDescription {
|
||||||
|
@ -346,22 +346,22 @@ impl JVM {
|
||||||
Instruction::StoreLocalInt0() => {
|
Instruction::StoreLocalInt0() => {
|
||||||
let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
|
let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))?;
|
||||||
|
|
||||||
wrap_stackframe_error(class, method, frame.store_local(0, Value::Int(int)))?;
|
wrap_stackframe_error(class, method, frame.store_local(0, StackValue::Int(int)))?;
|
||||||
},
|
},
|
||||||
Instruction::StoreLocalInt1() => {
|
Instruction::StoreLocalInt1() => {
|
||||||
let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(1))?;
|
let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(1))?;
|
||||||
|
|
||||||
wrap_stackframe_error(class, method, frame.store_local(0, Value::Int(int)))?;
|
wrap_stackframe_error(class, method, frame.store_local(0, StackValue::Int(int)))?;
|
||||||
},
|
},
|
||||||
Instruction::StoreLocalInt2() => {
|
Instruction::StoreLocalInt2() => {
|
||||||
let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(2))?;
|
let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(2))?;
|
||||||
|
|
||||||
wrap_stackframe_error(class, method, frame.store_local(0, Value::Int(int)))?;
|
wrap_stackframe_error(class, method, frame.store_local(0, StackValue::Int(int)))?;
|
||||||
},
|
},
|
||||||
Instruction::StoreLocalInt3() => {
|
Instruction::StoreLocalInt3() => {
|
||||||
let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(3))?;
|
let int = wrap_stackframe_error(class, method, frame.operand_stack.pop_int(3))?;
|
||||||
|
|
||||||
wrap_stackframe_error(class, method, frame.store_local(0, Value::Int(int)))?;
|
wrap_stackframe_error(class, method, frame.store_local(0, StackValue::Int(int)))?;
|
||||||
},
|
},
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -379,7 +379,7 @@ impl JVM {
|
||||||
|
|
||||||
enum JVMCallbackOperation {
|
enum JVMCallbackOperation {
|
||||||
PopFrame(),
|
PopFrame(),
|
||||||
ReturnFrame(Value),
|
ReturnFrame(StackValue),
|
||||||
PushFrame(StackFrame),
|
PushFrame(StackFrame),
|
||||||
LoadClass(String),
|
LoadClass(String),
|
||||||
InitClass(String),
|
InitClass(String),
|
||||||
|
@ -394,19 +394,19 @@ fn load_local_int(class: &JavaClassFile, method: &MethodInfo, frame: &mut StackF
|
||||||
Err(err) => return Err(Error::StackFrameError(err, format!("in '{}', in class '{}'", method.name, class.get_classname().unwrap()))),
|
Err(err) => return Err(Error::StackFrameError(err, format!("in '{}', in class '{}'", method.name, class.get_classname().unwrap()))),
|
||||||
};
|
};
|
||||||
|
|
||||||
let frame_result = frame.operand_stack.push(Value::Int(local_int));
|
let frame_result = frame.operand_stack.push(StackValue::Int(local_int));
|
||||||
match frame_result {
|
match frame_result {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(err) => return Err(Error::StackFrameError(err, format!("in '{}', in class '{}'", method.name, class.get_classname().unwrap()))),
|
Err(err) => return Err(Error::StackFrameError(err, format!("in '{}', in class '{}'", method.name, class.get_classname().unwrap()))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut VecDeque<Value>, argument_types: &Box<[AbstractTypeDescription]>, stack: &mut OperandStack) -> Result<(), Error> {
|
fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut VecDeque<StackValue>, argument_types: &Box<[AbstractTypeDescription]>, stack: &mut OperandStack) -> Result<(), Error> {
|
||||||
for argument_type in argument_types {
|
for argument_type in argument_types {
|
||||||
if argument_type.array_level != 0 {
|
if argument_type.array_level != 0 {
|
||||||
// TODO: Type checking
|
// TODO: Type checking
|
||||||
arguments.push_front(
|
arguments.push_front(
|
||||||
Value::Reference(wrap_stackframe_error(class, method, stack.pop_reference(0))?),
|
StackValue::Reference(wrap_stackframe_error(class, method, stack.pop_reference(0))?),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
match argument_type.kind {
|
match argument_type.kind {
|
||||||
|
@ -414,7 +414,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve
|
||||||
// TODO: Add better description
|
// TODO: Add better description
|
||||||
AbstractTypeKind::Byte() => {
|
AbstractTypeKind::Byte() => {
|
||||||
arguments.push_front(
|
arguments.push_front(
|
||||||
Value::Byte(
|
StackValue::Byte(
|
||||||
wrap_stackframe_error(
|
wrap_stackframe_error(
|
||||||
class,
|
class,
|
||||||
method,
|
method,
|
||||||
|
@ -425,7 +425,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve
|
||||||
},
|
},
|
||||||
AbstractTypeKind::Char() => {
|
AbstractTypeKind::Char() => {
|
||||||
arguments.push_front(
|
arguments.push_front(
|
||||||
Value::Char(
|
StackValue::Char(
|
||||||
wrap_stackframe_error(
|
wrap_stackframe_error(
|
||||||
class,
|
class,
|
||||||
method,
|
method,
|
||||||
|
@ -436,7 +436,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve
|
||||||
},
|
},
|
||||||
AbstractTypeKind::Double() => {
|
AbstractTypeKind::Double() => {
|
||||||
arguments.push_front(
|
arguments.push_front(
|
||||||
Value::Double1(
|
StackValue::Double1(
|
||||||
wrap_stackframe_error(
|
wrap_stackframe_error(
|
||||||
class,
|
class,
|
||||||
method,
|
method,
|
||||||
|
@ -445,7 +445,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
arguments.push_front(
|
arguments.push_front(
|
||||||
Value::Double0(
|
StackValue::Double0(
|
||||||
wrap_stackframe_error(
|
wrap_stackframe_error(
|
||||||
class,
|
class,
|
||||||
method,
|
method,
|
||||||
|
@ -456,7 +456,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve
|
||||||
},
|
},
|
||||||
AbstractTypeKind::Float() => {
|
AbstractTypeKind::Float() => {
|
||||||
arguments.push_front(
|
arguments.push_front(
|
||||||
Value::Float(
|
StackValue::Float(
|
||||||
wrap_stackframe_error(
|
wrap_stackframe_error(
|
||||||
class,
|
class,
|
||||||
method,
|
method,
|
||||||
|
@ -467,7 +467,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve
|
||||||
},
|
},
|
||||||
AbstractTypeKind::Int() => {
|
AbstractTypeKind::Int() => {
|
||||||
arguments.push_front(
|
arguments.push_front(
|
||||||
Value::Int(
|
StackValue::Int(
|
||||||
wrap_stackframe_error(
|
wrap_stackframe_error(
|
||||||
class,
|
class,
|
||||||
method,
|
method,
|
||||||
|
@ -478,7 +478,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve
|
||||||
},
|
},
|
||||||
AbstractTypeKind::Long() => {
|
AbstractTypeKind::Long() => {
|
||||||
arguments.push_front(
|
arguments.push_front(
|
||||||
Value::Long1(
|
StackValue::Long1(
|
||||||
wrap_stackframe_error(
|
wrap_stackframe_error(
|
||||||
class,
|
class,
|
||||||
method,
|
method,
|
||||||
|
@ -487,7 +487,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
arguments.push_front(
|
arguments.push_front(
|
||||||
Value::Long0(
|
StackValue::Long0(
|
||||||
wrap_stackframe_error(
|
wrap_stackframe_error(
|
||||||
class,
|
class,
|
||||||
method,
|
method,
|
||||||
|
@ -499,7 +499,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve
|
||||||
AbstractTypeKind::Classname(ref name) => {
|
AbstractTypeKind::Classname(ref name) => {
|
||||||
// TODO: Type checking
|
// TODO: Type checking
|
||||||
arguments.push_front(
|
arguments.push_front(
|
||||||
Value::Reference(
|
StackValue::Reference(
|
||||||
wrap_stackframe_error(
|
wrap_stackframe_error(
|
||||||
class,
|
class,
|
||||||
method,
|
method,
|
||||||
|
@ -510,7 +510,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve
|
||||||
},
|
},
|
||||||
AbstractTypeKind::Short() => {
|
AbstractTypeKind::Short() => {
|
||||||
arguments.push_front(
|
arguments.push_front(
|
||||||
Value::Short(
|
StackValue::Short(
|
||||||
wrap_stackframe_error(
|
wrap_stackframe_error(
|
||||||
class,
|
class,
|
||||||
method,
|
method,
|
||||||
|
@ -521,7 +521,7 @@ fn fill_arguments(class: &JavaClassFile, method: &MethodInfo, arguments: &mut Ve
|
||||||
},
|
},
|
||||||
AbstractTypeKind::Boolean() => {
|
AbstractTypeKind::Boolean() => {
|
||||||
arguments.push_front(
|
arguments.push_front(
|
||||||
Value::Boolean(
|
StackValue::Boolean(
|
||||||
wrap_stackframe_error(
|
wrap_stackframe_error(
|
||||||
class,
|
class,
|
||||||
method,
|
method,
|
||||||
|
|
|
@ -9,7 +9,7 @@ mod heap_area;
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
|
||||||
use crate::stackframe::Value;
|
use crate::stackframe::StackValue;
|
||||||
use crate::classfile::JavaClassFile;
|
use crate::classfile::JavaClassFile;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::classfile::{ JavaClassFile, AttributeData, AbstractTypeDescription };
|
||||||
use crate::heap_area::ObjectReference;
|
use crate::heap_area::ObjectReference;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum Value {
|
pub enum StackValue {
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
Byte(u8),
|
Byte(u8),
|
||||||
Char(u16),
|
Char(u16),
|
||||||
|
@ -18,13 +18,13 @@ pub enum Value {
|
||||||
Empty(),
|
Empty(),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Value {
|
impl StackValue {
|
||||||
fn default_for(t: AbstractTypeDescription) -> Self {
|
fn default_for(t: AbstractTypeDescription) -> Self {
|
||||||
match t {
|
match t {
|
||||||
AbstractTypeDescription::Void() => unreachable!(),
|
AbstractTypeDescription::Void() => unreachable!(),
|
||||||
AbstractTypeDescription::Byte() => Value::Byte(0),
|
AbstractTypeDescription::Byte() => StackValue::Byte(0),
|
||||||
AbstractTypeDescription::Char() => Value::Char(0),
|
AbstractTypeDescription::Char() => StackValue::Char(0),
|
||||||
AbstractTypeDescription::Double() => Value::Double(0),
|
AbstractTypeDescription::Double() => StackValue::Double(0),
|
||||||
AbstractTypeDescription::Float() => ,
|
AbstractTypeDescription::Float() => ,
|
||||||
AbstractTypeDescription::Int() => ,
|
AbstractTypeDescription::Int() => ,
|
||||||
AbstractTypeDescription::Long() => ,
|
AbstractTypeDescription::Long() => ,
|
||||||
|
@ -37,7 +37,7 @@ impl Value {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct OperandStack {
|
pub struct OperandStack {
|
||||||
stack: Box<[Value]>,
|
stack: Box<[StackValue]>,
|
||||||
depth: u16,
|
depth: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,12 +50,12 @@ pub enum Error {
|
||||||
impl OperandStack {
|
impl OperandStack {
|
||||||
fn new(size: u16) -> Self {
|
fn new(size: u16) -> Self {
|
||||||
return OperandStack {
|
return OperandStack {
|
||||||
stack: vec![Value::Empty(); size.into()].into_boxed_slice(),
|
stack: vec![StackValue::Empty(); size.into()].into_boxed_slice(),
|
||||||
depth: 0,
|
depth: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(&mut self, value: Value) -> Result<(), Error> {
|
pub fn push(&mut self, value: StackValue) -> Result<(), Error> {
|
||||||
if self.depth as usize == self.stack.len() {
|
if self.depth as usize == self.stack.len() {
|
||||||
return Err(Error::PushError(format!("Trying to push onto full operand stack, capacity: {}, value: {:?}", self.depth, value)))
|
return Err(Error::PushError(format!("Trying to push onto full operand stack, capacity: {}, value: {:?}", self.depth, value)))
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ impl OperandStack {
|
||||||
let value = self.stack[absolute_index];
|
let value = self.stack[absolute_index];
|
||||||
self.depth -= 1;
|
self.depth -= 1;
|
||||||
match value {
|
match value {
|
||||||
Value::Boolean(b) => Ok(b),
|
StackValue::Boolean(b) => Ok(b),
|
||||||
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Boolean but found '{:?}'", index, value)))
|
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Boolean but found '{:?}'", index, value)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ impl OperandStack {
|
||||||
let absolute_index = self.depth as usize - 1 - index;
|
let absolute_index = self.depth as usize - 1 - index;
|
||||||
let value = self.stack[absolute_index];
|
let value = self.stack[absolute_index];
|
||||||
match value {
|
match value {
|
||||||
Value::Byte(b) => Ok(b),
|
StackValue::Byte(b) => Ok(b),
|
||||||
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Byte but found '{:?}'", index, value)))
|
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Byte but found '{:?}'", index, value)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ impl OperandStack {
|
||||||
let value = self.stack[absolute_index];
|
let value = self.stack[absolute_index];
|
||||||
self.depth -= 1;
|
self.depth -= 1;
|
||||||
match value {
|
match value {
|
||||||
Value::Char(c) => Ok(c),
|
StackValue::Char(c) => Ok(c),
|
||||||
_ => 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 Char but found '{:?}'", index, value)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ impl OperandStack {
|
||||||
let value = self.stack[absolute_index];
|
let value = self.stack[absolute_index];
|
||||||
self.depth -= 1;
|
self.depth -= 1;
|
||||||
match value {
|
match value {
|
||||||
Value::Short(s) => Ok(s),
|
StackValue::Short(s) => Ok(s),
|
||||||
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Short but found '{:?}'", index, value)))
|
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Short but found '{:?}'", index, value)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ impl OperandStack {
|
||||||
let value = self.stack[absolute_index];
|
let value = self.stack[absolute_index];
|
||||||
self.depth -= 1;
|
self.depth -= 1;
|
||||||
match value {
|
match value {
|
||||||
Value::Int(i) => Ok(i),
|
StackValue::Int(i) => Ok(i),
|
||||||
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Int but found '{:?}'", index, value)))
|
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Int but found '{:?}'", index, value)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ impl OperandStack {
|
||||||
let value = self.stack[absolute_index];
|
let value = self.stack[absolute_index];
|
||||||
self.depth -= 1;
|
self.depth -= 1;
|
||||||
match value {
|
match value {
|
||||||
Value::Float(f) => Ok(f),
|
StackValue::Float(f) => Ok(f),
|
||||||
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Float but found '{:?}'", index, value)))
|
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Float but found '{:?}'", index, value)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ impl OperandStack {
|
||||||
let value = self.stack[absolute_index];
|
let value = self.stack[absolute_index];
|
||||||
self.depth -= 1;
|
self.depth -= 1;
|
||||||
match value {
|
match value {
|
||||||
Value::Reference(o) => Ok(o),
|
StackValue::Reference(o) => Ok(o),
|
||||||
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Reference but found '{:?}'", index, value)))
|
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Reference but found '{:?}'", index, value)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ impl OperandStack {
|
||||||
let value = self.stack[absolute_index];
|
let value = self.stack[absolute_index];
|
||||||
self.depth -= 1;
|
self.depth -= 1;
|
||||||
match value {
|
match value {
|
||||||
Value::ReturnAddress(a) => Ok(a),
|
StackValue::ReturnAddress(a) => Ok(a),
|
||||||
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected ReturnAddress but found '{:?}'", index, value)))
|
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected ReturnAddress but found '{:?}'", index, value)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ impl OperandStack {
|
||||||
let value = self.stack[absolute_index];
|
let value = self.stack[absolute_index];
|
||||||
self.depth -= 1;
|
self.depth -= 1;
|
||||||
match value {
|
match value {
|
||||||
Value::Double0(a) => Ok(a),
|
StackValue::Double0(a) => Ok(a),
|
||||||
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Double0 but found '{:?}'", index, value)))
|
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Double0 but found '{:?}'", index, value)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ impl OperandStack {
|
||||||
let value = self.stack[absolute_index];
|
let value = self.stack[absolute_index];
|
||||||
self.depth -= 1;
|
self.depth -= 1;
|
||||||
match value {
|
match value {
|
||||||
Value::Double1(a) => Ok(a),
|
StackValue::Double1(a) => Ok(a),
|
||||||
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Double1 but found '{:?}'", index, value)))
|
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Double1 but found '{:?}'", index, value)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ impl OperandStack {
|
||||||
let value = self.stack[absolute_index];
|
let value = self.stack[absolute_index];
|
||||||
self.depth -= 1;
|
self.depth -= 1;
|
||||||
match value {
|
match value {
|
||||||
Value::Long0(a) => Ok(a),
|
StackValue::Long0(a) => Ok(a),
|
||||||
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Long0 but found '{:?}'", index, value)))
|
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Long0 but found '{:?}'", index, value)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ impl OperandStack {
|
||||||
let value = self.stack[absolute_index];
|
let value = self.stack[absolute_index];
|
||||||
self.depth -= 1;
|
self.depth -= 1;
|
||||||
match value {
|
match value {
|
||||||
Value::Long1(a) => Ok(a),
|
StackValue::Long1(a) => Ok(a),
|
||||||
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Long1 but found '{:?}'", index, value)))
|
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function operand stack, expected Long1 but found '{:?}'", index, value)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,7 +191,7 @@ impl OperandStack {
|
||||||
let lower_bytes = self.stack[absolute_index + 1];
|
let lower_bytes = self.stack[absolute_index + 1];
|
||||||
self.depth -= 2;
|
self.depth -= 2;
|
||||||
match (higher_bytes, lower_bytes) {
|
match (higher_bytes, lower_bytes) {
|
||||||
(Value::Double0(hi), Value::Double1(lo)) => {
|
(StackValue::Double0(hi), StackValue::Double1(lo)) => {
|
||||||
let v: u64 = ((hi as u64) << 32) | lo as u64;
|
let v: u64 = ((hi as u64) << 32) | lo as u64;
|
||||||
Ok(
|
Ok(
|
||||||
f64::from_bits(v)
|
f64::from_bits(v)
|
||||||
|
@ -207,7 +207,7 @@ impl OperandStack {
|
||||||
let lower_bytes = self.stack[absolute_index + 1];
|
let lower_bytes = self.stack[absolute_index + 1];
|
||||||
self.depth -= 2;
|
self.depth -= 2;
|
||||||
match (higher_bytes, lower_bytes) {
|
match (higher_bytes, lower_bytes) {
|
||||||
(Value::Long0(hi), Value::Long1(lo)) => {
|
(StackValue::Long0(hi), StackValue::Long1(lo)) => {
|
||||||
Ok(((hi as u64) << 32) | lo as u64)
|
Ok(((hi as u64) << 32) | lo as u64)
|
||||||
},
|
},
|
||||||
_ => Err(Error::LocalError(format!("Mismatched types at index {} of the function operand stack, expected (Long0, Long1) but found '{:?}'", index, (higher_bytes, lower_bytes))))
|
_ => Err(Error::LocalError(format!("Mismatched types at index {} of the function operand stack, expected (Long0, Long1) but found '{:?}'", index, (higher_bytes, lower_bytes))))
|
||||||
|
@ -217,7 +217,7 @@ impl OperandStack {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StackFrame {
|
pub struct StackFrame {
|
||||||
pub locals: Box<[Value]>,
|
pub locals: Box<[StackValue]>,
|
||||||
pub operand_stack: OperandStack,
|
pub operand_stack: OperandStack,
|
||||||
pub class_index: usize,
|
pub class_index: usize,
|
||||||
pub method_index: u16,
|
pub method_index: u16,
|
||||||
|
@ -225,13 +225,13 @@ pub struct StackFrame {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StackFrame {
|
impl StackFrame {
|
||||||
pub fn new(classfile: &JavaClassFile, class_index: usize, method_index: u16, arguments: &[Value]) -> Self {
|
pub fn new(classfile: &JavaClassFile, class_index: usize, method_index: u16, arguments: &[StackValue]) -> Self {
|
||||||
let method_info = &classfile.methods[method_index as usize];
|
let method_info = &classfile.methods[method_index as usize];
|
||||||
let code_data = match &method_info.attributes[method_info.code_attribute_index].data {
|
let code_data = match &method_info.attributes[method_info.code_attribute_index].data {
|
||||||
AttributeData::Code(data) => data,
|
AttributeData::Code(data) => data,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
let mut locals = vec![Value::Empty(); code_data.max_locals.into()].into_boxed_slice();
|
let mut locals = vec![StackValue::Empty(); code_data.max_locals.into()].into_boxed_slice();
|
||||||
|
|
||||||
assert!(locals.len() >= arguments.len());
|
assert!(locals.len() >= arguments.len());
|
||||||
|
|
||||||
|
@ -251,12 +251,12 @@ impl StackFrame {
|
||||||
pub fn load_local_int(&self, index: u16) -> Result<i32, Error> {
|
pub fn load_local_int(&self, index: u16) -> Result<i32, Error> {
|
||||||
let local = self.locals[index as usize];
|
let local = self.locals[index as usize];
|
||||||
match local {
|
match local {
|
||||||
Value::Int(i) => Ok(i),
|
StackValue::Int(i) => Ok(i),
|
||||||
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function locals, expected Int but found '{:?}'", index, local)))
|
_ => Err(Error::LocalError(format!("Mismatched type at index {} of the function locals, expected Int but found '{:?}'", index, local)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn store_local(&mut self, index: u16, value: Value) -> Result<(), Error> {
|
pub fn store_local(&mut self, index: u16, value: StackValue) -> Result<(), Error> {
|
||||||
let field = self.locals.get_mut(index as usize);
|
let field = self.locals.get_mut(index as usize);
|
||||||
match field {
|
match field {
|
||||||
Some(f) => {
|
Some(f) => {
|
||||||
|
|
Loading…
Reference in a new issue