1mod commons;
2mod error;
3mod exception;
4mod execution_engine;
5mod heap;
6mod helper;
7mod launcher;
8mod method_area;
9mod properties;
10mod stack;
11mod system_native;
12mod validation;
13
14use crate::vm::error::{Error, Result};
15use crate::vm::execution_engine::executor::Executor;
16use crate::vm::execution_engine::static_init::StaticInit;
17use crate::vm::execution_engine::string_pool_helper::StringPoolHelper;
18use crate::vm::launcher::resolve_and_execute_main_method;
19use crate::vm::method_area::java_class::JavaClass;
20use crate::vm::method_area::method_area::{with_method_area, MethodArea};
21use crate::vm::properties::system_properties::init_system_properties;
22use crate::vm::system_native::properties_provider::properties::is_bigendian;
23use crate::vm::validation::validate_class_name;
24use crate::Arguments;
25use std::path::{Path, PathBuf};
26use std::sync::{Arc, OnceLock};
27use tracing_subscriber::layer::SubscriberExt;
28use tracing_subscriber::util::SubscriberInitExt;
29use tracing_subscriber::{fmt, EnvFilter};
30
31pub fn run(arguments: &Arguments, java_home: &Path) -> Result<Vec<i32>> {
40 JAVA_HOME
41 .set(java_home.to_path_buf())
42 .map_err(|e| Error::new_execution(&format!("JAVA_HOME already set: {e:?}")))?;
43 let main_class_name = arguments.entry_point();
44 validate_class_name(main_class_name)?;
45
46 init_system_properties(arguments.system_properties().clone())?;
47
48 prelude()?;
49
50 let internal_name = &main_class_name.replace('.', "/");
51 StaticInit::initialize(internal_name)?; resolve_and_execute_main_method(internal_name, arguments.program_args())?;
54 Ok(vec![])
55}
56
57fn prelude() -> Result<()> {
58 init_logger()?;
59
60 MethodArea::init()?;
61
62 init()?;
63
64 Ok(())
65}
66
67fn init_logger() -> Result<()> {
68 let fmt_layer = fmt::layer()
69 .with_target(false)
70 .without_time()
71 .with_ansi(false);
72 let filter_layer = EnvFilter::try_from_default_env()
73 .or_else(|_| EnvFilter::try_new("info"))
74 .map_err(|e| Error::new_execution(&format!("Error creating EnvFilter: {e}")))?;
75 tracing_subscriber::registry()
76 .with(filter_layer)
77 .with(fmt_layer)
78 .init();
79
80 Ok(())
81}
82
83fn init() -> Result<()> {
84 StaticInit::initialize("jdk/internal/misc/UnsafeConstants")?;
85 let lc = with_method_area(|area| area.get("jdk/internal/misc/UnsafeConstants"))?;
86 let big_endian = lc.static_field("BIG_ENDIAN").unwrap();
87 big_endian.set_raw_value(vec![if is_bigendian() { 1 } else { 0 }])?;
88
89 let address_size0 = lc.static_field("ADDRESS_SIZE0").unwrap();
90 address_size0.set_raw_value(vec![8])?;
91
92 StaticInit::initialize("java/lang/reflect/AccessibleObject")?;
93
94 put_synthetic_instance_field("java/lang/invoke/ResolvedMethodName", "vmtarget", "J", 0)?;
95
96 let tg_obj_ref = Executor::invoke_default_constructor("java/lang/ThreadGroup")?;
98 with_method_area(|area| area.set_system_thread_group_id(tg_obj_ref))?;
99 let string_obj_ref = StringPoolHelper::get_string("system")?; let _thread_obj_ref =
101 Executor::create_primordial_thread(&vec![tg_obj_ref.into(), string_obj_ref.into()])?;
102
103 Executor::invoke_static_method("java/lang/System", "initPhase1:()V", &[])?;
104
105 Ok(())
106}
107
108fn put_synthetic_instance_field(
109 class_name: &str,
110 field_name: &str,
111 type_descriptor: &str,
112 flags: u16,
113) -> Result<()> {
114 let lc = with_method_area(|area| area.get(class_name))?;
115 let raw_java_class = Arc::into_raw(lc) as *mut JavaClass;
116 let result = unsafe {
117 (*raw_java_class).put_instance_field_descriptor(
118 field_name.to_string(),
119 str::parse(type_descriptor)?,
120 flags,
121 class_name,
122 )?
123 };
124 match result {
125 Some(field_property) => Err(Error::new_execution(&format!(
126 "field {field_name}:{} already exists in {class_name}",
127 field_property.type_descriptor()
128 ))),
129 None => Ok(()),
130 }
131}
132
133static JAVA_HOME: OnceLock<PathBuf> = OnceLock::new();