Skip to content

Commit

Permalink
Introduce operations on float
Browse files Browse the repository at this point in the history
  • Loading branch information
hextriclosan committed Oct 9, 2024
1 parent 3fddc3f commit 5a8bd89
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 1 deletion.
6 changes: 5 additions & 1 deletion jdescriptor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub fn default_value(type_descriptor: &TypeDescriptor) -> Vec<i32> {
match type_descriptor {
Byte | Char | Int | Short | Boolean => vec![0],
Long => vec![0, 0],
Float => todo!(),
Float => from_f32(0.0),
Double => todo!(),
Void => panic!("field can't be a void type"),
Array(_, _) => vec![0],
Expand Down Expand Up @@ -176,6 +176,10 @@ impl Display for DescriptorError {
}
}

fn from_f32(value: f32) -> Vec<i32> {
vec![value.to_bits() as i32]
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
15 changes: 15 additions & 0 deletions tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,15 @@ fn should_do_trivial_reflection() {
assert_eq!(2578, get_int(last_frame_value))
}

#[test]
fn should_do_subtraction_with_floats() {
let mut vm = VM::new("std");
let last_frame_value = vm
.run("samples.arithmetics.sub.floats.SubFloats")
.unwrap();
assert_eq!(-998.9, get_float(last_frame_value))
}

fn get_int(locals: Option<Vec<i32>>) -> i32 {
*locals.unwrap().last().unwrap()
}
Expand All @@ -294,3 +303,9 @@ fn get_long(locals_opt: Option<Vec<i32>>) -> i64 {

((high as i64) << 32) | (low as i64)
}

fn get_float(locals: Option<Vec<i32>>) -> f32 {
let value = *locals.unwrap().last().unwrap();

f32::from_bits(value as u32)
}
9 changes: 9 additions & 0 deletions tests/test_data/SubFloats.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package samples.arithmetics.sub.floats;

public class SubFloats {
public static void main(String[] args) {
float first = 1.1f;
int second = 1000;
float result = first - second;
}
}
Binary file not shown.
38 changes: 38 additions & 0 deletions vm/src/execution_engine/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,13 @@ impl Engine {
stack_frame.incr_pc();
println!("LLOAD_3 -> value={value}");
}
FLOAD_1 => {
let value = stack_frame.get_local(1);
stack_frame.push(value);

stack_frame.incr_pc();
println!("FLOAD_1 -> value={value}");
}
ALOAD_0 => {
let reference = stack_frame.get_local(0);
stack_frame.push(reference);
Expand Down Expand Up @@ -401,6 +408,20 @@ impl Engine {
let value = ((high as i64) << 32) | (low as i64);
println!("LSTORE_3 -> value={value}");
}
FSTORE_1 => {
let value = stack_frame.pop();
stack_frame.set_local(1, value);

stack_frame.incr_pc();
println!("FSTORE_1 -> value={value}");
}
FSTORE_3 => {
let value = stack_frame.pop();
stack_frame.set_local(3, value);

stack_frame.incr_pc();
println!("FSTORE_3 -> value={value}");
}
ASTORE_0 => {
let objectref = stack_frame.pop();
stack_frame.set_local(0, objectref);
Expand Down Expand Up @@ -543,6 +564,15 @@ impl Engine {
stack_frame.incr_pc();
println!("LSUB -> {a} - {b} = {result}");
}
FSUB => {
let b = stack_frame.pop_f32();
let a = stack_frame.pop_f32();
let result = a - b;
stack_frame.push_f32(result);

stack_frame.incr_pc();
println!("FSUB -> {a} - {b} = {result}");
}
IMUL => {
let b = stack_frame.pop();
let a = stack_frame.pop();
Expand Down Expand Up @@ -636,6 +666,14 @@ impl Engine {
stack_frame.incr_pc();
println!("I2L -> {low}L");
}
I2F => {
let value = stack_frame.pop() as f32;

stack_frame.push_f32(value);

stack_frame.incr_pc();
println!("I2F -> {value}F");
}
LCMP => {
let b = stack_frame.pop_i64();
let a = stack_frame.pop_i64();
Expand Down
10 changes: 10 additions & 0 deletions vm/src/stack/stack_frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,23 @@ impl<'a> StackFrame {
self.push(high);
}

pub(crate) fn push_f32(&mut self, value: f32) {
self.push(value.to_bits() as i32);
}

pub fn pop_i64(&mut self) -> i64 {
let high = self.pop();
let low = self.pop();

i32toi64(high, low)
}

pub fn pop_f32(&mut self) -> f32 {
let high = self.pop();

f32::from_bits(high as u32)
}

pub fn pop(&mut self) -> i32 {
self.operand_stack.pop().expect("Empty stack")
}
Expand Down

0 comments on commit 5a8bd89

Please sign in to comment.