rvmti/
lib.rs

1extern crate core;
2
3use std::{mem, ptr, slice};
4use std::ffi::{CStr, CString};
5use std::os::raw::{c_char, c_uchar, c_void};
6
7use jni::sys::*;
8
9use crate::bindings::*;
10use crate::callback::JvmtiEventCallbacks;
11
12pub mod sync;
13pub mod bindings;
14pub mod callback;
15
16pub type JvmtiResult<T> = Result<T, jvmtiError>;
17
18macro_rules! jvmti_unchecked {
19    ($jvmti:expr, $name:tt $(, $args:expr)*) => {
20        unsafe {
21            (**$jvmti.internal).$name.unwrap()($jvmti.internal, $($args),*)
22        }
23    };
24}
25
26fn to_string(ptr: *const c_char) -> String {
27    unsafe {
28        let c_str = CStr::from_ptr(ptr);
29        c_str.to_str().unwrap().to_string()
30    }
31}
32
33fn as_slice<'a, T>(count: i32, ptr: *const T) -> &'a [T] {
34    unsafe {
35        let size = count as usize;
36
37        slice::from_raw_parts(ptr, size)
38    }
39}
40
41fn as_c_char(name: &str) -> *const c_char {
42    let c_str = CString::new(name).unwrap();
43
44    unsafe {
45        slice::from_raw_parts(c_str.as_ptr(), name.len() + 1).to_vec().as_ptr()
46    }
47}
48
49fn none<T>() -> T {
50    unsafe {
51        mem::zeroed()
52    }
53}
54
55pub struct JvmtiEnv {
56    pub internal: *mut jvmtiEnv,
57}
58
59impl JvmtiEnv {
60    pub fn set_event_notification_mode(&self, event_type: jvmtiEvent, event_thread: jthread, enabled: bool) -> JvmtiResult<()> {
61        let mode = if enabled {
62            jvmtiEventMode::JVMTI_ENABLE
63        } else {
64            jvmtiEventMode::JVMTI_DISABLE
65        };
66        jvmti_unchecked!(self, SetEventNotificationMode, mode, event_type, event_thread).value(|| { () })
67    }
68
69    pub fn get_all_threads(&self) -> JvmtiResult<&[jthread]> {
70        let mut count: i32 = none();
71        let count_ptr: *mut i32 = &mut count;
72        let mut threads: *mut jthread = none();
73        let threads_ptr: *mut *mut jthread = &mut threads;
74
75        let error = jvmti_unchecked!(self, GetAllThreads, count_ptr, threads_ptr);
76
77        error.value(|| { as_slice(count, threads) })
78    }
79
80    pub fn suspend_thread(&self, thread: jthread) -> JvmtiResult<()> {
81        jvmti_unchecked!(self, SuspendThread, thread).value(|| { () })
82    }
83
84    pub fn resume_thread(&self, thread: jthread) -> JvmtiResult<()> {
85        jvmti_unchecked!(self, ResumeThread, thread).value(|| { () })
86    }
87
88    pub fn stop_thread(&self, thread: jthread, exception: jobject) -> JvmtiResult<()> {
89        jvmti_unchecked!(self, StopThread, thread, exception).value(|| { () })
90    }
91
92    pub fn interrupt_thread(&self, thread: jthread) -> JvmtiResult<()> {
93        jvmti_unchecked!(self, InterruptThread, thread).value(|| { () })
94    }
95
96    pub fn get_thread_info(&self, thread: jthread) -> JvmtiResult<jvmtiThreadInfo> {
97        let mut info: jvmtiThreadInfo = none();
98        let info_ptr: *mut jvmtiThreadInfo = &mut info;
99
100        jvmti_unchecked!(self, GetThreadInfo, thread, info_ptr).value(|| { info })
101    }
102
103    pub fn get_owned_monitor_info(&self, thread: jthread) -> JvmtiResult<&[jobject]> {
104        let mut count: i32 = none();
105        let count_ptr: *mut i32 = &mut count;
106        let mut monitors: *mut jobject = none();
107        let monitors_ptr: *mut *mut jobject = &mut monitors;
108
109        let error = jvmti_unchecked!(self, GetOwnedMonitorInfo, thread, count_ptr, monitors_ptr);
110
111        error.value(|| { as_slice(count, monitors) })
112    }
113
114    pub fn get_current_contended_monitor(&self, thread: jthread) -> JvmtiResult<jobject> {
115        let mut monitor: jobject = none();
116        let monitor_ptr: *mut jobject = &mut monitor;
117
118        jvmti_unchecked!(self, GetCurrentContendedMonitor, thread, monitor_ptr).value(|| { monitor })
119    }
120
121    pub fn run_agent_thread(&self, thread: jthread, _proc: jvmtiStartFunction, arg: *const c_void, priority: jint) -> JvmtiResult<()> {
122        jvmti_unchecked!(self, RunAgentThread, thread, _proc, arg, priority).value(|| { () })
123    }
124
125    pub fn get_top_thread_groups(&self) -> JvmtiResult<&[jthreadGroup]> {
126        let mut count: i32 = none();
127        let count_ptr: *mut i32 = &mut count;
128        let mut groups: *mut jthreadGroup = none();
129        let groups_ptr: *mut *mut jthreadGroup = &mut groups;
130
131        let error = jvmti_unchecked!(self, GetTopThreadGroups, count_ptr, groups_ptr);
132
133        error.value(|| { as_slice(count, groups) })
134    }
135
136    pub fn get_thread_group_info(&self, group: jthreadGroup) -> JvmtiResult<jvmtiThreadGroupInfo> {
137        let mut info: jvmtiThreadGroupInfo = none();
138        let info_ptr: *mut jvmtiThreadGroupInfo = &mut info;
139
140        jvmti_unchecked!(self, GetThreadGroupInfo, group, info_ptr).value(|| { info })
141    }
142
143    pub fn get_thread_group_children(&self, group: jthreadGroup) -> JvmtiResult<(&[jthread], &[jthreadGroup])> {
144        let mut thread_count: i32 = none();
145        let thread_count_ptr: *mut i32 = &mut thread_count;
146        let mut threads: *mut jthread = none();
147        let threads_ptr: *mut *mut jthread = &mut threads;
148
149        let mut group_count: i32 = none();
150        let group_count_ptr: *mut i32 = &mut group_count;
151        let mut groups: *mut jthreadGroup = none();
152        let groups_ptr: *mut *mut jthreadGroup = &mut groups;
153
154        let error = jvmti_unchecked!(self, GetThreadGroupChildren,group, thread_count_ptr, threads_ptr, group_count_ptr, groups_ptr);
155
156        error.value(|| { (as_slice(thread_count, threads), as_slice(group_count, groups)) })
157    }
158
159    pub fn get_frame_count(&self, thread: jthread) -> JvmtiResult<jint> {
160        let mut count: i32 = none();
161        let count_ptr: *mut i32 = &mut count;
162
163        jvmti_unchecked!(self, GetFrameCount ,thread, count_ptr).value(|| { count })
164    }
165
166    pub fn get_thread_state(&self, thread: jthread) -> JvmtiResult<jint> {
167        let mut state: i32 = none();
168        let state_ptr: *mut i32 = &mut state;
169
170        jvmti_unchecked!(self, GetThreadState, thread, state_ptr).value(|| { state })
171    }
172
173    pub fn get_current_thread(&self) -> JvmtiResult<jthread> {
174        let mut thread: jthread = none();
175        let thread_ptr: *mut jthread = &mut thread;
176
177        jvmti_unchecked!(self, GetCurrentThread, thread_ptr).value(|| { thread })
178    }
179
180    pub fn get_frame_location(&self, thread: jthread, depth: jint) -> JvmtiResult<(jmethodID, jlocation)> {
181        let mut method: jmethodID = none();
182        let method_ptr: *mut jmethodID = &mut method;
183        let mut location: jlocation = none();
184        let location_ptr: *mut jlocation = &mut location;
185
186        jvmti_unchecked!(self, GetFrameLocation, thread, depth, method_ptr, location_ptr).value(|| { (method, location) })
187    }
188
189    pub fn notify_frame_pop(&self, thread: jthread, depth: jint) -> JvmtiResult<()> {
190        jvmti_unchecked!(self, NotifyFramePop, thread, depth).value(|| {})
191    }
192
193    pub fn get_local_object(&self, thread: jthread, depth: jint, slot: jint) -> JvmtiResult<jobject> {
194        let mut object: jobject = none();
195        let object_ptr: *mut jobject = &mut object;
196
197        jvmti_unchecked!(self, GetLocalObject, thread, depth, slot, object_ptr).value(|| { object })
198    }
199
200    pub fn get_local_int(&self, thread: jthread, depth: jint, slot: jint) -> JvmtiResult<jint> {
201        let mut int: jint = none();
202        let int_ptr: *mut jint = &mut int;
203
204        jvmti_unchecked!(self, GetLocalInt, thread, depth, slot, int_ptr).value(|| { int })
205    }
206
207    pub fn get_local_long(&self, thread: jthread, depth: jint, slot: jint) -> JvmtiResult<jlong> {
208        let mut long: jlong = none();
209        let long_ptr: *mut jlong = &mut long;
210
211        jvmti_unchecked!(self, GetLocalLong, thread, depth, slot, long_ptr).value(|| { long })
212    }
213
214    pub fn get_local_float(&self, thread: jthread, depth: jint, slot: jint) -> JvmtiResult<jfloat> {
215        let mut float: jfloat = none();
216        let float_ptr: *mut jfloat = &mut float;
217
218        jvmti_unchecked!(self, GetLocalFloat, thread, depth, slot, float_ptr).value(|| { float })
219    }
220
221    pub fn get_local_double(&self, thread: jthread, depth: jint, slot: jint) -> JvmtiResult<jdouble> {
222        let mut double: jdouble = none();
223        let double_ptr: *mut jdouble = &mut double;
224
225        jvmti_unchecked!(self, GetLocalDouble, thread, depth, slot, double_ptr).value(|| { double })
226    }
227
228    pub fn create_raw_monitor(&self, name: &str) -> JvmtiResult<jrawMonitorID> {
229        let mut monitor: jrawMonitorID = none();
230        let monitor_ptr: *mut jrawMonitorID = &mut monitor;
231
232        let name_ptr = as_c_char(name);
233
234        jvmti_unchecked!(self, CreateRawMonitor, name_ptr, monitor_ptr).value(|| { monitor })
235    }
236
237    pub fn destroy_raw_monitor(&self, monitor: jrawMonitorID) -> JvmtiResult<()> {
238        jvmti_unchecked!(self, DestroyRawMonitor, monitor).value(|| { () })
239    }
240
241    pub fn raw_monitor_enter(&self, monitor: jrawMonitorID) -> JvmtiResult<()> {
242        jvmti_unchecked!(self, RawMonitorEnter, monitor).value(|| { () })
243    }
244
245    pub fn raw_monitor_exit(&self, monitor: jrawMonitorID) -> JvmtiResult<()> {
246        jvmti_unchecked!(self, RawMonitorExit, monitor).value(|| { () })
247    }
248
249    pub fn raw_monitor_wait(&self, monitor: jrawMonitorID, millis: jlong) -> JvmtiResult<()> {
250        jvmti_unchecked!(self, RawMonitorWait, monitor, millis).value(|| { () })
251    }
252
253    pub fn raw_monitor_notify(&self, monitor: jrawMonitorID) -> JvmtiResult<()> {
254        jvmti_unchecked!(self, RawMonitorNotify, monitor).value(|| { () })
255    }
256
257    pub fn raw_monitor_notify_all(&self, monitor: jrawMonitorID) -> JvmtiResult<()> {
258        jvmti_unchecked!(self, RawMonitorNotifyAll, monitor).value(|| { () })
259    }
260
261    pub fn set_break_point(&self, method: jmethodID, location: jlocation) -> JvmtiResult<()> {
262        jvmti_unchecked!(self, SetBreakpoint, method, location).value(|| { () })
263    }
264
265    pub fn clear_breakpoint(&self, method: jmethodID, location: jlocation) -> JvmtiResult<()> {
266        jvmti_unchecked!(self, ClearBreakpoint, method, location).value(|| { () })
267    }
268
269    pub fn set_field_access_watch(&self, class: jclass, field: jfieldID) -> JvmtiResult<()> {
270        jvmti_unchecked!(self, SetFieldAccessWatch, class, field).value(|| { () })
271    }
272
273    pub fn clear_field_access_watch(&self, class: jclass, field: jfieldID) -> JvmtiResult<()> {
274        jvmti_unchecked!(self, ClearFieldAccessWatch, class, field).value(|| { () })
275    }
276
277    pub fn set_field_modification_watch(&self, class: jclass, field: jfieldID) -> JvmtiResult<()> {
278        jvmti_unchecked!(self, SetFieldModificationWatch, class, field).value(|| { () })
279    }
280
281    pub fn clear_field_modification_watch(&self, class: jclass, field: jfieldID) -> JvmtiResult<()> {
282        jvmti_unchecked!(self, ClearFieldModificationWatch, class, field).value(|| { () })
283    }
284
285    pub fn is_modifiable_class(&self, class: jclass) -> JvmtiResult<bool> {
286        let mut modifiable: jboolean = none();
287        let modifiable_ptr: *mut jboolean = &mut modifiable;
288
289        jvmti_unchecked!(self, IsModifiableClass, class, modifiable_ptr).value(|| { modifiable == 1 })
290    }
291
292    pub fn allocate(&self, size: jlong) -> JvmtiResult<*mut c_uchar> {
293        let mut mem: *mut c_uchar = none();
294        let mem_ptr: *mut *mut c_uchar = &mut mem;
295
296        jvmti_unchecked!(self, Allocate, size, mem_ptr).value(|| { mem })
297    }
298
299    pub fn deallocate(&self, mem: *mut c_uchar) -> JvmtiResult<()> {
300        jvmti_unchecked!(self, Deallocate, mem).value(|| { () })
301    }
302
303    /// Returns name, generic
304    pub fn get_class_signature(&self, class: jclass) -> JvmtiResult<(String, Option<String>)> {
305        let mut signature: *mut c_char = none();
306        let signature_ptr: *mut *mut c_char = &mut signature;
307        let mut generic: *mut c_char = none();
308        let generic_ptr: *mut *mut c_char = &mut generic;
309
310        let error = jvmti_unchecked!(self, GetClassSignature, class, signature_ptr, generic_ptr);
311
312        let generic_option = unsafe {
313            match generic.as_ref() {
314                Some(_) => { Some(to_string(generic)) }
315                None => { None }
316            }
317        };
318
319        error.value(|| { (to_string(signature), generic_option) })
320    }
321
322    pub fn get_class_status(&self, class: jclass) -> JvmtiResult<jint> {
323        let mut status: jint = none();
324        let status_ptr: *mut jint = &mut status;
325
326        jvmti_unchecked!(self,GetClassStatus , class, status_ptr).value(|| { status })
327    }
328
329    pub fn get_source_file_name(&self, class: jclass) -> JvmtiResult<String> {
330        let mut name: *mut c_char = none();
331        let name_ptr: *mut *mut c_char = &mut name;
332
333        jvmti_unchecked!(self, GetSourceFileName, class, name_ptr).value(|| { to_string(name) })
334    }
335
336    pub fn get_class_modifiers(&self, class: jclass) -> JvmtiResult<jint> {
337        let mut modifiers: jint = none();
338        let modifiers_ptr: *mut jint = &mut modifiers;
339
340        jvmti_unchecked!(self, GetClassModifiers, class, modifiers_ptr).value(|| { modifiers })
341    }
342
343    pub fn get_class_methods(&self, class: jclass) -> JvmtiResult<&[jmethodID]> {
344        let mut count: i32 = none();
345        let count_ptr: *mut i32 = &mut count;
346
347        let mut methods: *mut jmethodID = none();
348        let methods_ptr: *mut *mut jmethodID = &mut methods;
349
350        jvmti_unchecked!(self, GetClassMethods, class, count_ptr, methods_ptr).value(|| { as_slice(count, methods) })
351    }
352
353    pub fn get_class_fields(&self, class: jclass) -> JvmtiResult<&[jfieldID]> {
354        let mut count: i32 = none();
355        let count_ptr: *mut i32 = &mut count;
356
357        let mut fields: *mut jfieldID = none();
358        let fields_ptr: *mut *mut jfieldID = &mut fields;
359
360
361        jvmti_unchecked!(self, GetClassFields, class, count_ptr, fields_ptr).value(|| { as_slice(count, fields) })
362    }
363
364    pub fn get_implemented_interfaces(&self, class: jclass) -> JvmtiResult<&[jclass]> {
365        let mut count: i32 = none();
366        let count_ptr: *mut i32 = &mut count;
367
368        let mut interfaces: *mut jclass = ptr::null_mut();
369        let interfaces_ptr: *mut *mut jclass = &mut interfaces;
370
371
372        jvmti_unchecked!(self, GetImplementedInterfaces, class, count_ptr, interfaces_ptr).value(|| { as_slice(count, interfaces) })
373    }
374
375    pub fn is_interface(&self, class: jclass) -> JvmtiResult<bool> {
376        let mut is_interface: jboolean = none();
377        let is_interface_ptr: *mut jboolean = &mut is_interface;
378
379        jvmti_unchecked!(self, IsInterface, class, is_interface_ptr).value(|| { is_interface == 1 })
380    }
381
382    pub fn is_array_class(&self, class: jclass) -> JvmtiResult<bool> {
383        let mut is_array: jboolean = none();
384        let is_array_ptr: *mut jboolean = &mut is_array;
385
386        jvmti_unchecked!(self, IsArrayClass, class, is_array_ptr).value(|| { is_array == 1 })
387    }
388
389    pub fn get_class_loader(&self, class: jclass) -> JvmtiResult<jobject> {
390        let mut loader: jobject = none();
391        let loader_ptr: *mut jobject = &mut loader;
392
393        jvmti_unchecked!(self, GetClassLoader, class, loader_ptr).value(|| { loader })
394    }
395
396    pub fn get_object_hash_code(&self, object: jobject) -> JvmtiResult<jint> {
397        let mut hashcode: jint = none();
398        let hashcode_ptr: *mut jint = &mut hashcode;
399
400        jvmti_unchecked!(self, GetObjectHashCode, object, hashcode_ptr).value(|| { hashcode })
401    }
402
403    pub fn get_object_monitor_usage(&self, object: jobject) -> JvmtiResult<jvmtiMonitorUsage> {
404        let mut usage: jvmtiMonitorUsage = none();
405        let usage_ptr: *mut jvmtiMonitorUsage = &mut usage;
406
407        jvmti_unchecked!(self, GetObjectMonitorUsage, object, usage_ptr).value(|| { usage })
408    }
409
410    /// Returns name, signature, generic
411    pub fn get_field_name(&self, class: jclass, field: jfieldID) -> JvmtiResult<(String, String, Option<String>)> {
412        let mut name: *mut c_char = none();
413        let name_ptr: *mut *mut c_char = &mut name;
414
415        let mut signature: *mut c_char = none();
416        let signature_ptr: *mut *mut c_char = &mut signature;
417
418        let mut generic: *mut c_char = none();
419        let generic_ptr: *mut *mut c_char = &mut generic;
420
421        let error = jvmti_unchecked!(self, GetFieldName, class, field, name_ptr, signature_ptr, generic_ptr);
422
423        let generic_option = unsafe {
424            match generic.as_ref() {
425                None => { None }
426                Some(_) => { Some(to_string(generic)) }
427            }
428        };
429
430        error.value(|| { (to_string(name), to_string(signature), generic_option) })
431    }
432
433    pub fn get_field_declaring_class(&self, class: jclass, field: jfieldID) -> JvmtiResult<jclass> {
434        let mut declaring: jclass = none();
435        let declaring_ptr: *mut jclass = &mut declaring;
436
437        jvmti_unchecked!(self, GetFieldDeclaringClass, class, field, declaring_ptr).value(|| { declaring })
438    }
439
440    pub fn get_field_modifiers(&self, class: jclass, field: jfieldID) -> JvmtiResult<jint> {
441        let mut modifiers: jint = none();
442        let modifiers_ptr: *mut jint = &mut modifiers;
443
444        jvmti_unchecked!(self, GetFieldModifiers, class, field, modifiers_ptr).value(|| { modifiers })
445    }
446
447    pub fn is_field_synthetic(&self, class: jclass, field: jfieldID) -> JvmtiResult<bool> {
448        let mut is_synthetic: jboolean = none();
449        let is_synthetic_ptr: *mut jboolean = &mut is_synthetic;
450
451        jvmti_unchecked!(self, IsFieldSynthetic, class, field, is_synthetic_ptr).value(|| { is_synthetic == 1 })
452    }
453
454    /// Returns name, signature, generic
455    pub fn get_method_name(&self, method: jmethodID) -> JvmtiResult<(String, String, Option<String>)> {
456        let mut name: *mut c_char = none();
457        let name_ptr: *mut *mut c_char = &mut name;
458
459        let mut signature: *mut c_char = none();
460        let signature_ptr: *mut *mut c_char = &mut signature;
461
462        let mut generic: *mut c_char = none();
463        let generic_ptr: *mut *mut c_char = &mut generic;
464
465        let error = jvmti_unchecked!(self, GetMethodName, method, name_ptr, signature_ptr, generic_ptr);
466
467        let generic_option = unsafe {
468            match generic.as_ref() {
469                None => { None }
470                Some(_) => { Some(to_string(generic)) }
471            }
472        };
473
474        error.value(|| { (to_string(name), to_string(signature), generic_option) })
475    }
476
477    pub fn get_method_declaring_class(&self, method: jmethodID) -> JvmtiResult<jclass> {
478        let mut declaring: jclass = none();
479        let declaring_ptr: *mut jclass = &mut declaring;
480
481        jvmti_unchecked!(self, GetMethodDeclaringClass, method, declaring_ptr).value(|| { declaring })
482    }
483
484    pub fn get_method_modifiers(&self, method: jmethodID) -> JvmtiResult<jint> {
485        let mut modifiers: jint = none();
486        let modifiers_ptr: *mut jint = &mut modifiers;
487
488        jvmti_unchecked!(self, GetMethodModifiers, method, modifiers_ptr).value(|| { modifiers })
489    }
490
491    pub fn get_max_locals(&self, method: jmethodID) -> JvmtiResult<jint> {
492        let mut max: jint = none();
493        let max_ptr: *mut jint = &mut max;
494
495        jvmti_unchecked!(self, GetMaxLocals, method, max_ptr).value(|| { max })
496    }
497
498    pub fn get_arguments_size(&self, method: jmethodID) -> JvmtiResult<jint> {
499        let mut size: jint = none();
500        let size_ptr: *mut jint = &mut size;
501
502        jvmti_unchecked!(self, GetArgumentsSize, method, size_ptr).value(|| { size })
503    }
504
505    pub fn get_line_number_table(&self, method: jmethodID) -> JvmtiResult<&[jvmtiLineNumberEntry]> {
506        let mut count: i32 = none();
507        let count_ptr: *mut i32 = &mut count;
508
509        let mut table: *mut jvmtiLineNumberEntry = ptr::null_mut();
510        let table_ptr: *mut *mut jvmtiLineNumberEntry = &mut table;
511
512        jvmti_unchecked!(self, GetLineNumberTable, method, count_ptr, table_ptr).value(|| { as_slice(count, table) })
513    }
514
515    /// Returns start location, end location
516    pub fn get_method_location(&self, method: jmethodID) -> JvmtiResult<(jlocation, jlocation)> {
517        let mut start: jlocation = none();
518        let start_ptr: *mut jlocation = &mut start;
519
520        let mut end: jlocation = 0;
521        let end_ptr: *mut jlocation = &mut end;
522
523        jvmti_unchecked!(self, GetMethodLocation,method, start_ptr, end_ptr).value(|| { (start, end) })
524    }
525
526    pub fn get_local_variable_table(&self, method: jmethodID) -> JvmtiResult<&[jvmtiLocalVariableEntry]> {
527        let mut count: i32 = none();
528        let count_ptr: *mut i32 = &mut count;
529
530        let mut table: *mut jvmtiLocalVariableEntry = none();
531        let table_ptr: *mut *mut jvmtiLocalVariableEntry = &mut table;
532
533        jvmti_unchecked!(self, GetLocalVariableTable, method, count_ptr, table_ptr).value(|| { as_slice(count, table) })
534    }
535
536    pub fn set_native_method_prefix(&self, prefix: &str) -> JvmtiResult<()> {
537        let prefix_ptr = as_c_char(prefix);
538        jvmti_unchecked!(self, SetNativeMethodPrefix, prefix_ptr).value(|| { () })
539    }
540
541    pub fn set_native_method_prefixes(&self, prefixes: &[&str]) -> JvmtiResult<()> {
542        let count = prefixes.len() as i32;
543        let mut vec: Vec<*mut c_char> = Vec::new();
544
545        for &x in prefixes {
546            vec.push(as_c_char(x) as *mut c_char)
547        }
548        jvmti_unchecked!(self, SetNativeMethodPrefixes, count, vec.as_mut_ptr()).value(|| { () })
549    }
550
551    pub fn get_bytecodes(&self, method: jmethodID) -> JvmtiResult<&[c_uchar]> {
552        let mut count: i32 = none();
553        let count_ptr: *mut i32 = &mut count;
554
555        let mut bytecodes: *mut c_uchar = ptr::null_mut();
556        let bytecodes_ptr: *mut *mut c_uchar = &mut bytecodes;
557
558        jvmti_unchecked!(self, GetBytecodes, method, count_ptr, bytecodes_ptr).value(|| { as_slice(count, bytecodes) })
559    }
560
561    pub fn is_method_native(&self, method: jmethodID) -> JvmtiResult<bool> {
562        let mut is_native: jboolean = none();
563        let is_native_ptr: *mut jboolean = &mut is_native;
564
565        jvmti_unchecked!(self, IsMethodNative, method, is_native_ptr).value(|| { is_native == 1 })
566    }
567
568    pub fn is_method_synthetic(&self, method: jmethodID) -> JvmtiResult<bool> {
569        let mut is_synthetic: jboolean = none();
570        let is_synthetic_ptr: *mut jboolean = &mut is_synthetic;
571
572        jvmti_unchecked!(self, IsMethodSynthetic, method, is_synthetic_ptr).value(|| { is_synthetic == 0 })
573    }
574
575    pub fn get_loaded_classes(&self) -> JvmtiResult<&[jclass]> {
576        let mut count: i32 = none();
577        let count_ptr: *mut i32 = &mut count;
578
579        let mut classes: *mut jclass = none();
580        let classes_ptr: *mut *mut jclass = &mut classes;
581
582        jvmti_unchecked!(self, GetLoadedClasses, count_ptr, classes_ptr).value(|| { as_slice(count, classes) })
583    }
584
585    pub fn get_class_loader_classes(&self, initiating_loader: jobject) -> JvmtiResult<&[jclass]> {
586        let mut count: i32 = none();
587        let count_ptr: *mut i32 = &mut count;
588
589        let mut classes: *mut jclass = none();
590        let classes_ptr: *mut *mut jclass = &mut classes;
591
592        jvmti_unchecked!(self, GetClassLoaderClasses, initiating_loader, count_ptr, classes_ptr).value(|| { as_slice(count, classes) })
593    }
594
595    pub fn pop_frame(&self, thread: jthread) -> JvmtiResult<()> {
596        jvmti_unchecked!(self, PopFrame, thread).value(|| { () })
597    }
598
599    pub fn force_early_return_object(&self, thread: jthread, value: jobject) -> JvmtiResult<()> {
600        jvmti_unchecked!(self, ForceEarlyReturnObject, thread, value).value(|| { () })
601    }
602
603    pub fn force_early_return_int(&self, thread: jthread, value: jint) -> JvmtiResult<()> {
604        jvmti_unchecked!(self, ForceEarlyReturnInt, thread, value).value(|| { () })
605    }
606
607    pub fn force_early_return_long(&self, thread: jthread, value: jlong) -> JvmtiResult<()> {
608        jvmti_unchecked!(self, ForceEarlyReturnLong, thread, value).value(|| { () })
609    }
610
611    pub fn force_early_return_float(&self, thread: jthread, value: jfloat) -> JvmtiResult<()> {
612        jvmti_unchecked!(self, ForceEarlyReturnFloat, thread, value).value(|| { () })
613    }
614
615    pub fn force_early_return_double(&self, thread: jthread, value: jdouble) -> JvmtiResult<()> {
616        jvmti_unchecked!(self, ForceEarlyReturnDouble, thread, value).value(|| { () })
617    }
618
619    pub fn force_early_return_void(&self, thread: jthread) -> JvmtiResult<()> {
620        jvmti_unchecked!(self, ForceEarlyReturnVoid, thread).value(|| { () })
621    }
622
623    pub fn redefine_classes(&self, class_definitions: Vec<jvmtiClassDefinition>) -> JvmtiResult<()> {
624        let count = class_definitions.len() as i32;
625        let ptr = class_definitions.as_ptr();
626
627        jvmti_unchecked!(self, RedefineClasses, count, ptr).value(|| { () })
628    }
629
630    pub fn get_version_number(&self) -> JvmtiResult<jint> {
631        let mut version: jint = none();
632        let version_ptr: *mut jint = &mut version;
633
634        jvmti_unchecked!(self, GetVersionNumber, version_ptr).value(|| { version })
635    }
636
637    pub fn get_capabilities(&self) -> JvmtiResult<jvmtiCapabilities> {
638        let mut capabilities: jvmtiCapabilities = none();
639        let capabilities_ptr: *mut jvmtiCapabilities = &mut capabilities;
640
641        jvmti_unchecked!(self, GetCapabilities, capabilities_ptr).value(|| { capabilities })
642    }
643
644    pub fn get_source_debug_extension(&self, class: jclass) -> JvmtiResult<String> {
645        let mut extension: *mut c_char = none();
646        let extension_ptr: *mut *mut c_char = &mut extension;
647
648        jvmti_unchecked!(self, GetSourceDebugExtension, class, extension_ptr).value(|| { to_string(extension) })
649    }
650
651    pub fn is_method_obsolete(&self, method: jmethodID) -> JvmtiResult<bool> {
652        let mut is_obsolete: jboolean = none();
653        let is_obsolete_ptr: *mut jboolean = &mut is_obsolete;
654
655        jvmti_unchecked!(self, IsMethodObsolete, method, is_obsolete_ptr).value(|| { is_obsolete == 1 })
656    }
657
658    pub fn suspend_thread_list(&self, request_list: Vec<jthread>) -> JvmtiResult<jvmtiError> {
659        let count = request_list.len() as i32;
660        let ptr = request_list.as_ptr();
661
662        let mut results: jvmtiError = none();
663        let results_ptr: *mut jvmtiError = &mut results;
664
665        jvmti_unchecked!(self, SuspendThreadList, count, ptr, results_ptr).value(|| { results })
666    }
667
668    pub fn resume_thread_list(&self, request_list: Vec<jthread>) -> JvmtiResult<jvmtiError> {
669        let count = request_list.len() as i32;
670        let ptr = request_list.as_ptr();
671
672        let mut results: jvmtiError = none();
673        let results_ptr: *mut jvmtiError = &mut results;
674
675        jvmti_unchecked!(self, ResumeThreadList, count, ptr, results_ptr).value(|| { results })
676    }
677
678    pub fn get_all_stack_traces(&self, max_frame_count: i32) -> JvmtiResult<&[jvmtiStackInfo]> {
679        let mut count: i32 = none();
680        let count_ptr: *mut i32 = &mut count;
681
682        let mut stack_info: *mut jvmtiStackInfo = none();
683        let stack_info_ptr: *mut *mut jvmtiStackInfo = &mut stack_info;
684
685        jvmti_unchecked!(self, GetAllStackTraces, max_frame_count, stack_info_ptr, count_ptr).value(|| { as_slice(count, stack_info) })
686    }
687
688    pub fn get_thread_list_stack_traces(&self, thread_list: Vec<jthread>, max_frame_count: i32) -> JvmtiResult<*mut jvmtiStackInfo> {
689        let count = thread_list.len() as i32;
690        let ptr = thread_list.as_ptr();
691
692        let mut stack_info: *mut jvmtiStackInfo = none();
693        let stack_info_ptr: *mut *mut jvmtiStackInfo = &mut stack_info;
694
695        jvmti_unchecked!(self, GetThreadListStackTraces, count, ptr, max_frame_count, stack_info_ptr).value(|| { stack_info })
696    }
697
698    pub fn get_thread_local_storage(&self, thread: jthread) -> JvmtiResult<*mut c_void> {
699        let mut data: *mut c_void = none();
700        let data_ptr: *mut *mut c_void = &mut data;
701
702        jvmti_unchecked!(self, GetThreadLocalStorage, thread, data_ptr).value(|| { data })
703    }
704
705    pub fn set_thread_local_storage(&self, thread: jthread, data: *const c_void) -> JvmtiResult<()> {
706        jvmti_unchecked!(self, SetThreadLocalStorage, thread, data).value(|| { () })
707    }
708
709    pub fn get_stack_trace(&self) {
710        panic!("Not implemented yet")
711    }
712
713    pub fn get_tag(&self, object: jobject) -> JvmtiResult<jlong> {
714        let mut tag: jlong = none();
715        let tag_ptr: *mut jlong = &mut tag;
716
717        jvmti_unchecked!(self, GetTag, object, tag_ptr).value(|| { tag })
718    }
719
720    pub fn set_tag(&self, object: jobject, tag: jlong) -> JvmtiResult<()> {
721        jvmti_unchecked!(self, SetTag, object, tag).value(|| { () })
722    }
723
724    pub fn force_garbage_collection(&self) -> JvmtiResult<()> {
725        jvmti_unchecked!(self, ForceGarbageCollection).value(|| { () })
726    }
727
728    pub fn iterate_over_objects_reachable_from_object(&self, object: jobject, object_reference_callback: jvmtiObjectReferenceCallback, user_data: *const c_void) -> JvmtiResult<()> {
729        jvmti_unchecked!(self, IterateOverObjectsReachableFromObject, object, object_reference_callback, user_data).value(|| { () })
730    }
731
732    pub fn iterate_over_reachable_objects(&self, heap_root_callback: jvmtiHeapRootCallback, stack_ref_callback: jvmtiStackReferenceCallback, object_ref_callback: jvmtiObjectReferenceCallback, user_data: *const c_void) -> JvmtiResult<()> {
733        jvmti_unchecked!(self, IterateOverReachableObjects, heap_root_callback, stack_ref_callback, object_ref_callback, user_data).value(|| { () })
734    }
735
736    pub fn iterate_over_heap(&self, object_filter: jvmtiHeapObjectFilter, heap_object_callback: jvmtiHeapObjectCallback, user_data: *const c_void) -> JvmtiResult<()> {
737        jvmti_unchecked!(self, IterateOverHeap, object_filter, heap_object_callback, user_data).value(|| { () })
738    }
739
740    pub fn iterate_over_instances_of_class(&self, class: jclass, object_filter: jvmtiHeapObjectFilter, heap_object_callback: jvmtiHeapObjectCallback, user_data: *const c_void) -> JvmtiResult<()> {
741        jvmti_unchecked!(self, IterateOverInstancesOfClass, class, object_filter, heap_object_callback, user_data).value(|| { () })
742    }
743
744    pub fn get_objects_with_tags(&self, tags: Vec<jlong>) -> JvmtiResult<Vec<(jobject, jlong)>> {
745        let count = tags.len() as i32;
746        let ptr = tags.as_ptr();
747
748        let mut result_count: i32 = none();
749        let result_count_ptr: *mut i32 = &mut result_count;
750
751        let mut object_result: *mut jobject = none();
752        let object_result_ptr: *mut *mut jobject = &mut object_result;
753
754        let mut tag_result: *mut jlong = none();
755        let tag_result_ptr: *mut *mut jlong = &mut tag_result;
756
757        let error = jvmti_unchecked!(self, GetObjectsWithTags, count, ptr, result_count_ptr, object_result_ptr, tag_result_ptr);
758
759        let object_vec = as_slice(result_count, object_result);
760        let tag_vec = as_slice(result_count, tag_result);
761        let mut result: Vec<(jobject, jlong)> = Vec::new();
762
763        for i in 0..result_count - 1 {
764            let index = i as usize;
765            let object = object_vec[index];
766            let tag = tag_vec[index];
767
768            result.push((object, tag));
769        }
770
771        error.value(|| { result })
772    }
773
774    pub fn follow_references(&self, heap_filter: i32, class: jclass, initial_object: jobject, callbacks: *const jvmtiHeapCallbacks, user_data: *const c_void) -> JvmtiResult<()> {
775        jvmti_unchecked!(self, FollowReferences, heap_filter, class, initial_object, callbacks, user_data).value(|| { () })
776    }
777
778    pub fn iterate_through_heap(&self, heap_filter: jint, class: jclass, callbacks: *const jvmtiHeapCallbacks, user_data: *const c_void) -> JvmtiResult<()> {
779        jvmti_unchecked!(self, IterateThroughHeap, heap_filter, class, callbacks, user_data).value(|| { () })
780    }
781
782    pub fn set_jni_function_table(&self, function_table: *const JNINativeInterface_) -> JvmtiResult<()> {
783        jvmti_unchecked!(self, SetJNIFunctionTable, function_table).value(|| { () })
784    }
785
786    pub fn get_jni_function_table(&self) -> JvmtiResult<*mut JNINativeInterface_> {
787        let mut function_table: *mut JNINativeInterface_ = none();
788        let function_table_ptr: *mut *mut JNINativeInterface_ = &mut function_table;
789
790        jvmti_unchecked!(self, GetJNIFunctionTable, function_table_ptr).value(|| { function_table })
791    }
792
793    pub fn set_event_callbacks(&self, callback: JvmtiEventCallbacks) -> JvmtiResult<()> {
794        let ptr: *const jvmtiEventCallbacks = &callback.to_raw();
795        let size = mem::size_of::<jvmtiEventCallbacks>();
796        jvmti_unchecked!(self, SetEventCallbacks, ptr, size as i32).value(|| { () })
797    }
798
799    pub fn generate_events(&self, event_type: jvmtiEvent) -> JvmtiResult<()> {
800        jvmti_unchecked!(self, GenerateEvents, event_type).value(|| { () })
801    }
802
803    pub fn get_extension_functions(&self) -> JvmtiResult<&[jvmtiExtensionFunctionInfo]> {
804        let mut count: i32 = none();
805        let count_ptr: *mut i32 = &mut count;
806
807        let mut extensions: *mut jvmtiExtensionFunctionInfo = ptr::null_mut();
808        let extensions_ptr: *mut *mut jvmtiExtensionFunctionInfo = &mut extensions;
809
810
811        jvmti_unchecked!(self, GetExtensionFunctions, count_ptr, extensions_ptr).value(|| { as_slice(count, extensions) })
812    }
813
814    pub fn get_extension_events(&self) -> JvmtiResult<&[jvmtiExtensionEventInfo]> {
815        let mut count: i32 = none();
816        let count_ptr: *mut i32 = &mut count;
817
818        let mut extensions: *mut jvmtiExtensionEventInfo = ptr::null_mut();
819        let extensions_ptr: *mut *mut jvmtiExtensionEventInfo = &mut extensions;
820
821
822        jvmti_unchecked!(self, GetExtensionEvents, count_ptr, extensions_ptr).value(|| { as_slice(count, extensions) })
823    }
824
825    pub fn set_extension_event_callback(&self, extension_event_index: i32, callback: jvmtiExtensionEvent) -> JvmtiResult<()> {
826        jvmti_unchecked!(self, SetExtensionEventCallback, extension_event_index, callback).value(|| { () })
827    }
828
829    pub fn dispose_environment(&self) -> JvmtiResult<()> {
830        jvmti_unchecked!(self, DisposeEnvironment).value(|| { () })
831    }
832
833    pub fn get_error_name(&self, error: jvmtiError) -> JvmtiResult<String> {
834        let mut name: *mut c_char = none();
835        let name_ptr: *mut *mut c_char = &mut name;
836
837
838        jvmti_unchecked!(self, GetErrorName, error, name_ptr).value(|| { to_string(name) })
839    }
840
841    pub fn get_jlocation_format(&self) -> JvmtiResult<jvmtiJlocationFormat> {
842        let mut format: jvmtiJlocationFormat = none();
843        let format_ptr: *mut jvmtiJlocationFormat = &mut format;
844
845        jvmti_unchecked!(self, GetJLocationFormat, format_ptr).value(|| { format })
846    }
847
848    pub fn get_system_properties(&self) -> JvmtiResult<()> {
849        panic!("Not yet implemented")
850    }
851
852    pub fn get_system_property(&self, property: &str) -> JvmtiResult<String> {
853        let mut value: *mut c_char = none();
854        let value_ptr: *mut *mut c_char = &mut value;
855
856        jvmti_unchecked!(self, GetSystemProperty, as_c_char(property), value_ptr).value(|| { to_string(value) })
857    }
858
859    pub fn set_system_property(&self, property: &str, value: &str) -> JvmtiResult<()> {
860        jvmti_unchecked!(self, SetSystemProperty, as_c_char(property), as_c_char(value)).value(|| { () })
861    }
862
863    pub fn get_phase(&self) -> JvmtiResult<jvmtiPhase> {
864        let mut phase: jvmtiPhase = none();
865        let phase_ptr: *mut jvmtiPhase = &mut phase;
866
867        jvmti_unchecked!(self, GetPhase, phase_ptr).value(|| { phase })
868    }
869
870    pub fn get_current_thread_cpu_timer_info(&self) -> JvmtiResult<jvmtiTimerInfo> {
871        let mut info: jvmtiTimerInfo = none();
872        let info_ptr: *mut jvmtiTimerInfo = &mut info;
873
874        jvmti_unchecked!(self, GetCurrentThreadCpuTimerInfo, info_ptr).value(|| { info })
875    }
876
877    pub fn get_current_cpu_time(&self) -> JvmtiResult<jlong> {
878        let mut nanos: jlong = none();
879        let nanos_ptr: *mut jlong = &mut nanos;
880
881        jvmti_unchecked!(self, GetCurrentThreadCpuTime, nanos_ptr).value(|| { nanos })
882    }
883
884    pub fn get_thread_cpu_timer_info(&self) -> JvmtiResult<jvmtiTimerInfo> {
885        let mut info: jvmtiTimerInfo = none();
886        let info_ptr: *mut jvmtiTimerInfo = &mut info;
887
888        jvmti_unchecked!(self, GetThreadCpuTimerInfo, info_ptr).value(|| { info })
889    }
890
891    pub fn get_thread_cpu_time(&self, thread: jthread) -> JvmtiResult<jlong> {
892        let mut nanos: jlong = none();
893        let nanos_ptr: *mut jlong = &mut nanos;
894
895        jvmti_unchecked!(self, GetThreadCpuTime, thread, nanos_ptr).value(|| { nanos })
896    }
897
898    pub fn get_timer_info(&self) -> JvmtiResult<jvmtiTimerInfo> {
899        let mut info: jvmtiTimerInfo = none();
900        let info_ptr: *mut jvmtiTimerInfo = &mut info;
901
902        jvmti_unchecked!(self, GetTimerInfo, info_ptr).value(|| { info })
903    }
904
905    pub fn get_time(&self) -> JvmtiResult<jlong> {
906        let mut nanos: jlong = none();
907        let nanos_ptr: *mut jlong = &mut nanos;
908
909        jvmti_unchecked!(self, GetTime, nanos_ptr).value(|| { nanos })
910    }
911
912    pub fn get_potential_capabilities(&self) -> JvmtiResult<jvmtiCapabilities> {
913        let mut capabilities: jvmtiCapabilities = none();
914        let capabilities_ptr: *mut jvmtiCapabilities = &mut capabilities;
915
916        jvmti_unchecked!(self, GetPotentialCapabilities, capabilities_ptr).value(|| { capabilities })
917    }
918
919    pub fn add_capabilities(&self, capabilities: jvmtiCapabilities) -> JvmtiResult<()> {
920        let ptr: *const jvmtiCapabilities = &capabilities;
921
922        jvmti_unchecked!(self, AddCapabilities, ptr).value(|| { () })
923    }
924
925    pub fn relinquish_capabilities(&self, capabilities: jvmtiCapabilities) -> JvmtiResult<()> {
926        let ptr: *const jvmtiCapabilities = &capabilities;
927
928        jvmti_unchecked!(self, RelinquishCapabilities, ptr).value(|| { () })
929    }
930
931    pub fn get_available_processors(&self) -> JvmtiResult<jint> {
932        let mut count: jint = none();
933        let count_ptr: *mut jint = &mut count;
934
935        jvmti_unchecked!(self, GetAvailableProcessors, count_ptr).value(|| { count })
936    }
937
938    /// Returns major, minor
939    pub fn get_class_version_numbers(&self, class: jclass) -> JvmtiResult<(jint, jint)> {
940        let mut major: jint = none();
941        let major_ptr: *mut jint = &mut major;
942
943        let mut minor: jint = none();
944        let minor_ptr: *mut jint = &mut minor;
945
946        jvmti_unchecked!(self, GetClassVersionNumbers, class, minor_ptr, major_ptr).value(|| { (major, minor) })
947    }
948
949    pub fn get_constant_pool(&self, class: jclass) -> JvmtiResult<(jint, &[c_uchar])> {
950        let mut count: i32 = none();
951        let count_ptr: *mut i32 = &mut count;
952
953        let mut byte_count: i32 = none();
954        let byte_count_ptr: *mut i32 = &mut byte_count;
955
956        let mut bytes: *mut c_uchar = none();
957        let bytes_ptr: *mut *mut c_uchar = &mut bytes;
958
959        let error = jvmti_unchecked!(self, GetConstantPool, class, count_ptr, byte_count_ptr, bytes_ptr);
960
961        error.value(|| { (count, as_slice(byte_count, bytes)) })
962    }
963
964    pub fn get_environment_local_storage(&self) -> JvmtiResult<*mut c_void> {
965        let mut data: *mut c_void = none();
966        let data_ptr: *mut *mut c_void = &mut data;
967
968        jvmti_unchecked!(self, GetEnvironmentLocalStorage, data_ptr).value(|| { data })
969    }
970
971    pub fn set_environment_local_storage(&self, data: *const c_void) -> JvmtiResult<()> {
972        jvmti_unchecked!(self, SetEnvironmentLocalStorage, data).value(|| { () })
973    }
974
975    pub fn add_to_bootstrap_class_loader_search(&self, segment: &str) -> JvmtiResult<()> {
976        jvmti_unchecked!(self, AddToBootstrapClassLoaderSearch, as_c_char(segment)).value(|| { () })
977    }
978
979    pub fn set_verbose_flag(&self, flag: jvmtiVerboseFlag, value: bool) -> JvmtiResult<()> {
980        jvmti_unchecked!(self, SetVerboseFlag, flag, value as jboolean).value(|| { () })
981    }
982
983    pub fn add_to_system_class_loader_search(&self, segment: &str) -> JvmtiResult<()> {
984        jvmti_unchecked!(self, AddToSystemClassLoaderSearch, as_c_char(segment)).value(|| { () })
985    }
986
987    pub fn retransform_classes(&self, classes: Vec<jclass>) -> JvmtiResult<()> {
988        let count = classes.len() as i32;
989        let ptr = classes.as_ptr();
990
991        jvmti_unchecked!(self, RetransformClasses, count, ptr).value(|| { () })
992    }
993
994    pub fn get_owned_monitor_stack_depth_info(&self, thread: jthread) -> JvmtiResult<&[jvmtiMonitorStackDepthInfo]> {
995        let mut count: i32 = none();
996        let count_ptr: *mut i32 = &mut count;
997
998        let mut monitor_info: *mut jvmtiMonitorStackDepthInfo = none();
999        let monitor_info_ptr: *mut *mut jvmtiMonitorStackDepthInfo = &mut monitor_info;
1000
1001        let error = jvmti_unchecked!(self, GetOwnedMonitorStackDepthInfo, thread, count_ptr, monitor_info_ptr);
1002
1003        error.value(|| { as_slice(count, monitor_info) })
1004    }
1005
1006    pub fn get_object_size(&self, object: jobject) -> JvmtiResult<jlong> {
1007        let mut size: jlong = none();
1008        let size_ptr: *mut jlong = &mut size;
1009
1010        jvmti_unchecked!(self, GetObjectSize, object, size_ptr).value(|| { size })
1011    }
1012
1013    pub fn get_local_instance(&self, thread: jthread, depth: i32) -> JvmtiResult<jobject> {
1014        let mut value: jobject = none();
1015        let value_ptr: *mut jobject = &mut value;
1016
1017        jvmti_unchecked!(self, GetLocalInstance, thread, depth, value_ptr).value(|| { value })
1018    }
1019}
1020
1021impl From<*mut jvmtiEnv> for JvmtiEnv {
1022    fn from(jvmti: *mut jvmtiEnv) -> Self {
1023        JvmtiEnv {
1024            internal: jvmti
1025        }
1026    }
1027}
1028
1029trait ErrorOr {
1030    fn value<T, F: FnOnce() -> T>(self, value: F) -> JvmtiResult<T>;
1031}
1032
1033impl ErrorOr for jvmtiError {
1034    fn value<T, F: FnOnce() -> T>(self, value: F) -> JvmtiResult<T> {
1035        return if matches!(self, jvmtiError::JVMTI_ERROR_NONE) {
1036            Ok(value())
1037        } else {
1038            Err(self)
1039        };
1040    }
1041}