Skip to content

Commit

Permalink
Add support of basic parts of PrintStream
Browse files Browse the repository at this point in the history
  • Loading branch information
hextriclosan committed Dec 3, 2024
1 parent 50d7a64 commit 3c5539c
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 3 deletions.
25 changes: 25 additions & 0 deletions tests/should_write_file_with_printstream.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
mod utils;
use std::fs;
use vm::vm::VM;

#[test]
fn should_write_file_with_print_stream() {
let file_path = "../tmp/print_stream_test.txt";
VM::run("samples.io.printstreamexample.PrintStreamExample").unwrap();

assert!(fs::metadata(file_path).is_ok(), "File does not exist");
let content = fs::read_to_string(file_path).expect("Failed to read file");
assert_eq!(
content,
r#"Hello, PrintStream!
First Line
Second Line
Third Line
Hello as raw bytes
This is written immediately. This follows after flush.
This is an example of chaining PrintStreams.
"#,
"File content does not match"
);
fs::remove_file(file_path).expect("Failed to delete file");
}
66 changes: 66 additions & 0 deletions tests/test_data/PrintStreamExample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package samples.io.printstreamexample;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

public class PrintStreamExample {
private static final String FILE_NAME = "../tmp/print_stream_test.txt";
private static final boolean APPEND = true;

public static void main(String[] args) throws IOException {
try (PrintStream ps = new PrintStream(FILE_NAME)) {
ps.println("Hello, PrintStream!");
}

try (PrintStream ps = new PrintStream(new FileOutputStream(FILE_NAME, APPEND))) {
ps.println("First Line");
ps.println("Second Line");
ps.println("Third Line");
}

// https://github.com/hextriclosan/rusty-jvm/issues/127
// try (PrintStream ps = new PrintStream(new FileOutputStream(FILE_NAME, APPEND))) {
// ps.printf("Hello %s, you are %d years old.%n", "Alice", 30);
// }

// try (PrintStream ps = new PrintStream(new FileOutputStream(FILE_NAME, APPEND))) {
// System.setOut(ps); // Redirects standard output to the file
// System.out.println("This will go to the file instead of the console.");
// }

try (PrintStream ps = new PrintStream(new FileOutputStream(FILE_NAME, APPEND))) {
ps.write("Hello as raw bytes".getBytes()); // Writes raw bytes
ps.println();
}

// try (PrintStream ps = new PrintStream(new FileOutputStream(FILE_NAME, APPEND))) {
// ps.println(new Person("John", 25));
// }

try (PrintStream ps = new PrintStream(new FileOutputStream(FILE_NAME, APPEND))) {
ps.print("This is written immediately. ");
ps.flush(); // Ensures the data is written to the file
ps.println("This follows after flush.");
}

try (PrintStream ps = new PrintStream(new PrintStream(new FileOutputStream(FILE_NAME, APPEND)))) {
ps.println("This is an example of chaining PrintStreams.");
}
}
}

class Person {
private final String name;
private final int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}

@Override
public String toString() {
return String.format("Person{name='%s', age=%d}", name, age);
}
}
Binary file not shown.
Binary file not shown.
10 changes: 8 additions & 2 deletions vm/src/execution_engine/system_native_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use crate::execution_engine::system_native_table::NativeMethod::{Basic, WithStac
use crate::helper::i64_to_vec;
use crate::stack::stack_frame::StackFrames;
use crate::system_native::class::{
class_init_class_name_wrp, get_modifiers_wrp, get_primitive_class_wrp, is_array_wrp,
is_interface_wrp, is_primitive_wrp,
class_init_class_name_wrp, for_name0_wrp, get_modifiers_wrp, get_primitive_class_wrp,
is_array_wrp, is_interface_wrp, is_primitive_wrp,
};
use crate::system_native::file_descriptor::file_descriptor_close0_wrp;
use crate::system_native::file_output_stream::{
Expand Down Expand Up @@ -82,6 +82,8 @@ static SYSTEM_NATIVE_TABLE: Lazy<HashMap<&'static str, NativeMethod>> = Lazy::ne
table.insert("java/lang/Class:isPrimitive:()Z", Basic(is_primitive_wrp));
table.insert("java/lang/Class:isArray:()Z", Basic(is_array_wrp));
table.insert("java/lang/Class:isInterface:()Z", Basic(is_interface_wrp));
table.insert("java/lang/Class:forName0:(Ljava/lang/String;ZLjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;", Basic(for_name0_wrp));
table.insert("java/lang/Class:registerNatives:()V", Basic(void_stub));
table.insert(
"java/lang/Class:initClassName:()Ljava/lang/String;",
Basic(class_init_class_name_wrp as fn(&[i32]) -> crate::error::Result<Vec<i32>>),
Expand Down Expand Up @@ -271,6 +273,10 @@ static SYSTEM_NATIVE_TABLE: Lazy<HashMap<&'static str, NativeMethod>> = Lazy::ne
"jdk/internal/reflect/Reflection:getCallerClass:()Ljava/lang/Class;",
WithStackFrames(reflection_get_caller_class_wrp),
);
table.insert(
"java/security/AccessController:ensureMaterializedForStackWalk:(Ljava/lang/Object;)V",
Basic(void_stub),
);

table
});
Expand Down
23 changes: 23 additions & 0 deletions vm/src/system_native/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,26 @@ fn init_class_name(class_ref: i32) -> crate::error::Result<i32> {
let string_ref = StringPoolHelper::get_string(class_name)?;
Ok(string_ref)
}

pub(crate) fn for_name0_wrp(args: &[i32]) -> crate::error::Result<Vec<i32>> {
let name_ref = args[0];
let initialize = args[1] != 0;
let loader_ref = args[2];
let caller_ref = args[3];

let class_ref = for_name0(name_ref, initialize, loader_ref, caller_ref)?;
Ok(vec![class_ref])
}
fn for_name0(
name_ref: i32,
_initialize: bool,
_loader_ref: i32,
_caller_ref: i32,
) -> crate::error::Result<i32> {
let name = get_utf8_string_by_ref(name_ref)?;
let internal_name = name.replace('.', "/");
let reflection_ref =
with_method_area(|method_area| method_area.load_reflection_class(&internal_name))?;

Ok(reflection_ref)
}
7 changes: 6 additions & 1 deletion vm/src/system_native/system_props_raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@ fn get_platform_properties() -> Vec<&'static str> {
"https.proxyHost_VALUE",
"https.proxyPort_VALUE",
"java.io.tmpdir_VALUE",
"line.separator_VALUE",
// todo https://github.com/hextriclosan/rusty-jvm/issues/128
if cfg!(target_os = "windows") {
"\r\n"
} else {
"\n"
}, // "line.separator"
"os.arch_VALUE",
"os.name_VALUE",
"os.version_VALUE",
Expand Down

0 comments on commit 3c5539c

Please sign in to comment.