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 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 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 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 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 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}