Skip to content

Commit

Permalink
Add proper static initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
hextriclosan committed Sep 19, 2024
1 parent 17eb519 commit 74ec18e
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 10 deletions.
1 change: 0 additions & 1 deletion tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
16 changes: 16 additions & 0 deletions vm/src/execution_engine/engine.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::collections::HashSet;
use crate::error::Error;
use crate::execution_engine::opcode::*;
use crate::heap::heap::Heap;
Expand All @@ -20,6 +21,7 @@ impl<'a> Engine<'a> {
let mut stack_frames = vec![method.new_stack_frame()];
let mut last_value: Option<Vec<i32>> = None;
let mut current_class_name: String;
let mut static_set: HashSet<String> = HashSet::new();

while !stack_frames.is_empty() {
let stack_frame = stack_frames
Expand Down Expand Up @@ -688,6 +690,20 @@ impl<'a> Engine<'a> {
fieldref_constpool_index,
)?;

//todo!!
//try call invoke static `"<clinit>:()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(), "<clinit>:()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}.<clinit>:()V");
continue;
}
}

let field = self
.method_area
.loaded_classes
Expand Down
9 changes: 0 additions & 9 deletions vm/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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("<clinit>:()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)
}
}

0 comments on commit 74ec18e

Please sign in to comment.