Refactor to StackValue
This commit is contained in:
parent
6c0fbd179a
commit
4ee673d5ff
4 changed files with 58 additions and 59 deletions
|
@ -2,7 +2,7 @@ use crate::classfile::{ JavaClassFile, AttributeData, AbstractTypeDescription };
|
|||
use crate::heap_area::ObjectReference;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum Value {
|
||||
pub enum StackValue {
|
||||
Boolean(bool),
|
||||
Byte(u8),
|
||||
Char(u16),
|
||||
|
@ -18,13 +18,13 @@ pub enum Value {
|
|||
Empty(),
|
||||
}
|
||||
|
||||
impl Value {
|
||||
impl StackValue {
|
||||
fn default_for(t: AbstractTypeDescription) -> Self {
|
||||
match t {
|
||||
AbstractTypeDescription::Void() => unreachable!(),
|
||||
AbstractTypeDescription::Byte() => Value::Byte(0),
|
||||
AbstractTypeDescription::Char() => Value::Char(0),
|
||||
AbstractTypeDescription::Double() => Value::Double(0),
|
||||
AbstractTypeDescription::Byte() => StackValue::Byte(0),
|
||||
AbstractTypeDescription::Char() => StackValue::Char(0),
|
||||
AbstractTypeDescription::Double() => StackValue::Double(0),
|
||||
AbstractTypeDescription::Float() => ,
|
||||
AbstractTypeDescription::Int() => ,
|
||||
AbstractTypeDescription::Long() => ,
|
||||
|
@ -37,7 +37,7 @@ impl Value {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct OperandStack {
|
||||
stack: Box<[Value]>,
|
||||
stack: Box<[StackValue]>,
|
||||
depth: u16,
|
||||
}
|
||||
|
||||
|
@ -50,12 +50,12 @@ pub enum Error {
|
|||
impl OperandStack {
|
||||
fn new(size: u16) -> Self {
|
||||
return OperandStack {
|
||||
stack: vec![Value::Empty(); size.into()].into_boxed_slice(),
|
||||
stack: vec![StackValue::Empty(); size.into()].into_boxed_slice(),
|
||||
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() {
|
||||
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];
|
||||
self.depth -= 1;
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ impl OperandStack {
|
|||
let absolute_index = self.depth as usize - 1 - index;
|
||||
let value = self.stack[absolute_index];
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ impl OperandStack {
|
|||
let value = self.stack[absolute_index];
|
||||
self.depth -= 1;
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ impl OperandStack {
|
|||
let value = self.stack[absolute_index];
|
||||
self.depth -= 1;
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ impl OperandStack {
|
|||
let value = self.stack[absolute_index];
|
||||
self.depth -= 1;
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ impl OperandStack {
|
|||
let value = self.stack[absolute_index];
|
||||
self.depth -= 1;
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ impl OperandStack {
|
|||
let value = self.stack[absolute_index];
|
||||
self.depth -= 1;
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ impl OperandStack {
|
|||
let value = self.stack[absolute_index];
|
||||
self.depth -= 1;
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ impl OperandStack {
|
|||
let value = self.stack[absolute_index];
|
||||
self.depth -= 1;
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ impl OperandStack {
|
|||
let value = self.stack[absolute_index];
|
||||
self.depth -= 1;
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ impl OperandStack {
|
|||
let value = self.stack[absolute_index];
|
||||
self.depth -= 1;
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ impl OperandStack {
|
|||
let value = self.stack[absolute_index];
|
||||
self.depth -= 1;
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ impl OperandStack {
|
|||
let lower_bytes = self.stack[absolute_index + 1];
|
||||
self.depth -= 2;
|
||||
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;
|
||||
Ok(
|
||||
f64::from_bits(v)
|
||||
|
@ -207,7 +207,7 @@ impl OperandStack {
|
|||
let lower_bytes = self.stack[absolute_index + 1];
|
||||
self.depth -= 2;
|
||||
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)
|
||||
},
|
||||
_ => 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)]
|
||||
pub struct StackFrame {
|
||||
pub locals: Box<[Value]>,
|
||||
pub locals: Box<[StackValue]>,
|
||||
pub operand_stack: OperandStack,
|
||||
pub class_index: usize,
|
||||
pub method_index: u16,
|
||||
|
@ -225,13 +225,13 @@ pub struct 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 code_data = match &method_info.attributes[method_info.code_attribute_index].data {
|
||||
AttributeData::Code(data) => data,
|
||||
_ => 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());
|
||||
|
||||
|
@ -251,12 +251,12 @@ impl StackFrame {
|
|||
pub fn load_local_int(&self, index: u16) -> Result<i32, Error> {
|
||||
let local = self.locals[index as usize];
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
match field {
|
||||
Some(f) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue