Skip to content

Commit

Permalink
Merge pull request #106 from cmjava2023/fix/int-empire
Browse files Browse the repository at this point in the history
fix(executor): remove {byte,short,char,bool} from {Stack,LocalVars}
  • Loading branch information
Kerreytsugo authored Jan 10, 2024
2 parents 5254c58 + 6e5c86d commit dce13c0
Show file tree
Hide file tree
Showing 4 changed files with 290 additions and 517 deletions.
16 changes: 8 additions & 8 deletions src/class/builtin_classes/print_stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,9 @@ fn println(frame: &mut Frame) -> RustMethodReturn {

fn println_boolean(frame: &mut Frame) -> RustMethodReturn {
let boolean = frame.local_variables.get(1);
let boolean: u8 = match boolean {
VariableValueOrValue::Boolean(b) => b,
_ => panic!("local variables have boolean to print at index 1"),
let boolean = match boolean {
VariableValueOrValue::Int(b) => b,
_ => panic!("local variables have int (boolean) to print at index 1"),
};
match boolean {
0 => println!("false"),
Expand All @@ -144,13 +144,13 @@ fn println_boolean(frame: &mut Frame) -> RustMethodReturn {

fn println_char(frame: &mut Frame) -> RustMethodReturn {
let c = frame.local_variables.get(1);
let c: u16 = match c {
VariableValueOrValue::Char(c) => c,
_ => panic!("local variables have char to print at index 1"),
let c = match c {
VariableValueOrValue::Int(c) => c,
_ => panic!("local variables have int (char) to print at index 1"),
};
println!(
"{}",
char::from_u32(c.into()).unwrap_or(char::REPLACEMENT_CHARACTER)
char::from_u32(c as u32).unwrap_or(char::REPLACEMENT_CHARACTER)
);

RustMethodReturn::Void
Expand Down Expand Up @@ -180,7 +180,7 @@ fn println_float(frame: &mut Frame) -> RustMethodReturn {

fn println_int(frame: &mut Frame) -> RustMethodReturn {
let int = frame.local_variables.get(1);
let int: i32 = int.as_computation_int().unwrap();
let int: i32 = int.try_into().unwrap();
println!("{}", int);

RustMethodReturn::Void
Expand Down
101 changes: 61 additions & 40 deletions src/executor/frame_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,13 @@ use crate::{
pub enum StackValue {
// Primitive Types
// Integral Types
Byte(i8),
Short(i16),
/// Covers int, byte, short, bool, char
Int(i32),
Long(i64),
// UTF-16 encoded Unicode Code point in the Basic Multilingual Plane
Char(u16),
// Floating-Point Types
Float(f32),
Double(f64),
// Other
/// Encodes false as 0, true as 1.
///
/// This is according to [the Java VM Spec](
/// https://docs.oracle.com/javase/specs/jvms/se8/html/
/// jvms-2.html#jvms-2.3.4
/// )
Boolean(u8),
/// used for in-method jumps,
/// therefor an offset works.
/// Encodes an absolute position.
Expand Down Expand Up @@ -54,35 +44,14 @@ impl StackValue {

pub fn type_name(&self) -> &'static str {
match self {
StackValue::Byte(_) => "byte",
StackValue::Short(_) => "short",
StackValue::Int(_) => "int",
StackValue::Long(_) => "long",
StackValue::Char(_) => "char",
StackValue::Float(_) => "float",
StackValue::Double(_) => "double",
StackValue::Boolean(_) => "boolean",
StackValue::ReturnAddress(_) => "return_address",
StackValue::Reference(_) => "reference",
}
}

pub fn as_computation_int(&self) -> Result<i32, RuntimeError> {
// int computional types according to
// https://docs.oracle.com/javase/specs/jvms/se8/html
// /jvms-2.html#jvms-2.11.1-320
Ok(match *self {
StackValue::Boolean(b) => b.into(),
StackValue::Byte(b) => b.into(),
StackValue::Char(c) => c.into(),
StackValue::Short(s) => s.into(),
StackValue::Int(i) => i,
_ => Err(RuntimeError::InvalidType {
expected: "int (computational type",
actual: self.type_name(),
})?,
})
}
}

#[derive(Debug)]
Expand Down Expand Up @@ -122,14 +91,14 @@ impl FrameStack {
impl From<FieldValue> for StackValue {
fn from(value: FieldValue) -> Self {
match value {
FieldValue::Byte(v) => StackValue::Byte(v),
FieldValue::Short(v) => StackValue::Short(v),
FieldValue::Byte(v) => StackValue::Int(v.into()),
FieldValue::Short(v) => StackValue::Int(v.into()),
FieldValue::Int(v) => StackValue::Int(v),
FieldValue::Long(v) => StackValue::Long(v),
FieldValue::Char(v) => StackValue::Char(v),
FieldValue::Char(v) => StackValue::Int(v.into()),
FieldValue::Float(v) => StackValue::Float(v),
FieldValue::Double(v) => StackValue::Double(v),
FieldValue::Boolean(v) => StackValue::Boolean(v),
FieldValue::Boolean(v) => StackValue::Int(v.into()),
FieldValue::Reference(v) => StackValue::Reference(v),
}
}
Expand All @@ -138,14 +107,10 @@ impl From<FieldValue> for StackValue {
impl From<VariableValueOrValue> for StackValue {
fn from(value: VariableValueOrValue) -> Self {
match value {
VariableValueOrValue::Byte(b) => StackValue::Byte(b),
VariableValueOrValue::Short(s) => StackValue::Short(s),
VariableValueOrValue::Int(i) => StackValue::Int(i),
VariableValueOrValue::Long(l) => StackValue::Long(l),
VariableValueOrValue::Char(c) => StackValue::Char(c),
VariableValueOrValue::Float(f) => StackValue::Float(f),
VariableValueOrValue::Double(d) => StackValue::Double(d),
VariableValueOrValue::Boolean(b) => StackValue::Boolean(b),
VariableValueOrValue::Reference(r) => StackValue::Reference(r),
VariableValueOrValue::ReturnAddress(a) => {
StackValue::ReturnAddress(a)
Expand All @@ -156,3 +121,59 @@ impl From<VariableValueOrValue> for StackValue {
}
}
}

impl TryFrom<StackValue> for i32 {
type Error = RuntimeError;

fn try_from(value: StackValue) -> Result<Self, Self::Error> {
match value {
StackValue::Int(i) => Ok(i),
_ => Err(RuntimeError::InvalidType {
expected: "int",
actual: value.type_name(),
}),
}
}
}

impl TryFrom<StackValue> for i64 {
type Error = RuntimeError;

fn try_from(value: StackValue) -> Result<Self, Self::Error> {
match value {
StackValue::Long(l) => Ok(l),
_ => Err(RuntimeError::InvalidType {
expected: "long",
actual: value.type_name(),
}),
}
}
}

impl TryFrom<StackValue> for f32 {
type Error = RuntimeError;

fn try_from(value: StackValue) -> Result<Self, Self::Error> {
match value {
StackValue::Float(f) => Ok(f),
_ => Err(RuntimeError::InvalidType {
expected: "float",
actual: value.type_name(),
}),
}
}
}

impl TryFrom<StackValue> for f64 {
type Error = RuntimeError;

fn try_from(value: StackValue) -> Result<Self, Self::Error> {
match value {
StackValue::Double(d) => Ok(d),
_ => Err(RuntimeError::InvalidType {
expected: "double",
actual: value.type_name(),
}),
}
}
}
Loading

0 comments on commit dce13c0

Please sign in to comment.