From b737b78b3ab86fdc3215cb61424c697a1f607ff1 Mon Sep 17 00:00:00 2001 From: Inseok Lee Date: Thu, 28 Dec 2023 10:02:20 +0900 Subject: [PATCH] Port method call to use jvm --- wie_impl_java/src/base.rs | 14 +---- .../impl/java/io/byte_array_input_stream.rs | 14 ++--- .../src/impl/java/io/data_input_stream.rs | 31 ++++----- .../src/impl/java/io/input_stream.rs | 22 +++++-- wie_impl_java/src/impl/java/lang/class.rs | 27 +++++--- wie_impl_java/src/impl/java/lang/object.rs | 16 +++-- wie_impl_java/src/impl/java/lang/runtime.rs | 9 ++- wie_impl_java/src/impl/java/lang/string.rs | 56 +++++++++++++---- .../src/impl/java/lang/string_buffer.rs | 15 ++--- wie_impl_java/src/impl/java/lang/thread.rs | 16 +++-- .../src/impl/org/kwis/msp/db/data_base.rs | 18 ++++-- .../src/impl/org/kwis/msp/lcdui/display.rs | 19 +++--- .../impl/org/kwis/msp/lcdui/event_queue.rs | 46 +++++++++----- .../src/impl/org/kwis/msp/lcdui/font.rs | 20 +++--- .../src/impl/org/kwis/msp/lcdui/graphics.rs | 31 +++++---- .../src/impl/org/kwis/msp/lcdui/image.rs | 36 +++++++---- .../src/impl/org/kwis/msp/lcdui/jlet.rs | 39 +++++++----- .../src/impl/org/kwis/msp/lcdui/main.rs | 49 +++++++++++---- wie_ktf/src/runtime/java/context.rs | 43 ++----------- .../java/context/array_class_instance.rs | 15 +---- wie_ktf/src/runtime/java/context/class.rs | 16 ++--- .../runtime/java/context/class_instance.rs | 23 +++---- wie_ktf/src/runtime/java/context/method.rs | 14 ++--- wie_ktf/src/runtime/java/context/value.rs | 63 ++++++++----------- 24 files changed, 352 insertions(+), 300 deletions(-) diff --git a/wie_impl_java/src/base.rs b/wie_impl_java/src/base.rs index c975e7ee..22cc7dd2 100644 --- a/wie_impl_java/src/base.rs +++ b/wie_impl_java/src/base.rs @@ -4,11 +4,7 @@ use jvm::{ClassInstanceRef, Jvm}; use wie_backend::{task::SleepFuture, Backend}; -use crate::{ - method::{MethodBody, MethodImpl, TypeConverter}, - proxy::JavaObjectProxy, - r#impl::java::lang::Object, -}; +use crate::method::{MethodBody, MethodImpl, TypeConverter}; pub struct JavaClassProto { pub parent_class: Option<&'static str>, @@ -104,14 +100,6 @@ pub trait JavaContext { fn instance_raw(&self, instance: &ClassInstanceRef) -> JavaWord; // TODO will be removed fn instance_from_raw(&self, raw: JavaWord) -> ClassInstanceRef; // TODO will be removed fn array_instance_from_raw(&self, raw: JavaWord) -> ClassInstanceRef; // TODO will be removed - async fn call_method( - &mut self, - instance: &JavaObjectProxy, - method_name: &str, - descriptor: &str, - args: &[JavaWord], - ) -> JavaResult; // invokespecial/invokevirtual - async fn call_static_method(&mut self, class_name: &str, method_name: &str, descriptor: &str, args: &[JavaWord]) -> JavaResult; // invokestatic fn backend(&mut self) -> &mut Backend; fn spawn(&mut self, callback: JavaMethodBody) -> JavaResult<()>; fn sleep(&mut self, duration: u64) -> SleepFuture; diff --git a/wie_impl_java/src/impl/java/io/byte_array_input_stream.rs b/wie_impl_java/src/impl/java/io/byte_array_input_stream.rs index 3c29ad25..3840e0ee 100644 --- a/wie_impl_java/src/impl/java/io/byte_array_input_stream.rs +++ b/wie_impl_java/src/impl/java/io/byte_array_input_stream.rs @@ -82,18 +82,18 @@ impl ByteArrayInputStream { return Ok(0); } - let b = context.instance_raw(&b.class_instance); context - .call_static_method( + .jvm() + .invoke_static_method( "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V", &[ - context.instance_raw(buf.as_object_ref().unwrap()), - pos as _, - b, - off as _, - len_to_read as _, + buf, + JavaValue::Int(pos as _), + JavaValue::Object(Some(b.class_instance)), + JavaValue::Int(off as _), + JavaValue::Int(len_to_read as _), ], ) .await?; diff --git a/wie_impl_java/src/impl/java/io/data_input_stream.rs b/wie_impl_java/src/impl/java/io/data_input_stream.rs index 67c23059..a2d61acb 100644 --- a/wie_impl_java/src/impl/java/io/data_input_stream.rs +++ b/wie_impl_java/src/impl/java/io/data_input_stream.rs @@ -5,7 +5,7 @@ use crate::{ base::{JavaClassProto, JavaFieldProto, JavaMethodProto}, proxy::{JvmArrayClassInstanceProxy, JvmClassInstanceProxy}, r#impl::java::io::InputStream, - JavaContext, JavaFieldAccessFlag, JavaMethodFlag, JavaObjectProxy, JavaResult, + JavaContext, JavaFieldAccessFlag, JavaMethodFlag, JavaResult, }; // class java.io.DataInputStream @@ -48,15 +48,11 @@ impl DataInputStream { let r#in = context.jvm().get_field(&this.class_instance, "in", "Ljava/io/InputStream;")?; let available = context - .call_method( - &JavaObjectProxy::new(context.instance_raw(r#in.as_object_ref().unwrap())), - "available", - "()I", - &[], - ) + .jvm() + .invoke_method(r#in.as_object_ref().unwrap(), "java/io/InputStream", "available", "()I", &[]) .await?; - Ok(available as _) + Ok(available.as_int()) } async fn read( @@ -75,17 +71,18 @@ impl DataInputStream { ); let r#in = context.jvm().get_field(&this.class_instance, "in", "Ljava/io/InputStream;")?; - let b = context.instance_raw(&b.class_instance); let result = context - .call_method( - &JavaObjectProxy::new(context.instance_raw(r#in.as_object_ref().unwrap())), + .jvm() + .invoke_method( + r#in.as_object_ref().unwrap(), + "java/io/InputStream", "read", "([BII)I", - &[b, off as _, len as _], + &[JavaValue::Object(Some(b.class_instance)), JavaValue::Int(off), JavaValue::Int(len)], ) .await?; - Ok(result as _) + Ok(result.as_int()) } async fn close(context: &mut dyn JavaContext, this: JvmClassInstanceProxy) -> JavaResult<()> { @@ -93,12 +90,8 @@ impl DataInputStream { let r#in = context.jvm().get_field(&this.class_instance, "in", "Ljava/io/InputStream;")?; context - .call_method( - &JavaObjectProxy::new(context.instance_raw(r#in.as_object_ref().unwrap())), - "close", - "()V", - &[], - ) + .jvm() + .invoke_method(r#in.as_object_ref().unwrap(), "java/io/InputStream", "close", "()V", &[]) .await?; Ok(()) diff --git a/wie_impl_java/src/impl/java/io/input_stream.rs b/wie_impl_java/src/impl/java/io/input_stream.rs index a51166c6..01bc9d66 100644 --- a/wie_impl_java/src/impl/java/io/input_stream.rs +++ b/wie_impl_java/src/impl/java/io/input_stream.rs @@ -1,9 +1,11 @@ use alloc::vec; +use jvm::JavaValue; + use crate::{ base::{JavaClassProto, JavaMethodProto}, proxy::{JvmArrayClassInstanceProxy, JvmClassInstanceProxy}, - JavaContext, JavaMethodFlag, JavaObjectProxy, JavaResult, + JavaContext, JavaMethodFlag, JavaResult, }; // class java.io.InputStream @@ -40,8 +42,20 @@ impl InputStream { let array_length = context.jvm().array_length(&b.class_instance)?; - let this = JavaObjectProxy::new(context.instance_raw(&this.class_instance)); - let b = context.instance_raw(&b.class_instance); - Ok(context.call_method(&this, "read", "([BII)I", &[b, 0, array_length as _]).await? as _) + Ok(context + .jvm() + .invoke_method( + &this.class_instance, + "java/io/InputStream", + "read", + "([BII)I", + &[ + JavaValue::Object(Some(b.class_instance)), + JavaValue::Int(0), + JavaValue::Int(array_length as _), + ], + ) + .await? + .as_int()) } } diff --git a/wie_impl_java/src/impl/java/lang/class.rs b/wie_impl_java/src/impl/java/lang/class.rs index a38875b8..2a7ebf9e 100644 --- a/wie_impl_java/src/impl/java/lang/class.rs +++ b/wie_impl_java/src/impl/java/lang/class.rs @@ -41,11 +41,15 @@ impl Class { #[allow(clippy::await_holding_refcell_ref)] // We manually drop Ref https://github.com/rust-lang/rust-clippy/issues/6353 async fn get_resource_as_stream( context: &mut dyn JavaContext, - this: JavaObjectProxy, + this: JvmClassInstanceProxy, name: JvmClassInstanceProxy, - ) -> JavaResult> { + ) -> JavaResult> { let name = String::to_rust_string(context, &name.class_instance)?; - tracing::debug!("java.lang.Class::getResourceAsStream({:#x}, {})", this.ptr_instance, name); + tracing::debug!( + "java.lang.Class::getResourceAsStream({:#x}, {})", + context.instance_raw(&this.class_instance), + name + ); let normalized_name = if let Some(x) = name.strip_prefix('/') { x } else { &name }; @@ -61,13 +65,20 @@ impl Class { drop(data); let result = context.jvm().instantiate_class("java/io/ByteArrayInputStream").await?; - let result = JavaObjectProxy::new(context.instance_raw(&result)); - let array = context.instance_raw(&array); - context.call_method(&result.cast(), "", "([B)V", &[array]).await?; + context + .jvm() + .invoke_method( + &result, + "java/io/ByteArrayInputStream", + "", + "([B)V", + &[JavaValue::Object(Some(array))], + ) + .await?; - Ok(result) + Ok(JvmClassInstanceProxy::new(result)) } else { - Ok(JavaObjectProxy::new(0)) + anyhow::bail!("No such instance") // TODO return null } } } diff --git a/wie_impl_java/src/impl/java/lang/object.rs b/wie_impl_java/src/impl/java/lang/object.rs index e96daf91..5d2ed7ed 100644 --- a/wie_impl_java/src/impl/java/lang/object.rs +++ b/wie_impl_java/src/impl/java/lang/object.rs @@ -2,8 +2,7 @@ use alloc::vec; use crate::{ base::{JavaClassProto, JavaContext, JavaMethodFlag, JavaMethodProto, JavaResult}, - proxy::JavaObjectProxy, - r#impl::java::lang::Class, + proxy::JvmClassInstanceProxy, }; // class java.lang.Object @@ -22,20 +21,19 @@ impl Object { } } - async fn init(_: &mut dyn JavaContext, this: JavaObjectProxy) -> JavaResult<()> { - tracing::debug!("java.lang.Object::({:#x})", this.ptr_instance); + async fn init(context: &mut dyn JavaContext, this: JvmClassInstanceProxy) -> JavaResult<()> { + tracing::debug!("java.lang.Object::({:#x})", context.instance_raw(&this.class_instance)); Ok(()) } - async fn get_class(context: &mut dyn JavaContext, this: JavaObjectProxy) -> JavaResult> { - tracing::warn!("stub java.lang.Object::get_class({:#x})", this.ptr_instance); + async fn get_class(context: &mut dyn JavaContext, this: JvmClassInstanceProxy) -> JavaResult> { + tracing::warn!("stub java.lang.Object::get_class({:#x})", context.instance_raw(&this.class_instance)); let result = context.jvm().instantiate_class("java/lang/Class").await?; - let result = JavaObjectProxy::new(context.instance_raw(&result)); - context.call_method(&result, "", "()V", &[]).await?; + context.jvm().invoke_method(&result, "java/lang/Class", "", "()V", &[]).await?; - Ok(result.cast()) + Ok(JvmClassInstanceProxy::new(result)) } } diff --git a/wie_impl_java/src/impl/java/lang/runtime.rs b/wie_impl_java/src/impl/java/lang/runtime.rs index c90552e3..2a034d24 100644 --- a/wie_impl_java/src/impl/java/lang/runtime.rs +++ b/wie_impl_java/src/impl/java/lang/runtime.rs @@ -2,7 +2,7 @@ use alloc::vec; use crate::{ base::{JavaClassProto, JavaContext, JavaMethodFlag, JavaMethodProto, JavaResult}, - proxy::JavaObjectProxy, + proxy::{JavaObjectProxy, JvmClassInstanceProxy}, }; // class java.lang.Runtime @@ -30,14 +30,13 @@ impl Runtime { Ok(()) } - async fn get_runtime(context: &mut dyn JavaContext) -> JavaResult> { + async fn get_runtime(context: &mut dyn JavaContext) -> JavaResult> { tracing::debug!("java.lang.Runtime::get_runtime"); let instance = context.jvm().instantiate_class("java/lang/Runtime").await?; - let instance = JavaObjectProxy::new(context.instance_raw(&instance)); - context.call_method(&instance.cast(), "", "()V", &[]).await?; + context.jvm().invoke_method(&instance, "java/lang/Runtime", "", "()V", &[]).await?; - Ok(instance) + Ok(JvmClassInstanceProxy::new(instance)) } async fn total_memory(_: &mut dyn JavaContext, this: JavaObjectProxy) -> JavaResult { diff --git a/wie_impl_java/src/impl/java/lang/string.rs b/wie_impl_java/src/impl/java/lang/string.rs index 77d3c240..648b3b64 100644 --- a/wie_impl_java/src/impl/java/lang/string.rs +++ b/wie_impl_java/src/impl/java/lang/string.rs @@ -62,9 +62,20 @@ impl String { let count = context.jvm().array_length(&value.class_instance)?; - let this = JavaObjectProxy::new(context.instance_raw(&this.class_instance)); - let value = context.instance_raw(&value.class_instance); - context.call_method(&this, "", "([BII)V", &[value, 0, count as _]).await?; + context + .jvm() + .invoke_method( + &this.class_instance, + "java/lang/String", + "", + "([BII)V", + &[ + JavaValue::Object(Some(value.class_instance)), + JavaValue::Int(0), + JavaValue::Int(count as _), + ], + ) + .await?; Ok(()) } @@ -82,9 +93,20 @@ impl String { let count = context.jvm().array_length(&value.class_instance)?; - let this = JavaObjectProxy::new(context.instance_raw(&this.class_instance)); - let value = context.instance_raw(&value.class_instance); - context.call_method(&this, "", "([CII)V", &[value, 0, count as _]).await?; + context + .jvm() + .invoke_method( + &this.class_instance, + "java/lang/String", + "", + "([CII)V", + &[ + JavaValue::Object(Some(value.class_instance)), + JavaValue::Int(0), + JavaValue::Int(count as _), + ], + ) + .await?; Ok(()) } @@ -138,9 +160,16 @@ impl String { let array = context.jvm().instantiate_array("C", utf16.len()).await?; context.jvm().store_array(&array, 0, &utf16)?; - let this = JavaObjectProxy::new(context.instance_raw(&this.class_instance)); - let array = context.instance_raw(&array); - context.call_method(&this, "", "([C)V", &[array]).await?; + context + .jvm() + .invoke_method( + &this.class_instance, + "java/lang/String", + "", + "([C)V", + &[JavaValue::Object(Some(array))], + ) + .await?; Ok(()) } @@ -323,11 +352,12 @@ impl String { context.jvm().store_array(&java_value, 0, &data)?; let instance = context.jvm().instantiate_class("java/lang/String").await?; - let instance = JavaObjectProxy::new(context.instance_raw(&instance)); - let java_value = context.instance_raw(&java_value); - context.call_method(&instance, "", "([C)V", &[java_value]).await?; + context + .jvm() + .invoke_method(&instance, "java/lang/String", "", "([C)V", &[JavaValue::Object(Some(java_value))]) + .await?; - Ok(JvmClassInstanceProxy::new(context.instance_from_raw(instance.ptr_instance))) + Ok(JvmClassInstanceProxy::new(instance)) } } diff --git a/wie_impl_java/src/impl/java/lang/string_buffer.rs b/wie_impl_java/src/impl/java/lang/string_buffer.rs index 9b1ecd67..8f7077c1 100644 --- a/wie_impl_java/src/impl/java/lang/string_buffer.rs +++ b/wie_impl_java/src/impl/java/lang/string_buffer.rs @@ -10,7 +10,7 @@ use crate::{ base::{JavaClassProto, JavaFieldProto, JavaMethodFlag, JavaMethodProto, JavaWord}, proxy::JvmClassInstanceProxy, r#impl::java::lang::String, - JavaContext, JavaObjectProxy, JavaResult, + JavaContext, JavaResult, }; // class java.lang.StringBuffer @@ -144,24 +144,19 @@ impl StringBuffer { Ok(this) } - async fn to_string(context: &mut dyn JavaContext, this: JvmClassInstanceProxy) -> JavaResult> { + async fn to_string(context: &mut dyn JavaContext, this: JvmClassInstanceProxy) -> JavaResult> { tracing::debug!("java.lang.StringBuffer::toString({:#x})", context.instance_raw(&this.class_instance)); let java_value = context.jvm().get_field(&this.class_instance, "value", "[C")?; let count = context.jvm().get_field(&this.class_instance, "count", "I")?; let string = context.jvm().instantiate_class("java/lang/String").await?; - let string = JavaObjectProxy::new(context.instance_raw(&string)); context - .call_method( - &string.cast(), - "", - "([CII)V", - &[context.instance_raw(java_value.as_object_ref().unwrap()), 0, count.as_int() as _], - ) + .jvm() + .invoke_method(&string, "java/lang/String", "", "([CII)V", &[java_value, JavaValue::Int(0), count]) .await?; - Ok(string) + Ok(JvmClassInstanceProxy::new(string)) } async fn ensure_capacity(context: &mut dyn JavaContext, this: &JvmClassInstanceProxy, capacity: JavaWord) -> JavaResult<()> { diff --git a/wie_impl_java/src/impl/java/lang/thread.rs b/wie_impl_java/src/impl/java/lang/thread.rs index 748ea2bd..60c54f43 100644 --- a/wie_impl_java/src/impl/java/lang/thread.rs +++ b/wie_impl_java/src/impl/java/lang/thread.rs @@ -52,25 +52,31 @@ impl Thread { tracing::debug!("Thread::start({:#x})", context.instance_raw(&this.class_instance)); struct ThreadStartProxy { - runnable: JavaObjectProxy, + thread_id: usize, + runnable: JvmClassInstanceProxy, } #[async_trait::async_trait(?Send)] impl MethodBody for ThreadStartProxy { - #[tracing::instrument(name = "thread", fields(thread = self.runnable.ptr_instance), skip_all)] + #[tracing::instrument(name = "thread", fields(thread = self.thread_id), skip_all)] async fn call(&self, context: &mut dyn JavaContext, _: &[JavaWord]) -> Result { tracing::trace!("Thread start"); - context.call_method(&self.runnable.cast(), "run", "()V", &[]).await?; + context + .jvm() + .invoke_method(&self.runnable.class_instance, "java/lang/Runnable", "run", "()V", &[]) + .await?; Ok(0) } } let target = context.jvm().get_field(&this.class_instance, "target", "Ljava/lang/Runnable;")?; - let target = JavaObjectProxy::new(context.instance_raw(target.as_object_ref().unwrap())); - context.spawn(Box::new(ThreadStartProxy { runnable: target }))?; + context.spawn(Box::new(ThreadStartProxy { + thread_id: context.instance_raw(target.as_object_ref().unwrap()), + runnable: JvmClassInstanceProxy::new(target.as_object().unwrap()), + }))?; Ok(()) } diff --git a/wie_impl_java/src/impl/org/kwis/msp/db/data_base.rs b/wie_impl_java/src/impl/org/kwis/msp/db/data_base.rs index c8b686a3..50f311db 100644 --- a/wie_impl_java/src/impl/org/kwis/msp/db/data_base.rs +++ b/wie_impl_java/src/impl/org/kwis/msp/db/data_base.rs @@ -51,24 +51,30 @@ impl DataBase { async fn open_data_base( context: &mut dyn JavaContext, - data_base_name: JavaObjectProxy, + data_base_name: JvmClassInstanceProxy, record_size: i32, create: i32, - ) -> JavaResult> { + ) -> JavaResult> { tracing::warn!( "stub org.kwis.msp.db.DataBase::openDataBase({:#x}, {}, {})", - data_base_name.ptr_instance, + context.instance_raw(&data_base_name.class_instance), record_size, create ); let instance = context.jvm().instantiate_class("org/kwis/msp/db/DataBase").await?; - let instance = JavaObjectProxy::new(context.instance_raw(&instance)); context - .call_method(&instance.cast(), "", "()V", &[data_base_name.ptr_instance]) + .jvm() + .invoke_method( + &instance, + "org/kwis/msp/db/DataBase", + "", + "()V", + &[JavaValue::Object(Some(data_base_name.class_instance))], + ) .await?; - Ok(instance) + Ok(JvmClassInstanceProxy::new(instance)) } async fn get_number_of_records(context: &mut dyn JavaContext, this: JvmClassInstanceProxy) -> JavaResult { diff --git a/wie_impl_java/src/impl/org/kwis/msp/lcdui/display.rs b/wie_impl_java/src/impl/org/kwis/msp/lcdui/display.rs index 81f465d2..733abc67 100644 --- a/wie_impl_java/src/impl/org/kwis/msp/lcdui/display.rs +++ b/wie_impl_java/src/impl/org/kwis/msp/lcdui/display.rs @@ -96,28 +96,31 @@ impl Display { tracing::warn!("stub org.kwis.msp.lcdui.Display::getDisplay({:#x})", str.ptr_instance); let jlet = context - .call_static_method("org/kwis/msp/lcdui/Jlet", "getActiveJlet", "()Lorg/kwis/msp/lcdui/Jlet;", &[]) + .jvm() + .invoke_static_method("org/kwis/msp/lcdui/Jlet", "getActiveJlet", "()Lorg/kwis/msp/lcdui/Jlet;", &[]) .await?; - let jlet = context.instance_from_raw(jlet); - let display = context.jvm().get_field(&jlet, "dis", "Lorg/kwis/msp/lcdui/Display;")?; + let display = context + .jvm() + .get_field(&jlet.as_object().unwrap(), "dis", "Lorg/kwis/msp/lcdui/Display;")?; Ok(JvmClassInstanceProxy::new(display.as_object_ref().unwrap().clone())) } - async fn get_default_display(context: &mut dyn JavaContext) -> JavaResult> { + async fn get_default_display(context: &mut dyn JavaContext) -> JavaResult> { tracing::debug!("org.kwis.msp.lcdui.Display::getDefaultDisplay"); - let ptr_instance = context - .call_static_method( + let result = context + .jvm() + .invoke_static_method( "org/kwis/msp/lcdui/Display", "getDisplay", "(Ljava/lang/String;)Lorg/kwis/msp/lcdui/Display;", - &[0], + &[JavaValue::Object(None)], ) .await?; - Ok(JavaObjectProxy::new(ptr_instance)) + Ok(JvmClassInstanceProxy::new(result.as_object().unwrap())) } async fn get_docked_card(_: &mut dyn JavaContext) -> JavaResult> { diff --git a/wie_impl_java/src/impl/org/kwis/msp/lcdui/event_queue.rs b/wie_impl_java/src/impl/org/kwis/msp/lcdui/event_queue.rs index bcd774bc..e59cf1da 100644 --- a/wie_impl_java/src/impl/org/kwis/msp/lcdui/event_queue.rs +++ b/wie_impl_java/src/impl/org/kwis/msp/lcdui/event_queue.rs @@ -190,11 +190,13 @@ impl EventQueue { async fn key_event(context: &mut dyn JavaContext, event_type: KeyboardEventType, code: i32) -> JavaResult<()> { let jlet = context - .call_static_method("org/kwis/msp/lcdui/Jlet", "getActiveJlet", "()Lorg/kwis/msp/lcdui/Jlet;", &[]) + .jvm() + .invoke_static_method("org/kwis/msp/lcdui/Jlet", "getActiveJlet", "()Lorg/kwis/msp/lcdui/Jlet;", &[]) .await?; - let jlet = context.instance_from_raw(jlet); - let display = context.jvm().get_field(&jlet, "dis", "Lorg/kwis/msp/lcdui/Display;")?; + let display = context + .jvm() + .get_field(jlet.as_object_ref().unwrap(), "dis", "Lorg/kwis/msp/lcdui/Display;")?; if display.as_object_ref().is_none() { return Ok(()); } @@ -207,19 +209,29 @@ impl EventQueue { return Ok(()); } - let card = JavaObjectProxy::new(context.instance_raw(card.as_object_ref().unwrap())); - context.call_method(&card, "keyNotify", "(II)Z", &[event_type as _, code as _]).await?; + context + .jvm() + .invoke_method( + card.as_object_ref().unwrap(), + "org/kwis/msp/lcdui/Card", + "keyNotify", + "(II)Z", + &[JavaValue::Int(event_type as _), JavaValue::Int(code)], + ) + .await?; Ok(()) } async fn repaint(context: &mut dyn JavaContext) -> JavaResult<()> { let jlet = context - .call_static_method("org/kwis/msp/lcdui/Jlet", "getActiveJlet", "()Lorg/kwis/msp/lcdui/Jlet;", &[]) + .jvm() + .invoke_static_method("org/kwis/msp/lcdui/Jlet", "getActiveJlet", "()Lorg/kwis/msp/lcdui/Jlet;", &[]) .await?; - let jlet = context.instance_from_raw(jlet); - let display = context.jvm().get_field(&jlet, "dis", "Lorg/kwis/msp/lcdui/Display;")?; + let display = context + .jvm() + .get_field(&jlet.as_object().unwrap(), "dis", "Lorg/kwis/msp/lcdui/Display;")?; if display.as_object_ref().is_none() { return Ok(()); } @@ -231,24 +243,30 @@ impl EventQueue { if card.as_object_ref().is_none() { return Ok(()); } - let card = JavaObjectProxy::new(context.instance_raw(card.as_object_ref().unwrap())); let graphics = context.jvm().instantiate_class("org/kwis/msp/lcdui/Graphics").await?; - let graphics = JavaObjectProxy::new(context.instance_raw(&graphics)); context - .call_method( + .jvm() + .invoke_method( &graphics, + "org/kwis/msp/lcdui/Graphics", "", "(Lorg/kwis/msp/lcdui/Display;)V", - &[context.instance_raw(display.as_object_ref().unwrap())], + &[JavaValue::Object(display.as_object())], ) .await?; context - .call_method(&card, "paint", "(Lorg/kwis/msp/lcdui/Graphics;)V", &[graphics.ptr_instance]) + .jvm() + .invoke_method( + card.as_object_ref().unwrap(), + "org/kwis/msp/lcdui/Card", + "paint", + "(Lorg/kwis/msp/lcdui/Graphics;)V", + &[JavaValue::Object(Some(graphics.clone()))], + ) .await?; - let graphics = context.instance_from_raw(graphics.ptr_instance); let java_image = context.jvm().get_field(&graphics, "img", "Lorg/kwis/msp/lcdui/Image;")?; if java_image.as_object_ref().is_some() { diff --git a/wie_impl_java/src/impl/org/kwis/msp/lcdui/font.rs b/wie_impl_java/src/impl/org/kwis/msp/lcdui/font.rs index e0cc7700..f9754126 100644 --- a/wie_impl_java/src/impl/org/kwis/msp/lcdui/font.rs +++ b/wie_impl_java/src/impl/org/kwis/msp/lcdui/font.rs @@ -66,23 +66,27 @@ impl Font { Ok(12) // TODO: hardcoded } - async fn get_default_font(context: &mut dyn JavaContext) -> JavaResult> { + async fn get_default_font(context: &mut dyn JavaContext) -> JavaResult> { tracing::warn!("stub org.kwis.msp.lcdui.Font::getDefaultFont"); let instance = context.jvm().instantiate_class("org/kwis/msp/lcdui/Font").await?; - let instance = JavaObjectProxy::new(context.instance_raw(&instance)); - context.call_method(&instance, "", "()V", &[]).await?; + context + .jvm() + .invoke_method(&instance, "org/kwis/msp/lcdui/Font", "", "()V", &[]) + .await?; - Ok(instance.cast()) + Ok(JvmClassInstanceProxy::new(instance)) } - async fn get_font(context: &mut dyn JavaContext, face: i32, style: i32, size: i32) -> JavaResult> { + async fn get_font(context: &mut dyn JavaContext, face: i32, style: i32, size: i32) -> JavaResult> { tracing::warn!("stub org.kwis.msp.lcdui.Font::getFont({:#x}, {:#x}, {:#x})", face, style, size); let instance = context.jvm().instantiate_class("org/kwis/msp/lcdui/Font").await?; - let instance = JavaObjectProxy::new(context.instance_raw(&instance)); - context.call_method(&instance, "", "()V", &[]).await?; + context + .jvm() + .invoke_method(&instance, "org/kwis/msp/lcdui/Font", "", "()V", &[]) + .await?; - Ok(instance.cast()) + Ok(JvmClassInstanceProxy::new(instance)) } } diff --git a/wie_impl_java/src/impl/org/kwis/msp/lcdui/graphics.rs b/wie_impl_java/src/impl/org/kwis/msp/lcdui/graphics.rs index f422b776..5ba56ae0 100644 --- a/wie_impl_java/src/impl/org/kwis/msp/lcdui/graphics.rs +++ b/wie_impl_java/src/impl/org/kwis/msp/lcdui/graphics.rs @@ -125,14 +125,16 @@ impl Graphics { Ok(()) } - async fn get_font(context: &mut dyn JavaContext, this: JavaObjectProxy) -> JavaResult> { + async fn get_font(context: &mut dyn JavaContext, this: JavaObjectProxy) -> JavaResult> { tracing::warn!("stub org.kwis.msp.lcdui.Graphics::getFont({:#x})", this.ptr_instance); let font = context.jvm().instantiate_class("org/kwis/msp/lcdui/Font").await?; - let font = JavaObjectProxy::new(context.instance_raw(&font)); - context.call_method(&font, "", "()V", &[]).await?; + context + .jvm() + .invoke_method(&font, "org/kwis/msp/lcdui/Font", "", "()V", &[]) + .await?; - Ok(font.cast()) + Ok(JvmClassInstanceProxy::new(font)) } async fn set_color(context: &mut dyn JavaContext, this: JvmClassInstanceProxy, rgb: i32) -> JavaResult<()> { @@ -396,24 +398,27 @@ impl Graphics { if image.as_object_ref().is_some() { Ok(JvmClassInstanceProxy::new(image.as_object_ref().unwrap().clone())) } else { - let width = context.jvm().get_field(this, "w", "I")?.as_int(); - let height = context.jvm().get_field(this, "h", "I")?.as_int(); + let width = context.jvm().get_field(this, "w", "I")?; + let height = context.jvm().get_field(this, "h", "I")?; let image = context - .call_static_method( + .jvm() + .invoke_static_method( "org/kwis/msp/lcdui/Image", "createImage", "(II)Lorg/kwis/msp/lcdui/Image;", - &[width as _, height as _], + &[width, height], ) .await?; - let image = context.instance_from_raw(image); - context - .jvm() - .put_field(this, "img", "Lorg/kwis/msp/lcdui/Image;", JavaValue::Object(Some(image.clone())))?; + context.jvm().put_field( + this, + "img", + "Lorg/kwis/msp/lcdui/Image;", + JavaValue::Object(Some(image.as_object_ref().unwrap().clone())), + )?; - Ok(JvmClassInstanceProxy::new(image)) + Ok(JvmClassInstanceProxy::new(image.as_object().unwrap())) } } } diff --git a/wie_impl_java/src/impl/org/kwis/msp/lcdui/image.rs b/wie_impl_java/src/impl/org/kwis/msp/lcdui/image.rs index fe3a8ed5..4571a52f 100644 --- a/wie_impl_java/src/impl/org/kwis/msp/lcdui/image.rs +++ b/wie_impl_java/src/impl/org/kwis/msp/lcdui/image.rs @@ -61,8 +61,10 @@ impl Image { tracing::debug!("org.kwis.msp.lcdui.Image::createImage({}, {})", width, height); let instance = context.jvm().instantiate_class("org/kwis/msp/lcdui/Image").await?; - let instance = JavaObjectProxy::new(context.instance_raw(&instance)); - context.call_method(&instance, "", "()V", &[]).await?; + context + .jvm() + .invoke_method(&instance, "org/kwis/msp/lcdui/Image", "", "()V", &[]) + .await?; let bytes_per_pixel = 4; @@ -113,24 +115,31 @@ impl Image { Self::create_image_instance(context, image.width(), image.height(), image.raw(), image.bytes_per_pixel()).await } - async fn get_graphics(context: &mut dyn JavaContext, this: JvmClassInstanceProxy) -> JavaResult> { + async fn get_graphics(context: &mut dyn JavaContext, this: JvmClassInstanceProxy) -> JavaResult> { tracing::debug!("org.kwis.msp.lcdui.Image::getGraphics({:#x})", context.instance_raw(&this.class_instance)); - let width = context.jvm().get_field(&this.class_instance, "w", "I")?.as_int(); - let height = context.jvm().get_field(&this.class_instance, "h", "I")?.as_int(); + let width = context.jvm().get_field(&this.class_instance, "w", "I")?; + let height = context.jvm().get_field(&this.class_instance, "h", "I")?; let instance = context.jvm().instantiate_class("org/kwis/msp/lcdui/Graphics").await?; - let instance = JavaObjectProxy::new(context.instance_raw(&instance)); context - .call_method( - &instance.cast(), + .jvm() + .invoke_method( + &instance, + "org/kwis/msp/lcdui/Graphics", "", "(Lorg/kwis/msp/lcdui/Image;IIII)V", - &[context.instance_raw(&this.class_instance), 0, 0, width as _, height as _], + &[ + JavaValue::Object(Some(this.class_instance.clone())), + JavaValue::Int(0), + JavaValue::Int(0), + width, + height, + ], ) .await?; - Ok(instance) + Ok(JvmClassInstanceProxy::new(instance)) } async fn get_width(context: &mut dyn JavaContext, this: JvmClassInstanceProxy) -> JavaResult { @@ -195,15 +204,16 @@ impl Image { bytes_per_pixel: u32, ) -> JavaResult> { let instance = context.jvm().instantiate_class("org/kwis/msp/lcdui/Image").await?; - let instance = JavaObjectProxy::new(context.instance_raw(&instance)); - context.call_method(&instance, "", "()V", &[]).await?; + context + .jvm() + .invoke_method(&instance, "org/kwis/msp/lcdui/Image", "", "()V", &[]) + .await?; let data = data.iter().map(|&x| JavaValue::Byte(x as _)).collect::>(); let data_array = context.jvm().instantiate_array("B", data.len() as _).await?; context.jvm().store_array(&data_array, 0, &data)?; - let instance = context.instance_from_raw(instance.ptr_instance); context.jvm().put_field(&instance, "w", "I", JavaValue::Int(width as _))?; context.jvm().put_field(&instance, "h", "I", JavaValue::Int(height as _))?; context.jvm().put_field(&instance, "imgData", "[B", JavaValue::Object(Some(data_array)))?; diff --git a/wie_impl_java/src/impl/org/kwis/msp/lcdui/jlet.rs b/wie_impl_java/src/impl/org/kwis/msp/lcdui/jlet.rs index 098cb772..6c81d3e3 100644 --- a/wie_impl_java/src/impl/org/kwis/msp/lcdui/jlet.rs +++ b/wie_impl_java/src/impl/org/kwis/msp/lcdui/jlet.rs @@ -45,16 +45,17 @@ impl Jlet { tracing::debug!("org.kwis.msp.lcdui.Jlet::({:#x})", context.instance_raw(&this.class_instance)); let display = context.jvm().instantiate_class("org/kwis/msp/lcdui/Display").await?; - let display = JavaObjectProxy::new(context.instance_raw(&display)); + context - .call_method( + .jvm() + .invoke_method( &display, + "org/kwis/msp/lcdui/Display", "", "(Lorg/kwis/msp/lcdui/Jlet;Lorg/kwis/msp/lcdui/DisplayProxy;)V", - &[context.instance_raw(&this.class_instance), 0], + &[JavaValue::Object(Some(this.class_instance.clone())), JavaValue::Int(0)], ) .await?; - let display = context.instance_from_raw(display.ptr_instance); context.jvm().put_field( &this.class_instance, @@ -64,17 +65,17 @@ impl Jlet { )?; let event_queue = context.jvm().instantiate_class("org/kwis/msp/lcdui/EventQueue").await?; - let event_queue = JavaObjectProxy::new(context.instance_raw(&event_queue)); context - .call_method( + .jvm() + .invoke_method( &event_queue, + "org/kwis/msp/lcdui/EventQueue", "", "(Lorg/kwis/msp/lcdui/Jlet;)V", - &[context.instance_raw(&this.class_instance)], + &[JavaValue::Object(Some(this.class_instance.clone()))], ) .await?; - let event_queue = context.instance_from_raw(event_queue.ptr_instance); context.jvm().put_field( &this.class_instance, "eq", @@ -120,15 +121,22 @@ impl Jlet { pub async fn start(context: &mut dyn JavaContext, main_class_name: &str) -> JavaResult<()> { let main_class_name = main_class_name.replace('.', "/"); - let ptr_main_class = context.jvm().instantiate_class(&main_class_name).await?; - let ptr_main_class = JavaObjectProxy::new(context.instance_raw(&ptr_main_class)); - context.call_method(&ptr_main_class, "", "()V", &[]).await?; + let main_class = context.jvm().instantiate_class(&main_class_name).await?; + context.jvm().invoke_method(&main_class, &main_class_name, "", "()V", &[]).await?; - tracing::debug!("Main class instance: {:#x}", ptr_main_class.ptr_instance); + tracing::debug!("Main class instance: {:#x}", context.instance_raw(&main_class)); let arg = context.jvm().instantiate_array("Ljava/lang/String;", 0).await?; - let arg = context.instance_raw(&arg); - context.call_method(&ptr_main_class, "startApp", "([Ljava/lang/String;)V", &[arg]).await?; + context + .jvm() + .invoke_method( + &main_class, + &main_class_name, + "startApp", + "([Ljava/lang/String;)V", + &[JavaValue::Object(Some(arg))], + ) + .await?; struct StartProxy {} @@ -137,7 +145,8 @@ impl Jlet { #[tracing::instrument(name = "main", skip_all)] async fn call(&self, context: &mut dyn JavaContext, _: &[usize]) -> Result { context - .call_static_method("org/kwis/msp/lcdui/Main", "main", "([Ljava/lang/String;)V", &[]) + .jvm() + .invoke_static_method("org/kwis/msp/lcdui/Main", "main", "([Ljava/lang/String;)V", &[]) .await?; Ok(0) diff --git a/wie_impl_java/src/impl/org/kwis/msp/lcdui/main.rs b/wie_impl_java/src/impl/org/kwis/msp/lcdui/main.rs index dd7c1801..61caa6e1 100644 --- a/wie_impl_java/src/impl/org/kwis/msp/lcdui/main.rs +++ b/wie_impl_java/src/impl/org/kwis/msp/lcdui/main.rs @@ -1,5 +1,7 @@ use alloc::vec; +use jvm::JavaValue; + use crate::{ base::{JavaClassProto, JavaContext, JavaMethodFlag, JavaMethodProto, JavaResult}, proxy::{JavaObjectProxy, JvmArrayClassInstanceProxy}, @@ -35,23 +37,44 @@ impl Main { context.instance_raw(&args.class_instance) ); - let jlet = JavaObjectProxy::new( - context - .call_static_method("org/kwis/msp/lcdui/Jlet", "getActiveJlet", "()Lorg/kwis/msp/lcdui/Jlet;", &[]) - .await?, - ); - let event_queue = JavaObjectProxy::new( - context - .call_method(&jlet, "getEventQueue", "()Lorg/kwis/msp/lcdui/EventQueue;", &[]) - .await?, - ); + let jlet = context + .jvm() + .invoke_static_method("org/kwis/msp/lcdui/Jlet", "getActiveJlet", "()Lorg/kwis/msp/lcdui/Jlet;", &[]) + .await?; + let event_queue = context + .jvm() + .invoke_method( + &jlet.as_object().unwrap(), + "org/kwis/msp/lcdui/Jlet", + "getEventQueue", + "()Lorg/kwis/msp/lcdui/EventQueue;", + &[], + ) + .await?; let event = context.jvm().instantiate_array("I", 4).await?; - let event = context.instance_raw(&event); loop { - context.call_method(&event_queue, "getNextEvent", "([I)V", &[event]).await?; - context.call_method(&event_queue, "dispatchEvent", "([I)V", &[event]).await?; + context + .jvm() + .invoke_method( + event_queue.as_object_ref().unwrap(), + "org/kwis/lcdui/EventQueue", + "getNextEvent", + "([I)V", + &[JavaValue::Object(Some(event.clone()))], + ) + .await?; + context + .jvm() + .invoke_method( + event_queue.as_object_ref().unwrap(), + "org/kwis/lcdui/EventQueue", + "dispatchEvent", + "([I)V", + &[JavaValue::Object(Some(event.clone()))], + ) + .await?; } } } diff --git a/wie_ktf/src/runtime/java/context.rs b/wie_ktf/src/runtime/java/context.rs index 8ca65a02..1bcef8cc 100644 --- a/wie_ktf/src/runtime/java/context.rs +++ b/wie_ktf/src/runtime/java/context.rs @@ -10,7 +10,7 @@ mod name; mod value; mod vtable_builder; -use alloc::{borrow::ToOwned, boxed::Box, format, rc::Rc}; +use alloc::{boxed::Box, format, rc::Rc}; use core::cell::RefCell; use bytemuck::{Pod, Zeroable}; @@ -22,7 +22,7 @@ use wie_backend::{ AsyncCallable, Backend, }; use wie_core_arm::ArmCore; -use wie_impl_java::{r#impl::java::lang::Object, JavaContext, JavaError, JavaMethodBody, JavaObjectProxy, JavaResult, JavaWord}; +use wie_impl_java::{JavaContext, JavaError, JavaMethodBody, JavaResult, JavaWord}; pub use self::name::JavaFullName; use self::{ @@ -30,6 +30,8 @@ use self::{ class_loader::ClassLoader, context_data::JavaContextData, }; +pub type KtfJvmWord = u32; + #[repr(C)] #[derive(Clone, Copy, Pod, Zeroable)] struct JavaExceptionHandler { @@ -112,10 +114,10 @@ impl<'a> KtfJavaContext<'a> { descriptor: "()V".into(), })?; - if let Some(mut x) = clinit { + if let Some(x) = clinit { tracing::trace!("Call "); - class.invoke_static_method(&mut x, &[]).await?; + x.run(&[]).await?; } Ok(()) @@ -151,39 +153,6 @@ impl JavaContext for KtfJavaContext<'_> { Rc::new(RefCell::new(Box::new(JavaArrayClassInstance::from_raw(raw as _, self.core)))) } - async fn call_method(&mut self, proxy: &JavaObjectProxy, method_name: &str, descriptor: &str, args: &[JavaWord]) -> JavaResult { - let instance = JavaClassInstance::from_raw(proxy.ptr_instance as _, self.core); - let class = instance.class()?; - - tracing::trace!("Call {}::{}({})", class.name()?, method_name, descriptor); - - let mut method = class - .method(&JavaFullName { - tag: 0, - name: method_name.to_owned(), - descriptor: descriptor.to_owned(), - })? - .unwrap(); - - Ok(instance.invoke_method(&mut method, args).await? as _) - } - - async fn call_static_method(&mut self, class_name: &str, method_name: &str, descriptor: &str, args: &[JavaWord]) -> JavaResult { - tracing::trace!("Call {}::{}({})", class_name, method_name, descriptor); - - let class = self.load_class(class_name).await?.unwrap(); - - let mut method = class - .method(&JavaFullName { - tag: 0, - name: method_name.to_owned(), - descriptor: descriptor.to_owned(), - })? - .unwrap(); - - Ok(class.invoke_static_method(&mut method, args).await? as _) - } - fn backend(&mut self) -> &mut Backend { self.backend } diff --git a/wie_ktf/src/runtime/java/context/array_class_instance.rs b/wie_ktf/src/runtime/java/context/array_class_instance.rs index d0f87889..936508c5 100644 --- a/wie_ktf/src/runtime/java/context/array_class_instance.rs +++ b/wie_ktf/src/runtime/java/context/array_class_instance.rs @@ -72,20 +72,11 @@ impl JavaArrayClassInstance { let base_address = self.class_instance.field_address(4)?; let element_size = self.element_size()?; - let element_type = self.element_type_descriptor()?; let raw_values = match element_size { - 1 => values.iter().map(|x| x.as_raw(&element_type) as u8).collect::>(), - 2 => values - .iter() - .map(|x| x.as_raw(&element_type) as u16) - .flat_map(u16::to_le_bytes) - .collect::>(), - 4 => values - .iter() - .map(|x| x.as_raw(&element_type) as u32) - .flat_map(u32::to_le_bytes) - .collect::>(), + 1 => values.iter().map(|x| x.as_raw() as u8).collect::>(), + 2 => values.iter().map(|x| x.as_raw() as u16).flat_map(u16::to_le_bytes).collect::>(), + 4 => values.iter().map(|x| x.as_raw()).flat_map(u32::to_le_bytes).collect::>(), _ => todo!(), }; diff --git a/wie_ktf/src/runtime/java/context/class.rs b/wie_ktf/src/runtime/java/context/class.rs index 138d8b0e..9f886d6b 100644 --- a/wie_ktf/src/runtime/java/context/class.rs +++ b/wie_ktf/src/runtime/java/context/class.rs @@ -18,7 +18,7 @@ use wie_impl_java::{JavaClassProto, JavaFieldAccessFlag, JavaResult, JavaWord}; use super::{ class_instance::JavaClassInstance, class_loader::ClassLoader, field::JavaField, method::JavaMethod, value::JavaValueExt, - vtable_builder::JavaVtableBuilder, JavaFullName, KtfJavaContext, + vtable_builder::JavaVtableBuilder, JavaFullName, KtfJavaContext, KtfJvmWord, }; #[repr(C)] @@ -245,21 +245,17 @@ impl JavaClass { Ok(None) } - pub fn read_static_field(&self, field: &JavaField) -> JavaResult { + pub fn read_static_field(&self, field: &JavaField) -> JavaResult { let address = field.static_address()?; - let result: u32 = read_generic(&self.core, address)?; + let result: KtfJvmWord = read_generic(&self.core, address)?; Ok(result as _) } - pub fn write_static_field(&mut self, field: &JavaField, value: JavaWord) -> JavaResult<()> { + pub fn write_static_field(&mut self, field: &JavaField, value: KtfJvmWord) -> JavaResult<()> { let address = field.static_address()?; - write_generic(&mut self.core, address, value as u32) - } - - pub async fn invoke_static_method(&self, method: &mut JavaMethod, args: &[JavaWord]) -> JavaResult { - method.run(args).await + write_generic(&mut self.core, address, value) } } @@ -301,7 +297,7 @@ impl Class for JavaClass { fn put_static_field(&mut self, field: &dyn Field, value: JavaValue) -> JvmResult<()> { let field = field.as_any().downcast_ref::().unwrap(); - let value = value.as_raw(&field.descriptor()); + let value = value.as_raw(); self.write_static_field(field, value as _) } diff --git a/wie_ktf/src/runtime/java/context/class_instance.rs b/wie_ktf/src/runtime/java/context/class_instance.rs index 05ede75b..8007e37c 100644 --- a/wie_ktf/src/runtime/java/context/class_instance.rs +++ b/wie_ktf/src/runtime/java/context/class_instance.rs @@ -1,4 +1,4 @@ -use alloc::{boxed::Box, string::String, vec, vec::Vec}; +use alloc::{boxed::Box, string::String, vec::Vec}; use core::{iter, mem::size_of}; use bytemuck::{Pod, Zeroable}; @@ -11,7 +11,7 @@ use wie_impl_java::{JavaResult, JavaWord}; use crate::runtime::java::context::context_data::JavaContextData; -use super::{class::JavaClass, field::JavaField, method::JavaMethod, value::JavaValueExt}; +use super::{class::JavaClass, field::JavaField, value::JavaValueExt, KtfJvmWord}; #[repr(C)] #[derive(Clone, Copy, Pod, Zeroable)] @@ -62,29 +62,22 @@ impl JavaClassInstance { Ok(JavaClass::from_raw(raw.ptr_class, &self.core)) } - pub fn read_field(&self, field: &JavaField) -> JavaResult { + pub fn read_field(&self, field: &JavaField) -> JavaResult { let offset = field.offset()?; let address = self.field_address(offset)?; - let value: u32 = read_generic(&self.core, address)?; + let value: KtfJvmWord = read_generic(&self.core, address)?; - Ok(value as _) + Ok(value) } - pub fn write_field(&mut self, field: &JavaField, value: JavaWord) -> JavaResult<()> { + pub fn write_field(&mut self, field: &JavaField, value: KtfJvmWord) -> JavaResult<()> { let offset = field.offset()?; let address = self.field_address(offset)?; - write_generic(&mut self.core, address, value as u32) - } - - pub async fn invoke_method(&self, method: &mut JavaMethod, args: &[JavaWord]) -> JavaResult { - let mut params = vec![self.ptr_raw as _]; - params.extend(args); - - method.run(¶ms).await + write_generic(&mut self.core, address, value) } pub(super) fn field_address(&self, offset: u32) -> JavaResult { @@ -144,7 +137,7 @@ impl ClassInstance for JavaClassInstance { fn put_field(&mut self, field: &dyn Field, value: JavaValue) -> JvmResult<()> { let field = field.as_any().downcast_ref::().unwrap(); - self.write_field(field, value.as_raw(&field.descriptor())) + self.write_field(field, value.as_raw()) } fn as_array_instance(&self) -> Option<&dyn ArrayClassInstance> { diff --git a/wie_ktf/src/runtime/java/context/method.rs b/wie_ktf/src/runtime/java/context/method.rs index 8fccf47a..ef4b8653 100644 --- a/wie_ktf/src/runtime/java/context/method.rs +++ b/wie_ktf/src/runtime/java/context/method.rs @@ -10,7 +10,7 @@ use wie_base::util::{read_generic, write_generic, ByteWrite}; use wie_core_arm::{Allocator, ArmCore, ArmEngineError, EmulatedFunction, EmulatedFunctionParam}; use wie_impl_java::{JavaMethodBody, JavaMethodFlag, JavaMethodProto, JavaResult, JavaWord}; -use super::{vtable_builder::JavaVtableBuilder, JavaFullName, KtfJavaContext}; +use super::{value::JavaValueExt, vtable_builder::JavaVtableBuilder, JavaFullName, KtfJavaContext}; #[repr(C)] #[derive(Clone, Copy, Pod, Zeroable)] @@ -106,7 +106,7 @@ impl JavaMethod { JavaFullName::from_ptr(&self.core, raw.ptr_name) } - pub async fn run(&self, args: &[JavaWord]) -> JavaResult { + pub async fn run(&self, args: &[JavaValue]) -> JavaResult { let raw: RawJavaMethod = read_generic(&self.core, self.ptr_raw)?; let mut core = self.core.clone(); @@ -114,7 +114,7 @@ impl JavaMethod { if raw.flag.contains(JavaMethodFlagBit::NATIVE) { let arg_container = Allocator::alloc(&mut core, (args.len() as u32) * 4)?; for (i, arg) in args.iter().enumerate() { - write_generic(&mut core, arg_container + (i * 4) as u32, *arg as u32)?; + write_generic(&mut core, arg_container + (i * 4) as u32, arg.as_raw())?; } let result = core.run_function(raw.fn_body_native_or_exception_table, &[0, arg_container]).await; @@ -124,7 +124,7 @@ impl JavaMethod { result } else { let mut params = vec![0]; - params.extend(args.iter().map(|&x| x as u32)); + params.extend(args.iter().map(|x| x.as_raw())); core.run_function(raw.fn_body, ¶ms).await } @@ -189,9 +189,9 @@ impl Method for JavaMethod { } async fn run(&self, _jvm: &mut Jvm, args: &[JavaValue]) -> JvmResult { - let args = args.iter().map(|x| x.as_long() as _).collect::>(); - let result = self.run(&args).await?; + let result = self.run(args).await?; + let return_type = &self.descriptor()[self.descriptor().find(')').unwrap() + 1..]; - Ok(JavaValue::Long(result as _)) + Ok(JavaValue::from_raw(result, return_type, &self.core)) } } diff --git a/wie_ktf/src/runtime/java/context/value.rs b/wie_ktf/src/runtime/java/context/value.rs index afa3ef91..708c8261 100644 --- a/wie_ktf/src/runtime/java/context/value.rs +++ b/wie_ktf/src/runtime/java/context/value.rs @@ -4,31 +4,31 @@ use core::cell::RefCell; use jvm::{JavaType, JavaValue}; use wie_core_arm::ArmCore; -use wie_impl_java::JavaWord; -use super::{array_class_instance::JavaArrayClassInstance, class_instance::JavaClassInstance}; +use super::{array_class_instance::JavaArrayClassInstance, class_instance::JavaClassInstance, KtfJvmWord}; pub trait JavaValueExt { - fn from_raw(raw: JavaWord, descriptor: &str, core: &ArmCore) -> JavaValue; - fn as_raw(&self, descriptor: &str) -> JavaWord; + fn from_raw(raw: KtfJvmWord, descriptor: &str, core: &ArmCore) -> JavaValue; + fn as_raw(&self) -> KtfJvmWord; } impl JavaValueExt for JavaValue { - fn from_raw(raw: JavaWord, descriptor: &str, core: &ArmCore) -> JavaValue { + fn from_raw(raw: KtfJvmWord, descriptor: &str, core: &ArmCore) -> JavaValue { let r#type = JavaType::parse(descriptor); match r#type { + JavaType::Void => JavaValue::Boolean(true), // TODO JavaType::Boolean => JavaValue::Boolean(raw != 0), JavaType::Byte => JavaValue::Byte(raw as i8), JavaType::Short => JavaValue::Short(raw as i16), JavaType::Int => JavaValue::Int(raw as i32), JavaType::Long => JavaValue::Long(raw as i64), - JavaType::Float => JavaValue::Float(f32::from_bits(raw as u32)), + JavaType::Float => JavaValue::Float(f32::from_bits(raw)), JavaType::Double => JavaValue::Double(f64::from_bits(raw as u64)), JavaType::Char => JavaValue::Char(raw as u16), JavaType::Class(_) => { if raw != 0 { - let instance = JavaClassInstance::from_raw(raw as u32, core); + let instance = JavaClassInstance::from_raw(raw, core); JavaValue::Object(Some(Rc::new(RefCell::new(Box::new(instance))))) } else { @@ -37,7 +37,7 @@ impl JavaValueExt for JavaValue { } JavaType::Array(_) => { if raw != 0 { - let instance = JavaArrayClassInstance::from_raw(raw as u32, core); + let instance = JavaArrayClassInstance::from_raw(raw, core); JavaValue::Object(Some(Rc::new(RefCell::new(Box::new(instance))))) } else { @@ -48,39 +48,30 @@ impl JavaValueExt for JavaValue { } } - fn as_raw(&self, descriptor: &str) -> JavaWord { - let r#type = JavaType::parse(descriptor); - - match r#type { - JavaType::Boolean => self.as_boolean() as u32 as JavaWord, - JavaType::Byte => self.as_byte() as u32 as JavaWord, - JavaType::Short => self.as_short() as u32 as JavaWord, - JavaType::Int => self.as_int() as u32 as JavaWord, - JavaType::Long => self.as_long() as JavaWord, - JavaType::Float => self.as_float().to_bits() as JavaWord, - JavaType::Double => self.as_double().to_bits() as JavaWord, - JavaType::Char => self.as_char() as u32 as JavaWord, - JavaType::Class(_) => { - if let Some(x) = self.as_object_ref() { + fn as_raw(&self) -> KtfJvmWord { + match self { + JavaValue::Boolean(x) => *x as _, + JavaValue::Byte(x) => *x as _, + JavaValue::Short(x) => *x as _, + JavaValue::Int(x) => *x as _, + JavaValue::Long(x) => *x as _, + JavaValue::Float(x) => x.to_bits() as _, + JavaValue::Double(x) => x.to_bits() as _, + JavaValue::Char(x) => *x as _, + JavaValue::Object(x) => { + if let Some(x) = x { let instance = x.as_ref().borrow(); - let instance = instance.as_any().downcast_ref::().unwrap(); - - instance.ptr_raw as _ + if let Some(x) = instance.as_any().downcast_ref::() { + x.ptr_raw as _ + } else if let Some(x) = instance.as_any().downcast_ref::() { + x.class_instance.ptr_raw as _ + } else { + panic!("Unknown instance type") + } } else { 0 } } - JavaType::Array(_) => { - if let Some(x) = self.as_object_ref() { - let instance = x.as_ref().borrow(); - let instance = instance.as_any().downcast_ref::().unwrap(); - - instance.class_instance.ptr_raw as _ - } else { - 0 - } - } - _ => todo!(), } } }