From 3f7e2e2786fad696a559b5ef5f0e2aa006094bd8 Mon Sep 17 00:00:00 2001 From: Shautvast Date: Mon, 6 Nov 2023 19:06:18 +0100 Subject: [PATCH] fixed some bugs --- src/class.rs | 2 +- src/classmanager.rs | 38 +++++----- src/vm/native.rs | 177 +++++++++++++++++++++++--------------------- src/vm/vm.rs | 31 ++++---- 4 files changed, 131 insertions(+), 117 deletions(-) diff --git a/src/class.rs b/src/class.rs index 14152db..954b4de 100644 --- a/src/class.rs +++ b/src/class.rs @@ -114,7 +114,7 @@ impl ObjectRef { CharArray(d) => d.len(), StringArray(d) => d.len(), ObjectArray(_, d) => d.len(), - _ => unreachable!("not an array") + _ => unreachable!("not an array {:?}", self) } } } diff --git a/src/classmanager.rs b/src/classmanager.rs index 2661fd7..969cf49 100644 --- a/src/classmanager.rs +++ b/src/classmanager.rs @@ -116,7 +116,7 @@ impl ClassManager { class_objects: HashMap::new(), names: HashMap::new(), classpath: vec![], - vm:Vm::new_internal(), + vm: Vm::new_internal(), } } @@ -146,6 +146,7 @@ impl ClassManager { } fn get_classdef(&self, id: &ClassId) -> &ClassDef { + debug!("get_classdef {}", *id); self.classdefs.get(&id).unwrap() } @@ -155,7 +156,10 @@ impl ClassManager { Some(id) => if self.classes.get(id).is_none() { 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 { + debug!("add class {}", name); let this_classid = self.load(name); 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.names.get(name) - .and_then(|id| - self.classes.insert(this_classid, Class { - id: this_classid, - initialized: false, - name: name.into(), - superclass: superclass_id, - parents, - interfaces: interface_ids, - object_field_mapping, - static_field_mapping, - // static_field_data: static_values, - })); + self.classes.insert(this_classid, Class { + id: this_classid, + initialized: false, + name: name.into(), + superclass: superclass_id, + parents, + interfaces: interface_ids, + object_field_mapping, + static_field_mapping, + // static_field_data: static_values, + }); + if name != "java/lang/Class" { let cls = self.get_class_by_name("java/lang/Class").unwrap(); let mut instance = Object::new(cls); @@ -223,7 +227,7 @@ impl ClassManager { let clinit = this_classdef.methods.contains_key("()V"); if clinit { - self.vm.execute_special(&mut vec![],name, "()V", vec![]).unwrap(); + self.vm.execute_special(&mut vec![], name, "()V", vec![]).unwrap(); } this_classid @@ -274,7 +278,7 @@ impl ClassManager { let classdef = self.classdefs .entry(id) .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>) -> Vec { diff --git a/src/vm/native.rs b/src/vm/native.rs index 8969e92..e1e1441 100644 --- a/src/vm/native.rs +++ b/src/vm/native.rs @@ -30,9 +30,9 @@ fn java_lang_class(_vm: &Vm, method_name: &str) -> Result { fn jdk_internal_util_SystemProps_Raw(vm: &mut Vm, stackframes: &mut Vec, method_name: &str) -> Result { 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 - "vmProperties()[Ljava/lang/String;" => cmdProps(vm, stackframes), + "vmProperties()[Ljava/lang/String;" => vmProperties(vm, stackframes), _ => Ok(Void) } } @@ -43,94 +43,101 @@ fn cmdProps(vm: &mut Vm, stackframes: &mut Vec) -> Result()V", vec![hashmap.clone()]); - panic!() + Ok(hashmap) } -fn systemProps() -> Result { - unsafe { - let props: Lazy> = Lazy::new(|| { - let mut vec: Vec = Vec::new(); - //TODO set correct values - vec.push("display_country".into()); //null in jdk21 - vec.push("display_language".into()); //null in jdk21 - vec.push("display_script".into()); //null in jdk21 - vec.push("display_variant".into()); //null in jdk21 - vec.push("UTF-8".into()); +fn vmProperties(vm: &mut Vm, stackframes: &mut Vec) -> Result { + let props: Lazy> = Lazy::new(|| { + let mut vec: Vec = Vec::new(); + //TODO insert some values + vec + }); + Ok(Value::Ref(ObjectRef::StringArray(props.to_vec()))) +} - { - #[cfg(target_family = "unix")] - vec.push("/".into()); - #[cfg(target_family = "windows")] - vec.push("\\"); - } - vec.push("format_country".into()); //null in jdk21 - vec.push("format_language".into()); //null in jdk21 - vec.push("format_script".into()); //null in jdk21 - vec.push("format_variant".into()); //null in jdk21 - vec.push("ftp_nonProxyHosts".into()); - if let Ok(ftp_proxy) = std::env::var("ftp_proxy") { - vec.push(ftp_proxy.to_owned());//TODO - vec.push(ftp_proxy); - } else { - vec.push("".to_owned()); - vec.push("".to_owned()); - } +fn platformProperties() -> Result { + let props: Lazy> = Lazy::new(|| { + let mut vec: Vec = Vec::new(); + //TODO set correct values + vec.push("display_country".into()); //null in jdk21 + vec.push("display_language".into()); //null in jdk21 + vec.push("display_script".into()); //null in jdk21 + vec.push("display_variant".into()); //null in jdk21 + vec.push("UTF-8".into()); - vec.push("http_nonProxyHosts".into()); - if let Ok(http_proxy) = std::env::var("http_proxy") { - vec.push(http_proxy.to_owned()); - vec.push(http_proxy);//TODO - } else { - vec.push("".to_owned()); - vec.push("".to_owned()); - } - if let Ok(https_proxy) = std::env::var("https_proxy") { - vec.push(https_proxy.to_owned()); - vec.push(https_proxy); - } else { - vec.push("".to_owned()); - vec.push("".to_owned()); - } - vec.push(std::env::temp_dir().display().to_string()); + { + #[cfg(target_family = "unix")] + vec.push("/".into()); + #[cfg(target_family = "windows")] + vec.push("\\"); + } + vec.push("format_country".into()); //null in jdk21 + vec.push("format_language".into()); //null in jdk21 + vec.push("format_script".into()); //null in jdk21 + vec.push("format_variant".into()); //null in jdk21 + vec.push("ftp_nonProxyHosts".into()); + if let Ok(ftp_proxy) = std::env::var("ftp_proxy") { + vec.push(ftp_proxy.to_owned());//TODO + vec.push(ftp_proxy); + } else { + vec.push("".to_owned()); + vec.push("".to_owned()); + } - { - #[cfg(target_family = "unix")] - vec.push("\n".into()); - #[cfg(target_family = "windows")] - vec.push("\r\n"); - } - vec.push(whoami::platform().to_string()); - vec.push(whoami::devicename()); - vec.push("os_version".into()); - { - #[cfg(target_family = "unix")] - vec.push(":".into()); - #[cfg(target_family = "windows")] - vec.push(";".into()); - } - vec.push("socksNonProxyHosts".into()); - vec.push("socksProxyHost".into()); - vec.push("socksProxyPort".into()); - vec.push("UTF-8".into()); - vec.push("UTF-8".into()); - vec.push("sun_arch_abi".into()); - vec.push("sun_arch_data_model".into()); - vec.push("sun_cpu_endian".into()); //null in jdk21 - vec.push("sun_cpu_isalist".into()); //null in jdk21 - vec.push("sun_io_unicode_encoding".into()); //null in jdk21 - vec.push("sun_jnu_encoding".into()); //null in jdk21 - vec.push("sun_os_patch_level".into()); //null in jdk21 - if let Ok(curdir) = std::env::current_dir() { - vec.push(curdir.display().to_string()); - } + vec.push("http_nonProxyHosts".into()); + if let Ok(http_proxy) = std::env::var("http_proxy") { + vec.push(http_proxy.to_owned()); + vec.push(http_proxy);//TODO + } else { + vec.push("".to_owned()); + vec.push("".to_owned()); + } + if let Ok(https_proxy) = std::env::var("https_proxy") { + vec.push(https_proxy.to_owned()); + vec.push(https_proxy); + } else { + vec.push("".to_owned()); + vec.push("".to_owned()); + } + vec.push(std::env::temp_dir().display().to_string()); - let home = std::env::home_dir().unwrap(); - vec.push(home.display().to_string()); - vec.push(whoami::username()); - vec.push("FIXED_LENGTH".into()); + { + #[cfg(target_family = "unix")] + vec.push("\n".into()); + #[cfg(target_family = "windows")] + vec.push("\r\n"); + } + vec.push(whoami::platform().to_string()); + vec.push(whoami::devicename()); + vec.push("os_version".into()); + { + #[cfg(target_family = "unix")] + vec.push(":".into()); + #[cfg(target_family = "windows")] + vec.push(";".into()); + } + vec.push("socksNonProxyHosts".into()); + vec.push("socksProxyHost".into()); + vec.push("socksProxyPort".into()); + vec.push("UTF-8".into()); + vec.push("UTF-8".into()); + vec.push("sun_arch_abi".into()); + vec.push("sun_arch_data_model".into()); + vec.push("sun_cpu_endian".into()); //null in jdk21 + vec.push("sun_cpu_isalist".into()); //null in jdk21 + vec.push("sun_io_unicode_encoding".into()); //null in jdk21 + vec.push("sun_jnu_encoding".into()); //null in jdk21 + vec.push("sun_os_patch_level".into()); //null in jdk21 + if let Ok(curdir) = std::env::current_dir() { + vec.push(curdir.display().to_string()); + } - vec - }); - 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()))) } \ No newline at end of file diff --git a/src/vm/vm.rs b/src/vm/vm.rs index fdda18a..e8c8917 100644 --- a/src/vm/vm.rs +++ b/src/vm/vm.rs @@ -48,7 +48,7 @@ impl Vm { fn init(vm: &mut Vm, stack: &mut Vec) { classmanager::load_class_by_name("java/lang/Class"); 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 method = cd.get_method(method_name); 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 { let name = classmanager::classdef_name(&this.class_id); if let Some(name) = name { @@ -242,18 +244,18 @@ impl Vm { let stringinstance = Ref(ObjectRef::Object(Vm::new_instance(stringclass))); - debug!("class id {}", this_class.id); - let string: Vec = - classmanager::get_classdef(&this_class.id).cp_utf8(utf8).as_bytes().into(); + // let string = classmanager::get_classdef(&this_class.id).cp_utf8(utf8); + debug!("new string \"{}\"", utf8); + // let string: Vec = string.as_bytes().into(); - self.execute_special(stackframes, - "java/lang/String", - "([B)V", - vec![ - stringinstance.clone(), - Ref(ObjectRef::new_byte_array(string)), - ], - )?; + // self.execute_special(stackframes, + // "java/lang/String", + // "([B)V", + // vec![ + // stringinstance.clone(), + // Ref(ObjectRef::new_byte_array(string)), + // ], + // )?; Self::current_frame(stackframes).push(stringinstance); } CpEntry::Long(l) => { @@ -369,8 +371,8 @@ impl Vm { Self::current_frame(stackframes).push(value); } IDIV => { - let value1 = 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())); } @@ -523,6 +525,7 @@ impl Vm { if let Some(invocation) = get_signature_for_invoke(&method.constant_pool, cp_index) { + debug!("invoke {:?}", invocation); let mut args = Vec::with_capacity(invocation.method.num_args); for _ in 0..invocation.method.num_args { args.insert(0, Self::current_frame(stackframes).pop()?.clone());