Skip to content

Commit

Permalink
Port instantiate to jvm
Browse files Browse the repository at this point in the history
  • Loading branch information
dlunch committed Dec 28, 2023
1 parent 7c82dc0 commit b581113
Show file tree
Hide file tree
Showing 18 changed files with 77 additions and 90 deletions.
2 changes: 0 additions & 2 deletions wie_impl_java/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,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 instantiate(&mut self, type_name: &str) -> JavaResult<JavaObjectProxy<Object>>; // new
async fn instantiate_array(&mut self, element_type_name: &str, count: JavaWord) -> JavaResult<JavaObjectProxy<Object>>; // newarray
async fn call_method(
&mut self,
instance: &JavaObjectProxy<Object>,
Expand Down
11 changes: 6 additions & 5 deletions wie_impl_java/src/impl/java/lang/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,16 @@ impl Class {
let backend1 = context.backend().clone();
let data = Ref::map(backend1.resource(), |x| x.data(id));

let array = context.instantiate_array("B", data.len() as _).await?;
let array_instance = context.array_instance_from_raw(array.ptr_instance);
let array = context.jvm().instantiate_array("B", data.len() as _).await?;

let data = data.iter().map(|&x| JavaValue::Byte(x as _)).collect::<Vec<_>>();
context.jvm().store_array(&array_instance, 0, &data)?;
context.jvm().store_array(&array, 0, &data)?;
drop(data);

let result = context.instantiate("Ljava/io/ByteArrayInputStream;").await?.cast();
context.call_method(&result.cast(), "<init>", "([B)V", &[array.ptr_instance]).await?;
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?;

Ok(result)
} else {
Expand Down
8 changes: 5 additions & 3 deletions wie_impl_java/src/impl/java/lang/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ impl Object {
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);

let result = context.instantiate("Ljava/lang/Class;").await?.cast();
context.call_method(&result.cast(), "<init>", "()V", &[]).await?;
let result = context.jvm().instantiate_class("java/lang/Class").await?;
let result = JavaObjectProxy::new(context.instance_raw(&result));

Ok(result)
context.call_method(&result, "<init>", "()V", &[]).await?;

Ok(result.cast())
}
}
3 changes: 2 additions & 1 deletion wie_impl_java/src/impl/java/lang/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ impl Runtime {
async fn get_runtime(context: &mut dyn JavaContext) -> JavaResult<JavaObjectProxy<Runtime>> {
tracing::debug!("java.lang.Runtime::get_runtime");

let instance = context.instantiate("Ljava/lang/Runtime;").await?.cast();
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?;

Ok(instance)
Expand Down
15 changes: 6 additions & 9 deletions wie_impl_java/src/impl/java/lang/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ impl String {
count
);

let array = context.instantiate_array("C", count as _).await?;
let array = context.array_instance_from_raw(array.ptr_instance);
let array = context.jvm().instantiate_array("C", count as _).await?;
context
.jvm()
.put_field(&this.class_instance, "value", "[C", JavaValue::Object(Some(array.clone())))?;
Expand Down Expand Up @@ -136,8 +135,7 @@ impl String {

let utf16 = string.encode_utf16().map(JavaValue::Char).collect::<Vec<_>>();

let array = context.instantiate_array("C", utf16.len()).await?;
let array = context.array_instance_from_raw(array.ptr_instance);
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));
Expand Down Expand Up @@ -201,8 +199,7 @@ impl String {
let bytes = encode_str(&string);
let bytes = bytes.into_iter().map(|x| JavaValue::Byte(x as _)).collect::<Vec<_>>();

let byte_array = context.instantiate_array("B", bytes.len()).await?;
let byte_array = context.instance_from_raw(byte_array.ptr_instance);
let byte_array = context.jvm().instantiate_array("B", bytes.len()).await?;
context.jvm().store_array(&byte_array, 0, &bytes)?;

Ok(JvmArrayClassInstanceProxy::new(byte_array))
Expand Down Expand Up @@ -320,13 +317,13 @@ impl String {
}

pub async fn from_utf16(context: &mut dyn JavaContext, data: &[u16]) -> JavaResult<JvmClassInstanceProxy<Self>> {
let java_value = context.instantiate_array("C", data.len()).await?;
let java_value = context.array_instance_from_raw(java_value.ptr_instance);
let java_value = context.jvm().instantiate_array("C", data.len()).await?;

let data = data.iter().map(|&x| JavaValue::Char(x)).collect::<Vec<_>>();
context.jvm().store_array(&java_value, 0, &data)?;

let instance = context.instantiate("Ljava/lang/String;").await?;
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?;
Expand Down
15 changes: 7 additions & 8 deletions wie_impl_java/src/impl/java/lang/string_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,10 @@ impl StringBuffer {
async fn init(context: &mut dyn JavaContext, this: JvmClassInstanceProxy<Self>) -> JavaResult<()> {
tracing::debug!("java.lang.StringBuffer::<init>({:#x})", context.instance_raw(&this.class_instance));

let array = context.instantiate_array("C", 16).await?;
let java_value_array = context.array_instance_from_raw(array.ptr_instance);
let array = context.jvm().instantiate_array("C", 16).await?;
context
.jvm()
.put_field(&this.class_instance, "value", "[C", JavaValue::Object(Some(java_value_array)))?;
.put_field(&this.class_instance, "value", "[C", JavaValue::Object(Some(array)))?;
context.jvm().put_field(&this.class_instance, "count", "I", JavaValue::Int(0))?;

Ok(())
Expand Down Expand Up @@ -151,7 +150,8 @@ impl StringBuffer {
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.instantiate("Ljava/lang/String;").await?.cast();
let string = context.jvm().instantiate_class("java/lang/String").await?;
let string = JavaObjectProxy::new(context.instance_raw(&string));
context
.call_method(
&string.cast(),
Expand All @@ -172,12 +172,11 @@ impl StringBuffer {
let old_values = context.jvm().load_array(java_value_array.as_object_ref().unwrap(), 0, current_capacity)?;
let new_capacity = capacity * 2;

let java_new_value_array = context.instantiate_array("C", new_capacity).await?;
let new_value = context.instance_from_raw(java_new_value_array.ptr_instance);
let java_new_value_array = context.jvm().instantiate_array("C", new_capacity).await?;
context
.jvm()
.put_field(&this.class_instance, "value", "[C", JavaValue::Object(Some(new_value.clone())))?;
context.jvm().store_array(&new_value, 0, &old_values)?;
.put_field(&this.class_instance, "value", "[C", JavaValue::Object(Some(java_new_value_array.clone())))?;
context.jvm().store_array(&java_new_value_array, 0, &old_values)?;
}

Ok(())
Expand Down
3 changes: 1 addition & 2 deletions wie_impl_java/src/impl/java/lang/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,9 @@ impl System {
async fn cl_init(context: &mut dyn JavaContext) -> JavaResult<()> {
tracing::debug!("java.lang.System::<clinit>()");

let out = context.instantiate("Ljava/io/PrintStream;").await?;
let out = context.jvm().instantiate_class("java/io/PrintStream").await?;
// TODO call constructor with dummy output stream?

let out = context.instance_from_raw(out.ptr_instance);
context
.jvm()
.put_static_field("java/lang/System", "out", "Ljava/io/PrintStream;", JavaValue::Object(Some(out)))
Expand Down
9 changes: 5 additions & 4 deletions wie_impl_java/src/impl/java/util/calendar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use alloc::vec;

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

// class java.util.Calendar
Expand All @@ -23,12 +24,12 @@ impl Calendar {
}
}

async fn get_instance(context: &mut dyn JavaContext) -> JavaResult<JavaObjectProxy<Calendar>> {
async fn get_instance(context: &mut dyn JavaContext) -> JavaResult<JvmClassInstanceProxy<Calendar>> {
tracing::warn!("stub java.util.Calendar::getInstance()");

let instance = context.instantiate("Ljava/util/GregorianCalendar;").await?.cast();
let instance = context.jvm().instantiate_class("java/util/GregorianCalendar").await?;
// TODO call <init>

Ok(instance)
Ok(JvmClassInstanceProxy::new(instance))
}
}
6 changes: 3 additions & 3 deletions wie_impl_java/src/impl/org/kwis/msp/db/data_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ impl DataBase {
create
);

let instance = context.instantiate("Lorg/kwis/msp/db/DataBase;").await?.cast();
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(), "<init>", "()V", &[data_base_name.ptr_instance])
.await?;
Expand Down Expand Up @@ -133,8 +134,7 @@ impl DataBase {
let data = context.backend().database().open(&db_name_str)?.get(record_id as _)?;
let data = data.into_iter().map(|x| JavaValue::Byte(x as _)).collect::<Vec<_>>();

let array = context.instantiate_array("B", data.len() as _).await?;
let array = context.array_instance_from_raw(array.ptr_instance);
let array = context.jvm().instantiate_array("B", data.len() as _).await?;
context.jvm().store_array(&array, 0, &data)?;

Ok(JvmArrayClassInstanceProxy::new(array))
Expand Down
3 changes: 1 addition & 2 deletions wie_impl_java/src/impl/org/kwis/msp/lcdui/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ impl Display {
display_proxy.ptr_instance
);

let cards = context.instantiate_array("Lorg/kwis/msp/lcdui/Card;", 1).await?;
let cards = context.array_instance_from_raw(cards.ptr_instance);
let cards = context.jvm().instantiate_array("Lorg/kwis/msp/lcdui/Card;", 1).await?;
context.jvm().put_field(
&this.class_instance,
"cards",
Expand Down
3 changes: 2 additions & 1 deletion wie_impl_java/src/impl/org/kwis/msp/lcdui/event_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ impl EventQueue {
}
let card = JavaObjectProxy::new(context.instance_raw(card.as_object_ref().unwrap()));

let graphics = context.instantiate("Lorg/kwis/msp/lcdui/Graphics;").await?;
let graphics = context.jvm().instantiate_class("org/kwis/msp/lcdui/Graphics").await?;
let graphics = JavaObjectProxy::new(context.instance_raw(&graphics));
context
.call_method(
&graphics,
Expand Down
6 changes: 4 additions & 2 deletions wie_impl_java/src/impl/org/kwis/msp/lcdui/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ impl Font {
async fn get_default_font(context: &mut dyn JavaContext) -> JavaResult<JavaObjectProxy<Font>> {
tracing::warn!("stub org.kwis.msp.lcdui.Font::getDefaultFont");

let instance = context.instantiate("Lorg/kwis/msp/lcdui/Font;").await?;
let instance = context.jvm().instantiate_class("org/kwis/msp/lcdui/Font").await?;
let instance = JavaObjectProxy::new(context.instance_raw(&instance));
context.call_method(&instance, "<init>", "()V", &[]).await?;

Ok(instance.cast())
Expand All @@ -78,7 +79,8 @@ impl Font {
async fn get_font(context: &mut dyn JavaContext, face: i32, style: i32, size: i32) -> JavaResult<JavaObjectProxy<Font>> {
tracing::warn!("stub org.kwis.msp.lcdui.Font::getFont({:#x}, {:#x}, {:#x})", face, style, size);

let instance = context.instantiate("Lorg/kwis/msp/lcdui/Font;").await?;
let instance = context.jvm().instantiate_class("org/kwis/msp/lcdui/Font").await?;
let instance = JavaObjectProxy::new(context.instance_raw(&instance));
context.call_method(&instance, "<init>", "()V", &[]).await?;

Ok(instance.cast())
Expand Down
7 changes: 4 additions & 3 deletions wie_impl_java/src/impl/org/kwis/msp/lcdui/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,11 @@ impl Graphics {
async fn get_font(context: &mut dyn JavaContext, this: JavaObjectProxy<Graphics>) -> JavaResult<JavaObjectProxy<Font>> {
tracing::warn!("stub org.kwis.msp.lcdui.Graphics::getFont({:#x})", this.ptr_instance);

let font = context.instantiate("Lorg/kwis/msp/lcdui/Font;").await?.cast();
context.call_method(&font.cast(), "<init>", "()V", &[]).await?;
let font = context.jvm().instantiate_class("org/kwis/msp/lcdui/Font").await?;
let font = JavaObjectProxy::new(context.instance_raw(&font));
context.call_method(&font, "<init>", "()V", &[]).await?;

Ok(font)
Ok(font.cast())
}

async fn set_color(context: &mut dyn JavaContext, this: JvmClassInstanceProxy<Self>, rgb: i32) -> JavaResult<()> {
Expand Down
16 changes: 9 additions & 7 deletions wie_impl_java/src/impl/org/kwis/msp/lcdui/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ impl Image {
async fn create_image(context: &mut dyn JavaContext, width: i32, height: i32) -> JavaResult<JvmClassInstanceProxy<Image>> {
tracing::debug!("org.kwis.msp.lcdui.Image::createImage({}, {})", width, height);

let instance = context.instantiate("Lorg/kwis/msp/lcdui/Image;").await?;
context.call_method(&instance.cast(), "<init>", "()V", &[]).await?;
let instance = context.jvm().instantiate_class("org/kwis/msp/lcdui/Image").await?;
let instance = JavaObjectProxy::new(context.instance_raw(&instance));
context.call_method(&instance, "<init>", "()V", &[]).await?;

let bytes_per_pixel = 4;

Expand Down Expand Up @@ -118,7 +119,8 @@ impl Image {
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 instance = context.instantiate("Lorg/kwis/msp/lcdui/Graphics;").await?.cast();
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(),
Expand Down Expand Up @@ -192,13 +194,13 @@ impl Image {
data: &[u8],
bytes_per_pixel: u32,
) -> JavaResult<JvmClassInstanceProxy<Image>> {
let instance = context.instantiate("Lorg/kwis/msp/lcdui/Image;").await?;
context.call_method(&instance.cast(), "<init>", "()V", &[]).await?;
let instance = context.jvm().instantiate_class("org/kwis/msp/lcdui/Image").await?;
let instance = JavaObjectProxy::new(context.instance_raw(&instance));
context.call_method(&instance, "<init>", "()V", &[]).await?;

let data = data.iter().map(|&x| JavaValue::Byte(x as _)).collect::<Vec<_>>();

let data_array = context.instantiate_array("B", data.len() as _).await?;
let data_array = context.array_instance_from_raw(data_array.ptr_instance);
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);
Expand Down
22 changes: 12 additions & 10 deletions wie_impl_java/src/impl/org/kwis/msp/lcdui/jlet.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use alloc::{boxed::Box, format, vec};
use alloc::{boxed::Box, vec};

use jvm::JavaValue;

Expand Down Expand Up @@ -44,10 +44,11 @@ impl Jlet {
async fn init(context: &mut dyn JavaContext, this: JvmClassInstanceProxy<Self>) -> JavaResult<()> {
tracing::debug!("org.kwis.msp.lcdui.Jlet::<init>({:#x})", context.instance_raw(&this.class_instance));

let display = context.instantiate("Lorg/kwis/msp/lcdui/Display;").await?;
let display = context.jvm().instantiate_class("org/kwis/msp/lcdui/Display").await?;
let display = JavaObjectProxy::new(context.instance_raw(&display));
context
.call_method(
&display.cast(),
&display,
"<init>",
"(Lorg/kwis/msp/lcdui/Jlet;Lorg/kwis/msp/lcdui/DisplayProxy;)V",
&[context.instance_raw(&this.class_instance), 0],
Expand All @@ -62,10 +63,11 @@ impl Jlet {
JavaValue::Object(Some(display)),
)?;

let event_queue = context.instantiate("Lorg/kwis/msp/lcdui/EventQueue;").await?;
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(
&event_queue.cast(),
&event_queue,
"<init>",
"(Lorg/kwis/msp/lcdui/Jlet;)V",
&[context.instance_raw(&this.class_instance)],
Expand Down Expand Up @@ -118,15 +120,15 @@ 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.instantiate(&format!("L{};", main_class_name)).await?;
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, "<init>", "()V", &[]).await?;

tracing::debug!("Main class instance: {:#x}", ptr_main_class.ptr_instance);

let arg = context.instantiate_array("Ljava/lang/String;", 0).await?;
context
.call_method(&ptr_main_class, "startApp", "([Ljava/lang/String;)V", &[arg.ptr_instance])
.await?;
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?;

struct StartProxy {}

Expand Down
7 changes: 4 additions & 3 deletions wie_impl_java/src/impl/org/kwis/msp/lcdui/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@ impl Main {
.await?,
);

let event = context.instantiate_array("I", 4).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.ptr_instance]).await?;
context.call_method(&event_queue, "dispatchEvent", "([I)V", &[event.ptr_instance]).await?;
context.call_method(&event_queue, "getNextEvent", "([I)V", &[event]).await?;
context.call_method(&event_queue, "dispatchEvent", "([I)V", &[event]).await?;
}
}
}
20 changes: 0 additions & 20 deletions wie_ktf/src/runtime/java/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,26 +151,6 @@ impl JavaContext for KtfJavaContext<'_> {
Rc::new(RefCell::new(Box::new(JavaArrayClassInstance::from_raw(raw as _, self.core))))
}

async fn instantiate(&mut self, type_name: &str) -> JavaResult<JavaObjectProxy<Object>> {
anyhow::ensure!(type_name.as_bytes()[0] != b'[', "Array class should not be instantiated here");

let class_name = &type_name[1..type_name.len() - 1]; // L{};

let instance = self.jvm.instantiate_class(class_name).await?;
let instance = instance.borrow();
let instance = instance.as_any().downcast_ref::<JavaClassInstance>().unwrap();

Ok(JavaObjectProxy::new(instance.ptr_raw as _))
}

async fn instantiate_array(&mut self, element_type_name: &str, count: JavaWord) -> JavaResult<JavaObjectProxy<Object>> {
let instance = self.jvm.instantiate_array(element_type_name, count).await?;
let instance = instance.borrow();
let instance = instance.as_any().downcast_ref::<JavaArrayClassInstance>().unwrap();

Ok(JavaObjectProxy::new(instance.class_instance.ptr_raw as _))
}

async fn call_method(&mut self, proxy: &JavaObjectProxy<Object>, method_name: &str, descriptor: &str, args: &[JavaWord]) -> JavaResult<JavaWord> {
let instance = JavaClassInstance::from_raw(proxy.ptr_instance as _, self.core);
let class = instance.class()?;
Expand Down
Loading

0 comments on commit b581113

Please sign in to comment.