jvmti_rs/wrapper/builder/
mut_object_builder.rs

1use std::os::raw::c_void;
2
3use log::error;
4
5use crate::{builder::*, JVMTIEnv, JvmtiError, objects::*,
6            slice_raw, sys::*};
7
8macro_rules! define_builder {
9    ($sys_type:ident, $wrapper_type:ident) => (
10        impl<'a> Builder<$wrapper_type<'a>> for MutObjectArrayBuilder<$sys_type> {
11            fn build(&self) -> Vec<$wrapper_type<'a>> {
12                if self.count == 0 || self.items.is_null() {
13                    return vec![];
14                }
15                let items = slice_raw(self.items, self.count);
16                let res: Vec<$wrapper_type<'a>> = items.iter()
17                    .map(|&e| (e).into())
18                    .collect();
19                res
20            }
21        }
22    );
23    ($sys_type:ident, $wrapper_type:ident, $convert_type:ty) => (
24        impl<'a> Builder<$wrapper_type<'a>> for MutObjectArrayBuilder<$sys_type> {
25            fn build(&self) -> Vec<$wrapper_type<'a>> {
26                if self.count == 0 || self.items.is_null() {
27                    return vec![];
28                }
29                let items = slice_raw(self.items, self.count);
30                let res: Vec<$wrapper_type<'a>> = items.iter()
31                    .map(|&e| (e as $convert_type).into())
32                    .collect();
33                res
34            }
35        }
36    )
37}
38
39macro_rules! define_auto_deallocate_builder {
40    ($sys_type:ident, $wrapper_type:ident) => (
41        impl<'a> AutoDeallocateBuilder<'a, $wrapper_type<'a>> for MutAutoDeallocateObjectArrayBuilder<$sys_type> {
42            fn build(&self, jvmti: &'a JVMTIEnv<'a>) -> Vec<$wrapper_type<'a>> {
43                if self.count == 0 || self.items.is_null() {
44                    return vec![];
45                }
46                let items = slice_raw(self.items, self.count);
47                let res: Vec<$wrapper_type<'a>> = items.iter()
48                    .map(|&e| (e).into())
49                    .collect();
50                match jvmti.deallocate_raw(self.items as *mut c_void as jmemory) {
51                    Err(e)=> error!("JVMTI deallocate memory fail {}",e),
52                    _=>{}
53                }
54                res
55            }
56        }
57    );
58    ($sys_type:ident, $wrapper_type:ident, $convert_type:ty) => (
59        impl<'a> AutoDeallocateBuilder<'a, $wrapper_type<'a>> for MutAutoDeallocateObjectArrayBuilder<$sys_type> {
60            fn build(&self, jvmti: &'a JVMTIEnv<'a>) -> Vec<$wrapper_type<'a>> {
61                if self.count == 0 || self.items.is_null() {
62                    return vec![];
63                }
64                let items = slice_raw(self.items, self.count);
65                let res: Vec<$wrapper_type<'a>> = items.iter()
66                    .map(|&e| (e as $convert_type).into())
67                    .collect();
68                match jvmti.deallocate_raw(self.items as *mut c_void as jmemory) {
69                    Err(e)=> error!("JVMTI deallocate memory fail {}",e),
70                    _=>{}
71                }
72                res
73            }
74        }
75    )
76}
77
78define_auto_deallocate_builder!(jobject, JObject);
79define_auto_deallocate_builder!(jvmtiMonitorStackDepthInfo, JMonitorStackDepthInfo);
80define_auto_deallocate_builder!(jvmtiParamInfo, JParamInfo);
81define_builder!(jvmtiFrameInfo, JFrameInfo);
82define_auto_deallocate_builder!(jvmtiStackInfo, JStackInfo);
83
84define_auto_deallocate_builder!(jthread, JThreadID, jthread);
85define_auto_deallocate_builder!(jthreadGroup, JThreadGroupID, jthreadGroup);
86define_auto_deallocate_builder!(jmethodID, JMethodID, jmethodID);
87define_auto_deallocate_builder!(jfieldID, JFieldID, jfieldID);
88define_auto_deallocate_builder!(jclass, JClass, jclass);
89define_auto_deallocate_builder!(jvmtiLineNumberEntry, JLineNumberEntry, jvmtiLineNumberEntry);
90
91impl<'a> Builder<JvmtiError> for MutObjectArrayBuilder<jvmtiError> {
92    fn build(&self) -> Vec<JvmtiError> {
93        if self.count == 0 || self.items.is_null() {
94            return vec![];
95        }
96        let items = slice_raw(self.items, self.count);
97        let res: Vec<JvmtiError> = items.iter()
98            .map(|&e| (e as jvmtiError).into())
99            .collect();
100        res
101    }
102}
103
104impl<'a> Builder<JCompiledMethodLoadRecordStackInfo<'a>> for MutObjectArrayBuilder<PCStackInfo> {
105    fn build(&self) -> Vec<JCompiledMethodLoadRecordStackInfo<'a>> {
106        if self.count == 0 || self.items.is_null() {
107            return vec![];
108        }
109        let res = slice_raw(self.items, self.count).iter().map(|e| {
110            let method_ids = slice_raw(e.methods, e.numstackframes);
111            let byte_code_indices = slice_raw(e.bcis, e.numstackframes);
112            let mut stack_frames = Vec::new();
113            if e.numstackframes > 0 {
114                for i in 0..(e.numstackframes as usize) {
115                    stack_frames.push(JCompiledMethodLoadRecordStackFrame {
116                        method: method_ids[i].into(),
117                        byte_code_index: byte_code_indices[i],
118                    });
119                }
120            }
121            JCompiledMethodLoadRecordStackInfo { pc_address: e.pc as usize, stack_frames: stack_frames }
122        }).collect();
123        res
124    }
125}
126
127impl<'a> AutoDeallocateBuilder<'a, JExtensionFunctionInfo<'a>> for MutAutoDeallocateObjectArrayBuilder<jvmtiExtensionFunctionInfo> {
128    fn build(&self, jvmti: &'a JVMTIEnv<'a>) -> Vec<JExtensionFunctionInfo<'a>> {
129        if self.count == 0 || self.items.is_null() {
130            return vec![];
131        }
132        let items = slice_raw(self.items, self.count);
133        let res: Vec<JExtensionFunctionInfo<'a>> = items.iter()
134            .map(|&e| JExtensionFunctionInfo::new(e as jvmtiExtensionFunctionInfo, jvmti))
135            .collect();
136
137        match jvmti.deallocate_raw(self.items as *mut c_void as jmemory) {
138            Err(e) => error!("JVMTI deallocate memory fail {}", e),
139            _ => {}
140        }
141        res
142    }
143}
144
145impl<'a> AutoDeallocateBuilder<'a, JExtensionEventInfo<'a>> for MutAutoDeallocateObjectArrayBuilder<jvmtiExtensionEventInfo> {
146    fn build(&self, jvmti: &'a JVMTIEnv<'a>) -> Vec<JExtensionEventInfo<'a>> {
147        if self.count == 0 || self.items.is_null() {
148            return vec![];
149        }
150        let items = slice_raw(self.items, self.count);
151        let res: Vec<JExtensionEventInfo<'a>> = items.iter()
152            .map(|&e| JExtensionEventInfo::new(e as jvmtiExtensionEventInfo, jvmti))
153            .collect();
154
155        match jvmti.deallocate_raw(self.items as *mut c_void as jmemory) {
156            Err(e) => error!("JVMTI deallocate memory fail {}", e),
157            _ => {}
158        }
159        res
160    }
161}
162
163impl<'a> AutoDeallocateBuilder<'a, JLocalVariableEntry<'a>> for MutAutoDeallocateObjectArrayBuilder<jvmtiLocalVariableEntry> {
164    fn build(&self, jvmti: &'a JVMTIEnv<'a>) -> Vec<JLocalVariableEntry<'a>> {
165        if self.count == 0 || self.items.is_null() {
166            return vec![];
167        }
168        let items = slice_raw(self.items, self.count);
169        let res: Vec<JLocalVariableEntry<'a>> = items.iter()
170            .map(|&e| {
171                let entry = e as jvmtiLocalVariableEntry;
172                JLocalVariableEntry::new(jvmti, &entry).unwrap()
173            })
174            .collect();
175        match jvmti.deallocate_raw(self.items as *mut c_void as jmemory) {
176            Err(e) => error!("JVMTI deallocate memory fail {}", e),
177            _ => {}
178        }
179        res
180    }
181}