fixed some bugs

This commit is contained in:
Shautvast 2023-11-06 19:06:18 +01:00
parent 769800ff71
commit 3f7e2e2786
4 changed files with 131 additions and 117 deletions

View file

@ -114,7 +114,7 @@ impl ObjectRef {
CharArray(d) => d.len(), CharArray(d) => d.len(),
StringArray(d) => d.len(), StringArray(d) => d.len(),
ObjectArray(_, d) => d.len(), ObjectArray(_, d) => d.len(),
_ => unreachable!("not an array") _ => unreachable!("not an array {:?}", self)
} }
} }
} }

View file

@ -116,7 +116,7 @@ impl ClassManager {
class_objects: HashMap::new(), class_objects: HashMap::new(),
names: HashMap::new(), names: HashMap::new(),
classpath: vec![], classpath: vec![],
vm:Vm::new_internal(), vm: Vm::new_internal(),
} }
} }
@ -146,6 +146,7 @@ impl ClassManager {
} }
fn get_classdef(&self, id: &ClassId) -> &ClassDef { fn get_classdef(&self, id: &ClassId) -> &ClassDef {
debug!("get_classdef {}", *id);
self.classdefs.get(&id).unwrap() self.classdefs.get(&id).unwrap()
} }
@ -155,7 +156,10 @@ impl ClassManager {
Some(id) => if self.classes.get(id).is_none() { Some(id) => if self.classes.get(id).is_none() {
self.add_class(name); self.add_class(name);
} }
None => { self.add_class(name); } None => {
self.add_class(name);
}
} }
} }
@ -165,6 +169,7 @@ impl ClassManager {
} }
fn add_class(&mut self, name: &str) -> ClassId { fn add_class(&mut self, name: &str) -> ClassId {
debug!("add class {}", name);
let this_classid = self.load(name); let this_classid = self.load(name);
let this_classdef = self.classdefs.get(&this_classid).unwrap(); let this_classdef = self.classdefs.get(&this_classid).unwrap();
@ -199,19 +204,18 @@ impl ClassManager {
self.static_class_data.insert(this_classid, Self::set_field_data(&static_field_mapping)); self.static_class_data.insert(this_classid, Self::set_field_data(&static_field_mapping));
self.names.get(name) self.classes.insert(this_classid, Class {
.and_then(|id| id: this_classid,
self.classes.insert(this_classid, Class { initialized: false,
id: this_classid, name: name.into(),
initialized: false, superclass: superclass_id,
name: name.into(), parents,
superclass: superclass_id, interfaces: interface_ids,
parents, object_field_mapping,
interfaces: interface_ids, static_field_mapping,
object_field_mapping, // static_field_data: static_values,
static_field_mapping, });
// static_field_data: static_values,
}));
if name != "java/lang/Class" { if name != "java/lang/Class" {
let cls = self.get_class_by_name("java/lang/Class").unwrap(); let cls = self.get_class_by_name("java/lang/Class").unwrap();
let mut instance = Object::new(cls); let mut instance = Object::new(cls);
@ -223,7 +227,7 @@ impl ClassManager {
let clinit = this_classdef.methods.contains_key("<clinit>()V"); let clinit = this_classdef.methods.contains_key("<clinit>()V");
if clinit { if clinit {
self.vm.execute_special(&mut vec![],name, "<clinit>()V", vec![]).unwrap(); self.vm.execute_special(&mut vec![], name, "<clinit>()V", vec![]).unwrap();
} }
this_classid this_classid
@ -274,7 +278,7 @@ impl ClassManager {
let classdef = self.classdefs let classdef = self.classdefs
.entry(id) .entry(id)
.or_insert_with(|| classloader::get_classdef(&self.classpath, name).expect("ClassNotFound")); .or_insert_with(|| classloader::get_classdef(&self.classpath, name).expect("ClassNotFound"));
(self.current_id, inspect_dependencies(classdef)) (id, inspect_dependencies(classdef))
} }
pub(crate) fn set_field_data(field_mapping: &HashMap<String, HashMap<String, TypeIndex>>) -> Vec<Value> { pub(crate) fn set_field_data(field_mapping: &HashMap<String, HashMap<String, TypeIndex>>) -> Vec<Value> {

View file

@ -30,9 +30,9 @@ fn java_lang_class(_vm: &Vm, method_name: &str) -> Result<Value, Error> {
fn jdk_internal_util_SystemProps_Raw(vm: &mut Vm, stackframes: &mut Vec<StackFrame>, method_name: &str) -> Result<Value, Error> { fn jdk_internal_util_SystemProps_Raw(vm: &mut Vm, stackframes: &mut Vec<StackFrame>, method_name: &str) -> Result<Value, Error> {
match method_name { match method_name {
"platformProperties()[Ljava/lang/String;" => systemProps(), "platformProperties()[Ljava/lang/String;" => platformProperties(),
"cmdProperties()Ljava/util/HashMap;" => cmdProps(vm, stackframes), //TODO ability to instantiate classes here "cmdProperties()Ljava/util/HashMap;" => cmdProps(vm, stackframes), //TODO ability to instantiate classes here
"vmProperties()[Ljava/lang/String;" => cmdProps(vm, stackframes), "vmProperties()[Ljava/lang/String;" => vmProperties(vm, stackframes),
_ => Ok(Void) _ => Ok(Void)
} }
} }
@ -43,94 +43,101 @@ fn cmdProps(vm: &mut Vm, stackframes: &mut Vec<StackFrame>) -> Result<Value, Err
let hashmap = Vm::new_instance(hashmap_class); let hashmap = Vm::new_instance(hashmap_class);
let hashmap = Value::Ref(Object(hashmap)); let hashmap = Value::Ref(Object(hashmap));
vm.execute_special(stackframes, "java/util/HashMap", "<init>()V", vec![hashmap.clone()]); vm.execute_special(stackframes, "java/util/HashMap", "<init>()V", vec![hashmap.clone()]);
panic!() Ok(hashmap)
} }
fn systemProps() -> Result<Value, Error> { fn vmProperties(vm: &mut Vm, stackframes: &mut Vec<StackFrame>) -> Result<Value, Error> {
unsafe { let props: Lazy<Vec<String>> = Lazy::new(|| {
let props: Lazy<Vec<String>> = Lazy::new(|| { let mut vec: Vec<String> = Vec::new();
let mut vec: Vec<String> = Vec::new(); //TODO insert some values
//TODO set correct values vec
vec.push("display_country".into()); //null in jdk21 });
vec.push("display_language".into()); //null in jdk21 Ok(Value::Ref(ObjectRef::StringArray(props.to_vec())))
vec.push("display_script".into()); //null in jdk21 }
vec.push("display_variant".into()); //null in jdk21
vec.push("UTF-8".into()); fn platformProperties() -> Result<Value, Error> {
let props: Lazy<Vec<String>> = Lazy::new(|| {
{ let mut vec: Vec<String> = Vec::new();
#[cfg(target_family = "unix")] //TODO set correct values
vec.push("/".into()); vec.push("display_country".into()); //null in jdk21
#[cfg(target_family = "windows")] vec.push("display_language".into()); //null in jdk21
vec.push("\\"); vec.push("display_script".into()); //null in jdk21
} vec.push("display_variant".into()); //null in jdk21
vec.push("format_country".into()); //null in jdk21 vec.push("UTF-8".into());
vec.push("format_language".into()); //null in jdk21
vec.push("format_script".into()); //null in jdk21 {
vec.push("format_variant".into()); //null in jdk21 #[cfg(target_family = "unix")]
vec.push("ftp_nonProxyHosts".into()); vec.push("/".into());
if let Ok(ftp_proxy) = std::env::var("ftp_proxy") { #[cfg(target_family = "windows")]
vec.push(ftp_proxy.to_owned());//TODO vec.push("\\");
vec.push(ftp_proxy); }
} else { vec.push("format_country".into()); //null in jdk21
vec.push("".to_owned()); vec.push("format_language".into()); //null in jdk21
vec.push("".to_owned()); vec.push("format_script".into()); //null in jdk21
} vec.push("format_variant".into()); //null in jdk21
vec.push("ftp_nonProxyHosts".into());
vec.push("http_nonProxyHosts".into()); if let Ok(ftp_proxy) = std::env::var("ftp_proxy") {
if let Ok(http_proxy) = std::env::var("http_proxy") { vec.push(ftp_proxy.to_owned());//TODO
vec.push(http_proxy.to_owned()); vec.push(ftp_proxy);
vec.push(http_proxy);//TODO } else {
} else { vec.push("".to_owned());
vec.push("".to_owned()); vec.push("".to_owned());
vec.push("".to_owned()); }
}
if let Ok(https_proxy) = std::env::var("https_proxy") { vec.push("http_nonProxyHosts".into());
vec.push(https_proxy.to_owned()); if let Ok(http_proxy) = std::env::var("http_proxy") {
vec.push(https_proxy); vec.push(http_proxy.to_owned());
} else { vec.push(http_proxy);//TODO
vec.push("".to_owned()); } else {
vec.push("".to_owned()); vec.push("".to_owned());
} vec.push("".to_owned());
vec.push(std::env::temp_dir().display().to_string()); }
if let Ok(https_proxy) = std::env::var("https_proxy") {
{ vec.push(https_proxy.to_owned());
#[cfg(target_family = "unix")] vec.push(https_proxy);
vec.push("\n".into()); } else {
#[cfg(target_family = "windows")] vec.push("".to_owned());
vec.push("\r\n"); vec.push("".to_owned());
} }
vec.push(whoami::platform().to_string()); vec.push(std::env::temp_dir().display().to_string());
vec.push(whoami::devicename());
vec.push("os_version".into()); {
{ #[cfg(target_family = "unix")]
#[cfg(target_family = "unix")] vec.push("\n".into());
vec.push(":".into()); #[cfg(target_family = "windows")]
#[cfg(target_family = "windows")] vec.push("\r\n");
vec.push(";".into()); }
} vec.push(whoami::platform().to_string());
vec.push("socksNonProxyHosts".into()); vec.push(whoami::devicename());
vec.push("socksProxyHost".into()); vec.push("os_version".into());
vec.push("socksProxyPort".into()); {
vec.push("UTF-8".into()); #[cfg(target_family = "unix")]
vec.push("UTF-8".into()); vec.push(":".into());
vec.push("sun_arch_abi".into()); #[cfg(target_family = "windows")]
vec.push("sun_arch_data_model".into()); vec.push(";".into());
vec.push("sun_cpu_endian".into()); //null in jdk21 }
vec.push("sun_cpu_isalist".into()); //null in jdk21 vec.push("socksNonProxyHosts".into());
vec.push("sun_io_unicode_encoding".into()); //null in jdk21 vec.push("socksProxyHost".into());
vec.push("sun_jnu_encoding".into()); //null in jdk21 vec.push("socksProxyPort".into());
vec.push("sun_os_patch_level".into()); //null in jdk21 vec.push("UTF-8".into());
if let Ok(curdir) = std::env::current_dir() { vec.push("UTF-8".into());
vec.push(curdir.display().to_string()); vec.push("sun_arch_abi".into());
} vec.push("sun_arch_data_model".into());
vec.push("sun_cpu_endian".into()); //null in jdk21
let home = std::env::home_dir().unwrap(); vec.push("sun_cpu_isalist".into()); //null in jdk21
vec.push(home.display().to_string()); vec.push("sun_io_unicode_encoding".into()); //null in jdk21
vec.push(whoami::username()); vec.push("sun_jnu_encoding".into()); //null in jdk21
vec.push("FIXED_LENGTH".into()); vec.push("sun_os_patch_level".into()); //null in jdk21
if let Ok(curdir) = std::env::current_dir() {
vec vec.push(curdir.display().to_string());
}); }
Ok(Value::Ref(ObjectRef::StringArray(props.to_vec())))
} let home = std::env::home_dir().unwrap();
vec.push(home.display().to_string());
vec.push(whoami::username());
vec.push("FIXED_LENGTH".into());
vec
});
Ok(Value::Ref(ObjectRef::StringArray(props.to_vec())))
} }

View file

@ -48,7 +48,7 @@ impl Vm {
fn init(vm: &mut Vm, stack: &mut Vec<StackFrame>) { fn init(vm: &mut Vm, stack: &mut Vec<StackFrame>) {
classmanager::load_class_by_name("java/lang/Class"); classmanager::load_class_by_name("java/lang/Class");
vm.execute_static(stack, "java/lang/System", "initPhase1()V", vec![]).expect("cannot create VM"); vm.execute_static(stack, "java/lang/System", "initPhase1()V", vec![]).expect("cannot create VM");
classmanager::load_class_by_name("java/lang/String"); // classmanager::load_class_by_name("java/lang/String");
} }
@ -85,7 +85,9 @@ impl Vm {
let cd = classmanager::get_classdef(&this.class_id); let cd = classmanager::get_classdef(&this.class_id);
let method = cd.get_method(method_name); let method = cd.get_method(method_name);
if let Some(method) = method { if let Some(method) = method {
return self.execute_class_id(stack, this.class_id, &method, args.clone()); classmanager::load_class_by_name(class_name);
let class = classmanager::get_class_by_name(class_name).unwrap();
return self.execute_class(stack, class, method.name().as_str(), args.clone());
} else { } else {
let name = classmanager::classdef_name(&this.class_id); let name = classmanager::classdef_name(&this.class_id);
if let Some(name) = name { if let Some(name) = name {
@ -242,18 +244,18 @@ impl Vm {
let stringinstance = let stringinstance =
Ref(ObjectRef::Object(Vm::new_instance(stringclass))); Ref(ObjectRef::Object(Vm::new_instance(stringclass)));
debug!("class id {}", this_class.id); // let string = classmanager::get_classdef(&this_class.id).cp_utf8(utf8);
let string: Vec<u8> = debug!("new string \"{}\"", utf8);
classmanager::get_classdef(&this_class.id).cp_utf8(utf8).as_bytes().into(); // let string: Vec<u8> = string.as_bytes().into();
self.execute_special(stackframes, // self.execute_special(stackframes,
"java/lang/String", // "java/lang/String",
"<init>([B)V", // "<init>([B)V",
vec![ // vec![
stringinstance.clone(), // stringinstance.clone(),
Ref(ObjectRef::new_byte_array(string)), // Ref(ObjectRef::new_byte_array(string)),
], // ],
)?; // )?;
Self::current_frame(stackframes).push(stringinstance); Self::current_frame(stackframes).push(stringinstance);
} }
CpEntry::Long(l) => { CpEntry::Long(l) => {
@ -369,8 +371,8 @@ impl Vm {
Self::current_frame(stackframes).push(value); Self::current_frame(stackframes).push(value);
} }
IDIV => { IDIV => {
let value1 = Self::current_frame(stackframes).pop()?;
let value2 = Self::current_frame(stackframes).pop()?; let value2 = Self::current_frame(stackframes).pop()?;
let value1 = Self::current_frame(stackframes).pop()?;
Self::current_frame(stackframes).push(I32(value1.into_i32() / value2.into_i32())); Self::current_frame(stackframes).push(I32(value1.into_i32() / value2.into_i32()));
} }
@ -523,6 +525,7 @@ impl Vm {
if let Some(invocation) = if let Some(invocation) =
get_signature_for_invoke(&method.constant_pool, cp_index) get_signature_for_invoke(&method.constant_pool, cp_index)
{ {
debug!("invoke {:?}", invocation);
let mut args = Vec::with_capacity(invocation.method.num_args); let mut args = Vec::with_capacity(invocation.method.num_args);
for _ in 0..invocation.method.num_args { for _ in 0..invocation.method.num_args {
args.insert(0, Self::current_frame(stackframes).pop()?.clone()); args.insert(0, Self::current_frame(stackframes).pop()?.clone());