Skip to content

Commit

Permalink
Port method call to use jvm
Browse files Browse the repository at this point in the history
  • Loading branch information
dlunch committed Dec 28, 2023
1 parent b581113 commit b737b78
Show file tree
Hide file tree
Showing 24 changed files with 352 additions and 300 deletions.
14 changes: 1 addition & 13 deletions wie_impl_java/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand Down Expand Up @@ -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<Object>,
method_name: &str,
descriptor: &str,
args: &[JavaWord],
) -> JavaResult<JavaWord>; // invokespecial/invokevirtual
async fn call_static_method(&mut self, class_name: &str, method_name: &str, descriptor: &str, args: &[JavaWord]) -> JavaResult<JavaWord>; // invokestatic
fn backend(&mut self) -> &mut Backend;
fn spawn(&mut self, callback: JavaMethodBody) -> JavaResult<()>;
fn sleep(&mut self, duration: u64) -> SleepFuture;
Expand Down
14 changes: 7 additions & 7 deletions wie_impl_java/src/impl/java/io/byte_array_input_stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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?;
Expand Down
31 changes: 12 additions & 19 deletions wie_impl_java/src/impl/java/io/data_input_stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand All @@ -75,30 +71,27 @@ 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<Self>) -> JavaResult<()> {
tracing::debug!("java.lang.DataInputStream::close({:#x})", context.instance_raw(&this.class_instance));

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(())
Expand Down
22 changes: 18 additions & 4 deletions wie_impl_java/src/impl/java/io/input_stream.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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())
}
}
27 changes: 19 additions & 8 deletions wie_impl_java/src/impl/java/lang/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Class>,
this: JvmClassInstanceProxy<Self>,
name: JvmClassInstanceProxy<String>,
) -> JavaResult<JavaObjectProxy<InputStream>> {
) -> JavaResult<JvmClassInstanceProxy<InputStream>> {
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 };

Expand All @@ -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(), "<init>", "([B)V", &[array]).await?;
context
.jvm()
.invoke_method(
&result,
"java/io/ByteArrayInputStream",
"<init>",
"([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
}
}
}
16 changes: 7 additions & 9 deletions wie_impl_java/src/impl/java/lang/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -22,20 +21,19 @@ impl Object {
}
}

async fn init(_: &mut dyn JavaContext, this: JavaObjectProxy<Object>) -> JavaResult<()> {
tracing::debug!("java.lang.Object::<init>({:#x})", this.ptr_instance);
async fn init(context: &mut dyn JavaContext, this: JvmClassInstanceProxy<Self>) -> JavaResult<()> {
tracing::debug!("java.lang.Object::<init>({:#x})", context.instance_raw(&this.class_instance));

Ok(())
}

async fn get_class(context: &mut dyn JavaContext, this: JavaObjectProxy<Object>) -> JavaResult<JavaObjectProxy<Class>> {
tracing::warn!("stub java.lang.Object::get_class({:#x})", this.ptr_instance);
async fn get_class(context: &mut dyn JavaContext, this: JvmClassInstanceProxy<Self>) -> JavaResult<JvmClassInstanceProxy<Self>> {
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, "<init>", "()V", &[]).await?;
context.jvm().invoke_method(&result, "java/lang/Class", "<init>", "()V", &[]).await?;

Ok(result.cast())
Ok(JvmClassInstanceProxy::new(result))
}
}
9 changes: 4 additions & 5 deletions wie_impl_java/src/impl/java/lang/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use alloc::vec;

use crate::{
base::{JavaClassProto, JavaContext, JavaMethodFlag, JavaMethodProto, JavaResult},
proxy::JavaObjectProxy,
proxy::{JavaObjectProxy, JvmClassInstanceProxy},
};

// class java.lang.Runtime
Expand Down Expand Up @@ -30,14 +30,13 @@ impl Runtime {
Ok(())
}

async fn get_runtime(context: &mut dyn JavaContext) -> JavaResult<JavaObjectProxy<Runtime>> {
async fn get_runtime(context: &mut dyn JavaContext) -> JavaResult<JvmClassInstanceProxy<Self>> {
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(), "<init>", "()V", &[]).await?;
context.jvm().invoke_method(&instance, "java/lang/Runtime", "<init>", "()V", &[]).await?;

Ok(instance)
Ok(JvmClassInstanceProxy::new(instance))
}

async fn total_memory(_: &mut dyn JavaContext, this: JavaObjectProxy<Runtime>) -> JavaResult<i32> {
Expand Down
56 changes: 43 additions & 13 deletions wie_impl_java/src/impl/java/lang/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, "<init>", "([BII)V", &[value, 0, count as _]).await?;
context
.jvm()
.invoke_method(
&this.class_instance,
"java/lang/String",
"<init>",
"([BII)V",
&[
JavaValue::Object(Some(value.class_instance)),
JavaValue::Int(0),
JavaValue::Int(count as _),
],
)
.await?;

Ok(())
}
Expand All @@ -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, "<init>", "([CII)V", &[value, 0, count as _]).await?;
context
.jvm()
.invoke_method(
&this.class_instance,
"java/lang/String",
"<init>",
"([CII)V",
&[
JavaValue::Object(Some(value.class_instance)),
JavaValue::Int(0),
JavaValue::Int(count as _),
],
)
.await?;

Ok(())
}
Expand Down Expand Up @@ -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, "<init>", "([C)V", &[array]).await?;
context
.jvm()
.invoke_method(
&this.class_instance,
"java/lang/String",
"<init>",
"([C)V",
&[JavaValue::Object(Some(array))],
)
.await?;

Ok(())
}
Expand Down Expand Up @@ -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, "<init>", "([C)V", &[java_value]).await?;
context
.jvm()
.invoke_method(&instance, "java/lang/String", "<init>", "([C)V", &[JavaValue::Object(Some(java_value))])
.await?;

Ok(JvmClassInstanceProxy::new(context.instance_from_raw(instance.ptr_instance)))
Ok(JvmClassInstanceProxy::new(instance))
}
}
15 changes: 5 additions & 10 deletions wie_impl_java/src/impl/java/lang/string_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -144,24 +144,19 @@ impl StringBuffer {
Ok(this)
}

async fn to_string(context: &mut dyn JavaContext, this: JvmClassInstanceProxy<Self>) -> JavaResult<JavaObjectProxy<String>> {
async fn to_string(context: &mut dyn JavaContext, this: JvmClassInstanceProxy<Self>) -> JavaResult<JvmClassInstanceProxy<String>> {
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(),
"<init>",
"([CII)V",
&[context.instance_raw(java_value.as_object_ref().unwrap()), 0, count.as_int() as _],
)
.jvm()
.invoke_method(&string, "java/lang/String", "<init>", "([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<Self>, capacity: JavaWord) -> JavaResult<()> {
Expand Down
Loading

0 comments on commit b737b78

Please sign in to comment.