extern crate core;
extern crate jvmti_sys;
use std::{mem, ptr};
use std::ffi::CString;
use std::os::raw::{c_char, c_uchar, c_void};
pub use jni::*;
use jni::sys::*;
pub use jvmti_sys::*;
use crate::errors::*;
pub mod sync;
pub mod errors;
macro_rules! jvmti_unchecked {
($jvmti:expr, $name:tt $(, $args:expr)*) => {
unsafe {
(**$jvmti.internal).$name.unwrap()($jvmti.internal, $($args),*)
}
};
}
fn to_string(ptr: *mut c_char) -> String {
unsafe {
let c_str = CString::from_raw(ptr);
String::from(c_str.to_str().unwrap())
}
}
fn as_vec<T>(count: i32, ptr: *mut T) -> Vec<T> {
unsafe {
let size = count as usize;
Vec::from_raw_parts(ptr, size, size)
}
}
fn as_c_char(name: &str) -> *const c_char {
let c_str = CString::new(name).unwrap();
return c_str.as_ptr();
}
fn none<T>() -> T {
unsafe {
mem::zeroed()
}
}
pub struct JvmtiEnv {
pub internal: *mut jvmtiEnv,
}
impl JvmtiEnv {
pub fn set_event_notification_mode(&self, mode: jvmtiEventMode, event_type: jvmtiEvent, event_thread: jthread) -> JvmtiResult<()> {
jvmti_unchecked!(self, SetEventNotificationMode, mode, event_type, event_thread).value(|| { () })
}
pub fn get_all_threads(&self) -> JvmtiResult<Vec<jthread>> {
let mut count: i32 = none();
let count_ptr: *mut i32 = &mut count;
let mut threads: *mut jthread = none();
let threads_ptr: *mut *mut jthread = &mut threads;
let error = jvmti_unchecked!(self, GetAllThreads, count_ptr, threads_ptr);
error.value(|| { as_vec(count, threads) })
}
pub fn suspend_thread(&self, thread: jthread) -> JvmtiResult<()> {
jvmti_unchecked!(self, SuspendThread, thread).value(|| { () })
}
pub fn resume_thread(&self, thread: jthread) -> JvmtiResult<()> {
jvmti_unchecked!(self, ResumeThread, thread).value(|| { () })
}
pub fn stop_thread(&self, thread: jthread, exception: jobject) -> JvmtiResult<()> {
jvmti_unchecked!(self, StopThread, thread, exception).value(|| { () })
}
pub fn interrupt_thread(&self, thread: jthread) -> JvmtiResult<()> {
jvmti_unchecked!(self, InterruptThread, thread).value(|| { () })
}
pub fn get_thread_info(&self, thread: jthread) -> JvmtiResult<jvmtiThreadInfo> {
let mut info: jvmtiThreadInfo = none();
let info_ptr: *mut jvmtiThreadInfo = &mut info;
jvmti_unchecked!(self, GetThreadInfo, thread, info_ptr).value(|| { info })
}
pub fn get_owned_monitor_info(&self, thread: jthread) -> JvmtiResult<Vec<jobject>> {
let mut count: i32 = none();
let count_ptr: *mut i32 = &mut count;
let mut monitors: *mut jobject = none();
let monitors_ptr: *mut *mut jobject = &mut monitors;
let error = jvmti_unchecked!(self, GetOwnedMonitorInfo, thread, count_ptr, monitors_ptr);
error.value(|| { as_vec(count, monitors) })
}
pub fn get_current_contended_monitor(&self, thread: jthread) -> JvmtiResult<jobject> {
let mut monitor: jobject = none();
let monitor_ptr: *mut jobject = &mut monitor;
jvmti_unchecked!(self, GetCurrentContendedMonitor, thread, monitor_ptr).value(|| { monitor })
}
pub fn run_agent_thread(&self, thread: jthread, _proc: jvmtiStartFunction, arg: *const c_void, priority: jint) -> JvmtiResult<()> {
jvmti_unchecked!(self, RunAgentThread, thread, _proc, arg, priority).value(|| { () })
}
pub fn get_top_thread_groups(&self) -> JvmtiResult<Vec<jthreadGroup>> {
let mut count: i32 = none();
let count_ptr: *mut i32 = &mut count;
let mut groups: *mut jthreadGroup = none();
let groups_ptr: *mut *mut jthreadGroup = &mut groups;
let error = jvmti_unchecked!(self, GetTopThreadGroups, count_ptr, groups_ptr);
error.value(|| { as_vec(count, groups) })
}
pub fn get_thread_group_info(&self, group: jthreadGroup) -> JvmtiResult<jvmtiThreadGroupInfo> {
let mut info: jvmtiThreadGroupInfo = none();
let info_ptr: *mut jvmtiThreadGroupInfo = &mut info;
jvmti_unchecked!(self, GetThreadGroupInfo, group, info_ptr).value(|| { info })
}
pub fn get_thread_group_children(&self, group: jthreadGroup) -> JvmtiResult<(Vec<jthread>, Vec<jthreadGroup>)> {
let mut thread_count: i32 = none();
let thread_count_ptr: *mut i32 = &mut thread_count;
let mut threads: *mut jthread = none();
let threads_ptr: *mut *mut jthread = &mut threads;
let mut group_count: i32 = none();
let group_count_ptr: *mut i32 = &mut group_count;
let mut groups: *mut jthreadGroup = none();
let groups_ptr: *mut *mut jthreadGroup = &mut groups;
let error = jvmti_unchecked!(self, GetThreadGroupChildren,group, thread_count_ptr, threads_ptr, group_count_ptr, groups_ptr);
error.value(|| { (as_vec(thread_count, threads), as_vec(group_count, groups)) })
}
pub fn get_frame_count(&self, thread: jthread) -> JvmtiResult<jint> {
let mut count: i32 = none();
let count_ptr: *mut i32 = &mut count;
jvmti_unchecked!(self, GetFrameCount ,thread, count_ptr).value(|| { count })
}
pub fn get_thread_state(&self, thread: jthread) -> JvmtiResult<jint> {
let mut state: i32 = none();
let state_ptr: *mut i32 = &mut state;
jvmti_unchecked!(self, GetThreadState, thread, state_ptr).value(|| { state })
}
pub fn get_current_thread(&self) -> JvmtiResult<jthread> {
let mut thread: jthread = none();
let thread_ptr: *mut jthread = &mut thread;
jvmti_unchecked!(self, GetCurrentThread, thread_ptr).value(|| { thread })
}
pub fn get_frame_location(&self, thread: jthread, depth: jint) -> JvmtiResult<(jmethodID, jlocation)> {
let mut method: jmethodID = none();
let method_ptr: *mut jmethodID = &mut method;
let mut location: jlocation = none();
let location_ptr: *mut jlocation = &mut location;
jvmti_unchecked!(self, GetFrameLocation, thread, depth, method_ptr, location_ptr).value(|| { (method, location) })
}
pub fn notify_frame_pop(&self, thread: jthread, depth: jint) -> JvmtiResult<()> {
jvmti_unchecked!(self, NotifyFramePop, thread, depth).value(|| {})
}
pub fn get_local_object(&self, thread: jthread, depth: jint, slot: jint) -> JvmtiResult<jobject> {
let mut object: jobject = none();
let object_ptr: *mut jobject = &mut object;
jvmti_unchecked!(self, GetLocalObject, thread, depth, slot, object_ptr).value(|| { object })
}
pub fn get_local_int(&self, thread: jthread, depth: jint, slot: jint) -> JvmtiResult<jint> {
let mut int: jint = none();
let int_ptr: *mut jint = &mut int;
jvmti_unchecked!(self, GetLocalInt, thread, depth, slot, int_ptr).value(|| { int })
}
pub fn get_local_long(&self, thread: jthread, depth: jint, slot: jint) -> JvmtiResult<jlong> {
let mut long: jlong = none();
let long_ptr: *mut jlong = &mut long;
jvmti_unchecked!(self, GetLocalLong, thread, depth, slot, long_ptr).value(|| { long })
}
pub fn get_local_float(&self, thread: jthread, depth: jint, slot: jint) -> JvmtiResult<jfloat> {
let mut float: jfloat = none();
let float_ptr: *mut jfloat = &mut float;
jvmti_unchecked!(self, GetLocalFloat, thread, depth, slot, float_ptr).value(|| { float })
}
pub fn get_local_double(&self, thread: jthread, depth: jint, slot: jint) -> JvmtiResult<jdouble> {
let mut double: jdouble = none();
let double_ptr: *mut jdouble = &mut double;
jvmti_unchecked!(self, GetLocalDouble, thread, depth, slot, double_ptr).value(|| { double })
}
pub fn create_raw_monitor(&self, name: &str) -> JvmtiResult<jrawMonitorID> {
let mut monitor: jrawMonitorID = none();
let monitor_ptr: *mut jrawMonitorID = &mut monitor;
let name_ptr = as_c_char(name);
jvmti_unchecked!(self, CreateRawMonitor, name_ptr, monitor_ptr).value(|| { monitor })
}
pub fn destroy_raw_monitor(&self, monitor: jrawMonitorID) -> JvmtiResult<()> {
jvmti_unchecked!(self, DestroyRawMonitor, monitor).value(|| { () })
}
pub fn raw_monitor_enter(&self, monitor: jrawMonitorID) -> JvmtiResult<()> {
jvmti_unchecked!(self, RawMonitorEnter, monitor).value(|| { () })
}
pub fn raw_monitor_exit(&self, monitor: jrawMonitorID) -> JvmtiResult<()> {
jvmti_unchecked!(self, RawMonitorExit, monitor).value(|| { () })
}
pub fn raw_monitor_wait(&self, monitor: jrawMonitorID, millis: jlong) -> JvmtiResult<()> {
jvmti_unchecked!(self, RawMonitorWait, monitor, millis).value(|| { () })
}
pub fn raw_monitor_notify(&self, monitor: jrawMonitorID) -> JvmtiResult<()> {
jvmti_unchecked!(self, RawMonitorNotify, monitor).value(|| { () })
}
pub fn raw_monitor_notify_all(&self, monitor: jrawMonitorID) -> JvmtiResult<()> {
jvmti_unchecked!(self, RawMonitorNotifyAll, monitor).value(|| { () })
}
pub fn set_break_point(&self, method: jmethodID, location: jlocation) -> JvmtiResult<()> {
jvmti_unchecked!(self, SetBreakpoint, method, location).value(|| { () })
}
pub fn clear_breakpoint(&self, method: jmethodID, location: jlocation) -> JvmtiResult<()> {
jvmti_unchecked!(self, ClearBreakpoint, method, location).value(|| { () })
}
pub fn set_field_access_watch(&self, class: jclass, field: jfieldID) -> JvmtiResult<()> {
jvmti_unchecked!(self, SetFieldAccessWatch, class, field).value(|| { () })
}
pub fn clear_field_access_watch(&self, class: jclass, field: jfieldID) -> JvmtiResult<()> {
jvmti_unchecked!(self, ClearFieldAccessWatch, class, field).value(|| { () })
}
pub fn set_field_modification_watch(&self, class: jclass, field: jfieldID) -> JvmtiResult<()> {
jvmti_unchecked!(self, SetFieldModificationWatch, class, field).value(|| { () })
}
pub fn clear_field_modification_watch(&self, class: jclass, field: jfieldID) -> JvmtiResult<()> {
jvmti_unchecked!(self, ClearFieldModificationWatch, class, field).value(|| { () })
}
pub fn is_modifiable_class(&self, class: jclass) -> JvmtiResult<bool> {
let mut modifiable: jboolean = none();
let modifiable_ptr: *mut jboolean = &mut modifiable;
jvmti_unchecked!(self, IsModifiableClass, class, modifiable_ptr).value(|| { modifiable == 1 })
}
pub fn allocate(&self, size: jlong) -> JvmtiResult<*mut c_uchar> {
let mut mem: *mut c_uchar = none();
let mem_ptr: *mut *mut c_uchar = &mut mem;
jvmti_unchecked!(self, Allocate, size, mem_ptr).value(|| { mem })
}
pub fn deallocate(&self, mem: *mut c_uchar) -> JvmtiResult<()> {
jvmti_unchecked!(self, Deallocate, mem).value(|| { () })
}
pub fn get_class_signature(&self, class: jclass) -> JvmtiResult<(String, String)> {
let mut signature: *mut c_char = none();
let signature_ptr: *mut *mut c_char = &mut signature;
let mut generic: *mut c_char = none();
let generic_ptr: *mut *mut c_char = &mut generic;
let error = jvmti_unchecked!(self, GetClassSignature, class, signature_ptr, generic_ptr);
error.value(|| { (to_string(signature), to_string(generic)) })
}
pub fn get_class_status(&self, class: jclass) -> JvmtiResult<jint> {
let mut status: jint = none();
let status_ptr: *mut jint = &mut status;
jvmti_unchecked!(self,GetClassStatus , class, status_ptr).value(|| { status })
}
pub fn get_source_file_name(&self, class: jclass) -> JvmtiResult<String> {
let mut name: *mut c_char = none();
let name_ptr: *mut *mut c_char = &mut name;
jvmti_unchecked!(self, GetSourceFileName, class, name_ptr).value(|| { to_string(name) })
}
pub fn get_class_modifiers(&self, class: jclass) -> JvmtiResult<jint> {
let mut modifiers: jint = none();
let modifiers_ptr: *mut jint = &mut modifiers;
jvmti_unchecked!(self, GetClassModifiers, class, modifiers_ptr).value(|| { modifiers })
}
pub fn get_class_methods(&self, class: jclass) -> JvmtiResult<Vec<jmethodID>> {
let mut count: i32 = none();
let count_ptr: *mut i32 = &mut count;
let mut methods: *mut jmethodID = none();
let methods_ptr: *mut *mut jmethodID = &mut methods;
jvmti_unchecked!(self, GetClassMethods, class, count_ptr, methods_ptr).value(|| { as_vec(count, methods) })
}
pub fn get_class_fields(&self, class: jclass) -> JvmtiResult<Vec<jfieldID>> {
let mut count: i32 = none();
let count_ptr: *mut i32 = &mut count;
let mut fields: *mut jfieldID = none();
let fields_ptr: *mut *mut jfieldID = &mut fields;
jvmti_unchecked!(self, GetClassFields, class, count_ptr, fields_ptr).value(|| { as_vec(count, fields) })
}
pub fn get_implemented_interfaces(&self, class: jclass) -> JvmtiResult<Vec<jclass>> {
let mut count: i32 = none();
let count_ptr: *mut i32 = &mut count;
let mut interfaces: *mut jclass = ptr::null_mut();
let interfaces_ptr: *mut *mut jclass = &mut interfaces;
jvmti_unchecked!(self, GetImplementedInterfaces, class, count_ptr, interfaces_ptr).value(|| { as_vec(count, interfaces) })
}
pub fn is_interface(&self, class: jclass) -> JvmtiResult<bool> {
let mut is_interface: jboolean = none();
let is_interface_ptr: *mut jboolean = &mut is_interface;
jvmti_unchecked!(self, IsInterface, class, is_interface_ptr).value(|| { is_interface == 1 })
}
pub fn is_array_class(&self, class: jclass) -> JvmtiResult<bool> {
let mut is_array: jboolean = none();
let is_array_ptr: *mut jboolean = &mut is_array;
jvmti_unchecked!(self, IsArrayClass, class, is_array_ptr).value(|| { is_array == 1 })
}
pub fn get_class_loader(&self, class: jclass) -> JvmtiResult<jobject> {
let mut loader: jobject = none();
let loader_ptr: *mut jobject = &mut loader;
jvmti_unchecked!(self, GetClassLoader, class, loader_ptr).value(|| { loader })
}
pub fn get_object_hash_code(&self, object: jobject) -> JvmtiResult<jint> {
let mut hashcode: jint = none();
let hashcode_ptr: *mut jint = &mut hashcode;
jvmti_unchecked!(self, GetObjectHashCode, object, hashcode_ptr).value(|| { hashcode })
}
pub fn get_object_monitor_usage(&self, object: jobject) -> JvmtiResult<jvmtiMonitorUsage> {
let mut usage: jvmtiMonitorUsage = none();
let usage_ptr: *mut jvmtiMonitorUsage = &mut usage;
jvmti_unchecked!(self, GetObjectMonitorUsage, object, usage_ptr).value(|| { usage })
}
pub fn get_field_name(&self, class: jclass, field: jfieldID) -> JvmtiResult<(String, String, String)> {
let mut name: *mut c_char = none();
let name_ptr: *mut *mut c_char = &mut name;
let mut signature: *mut c_char = none();
let signature_ptr: *mut *mut c_char = &mut signature;
let mut generic: *mut c_char = none();
let generic_ptr: *mut *mut c_char = &mut generic;
let error = jvmti_unchecked!(self, GetFieldName, class, field, name_ptr, signature_ptr, generic_ptr);
error.value(|| { (to_string(name), to_string(signature), to_string(generic)) })
}
pub fn get_field_declaring_class(&self, class: jclass, field: jfieldID) -> JvmtiResult<jclass> {
let mut declaring: jclass = none();
let declaring_ptr: *mut jclass = &mut declaring;
jvmti_unchecked!(self, GetFieldDeclaringClass, class, field, declaring_ptr).value(|| { declaring })
}
pub fn get_field_modifiers(&self, class: jclass, field: jfieldID) -> JvmtiResult<jint> {
let mut modifiers: jint = none();
let modifiers_ptr: *mut jint = &mut modifiers;
jvmti_unchecked!(self, GetFieldModifiers, class, field, modifiers_ptr).value(|| { modifiers })
}
pub fn is_field_synthetic(&self, class: jclass, field: jfieldID) -> JvmtiResult<bool> {
let mut is_synthetic: jboolean = none();
let is_synthetic_ptr: *mut jboolean = &mut is_synthetic;
jvmti_unchecked!(self, IsFieldSynthetic, class, field, is_synthetic_ptr).value(|| { is_synthetic == 1 })
}
pub fn get_method_name(&self, method: jmethodID) -> JvmtiResult<(String, String, String)> {
let mut name: *mut c_char = none();
let name_ptr: *mut *mut c_char = &mut name;
let mut signature: *mut c_char = none();
let signature_ptr: *mut *mut c_char = &mut signature;
let mut generic: *mut c_char = none();
let generic_ptr: *mut *mut c_char = &mut generic;
let error = jvmti_unchecked!(self, GetMethodName, method, name_ptr, signature_ptr, generic_ptr);
error.value(|| { (to_string(name), to_string(signature), to_string(generic)) })
}
pub fn get_method_declaring_class(&self, method: jmethodID) -> JvmtiResult<jclass> {
let mut declaring: jclass = none();
let declaring_ptr: *mut jclass = &mut declaring;
jvmti_unchecked!(self, GetMethodDeclaringClass, method, declaring_ptr).value(|| { declaring })
}
pub fn get_method_modifiers(&self, method: jmethodID) -> JvmtiResult<jint> {
let mut modifiers: jint = none();
let modifiers_ptr: *mut jint = &mut modifiers;
jvmti_unchecked!(self, GetMethodModifiers, method, modifiers_ptr).value(|| { modifiers })
}
pub fn get_max_locals(&self, method: jmethodID) -> JvmtiResult<jint> {
let mut max: jint = none();
let max_ptr: *mut jint = &mut max;
jvmti_unchecked!(self, GetMaxLocals, method, max_ptr).value(|| { max })
}
pub fn get_arguments_size(&self, method: jmethodID) -> JvmtiResult<jint> {
let mut size: jint = none();
let size_ptr: *mut jint = &mut size;
jvmti_unchecked!(self, GetArgumentsSize, method, size_ptr).value(|| { size })
}
pub fn get_line_number_table(&self, method: jmethodID) -> JvmtiResult<Vec<jvmtiLineNumberEntry>> {
let mut count: i32 = none();
let count_ptr: *mut i32 = &mut count;
let mut table: *mut jvmtiLineNumberEntry = ptr::null_mut();
let table_ptr: *mut *mut jvmtiLineNumberEntry = &mut table;
jvmti_unchecked!(self, GetLineNumberTable, method, count_ptr, table_ptr).value(|| { as_vec(count, table) })
}
pub fn get_method_location(&self, method: jmethodID) -> JvmtiResult<(jlocation, jlocation)> {
let mut start: jlocation = none();
let start_ptr: *mut jlocation = &mut start;
let mut end: jlocation = 0;
let end_ptr: *mut jlocation = &mut end;
jvmti_unchecked!(self, GetMethodLocation,method, start_ptr, end_ptr).value(|| { (start, end) })
}
pub fn get_local_variable_table(&self, method: jmethodID) -> JvmtiResult<Vec<jvmtiLocalVariableEntry>> {
let mut count: i32 = none();
let count_ptr: *mut i32 = &mut count;
let mut table: *mut jvmtiLocalVariableEntry = none();
let table_ptr: *mut *mut jvmtiLocalVariableEntry = &mut table;
jvmti_unchecked!(self, GetLocalVariableTable, method, count_ptr, table_ptr).value(|| { as_vec(count, table) })
}
pub fn set_native_method_prefix(&self, prefix: &str) -> JvmtiResult<()> {
let prefix_ptr = as_c_char(prefix);
jvmti_unchecked!(self, SetNativeMethodPrefix, prefix_ptr).value(|| { () })
}
pub fn set_native_method_prefixes(&self, prefixes: &[&str]) -> JvmtiResult<()> {
let count = prefixes.len() as i32;
let mut vec: Vec<*mut c_char> = Vec::new();
for &x in prefixes {
vec.push(as_c_char(x) as *mut c_char)
}
jvmti_unchecked!(self, SetNativeMethodPrefixes, count, vec.as_mut_ptr()).value(|| { () })
}
pub fn get_bytecodes(&self, method: jmethodID) -> JvmtiResult<Vec<c_uchar>> {
let mut count: i32 = none();
let count_ptr: *mut i32 = &mut count;
let mut bytecodes: *mut c_uchar = ptr::null_mut();
let bytecodes_ptr: *mut *mut c_uchar = &mut bytecodes;
jvmti_unchecked!(self, GetBytecodes, method, count_ptr, bytecodes_ptr).value(|| { as_vec(count, bytecodes) })
}
pub fn is_method_native(&self, method: jmethodID) -> JvmtiResult<bool> {
let mut is_native: jboolean = none();
let is_native_ptr: *mut jboolean = &mut is_native;
jvmti_unchecked!(self, IsMethodNative, method, is_native_ptr).value(|| { is_native == 1 })
}
pub fn is_method_synthetic(&self, method: jmethodID) -> JvmtiResult<bool> {
let mut is_synthetic: jboolean = none();
let is_synthetic_ptr: *mut jboolean = &mut is_synthetic;
jvmti_unchecked!(self, IsMethodSynthetic, method, is_synthetic_ptr).value(|| { is_synthetic == 0 })
}
pub fn get_loaded_classes(&self) -> JvmtiResult<Vec<jclass>> {
let mut count: i32 = none();
let count_ptr: *mut i32 = &mut count;
let mut classes: *mut jclass = none();
let classes_ptr: *mut *mut jclass = &mut classes;
jvmti_unchecked!(self, GetLoadedClasses, count_ptr, classes_ptr).value(|| { as_vec(count, classes) })
}
pub fn get_class_loader_classes(&self, initiating_loader: jobject) -> JvmtiResult<Vec<jclass>> {
let mut count: i32 = none();
let count_ptr: *mut i32 = &mut count;
let mut classes: *mut jclass = none();
let classes_ptr: *mut *mut jclass = &mut classes;
jvmti_unchecked!(self, GetClassLoaderClasses, initiating_loader, count_ptr, classes_ptr).value(|| { as_vec(count, classes) })
}
pub fn pop_frame(&self, thread: jthread) -> JvmtiResult<()> {
jvmti_unchecked!(self, PopFrame, thread).value(|| { () })
}
pub fn force_early_return_object(&self, thread: jthread, value: jobject) -> JvmtiResult<()> {
jvmti_unchecked!(self, ForceEarlyReturnObject, thread, value).value(|| { () })
}
pub fn force_early_return_int(&self, thread: jthread, value: jint) -> JvmtiResult<()> {
jvmti_unchecked!(self, ForceEarlyReturnInt, thread, value).value(|| { () })
}
pub fn force_early_return_long(&self, thread: jthread, value: jlong) -> JvmtiResult<()> {
jvmti_unchecked!(self, ForceEarlyReturnLong, thread, value).value(|| { () })
}
pub fn force_early_return_float(&self, thread: jthread, value: jfloat) -> JvmtiResult<()> {
jvmti_unchecked!(self, ForceEarlyReturnFloat, thread, value).value(|| { () })
}
pub fn force_early_return_double(&self, thread: jthread, value: jdouble) -> JvmtiResult<()> {
jvmti_unchecked!(self, ForceEarlyReturnDouble, thread, value).value(|| { () })
}
pub fn force_early_return_void(&self, thread: jthread) -> JvmtiResult<()> {
jvmti_unchecked!(self, ForceEarlyReturnVoid, thread).value(|| { () })
}
pub fn redefine_classes(&self, class_definitions: Vec<jvmtiClassDefinition>) -> JvmtiResult<()> {
let count = class_definitions.len() as i32;
let ptr = class_definitions.as_ptr();
jvmti_unchecked!(self, RedefineClasses, count, ptr).value(|| { () })
}
pub fn get_version_number(&self) -> JvmtiResult<jint> {
let mut version: jint = none();
let version_ptr: *mut jint = &mut version;
jvmti_unchecked!(self, GetVersionNumber, version_ptr).value(|| { version })
}
pub fn get_capabilities(&self) -> JvmtiResult<jvmtiCapabilities> {
let mut capabilities: jvmtiCapabilities = none();
let capabilities_ptr: *mut jvmtiCapabilities = &mut capabilities;
jvmti_unchecked!(self, GetCapabilities, capabilities_ptr).value(|| { capabilities })
}
pub fn get_source_debug_extension(&self, class: jclass) -> JvmtiResult<String> {
let mut extension: *mut c_char = none();
let extension_ptr: *mut *mut c_char = &mut extension;
jvmti_unchecked!(self, GetSourceDebugExtension, class, extension_ptr).value(|| { to_string(extension) })
}
pub fn is_method_obsolete(&self, method: jmethodID) -> JvmtiResult<bool> {
let mut is_obsolete: jboolean = none();
let is_obsolete_ptr: *mut jboolean = &mut is_obsolete;
jvmti_unchecked!(self, IsMethodObsolete, method, is_obsolete_ptr).value(|| { is_obsolete == 1 })
}
pub fn suspend_thread_list(&self, request_list: Vec<jthread>) -> JvmtiResult<jvmtiError> {
let count = request_list.len() as i32;
let ptr = request_list.as_ptr();
let mut results: jvmtiError = none();
let results_ptr: *mut jvmtiError = &mut results;
jvmti_unchecked!(self, SuspendThreadList, count, ptr, results_ptr).value(|| { results })
}
pub fn resume_thread_list(&self, request_list: Vec<jthread>) -> JvmtiResult<jvmtiError> {
let count = request_list.len() as i32;
let ptr = request_list.as_ptr();
let mut results: jvmtiError = none();
let results_ptr: *mut jvmtiError = &mut results;
jvmti_unchecked!(self, ResumeThreadList, count, ptr, results_ptr).value(|| { results })
}
pub fn get_all_stack_traces(&self, max_frame_count: i32) -> JvmtiResult<Vec<jvmtiStackInfo>> {
let mut count: i32 = none();
let count_ptr: *mut i32 = &mut count;
let mut stack_info: *mut jvmtiStackInfo = none();
let stack_info_ptr: *mut *mut jvmtiStackInfo = &mut stack_info;
jvmti_unchecked!(self, GetAllStackTraces, max_frame_count, stack_info_ptr, count_ptr).value(|| { as_vec(count, stack_info) })
}
pub fn get_thread_list_stack_traces(&self, thread_list: Vec<jthread>, max_frame_count: i32) -> JvmtiResult<*mut jvmtiStackInfo> {
let count = thread_list.len() as i32;
let ptr = thread_list.as_ptr();
let mut stack_info: *mut jvmtiStackInfo = none();
let stack_info_ptr: *mut *mut jvmtiStackInfo = &mut stack_info;
jvmti_unchecked!(self, GetThreadListStackTraces, count, ptr, max_frame_count, stack_info_ptr).value(|| { stack_info })
}
pub fn get_thread_local_storage(&self, thread: jthread) -> JvmtiResult<*mut c_void> {
let mut data: *mut c_void = none();
let data_ptr: *mut *mut c_void = &mut data;
jvmti_unchecked!(self, GetThreadLocalStorage, thread, data_ptr).value(|| { data })
}
pub fn set_thread_local_storage(&self, thread: jthread, data: *const c_void) -> JvmtiResult<()> {
jvmti_unchecked!(self, SetThreadLocalStorage, thread, data).value(|| { () })
}
pub fn get_stack_trace(&self) {
panic!("Not implemented yet")
}
pub fn get_tag(&self, object: jobject) -> JvmtiResult<jlong> {
let mut tag: jlong = none();
let tag_ptr: *mut jlong = &mut tag;
jvmti_unchecked!(self, GetTag, object, tag_ptr).value(|| { tag })
}
pub fn set_tag(&self, object: jobject, tag: jlong) -> JvmtiResult<()> {
jvmti_unchecked!(self, SetTag, object, tag).value(|| { () })
}
pub fn force_garbage_collection(&self) -> JvmtiResult<()> {
jvmti_unchecked!(self, ForceGarbageCollection).value(|| { () })
}
pub fn iterate_over_objects_reachable_from_object(&self, object: jobject, object_reference_callback: jvmtiObjectReferenceCallback, user_data: *const c_void) -> JvmtiResult<()> {
jvmti_unchecked!(self, IterateOverObjectsReachableFromObject, object, object_reference_callback, user_data).value(|| { () })
}
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<()> {
jvmti_unchecked!(self, IterateOverReachableObjects, heap_root_callback, stack_ref_callback, object_ref_callback, user_data).value(|| { () })
}
pub fn iterate_over_heap(&self, object_filter: jvmtiHeapObjectFilter, heap_object_callback: jvmtiHeapObjectCallback, user_data: *const c_void) -> JvmtiResult<()> {
jvmti_unchecked!(self, IterateOverHeap, object_filter, heap_object_callback, user_data).value(|| { () })
}
pub fn iterate_over_instances_of_class(&self, class: jclass, object_filter: jvmtiHeapObjectFilter, heap_object_callback: jvmtiHeapObjectCallback, user_data: *const c_void) -> JvmtiResult<()> {
jvmti_unchecked!(self, IterateOverInstancesOfClass, class, object_filter, heap_object_callback, user_data).value(|| { () })
}
pub fn get_objects_with_tags(&self, tags: Vec<jlong>) -> JvmtiResult<Vec<(jobject, jlong)>> {
let count = tags.len() as i32;
let ptr = tags.as_ptr();
let mut result_count: i32 = none();
let result_count_ptr: *mut i32 = &mut result_count;
let mut object_result: *mut jobject = none();
let object_result_ptr: *mut *mut jobject = &mut object_result;
let mut tag_result: *mut jlong = none();
let tag_result_ptr: *mut *mut jlong = &mut tag_result;
let error = jvmti_unchecked!(self, GetObjectsWithTags, count, ptr, result_count_ptr, object_result_ptr, tag_result_ptr);
let object_vec = as_vec(result_count, object_result);
let tag_vec = as_vec(result_count, tag_result);
let mut result: Vec<(jobject, jlong)> = Vec::new();
for i in 0..result_count - 1 {
let index = i as usize;
let object = object_vec[index];
let tag = tag_vec[index];
result.push((object, tag));
}
error.value(|| { result })
}
pub fn follow_references(&self, heap_filter: i32, class: jclass, initial_object: jobject, callbacks: *const jvmtiHeapCallbacks, user_data: *const c_void) -> JvmtiResult<()> {
jvmti_unchecked!(self, FollowReferences, heap_filter, class, initial_object, callbacks, user_data).value(|| { () })
}
pub fn iterate_through_heap(&self, heap_filter: jint, class: jclass, callbacks: *const jvmtiHeapCallbacks, user_data: *const c_void) -> JvmtiResult<()> {
jvmti_unchecked!(self, IterateThroughHeap, heap_filter, class, callbacks, user_data).value(|| { () })
}
pub fn set_jni_function_table(&self, function_table: *const JNINativeInterface_) -> JvmtiResult<()> {
jvmti_unchecked!(self, SetJNIFunctionTable, function_table).value(|| { () })
}
pub fn get_jni_function_table(&self) -> JvmtiResult<*mut JNINativeInterface_> {
let mut function_table: *mut JNINativeInterface_ = none();
let function_table_ptr: *mut *mut JNINativeInterface_ = &mut function_table;
jvmti_unchecked!(self, GetJNIFunctionTable, function_table_ptr).value(|| { function_table })
}
pub fn set_event_callbacks(&self, callbacks: Vec<jvmtiEventCallbacks>) -> JvmtiResult<()> {
let count = callbacks.len() as i32;
let ptr = callbacks.as_ptr();
jvmti_unchecked!(self, SetEventCallbacks, ptr, count).value(|| { () })
}
pub fn generate_events(&self, event_type: jvmtiEvent) -> JvmtiResult<()> {
jvmti_unchecked!(self, GenerateEvents, event_type).value(|| { () })
}
pub fn get_extension_functions(&self) -> JvmtiResult<Vec<jvmtiExtensionFunctionInfo>> {
let mut count: i32 = none();
let count_ptr: *mut i32 = &mut count;
let mut extensions: *mut jvmtiExtensionFunctionInfo = ptr::null_mut();
let extensions_ptr: *mut *mut jvmtiExtensionFunctionInfo = &mut extensions;
jvmti_unchecked!(self, GetExtensionFunctions, count_ptr, extensions_ptr).value(|| { as_vec(count, extensions) })
}
pub fn get_extension_events(&self) -> JvmtiResult<Vec<jvmtiExtensionEventInfo>> {
let mut count: i32 = none();
let count_ptr: *mut i32 = &mut count;
let mut extensions: *mut jvmtiExtensionEventInfo = ptr::null_mut();
let extensions_ptr: *mut *mut jvmtiExtensionEventInfo = &mut extensions;
jvmti_unchecked!(self, GetExtensionEvents, count_ptr, extensions_ptr).value(|| { as_vec(count, extensions) })
}
pub fn set_extension_event_callback(&self, extension_event_index: i32, callback: jvmtiExtensionEvent) -> JvmtiResult<()> {
jvmti_unchecked!(self, SetExtensionEventCallback, extension_event_index, callback).value(|| { () })
}
pub fn dispose_environment(&self) -> JvmtiResult<()> {
jvmti_unchecked!(self, DisposeEnvironment).value(|| { () })
}
pub fn get_error_name(&self, error: jvmtiError) -> JvmtiResult<String> {
let mut name: *mut c_char = none();
let name_ptr: *mut *mut c_char = &mut name;
jvmti_unchecked!(self, GetErrorName, error, name_ptr).value(|| { to_string(name) })
}
pub fn get_jlocation_format(&self) -> JvmtiResult<jvmtiJlocationFormat> {
let mut format: jvmtiJlocationFormat = none();
let format_ptr: *mut jvmtiJlocationFormat = &mut format;
jvmti_unchecked!(self, GetJLocationFormat, format_ptr).value(|| { format })
}
pub fn get_system_properties(&self) -> JvmtiResult<()> {
panic!("Not yet implemented")
}
pub fn get_system_property(&self, property: &str) -> JvmtiResult<String> {
let mut value: *mut c_char = none();
let value_ptr: *mut *mut c_char = &mut value;
jvmti_unchecked!(self, GetSystemProperty, as_c_char(property), value_ptr).value(|| { to_string(value) })
}
pub fn set_system_property(&self, property: &str, value: &str) -> JvmtiResult<()> {
jvmti_unchecked!(self, SetSystemProperty, as_c_char(property), as_c_char(value)).value(|| { () })
}
pub fn get_phase(&self) -> JvmtiResult<jvmtiPhase> {
let mut phase: jvmtiPhase = none();
let phase_ptr: *mut jvmtiPhase = &mut phase;
jvmti_unchecked!(self, GetPhase, phase_ptr).value(|| { phase })
}
pub fn get_current_thread_cpu_timer_info(&self) -> JvmtiResult<jvmtiTimerInfo> {
let mut info: jvmtiTimerInfo = none();
let info_ptr: *mut jvmtiTimerInfo = &mut info;
jvmti_unchecked!(self, GetCurrentThreadCpuTimerInfo, info_ptr).value(|| { info })
}
pub fn get_current_cpu_time(&self) -> JvmtiResult<jlong> {
let mut nanos: jlong = none();
let nanos_ptr: *mut jlong = &mut nanos;
jvmti_unchecked!(self, GetCurrentThreadCpuTime, nanos_ptr).value(|| { nanos })
}
pub fn get_thread_cpu_timer_info(&self) -> JvmtiResult<jvmtiTimerInfo> {
let mut info: jvmtiTimerInfo = none();
let info_ptr: *mut jvmtiTimerInfo = &mut info;
jvmti_unchecked!(self, GetThreadCpuTimerInfo, info_ptr).value(|| { info })
}
pub fn get_thread_cpu_time(&self, thread: jthread) -> JvmtiResult<jlong> {
let mut nanos: jlong = none();
let nanos_ptr: *mut jlong = &mut nanos;
jvmti_unchecked!(self, GetThreadCpuTime, thread, nanos_ptr).value(|| { nanos })
}
pub fn get_timer_info(&self) -> JvmtiResult<jvmtiTimerInfo> {
let mut info: jvmtiTimerInfo = none();
let info_ptr: *mut jvmtiTimerInfo = &mut info;
jvmti_unchecked!(self, GetTimerInfo, info_ptr).value(|| { info })
}
pub fn get_time(&self) -> JvmtiResult<jlong> {
let mut nanos: jlong = none();
let nanos_ptr: *mut jlong = &mut nanos;
jvmti_unchecked!(self, GetTime, nanos_ptr).value(|| { nanos })
}
pub fn get_potential_capabilities(&self) -> JvmtiResult<jvmtiCapabilities> {
let mut capabilities: jvmtiCapabilities = none();
let capabilities_ptr: *mut jvmtiCapabilities = &mut capabilities;
jvmti_unchecked!(self, GetPotentialCapabilities, capabilities_ptr).value(|| { capabilities })
}
pub fn add_capabilities(&self, capabilities: jvmtiCapabilities) -> JvmtiResult<()> {
let ptr = vec!(capabilities).as_ptr();
jvmti_unchecked!(self, AddCapabilities, ptr).value(|| { () })
}
pub fn relinquish_capabilities(&self, capabilities: jvmtiCapabilities) -> JvmtiResult<()> {
let ptr = vec!(capabilities).as_ptr();
jvmti_unchecked!(self, RelinquishCapabilities, ptr).value(|| { () })
}
pub fn get_available_processors(&self) -> JvmtiResult<jint> {
let mut count: jint = none();
let count_ptr: *mut jint = &mut count;
jvmti_unchecked!(self, GetAvailableProcessors, count_ptr).value(|| { count })
}
pub fn get_class_version_numbers(&self, class: jclass) -> JvmtiResult<(jint, jint)> {
let mut major: jint = none();
let major_ptr: *mut jint = &mut major;
let mut minor: jint = none();
let minor_ptr: *mut jint = &mut minor;
jvmti_unchecked!(self, GetClassVersionNumbers, class, minor_ptr, major_ptr).value(|| { (major, minor) })
}
pub fn get_constant_pool(&self, class: jclass) -> JvmtiResult<(jint, Vec<c_uchar>)> {
let mut count: i32 = none();
let count_ptr: *mut i32 = &mut count;
let mut byte_count: i32 = none();
let byte_count_ptr: *mut i32 = &mut byte_count;
let mut bytes: *mut c_uchar = none();
let bytes_ptr: *mut *mut c_uchar = &mut bytes;
let error = jvmti_unchecked!(self, GetConstantPool, class, count_ptr, byte_count_ptr, bytes_ptr);
error.value(|| { (count, as_vec(byte_count, bytes)) })
}
pub fn get_environment_local_storage(&self) -> JvmtiResult<*mut c_void> {
let mut data: *mut c_void = none();
let data_ptr: *mut *mut c_void = &mut data;
jvmti_unchecked!(self, GetEnvironmentLocalStorage, data_ptr).value(|| { data })
}
pub fn set_environment_local_storage(&self, data: *const c_void) -> JvmtiResult<()> {
jvmti_unchecked!(self, SetEnvironmentLocalStorage, data).value(|| { () })
}
pub fn add_to_bootstrap_class_loader_search(&self, segment: &str) -> JvmtiResult<()> {
jvmti_unchecked!(self, AddToBootstrapClassLoaderSearch, as_c_char(segment)).value(|| { () })
}
pub fn set_verbose_flag(&self, flag: jvmtiVerboseFlag, value: bool) -> JvmtiResult<()> {
jvmti_unchecked!(self, SetVerboseFlag, flag, value as jboolean).value(|| { () })
}
pub fn add_to_system_class_loader_search(&self, segment: &str) -> JvmtiResult<()> {
jvmti_unchecked!(self, AddToSystemClassLoaderSearch, as_c_char(segment)).value(|| { () })
}
pub fn retransform_classes(&self, classes: Vec<jclass>) -> JvmtiResult<()> {
let count = classes.len() as i32;
let ptr = classes.as_ptr();
jvmti_unchecked!(self, RetransformClasses, count, ptr).value(|| { () })
}
pub fn get_owned_monitor_stack_depth_info(&self, thread: jthread) -> JvmtiResult<Vec<jvmtiMonitorStackDepthInfo>> {
let mut count: i32 = none();
let count_ptr: *mut i32 = &mut count;
let mut monitor_info: *mut jvmtiMonitorStackDepthInfo = none();
let monitor_info_ptr: *mut *mut jvmtiMonitorStackDepthInfo = &mut monitor_info;
let error = jvmti_unchecked!(self, GetOwnedMonitorStackDepthInfo, thread, count_ptr, monitor_info_ptr);
error.value(|| { as_vec(count, monitor_info) })
}
pub fn get_object_size(&self, object: jobject) -> JvmtiResult<jlong> {
let mut size: jlong = none();
let size_ptr: *mut jlong = &mut size;
jvmti_unchecked!(self, GetObjectSize, object, size_ptr).value(|| { size })
}
pub fn get_local_instance(&self, thread: jthread, depth: i32) -> JvmtiResult<jobject> {
let mut value: jobject = none();
let value_ptr: *mut jobject = &mut value;
jvmti_unchecked!(self, GetLocalInstance, thread, depth, value_ptr).value(|| { value })
}
}
impl From<*mut jvmtiEnv> for JvmtiEnv {
fn from(jvmti: *mut jvmtiEnv) -> Self {
JvmtiEnv {
internal: jvmti
}
}
}
trait ErrorOr {
fn value<T, F: FnOnce() -> T>(&self, value: F) -> JvmtiResult<T>;
}
impl ErrorOr for jvmtiError {
fn value<T, F: FnOnce() -> T>(&self, value: F) -> JvmtiResult<T> {
return if matches!(self, jvmtiError::JVMTI_ERROR_NONE) {
Ok(value())
} else {
Err(JvmtiError::from(self))
};
}
}