From 74ec18e2e3af05993cde8b9ba919a093ac6819c2 Mon Sep 17 00:00:00 2001 From: Igor Rudenko Date: Fri, 20 Sep 2024 00:07:41 +0300 Subject: [PATCH 1/2] Add proper static initialization --- tests/integration_test.rs | 1 - vm/src/execution_engine/engine.rs | 16 ++++++++++++++++ vm/src/vm.rs | 9 --------- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 620896b1..80d1a5e7 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -154,7 +154,6 @@ fn should_do_class_static_initialization() { assert_eq!(257, get_int(last_frame_value)) } -#[ignore] #[test] fn should_do_class_static_initialization_multiple_classes() { let vm = VM::new( diff --git a/vm/src/execution_engine/engine.rs b/vm/src/execution_engine/engine.rs index ae2ea31b..40bcd94b 100644 --- a/vm/src/execution_engine/engine.rs +++ b/vm/src/execution_engine/engine.rs @@ -1,3 +1,4 @@ +use std::collections::HashSet; use crate::error::Error; use crate::execution_engine::opcode::*; use crate::heap::heap::Heap; @@ -20,6 +21,7 @@ impl<'a> Engine<'a> { let mut stack_frames = vec![method.new_stack_frame()]; let mut last_value: Option> = None; let mut current_class_name: String; + let mut static_set: HashSet = HashSet::new(); while !stack_frames.is_empty() { let stack_frame = stack_frames @@ -688,6 +690,20 @@ impl<'a> Engine<'a> { fieldref_constpool_index, )?; + //todo!! + //try call invoke static `":()V"` on `class_name` (it should be done only once) + if !static_set.contains(class_name.as_str()) { + static_set.insert(class_name.clone()); + if let Ok(clinit) = self.method_area.get_method_by_name_signature(class_name.as_str(), ":()V") { + stack_frame.advance_pc(-2); + let next_frame = clinit.new_stack_frame(); + //stack_frame.incr_pc(); //incr here because of borrowing problem + stack_frames.push(next_frame); + println!("!!!invoke -> {class_name}.:()V"); + continue; + } + } + let field = self .method_area .loaded_classes diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 029a4850..19238108 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -20,15 +20,6 @@ impl VM { let mut engine = Engine::new(&self.class_loader.method_area()); - for (class_name, java_class) in self.class_loader.method_area().loaded_classes.iter() { - if let Some(java_method) = java_class.methods.method_by_signature.get(":()V") { - println!( - "About to initialize java class {class_name} java_method={java_method:?}" - ); - engine.execute(java_method)?; //todo implement multiclass correct initialization order - } - } - engine.execute(main_method) } } From daf6dee8c08d46a49b1d4bb81c64adaa1b4ad39d Mon Sep 17 00:00:00 2001 From: Igor Rudenko Date: Fri, 20 Sep 2024 17:18:56 +0300 Subject: [PATCH 2/2] better --- jdescriptor/src/lib.rs | 4 +- src/main.rs | 5 +- tests/integration_test.rs | 57 +++++++++- tests/test_data/ClassA.class | Bin 0 -> 279 bytes tests/test_data/ClassACircular.class | Bin 0 -> 340 bytes tests/test_data/ClassB.class | Bin 0 -> 280 bytes tests/test_data/ClassBCircular.class | Bin 0 -> 341 bytes tests/test_data/ClassC.class | Bin 0 -> 442 bytes tests/test_data/ClassD.class | Bin 0 -> 360 bytes tests/test_data/ClassE.class | Bin 0 -> 342 bytes tests/test_data/Helper.class | Bin 0 -> 408 bytes .../StaticInitializationAdvanced.class | Bin 0 -> 432 bytes .../StaticInitializationAdvanced.java | 56 ++++++++++ .../StaticInitializationCircular.class | Bin 0 -> 398 bytes .../StaticInitializationCircular.java | 25 +++++ .../StaticInitializationWithinOneClass.class | Bin 0 -> 432 bytes .../StaticInitializationWithinOneClass.java | 15 +++ vm/src/execution_engine/engine.rs | 98 ++++++++++++++---- vm/src/heap/heap.rs | 6 +- vm/src/heap/java_instance.rs | 2 +- vm/src/method_area/method_area.rs | 2 +- vm/src/stack/stack_frame.rs | 1 - 22 files changed, 237 insertions(+), 34 deletions(-) create mode 100644 tests/test_data/ClassA.class create mode 100644 tests/test_data/ClassACircular.class create mode 100644 tests/test_data/ClassB.class create mode 100644 tests/test_data/ClassBCircular.class create mode 100644 tests/test_data/ClassC.class create mode 100644 tests/test_data/ClassD.class create mode 100644 tests/test_data/ClassE.class create mode 100644 tests/test_data/Helper.class create mode 100644 tests/test_data/StaticInitializationAdvanced.class create mode 100644 tests/test_data/StaticInitializationAdvanced.java create mode 100644 tests/test_data/StaticInitializationCircular.class create mode 100644 tests/test_data/StaticInitializationCircular.java create mode 100644 tests/test_data/StaticInitializationWithinOneClass.class create mode 100644 tests/test_data/StaticInitializationWithinOneClass.java diff --git a/jdescriptor/src/lib.rs b/jdescriptor/src/lib.rs index c54815e5..470bfca4 100644 --- a/jdescriptor/src/lib.rs +++ b/jdescriptor/src/lib.rs @@ -42,7 +42,7 @@ pub fn default_value(type_descriptor: &TypeDescriptor) -> Vec { Double => todo!(), Void => panic!("field can't be a void type"), Array(_, _) => vec![0], - Object(_) => todo!(), + Object(_) => vec![0], } } @@ -52,7 +52,7 @@ pub fn get_length(type_descriptor: &TypeDescriptor) -> usize { Long | Double => 2, Void => panic!("field can't be a void type"), Array(_, _) => 1, - Object(_) => todo!(), + Object(_) => 1, } } diff --git a/src/main.rs b/src/main.rs index 03b20720..b42596cf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,8 +46,5 @@ fn main() { } }; - println!( - "\nresult={:?}", - result.map_or_else(|| vec![], |v| v) - ); + println!("\nresult={:?}", result.map_or_else(|| vec![], |v| v)); } diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 80d1a5e7..f35cb1b7 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -24,7 +24,7 @@ fn should_do_adding_with_negative_longs() { vec!["tests/test_data/AdderNegativeLong.class"], "tests/test_data/std", ) - .unwrap(); + .unwrap(); let last_frame_value = vm.run("AdderNegativeLong").unwrap(); assert_eq!(-1990000000000000, get_long(last_frame_value)) } @@ -66,7 +66,7 @@ fn should_write_read_instance_fields_with_longs() { ], "tests/test_data/std", ) - .unwrap(); + .unwrap(); let last_frame_value = vm.run("InstanceFieldsUserLong").unwrap(); assert_eq!(4_380_866_642_760, get_long(last_frame_value)) } @@ -102,7 +102,7 @@ fn should_do_extreme_stack_operations_with_longs() { vec!["tests/test_data/ExtremeStackTestLong.class"], "tests/test_data/std", ) - .unwrap(); + .unwrap(); let last_frame_value = vm.run("ExtremeStackTestLong").unwrap(); assert_eq!(454, get_long(last_frame_value)) } @@ -138,7 +138,11 @@ fn should_do_arrays() { #[test] fn should_do_arrays_with_longs() { - let vm = VM::new(vec!["tests/test_data/ArrayLong.class"], "tests/test_data/std").unwrap(); + let vm = VM::new( + vec!["tests/test_data/ArrayLong.class"], + "tests/test_data/std", + ) + .unwrap(); let last_frame_value = vm.run("ArrayLong").unwrap(); assert_eq!(233646220932000, get_long(last_frame_value)) } @@ -169,6 +173,51 @@ fn should_do_class_static_initialization_multiple_classes() { assert_eq!(350, get_int(last_frame_value)) } +#[test] +fn should_do_class_static_initialization_within_one_class() { + let vm = VM::new( + vec!["tests/test_data/StaticInitializationWithinOneClass.class"], + "tests/test_data/std", + ) + .unwrap(); + let last_frame_value = vm.run("StaticInitializationWithinOneClass").unwrap(); + assert_eq!(100, get_int(last_frame_value)) +} + +#[test] +fn should_do_class_static_initialization_advanced() { + let vm = VM::new( + vec![ + "tests/test_data/StaticInitializationAdvanced.class", + "tests/test_data/ClassA.class", + "tests/test_data/ClassB.class", + "tests/test_data/ClassC.class", + "tests/test_data/ClassD.class", + "tests/test_data/ClassE.class", + "tests/test_data/Helper.class", + ], + "tests/test_data/std", + ) + .unwrap(); + let last_frame_value = vm.run("StaticInitializationAdvanced").unwrap(); + assert_eq!(826, get_int(last_frame_value)) +} + +#[test] +fn should_do_class_static_initialization_circular() { + let vm = VM::new( + vec![ + "tests/test_data/StaticInitializationCircular.class", + "tests/test_data/ClassACircular.class", + "tests/test_data/ClassBCircular.class", + ], + "tests/test_data/std", + ) + .unwrap(); + let last_frame_value = vm.run("StaticInitializationCircular").unwrap(); + assert_eq!(700, get_int(last_frame_value)) +} + fn get_int(locals: Option>) -> i32 { *locals.unwrap().last().unwrap() } diff --git a/tests/test_data/ClassA.class b/tests/test_data/ClassA.class new file mode 100644 index 0000000000000000000000000000000000000000..be418d6fd32a3f6ea2ce073419430789d160a0bb GIT binary patch literal 279 zcmYLEO>4qH6r2}7Vq&bR^wL71^rRm24~S3$LZP*XmfknXQdZUoCiZ_74}~831Nx)H zSrL1AJ3BM)&3k|QpI-no^g?*3`KU)|pecx#>QjxaDn7<9=~8EvpgA#xsiuNjfAAil zg}_G`p^b=IVpUl_2-;<(DwEBPwz)ta1@&Z|YeDzP6ne2;rF!$GQcI>a$?R!j_`2S1 zGCenr51y4NMlK(BO!2rM%`S(?{kR~R4$&=Nam?@=@?3P-eH{h8hAK*uc zJ;9jEOm$6lb@hDze0~9#;vj;Do{xTvEer_hQa!7&RpsOOHeVXu5(X14xxFOxPS5T` z1PFaZF@}f|y^G+BZJU literal 0 HcmV?d00001 diff --git a/tests/test_data/ClassB.class b/tests/test_data/ClassB.class new file mode 100644 index 0000000000000000000000000000000000000000..7c0b5441cb809503a3f41a4099975b0327627f02 GIT binary patch literal 280 zcmYL^&1wQc5QM8&YlB@u})AUP-qf{6#k`|LV|k;yLXkMAWO0y+2qK9txk zl3ZqLsy@1U&X?a4fC;(*9MoLYLp-2CXz$csjjT$)M$34olakOFo79x=gxbsN#)k*r zMG&Hikh7^(MKK{Xi&B*)nHg=j1ez1-(`>5=(ZZzqv-*y8zE-hi#~Ua1J~3EjRi5aX z5#Rq%CVi8BJaLP|`!Os%tmMTDveRPK>~&NN<9c3`~W{n z>q^@NR`6KEQs4OAHz9byka%<0o#>Ep*T60ZKg9n~5=k`i z1NjyDk-iMi z7?O?V$bd=6rBIJzYQcb|bvcGq!)cDP*ubWNyo~~iMC&R(n{_F9&m> zlo)C*S8k+uCVckejV349p?#Zr~9y-h?eX<05p@gAIul@!JP1OFWZ6pZ;svj_JitKxd>;iTX&#$oGuywmY WdEH<$CYNZ6GWk@fU7e%}9Q*>Z=21Za literal 0 HcmV?d00001 diff --git a/tests/test_data/ClassD.class b/tests/test_data/ClassD.class new file mode 100644 index 0000000000000000000000000000000000000000..9a5c55fac75de6c7437ac14063050a1fadcf2b94 GIT binary patch literal 360 zcmYLF%Sr=55Uk$BY_eHRd_TY!Uets6fgorkxFC9nQTw1QA49`GG<%pnJ;Q#2^}BZ5X)E*-@tNFToKyE zTuz{fP#B_*4nAZQLM>7ua-{HSvaV~Zr P3G9h*UnCoXJ#78}noB~y literal 0 HcmV?d00001 diff --git a/tests/test_data/ClassE.class b/tests/test_data/ClassE.class new file mode 100644 index 0000000000000000000000000000000000000000..bc3fe574035d65a59da4912598c9e4c5fd8ed123 GIT binary patch literal 342 zcmYLF%T5A85UgI1WgiNHuZxL#5cD8FKulzngv96pQ0bmM z2B;(O5yprRb1gBVC=xj2x1XswAGLN&=VMQGe=tL|nm zshU2B)G$-;OSAF}$N6k3)lfVBc)TS7@TeMV`8jr)q_|;Z*9N^Ja`g8g#LTAMoW$AyCKhBDItOmMNJFM^_J!)z6BNemsJXy#zR!P77 z4i0F##_tNWOWUmKyf!vCX|M{3mbf3jL4DiVJ?r= h!q*dXwc#wM$BgY2bDv$wwZj*RT$GPX8b2HyRpI-p3PW#Aq|ga-Hl8$$-y zpRX2y=t)hk{bzEf_ff+R{eyl6nEnZhCF-h_8Rf+32iO}G;OgrDTQAt;AO67&dK~u*fn+b(UfgE~$ESQihZdX>Q=? E7c;q19smFU literal 0 HcmV?d00001 diff --git a/tests/test_data/StaticInitializationAdvanced.java b/tests/test_data/StaticInitializationAdvanced.java new file mode 100644 index 00000000..a8dbc0d1 --- /dev/null +++ b/tests/test_data/StaticInitializationAdvanced.java @@ -0,0 +1,56 @@ +public class StaticInitializationAdvanced { + public static void main(String[] args) { + int classCWithHelperNonStaticGetter = ClassC.staticField; + + int classDWithHelperStaticGetter = ClassD.staticField; + + ClassC.staticField = 600; + int classCIsModified = ClassC.staticField; + + int classEAsSumOfCAndD = ClassE.staticField; + + int result = classCWithHelperNonStaticGetter + classDWithHelperStaticGetter * classCIsModified / classEAsSumOfCAndD; + } +} + +class ClassC { + static Helper helper; + static int staticField; + + static { + helper = new Helper(500); + staticField = 150 + helper.calculateNonStaticFieldValue(); + } +} + +class ClassD { + static int staticField; + + static { + staticField = Helper.calculateStaticFieldValue(); + } +} + +class ClassE { + static int staticField; + + static { + staticField = ClassC.staticField + ClassD.staticField; + } +} + +class Helper { + private final int value; + + Helper(int value) { + this.value = value; + } + + static int calculateStaticFieldValue() { + return 250; + } + + public int calculateNonStaticFieldValue() { + return value; + } +} diff --git a/tests/test_data/StaticInitializationCircular.class b/tests/test_data/StaticInitializationCircular.class new file mode 100644 index 0000000000000000000000000000000000000000..801a4aa06d5eb4eb8fefe2ba67797a3960b50dba GIT binary patch literal 398 zcmaKoO;5r=5Qg9Br!D0}{7l3HH{c-gERskQ5)z_^8ZKVkmWC`TZPFGG{wukdc<=}K zql~j84LA4j&g{ADj?QSXCL&;ouZ!oGbK}tp>;X4)$n= b`u$bsb$qb2_eGP{;tAUDSos5N&~Whw&YMwU literal 0 HcmV?d00001 diff --git a/tests/test_data/StaticInitializationCircular.java b/tests/test_data/StaticInitializationCircular.java new file mode 100644 index 00000000..6f301dcd --- /dev/null +++ b/tests/test_data/StaticInitializationCircular.java @@ -0,0 +1,25 @@ + + +public class StaticInitializationCircular { + public static void main(String[] args) { + int classA = ClassACircular.staticField; + int classB = ClassBCircular.staticField; + int result = classA + classB; + } +} + +class ClassACircular { + static int staticField; + + static { + staticField = 100 + ClassBCircular.staticField; + } +} + +class ClassBCircular { + static int staticField; + + static { + staticField = 300 + ClassACircular.staticField; + } +} diff --git a/tests/test_data/StaticInitializationWithinOneClass.class b/tests/test_data/StaticInitializationWithinOneClass.class new file mode 100644 index 0000000000000000000000000000000000000000..5fb821618d4898e39cec38e913e688c61d58eb7a GIT binary patch literal 432 zcmaixKTiTd5XIjB$8iVpM~#Jvg*F0()P{?NBqSt63Jexj%dx>F$CAK7;kQx?6AM3p zAIkWa5J_xoW@dMP@9oU)*Z0RKfLk1g$RO(@SAvJUpgL0<)k>6|wg%&wj#EKCGS;Lw zf^5Ap3Q$1cBP^kalHg*Ps?@|i0!Ag~nTv&eFzJ)A1FJiUTCD`d)fVa+olFGM6XZIJ zi567)#_GHEe5{xEYMgKL2b%!>YomE(!yup8kAMN=v nStNmWlpw77kHSfB8O6gx2e}e+PGqFR0865opA9PR5 literal 0 HcmV?d00001 diff --git a/tests/test_data/StaticInitializationWithinOneClass.java b/tests/test_data/StaticInitializationWithinOneClass.java new file mode 100644 index 00000000..695291fd --- /dev/null +++ b/tests/test_data/StaticInitializationWithinOneClass.java @@ -0,0 +1,15 @@ + + +public class StaticInitializationWithinOneClass { + static int staticField; + + static { + int xxx = 1337; + staticField = xxx; + } + + public static void main(String[] args) { + staticField = 100; + int result = staticField; + } +} diff --git a/vm/src/execution_engine/engine.rs b/vm/src/execution_engine/engine.rs index 40bcd94b..27da625a 100644 --- a/vm/src/execution_engine/engine.rs +++ b/vm/src/execution_engine/engine.rs @@ -1,4 +1,3 @@ -use std::collections::HashSet; use crate::error::Error; use crate::execution_engine::opcode::*; use crate::heap::heap::Heap; @@ -10,6 +9,7 @@ use crate::util::{ get_class_name_by_cpool_class_index, get_cpool_integer, get_cpool_long_double, Primitive, }; use jdescriptor::get_length; +use std::collections::HashSet; pub(crate) struct Engine<'a> { method_area: &'a MethodArea, @@ -17,7 +17,10 @@ pub(crate) struct Engine<'a> { } impl<'a> Engine<'a> { - pub(crate) fn execute(&mut self, method: &JavaMethod) -> crate::error::Result>> { + pub(crate) fn execute( + &mut self, + method: &JavaMethod, + ) -> crate::error::Result>> { let mut stack_frames = vec![method.new_stack_frame()]; let mut last_value: Option> = None; let mut current_class_name: String; @@ -247,7 +250,10 @@ impl<'a> Engine<'a> { stack_frame.push(value[0]); stack_frame.incr_pc(); - println!("IALOAD -> arrayref={arrayref}, index={index}, value={}", value[0]); + println!( + "IALOAD -> arrayref={arrayref}, index={index}, value={}", + value[0] + ); } LALOAD => { let index = stack_frame.pop(); @@ -269,7 +275,10 @@ impl<'a> Engine<'a> { stack_frame.push(objref[0]); stack_frame.incr_pc(); - println!("AALOAD -> arrayref={arrayref}, index={index}, objref={}", objref[0]); + println!( + "AALOAD -> arrayref={arrayref}, index={index}, objref={}", + objref[0] + ); } ISTORE => { stack_frame.incr_pc(); @@ -287,7 +296,7 @@ impl<'a> Engine<'a> { let low = stack_frame.pop(); stack_frame.set_local(pos, low); - stack_frame.set_local(pos+1, high); + stack_frame.set_local(pos + 1, high); stack_frame.incr_pc(); let value = i32toi64(high, low); @@ -666,11 +675,13 @@ impl<'a> Engine<'a> { } RETURN => { println!("RETURN -> stack_frame.locals={:?}", stack_frame.locals); - last_value = Some(stack_frames - .last() - .ok_or(Error::new_execution("Error getting stack last value"))? - .locals - .clone()); + last_value = Some( + stack_frames + .last() + .ok_or(Error::new_execution("Error getting stack last value"))? + .locals + .clone(), + ); stack_frames.pop(); // Return from method, pop the current frame // add more logic here @@ -690,16 +701,17 @@ impl<'a> Engine<'a> { fieldref_constpool_index, )?; - //todo!! - //try call invoke static `":()V"` on `class_name` (it should be done only once) + //calling static block if needed, todo: move me to single place if !static_set.contains(class_name.as_str()) { static_set.insert(class_name.clone()); - if let Ok(clinit) = self.method_area.get_method_by_name_signature(class_name.as_str(), ":()V") { + if let Ok(clinit) = self + .method_area + .get_method_by_name_signature(class_name.as_str(), ":()V") + { stack_frame.advance_pc(-2); let next_frame = clinit.new_stack_frame(); - //stack_frame.incr_pc(); //incr here because of borrowing problem stack_frames.push(next_frame); - println!("!!!invoke -> {class_name}.:()V"); + println!(" -> {class_name}.:()V"); continue; } } @@ -715,9 +727,16 @@ impl<'a> Engine<'a> { .unwrap() .borrow(); - field.raw_value().iter().rev().for_each(|x| stack_frame.push(*x)); + field + .raw_value() + .iter() + .rev() + .for_each(|x| stack_frame.push(*x)); - println!("GETSTATIC -> {class_name}.{field_name} is {:?}", field.raw_value()); + println!( + "GETSTATIC -> {class_name}.{field_name} is {:?}", + field.raw_value() + ); stack_frame.incr_pc(); } PUTSTATIC => { @@ -735,6 +754,21 @@ impl<'a> Engine<'a> { fieldref_constpool_index, )?; + //calling static block if needed, todo: move me to single place + if !static_set.contains(class_name.as_str()) { + static_set.insert(class_name.clone()); + if let Ok(clinit) = self + .method_area + .get_method_by_name_signature(class_name.as_str(), ":()V") + { + stack_frame.advance_pc(-2); + let next_frame = clinit.new_stack_frame(); + stack_frames.push(next_frame); + println!(" -> {class_name}.:()V"); + continue; + } + } + let len = { let field = self .method_area @@ -755,8 +789,11 @@ impl<'a> Engine<'a> { value.push(stack_frame.pop()); } - self.method_area - .set_static_field_value(&class_name, &field_name, value.clone())?; + self.method_area.set_static_field_value( + &class_name, + &field_name, + value.clone(), + )?; println!("PUTSTATIC -> {class_name}.{field_name} = {value:?}"); stack_frame.incr_pc(); @@ -902,6 +939,22 @@ impl<'a> Engine<'a> { methodref_constpool_index, )?; + //calling static block if needed, todo: move me to single place + // requirements of JVMS Section 5.4 + if !static_set.contains(class_name.as_str()) { + static_set.insert(class_name.clone()); + if let Ok(clinit) = self + .method_area + .get_method_by_name_signature(class_name.as_str(), ":()V") + { + stack_frame.advance_pc(-2); + let next_frame = clinit.new_stack_frame(); + stack_frames.push(next_frame); + println!(" -> {class_name}.:()V"); + continue; + } + } + let mut next_frame = static_method.new_stack_frame(); let arg_num = static_method.get_signature().arguments_length(); @@ -931,7 +984,12 @@ impl<'a> Engine<'a> { self.method_area .loaded_classes .get(class_to_invoke_new_for.as_str()) - .unwrap(), + .expect( + format!( + "class_to_invoke_new_for not found: {class_to_invoke_new_for}" + ) + .as_str(), + ), )?; let instanceref = self.heap.create_instance(default_field_values_instance); diff --git a/vm/src/heap/heap.rs b/vm/src/heap/heap.rs index 92ccb85f..d611bcab 100644 --- a/vm/src/heap/heap.rs +++ b/vm/src/heap/heap.rs @@ -59,7 +59,11 @@ impl<'a> Heap<'a> { self.next_id } - pub(crate) fn get_array_value(&self, arrayref: i32, index: i32) -> crate::error::Result<&Vec> { + pub(crate) fn get_array_value( + &self, + arrayref: i32, + index: i32, + ) -> crate::error::Result<&Vec> { if let Some(Arr(arr)) = self.data.get(&arrayref) { arr.get_value(index) } else { diff --git a/vm/src/heap/java_instance.rs b/vm/src/heap/java_instance.rs index 5ae7a23a..c56e7050 100644 --- a/vm/src/heap/java_instance.rs +++ b/vm/src/heap/java_instance.rs @@ -19,7 +19,7 @@ pub(crate) struct Array { impl Array { pub fn new(len: i32) -> Self { Self { - data: vec![vec![0,0]; len as usize], //todo: use either 1 or 2 elements vector for corresponding type + data: vec![vec![0, 0]; len as usize], //todo: use either 1 or 2 elements vector for corresponding type } } diff --git a/vm/src/method_area/method_area.rs b/vm/src/method_area/method_area.rs index c8913a0e..2f37c2b8 100644 --- a/vm/src/method_area/method_area.rs +++ b/vm/src/method_area/method_area.rs @@ -40,7 +40,7 @@ impl MethodArea { if let Some(found) = self .loaded_classes .get(class_name) - .unwrap() + .expect(format!("class {class_name} not found").as_str()) .methods .method_by_signature .get(method_name_signature) diff --git a/vm/src/stack/stack_frame.rs b/vm/src/stack/stack_frame.rs index 8880c3c9..001de012 100644 --- a/vm/src/stack/stack_frame.rs +++ b/vm/src/stack/stack_frame.rs @@ -58,7 +58,6 @@ impl<'a> StackFrame<'a> { self.push(high); } - pub fn pop_i64(&mut self) -> i64 { let high = self.pop(); let low = self.pop();