|
1 | | -use alloc::{boxed::Box, format, string::String as RustString, sync::Arc, vec, vec::Vec}; |
| 1 | +use alloc::{boxed::Box, format, vec, vec::Vec}; |
2 | 2 |
|
3 | 3 | use java_class_proto::{JavaFieldProto, JavaMethodProto}; |
4 | | -use jvm::{ClassInstance, ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; |
| 4 | +use jvm::{Array, ClassInstance, ClassInstanceRef, Jvm, Result, runtime::JavaLangString}; |
5 | 5 |
|
6 | 6 | use crate::{ |
7 | 7 | RuntimeClassProto, RuntimeContext, |
@@ -46,7 +46,7 @@ impl Throwable { |
46 | 46 | ], |
47 | 47 | fields: vec![ |
48 | 48 | JavaFieldProto::new("detailMessage", "Ljava/lang/String;", Default::default()), |
49 | | - JavaFieldProto::new("stackTrace", "[B", Default::default()), |
| 49 | + JavaFieldProto::new("stackTrace", "[Ljava/lang/String;", Default::default()), |
50 | 50 | ], |
51 | 51 | access_flags: Default::default(), |
52 | 52 | } |
@@ -77,9 +77,13 @@ impl Throwable { |
77 | 77 | async fn fill_in_stack_trace(jvm: &Jvm, _: &mut RuntimeContext, mut this: ClassInstanceRef<Self>) -> Result<ClassInstanceRef<Self>> { |
78 | 78 | tracing::debug!("java.lang.Throwable::fillInStackTrace({:?})", &this); |
79 | 79 |
|
80 | | - let stack_trace = Arc::new(jvm.stack_trace()); |
81 | | - |
82 | | - jvm.put_rust_object_field(&mut this, "stackTrace", stack_trace).await?; |
| 80 | + let stack_trace = jvm.stack_trace(); |
| 81 | + let mut stack_trace_array = jvm.instantiate_array("Ljava/lang/String;", stack_trace.len()).await?; |
| 82 | + for (i, line) in stack_trace.iter().enumerate() { |
| 83 | + let java_line = JavaLangString::from_rust_string(jvm, line).await?; |
| 84 | + jvm.store_array(&mut stack_trace_array, i, core::iter::once(java_line)).await?; |
| 85 | + } |
| 86 | + jvm.put_field(&mut this, "stackTrace", "[Ljava/lang/String;", stack_trace_array).await?; |
83 | 87 |
|
84 | 88 | Ok(this) |
85 | 89 | } |
@@ -146,18 +150,23 @@ impl Throwable { |
146 | 150 | } |
147 | 151 |
|
148 | 152 | async fn do_print_stack_trace(jvm: &Jvm, this: ClassInstanceRef<Self>, stream_or_writer: Box<dyn ClassInstance>) -> Result<()> { |
149 | | - let stack_trace: Arc<Vec<RustString>> = jvm.get_rust_object_field(&this, "stackTrace").await?; |
| 153 | + let stack_trace: ClassInstanceRef<Array<ClassInstanceRef<String>>> = jvm.get_field(&this, "stackTrace", "[Ljava/lang/String;").await?; |
150 | 154 |
|
151 | 155 | // TODO we can call println(Ljava/lang/Object;)V |
152 | 156 | let string: ClassInstanceRef<String> = jvm.invoke_virtual(&this, "toString", "()Ljava/lang/String;", ()).await?; |
153 | 157 | let _: () = jvm |
154 | 158 | .invoke_virtual(&stream_or_writer, "println", "(Ljava/lang/String;)V", (string,)) |
155 | 159 | .await?; |
156 | 160 |
|
157 | | - for line in stack_trace.iter() { |
158 | | - let line = format!("\tat {line}"); |
159 | | - let line = JavaLangString::from_rust_string(jvm, &line).await?; |
160 | | - let _: () = jvm.invoke_virtual(&stream_or_writer, "println", "(Ljava/lang/String;)V", (line,)).await?; |
| 161 | + if !stack_trace.is_null() { |
| 162 | + let length = jvm.array_length(&stack_trace).await?; |
| 163 | + let lines: Vec<ClassInstanceRef<String>> = jvm.load_array(&stack_trace, 0, length).await?; |
| 164 | + for line_ref in lines { |
| 165 | + let line = JavaLangString::to_rust_string(jvm, &line_ref).await?; |
| 166 | + let line = format!("\tat {line}"); |
| 167 | + let line = JavaLangString::from_rust_string(jvm, &line).await?; |
| 168 | + let _: () = jvm.invoke_virtual(&stream_or_writer, "println", "(Ljava/lang/String;)V", (line,)).await?; |
| 169 | + } |
161 | 170 | } |
162 | 171 |
|
163 | 172 | Ok(()) |
|
0 commit comments