(class_file: &mut Classfile)
| 156 | } |
| 157 | |
| 158 | unsafe fn update_fill_method(class_file: &mut Classfile) -> Result<(), String> { |
| 159 | // Change existing fillInStackTrace to call stackParamFillInStackTrace(Thread) right after fillInStackTrace(0) |
| 160 | let fill_meth_name_idx = utf8_const(class_file, "fillInStackTrace"); |
| 161 | // Get the code |
| 162 | let curr_thread_ref_idx = method_ref_const(class_file, "java/lang/Thread", "currentThread", "()Ljava/lang/Thread;"); |
| 163 | let meth_ret_throwable_idx = utf8_const(class_file, "()Ljava/lang/Throwable;"); |
| 164 | let native_fill_meth_ref_idx = method_ref_const(class_file, "java/lang/Throwable", "fillInStackTrace", "(I)Ljava/lang/Throwable;"); |
| 165 | let new_native_fill_meth_ref_idx = method_ref_const(class_file, |
| 166 | "java/lang/Throwable", |
| 167 | "stackParamFillInStackTrace", |
| 168 | "(Ljava/lang/Thread;)Ljava/lang/Throwable;"); |
| 169 | let mut fill_meth = class_file.methods.iter_mut().find(|m| { |
| 170 | m.name_index.idx == fill_meth_name_idx && m.descriptor_index.idx == meth_ret_throwable_idx |
| 171 | }).ok_or("Cannot find fill method".to_string())?; |
| 172 | let mut fill_meth_code = get_method_code_mut(&mut fill_meth)?; |
| 173 | // Find the index of the invoke special |
| 174 | let fill_invoke_idx = fill_meth_code.iter().position(|i| { |
| 175 | match i { |
| 176 | &Instruction::INVOKESPECIAL(ref idx) if *idx == native_fill_meth_ref_idx as u16 => true, |
| 177 | _ => false |
| 178 | } |
| 179 | }).ok_or("Cannot find invoke of native fill".to_string())?; |
| 180 | // Call mine afterwards. "this" is currently on the stack already. It takes the current thread, |
| 181 | // so we grab that statically before calling so it is on the stack (current max stack of >= 2 is |
| 182 | // still ok for us). Result is a throwable so the stack is left how we got it. |
| 183 | fill_meth_code.insert(fill_invoke_idx + 1, Instruction::INVOKESTATIC(curr_thread_ref_idx as u16)); |
| 184 | fill_meth_code.insert(fill_invoke_idx + 2, Instruction::INVOKESPECIAL(new_native_fill_meth_ref_idx as u16)); |
| 185 | return Result::Ok(()); |
| 186 | } |
| 187 | |
| 188 | unsafe fn replace_our_trace_method(class_file: &mut Classfile) -> Result<(), String> { |
| 189 | // Rename getOurStackTrace to $$stack_param$$getOurStackTrace, then create a new |
no test coverage detected