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(),
StringArray(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(),
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("<clinit>()V");
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
@ -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<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> {
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<StackFrame>) -> Result<Value, Err
let hashmap = Vm::new_instance(hashmap_class);
let hashmap = Value::Ref(Object(hashmap));
vm.execute_special(stackframes, "java/util/HashMap", "<init>()V", vec![hashmap.clone()]);
panic!()
Ok(hashmap)
}
fn systemProps() -> Result<Value, Error> {
unsafe {
let props: Lazy<Vec<String>> = Lazy::new(|| {
let mut vec: Vec<String> = 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());
{
#[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());
}
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("\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());
}
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())))
}
fn vmProperties(vm: &mut Vm, stackframes: &mut Vec<StackFrame>) -> Result<Value, Error> {
let props: Lazy<Vec<String>> = Lazy::new(|| {
let mut vec: Vec<String> = Vec::new();
//TODO insert some values
vec
});
Ok(Value::Ref(ObjectRef::StringArray(props.to_vec())))
}
fn platformProperties() -> Result<Value, Error> {
let props: Lazy<Vec<String>> = Lazy::new(|| {
let mut vec: Vec<String> = 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());
{
#[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());
}
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("\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());
}
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>) {
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<u8> =
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<u8> = string.as_bytes().into();
self.execute_special(stackframes,
"java/lang/String",
"<init>([B)V",
vec![
stringinstance.clone(),
Ref(ObjectRef::new_byte_array(string)),
],
)?;
// self.execute_special(stackframes,
// "java/lang/String",
// "<init>([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());