Skip to main content

jni_simple/
lib.rs

1//! # jni-simple
2//! This crate contains a simple dumb handwritten rust wrapper around the JNI (Java Native Interface) API.
3//! It does absolutely no magic around the JNI Calls and lets you just use it as you would in C.
4//!
5//! In addition to JNI, this crate also provides a similar simplistic wrapper for the JVMTI (Java VM Tool Interface) API.
6//! The JVMTI Api can be used to write, for example, a Java Agent (like a Java debugger) in Rust or perform similar deep instrumentation with the JVM.
7//!
8//! If you are looking to start a jvm from rust then the entrypoints in this create are
9//! `init_dynamic_link`, `load_jvm_from_library`, `JNI_CreateJavaVM` and `JNI_GetCreatedJavaVMs`.
10//!
11//! If you are looking to write a jni library in rust then the types `JNIEnv` and jclass, etc.
12//! should be sufficient.
13//!
14#![no_std]
15#![allow(non_snake_case)]
16#![allow(non_camel_case_types)]
17#![deny(clippy::correctness)]
18#![deny(
19    clippy::perf,
20    clippy::complexity,
21    clippy::style,
22    clippy::nursery,
23    clippy::pedantic,
24    clippy::clone_on_ref_ptr,
25    clippy::decimal_literal_representation,
26    clippy::float_cmp_const,
27    clippy::missing_docs_in_private_items,
28    clippy::multiple_inherent_impl,
29    clippy::unwrap_used,
30    clippy::cargo_common_metadata,
31    clippy::used_underscore_binding
32)]
33#![allow(clippy::cognitive_complexity)]
34#![allow(clippy::inline_always)]
35//#![allow(clippy::trivially_copy_pass_by_ref)]
36
37/// This module contains the abi wrapper for jboolean using `core::ffi::c_uchar`
38mod jbool;
39/// This module contains all functions that are relevant for dynamic linking of the jvm.
40mod linking;
41
42pub use linking::{JNI_CreateJavaVM, JNI_CreateJavaVM_with_string_args, JNI_GetCreatedJavaVMs, JNI_GetCreatedJavaVMs_first, init_dynamic_link, is_jvm_loaded};
43
44#[cfg(feature = "loadjvm")]
45pub use linking::{LoadFromLibraryError, load_jvm_from_library};
46
47#[cfg(all(feature = "loadjvm", feature = "std"))]
48pub use linking::{LoadFromJavaHomeError, LoadFromJavaHomeFolderError, load_jvm_from_java_home, load_jvm_from_java_home_folder};
49
50extern crate alloc;
51#[cfg(feature = "std")]
52extern crate std;
53
54use alloc::borrow::Cow;
55use alloc::ffi::CString;
56use alloc::string::String;
57use alloc::string::ToString;
58use alloc::vec;
59use alloc::vec::Vec;
60
61use crate::private::{SealedAsJNILinkage, SealedEnvVTable, SealedJBooleanInputLayout, SealedJBooleanMutPtr};
62use alloc::boxed::Box;
63use core::cmp::Ordering;
64use core::ffi::{CStr, c_char, c_int, c_uchar, c_void};
65use core::fmt::{Debug, Display, Formatter};
66use core::hash::{Hash, Hasher};
67use core::ptr::null;
68use core::ptr::null_mut;
69use core::sync::atomic::Ordering::SeqCst;
70use sync_ptr::{FromMutPtr, SyncFnPtr, SyncMutPtr, sync_fn_ptr, sync_fn_ptr_opt};
71
72pub use crate::jbool::jboolean;
73pub const JNI_TRUE: jboolean = jboolean::TRUE;
74pub const JNI_FALSE: jboolean = jboolean::FALSE;
75
76///
77/// Trait for all types that can be used as a mutable boolean pointer for jni.
78/// JVM commonly uses this for functions that have an c-style output parameter via a pointer.
79///
80/// Implemented by
81/// - `&mut jboolean`
82/// - `* mut jboolean`
83/// - `&mut bool`
84/// - `* mut bool`
85/// - `()` -> "null pointer"
86///
87pub trait JBooleanMutPtr: SealedJBooleanMutPtr {}
88
89/// Trait for all types that have a ABI that is compatible for
90/// passing a jboolean from rust to java.
91///
92/// Implemented by:
93/// - `core::ffi::c_uchar`
94/// - `bool`
95/// - `jboolean`
96pub trait JBooleanInputLayout: SealedJBooleanInputLayout {}
97
98pub const JNI_OK: jint = 0;
99
100pub const JNI_COMMIT: jint = 1;
101
102pub const JNI_ABORT: jint = 2;
103pub const JNI_ERR: jint = -1;
104pub const JNI_EDETACHED: jint = -2;
105pub const JNI_EVERSION: jint = -3;
106pub const JNI_ENOMEM: jint = -4;
107pub const JNI_EEXIST: jint = -5;
108pub const JNI_EINVAL: jint = -6;
109pub const JVMTI_VERSION_1: jint = 0x3001_0000;
110pub const JVMTI_VERSION_1_0: jint = 0x3001_0000;
111pub const JVMTI_VERSION_1_1: jint = 0x3001_0100;
112pub const JVMTI_VERSION_1_2: jint = 0x3001_0200;
113
114pub const JVMTI_VERSION_9: jint = 0x3009_0000;
115pub const JVMTI_VERSION_11: jint = 0x300B_0000;
116pub const JVMTI_VERSION_19: jint = 0x3013_0000;
117pub const JVMTI_VERSION_21: jint = 0x3015_0000;
118
119pub const JVMTI_VERSION_25: jint = 0x3019_0000;
120
121pub const JNI_VERSION_1_1: jint = 0x0001_0001;
122pub const JNI_VERSION_1_2: jint = 0x0001_0002;
123pub const JNI_VERSION_1_4: jint = 0x0001_0004;
124pub const JNI_VERSION_1_6: jint = 0x0001_0006;
125pub const JNI_VERSION_1_8: jint = 0x0001_0008;
126pub const JNI_VERSION_9: jint = 0x0009_0000;
127pub const JNI_VERSION_10: jint = 0x000a_0000;
128pub const JNI_VERSION_19: jint = 0x0013_0000;
129pub const JNI_VERSION_20: jint = 0x0014_0000;
130pub const JNI_VERSION_21: jint = 0x0015_0000;
131
132pub const JNI_VERSION_24: jint = 0x0018_0000;
133
134//https://docs.oracle.com/en/java/javase/17/docs/api/constant-values.html#java.lang.reflect.Modifier.FINAL
135
136/// JVM modifier constant that represents the "final" keyword.
137pub const REFLECT_MODIFIER_FINAL: jint = 16;
138
139/// JVM modifier constant that represents the "interface" keyword.
140pub const REFLECT_MODIFIER_INTERFACE: jint = 512;
141
142/// JVM modifier constant that represents the "native" keyword.
143pub const REFLECT_MODIFIER_NATIVE: jint = 256;
144
145/// JVM modifier constant that represents the "private" keyword.
146pub const REFLECT_MODIFIER_PRIVATE: jint = 2;
147
148/// JVM modifier constant that represents the "protected" keyword.
149pub const REFLECT_MODIFIER_PROTECTED: jint = 4;
150
151/// JVM modifier constant that represents the "public" keyword.
152pub const REFLECT_MODIFIER_PUBLIC: jint = 1;
153
154/// JVM modifier constant that represents the "static" keyword.
155pub const REFLECT_MODIFIER_STATIC: jint = 8;
156
157/// JVM modifier constant that represents the "strictfp" keyword.
158pub const REFLECT_MODIFIER_STRICT: jint = 2048;
159
160/// JVM modifier constant that represents the "synchronized" keyword.
161pub const REFLECT_MODIFIER_SYNCHRONIZED: jint = 32;
162
163/// JVM modifier constant that represents the "transient" keyword.
164pub const REFLECT_MODIFIER_TRANSIENT: jint = 128;
165
166/// JVM modifier constant that represents the "volatile" keyword.
167pub const REFLECT_MODIFIER_VOLATILE: jint = 64;
168
169pub type jlong = i64;
170
171pub type jlocation = jlong;
172
173pub type jint = i32;
174pub type jsize = jint;
175pub type jshort = i16;
176pub type jchar = u16;
177pub type jbyte = i8;
178
179pub type jfloat = core::ffi::c_float;
180
181pub type jdouble = core::ffi::c_double;
182
183pub type jclass = *mut c_void;
184
185pub type jobject = *mut c_void;
186
187pub type jstring = jobject;
188
189pub type jarray = jobject;
190
191pub type jobjectArray = jarray;
192
193pub type jbooleanArray = jarray;
194
195pub type jbyteArray = jarray;
196
197pub type jcharArray = jarray;
198
199pub type jshortArray = jarray;
200
201pub type jintArray = jarray;
202
203pub type jlongArray = jarray;
204
205pub type jfloatArray = jarray;
206
207pub type jdoubleArray = jarray;
208
209#[repr(C)]
210#[derive(Debug, Ord, Eq, PartialOrd, PartialEq, Hash, Clone, Copy)]
211pub enum jobjectRefType {
212    JNIInvalidRefType = 0,
213    JNILocalRefType = 1,
214    JNIGlobalRefType = 2,
215    JNIWeakGlobalRefType = 3,
216}
217
218/// Rust enum that mirrors jvmtiError, however it has a different repr to `c_int` causing it to be incompatible outside of rust code.
219///
220/// It is mainly useful to use in rusts match statements.
221///
222/// This enum can be transformed from the repr(C) jvmtiError or transformed into it via the From/Into traits.
223#[derive(Debug, Eq, Clone, Copy)]
224pub enum JvmtiError {
225    NONE,
226    INVALID_THREAD,
227    INVALID_THREAD_GROUP,
228    INVALID_PRIORITY,
229    THREAD_NOT_SUSPENDED,
230    THREAD_SUSPENDED,
231    THREAD_NOT_ALIVE,
232    INVALID_OBJECT,
233    INVALID_CLASS,
234    CLASS_NOT_PREPARED,
235    INVALID_METHODID,
236    INVALID_LOCATION,
237    INVALID_FIELDID,
238    INVALID_MODULE,
239    NO_MORE_FRAMES,
240    OPAQUE_FRAME,
241    TYPE_MISMATCH,
242    INVALID_SLOT,
243    DUPLICATE,
244    NOT_FOUND,
245    INVALID_MONITOR,
246    NOT_MONITOR_OWNER,
247    INTERRUPT,
248    INVALID_CLASS_FORMAT,
249    CIRCULAR_CLASS_DEFINITION,
250    FAILS_VERIFICATION,
251    UNSUPPORTED_REDEFINITION_METHOD_ADDED,
252    UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED,
253    INVALID_TYPESTATE,
254    UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED,
255    UNSUPPORTED_REDEFINITION_METHOD_DELETED,
256    UNSUPPORTED_VERSION,
257    NAMES_DONT_MATCH,
258    UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED,
259    UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED,
260    UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED,
261    UNSUPPORTED_OPERATION,
262    UNMODIFIABLE_CLASS,
263    UNMODIFIABLE_MODULE,
264    NOT_AVAILABLE,
265    MUST_POSSESS_CAPABILITY,
266    NULL_POINTER,
267    ABSENT_INFORMATION,
268    INVALID_EVENT_TYPE,
269    ILLEGAL_ARGUMENT,
270    NATIVE_METHOD,
271    CLASS_LOADER_UNSUPPORTED,
272    OUT_OF_MEMORY,
273    ACCESS_DENIED,
274    WRONG_PHASE,
275    INTERNAL,
276    UNATTACHED_THREAD,
277    INVALID_ENVIRONMENT,
278    OTHER(c_int), //TODO seal this c_int
279}
280
281impl Display for JvmtiError {
282    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
283        //Unwind the other case and fold it into known codes.
284        let me: c_int = (*self).into();
285        let reform = Self::from(me);
286        //Debug fmt it.
287        Debug::fmt(&reform, f)
288    }
289}
290
291//we have to implement this because the OTHER case may shadow an actual error code.
292impl PartialEq for JvmtiError {
293    fn eq(&self, other: &Self) -> bool {
294        let me: c_int = (*self).into();
295        let other: c_int = (*other).into();
296        me == other
297    }
298}
299
300//we have to implement this because the OTHER case may shadow an actual error code.
301impl Ord for JvmtiError {
302    fn cmp(&self, other: &Self) -> Ordering {
303        let me: c_int = (*self).into();
304        let other: c_int = (*other).into();
305        c_int::cmp(&me, &other)
306    }
307}
308
309impl PartialOrd for JvmtiError {
310    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
311        Some(self.cmp(other))
312    }
313}
314
315//we have to implement this because the OTHER case may shadow an actual error code.
316impl Hash for JvmtiError {
317    fn hash<H: Hasher>(&self, state: &mut H) {
318        let me: c_int = (*self).into();
319        state.write_i64(i64::from(me));
320    }
321}
322
323impl From<c_int> for JvmtiError {
324    fn from(value: c_int) -> Self {
325        Self::from_raw(value)
326    }
327}
328
329impl From<&JvmtiError> for c_int {
330    fn from(value: &JvmtiError) -> Self {
331        (*value).into()
332    }
333}
334
335impl From<JvmtiError> for c_int {
336    fn from(value: JvmtiError) -> Self {
337        JvmtiError::into_raw(value)
338    }
339}
340
341impl JvmtiError {
342    /// Const implementation of `From<c_int>`
343    #[must_use]
344    pub const fn from_raw(raw: c_int) -> Self {
345        match raw {
346            0 => Self::NONE,
347            10 => Self::INVALID_THREAD,
348            11 => Self::INVALID_THREAD_GROUP,
349            12 => Self::INVALID_PRIORITY,
350            13 => Self::THREAD_NOT_SUSPENDED,
351            14 => Self::THREAD_SUSPENDED,
352            15 => Self::THREAD_NOT_ALIVE,
353            20 => Self::INVALID_OBJECT,
354            21 => Self::INVALID_CLASS,
355            22 => Self::CLASS_NOT_PREPARED,
356            23 => Self::INVALID_METHODID,
357            24 => Self::INVALID_LOCATION,
358            25 => Self::INVALID_FIELDID,
359            26 => Self::INVALID_MODULE,
360            31 => Self::NO_MORE_FRAMES,
361            32 => Self::OPAQUE_FRAME,
362            34 => Self::TYPE_MISMATCH,
363            35 => Self::INVALID_SLOT,
364            40 => Self::DUPLICATE,
365            41 => Self::NOT_FOUND,
366            50 => Self::INVALID_MONITOR,
367            51 => Self::NOT_MONITOR_OWNER,
368            52 => Self::INTERRUPT,
369            60 => Self::INVALID_CLASS_FORMAT,
370            61 => Self::CIRCULAR_CLASS_DEFINITION,
371            62 => Self::FAILS_VERIFICATION,
372            63 => Self::UNSUPPORTED_REDEFINITION_METHOD_ADDED,
373            64 => Self::UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED,
374            65 => Self::INVALID_TYPESTATE,
375            66 => Self::UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED,
376            67 => Self::UNSUPPORTED_REDEFINITION_METHOD_DELETED,
377            68 => Self::UNSUPPORTED_VERSION,
378            69 => Self::NAMES_DONT_MATCH,
379            70 => Self::UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED,
380            71 => Self::UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED,
381            72 => Self::UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED,
382            73 => Self::UNSUPPORTED_OPERATION,
383            79 => Self::UNMODIFIABLE_CLASS,
384            80 => Self::UNMODIFIABLE_MODULE,
385            98 => Self::NOT_AVAILABLE,
386            99 => Self::MUST_POSSESS_CAPABILITY,
387            100 => Self::NULL_POINTER,
388            101 => Self::ABSENT_INFORMATION,
389            102 => Self::INVALID_EVENT_TYPE,
390            103 => Self::ILLEGAL_ARGUMENT,
391            104 => Self::NATIVE_METHOD,
392            106 => Self::CLASS_LOADER_UNSUPPORTED,
393            110 => Self::OUT_OF_MEMORY,
394            111 => Self::ACCESS_DENIED,
395            112 => Self::WRONG_PHASE,
396            113 => Self::INTERNAL,
397            115 => Self::UNATTACHED_THREAD,
398            116 => Self::INVALID_ENVIRONMENT,
399            other => Self::OTHER(other),
400        }
401    }
402
403    /// Const implementation of `Into<c_int>`
404    #[must_use]
405    pub const fn into_raw(self) -> c_int {
406        match self {
407            Self::NONE => 0,
408            Self::INVALID_THREAD => 10,
409            Self::INVALID_THREAD_GROUP => 11,
410            Self::INVALID_PRIORITY => 12,
411            Self::THREAD_NOT_SUSPENDED => 13,
412            Self::THREAD_SUSPENDED => 14,
413            Self::THREAD_NOT_ALIVE => 15,
414            Self::INVALID_OBJECT => 20,
415            Self::INVALID_CLASS => 21,
416            Self::CLASS_NOT_PREPARED => 22,
417            Self::INVALID_METHODID => 23,
418            Self::INVALID_LOCATION => 24,
419            Self::INVALID_FIELDID => 25,
420            Self::INVALID_MODULE => 26,
421            Self::NO_MORE_FRAMES => 31,
422            Self::OPAQUE_FRAME => 32,
423            Self::TYPE_MISMATCH => 34,
424            Self::INVALID_SLOT => 35,
425            Self::DUPLICATE => 40,
426            Self::NOT_FOUND => 41,
427            Self::INVALID_MONITOR => 50,
428            Self::NOT_MONITOR_OWNER => 51,
429            Self::INTERRUPT => 52,
430            Self::INVALID_CLASS_FORMAT => 60,
431            Self::CIRCULAR_CLASS_DEFINITION => 61,
432            Self::FAILS_VERIFICATION => 62,
433            Self::UNSUPPORTED_REDEFINITION_METHOD_ADDED => 63,
434            Self::UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED => 64,
435            Self::INVALID_TYPESTATE => 65,
436            Self::UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED => 66,
437            Self::UNSUPPORTED_REDEFINITION_METHOD_DELETED => 67,
438            Self::UNSUPPORTED_VERSION => 68,
439            Self::NAMES_DONT_MATCH => 69,
440            Self::UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED => 70,
441            Self::UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED => 71,
442            Self::UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED => 72,
443            Self::UNSUPPORTED_OPERATION => 73,
444            Self::UNMODIFIABLE_CLASS => 79,
445            Self::UNMODIFIABLE_MODULE => 80,
446            Self::NOT_AVAILABLE => 98,
447            Self::MUST_POSSESS_CAPABILITY => 99,
448            Self::NULL_POINTER => 100,
449            Self::ABSENT_INFORMATION => 101,
450            Self::INVALID_EVENT_TYPE => 102,
451            Self::ILLEGAL_ARGUMENT => 103,
452            Self::NATIVE_METHOD => 104,
453            Self::CLASS_LOADER_UNSUPPORTED => 106,
454            Self::OUT_OF_MEMORY => 110,
455            Self::ACCESS_DENIED => 111,
456            Self::WRONG_PHASE => 112,
457            Self::INTERNAL => 113,
458            Self::UNATTACHED_THREAD => 115,
459            Self::INVALID_ENVIRONMENT => 116,
460            Self::OTHER(value) => value,
461        }
462    }
463
464    /// Returns true if this `JvmtiError` refers to `JVMTI_ERROR_NONE`
465    #[must_use]
466    pub const fn is_ok(&self) -> bool {
467        matches!(self, Self::NONE)
468    }
469
470    /// Returns true if this `JvmtiError` does not refer to `JVMTI_ERROR_NONE`
471    #[must_use]
472    pub const fn is_err(&self) -> bool {
473        !self.is_ok()
474    }
475
476    /// Returns `Ok(())` if self is `JVMTI_ERROR_NONE` otherwise returns `Err(self)`
477    ///
478    /// # Errors
479    /// if self is not `JVMTI_ERROR_NONE`
480    pub const fn into_result(self) -> Result<(), Self> {
481        if self.is_ok() {
482            return Ok(());
483        }
484
485        Err(self)
486    }
487}
488
489//We cannot turn this into an enum because the JVM may with a reasonable likelihood decide to add new codes in the future.
490//If we enum this and the VM returned a code we don't know it would instantly be UB.
491#[repr(transparent)]
492#[derive(Debug, Ord, Eq, PartialOrd, PartialEq, Hash, Clone, Copy)]
493#[must_use]
494pub struct jvmtiError(pub c_int);
495
496impl Display for jvmtiError {
497    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
498        let display_var = JvmtiError::from(self.0);
499        Display::fmt(&display_var, f)
500    }
501}
502
503impl From<c_int> for jvmtiError {
504    fn from(value: c_int) -> Self {
505        Self(value)
506    }
507}
508
509impl From<jvmtiError> for c_int {
510    fn from(value: jvmtiError) -> Self {
511        value.0
512    }
513}
514
515impl From<&jvmtiError> for c_int {
516    fn from(value: &jvmtiError) -> Self {
517        value.0
518    }
519}
520
521impl From<JvmtiError> for jvmtiError {
522    fn from(value: JvmtiError) -> Self {
523        let me: c_int = value.into();
524        me.into()
525    }
526}
527
528impl From<jvmtiError> for JvmtiError {
529    fn from(value: jvmtiError) -> Self {
530        let me: c_int = value.into();
531        me.into()
532    }
533}
534
535impl jvmtiError {
536    #[must_use]
537    pub const fn is_ok(self) -> bool {
538        self.0 == JVMTI_ERROR_NONE.0
539    }
540
541    #[must_use]
542    pub const fn is_err(self) -> bool {
543        self.0 != JVMTI_ERROR_NONE.0
544    }
545
546    /// This function transforms the jvmtiError into a Result if the jvmtiError is not `JVMTI_ERROR_NONE`.
547    /// Its useful if you want to use the "if let" pattern.
548    ///
549    /// # Errors
550    /// if jvmtiError is not equal to `JVMTI_ERROR_NONE`
551    ///
552    /// # Example
553    /// ```rust
554    /// use jni_simple::{jint, JVMTIEnv, JVMTI_VERSION_21};
555    ///
556    /// fn check_version21(env: JVMTIEnv) {
557    ///     unsafe {
558    ///         let mut version: jint = 0;
559    ///         if let Err(err) = env.GetVersionNumber(&mut version).into_result() {
560    ///             //Handle failed jvmti call
561    ///             //You can also match on err here if you want.
562    ///             panic!("GetVersionNumber call failed with err={err}")
563    ///         }
564    ///
565    ///         //Handle successful jvmti call
566    ///         if version != JVMTI_VERSION_21 {
567    ///             panic!("JVMTI Version is not 21");
568    ///         }
569    ///     }
570    /// }
571    ///
572    /// ```
573    ///
574    pub const fn into_result(self) -> Result<(), JvmtiError> {
575        if self.is_ok() {
576            return Ok(());
577        }
578
579        Err(JvmtiError::from_raw(self.0))
580    }
581
582    /// This function will return if self is `JVMTI_ERROR_NONE` otherwise
583    /// it will panic with the given message as well as the value of self.
584    ///
585    /// This method will attempt to resolve self to a known constant and print the name
586    /// of the constant in the panic message if at all possible. If self is not a known
587    /// constant the numeric value of self will be contained in the panic message.
588    ///
589    /// # Panics
590    /// if self is not `JVMTI_ERROR_NONE`
591    ///
592    pub fn expect(self, msg: &str) {
593        self.into_result().expect(msg);
594    }
595
596    /// This function transforms the jvmtiError into a rust enum that you can easily match on.
597    ///
598    /// # Example
599    /// ```rust
600    /// use jni_simple::{jint, JVMTIEnv, JvmtiError, JVMTI_VERSION_21};
601    ///
602    /// fn check_version21(env: JVMTIEnv) {
603    ///     unsafe {
604    ///         let mut version: jint = 0;
605    ///         match env.GetVersionNumber(&mut version).into_enum() {
606    ///             JvmtiError::NONE => {
607    ///              //Handle successful jvmti call
608    ///              if version != JVMTI_VERSION_21 {
609    ///                  panic!("JVMTI Version is not 21");
610    ///              }
611    ///             }
612    ///             err => {
613    ///                  panic!("GetVersionNumber call failed with err={err}")
614    ///             }
615    ///         }
616    ///     }
617    /// }
618    ///
619    /// ```
620    ///
621    #[must_use]
622    pub const fn into_enum(self) -> JvmtiError {
623        JvmtiError::from_raw(self.0)
624    }
625
626    /// This function transforms the jvmtiError back into its raw magic number from the jvm.
627    /// This is useful if you deal with undocumented errors from customized jvm's.
628    ///
629    /// # Example
630    /// ```rust
631    /// use std::ffi::c_int;
632    /// use jni_simple::{jint, JVMTIEnv, JvmtiError, JVMTI_VERSION_21};
633    ///
634    /// fn check_version21(env: JVMTIEnv) {
635    ///     unsafe {
636    ///         let mut version: jint = 0;
637    ///         let raw_err : c_int = env.GetVersionNumber(&mut version).into_raw();
638    ///         match raw_err {
639    ///             0 => {
640    ///              //Handle successful jvmti call
641    ///              if version != JVMTI_VERSION_21 {
642    ///                  panic!("JVMTI Version is not 21");
643    ///              }
644    ///             }
645    ///             err => {
646    ///                  panic!("GetVersionNumber call failed with magic number err={err}")
647    ///             }
648    ///         }
649    ///     }
650    /// }
651    ///
652    /// ```
653    ///
654    #[must_use]
655    pub const fn into_raw(self) -> c_int {
656        self.0
657    }
658}
659
660pub const JVMTI_ERROR_NONE: jvmtiError = jvmtiError(0);
661pub const JVMTI_ERROR_INVALID_THREAD: jvmtiError = jvmtiError(10);
662pub const JVMTI_ERROR_INVALID_THREAD_GROUP: jvmtiError = jvmtiError(11);
663pub const JVMTI_ERROR_INVALID_PRIORITY: jvmtiError = jvmtiError(12);
664pub const JVMTI_ERROR_THREAD_NOT_SUSPENDED: jvmtiError = jvmtiError(13);
665pub const JVMTI_ERROR_THREAD_SUSPENDED: jvmtiError = jvmtiError(14);
666pub const JVMTI_ERROR_THREAD_NOT_ALIVE: jvmtiError = jvmtiError(15);
667pub const JVMTI_ERROR_INVALID_OBJECT: jvmtiError = jvmtiError(20);
668pub const JVMTI_ERROR_INVALID_CLASS: jvmtiError = jvmtiError(21);
669pub const JVMTI_ERROR_CLASS_NOT_PREPARED: jvmtiError = jvmtiError(22);
670pub const JVMTI_ERROR_INVALID_METHODID: jvmtiError = jvmtiError(23);
671pub const JVMTI_ERROR_INVALID_LOCATION: jvmtiError = jvmtiError(24);
672pub const JVMTI_ERROR_INVALID_FIELDID: jvmtiError = jvmtiError(25);
673pub const JVMTI_ERROR_INVALID_MODULE: jvmtiError = jvmtiError(26);
674pub const JVMTI_ERROR_NO_MORE_FRAMES: jvmtiError = jvmtiError(31);
675pub const JVMTI_ERROR_OPAQUE_FRAME: jvmtiError = jvmtiError(32);
676pub const JVMTI_ERROR_TYPE_MISMATCH: jvmtiError = jvmtiError(34);
677pub const JVMTI_ERROR_INVALID_SLOT: jvmtiError = jvmtiError(35);
678pub const JVMTI_ERROR_DUPLICATE: jvmtiError = jvmtiError(40);
679pub const JVMTI_ERROR_NOT_FOUND: jvmtiError = jvmtiError(41);
680pub const JVMTI_ERROR_INVALID_MONITOR: jvmtiError = jvmtiError(50);
681pub const JVMTI_ERROR_NOT_MONITOR_OWNER: jvmtiError = jvmtiError(51);
682pub const JVMTI_ERROR_INTERRUPT: jvmtiError = jvmtiError(52);
683pub const JVMTI_ERROR_INVALID_CLASS_FORMAT: jvmtiError = jvmtiError(60);
684pub const JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION: jvmtiError = jvmtiError(61);
685pub const JVMTI_ERROR_FAILS_VERIFICATION: jvmtiError = jvmtiError(62);
686pub const JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED: jvmtiError = jvmtiError(63);
687pub const JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED: jvmtiError = jvmtiError(64);
688pub const JVMTI_ERROR_INVALID_TYPESTATE: jvmtiError = jvmtiError(65);
689pub const JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED: jvmtiError = jvmtiError(66);
690pub const JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED: jvmtiError = jvmtiError(67);
691pub const JVMTI_ERROR_UNSUPPORTED_VERSION: jvmtiError = jvmtiError(68);
692pub const JVMTI_ERROR_NAMES_DONT_MATCH: jvmtiError = jvmtiError(69);
693pub const JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED: jvmtiError = jvmtiError(70);
694pub const JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED: jvmtiError = jvmtiError(71);
695pub const JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED: jvmtiError = jvmtiError(72);
696pub const JVMTI_ERROR_UNSUPPORTED_OPERATION: jvmtiError = jvmtiError(73);
697pub const JVMTI_ERROR_UNMODIFIABLE_CLASS: jvmtiError = jvmtiError(79);
698pub const JVMTI_ERROR_UNMODIFIABLE_MODULE: jvmtiError = jvmtiError(80);
699pub const JVMTI_ERROR_NOT_AVAILABLE: jvmtiError = jvmtiError(98);
700pub const JVMTI_ERROR_MUST_POSSESS_CAPABILITY: jvmtiError = jvmtiError(99);
701pub const JVMTI_ERROR_NULL_POINTER: jvmtiError = jvmtiError(100);
702pub const JVMTI_ERROR_ABSENT_INFORMATION: jvmtiError = jvmtiError(101);
703pub const JVMTI_ERROR_INVALID_EVENT_TYPE: jvmtiError = jvmtiError(102);
704pub const JVMTI_ERROR_ILLEGAL_ARGUMENT: jvmtiError = jvmtiError(103);
705pub const JVMTI_ERROR_NATIVE_METHOD: jvmtiError = jvmtiError(104);
706pub const JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED: jvmtiError = jvmtiError(106);
707pub const JVMTI_ERROR_OUT_OF_MEMORY: jvmtiError = jvmtiError(110);
708pub const JVMTI_ERROR_ACCESS_DENIED: jvmtiError = jvmtiError(111);
709pub const JVMTI_ERROR_WRONG_PHASE: jvmtiError = jvmtiError(112);
710pub const JVMTI_ERROR_INTERNAL: jvmtiError = jvmtiError(113);
711pub const JVMTI_ERROR_UNATTACHED_THREAD: jvmtiError = jvmtiError(115);
712pub const JVMTI_ERROR_INVALID_ENVIRONMENT: jvmtiError = jvmtiError(116);
713pub const JVMTI_ERROR_MAX: jvmtiError = jvmtiError(116);
714
715/////////////////////////////////////////////////////////////////////
716///Thread is alive. Zero if thread is new (not started) or terminated.
717pub const JVMTI_THREAD_STATE_ALIVE: jint = 0x0001;
718
719/// Thread has completed execution.
720pub const JVMTI_THREAD_STATE_TERMINATED: jint = 0x0002;
721
722/// Thread is runnable.
723pub const JVMTI_THREAD_STATE_RUNNABLE: jint = 0x0004;
724
725/// Thread is waiting to enter a synchronized block/method or, after an `Object.wait()`, waiting to re-enter a synchronized block/method.
726pub const JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER: jint = 0x0400;
727
728/// Thread is waiting.
729pub const JVMTI_THREAD_STATE_WAITING: jint = 0x0080;
730
731/// Thread is waiting without a timeout. For example, `Object.wait()`.
732pub const JVMTI_THREAD_STATE_WAITING_INDEFINITELY: jint = 0x0010;
733
734/// Thread is waiting with a maximum time to wait specified. For example, Object.wait(long).
735pub const JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT: jint = 0x0020;
736
737/// Thread is sleeping -- Thread.sleep.
738pub const JVMTI_THREAD_STATE_SLEEPING: jint = 0x0040;
739
740/// Thread is waiting on an object monitor -- Object.wait.
741pub const JVMTI_THREAD_STATE_IN_OBJECT_WAIT: jint = 0x0100;
742
743/// Thread is parked, for example: LockSupport.park, LockSupport.parkUtil and LockSupport.parkNanos. A virtual thread that is sleeping, in Thread.sleep, may have this state flag set instead of `JVMTI_THREAD_STATE_SLEEPING`.
744pub const JVMTI_THREAD_STATE_PARKED: jint = 0x0200;
745
746/// Thread is suspended by a suspend function (such as `SuspendThread`). If this bit is set, the other bits refer to the thread state before suspension.
747pub const JVMTI_THREAD_STATE_SUSPENDED: jint = 0x0010_0000;
748
749/// Thread has been interrupted.
750pub const JVMTI_THREAD_STATE_INTERRUPTED: jint = 0x0020_0000;
751
752/// Thread is in native code--that is, a native method is running which has not called back into the VM or Java programming language code.
753///
754/// This flag is not set when running VM compiled Java programming language code nor is it set when running VM code or VM support code.
755///
756/// Native VM interface functions, such as JNI and JVM TI functions, may be implemented as VM code.
757pub const JVMTI_THREAD_STATE_IN_NATIVE: jint = 0x0040_0000;
758
759/// Defined by VM vendor.
760pub const JVMTI_THREAD_STATE_VENDOR_1: jint = 0x1000_0000;
761
762/// Defined by VM vendor.
763pub const JVMTI_THREAD_STATE_VENDOR_2: jint = 0x2000_0000;
764
765/// Defined by VM vendor.
766pub const JVMTI_THREAD_STATE_VENDOR_3: jint = 0x4000_0000;
767
768/// Mod for private trait seals that should be hidden.
769mod private {
770    use crate::{jboolean, jrawMonitorID};
771    use core::ffi::{c_char, c_void};
772
773    /// Trait seal for `AsJrawMonitorID`
774    pub trait SealedAsJrawMonitorID {
775        /// Gets the underlying `jrawMonitorID`
776        fn jraw_monitor_id(self) -> jrawMonitorID;
777    }
778
779    /// Trait seal for `JrawMonitorIDReceiver`
780    pub trait SealedReceiveJrawMonitorID {
781        /// Can the arg produce a pointer that can be directly passed to jvmti?
782        fn is_direct() -> bool;
783
784        /// Get the raw pointer to pass directly to jvmti.
785        fn direct_arg(self) -> *mut jrawMonitorID;
786
787        /// Store the newly created `jrawMonitorID`
788        fn receive(self, monitor: jrawMonitorID);
789    }
790
791    ///Trait seal for `AsJNILinkage`
792    pub trait SealedAsJNILinkage {
793        /// Returns the jni linkage index.
794        fn linkage(self) -> usize;
795    }
796
797    /// Trait seal for `JBooleanMutPtr`
798    pub trait SealedJBooleanMutPtr {
799        /// Call the closure with a *mut jboolean pointer that is valid for at least the duration of the call.
800        fn use_jboolean_mut<R>(self, func: impl FnOnce(*mut jboolean) -> R) -> R;
801    }
802
803    /// Trait seal for `JBooleanInputLayout`
804    pub trait SealedJBooleanInputLayout {}
805
806    /// Trait seal for `JType`
807    pub trait SealedJType {}
808
809    /// Trait Seal for `UseCString`
810    pub trait SealedUseCString {
811        /// Transform the string into a zero terminated string if necessary and calls the closure with it.
812        /// The pointer passed into the closure only stays valid until the closure returns.
813        /// The string is guaranteed to be 0 terminated!
814        /// The string is not guaranteed to be valid utf-8, but it can generally be assumed to be utf-8!
815        ///
816        /// # Undefined Behavior
817        /// If called on a raw pointer type that is not in fact 0 terminated.
818        /// Yes I am aware that is should make this fn unsafe because of this.
819        /// I choose not to do so because it doesnt apply for 90% of the implementations of this trait.
820        ///
821        /// # Panics
822        /// panics if asserts feature is enabled and the implementation is capable of detecting that the string is not utf-8.
823        /// This check is only relevant for types that do not do conversion to utf-8 by default (such as `OsString` and friends)
824        ///
825        fn use_as_const_c_char<X>(self, param: impl FnOnce(*const c_char) -> X) -> X;
826    }
827
828    #[test]
829    #[cfg(feature = "std")]
830    pub fn testSealedUseCString() {
831        use std::ffi::{CStr, OsString};
832
833        unsafe {
834            assert!([].use_as_const_c_char(|ptr| CStr::from_ptr(ptr).to_bytes().is_empty()));
835            assert!([0u8].use_as_const_c_char(|ptr| CStr::from_ptr(ptr).to_bytes().is_empty()));
836            assert!("".use_as_const_c_char(|ptr| CStr::from_ptr(ptr).to_bytes().is_empty()));
837            assert!("abc".use_as_const_c_char(|ptr| CStr::from_ptr(ptr).to_bytes() == [b'a', b'b', b'c']));
838            assert!([b'a', b'b', 0, b'c'].use_as_const_c_char(|ptr| CStr::from_ptr(ptr).to_bytes() == [b'a', b'b']));
839            assert!("abc\0".use_as_const_c_char(|ptr| CStr::from_ptr(ptr).to_bytes() == [b'a', b'b', b'c']));
840            assert!(OsString::from("abc").use_as_const_c_char(|ptr| CStr::from_ptr(ptr).to_bytes() == [b'a', b'b', b'c']));
841
842            #[cfg(feature = "asserts")]
843            {
844                let r = std::panic::catch_unwind(|| [0b1011_1111, b'A', b'B'].as_slice().use_as_const_c_char(|_| std::process::abort()));
845                assert!(r.is_err());
846            }
847        }
848    }
849
850    /// Sealed trait for the Env Vtable receiver so we can check if the receiver is correct if asssertions are correct.
851    pub trait SealedEnvVTable: From<*mut c_void> {
852        /// can this receiver get the JNI function table?
853        fn can_jni() -> bool;
854
855        /// can this receiver get the JVMTI function table?
856        fn can_jvmti() -> bool;
857    }
858
859    impl SealedEnvVTable for *mut c_void {
860        fn can_jni() -> bool {
861            true
862        }
863
864        fn can_jvmti() -> bool {
865            true
866        }
867    }
868}
869
870pub type jweak = jobject;
871
872pub type jthrowable = jobject;
873
874pub type jthread = jobject;
875
876pub type jthreadGroup = jobject;
877
878pub type jmethodID = jobject;
879pub type jfieldID = jobject;
880
881///
882/// Marker trait for all types that are valid to use to make variadic JNI Up-calls with.
883///
884pub trait JType: private::SealedJType + Into<jtype> + Clone + Copy {
885    ///
886    /// Returns a single character that equals the type's JNI signature.
887    ///
888    /// Boolean -> Z
889    /// Byte -> B
890    /// Short -> S
891    /// Char -> C
892    /// Int -> I
893    /// Long -> J
894    /// Float -> F
895    /// Double -> D
896    /// any java.lang.Object -> L
897    ///
898    ///
899    fn jtype_id() -> char;
900}
901impl private::SealedJType for jobject {}
902impl JType for jobject {
903    #[inline(always)]
904    fn jtype_id() -> char {
905        'L'
906    }
907}
908impl private::SealedJType for jboolean {}
909impl JType for jboolean {
910    #[inline(always)]
911    fn jtype_id() -> char {
912        'Z'
913    }
914}
915impl private::SealedJType for jbyte {}
916impl JType for jbyte {
917    #[inline(always)]
918    fn jtype_id() -> char {
919        'B'
920    }
921}
922impl private::SealedJType for jshort {}
923impl JType for jshort {
924    #[inline(always)]
925    fn jtype_id() -> char {
926        'S'
927    }
928}
929impl private::SealedJType for jchar {}
930impl JType for jchar {
931    #[inline(always)]
932    fn jtype_id() -> char {
933        'C'
934    }
935}
936impl private::SealedJType for jint {}
937impl JType for jint {
938    #[inline(always)]
939    fn jtype_id() -> char {
940        'I'
941    }
942}
943impl private::SealedJType for jlong {}
944impl JType for jlong {
945    #[inline(always)]
946    fn jtype_id() -> char {
947        'J'
948    }
949}
950impl private::SealedJType for jfloat {}
951impl JType for jfloat {
952    #[inline(always)]
953    fn jtype_id() -> char {
954        'F'
955    }
956}
957impl private::SealedJType for jdouble {}
958impl JType for jdouble {
959    #[inline(always)]
960    fn jtype_id() -> char {
961        'D'
962    }
963}
964
965#[repr(C)]
966#[derive(Clone, Copy)]
967#[allow(clippy::missing_docs_in_private_items)]
968pub union jtype {
969    long: jlong,
970    int: jint,
971    short: jshort,
972    char: jchar,
973    byte: jbyte,
974    boolean: jboolean,
975    float: jfloat,
976    double: jdouble,
977    object: jobject,
978    class: jclass,
979    throwable: jthrowable,
980}
981
982pub type jvalue = jtype;
983
984pub type jrawMonitorID = *mut jrawMonitorIDType;
985
986pub type jrawMonitorIDType = c_void;
987
988pub trait AsJrawMonitorID: private::SealedAsJrawMonitorID {}
989
990pub trait ReceiveJrawMonitorID: private::SealedReceiveJrawMonitorID {}
991
992impl private::SealedAsJrawMonitorID for jrawMonitorID {
993    fn jraw_monitor_id(self) -> jrawMonitorID {
994        self
995    }
996}
997impl AsJrawMonitorID for jrawMonitorID {}
998
999impl private::SealedAsJrawMonitorID for &core::sync::atomic::AtomicPtr<jrawMonitorIDType> {
1000    fn jraw_monitor_id(self) -> jrawMonitorID {
1001        self.load(SeqCst)
1002    }
1003}
1004impl AsJrawMonitorID for &core::sync::atomic::AtomicPtr<jrawMonitorIDType> {}
1005
1006impl private::SealedReceiveJrawMonitorID for &mut jrawMonitorID {
1007    fn is_direct() -> bool {
1008        false
1009    }
1010
1011    fn direct_arg(self) -> *mut jrawMonitorID {
1012        unreachable!()
1013    }
1014    fn receive(self, monitor: jrawMonitorID) {
1015        *self = monitor;
1016    }
1017}
1018
1019impl ReceiveJrawMonitorID for &mut jrawMonitorID {}
1020
1021impl private::SealedReceiveJrawMonitorID for &core::sync::atomic::AtomicPtr<jrawMonitorIDType> {
1022    fn is_direct() -> bool {
1023        false
1024    }
1025
1026    fn direct_arg(self) -> *mut jrawMonitorID {
1027        unreachable!()
1028    }
1029
1030    fn receive(self, monitor: jrawMonitorID) {
1031        self.store(monitor, SeqCst);
1032    }
1033}
1034
1035impl ReceiveJrawMonitorID for &core::sync::atomic::AtomicPtr<jrawMonitorIDType> {}
1036
1037impl private::SealedReceiveJrawMonitorID for *mut jrawMonitorID {
1038    fn is_direct() -> bool {
1039        true
1040    }
1041
1042    fn direct_arg(self) -> *mut jrawMonitorID {
1043        self
1044    }
1045
1046    fn receive(self, _monitor: jrawMonitorID) {
1047        unreachable!()
1048    }
1049}
1050
1051impl ReceiveJrawMonitorID for *mut jrawMonitorID {}
1052
1053///
1054/// This macro is usefull for constructing jtype arrays.
1055/// This is often needed when making upcalls into the jvm with many arguments using the 'A' type functions:
1056/// * CallStatic(TYPE)MethodA
1057///     * `CallStaticVoidMethodA`
1058///     * `CallStaticIntMethodA`
1059///     * ...
1060/// * Call(TYPE)MethodA
1061///     * `CallVoidMethodA`
1062///     * ...
1063/// * `NewObjectA`
1064///
1065/// # Example
1066/// ```rust
1067/// use jni_simple::{*};
1068///
1069/// unsafe fn test(env: JNIEnv, class: jclass) {
1070///     //public static void methodWith5Params(int a, int b, long c, long d, boolean e) {}
1071///     let meth = env.GetStaticMethodID(class, "methodWith5Params", "(IIJJZ)V");
1072///     if meth.is_null() {
1073///         unimplemented!("handle method not found");
1074///     }
1075///     // methodWith5Params(16, 32, 12, 13, false);
1076///     env.CallStaticVoidMethodA(class, meth, jtypes!(16i32, 64i32, 12i64, 13i64, false).as_ptr());
1077/// }
1078/// ```
1079///
1080#[macro_export]
1081macro_rules! jtypes {
1082    ( $($x:expr),* ) => {
1083        {
1084            [ $(jtype::from($x)),* ]
1085        }
1086    };
1087}
1088
1089impl Debug for jtype {
1090    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1091        //Call jtype::debug if more information is desired.
1092        f.write_str("jtype")
1093    }
1094}
1095
1096impl jtype {
1097    ///
1098    /// Helper function to "create" a jtype with a null jobject.
1099    ///
1100    /// This function is guaranteed to fully initialize all unused bits of the union to 0.
1101    ///
1102    #[inline(always)]
1103    #[must_use]
1104    pub const fn null() -> Self {
1105        #[cfg(target_pointer_width = "32")]
1106        {
1107            let mut jt = jtype { long: 0 };
1108            jt.object = null_mut();
1109            jt
1110        }
1111        #[cfg(target_pointer_width = "64")]
1112        {
1113            jtype { object: null_mut() }
1114        }
1115    }
1116
1117    /// read this jtype as jlong
1118    /// # Safety
1119    /// only safe if jtype was a jlong.
1120    #[inline(always)]
1121    #[must_use]
1122    pub const unsafe fn long(&self) -> jlong {
1123        unsafe { self.long }
1124    }
1125
1126    /// read this jtype as jint
1127    /// # Safety
1128    /// only safe if jtype was a jint.
1129    #[inline(always)]
1130    #[must_use]
1131    pub const unsafe fn int(&self) -> jint {
1132        unsafe { self.int }
1133    }
1134
1135    /// read this jtype as jshort
1136    /// # Safety
1137    /// only safe if jtype was a jshort.
1138    #[inline(always)]
1139    #[must_use]
1140    pub const unsafe fn short(&self) -> jshort {
1141        unsafe { self.short }
1142    }
1143
1144    /// read this jtype as jchar
1145    /// # Safety
1146    /// only safe if jtype was a jchar.
1147    #[inline(always)]
1148    #[must_use]
1149    pub const unsafe fn char(&self) -> jchar {
1150        unsafe { self.char }
1151    }
1152
1153    /// read this jtype as jbyte
1154    /// # Safety
1155    /// only safe if jtype was a jbyte.
1156    #[inline(always)]
1157    #[must_use]
1158    pub const unsafe fn byte(&self) -> jbyte {
1159        unsafe { self.byte }
1160    }
1161
1162    /// read this jtype as jboolean
1163    /// # Safety
1164    /// only safe if jtype was a jboolean.
1165    #[inline(always)]
1166    #[must_use]
1167    pub const unsafe fn boolean(&self) -> jboolean {
1168        unsafe { self.boolean }
1169    }
1170
1171    /// read this jtype as jboolean
1172    /// # Safety
1173    /// only safe if jtype was a jboolean.
1174    #[inline(always)]
1175    #[must_use]
1176    pub const unsafe fn bool(&self) -> bool {
1177        unsafe { self.boolean.as_bool() }
1178    }
1179
1180    /// read this jtype as jfloat
1181    /// # Safety
1182    /// only safe if jtype was a jfloat.
1183    #[inline(always)]
1184    #[must_use]
1185    pub const unsafe fn float(&self) -> jfloat {
1186        unsafe { self.float }
1187    }
1188
1189    /// read this jtype as jdouble
1190    /// # Safety
1191    /// only safe if jtype was a jdouble.
1192    #[inline(always)]
1193    #[must_use]
1194    pub const unsafe fn double(&self) -> jdouble {
1195        unsafe { self.double }
1196    }
1197
1198    /// read this jtype as jobject
1199    /// # Safety
1200    /// only safe if jtype was a jobject.
1201    #[inline(always)]
1202    #[must_use]
1203    pub const unsafe fn object(&self) -> jobject {
1204        unsafe { self.object }
1205    }
1206
1207    /// read this jtype as jclass
1208    /// # Safety
1209    /// only safe if jtype was a jclass.
1210    #[inline(always)]
1211    #[must_use]
1212    pub const unsafe fn class(&self) -> jclass {
1213        unsafe { self.class }
1214    }
1215
1216    /// read this jtype as jthrowable
1217    /// # Safety
1218    /// only safe if jtype was a jthrowable.
1219    #[inline(always)]
1220    #[must_use]
1221    pub const unsafe fn throwable(&self) -> jthrowable {
1222        unsafe { self.throwable }
1223    }
1224
1225    /// Sets the jtype to a value, this is always safe.
1226    ///
1227    /// This function is guaranteed to set all bits
1228    /// of the union that are not used by the type T to 0.
1229    #[inline(always)]
1230    pub fn set<T: Into<Self>>(&mut self, value: T) {
1231        *self = value.into();
1232    }
1233
1234    /// Returns a helper struct which implements debug and reads the actual values from the jtype.
1235    ///
1236    /// This function should be avoided in productive code.
1237    ///
1238    /// # Safety
1239    /// This is always safe for all jtype values constructed in rust regardless of the union variant.
1240    ///
1241    /// This is only safe for jtype values constructed by the jvm if they were 'jdouble, jlong or on 64-bit jvm's jobject/jthrowable/jclass'.
1242    /// All the other jtype variants may cause reading of uninitialized memory
1243    /// when the `Debug::fmt` is invoked. It depends entirely on the jvm implementation
1244    /// if this is the case or not.
1245    ///
1246    /// It is impossible to get a pointer to a jtype value constructed by the jvm without using JVMTI.
1247    /// If you only use JNI then this function should always be safe since no JNI function as of java 25
1248    /// returns a jtype. Its only used as a input parameter.
1249    ///
1250    ///
1251    /// # Example
1252    /// ```rust
1253    /// use jni_simple::*;
1254    ///
1255    /// fn some_func() {
1256    ///     let x : jlong = 4;
1257    ///     let jt = jtype::from(x);
1258    ///
1259    ///     //Safe but opaque
1260    ///     assert_eq!("jtype", format!("{jt:?}").as_str());
1261    ///
1262    ///     // Safe in this case because `jt` was initialized in rust and is jlong.
1263    ///     assert!(format!("{:?}", unsafe { jt.debug() }).as_str().contains("long=0x4"));
1264    /// }
1265    /// ```
1266    ///
1267    #[inline(always)]
1268    #[must_use]
1269    pub const unsafe fn debug(&self) -> JTypeDebug<'_> {
1270        JTypeDebug(self)
1271    }
1272}
1273
1274impl From<jlong> for jtype {
1275    fn from(value: jlong) -> Self {
1276        jtype { long: value }
1277    }
1278}
1279
1280impl From<jobject> for jtype {
1281    #[cfg(target_pointer_width = "64")]
1282    fn from(value: jobject) -> Self {
1283        jtype { object: value }
1284    }
1285
1286    #[cfg(target_pointer_width = "32")]
1287    fn from(value: jobject) -> Self {
1288        let mut jt = jtype { long: 0 };
1289        jt.object = value;
1290        jt
1291    }
1292}
1293impl From<jint> for jtype {
1294    fn from(value: jint) -> Self {
1295        let mut jt = jtype { long: 0 };
1296        jt.int = value;
1297        jt
1298    }
1299}
1300
1301impl From<jshort> for jtype {
1302    fn from(value: jshort) -> Self {
1303        let mut jt = jtype { long: 0 };
1304        jt.short = value;
1305        jt
1306    }
1307}
1308
1309impl From<jbyte> for jtype {
1310    fn from(value: jbyte) -> Self {
1311        let mut jt = jtype { long: 0 };
1312        jt.byte = value;
1313        jt
1314    }
1315}
1316
1317impl From<jchar> for jtype {
1318    fn from(value: jchar) -> Self {
1319        let mut jt = jtype { long: 0 };
1320        jt.char = value;
1321        jt
1322    }
1323}
1324
1325impl From<jfloat> for jtype {
1326    fn from(value: jfloat) -> Self {
1327        let mut jt = jtype { long: 0 };
1328        jt.float = value;
1329        jt
1330    }
1331}
1332
1333impl From<jdouble> for jtype {
1334    fn from(value: jdouble) -> Self {
1335        jtype { double: value }
1336    }
1337}
1338impl From<jboolean> for jtype {
1339    fn from(value: jboolean) -> Self {
1340        let mut jt = jtype { long: 0 };
1341        jt.boolean = value;
1342        jt
1343    }
1344}
1345
1346impl From<bool> for jtype {
1347    fn from(value: bool) -> Self {
1348        let mut jt = jtype { long: 0 };
1349        jt.boolean = jboolean::from(value);
1350        jt
1351    }
1352}
1353
1354/// Debug helper struct that ensures that the caller understands the safety of printing/debugging the jtype.
1355/// Its impossible to construct this type without unsafe code.
1356#[repr(transparent)]
1357pub struct JTypeDebug<'a>(&'a jtype);
1358
1359impl Debug for JTypeDebug<'_> {
1360    #[inline(never)]
1361    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1362        // Safety:
1363        // This is safe for any jtype's we created in rust as we always fully initalize the jtype.
1364        // This is not safe for jtype pointers passed to us from jvmti as the jvm does not need to guarantee that it points
1365        // to an initialized allocation of 8 bytes. Its perfectly valid for the jvm to give us a pointer to a jbyte and cast it to jtype.
1366        // We would then read 8 bytes here, reading beyond the bytes. We mitigate this to some degree by using read_unaligned but we still might segfault here.
1367        unsafe {
1368            let long = core::ptr::read_unaligned(core::ptr::from_ref::<jlong>(&self.0.long));
1369            let int = core::ptr::read_unaligned(core::ptr::from_ref::<jint>(&self.0.int));
1370            let short = core::ptr::read_unaligned(core::ptr::from_ref::<jshort>(&self.0.short));
1371            let byte = core::ptr::read_unaligned(core::ptr::from_ref::<jbyte>(&self.0.byte));
1372            let float = core::ptr::read_unaligned(core::ptr::from_ref::<jfloat>(&self.0.float));
1373            let double = core::ptr::read_unaligned(core::ptr::from_ref::<jdouble>(&self.0.double));
1374
1375            f.write_fmt(format_args!(
1376                "jtype union[long=0x{long:x} int=0x{int:x} short=0x{short:x} byte=0x{byte:x} float={float:e} double={double:e}]"
1377            ))
1378        }
1379    }
1380}
1381
1382#[repr(C)]
1383#[derive(Debug, Copy, Clone)]
1384pub struct JNINativeMethod {
1385    /// Name of the native method
1386    name: *const c_char,
1387    /// JNI Signature of the native method
1388    signature: *const c_char,
1389    /// raw Function pointer that should be called when the native method is called.
1390    fnPtr: *const c_void,
1391}
1392
1393/// The invocation interface pointer
1394type JNIInvPtr = SyncMutPtr<*mut *mut c_void>;
1395
1396#[repr(transparent)]
1397#[derive(Debug, Clone, Copy)]
1398pub struct JavaVM {
1399    /// The vtable of the `JavaVM` object.
1400    vtable: JNIInvPtr,
1401}
1402
1403#[repr(C)]
1404#[derive(Debug, Copy, Clone)]
1405pub struct JavaVMAttachArgs {
1406    /// Jni version
1407    version: jint,
1408    /// Thread name as a C-Linke string
1409    name: *const c_char,
1410    /// `ThreadGroup` reference. This can be null
1411    group: jobject,
1412}
1413
1414#[repr(C)]
1415#[derive(Debug, Clone, Copy)]
1416pub struct JavaVMOption {
1417    /// this field contains the string option as a C-like string.
1418    optionString: *mut c_char,
1419    /// This field is reserved and should be set to null
1420    extraInfo: *mut c_void,
1421}
1422
1423impl JavaVMOption {
1424    pub const fn new(option_string: *mut c_char, extra_info: *mut c_void) -> Self {
1425        Self {
1426            optionString: option_string,
1427            extraInfo: extra_info,
1428        }
1429    }
1430
1431    #[must_use]
1432    pub const fn optionString(&self) -> *mut c_char {
1433        self.optionString
1434    }
1435
1436    #[must_use]
1437    pub const fn extraInfo(&self) -> *mut c_void {
1438        self.extraInfo
1439    }
1440}
1441
1442#[repr(C)]
1443#[derive(Debug, Clone, Copy)]
1444pub struct JavaVMInitArgs {
1445    /// The JNI version
1446    version: i32,
1447    /// amount of options
1448    nOptions: i32,
1449    /// options
1450    options: *mut JavaVMOption,
1451    /// flat to indicate if the jvm should ignore unrecognized options instead of returning an error 1 = yes, 0 = no
1452    ignoreUnrecognized: u8,
1453}
1454
1455impl JavaVMInitArgs {
1456    pub const fn new(version: i32, n_options: i32, options: *mut JavaVMOption, ignore_unrecognized: u8) -> Self {
1457        Self {
1458            version,
1459            nOptions: n_options,
1460            options,
1461            ignoreUnrecognized: ignore_unrecognized,
1462        }
1463    }
1464
1465    #[must_use]
1466    pub const fn version(&self) -> i32 {
1467        self.version
1468    }
1469
1470    #[must_use]
1471    pub const fn nOptions(&self) -> i32 {
1472        self.nOptions
1473    }
1474
1475    #[must_use]
1476    pub const fn options(&self) -> *mut JavaVMOption {
1477        self.options
1478    }
1479
1480    #[must_use]
1481    pub const fn ignoreUnrecognized(&self) -> u8 {
1482        self.ignoreUnrecognized
1483    }
1484}
1485
1486#[derive(Debug, Copy, Clone)]
1487#[repr(C)]
1488pub struct jvmtiThreadInfo {
1489    pub name: *const c_char,
1490    pub priority: jint,
1491    pub is_daemon: jboolean,
1492    pub thread_group: jthreadGroup,
1493    pub context_class_loader: jobject,
1494}
1495
1496impl Default for jvmtiThreadInfo {
1497    fn default() -> Self {
1498        Self {
1499            name: null(),
1500            priority: 0,
1501            is_daemon: jboolean::from(false),
1502            thread_group: null_mut(),
1503            context_class_loader: null_mut(),
1504        }
1505    }
1506}
1507
1508#[derive(Debug, Copy, Clone)]
1509#[repr(C)]
1510pub struct jvmtiThreadGroupInfo {
1511    pub parent: jthreadGroup,
1512    pub name: *const c_char,
1513    pub max_priority: jint,
1514    pub is_daemon: jboolean,
1515}
1516
1517#[derive(Debug, Copy, Clone)]
1518#[repr(C)]
1519pub struct jvmtiMonitorStackDepthInfo {
1520    pub monitor: jobject,
1521    pub stack_depth: jint,
1522}
1523
1524pub type jvmtiEventReserved = extern "system" fn();
1525pub type jvmtiEventBreakpoint = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, method: jmethodID, location: jlocation);
1526
1527pub type jvmtiEventClassFileLoadHook = extern "system" fn(
1528    jvmti_env: JVMTIEnv,
1529    jni_env: JNIEnv,
1530    class_being_redefined: jclass,
1531    loader: jobject,
1532    name: *const c_char,
1533    protection_domain: jobject,
1534    class_data_len: jint,
1535    class_data: *const c_uchar,
1536    new_class_data_len: *mut jint,
1537    new_class_data: *mut *mut c_uchar,
1538);
1539
1540pub type jvmtiEventClassLoad = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, klass: jclass);
1541
1542pub type jvmtiEventClassPrepare = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, klass: jclass);
1543
1544#[derive(Debug)]
1545#[repr(C)]
1546pub struct jvmtiAddrLocationMap {
1547    pub start_address: *const c_void,
1548    pub location: jlocation,
1549}
1550pub type jvmtiEventCompiledMethodLoad = extern "system" fn(
1551    jvmti_env: JVMTIEnv,
1552    method: jmethodID,
1553    code_size: jint,
1554    code_addr: *const c_void,
1555    map_length: jint,
1556    map: *const jvmtiAddrLocationMap,
1557    compile_info: *const c_void,
1558);
1559
1560pub type jvmtiEventCompiledMethodUnload = extern "system" fn(jvmti_env: JVMTIEnv, method: jmethodID, code_addr: *const c_void);
1561
1562pub type jvmtiEventDataDumpRequest = extern "system" fn(jvmti_env: JVMTIEnv);
1563
1564pub type jvmtiEventDynamicCodeGenerated = extern "system" fn(jvmti_env: JVMTIEnv, name: *const c_char, address: *const c_void, length: jint);
1565
1566pub type jvmtiEventException = extern "system" fn(
1567    jvmti_env: JVMTIEnv,
1568    jni_env: JNIEnv,
1569    thread: jthread,
1570    method: jmethodID,
1571    location: jlocation,
1572    exception: jobject,
1573    catch_method: jmethodID,
1574    catch_location: jlocation,
1575);
1576
1577pub type jvmtiEventExceptionCatch = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, method: jmethodID, location: jlocation, exception: jobject);
1578
1579pub type jvmtiEventFieldAccess =
1580    extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, method: jmethodID, location: jlocation, field_klass: jclass, object: jobject, field: jfieldID);
1581
1582pub type jvmtiEventFieldModification = extern "system" fn(
1583    jvmti_env: JVMTIEnv,
1584    jni_env: JNIEnv,
1585    thread: jthread,
1586    method: jmethodID,
1587    location: jlocation,
1588    field_klass: jclass,
1589    object: jobject,
1590    field: jfieldID,
1591    signature_type: c_char,
1592    new_value: jvalue,
1593);
1594
1595pub type jvmtiEventFramePop = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, method: jmethodID, was_popped_by_exception: jboolean);
1596
1597pub type jvmtiEventGarbageCollectionFinish = extern "system" fn(jvmti_env: JVMTIEnv);
1598
1599pub type jvmtiEventGarbageCollectionStart = extern "system" fn(jvmti_env: JVMTIEnv);
1600
1601pub type jvmtiEventMethodEntry = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, method: jmethodID);
1602
1603pub type jvmtiEventMethodExit =
1604    extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, method: jmethodID, was_popped_by_exception: jboolean, return_value: jvalue);
1605
1606pub type jvmtiEventMonitorContendedEnter = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, object: jobject);
1607
1608pub type jvmtiEventMonitorContendedEntered = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, object: jobject);
1609
1610pub type jvmtiEventMonitorWait = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, object: jobject, timeout: jlong);
1611
1612pub type jvmtiEventMonitorWaited = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, object: jobject, timed_out: jboolean);
1613
1614pub type jvmtiEventNativeMethodBind =
1615    extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, method: jmethodID, address: *mut c_void, new_address_ptr: *mut *mut c_void);
1616
1617pub type jvmtiEventObjectFree = extern "system" fn(jvmti_env: JVMTIEnv, tag: jlong);
1618
1619pub type jvmtiEventResourceExhausted = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, flags: jint, reserved: *const c_void, description: *const c_char);
1620
1621pub type jvmtiEventSampledObjectAlloc = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, object: jobject, object_klass: jclass, size: jlong);
1622
1623pub type jvmtiEventSingleStep = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, method: jmethodID, location: jlocation);
1624
1625pub type jvmtiEventThreadEnd = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread);
1626
1627pub type jvmtiEventThreadStart = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread);
1628
1629pub type jvmtiEventVirtualThreadEnd = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, virtual_thread: jthread);
1630
1631pub type jvmtiEventVirtualThreadStart = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, virtual_thread: jthread);
1632
1633pub type jvmtiEventVMDeath = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv);
1634
1635pub type jvmtiEventVMInit = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread);
1636
1637pub type jvmtiEventVMObjectAlloc = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, object: jobject, object_klass: jclass, size: jlong);
1638
1639pub type jvmtiEventVMStart = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv);
1640
1641#[derive(Debug, Clone, Default)]
1642#[repr(C)]
1643#[allow(clippy::missing_docs_in_private_items)] //TODO later
1644pub struct jvmtiEventCallbacks {
1645    VMInit: SyncFnPtr<jvmtiEventVMInit>,
1646    VMDeath: SyncFnPtr<jvmtiEventVMDeath>,
1647    ThreadStart: SyncFnPtr<jvmtiEventThreadStart>,
1648    ThreadEnd: SyncFnPtr<jvmtiEventThreadEnd>,
1649    ClassFileLoadHook: SyncFnPtr<jvmtiEventClassFileLoadHook>,
1650    ClassLoad: SyncFnPtr<jvmtiEventClassLoad>,
1651    ClassPrepare: SyncFnPtr<jvmtiEventClassPrepare>,
1652    VMStart: SyncFnPtr<jvmtiEventVMStart>,
1653    Exception: SyncFnPtr<jvmtiEventException>,
1654    ExceptionCatch: SyncFnPtr<jvmtiEventExceptionCatch>,
1655    SingleStep: SyncFnPtr<jvmtiEventSingleStep>,
1656    FramePop: SyncFnPtr<jvmtiEventFramePop>,
1657    Breakpoint: SyncFnPtr<jvmtiEventBreakpoint>,
1658    FieldAccess: SyncFnPtr<jvmtiEventFieldAccess>,
1659    FieldModification: SyncFnPtr<jvmtiEventFieldModification>,
1660    MethodEntry: SyncFnPtr<jvmtiEventMethodEntry>,
1661    MethodExit: SyncFnPtr<jvmtiEventMethodExit>,
1662    NativeMethodBind: SyncFnPtr<jvmtiEventNativeMethodBind>,
1663    CompiledMethodLoad: SyncFnPtr<jvmtiEventCompiledMethodLoad>,
1664    CompiledMethodUnload: SyncFnPtr<jvmtiEventCompiledMethodUnload>,
1665    DynamicCodeGenerated: SyncFnPtr<jvmtiEventDynamicCodeGenerated>,
1666    DataDumpRequest: SyncFnPtr<jvmtiEventDataDumpRequest>,
1667    reserved72: SyncFnPtr<jvmtiEventReserved>,
1668    MonitorWait: SyncFnPtr<jvmtiEventMonitorWait>,
1669    MonitorWaited: SyncFnPtr<jvmtiEventMonitorWaited>,
1670    MonitorContendedEnter: SyncFnPtr<jvmtiEventMonitorContendedEnter>,
1671    MonitorContendedEntered: SyncFnPtr<jvmtiEventMonitorContendedEntered>,
1672    reserved77: SyncFnPtr<jvmtiEventReserved>,
1673    reserved78: SyncFnPtr<jvmtiEventReserved>,
1674    reserved79: SyncFnPtr<jvmtiEventReserved>,
1675    ResourceExhausted: SyncFnPtr<jvmtiEventResourceExhausted>,
1676    GarbageCollectionStart: SyncFnPtr<jvmtiEventGarbageCollectionStart>,
1677    GarbageCollectionFinish: SyncFnPtr<jvmtiEventGarbageCollectionFinish>,
1678    ObjectFree: SyncFnPtr<jvmtiEventObjectFree>,
1679    VMObjectAlloc: SyncFnPtr<jvmtiEventVMObjectAlloc>,
1680    reserved85: SyncFnPtr<jvmtiEventReserved>,
1681    SampledObjectAlloc: SyncFnPtr<jvmtiEventSampledObjectAlloc>,
1682    VirtualThreadStart: SyncFnPtr<jvmtiEventVirtualThreadStart>,
1683    VirtualThreadEnd: SyncFnPtr<jvmtiEventVirtualThreadEnd>,
1684}
1685
1686/// private helper macro to generate getters/setters for some ffi structs.
1687macro_rules! sync_ptr_setter {
1688    ($field:ident, $setter:ident, $with:ident, $typ:ty) => {
1689        /// Gets the function pointer value.
1690        ///
1691        /// # Returns
1692        /// None if the function pointer is null.
1693        #[must_use]
1694        pub const fn $field(&self) -> Option<$typ> {
1695            self.$field.inner()
1696        }
1697
1698        /// Sets the function pointer value.
1699        /// Pass None to set the function pointer value to null.
1700        pub const fn $setter(&mut self, function: Option<$typ>) {
1701            self.$field = sync_fn_ptr_opt!($typ, function);
1702        }
1703
1704        /// Sets the function pointer value.
1705        ///
1706        /// # Returns
1707        /// Self to allow for using the builder pattern.
1708        #[must_use]
1709        pub const fn $with(mut self, function: $typ) -> Self {
1710            self.$field = sync_fn_ptr!($typ, function);
1711            self
1712        }
1713    };
1714}
1715impl jvmtiEventCallbacks {
1716    /// Creates new jvmtiEventCallbacks with all callback function pointers set to null.
1717    #[must_use]
1718    pub const fn new() -> Self {
1719        Self {
1720            VMInit: SyncFnPtr::null(),
1721            VMDeath: SyncFnPtr::null(),
1722            ThreadStart: SyncFnPtr::null(),
1723            ThreadEnd: SyncFnPtr::null(),
1724            ClassFileLoadHook: SyncFnPtr::null(),
1725            ClassLoad: SyncFnPtr::null(),
1726            ClassPrepare: SyncFnPtr::null(),
1727            VMStart: SyncFnPtr::null(),
1728            Exception: SyncFnPtr::null(),
1729            ExceptionCatch: SyncFnPtr::null(),
1730            SingleStep: SyncFnPtr::null(),
1731            FramePop: SyncFnPtr::null(),
1732            Breakpoint: SyncFnPtr::null(),
1733            FieldAccess: SyncFnPtr::null(),
1734            FieldModification: SyncFnPtr::null(),
1735            MethodEntry: SyncFnPtr::null(),
1736            MethodExit: SyncFnPtr::null(),
1737            NativeMethodBind: SyncFnPtr::null(),
1738            CompiledMethodLoad: SyncFnPtr::null(),
1739            CompiledMethodUnload: SyncFnPtr::null(),
1740            DynamicCodeGenerated: SyncFnPtr::null(),
1741            DataDumpRequest: SyncFnPtr::null(),
1742            reserved72: SyncFnPtr::null(),
1743            MonitorWait: SyncFnPtr::null(),
1744            MonitorWaited: SyncFnPtr::null(),
1745            MonitorContendedEnter: SyncFnPtr::null(),
1746            MonitorContendedEntered: SyncFnPtr::null(),
1747            reserved77: SyncFnPtr::null(),
1748            reserved78: SyncFnPtr::null(),
1749            reserved79: SyncFnPtr::null(),
1750            ResourceExhausted: SyncFnPtr::null(),
1751            GarbageCollectionStart: SyncFnPtr::null(),
1752            GarbageCollectionFinish: SyncFnPtr::null(),
1753            ObjectFree: SyncFnPtr::null(),
1754            VMObjectAlloc: SyncFnPtr::null(),
1755            reserved85: SyncFnPtr::null(),
1756            SampledObjectAlloc: SyncFnPtr::null(),
1757            VirtualThreadStart: SyncFnPtr::null(),
1758            VirtualThreadEnd: SyncFnPtr::null(),
1759        }
1760    }
1761
1762    sync_ptr_setter!(VMInit, set_VMInit, with_VMInit, jvmtiEventVMInit);
1763    sync_ptr_setter!(VMDeath, set_VMDeath, with_VMDeath, jvmtiEventVMDeath);
1764    sync_ptr_setter!(ThreadStart, set_ThreadStart, with_ThreadStart, jvmtiEventThreadStart);
1765    sync_ptr_setter!(ThreadEnd, set_ThreadEnd, with_ThreadEnd, jvmtiEventThreadEnd);
1766    sync_ptr_setter!(ClassFileLoadHook, set_ClassFileLoadHook, with_ClassFileLoadHook, jvmtiEventClassFileLoadHook);
1767    sync_ptr_setter!(ClassLoad, set_ClassLoad, with_ClassLoad, jvmtiEventClassLoad);
1768    sync_ptr_setter!(ClassPrepare, set_ClassPrepare, with_ClassPrepare, jvmtiEventClassPrepare);
1769    sync_ptr_setter!(VMStart, set_VMStart, with_VMStart, jvmtiEventVMStart);
1770    sync_ptr_setter!(Exception, set_Exception, with_Exception, jvmtiEventException);
1771    sync_ptr_setter!(ExceptionCatch, set_ExceptionCatch, with_ExceptionCatch, jvmtiEventExceptionCatch);
1772    sync_ptr_setter!(SingleStep, set_SingleStep, with_SingleStep, jvmtiEventSingleStep);
1773    sync_ptr_setter!(FramePop, set_FramePop, with_FramePop, jvmtiEventFramePop);
1774    sync_ptr_setter!(Breakpoint, set_Breakpoint, with_Breakpoint, jvmtiEventBreakpoint);
1775    sync_ptr_setter!(FieldAccess, set_FieldAccess, with_FieldAccess, jvmtiEventFieldAccess);
1776    sync_ptr_setter!(FieldModification, set_FieldModification, with_FieldModification, jvmtiEventFieldModification);
1777    sync_ptr_setter!(MethodEntry, set_MethodEntry, with_MethodEntry, jvmtiEventMethodEntry);
1778    sync_ptr_setter!(MethodExit, set_MethodExit, with_MethodExit, jvmtiEventMethodExit);
1779    sync_ptr_setter!(NativeMethodBind, set_NativeMethodBind, with_NativeMethodBind, jvmtiEventNativeMethodBind);
1780    sync_ptr_setter!(CompiledMethodLoad, set_CompiledMethodLoad, with_CompiledMethodLoad, jvmtiEventCompiledMethodLoad);
1781    sync_ptr_setter!(CompiledMethodUnload, set_CompiledMethodUnload, with_CompiledMethodUnload, jvmtiEventCompiledMethodUnload);
1782    sync_ptr_setter!(DynamicCodeGenerated, set_DynamicCodeGenerated, with_DynamicCodeGenerated, jvmtiEventDynamicCodeGenerated);
1783    sync_ptr_setter!(DataDumpRequest, set_DataDumpRequest, with_DataDumpRequest, jvmtiEventDataDumpRequest);
1784    sync_ptr_setter!(reserved72, set_reserved72, with_reserved72, jvmtiEventReserved);
1785    sync_ptr_setter!(MonitorWait, set_MonitorWait, with_MonitorWait, jvmtiEventMonitorWait);
1786    sync_ptr_setter!(MonitorWaited, set_MonitorWaited, with_MonitorWaited, jvmtiEventMonitorWaited);
1787    sync_ptr_setter!(
1788        MonitorContendedEnter,
1789        set_MonitorContendedEnter,
1790        with_MonitorContendedEnter,
1791        jvmtiEventMonitorContendedEnter
1792    );
1793    sync_ptr_setter!(
1794        MonitorContendedEntered,
1795        set_MonitorContendedEntered,
1796        with_MonitorContendedEntered,
1797        jvmtiEventMonitorContendedEntered
1798    );
1799    sync_ptr_setter!(reserved77, set_reserved77, with_reserved77, jvmtiEventReserved);
1800    sync_ptr_setter!(reserved78, set_reserved78, with_reserved78, jvmtiEventReserved);
1801    sync_ptr_setter!(reserved79, set_reserved79, with_reserved79, jvmtiEventReserved);
1802    sync_ptr_setter!(ResourceExhausted, set_ResourceExhausted, with_ResourceExhausted, jvmtiEventResourceExhausted);
1803    sync_ptr_setter!(
1804        GarbageCollectionStart,
1805        set_GarbageCollectionStart,
1806        with_GarbageCollectionStart,
1807        jvmtiEventGarbageCollectionStart
1808    );
1809    sync_ptr_setter!(
1810        GarbageCollectionFinish,
1811        set_GarbageCollectionFinish,
1812        with_GarbageCollectionFinish,
1813        jvmtiEventGarbageCollectionFinish
1814    );
1815    sync_ptr_setter!(ObjectFree, set_ObjectFree, with_ObjectFree, jvmtiEventObjectFree);
1816    sync_ptr_setter!(VMObjectAlloc, set_VMObjectAlloc, with_VMObjectAlloc, jvmtiEventVMObjectAlloc);
1817    sync_ptr_setter!(reserved85, set_reserved85, with_reserved85, jvmtiEventReserved);
1818    sync_ptr_setter!(SampledObjectAlloc, set_SampledObjectAlloc, with_SampledObjectAlloc, jvmtiEventSampledObjectAlloc);
1819    sync_ptr_setter!(VirtualThreadStart, set_VirtualThreadStart, with_VirtualThreadStart, jvmtiEventVirtualThreadStart);
1820    sync_ptr_setter!(VirtualThreadEnd, set_VirtualThreadEnd, with_VirtualThreadEnd, jvmtiEventVirtualThreadEnd);
1821}
1822
1823#[repr(C)]
1824#[derive(Debug, Copy, Clone, Default)]
1825pub enum jvmtiEventMode {
1826    #[default]
1827    JVMTI_ENABLE = 1,
1828    JVMTI_DISABLE = 0,
1829}
1830
1831#[repr(C)]
1832#[derive(Debug, Copy, Clone, Default)]
1833pub enum jvmtiEvent {
1834    #[default]
1835    JVMTI_EVENT_VM_DEATH = 51,
1836    JVMTI_EVENT_THREAD_START = 52,
1837    JVMTI_EVENT_THREAD_END = 53,
1838    JVMTI_EVENT_CLASS_FILE_LOAD_HOOK = 54,
1839    JVMTI_EVENT_CLASS_LOAD = 55,
1840    JVMTI_EVENT_CLASS_PREPARE = 56,
1841    JVMTI_EVENT_VM_START = 57,
1842    JVMTI_EVENT_EXCEPTION = 58,
1843    JVMTI_EVENT_EXCEPTION_CATCH = 59,
1844    JVMTI_EVENT_SINGLE_STEP = 60,
1845    JVMTI_EVENT_FRAME_POP = 61,
1846    JVMTI_EVENT_BREAKPOINT = 62,
1847    JVMTI_EVENT_FIELD_ACCESS = 63,
1848    JVMTI_EVENT_FIELD_MODIFICATION = 64,
1849    JVMTI_EVENT_METHOD_ENTRY = 65,
1850    JVMTI_EVENT_METHOD_EXIT = 66,
1851    JVMTI_EVENT_NATIVE_METHOD_BIND = 67,
1852    JVMTI_EVENT_COMPILED_METHOD_LOAD = 68,
1853    JVMTI_EVENT_COMPILED_METHOD_UNLOAD = 69,
1854    JVMTI_EVENT_DYNAMIC_CODE_GENERATED = 70,
1855    JVMTI_EVENT_DATA_DUMP_REQUEST = 71,
1856    JVMTI_EVENT_MONITOR_WAIT = 73,
1857    JVMTI_EVENT_MONITOR_WAITED = 74,
1858    JVMTI_EVENT_MONITOR_CONTENDED_ENTER = 75,
1859    JVMTI_EVENT_MONITOR_CONTENDED_ENTERED = 76,
1860    JVMTI_EVENT_RESOURCE_EXHAUSTED = 80,
1861    JVMTI_EVENT_GARBAGE_COLLECTION_START = 81,
1862    JVMTI_EVENT_GARBAGE_COLLECTION_FINISH = 82,
1863    JVMTI_EVENT_OBJECT_FREE = 83,
1864    JVMTI_EVENT_VM_OBJECT_ALLOC = 84,
1865    JVMTI_EVENT_SAMPLED_OBJECT_ALLOC = 86,
1866    JVMTI_EVENT_VIRTUAL_THREAD_START = 87,
1867    JVMTI_EVENT_VIRTUAL_THREAD_END = 88,
1868}
1869
1870pub type jvmtiExtensionFunction = Option<extern "C" fn(jvmti_env: JVMTIEnv, ...)>;
1871
1872pub type jvmtiExtensionEvent = Option<extern "C" fn(jvmti_env: JVMTIEnv, ...)>;
1873
1874//We cant enum this as the jvm returning an unknown value to us would be ub.
1875pub type jvmtiParamKind = c_int;
1876
1877/// Ingoing argument - foo.
1878pub const JVMTI_KIND_IN: c_int = 91;
1879
1880/// Ingoing pointer argument - const foo*.
1881pub const JVMTI_KIND_IN_PTR: c_int = 92;
1882
1883/// Ingoing array argument - const foo*.
1884pub const JVMTI_KIND_IN_BUF: c_int = 93;
1885
1886/// Outgoing allocated array argument - foo**. Free with Deallocate.
1887pub const JVMTI_KIND_ALLOC_BUF: c_int = 94;
1888
1889/// Outgoing allocated array of allocated arrays argument - foo***. Free with Deallocate.
1890pub const JVMTI_KIND_ALLOC_ALLOC_BUF: c_int = 95;
1891
1892/// Outgoing argument - foo*.
1893pub const JVMTI_KIND_OUT: c_int = 96;
1894
1895/// Outgoing array argument (pre-allocated by agent) - foo*. Do not Deallocate.
1896pub const JVMTI_KIND_OUT_BUF: c_int = 97;
1897
1898//We cant enum this as the jvm returning an unknown value to us would be ub.
1899pub type jvmtiParamTypes = c_int;
1900
1901/// Java programming language primitive type - byte. JNI type jbyte.
1902pub const JVMTI_TYPE_JBYTE: c_int = 101;
1903
1904/// Java programming language primitive type - char. JNI type jchar.
1905pub const JVMTI_TYPE_JCHAR: c_int = 102;
1906
1907/// Java programming language primitive type - short. JNI type jshort.
1908pub const JVMTI_TYPE_JSHORT: c_int = 103;
1909
1910/// Java programming language primitive type - int. JNI type jint.
1911pub const JVMTI_TYPE_JINT: c_int = 104;
1912
1913/// Java programming language primitive type - long. JNI type jlong.
1914pub const JVMTI_TYPE_JLONG: c_int = 105;
1915
1916/// Java programming language primitive type - float. JNI type jfloat.
1917pub const JVMTI_TYPE_JFLOAT: c_int = 106;
1918
1919/// Java programming language primitive type - double. JNI type jdouble.
1920pub const JVMTI_TYPE_JDOUBLE: c_int = 107;
1921
1922/// Java programming language primitive type - boolean. JNI type jboolean.
1923pub const JVMTI_TYPE_JBOOLEAN: c_int = 108;
1924
1925/// Java programming language object type - java.lang.Object. JNI type jobject. Returned values are JNI local references and must be managed.
1926pub const JVMTI_TYPE_JOBJECT: c_int = 109;
1927
1928/// Java programming language object type - java.lang.Thread. JVM TI type jthread. Returned values are JNI local references and must be managed.
1929pub const JVMTI_TYPE_JTHREAD: c_int = 110;
1930
1931/// Java programming language object type - java.lang.Class. JNI type jclass. Returned values are JNI local references and must be managed.
1932pub const JVMTI_TYPE_JCLASS: c_int = 111;
1933
1934/// Union of all Java programming language primitive and object types - JNI type jvalue. Returned values which represent object types are JNI local references and must be managed.
1935pub const JVMTI_TYPE_JVALUE: c_int = 112;
1936
1937/// Java programming language field identifier - JNI type jfieldID.
1938pub const JVMTI_TYPE_JFIELDID: c_int = 113;
1939
1940/// Java programming language method identifier - JNI type jmethodID.
1941pub const JVMTI_TYPE_JMETHODID: c_int = 114;
1942
1943/// C programming language type - char.
1944pub const JVMTI_TYPE_CCHAR: c_int = 115;
1945
1946/// C programming language type - void.
1947pub const JVMTI_TYPE_CVOID: c_int = 116;
1948
1949/// JNI environment - `JNIEnv`. Should be used with the correct jvmtiParamKind to make it a pointer type.
1950pub const JVMTI_TYPE_JNIENV: c_int = 117;
1951
1952pub type jvmtiTimerKind = c_int;
1953
1954pub const JVMTI_TIMER_USER_CPU: jvmtiTimerKind = 30;
1955
1956pub const JVMTI_TIMER_TOTAL_CPU: jvmtiTimerKind = 31;
1957
1958pub const JVMTI_TIMER_ELAPSED: jvmtiTimerKind = 32;
1959#[repr(C)]
1960#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
1961pub struct jvmtiTimerInfo {
1962    pub max_value: jlong,
1963    pub may_skip_forward: jboolean,
1964    pub may_skip_backward: jboolean,
1965    pub kind: jvmtiTimerKind,
1966    pub reserved1: jlong,
1967    pub reserved2: jlong,
1968}
1969
1970#[repr(C)]
1971#[derive(Debug, Copy, Clone)]
1972pub struct jvmtiParamInfo {
1973    pub name: *mut c_char,
1974    pub kind: jvmtiParamKind,
1975    pub base_type: jvmtiParamTypes,
1976    pub null_ok: jboolean,
1977}
1978#[repr(C)]
1979#[derive(Debug, Copy, Clone)]
1980pub struct jvmtiExtensionFunctionInfo {
1981    pub func: jvmtiExtensionFunction,
1982    pub id: *mut c_char,
1983    pub short_description: *mut c_char,
1984    pub param_count: jint,
1985    pub params: *mut jvmtiParamInfo,
1986    pub error_count: jint,
1987    pub errors: *mut jvmtiError,
1988}
1989
1990impl Default for jvmtiExtensionFunctionInfo {
1991    fn default() -> Self {
1992        Self {
1993            func: None,
1994            id: null_mut(),
1995            short_description: null_mut(),
1996            param_count: 0,
1997            params: null_mut(),
1998            error_count: 0,
1999            errors: null_mut(),
2000        }
2001    }
2002}
2003
2004#[repr(C)]
2005#[derive(Debug, Copy, Clone)]
2006pub struct jvmtiExtensionEventInfo {
2007    pub extension_event_index: jint,
2008    pub id: *mut c_char,
2009    pub short_description: *mut c_char,
2010    pub param_count: jint,
2011    pub params: *mut jvmtiParamInfo,
2012}
2013
2014impl Default for jvmtiExtensionEventInfo {
2015    fn default() -> Self {
2016        Self {
2017            extension_event_index: 0,
2018            id: null_mut(),
2019            short_description: null_mut(),
2020            param_count: 0,
2021            params: null_mut(),
2022        }
2023    }
2024}
2025
2026pub type jvmtiPhase = c_int;
2027pub const JVMTI_PHASE_ONLOAD: jvmtiPhase = 1;
2028pub const JVMTI_PHASE_PRIMORDIAL: jvmtiPhase = 2;
2029pub const JVMTI_PHASE_START: jvmtiPhase = 6;
2030pub const JVMTI_PHASE_LIVE: jvmtiPhase = 4;
2031pub const JVMTI_PHASE_DEAD: jvmtiPhase = 8;
2032
2033#[repr(C)]
2034#[derive(Debug, Copy, Clone)]
2035pub enum jvmtiVerboseFlag {
2036    JVMTI_VERBOSE_OTHER = 0,
2037    JVMTI_VERBOSE_GC = 1,
2038    JVMTI_VERBOSE_CLASS = 2,
2039    JVMTI_VERBOSE_JNI = 4,
2040}
2041
2042pub type jvmtiJlocationFormat = c_int;
2043
2044/// jlocation values represent virtual machine bytecode indices--that is, offsets into the virtual machine code for a method.
2045pub const JVMTI_JLOCATION_JVMBCI: jvmtiJlocationFormat = 1;
2046
2047/// jlocation values represent native machine program counter values.
2048pub const JVMTI_JLOCATION_MACHINEPC: jvmtiJlocationFormat = 2;
2049
2050/// jlocation values have some other representation.
2051pub const JVMTI_JLOCATION_OTHER: jvmtiJlocationFormat = 0;
2052
2053#[repr(transparent)]
2054#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
2055pub struct jvmtiCapabilities(u128);
2056
2057/// Dumped from c program `bitfield_gen` in this repo.
2058#[expect(clippy::missing_docs_in_private_items)]
2059#[cfg(target_endian = "little")]
2060mod jvmti_cap_offsets {
2061    pub const OFFSET_CAN_TAG_OBJECTS: usize = 0x0001;
2062    pub const OFFSET_CAN_GENERATE_FIELD_MODIFICATION_EVENTS: usize = 0x0002;
2063    pub const OFFSET_CAN_GENERATE_FIELD_ACCESS_EVENTS: usize = 0x0004;
2064    pub const OFFSET_CAN_GET_BYTECODES: usize = 0x0008;
2065    pub const OFFSET_CAN_GET_SYNTHETIC_ATTRIBUTE: usize = 0x0010;
2066    pub const OFFSET_CAN_GET_OWNED_MONITOR_INFO: usize = 0x0020;
2067    pub const OFFSET_CAN_GET_CURRENT_CONTENDED_MONITOR: usize = 0x0040;
2068    pub const OFFSET_CAN_GET_MONITOR_INFO: usize = 0x0080;
2069    pub const OFFSET_CAN_POP_FRAME: usize = 0x0101;
2070    pub const OFFSET_CAN_REDEFINE_CLASSES: usize = 0x0102;
2071    pub const OFFSET_CAN_SIGNAL_THREAD: usize = 0x0104;
2072    pub const OFFSET_CAN_GET_SOURCE_FILE_NAME: usize = 0x0108;
2073    pub const OFFSET_CAN_GET_LINE_NUMBERS: usize = 0x0110;
2074    pub const OFFSET_CAN_GET_SOURCE_DEBUG_EXTENSION: usize = 0x0120;
2075    pub const OFFSET_CAN_ACCESS_LOCAL_VARIABLES: usize = 0x0140;
2076    pub const OFFSET_CAN_MAINTAIN_ORIGINAL_METHOD_ORDER: usize = 0x0180;
2077    pub const OFFSET_CAN_GENERATE_SINGLE_STEP_EVENTS: usize = 0x0201;
2078    pub const OFFSET_CAN_GENERATE_EXCEPTION_EVENTS: usize = 0x0202;
2079    pub const OFFSET_CAN_GENERATE_FRAME_POP_EVENTS: usize = 0x0204;
2080    pub const OFFSET_CAN_GENERATE_BREAKPOINT_EVENTS: usize = 0x0208;
2081    pub const OFFSET_CAN_SUSPEND: usize = 0x0210;
2082    pub const OFFSET_CAN_REDEFINE_ANY_CLASS: usize = 0x0220;
2083    pub const OFFSET_CAN_GET_CURRENT_THREAD_CPU_TIME: usize = 0x0240;
2084    pub const OFFSET_CAN_GET_THREAD_CPU_TIME: usize = 0x0280;
2085    pub const OFFSET_CAN_GENERATE_METHOD_ENTRY_EVENTS: usize = 0x0301;
2086    pub const OFFSET_CAN_GENERATE_METHOD_EXIT_EVENTS: usize = 0x0302;
2087    pub const OFFSET_CAN_GENERATE_ALL_CLASS_HOOK_EVENTS: usize = 0x0304;
2088    pub const OFFSET_CAN_GENERATE_COMPILED_METHOD_LOAD_EVENTS: usize = 0x0308;
2089    pub const OFFSET_CAN_GENERATE_MONITOR_EVENTS: usize = 0x0310;
2090    pub const OFFSET_CAN_GENERATE_VM_OBJECT_ALLOC_EVENTS: usize = 0x0320;
2091    pub const OFFSET_CAN_GENERATE_NATIVE_METHOD_BIND_EVENTS: usize = 0x0340;
2092    pub const OFFSET_CAN_GENERATE_GARBAGE_COLLECTION_EVENTS: usize = 0x0380;
2093    pub const OFFSET_CAN_GENERATE_OBJECT_FREE_EVENTS: usize = 0x0401;
2094    pub const OFFSET_CAN_FORCE_EARLY_RETURN: usize = 0x0402;
2095    pub const OFFSET_CAN_GET_OWNED_MONITOR_STACK_DEPTH_INFO: usize = 0x0404;
2096    pub const OFFSET_CAN_GET_CONSTANT_POOL: usize = 0x0408;
2097    pub const OFFSET_CAN_SET_NATIVE_METHOD_PREFIX: usize = 0x0410;
2098    pub const OFFSET_CAN_RETRANSFORM_CLASSES: usize = 0x0420;
2099    pub const OFFSET_CAN_RETRANSFORM_ANY_CLASS: usize = 0x0440;
2100    pub const OFFSET_CAN_GENERATE_RESOURCE_EXHAUSTION_HEAP_EVENTS: usize = 0x0480;
2101    pub const OFFSET_CAN_GENERATE_RESOURCE_EXHAUSTION_THREAD_EVENETS: usize = 0x0501;
2102    pub const OFFSET_CAN_GENERATE_EARLY_VMSTART: usize = 0x0502;
2103    pub const OFFSET_CAN_GENERATE_EARLY_CLASS_HOOK_EVENTS: usize = 0x0504;
2104    pub const OFFSET_CAN_GENERATE_SAMPLED_OBJECT_ALLOC_EVENTS: usize = 0x0508;
2105    pub const OFFSET_CAN_SUPPORT_VIRTUAL_THREADS: usize = 0x0510;
2106}
2107
2108#[expect(clippy::missing_docs_in_private_items)]
2109#[cfg(target_endian = "big")]
2110mod jvmti_cap_offsets {
2111    pub const OFFSET_CAN_TAG_OBJECTS: usize = 0x0080;
2112    pub const OFFSET_CAN_GENERATE_FIELD_MODIFICATION_EVENTS: usize = 0x0040;
2113    pub const OFFSET_CAN_GENERATE_FIELD_ACCESS_EVENTS: usize = 0x0020;
2114    pub const OFFSET_CAN_GET_BYTECODES: usize = 0x0010;
2115    pub const OFFSET_CAN_GET_SYNTHETIC_ATTRIBUTE: usize = 0x0008;
2116    pub const OFFSET_CAN_GET_OWNED_MONITOR_INFO: usize = 0x0004;
2117    pub const OFFSET_CAN_GET_CURRENT_CONTENDED_MONITOR: usize = 0x0002;
2118    pub const OFFSET_CAN_GET_MONITOR_INFO: usize = 0x0001;
2119    pub const OFFSET_CAN_POP_FRAME: usize = 0x0180;
2120    pub const OFFSET_CAN_REDEFINE_CLASSES: usize = 0x0140;
2121    pub const OFFSET_CAN_SIGNAL_THREAD: usize = 0x0120;
2122    pub const OFFSET_CAN_GET_SOURCE_FILE_NAME: usize = 0x0110;
2123    pub const OFFSET_CAN_GET_LINE_NUMBERS: usize = 0x0108;
2124    pub const OFFSET_CAN_GET_SOURCE_DEBUG_EXTENSION: usize = 0x0104;
2125    pub const OFFSET_CAN_ACCESS_LOCAL_VARIABLES: usize = 0x0102;
2126    pub const OFFSET_CAN_MAINTAIN_ORIGINAL_METHOD_ORDER: usize = 0x0101;
2127    pub const OFFSET_CAN_GENERATE_SINGLE_STEP_EVENTS: usize = 0x0280;
2128    pub const OFFSET_CAN_GENERATE_EXCEPTION_EVENTS: usize = 0x0240;
2129    pub const OFFSET_CAN_GENERATE_FRAME_POP_EVENTS: usize = 0x0220;
2130    pub const OFFSET_CAN_GENERATE_BREAKPOINT_EVENTS: usize = 0x0210;
2131    pub const OFFSET_CAN_SUSPEND: usize = 0x0208;
2132    pub const OFFSET_CAN_REDEFINE_ANY_CLASS: usize = 0x0204;
2133    pub const OFFSET_CAN_GET_CURRENT_THREAD_CPU_TIME: usize = 0x0202;
2134    pub const OFFSET_CAN_GET_THREAD_CPU_TIME: usize = 0x0201;
2135    pub const OFFSET_CAN_GENERATE_METHOD_ENTRY_EVENTS: usize = 0x0380;
2136    pub const OFFSET_CAN_GENERATE_METHOD_EXIT_EVENTS: usize = 0x0340;
2137    pub const OFFSET_CAN_GENERATE_ALL_CLASS_HOOK_EVENTS: usize = 0x0320;
2138    pub const OFFSET_CAN_GENERATE_COMPILED_METHOD_LOAD_EVENTS: usize = 0x0310;
2139    pub const OFFSET_CAN_GENERATE_MONITOR_EVENTS: usize = 0x0308;
2140    pub const OFFSET_CAN_GENERATE_VM_OBJECT_ALLOC_EVENTS: usize = 0x0304;
2141    pub const OFFSET_CAN_GENERATE_NATIVE_METHOD_BIND_EVENTS: usize = 0x0302;
2142    pub const OFFSET_CAN_GENERATE_GARBAGE_COLLECTION_EVENTS: usize = 0x0301;
2143    pub const OFFSET_CAN_GENERATE_OBJECT_FREE_EVENTS: usize = 0x0480;
2144    pub const OFFSET_CAN_FORCE_EARLY_RETURN: usize = 0x0440;
2145    pub const OFFSET_CAN_GET_OWNED_MONITOR_STACK_DEPTH_INFO: usize = 0x0420;
2146    pub const OFFSET_CAN_GET_CONSTANT_POOL: usize = 0x0410;
2147    pub const OFFSET_CAN_SET_NATIVE_METHOD_PREFIX: usize = 0x0408;
2148    pub const OFFSET_CAN_RETRANSFORM_CLASSES: usize = 0x0404;
2149    pub const OFFSET_CAN_RETRANSFORM_ANY_CLASS: usize = 0x0402;
2150    pub const OFFSET_CAN_GENERATE_RESOURCE_EXHAUSTION_HEAP_EVENTS: usize = 0x0401;
2151    pub const OFFSET_CAN_GENERATE_RESOURCE_EXHAUSTION_THREAD_EVENETS: usize = 0x0580;
2152    pub const OFFSET_CAN_GENERATE_EARLY_VMSTART: usize = 0x0540;
2153    pub const OFFSET_CAN_GENERATE_EARLY_CLASS_HOOK_EVENTS: usize = 0x0520;
2154    pub const OFFSET_CAN_GENERATE_SAMPLED_OBJECT_ALLOC_EVENTS: usize = 0x0510;
2155    pub const OFFSET_CAN_SUPPORT_VIRTUAL_THREADS: usize = 0x0508;
2156}
2157
2158#[expect(clippy::wildcard_imports)]
2159use crate::jvmti_cap_offsets::*;
2160
2161/// This macro generates an setter and getter for a field that is stored in the C jvmtiCapabilities bitfield struct
2162/// In rust we store the bitfield in a u128.
2163macro_rules! jvmtiCapField {
2164    ($getter:ident, $setter:ident, $constant:expr) => {
2165        #[must_use]
2166        pub const fn $getter(&self) -> bool {
2167            self.get($constant)
2168        }
2169
2170        pub const fn $setter(&mut self, value: bool) {
2171            self.set($constant, value);
2172        }
2173    };
2174}
2175
2176impl jvmtiCapabilities {
2177    /// Copies the raw data into the given slice.
2178    /// # Panics
2179    /// if the target slice does not have the same length as `size()` returns
2180    #[inline(always)]
2181    pub const fn copy_to_slice(&self, target: &mut [u8]) {
2182        target.copy_from_slice(self.0.to_ne_bytes().as_slice());
2183    }
2184
2185    /// Copies the raw data from the given slice into this structure.
2186    /// # Panics
2187    /// if the target slice does not have the same length as `size()` returns
2188    #[inline(always)]
2189    pub const fn copy_from_slice(&mut self, data: &[u8]) {
2190        let mut raw = [0u8; 16];
2191        raw.copy_from_slice(data);
2192        self.0 = u128::from_ne_bytes(raw);
2193    }
2194
2195    ///Returns the amount of bytes needed to access the raw data in this struct.
2196    #[inline(always)]
2197    #[must_use]
2198    pub const fn size() -> usize {
2199        16
2200    }
2201
2202    /// C compatible bitfield setter, translates the offset constant into a slice index and bitmask.
2203    #[expect(clippy::cast_possible_truncation)]
2204    const fn set(&mut self, offset: usize, value: bool) {
2205        let idx = offset >> 8;
2206        let mask = (offset & 0xFF) as u8;
2207        let mut raw = self.0.to_ne_bytes();
2208        if value {
2209            raw[idx] |= mask;
2210        } else {
2211            raw[idx] &= !mask;
2212        }
2213        self.0 = u128::from_ne_bytes(raw);
2214    }
2215
2216    /// C compatible bitfield getter, translates the offset constant into a slice index and bitmask.
2217    #[must_use]
2218    #[expect(clippy::cast_possible_truncation)]
2219    const fn get(&self, offset: usize) -> bool {
2220        let idx = offset >> 8;
2221        let mask = (offset & 0xFF) as u8;
2222        let raw = self.0.to_ne_bytes();
2223        raw[idx] & mask != 0
2224    }
2225
2226    jvmtiCapField!(can_tag_objects, set_can_tag_objects, OFFSET_CAN_TAG_OBJECTS);
2227    jvmtiCapField!(
2228        can_generate_field_modification_events,
2229        set_can_generate_field_modification_events,
2230        OFFSET_CAN_GENERATE_FIELD_MODIFICATION_EVENTS
2231    );
2232    jvmtiCapField!(
2233        can_generate_field_access_events,
2234        set_can_generate_field_access_events,
2235        OFFSET_CAN_GENERATE_FIELD_ACCESS_EVENTS
2236    );
2237    jvmtiCapField!(can_get_bytecodes, set_can_get_bytecodes, OFFSET_CAN_GET_BYTECODES);
2238    jvmtiCapField!(can_get_synthetic_attribute, set_can_get_synthetic_attribute, OFFSET_CAN_GET_SYNTHETIC_ATTRIBUTE);
2239    jvmtiCapField!(can_get_owned_monitor_info, set_can_get_owned_monitor_info, OFFSET_CAN_GET_OWNED_MONITOR_INFO);
2240    jvmtiCapField!(
2241        can_get_current_contended_monitor,
2242        set_can_get_current_contended_monitor,
2243        OFFSET_CAN_GET_CURRENT_CONTENDED_MONITOR
2244    );
2245    jvmtiCapField!(can_get_monitor_info, set_can_get_monitor_info, OFFSET_CAN_GET_MONITOR_INFO);
2246    jvmtiCapField!(can_pop_frame, set_can_pop_frame, OFFSET_CAN_POP_FRAME);
2247    jvmtiCapField!(can_redefine_classes, set_can_redefine_classes, OFFSET_CAN_REDEFINE_CLASSES);
2248    jvmtiCapField!(can_signal_thread, set_can_signal_thread, OFFSET_CAN_SIGNAL_THREAD);
2249    jvmtiCapField!(can_get_source_file_name, set_can_get_source_file_name, OFFSET_CAN_GET_SOURCE_FILE_NAME);
2250    jvmtiCapField!(can_get_line_numbers, set_can_get_line_numbers, OFFSET_CAN_GET_LINE_NUMBERS);
2251    jvmtiCapField!(can_get_source_debug_extension, set_can_get_source_debug_extension, OFFSET_CAN_GET_SOURCE_DEBUG_EXTENSION);
2252    jvmtiCapField!(can_access_local_variables, set_can_access_local_variables, OFFSET_CAN_ACCESS_LOCAL_VARIABLES);
2253    jvmtiCapField!(
2254        can_maintain_original_method_order,
2255        set_can_maintain_original_method_order,
2256        OFFSET_CAN_MAINTAIN_ORIGINAL_METHOD_ORDER
2257    );
2258    jvmtiCapField!(can_generate_single_step_events, set_generate_single_step_events, OFFSET_CAN_GENERATE_SINGLE_STEP_EVENTS);
2259    jvmtiCapField!(can_generate_exception_events, set_can_generate_exception_events, OFFSET_CAN_GENERATE_EXCEPTION_EVENTS);
2260    jvmtiCapField!(can_generate_frame_pop_events, set_can_generate_frame_pop_events, OFFSET_CAN_GENERATE_FRAME_POP_EVENTS);
2261    jvmtiCapField!(can_generate_breakpoint_events, set_can_generate_breakpoint_events, OFFSET_CAN_GENERATE_BREAKPOINT_EVENTS);
2262    jvmtiCapField!(can_suspend, set_can_suspend, OFFSET_CAN_SUSPEND);
2263    jvmtiCapField!(can_redefine_any_class, set_can_redefine_any_class, OFFSET_CAN_REDEFINE_ANY_CLASS);
2264    jvmtiCapField!(can_get_current_thread_cpu_time, set_can_get_current_thread_cpu_time, OFFSET_CAN_GET_CURRENT_THREAD_CPU_TIME);
2265    jvmtiCapField!(can_get_thread_cpu_time, set_can_get_thread_cpu_time, OFFSET_CAN_GET_THREAD_CPU_TIME);
2266    jvmtiCapField!(
2267        can_generate_method_entry_events,
2268        set_can_generate_method_entry_events,
2269        OFFSET_CAN_GENERATE_METHOD_ENTRY_EVENTS
2270    );
2271    jvmtiCapField!(can_generate_method_exit_events, set_can_generate_method_exit_events, OFFSET_CAN_GENERATE_METHOD_EXIT_EVENTS);
2272    jvmtiCapField!(
2273        can_generate_all_class_hook_events,
2274        set_can_generate_all_class_hook_events,
2275        OFFSET_CAN_GENERATE_ALL_CLASS_HOOK_EVENTS
2276    );
2277    jvmtiCapField!(
2278        can_generate_compiled_method_load_events,
2279        set_can_generate_compiled_method_load_events,
2280        OFFSET_CAN_GENERATE_COMPILED_METHOD_LOAD_EVENTS
2281    );
2282    jvmtiCapField!(can_generate_monitor_events, set_can_generate_monitor_events, OFFSET_CAN_GENERATE_MONITOR_EVENTS);
2283    jvmtiCapField!(
2284        can_generate_vm_object_alloc_events,
2285        set_can_generate_vm_object_alloc_events,
2286        OFFSET_CAN_GENERATE_VM_OBJECT_ALLOC_EVENTS
2287    );
2288    jvmtiCapField!(
2289        can_generate_native_method_bind_events,
2290        set_can_generate_native_method_bind_events,
2291        OFFSET_CAN_GENERATE_NATIVE_METHOD_BIND_EVENTS
2292    );
2293    jvmtiCapField!(
2294        can_generate_garbage_collection_events,
2295        set_can_generate_garbage_collection_events,
2296        OFFSET_CAN_GENERATE_GARBAGE_COLLECTION_EVENTS
2297    );
2298    jvmtiCapField!(can_generate_object_free_events, set_can_generate_object_free_events, OFFSET_CAN_GENERATE_OBJECT_FREE_EVENTS);
2299    jvmtiCapField!(can_force_early_return, set_can_force_early_return, OFFSET_CAN_FORCE_EARLY_RETURN);
2300    jvmtiCapField!(
2301        can_get_owned_monitor_stack_depth_info,
2302        set_can_get_owned_monitor_stack_depth_info,
2303        OFFSET_CAN_GET_OWNED_MONITOR_STACK_DEPTH_INFO
2304    );
2305    jvmtiCapField!(can_get_constant_pool, set_can_get_constant_pool, OFFSET_CAN_GET_CONSTANT_POOL);
2306    jvmtiCapField!(can_set_native_method_prefix, set_can_set_native_method_prefix, OFFSET_CAN_SET_NATIVE_METHOD_PREFIX);
2307    jvmtiCapField!(can_retransform_classes, set_can_retransform_classes, OFFSET_CAN_RETRANSFORM_CLASSES);
2308    jvmtiCapField!(can_retransform_any_class, set_can_retransform_any_class, OFFSET_CAN_RETRANSFORM_ANY_CLASS);
2309    jvmtiCapField!(
2310        can_generate_resource_exhaustion_heap_events,
2311        set_can_generate_resource_exhaustion_heap_events,
2312        OFFSET_CAN_GENERATE_RESOURCE_EXHAUSTION_HEAP_EVENTS
2313    );
2314    jvmtiCapField!(
2315        can_generate_resource_exhaustion_threads_events,
2316        set_can_generate_resource_exhaustion_threads_events,
2317        OFFSET_CAN_GENERATE_RESOURCE_EXHAUSTION_THREAD_EVENETS
2318    );
2319    jvmtiCapField!(can_generate_early_vmstart, set_can_generate_early_vmstart, OFFSET_CAN_GENERATE_EARLY_VMSTART);
2320    jvmtiCapField!(
2321        can_generate_early_class_hook_events,
2322        set_can_generate_early_class_hook_events,
2323        OFFSET_CAN_GENERATE_EARLY_CLASS_HOOK_EVENTS
2324    );
2325    jvmtiCapField!(
2326        can_generate_sampled_object_alloc_events,
2327        set_can_generate_sampled_object_alloc_events,
2328        OFFSET_CAN_GENERATE_SAMPLED_OBJECT_ALLOC_EVENTS
2329    );
2330    jvmtiCapField!(can_support_virtual_threads, set_can_support_virtual_threads, OFFSET_CAN_SUPPORT_VIRTUAL_THREADS);
2331}
2332
2333impl Display for jvmtiCapabilities {
2334    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
2335        f.write_fmt(format_args!(
2336            "jvmtiCapabilities {{
2337    can_tag_objects: {}
2338    can_generate_field_modification_events: {}
2339    can_generate_field_access_events: {}
2340    can_get_bytecodes: {}
2341    can_get_synthetic_attribute: {}
2342    can_get_owned_monitor_info: {}
2343    can_get_current_contended_monitor: {}
2344    can_get_monitor_info: {}
2345    can_pop_frame: {}
2346    can_redefine_classes: {}
2347    can_signal_thread: {}
2348    can_get_source_file_name: {}
2349    can_get_line_numbers: {}
2350    can_get_source_debug_extension: {}
2351    can_access_local_variables: {}
2352    can_maintain_original_method_order: {}
2353    can_generate_single_step_events: {}
2354    can_generate_exception_events: {}
2355    can_generate_frame_pop_events: {}
2356    can_generate_breakpoint_events: {}
2357    can_suspend: {}
2358    can_redefine_any_class: {}
2359    can_get_current_thread_cpu_time: {}
2360    can_get_thread_cpu_time: {}
2361    can_generate_method_entry_events: {}
2362    can_generate_method_exit_events: {}
2363    can_generate_all_class_hook_events: {}
2364    can_generate_compiled_method_load_events: {}
2365    can_generate_monitor_events: {}
2366    can_generate_vm_object_alloc_events: {}
2367    can_generate_native_method_bind_events: {}
2368    can_generate_garbage_collection_events: {}
2369    can_generate_object_free_events: {}
2370    can_force_early_return: {}
2371    can_get_owned_monitor_stack_depth_info: {}
2372    can_get_constant_pool: {}
2373    can_set_native_method_prefix: {}
2374    can_retransform_classes: {}
2375    can_retransform_any_class: {}
2376    can_generate_resource_exhaustion_heap_events: {}
2377    can_generate_resource_exhaustion_threads_events: {}
2378    can_generate_early_vmstart: {}
2379    can_generate_early_class_hook_events: {}
2380    can_generate_sampled_object_alloc_events: {}
2381    can_support_virtual_threads: {}
2382}}",
2383            self.can_tag_objects(),
2384            self.can_generate_field_modification_events(),
2385            self.can_generate_field_access_events(),
2386            self.can_get_bytecodes(),
2387            self.can_get_synthetic_attribute(),
2388            self.can_get_owned_monitor_info(),
2389            self.can_get_current_contended_monitor(),
2390            self.can_get_monitor_info(),
2391            self.can_pop_frame(),
2392            self.can_redefine_classes(),
2393            self.can_signal_thread(),
2394            self.can_get_source_file_name(),
2395            self.can_get_line_numbers(),
2396            self.can_get_source_debug_extension(),
2397            self.can_access_local_variables(),
2398            self.can_maintain_original_method_order(),
2399            self.can_generate_single_step_events(),
2400            self.can_generate_exception_events(),
2401            self.can_generate_frame_pop_events(),
2402            self.can_generate_breakpoint_events(),
2403            self.can_suspend(),
2404            self.can_redefine_any_class(),
2405            self.can_get_current_thread_cpu_time(),
2406            self.can_get_thread_cpu_time(),
2407            self.can_generate_method_entry_events(),
2408            self.can_generate_method_exit_events(),
2409            self.can_generate_all_class_hook_events(),
2410            self.can_generate_compiled_method_load_events(),
2411            self.can_generate_monitor_events(),
2412            self.can_generate_vm_object_alloc_events(),
2413            self.can_generate_native_method_bind_events(),
2414            self.can_generate_garbage_collection_events(),
2415            self.can_generate_object_free_events(),
2416            self.can_force_early_return(),
2417            self.can_get_owned_monitor_stack_depth_info(),
2418            self.can_get_constant_pool(),
2419            self.can_set_native_method_prefix(),
2420            self.can_retransform_classes(),
2421            self.can_retransform_any_class(),
2422            self.can_generate_resource_exhaustion_heap_events(),
2423            self.can_generate_resource_exhaustion_threads_events(),
2424            self.can_generate_early_vmstart(),
2425            self.can_generate_early_class_hook_events(),
2426            self.can_generate_sampled_object_alloc_events(),
2427            self.can_support_virtual_threads(),
2428        ))
2429    }
2430}
2431
2432#[repr(C)]
2433#[derive(Debug, Default, Clone, Copy)]
2434pub struct jvmtiHeapReferenceInfoReserved {
2435    pub reserved1: jlong,
2436    pub reserved2: jlong,
2437    pub reserved3: jlong,
2438    pub reserved4: jlong,
2439    pub reserved5: jlong,
2440    pub reserved6: jlong,
2441    pub reserved7: jlong,
2442    pub reserved8: jlong,
2443}
2444
2445pub const JVMTI_HEAP_FILTER_TAGGED: jint = 0x4;
2446pub const JVMTI_HEAP_FILTER_UNTAGGED: jint = 0x8;
2447pub const JVMTI_HEAP_FILTER_CLASS_TAGGED: jint = 0x10;
2448pub const JVMTI_HEAP_FILTER_CLASS_UNTAGGED: jint = 0x20;
2449pub const JVMTI_VISIT_OBJECTS: jint = 0x100;
2450pub const JVMTI_VISIT_ABORT: jint = 0x8000;
2451
2452#[repr(C)]
2453#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash, Ord, PartialOrd)]
2454pub enum jvmtiHeapReferenceKind {
2455    CLASS = 0x1,
2456    FIELD = 0x2,
2457    ARRAY_ELEMENT = 0x3,
2458    CLASS_LOADER = 0x4,
2459    SIGNERS = 0x5,
2460    PROTECTION_DOMAIN = 0x6,
2461    INTERFACE = 0x7,
2462    STATIC_FIELD = 0x8,
2463    CONSTANT_POOL = 0x9,
2464    SUPERCLASS = 0x10,
2465    JNI_GLOBAL = 0x21,
2466    SYSTEM_CLASS = 0x22,
2467    MONITOR = 0x23,
2468    STACK_LOCAL = 0x24,
2469    JNI_LOCAL = 0x25,
2470    THREAD = 0x26,
2471    OTHER = 0x27,
2472}
2473pub const JVMTI_HEAP_REFERENCE_CLASS: jint = 0x1;
2474
2475pub const JVMTI_HEAP_REFERENCE_FIELD: jint = 0x2;
2476pub const JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT: jint = 0x3;
2477pub const JVMTI_HEAP_REFERENCE_CLASS_LOADER: jint = 0x4;
2478pub const JVMTI_HEAP_REFERENCE_SIGNERS: jint = 0x5;
2479pub const JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN: jint = 0x6;
2480pub const JVMTI_HEAP_REFERENCE_INTERFACE: jint = 0x7;
2481pub const JVMTI_HEAP_REFERENCE_STATIC_FIELD: jint = 0x8;
2482pub const JVMTI_HEAP_REFERENCE_CONSTANT_POOL: jint = 0x9;
2483pub const JVMTI_HEAP_REFERENCE_SUPERCLASS: jint = 0x10;
2484pub const JVMTI_HEAP_REFERENCE_JNI_GLOBAL: jint = 0x21;
2485pub const JVMTI_HEAP_REFERENCE_SYSTEM_CLASS: jint = 0x22;
2486pub const JVMTI_HEAP_REFERENCE_MONITOR: jint = 0x23;
2487pub const JVMTI_HEAP_REFERENCE_STACK_LOCAL: jint = 0x24;
2488pub const JVMTI_HEAP_REFERENCE_JNI_LOCAL: jint = 0x25;
2489pub const JVMTI_HEAP_REFERENCE_THREAD: jint = 0x26;
2490pub const JVMTI_HEAP_REFERENCE_OTHER: jint = 0x27;
2491
2492#[repr(C)]
2493#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash, Ord, PartialOrd)]
2494pub enum jvmtiPrimitiveType {
2495    JVMTI_PRIMITIVE_TYPE_BOOLEAN = 90,
2496    JVMTI_PRIMITIVE_TYPE_BYTE = 66,
2497    JVMTI_PRIMITIVE_TYPE_CHAR = 67,
2498    JVMTI_PRIMITIVE_TYPE_SHORT = 83,
2499    JVMTI_PRIMITIVE_TYPE_INT = 73,
2500    JVMTI_PRIMITIVE_TYPE_LONG = 74,
2501    JVMTI_PRIMITIVE_TYPE_FLOAT = 70,
2502    JVMTI_PRIMITIVE_TYPE_DOUBLE = 68,
2503}
2504pub const JVMTI_PRIMITIVE_TYPE_BOOLEAN: c_int = 90;
2505pub const JVMTI_PRIMITIVE_TYPE_BYTE: c_int = 66;
2506pub const JVMTI_PRIMITIVE_TYPE_CHAR: c_int = 67;
2507pub const JVMTI_PRIMITIVE_TYPE_SHORT: c_int = 83;
2508pub const JVMTI_PRIMITIVE_TYPE_INT: c_int = 73;
2509pub const JVMTI_PRIMITIVE_TYPE_LONG: c_int = 74;
2510pub const JVMTI_PRIMITIVE_TYPE_FLOAT: c_int = 70;
2511pub const JVMTI_PRIMITIVE_TYPE_DOUBLE: c_int = 68;
2512
2513#[repr(C)]
2514#[derive(Debug, Default, Clone, Copy)]
2515pub struct jvmtiHeapReferenceInfoField {
2516    pub index: jint,
2517}
2518
2519#[repr(C)]
2520#[derive(Debug, Default, Clone, Copy)]
2521pub struct jvmtiHeapReferenceInfoArray {
2522    pub index: jint,
2523}
2524
2525#[repr(C)]
2526#[derive(Debug, Default, Clone, Copy)]
2527pub struct jvmtiHeapReferenceInfoConstantPool {
2528    pub index: jint,
2529}
2530
2531#[repr(C)]
2532#[derive(Debug, Clone, Copy)]
2533pub struct jvmtiHeapReferenceInfoStackLocal {
2534    pub thread_tag: jlong,
2535    pub thread_id: jlong,
2536    pub depth: jint,
2537    pub method: jmethodID,
2538    pub location: jlocation,
2539    pub slot: jint,
2540}
2541
2542impl Default for jvmtiHeapReferenceInfoStackLocal {
2543    fn default() -> Self {
2544        Self {
2545            thread_tag: 0,
2546            thread_id: 0,
2547            depth: 0,
2548            method: null_mut(),
2549            location: 0,
2550            slot: 0,
2551        }
2552    }
2553}
2554
2555#[repr(C)]
2556#[derive(Debug, Clone, Copy)]
2557pub struct jvmtiHeapReferenceInfoJniLocal {
2558    pub thread_tag: jlong,
2559    pub thread_id: jlong,
2560    pub depth: jint,
2561    pub method: jmethodID,
2562}
2563
2564impl Default for jvmtiHeapReferenceInfoJniLocal {
2565    fn default() -> Self {
2566        Self {
2567            thread_tag: 0,
2568            thread_id: 0,
2569            depth: 0,
2570            method: null_mut(),
2571        }
2572    }
2573}
2574
2575#[repr(C)]
2576pub union jvmtiHeapReferenceInfo {
2577    pub field: jvmtiHeapReferenceInfoField,
2578    pub array: jvmtiHeapReferenceInfoArray,
2579    pub constant_pool: jvmtiHeapReferenceInfoConstantPool,
2580    pub stack_local: jvmtiHeapReferenceInfoStackLocal,
2581    pub jni_local: jvmtiHeapReferenceInfoJniLocal,
2582    pub other: jvmtiHeapReferenceInfoReserved,
2583}
2584
2585pub type jvmtiHeapIterationCallback = extern "system" fn(class_tag: jlong, size: jlong, tag_ptr: *mut jlong, length: jint, user_data: *mut c_void) -> jint;
2586pub type jvmtiHeapReferenceCallback = extern "system" fn(
2587    reference_kind: jvmtiHeapReferenceKind,
2588    reference_info: *const jvmtiHeapReferenceInfo,
2589    class_tag: jlong,
2590    referrer_class_tag: jlong,
2591    size: jlong,
2592    tag_ptr: *mut jlong,
2593    referrer_tag_ptr: *mut jlong,
2594    length: jint,
2595    user_data: *mut c_void,
2596) -> jint;
2597
2598pub type jvmtiPrimitiveFieldCallback = extern "system" fn(
2599    kind: jvmtiHeapReferenceKind,
2600    info: *const jvmtiHeapReferenceInfo,
2601    object_class_tag: jlong,
2602    object_tag_ptr: *mut jlong,
2603    value: jvalue,
2604    value_type: jvmtiPrimitiveType,
2605    user_data: *mut c_void,
2606) -> jint;
2607
2608pub type jvmtiArrayPrimitiveValueCallback = extern "system" fn(
2609    class_tag: jlong,
2610    size: jlong,
2611    tag_ptr: *mut jlong,
2612    element_count: jint,
2613    element_type: jvmtiPrimitiveType,
2614    elements: *const c_void,
2615    user_data: *mut c_void,
2616) -> jint;
2617
2618pub type jvmtiStringPrimitiveValueCallback =
2619    extern "system" fn(class_tag: jlong, size: jlong, tag_ptr: *mut jlong, value: *const jchar, value_length: jint, user_data: *mut c_void) -> jint;
2620
2621pub type jvmtiReservedCallback = extern "system" fn() -> jint;
2622
2623#[repr(C)]
2624#[derive(Debug, Clone, Default)]
2625pub struct jvmtiHeapCallbacks {
2626    pub heap_iteration_callback: Option<jvmtiHeapIterationCallback>,
2627    pub heap_reference_callback: Option<jvmtiHeapReferenceCallback>,
2628    pub primitive_field_callback: Option<jvmtiPrimitiveFieldCallback>,
2629    pub array_primitive_value_callback: Option<jvmtiArrayPrimitiveValueCallback>,
2630    pub string_primitive_value_callback: Option<jvmtiStringPrimitiveValueCallback>,
2631    pub reserved5: Option<jvmtiReservedCallback>,
2632    pub reserved6: Option<jvmtiReservedCallback>,
2633    pub reserved7: Option<jvmtiReservedCallback>,
2634    pub reserved8: Option<jvmtiReservedCallback>,
2635    pub reserved9: Option<jvmtiReservedCallback>,
2636    pub reserved10: Option<jvmtiReservedCallback>,
2637    pub reserved11: Option<jvmtiReservedCallback>,
2638    pub reserved12: Option<jvmtiReservedCallback>,
2639    pub reserved13: Option<jvmtiReservedCallback>,
2640    pub reserved14: Option<jvmtiReservedCallback>,
2641    pub reserved15: Option<jvmtiReservedCallback>,
2642}
2643
2644#[derive(Debug, Default, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
2645#[repr(C)]
2646pub enum jvmtiIterationControl {
2647    #[default]
2648    JVMTI_ITERATION_ABORT = 0,
2649    JVMTI_ITERATION_CONTINUE = 1,
2650    JVMTI_ITERATION_IGNORE = 2,
2651}
2652
2653/// jvmtiHeapRootKind cant enum this because we are called with it, making addition in a future version of JVMTI UB in rust.
2654pub type jvmtiHeapRootKind = c_int;
2655pub const JVMTI_HEAP_ROOT_JNI_GLOBAL: jvmtiHeapRootKind = 1;
2656pub const JVMTI_HEAP_ROOT_SYSTEM_CLASS: jvmtiHeapRootKind = 2;
2657pub const JVMTI_HEAP_ROOT_MONITOR: jvmtiHeapRootKind = 3;
2658pub const JVMTI_HEAP_ROOT_STACK_LOCAL: jvmtiHeapRootKind = 4;
2659pub const JVMTI_HEAP_ROOT_JNI_LOCAL: jvmtiHeapRootKind = 5;
2660pub const JVMTI_HEAP_ROOT_THREAD: jvmtiHeapRootKind = 6;
2661pub const JVMTI_HEAP_ROOT_OTHER: jvmtiHeapRootKind = 7;
2662
2663/// jvmtiHeapRootKind cant enum this because we are called with it, making addition in a future version of JVMTI UB in rust.
2664pub type jvmtiObjectReferenceKind = c_int;
2665
2666pub const JVMTI_REFERENCE_CLASS: jvmtiObjectReferenceKind = 1;
2667pub const JVMTI_REFERENCE_FIELD: jvmtiObjectReferenceKind = 2;
2668pub const JVMTI_REFERENCE_ARRAY_ELEMENT: jvmtiObjectReferenceKind = 3;
2669pub const JVMTI_REFERENCE_CLASS_LOADER: jvmtiObjectReferenceKind = 4;
2670pub const JVMTI_REFERENCE_SIGNERS: jvmtiObjectReferenceKind = 5;
2671pub const JVMTI_REFERENCE_PROTECTION_DOMAIN: jvmtiObjectReferenceKind = 6;
2672pub const JVMTI_REFERENCE_INTERFACE: jvmtiObjectReferenceKind = 7;
2673pub const JVMTI_REFERENCE_STATIC_FIELD: jvmtiObjectReferenceKind = 8;
2674pub const JVMTI_REFERENCE_CONSTANT_POOL: jvmtiObjectReferenceKind = 9;
2675
2676// GetClassStatus bitmask values
2677
2678/// Class bytecodes have been verified
2679pub const JVMTI_CLASS_STATUS_VERIFIED: jint = 1;
2680/// Class preparation is complete
2681pub const JVMTI_CLASS_STATUS_PREPARED: jint = 2;
2682/// Class initialization is complete. Static initializer has been run.
2683pub const JVMTI_CLASS_STATUS_INITIALIZED: jint = 4;
2684/// Error during initialization makes class unusable
2685pub const JVMTI_CLASS_STATUS_ERROR: jint = 8;
2686/// Class is an array. If set, all other bits are zero.
2687pub const JVMTI_CLASS_STATUS_ARRAY: jint = 16;
2688/// Class is a primitive class (for example, java.lang.Integer.TYPE). If set, all other bits are zero.
2689pub const JVMTI_CLASS_STATUS_PRIMITIVE: jint = 32;
2690
2691#[derive(Debug, Default, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
2692#[repr(C)]
2693pub enum jvmtiHeapObjectFilter {
2694    JVMTI_HEAP_OBJECT_TAGGED = 1,
2695    JVMTI_HEAP_OBJECT_UNTAGGED = 2,
2696    #[default]
2697    JVMTI_HEAP_OBJECT_EITHER = 3,
2698}
2699
2700pub type jvmtiHeapObjectCallback = extern "system" fn(class_tag: jlong, size: jlong, tag_ptr: *mut jlong, user_data: *mut c_void) -> jvmtiIterationControl;
2701
2702pub type jvmtiHeapRootCallback =
2703    extern "system" fn(root_kind: jvmtiHeapRootKind, class_tag: jlong, size: jlong, tag_ptr: *mut jlong, user_data: *mut c_void) -> jvmtiIterationControl;
2704
2705pub type jvmtiStackReferenceCallback = extern "system" fn(
2706    root_kind: jvmtiHeapRootKind,
2707    class_tag: jlong,
2708    size: jlong,
2709    tag_ptr: *mut jlong,
2710    thread_tag: jlong,
2711    depth: jint,
2712    method: jmethodID,
2713    slot: jint,
2714    user_data: *mut c_void,
2715) -> jvmtiIterationControl;
2716
2717pub type jvmtiObjectReferenceCallback = extern "system" fn(
2718    reference_kind: jvmtiObjectReferenceKind,
2719    class_tag: jlong,
2720    size: jlong,
2721    tag_ptr: *mut jlong,
2722    referrer_tag: jlong,
2723    referrer_index: jint,
2724    user_data: *mut c_void,
2725) -> jvmtiIterationControl;
2726
2727impl From<jvmtiHeapIterationCallback> for jvmtiHeapCallbacks {
2728    fn from(value: jvmtiHeapIterationCallback) -> Self {
2729        Self {
2730            heap_iteration_callback: Some(value),
2731            ..Default::default()
2732        }
2733    }
2734}
2735
2736impl From<jvmtiHeapReferenceCallback> for jvmtiHeapCallbacks {
2737    fn from(value: jvmtiHeapReferenceCallback) -> Self {
2738        Self {
2739            heap_reference_callback: Some(value),
2740            ..Default::default()
2741        }
2742    }
2743}
2744
2745impl From<jvmtiPrimitiveFieldCallback> for jvmtiHeapCallbacks {
2746    fn from(value: jvmtiPrimitiveFieldCallback) -> Self {
2747        Self {
2748            primitive_field_callback: Some(value),
2749            ..Default::default()
2750        }
2751    }
2752}
2753
2754impl From<jvmtiArrayPrimitiveValueCallback> for jvmtiHeapCallbacks {
2755    fn from(value: jvmtiArrayPrimitiveValueCallback) -> Self {
2756        Self {
2757            array_primitive_value_callback: Some(value),
2758            ..Default::default()
2759        }
2760    }
2761}
2762
2763impl From<jvmtiStringPrimitiveValueCallback> for jvmtiHeapCallbacks {
2764    fn from(value: jvmtiStringPrimitiveValueCallback) -> Self {
2765        Self {
2766            string_primitive_value_callback: Some(value),
2767            ..Default::default()
2768        }
2769    }
2770}
2771
2772pub type jvmtiStartFunction = extern "system" fn(JVMTIEnv, JNIEnv, *mut c_void);
2773
2774#[derive(Debug, Clone, Copy)]
2775#[repr(C)]
2776pub struct jvmtiClassDefinition {
2777    pub klass: jclass,
2778    pub class_byte_count: jint,
2779    pub class_bytes: *const c_uchar,
2780}
2781
2782#[derive(Debug, Clone, Copy)]
2783#[repr(C)]
2784pub struct jvmtiMonitorUsage {
2785    pub owner: jthread,
2786    pub entry_count: jint,
2787    pub waiter_count: jint,
2788    pub waiters: *mut jthread,
2789    pub notify_waiter_count: jint,
2790    pub notify_waiters: *mut jthread,
2791}
2792
2793#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
2794#[repr(C)]
2795pub struct jvmtiLineNumberEntry {
2796    pub start_location: jlocation,
2797    pub line_number: jint,
2798}
2799
2800#[derive(Debug, Clone, Copy)]
2801#[repr(C)]
2802pub struct jvmtiLocalVariableEntry {
2803    pub start_location: jlocation,
2804    pub length: jint,
2805    pub name: *mut c_char,
2806    pub signature: *mut c_char,
2807    pub generic_signature: *mut c_char,
2808    pub slot: jint,
2809}
2810
2811/// Vtable of `JVMTIEnv` is passed like this.
2812type JVMTIEnvVTable = SyncMutPtr<*mut *mut c_void>;
2813
2814#[derive(Debug, Clone, Copy)]
2815#[repr(transparent)]
2816pub struct JVMTIEnv {
2817    /// The vtable that contains all the functions
2818    vtable: JVMTIEnvVTable,
2819}
2820
2821impl SealedEnvVTable for JVMTIEnv {
2822    fn can_jni() -> bool {
2823        false
2824    }
2825
2826    fn can_jvmti() -> bool {
2827        true
2828    }
2829}
2830
2831impl From<*mut c_void> for JVMTIEnv {
2832    #[allow(clippy::not_unsafe_ptr_arg_deref)]
2833    fn from(value: *mut c_void) -> Self {
2834        Self {
2835            vtable: value.as_sync_mut().cast(),
2836        }
2837    }
2838}
2839
2840impl JVMTIEnv {
2841    ///
2842    /// resolves the function pointer given its linkage index of the jvmt vtable.
2843    /// The indices are documented and guaranteed by the Oracle JVM Spec.
2844    /// NOTE: Oracle has documented them with index starting at 1 so you have to subtract 1!
2845    ///
2846    #[inline(always)]
2847    unsafe fn jvmti<X>(&self, index: usize) -> X {
2848        unsafe { core::mem::transmute_copy(&(self.vtable.read_volatile().add(index).read_volatile())) }
2849    }
2850
2851    /// Returns the raw jvmti vtable.
2852    /// Calling this function is usually not needed.
2853    #[must_use]
2854    pub const fn vtable(&self) -> *mut c_void {
2855        self.vtable.inner().cast()
2856    }
2857
2858    /// Return the JVM TI version via `version_ptr`.
2859    ///
2860    /// The return value is the version identifier.
2861    /// The version identifier includes major, minor and micro version as well as the interface type.
2862    ///
2863    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetVersionNumber>
2864    ///
2865    /// # Safety
2866    /// JVM Implementation dependant
2867    ///
2868    pub unsafe fn GetVersionNumber(&self, version_ptr: *mut jint) -> jvmtiError {
2869        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jint) -> jvmtiError>(87)(self.vtable, version_ptr) }
2870    }
2871
2872    /// Return the current phase of VM execution.
2873    ///
2874    /// The phases proceed in sequence:
2875    /// * `JVMTI_PHASE_ONLOAD` - `OnLoad` phase: while in the `Agent_OnLoad` or, for statically linked agents, the `Agent_OnLoad_<agent-lib-name>` function.
2876    /// * `JVMTI_PHASE_PRIMORDIAL` - `Primordial` phase: between return from `Agent_OnLoad` or `Agent_OnLoad_<agent-lib-name>` and the `VMStart` event.
2877    /// * `JVMTI_PHASE_START` - `Start` phase: when the `VMStart` event is sent and until the `VMInit` event is sent.
2878    /// * `JVMTI_PHASE_LIVE` - `Live` phase: when the `VMInit` event is sent and until the `VMDeath` event returns.
2879    /// * `JVMTI_PHASE_DEAD` - `Dead` phase: after the `VMDeath` event returns or after start-up failure.
2880    ///
2881    /// In the case of start-up failure the VM will proceed directly to the dead phase skipping
2882    /// intermediate phases and neither a `VMInit` nor `VMDeath` event will be sent.
2883    ///
2884    /// JNI functions (except the Invocation API) must only be used in the start or live phases.
2885    /// Most JVM TI events are sent only in the live phase.
2886    ///
2887    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetPhase>
2888    ///
2889    /// # Safety
2890    /// JVM Implementation dependant
2891    ///
2892    pub unsafe fn GetPhase(&self, phase: *mut jvmtiPhase) -> jvmtiError {
2893        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut c_int) -> jvmtiError>(132)(self.vtable, phase) }
2894    }
2895
2896    /// Allocate an area of memory through the JVM TI allocator.
2897    ///
2898    /// The allocated memory should be freed with Deallocate.
2899    ///
2900    ///  See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#Allocate>
2901    ///
2902    /// # Safety
2903    /// The receiver pointer must not be dangling.
2904    ///
2905    pub unsafe fn Allocate(&self, size: jlong, mem_ptr: *mut *mut c_uchar) -> jvmtiError {
2906        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jlong, *mut *mut c_uchar) -> jvmtiError>(45)(self.vtable, size, mem_ptr) }
2907    }
2908
2909    /// Deallocate mem using the JVM TI allocator.
2910    ///
2911    /// This function should be used to deallocate any memory allocated and returned by a JVM TI function (including memory allocated with Allocate).
2912    /// All allocated memory must be deallocated or the memory cannot be reclaimed.
2913    ///
2914    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#Deallocate>
2915    ///
2916    /// # Safety
2917    /// The pointer must have been allocated by the JVMTI allocator using allocate or returned by some JVMTI function.
2918    /// Naturally use after free problems may arise if the memory is used after this function is called.
2919    ///
2920    pub unsafe fn Deallocate<T>(&self, mem: *const T) -> jvmtiError {
2921        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const c_uchar) -> jvmtiError>(46)(self.vtable, mem.cast()) }
2922    }
2923
2924    /// Get the state of a thread.
2925    ///
2926    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetThreadState>
2927    ///
2928    /// # Safety
2929    /// The `thread` must be a valid strong reference to a thread.
2930    /// The `thread_state_ptr` must not be a dangling pointer.
2931    ///
2932    pub unsafe fn GetThreadState(&self, thread: jthread, thread_state_ptr: *mut jint) -> jvmtiError {
2933        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, *mut jint) -> jvmtiError>(16)(self.vtable, thread, thread_state_ptr) }
2934    }
2935
2936    /// Get the current thread.
2937    ///
2938    /// The current thread is the Java programming language thread which has called the function.
2939    /// The function may return a null pointer in the start phase if the `can_generate_early_vmstart` capability is enabled and the java.lang.Thread class has not been initialized yet.
2940    /// Note that most JVM TI functions that take a thread as an argument will accept null to mean the current thread.
2941    ///
2942    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetCurrentThread>
2943    ///
2944    /// # Safety
2945    /// The thread receiver pointer must not be dangling.
2946    ///
2947    pub unsafe fn GetCurrentThread(&self, thread: *mut jthread) -> jvmtiError {
2948        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jthread) -> jvmtiError>(17)(self.vtable, thread) }
2949    }
2950
2951    /// Get all live platform threads that are attached to the VM.
2952    ///
2953    /// The list of threads includes agent threads.
2954    /// It does not include virtual threads.
2955    /// A thread is live if `java.lang.Thread.isAlive()` would return true, that is, the thread has been started and has not yet terminated.
2956    /// The universe of threads is determined by the context of the JVM TI environment, which typically is all threads attached to the VM.
2957    ///
2958    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetAllThreads>
2959    ///
2960    /// # Safety
2961    /// All pointer parameters must not be dangling.
2962    ///
2963    pub unsafe fn GetAllThreads(&self, threads_count_ptr: *mut jint, threads_ptr: *mut *mut jthread) -> jvmtiError {
2964        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jint, *mut *mut jthread) -> jvmtiError>(3)(self.vtable, threads_count_ptr, threads_ptr) }
2965    }
2966
2967    /// Get all live platform threads that are attached to the VM as a Vec.
2968    /// Each jthread inside the returned Vec must be freed by the caller by calling `JniEnv::DeleteLocalRef`
2969    ///
2970    /// This convenience function automatically handles deallocating the memory using the jvmti allocator.
2971    ///
2972    /// The list of threads includes agent threads.
2973    /// It does not include virtual threads.
2974    /// A thread is live if `java.lang.Thread.isAlive()` would return true, that is, the thread has been started and has not yet terminated.
2975    /// The universe of threads is determined by the context of the JVM TI environment, which typically is all threads attached to the VM.
2976    ///
2977    /// # Safety
2978    /// JVM implementation specific.
2979    ///
2980    /// # Panics
2981    /// If the jvm returns unexpected data such as negative array lengths or null pointers without providing an error code.
2982    ///
2983    /// # Errors
2984    /// If the jvm fails to list the threads.
2985    ///
2986    pub unsafe fn GetAllThreads_as_vec(&self) -> Result<Vec<jthread>, jvmtiError> {
2987        unsafe {
2988            let mut count = 0;
2989            let mut threads_ptr = null_mut();
2990            self.GetAllThreads(&raw mut count, &raw mut threads_ptr).into_result()?;
2991            let count = usize::try_from(count).expect("JVMTI GetAllThreads provided an array with a negative number of threads");
2992            if count == 0 {
2993                if !threads_ptr.is_null() {
2994                    _ = self.Deallocate(threads_ptr);
2995                }
2996                return Ok(Vec::new());
2997            }
2998
2999            assert!(
3000                !threads_ptr.is_null(),
3001                "JVMTI GetAllThreads returned a null pointer thread array without returning an error"
3002            );
3003            let result = core::slice::from_raw_parts(threads_ptr, count).to_vec();
3004            _ = self.Deallocate(threads_ptr);
3005            Ok(result)
3006        }
3007    }
3008
3009    /// Suspend the specified thread.
3010    ///
3011    /// If the calling thread is specified,
3012    /// this function will not return until some other thread calls `ResumeThread`.
3013    /// If the thread is currently suspended, this function does nothing and returns an error.
3014    ///
3015    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SuspendThread>
3016    ///
3017    /// # Safety
3018    /// The thread must be a valid strong reference to a thread.
3019    ///
3020    pub unsafe fn SuspendThread(&self, thread: jthread) -> jvmtiError {
3021        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread) -> jvmtiError>(4)(self.vtable, thread) }
3022    }
3023
3024    /// Suspend the `request_count` threads specified in the `request_list` array.
3025    ///
3026    /// Threads may be resumed with `ResumeThreadList` or `ResumeThread`.
3027    /// If the calling thread is specified in the `request_list` array, this function will not return until some other thread resumes it.
3028    /// Errors encountered in the suspension of a thread are returned in the results array, not in the return value of this function.
3029    /// Threads that are currently suspended do not change state.
3030    ///
3031    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SuspendThreadList>
3032    ///
3033    /// # Safety
3034    /// All threads must be valid strong references to a thread.
3035    /// the `request_list` parameter must be a valid array.
3036    /// None of the pointer parameters must be dangling.
3037    ///
3038    pub unsafe fn SuspendThreadList(&self, request_count: jint, request_list: *const jthread, results: *mut jvmtiError) -> jvmtiError {
3039        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, *const jthread, *mut jvmtiError) -> jvmtiError>(91)(self.vtable, request_count, request_list, results) }
3040    }
3041
3042    /// Suspend all virtual threads except those in the exception list.
3043    /// Virtual threads that are currently suspended do not change state.
3044    /// Virtual threads may be resumed with `ResumeAllVirtualThreads` or `ResumeThreadList` or `ResumeThread`.
3045    ///
3046    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SuspendAllVirtualThreads>
3047    ///
3048    /// # Safety
3049    /// All threads must be valid strong references to a thread.
3050    /// the `except_list` and `except_count` parameter must be a valid array.
3051    /// `except_list` must not be a dangling pointer.
3052    ///
3053    pub unsafe fn SuspendAllVirtualThreads(&self, except_count: jint, except_list: *const jthread) -> jvmtiError {
3054        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, *const jthread) -> jvmtiError>(117)(self.vtable, except_count, except_list) }
3055    }
3056
3057    /// Resume a suspended thread.
3058    ///
3059    /// Any threads currently suspended through a JVM TI suspend function (eg. `SuspendThread`) will resume execution;
3060    /// all other threads are unaffected.
3061    ///
3062    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ResumeThread>
3063    ///
3064    /// # Safety
3065    /// thread must refer to a valid strong reference to a thread.
3066    ///
3067    pub unsafe fn ResumeThread(&self, thread: jthread) -> jvmtiError {
3068        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread) -> jvmtiError>(5)(self.vtable, thread) }
3069    }
3070
3071    /// Resume the `request_count` threads specified in the `request_list` array.
3072    /// Any thread suspended through a JVM TI suspend function (eg. `SuspendThreadList`) will resume execution.
3073    ///
3074    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ResumeThreadList>
3075    ///
3076    /// # Safety
3077    /// All threads must be valid strong references to a thread.
3078    /// The `request_list` parameter must be a valid array.
3079    /// None of the pointer parameters must be dangling.
3080    ///
3081    pub unsafe fn ResumeThreadList(&self, request_count: jint, request_list: *const jthread, results: *mut jvmtiError) -> jvmtiError {
3082        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, *const jthread, *mut jvmtiError) -> jvmtiError>(92)(self.vtable, request_count, request_list, results) }
3083    }
3084
3085    /// Resume all virtual threads except those in the exception list.
3086    /// Virtual threads that are currently resumed do not change state.
3087    /// Virtual threads may be suspended with `SuspendAllVirtualThreads` or `SuspendThreadList` or `SuspendThread`.
3088    ///
3089    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ResumeAllVirtualThreads>
3090    ///
3091    /// # Safety
3092    /// All threads must be valid strong references to a thread.
3093    /// The `except_list` and `except_count` parameter must be a valid array.
3094    /// `except_list` must not be a dangling pointer.
3095    ///
3096    pub unsafe fn ResumeAllVirtualThreads(&self, except_count: jint, except_list: *const jthread) -> jvmtiError {
3097        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, *const jthread) -> jvmtiError>(118)(self.vtable, except_count, except_list) }
3098    }
3099
3100    /// Send the specified asynchronous exception to the specified thread.
3101    ///
3102    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#StopThread>
3103    ///
3104    /// # Safety
3105    /// thread must refer to a valid strong reference to a thread.
3106    /// exception must refer to a valid strong reference to a object.
3107    ///
3108    pub unsafe fn StopThread(&self, thread: jthread, exception: jobject) -> jvmtiError {
3109        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jobject) -> jvmtiError>(6)(self.vtable, thread, exception) }
3110    }
3111
3112    /// Interrupt the specified thread (similar to java.lang.Thread.interrupt).
3113    ///
3114    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#InterruptThread>
3115    ///
3116    /// # Safety
3117    /// thread must refer to a valid strong reference to a thread.
3118    ///
3119    pub unsafe fn InterruptThread(&self, thread: jthread) -> jvmtiError {
3120        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread) -> jvmtiError>(7)(self.vtable, thread) }
3121    }
3122
3123    /// Get thread information. The fields of the jvmtiThreadInfo structure are filled in with details of the specified thread.
3124    ///
3125    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetThreadInfo>
3126    ///
3127    /// # Safety
3128    /// thread must refer to a valid strong reference to a thread.
3129    /// `info_ptr` must not be dangling.
3130    ///
3131    pub unsafe fn GetThreadInfo(&self, thread: jthread, info_ptr: *mut jvmtiThreadInfo) -> jvmtiError {
3132        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, *mut jvmtiThreadInfo) -> jvmtiError>(8)(self.vtable, thread, info_ptr) }
3133    }
3134
3135    /// Get information about the monitors owned by the specified thread.
3136    ///
3137    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetOwnedMonitorInfo>
3138    ///
3139    /// # Safety
3140    /// thread must refer to a valid strong reference to a thread.
3141    /// pointer parameters must not be dangling.
3142    ///
3143    pub unsafe fn GetOwnedMonitorInfo(&self, thread: jthread, owned_monitor_count_ptr: *mut jint, owned_monitors_ptr: *mut *mut jobject) -> jvmtiError {
3144        unsafe {
3145            self.jvmti::<extern "system" fn(JVMTIEnvVTable, crate::jthread, *mut jint, *mut *mut jobject) -> jvmtiError>(9)(
3146                self.vtable,
3147                thread,
3148                owned_monitor_count_ptr,
3149                owned_monitors_ptr,
3150            )
3151        }
3152    }
3153
3154    /// Get information about the monitors owned by the specified thread and the depth of the stack frame which locked them.
3155    ///
3156    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetOwnedMonitorStackDepthInfo>
3157    ///
3158    /// # Safety
3159    /// thread must refer to a valid strong reference to a thread.
3160    /// pointer parameters must not be dangling.
3161    ///
3162    pub unsafe fn GetOwnedMonitorStackDepthInfo(&self, thread: jthread, monitor_info_count_ptr: *mut jint, monitor_info_ptr: *mut *mut jvmtiMonitorStackDepthInfo) -> jvmtiError {
3163        unsafe {
3164            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, *mut jint, *mut *mut jvmtiMonitorStackDepthInfo) -> jvmtiError>(152)(
3165                self.vtable,
3166                thread,
3167                monitor_info_count_ptr,
3168                monitor_info_ptr,
3169            )
3170        }
3171    }
3172
3173    /// Get the object, if any, whose monitor the specified thread is waiting to enter or waiting to regain through java.lang.Object.wait.
3174    ///
3175    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetCurrentContendedMonitor>
3176    ///
3177    /// # Safety
3178    /// `thread` must refer to a valid strong reference to a thread.
3179    /// `monitor_ptr` parameter must not be dangling.
3180    ///
3181    pub unsafe fn GetCurrentContendedMonitor(&self, thread: jthread, monitor_ptr: *mut jobject) -> jvmtiError {
3182        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, *mut jobject) -> jvmtiError>(10)(self.vtable, thread, monitor_ptr) }
3183    }
3184
3185    /// Starts the execution of an agent thread. with the specified native function.
3186    ///
3187    /// The parameter arg is forwarded on to the start function (specified with proc) as its single argument.
3188    /// This function allows the creation of agent threads for handling communication with another process or for handling events without the need to load a special subclass of java.lang.Thread or implementer of java.lang.Runnable.
3189    /// Instead, the created thread can run entirely in native code. However, the created thread does require a newly created instance of java.lang.Thread (referenced by the argument thread) to which it will be associated.
3190    /// The thread object can be created with JNI calls.
3191    ///
3192    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#RunAgentThread>
3193    ///
3194    /// # Safety
3195    /// `thread` must refer to a valid strong reference to a thread.
3196    /// `proc` must refer to a extern system fn with a matching signature.
3197    ///
3198    pub unsafe fn RunAgentThread(&self, thread: jthread, proc: jvmtiStartFunction, arg: *mut c_void, priority: jint) -> jvmtiError {
3199        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jvmtiStartFunction, *mut c_void, jint) -> jvmtiError>(11)(self.vtable, thread, proc, arg, priority) }
3200    }
3201
3202    /// Starts the execution of an agent thread. with the specified rust closure/function.
3203    ///
3204    /// This is a convenience function that automatically handles wrapping of a rust `FnOnce` to
3205    /// be invoked by the JVM in a new thread.
3206    ///
3207    /// In case of error the `proc` parameter is dropped without ever being executed.
3208    ///
3209    /// # Safety
3210    /// `thread` must refer to a valid strong reference to a thread.
3211    /// `proc` must not panic when called. (compile with panic=abort or use `panic::catch_unwind`.)
3212    /// # Example
3213    /// ```rust
3214    /// use jni_simple::{JNIEnv, JVMTIEnv};
3215    ///
3216    /// fn start_agent_thread(jvmti: JVMTIEnv, env: JNIEnv) {
3217    ///     unsafe {
3218    ///         //Do this once in your init function, remember to check for errors!
3219    ///         let thread_class = env.FindClass("java/lang/Thread");
3220    ///         let thread_constructor = env.GetMethodID(thread_class, "<init>", "()V");
3221    ///
3222    ///         // Create a new java thread handle.
3223    ///         let virgin_thread = env.NewObject0(thread_class, thread_constructor);
3224    ///         // Customize your thread here as needed using jni. (set_name for example)
3225    ///
3226    ///         eprintln!("JVMTI Agent thread {:?}", std::thread::current().id());
3227    ///
3228    ///         jvmti.RunAgentThread_fn(virgin_thread, 1, |jvmti, env| {
3229    ///             eprintln!("JVMTI Agent thread {:?}", std::thread::current().id());
3230    ///             //...
3231    ///         }).expect("Failed to start agent thread");
3232    ///     }
3233    /// }
3234    /// ```
3235    ///
3236    pub unsafe fn RunAgentThread_fn(&self, thread: jthread, priority: jint, proc: impl FnOnce(Self, JNIEnv) + 'static + Send + Sync) -> jvmtiError {
3237        extern "system" fn agent_new_thread_wrapper_shim(jvmti: JVMTIEnv, env: JNIEnv, arg: *mut c_void) {
3238            // SAFETY: As long as the jvm passes us the pointer we gave it
3239            // and doesnt call this function in case of it returning an error we should be good.
3240            // Both of those assumptions are fair for any properly implemented jvm.
3241            unsafe { Box::from_raw(arg.cast::<Box<dyn FnOnce(JVMTIEnv, JNIEnv) + 'static + Send + Sync>>())(jvmti, env) };
3242        }
3243
3244        unsafe {
3245            let boxed = Box::new(proc) as Box<dyn FnOnce(Self, JNIEnv) + 'static + Send + Sync>;
3246            //We must double box it because otherwise we run into compiler error E0277.
3247            let raw_box = Box::into_raw(Box::new(boxed));
3248            let err = self.RunAgentThread(thread, agent_new_thread_wrapper_shim, raw_box.cast(), priority);
3249            if err.is_ok() {
3250                //No error we asssume agent_new_thread_wrapper_shim was or is going to be invoked.
3251                return err;
3252            }
3253
3254            // Reclaim the memory in case of error.
3255            // SAFETY: We assume the jvm did not call agent_new_thread_wrapper_shim with this pointer in case of error.
3256            _ = Box::from_raw(raw_box);
3257
3258            err
3259        }
3260    }
3261
3262    /// The VM stores a pointer value associated with each environment-thread pair.
3263    ///
3264    /// This pointer value is called thread-local storage.
3265    ///
3266    /// This value is null unless set with this function. Agents can allocate memory in which they store thread specific information.
3267    /// By setting thread-local storage it can then be accessed with `GetThreadLocalStorage`.
3268    /// This function is called by the agent to set the value of the JVM TI thread-local storage.
3269    /// JVM TI supplies to the agent a pointer-size thread-local storage that can be used to record per-thread information.
3270    ///
3271    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetThreadLocalStorage>
3272    ///
3273    /// # Safety
3274    /// `thread` must refer to a valid strong reference to a thread.
3275    ///
3276    pub unsafe fn SetThreadLocalStorage(&self, thread: jthread, data: *mut c_void) -> jvmtiError {
3277        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, *const c_void) -> jvmtiError>(102)(self.vtable, thread, data) }
3278    }
3279
3280    /// Called by the agent to get the value of the JVM TI thread-local storage.
3281    ///
3282    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetThreadLocalStorage>
3283    ///
3284    /// # Safety
3285    /// `thread` must refer to a valid strong reference to a thread.
3286    /// `data_ptr` must not be dangling.
3287    ///
3288    pub unsafe fn GetThreadLocalStorage(&self, thread: jthread, data_ptr: *mut *mut c_void) -> jvmtiError {
3289        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, *mut *mut c_void) -> jvmtiError>(101)(self.vtable, thread, data_ptr) }
3290    }
3291
3292    /// Return all top-level (parentless) thread groups in the VM.
3293    ///
3294    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetTopThreadGroups>
3295    ///
3296    /// # Safety
3297    /// all pointer parameters must not be dangling.
3298    ///
3299    pub unsafe fn GetTopThreadGroups(&self, group_count_ptr: *mut jint, groups_ptr: *mut *mut jthreadGroup) -> jvmtiError {
3300        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jint, *mut *mut jthreadGroup) -> jvmtiError>(12)(self.vtable, group_count_ptr, groups_ptr) }
3301    }
3302
3303    /// Return all top-level (parentless) thread groups in the VM.
3304    ///
3305    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetThreadGroupInfo>
3306    ///
3307    /// # Safety
3308    /// all pointer parameters must not be dangling.
3309    ///
3310    pub unsafe fn GetThreadGroupInfo(&self, group: jthreadGroup, info_ptr: *mut jvmtiThreadGroupInfo) -> jvmtiError {
3311        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthreadGroup, *mut jvmtiThreadGroupInfo) -> jvmtiError>(13)(self.vtable, group, info_ptr) }
3312    }
3313
3314    /// Get the live platform threads and the child thread groups in this thread group. Virtual threads are not returned by this function.
3315    ///
3316    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetThreadGroupChildren>
3317    ///
3318    /// # Safety
3319    /// all pointer parameters must not be dangling.
3320    ///
3321    pub unsafe fn GetThreadGroupChildren(
3322        &self,
3323        group: jthreadGroup,
3324        thread_count_ptr: *mut jint,
3325        threads_ptr: *mut *mut jthread,
3326        group_count_ptr: *mut jint,
3327        groups_ptr: *mut *mut jthreadGroup,
3328    ) -> jvmtiError {
3329        unsafe {
3330            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthreadGroup, *mut jint, *mut *mut jthread, *mut jint, *mut *mut jthreadGroup) -> jvmtiError>(14)(
3331                self.vtable,
3332                group,
3333                thread_count_ptr,
3334                threads_ptr,
3335                group_count_ptr,
3336                groups_ptr,
3337            )
3338        }
3339    }
3340
3341    /// Returns via `capabilities_ptr` the JVM TI features that can potentially be possessed by this environment at this time.
3342    /// The returned capabilities differ from the complete set of capabilities implemented by the VM in two cases:
3343    /// * another environment possesses capabilities that can only be possessed by one environment
3344    /// * the current phase is live, and certain capabilities can only be added during the `OnLoad` phase.
3345    ///
3346    /// The `AddCapabilities` function may be used to set any or all or these capabilities.
3347    /// Currently possessed capabilities are included.
3348    ///
3349    /// Typically this function is used in the `OnLoad` function.
3350    /// Some virtual machines may allow a limited set of capabilities to be added in the live phase.
3351    /// In this case, the set of potentially available capabilities will likely differ from the `OnLoad` phase set.
3352    ///
3353    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetPotentialCapabilities>
3354    ///
3355    /// # Safety
3356    /// `capabilities_ptr` pointer must not be dangling.
3357    ///
3358    pub unsafe fn GetPotentialCapabilities(&self, capabilities_ptr: *mut jvmtiCapabilities) -> jvmtiError {
3359        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jvmtiCapabilities) -> jvmtiError>(139)(self.vtable, capabilities_ptr) }
3360    }
3361
3362    /// Returns via `capabilities_ptr` the optional JVM TI features which this environment currently possesses.
3363    ///
3364    /// Each possessed capability is indicated by a one (1) in the corresponding bitfield of the capabilities structure.
3365    /// An environment does not possess a capability unless it has been successfully added with `AddCapabilities`.
3366    /// An environment only loses possession of a capability if it has been relinquished with `RelinquishCapabilities`.
3367    /// Thus, this function returns the net result of the `AddCapabilities` and `RelinquishCapabilities` calls which have been made.
3368    ///
3369    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetPotentialCapabilities>
3370    ///
3371    /// # Safety
3372    /// `capabilities_ptr` pointer must not be dangling.
3373    ///
3374    pub unsafe fn GetCapabilities(&self, capabilities_ptr: *mut jvmtiCapabilities) -> jvmtiError {
3375        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jvmtiCapabilities) -> jvmtiError>(88)(self.vtable, capabilities_ptr) }
3376    }
3377
3378    /// Set new capabilities by adding the capabilities whose values are set to one in `capabilities_ptr`.
3379    /// All previous capabilities are retained.
3380    /// Typically this function is used in the `OnLoad` function.
3381    /// Some virtual machines may allow a limited set of capabilities to be added in the live phase.
3382    ///
3383    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#AddCapabilities>
3384    ///
3385    /// # Safety
3386    /// `capabilities_ptr` pointer must not be dangling.
3387    ///
3388    pub unsafe fn AddCapabilities(&self, capabilities_ptr: *const jvmtiCapabilities) -> jvmtiError {
3389        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const jvmtiCapabilities) -> jvmtiError>(141)(self.vtable, capabilities_ptr) }
3390    }
3391
3392    /// Relinquish the capabilities whose values are set to one in `capabilities_ptr`.
3393    ///
3394    /// Some implementations may allow only one environment to have a capability.
3395    /// This function releases capabilities so that they may be used by other agents.
3396    /// All other capabilities are retained. The capability will no longer be present in `GetCapabilities`.
3397    /// Attempting to relinquish a capability that the agent does not possess is not an error.
3398    ///
3399    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#AddCapabilities>
3400    ///
3401    /// # Safety
3402    /// `capabilities_ptr` pointer must not be dangling.
3403    pub unsafe fn RelinquishCapabilities(&self, capabilities_ptr: *const jvmtiCapabilities) -> jvmtiError {
3404        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const jvmtiCapabilities) -> jvmtiError>(142)(self.vtable, capabilities_ptr) }
3405    }
3406
3407    /// Get the number of frames currently in the specified thread's call stack.
3408    ///
3409    /// If this function is called for a thread actively executing bytecodes
3410    /// (for example, not the current thread and not suspended),
3411    /// the information returned is transient.
3412    ///
3413    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetFrameCount>
3414    ///
3415    /// # Safety
3416    /// `count_ptr` pointer must not be dangling.
3417    pub unsafe fn GetFrameCount(&self, thread: jthread, count_ptr: *mut jint) -> jvmtiError {
3418        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, *mut jint) -> jvmtiError>(15)(self.vtable, thread, count_ptr) }
3419    }
3420
3421    /// Pop the current frame of thread's stack. Popping a frame takes you to the previous frame.
3422    ///
3423    /// When the thread is resumed, the execution state of the thread is reset to the state immediately before the called method was invoked.
3424    /// * the current frame is discarded as the previous frame becomes the current one
3425    /// * the operand stack is restored--the argument values are added back and if the invoke was not invokestatic, objectref is added back as well
3426    /// * the Java virtual machine PC is restored to the opcode of the invoke instruction
3427    ///
3428    /// Note however, that any changes to the arguments, which occurred in the called method, remain; when execution continues, the first instruction to execute will be the invoke.
3429    /// Between calling `PopFrame` and resuming the thread the state of the stack is undefined. To pop frames beyond the first, these three steps must be repeated:
3430    /// * suspend the thread via an event (step, breakpoint, ...)
3431    /// * call `PopFrame`
3432    /// * resume the thread
3433    ///
3434    /// A lock acquired by calling the called method (if it is a synchronized method)
3435    /// and locks acquired by entering synchronized blocks within the called method are released.
3436    /// Note: this does not apply to native locks or java.util.concurrent.locks locks.
3437    ///
3438    /// Finally blocks are not executed.
3439    /// Changes to global state are not addressed and thus remain changed.
3440    /// The specified thread must be suspended or must be the current thread.
3441    /// Both the called method and calling method must be non-native Java programming language methods.
3442    /// No JVM TI events are generated by this function.
3443    ///
3444    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#PopFrame>
3445    ///
3446    /// # Safety
3447    /// `thread` must refer to a valid strong reference to a thread.
3448    pub unsafe fn PopFrame(&self, thread: jthread) -> jvmtiError {
3449        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread) -> jvmtiError>(79)(self.vtable, thread) }
3450    }
3451
3452    /// For a Java programming language frame, return the location of the instruction currently executing.
3453    ///
3454    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetFrameLocation>
3455    ///
3456    /// # Safety
3457    /// `method_ptr` and `location_ptr` pointer must not be dangling.
3458    pub unsafe fn GetFrameLocation(&self, thread: jthread, depth: jint, method_ptr: *mut jmethodID, location_ptr: *mut jlocation) -> jvmtiError {
3459        unsafe {
3460            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, *mut jmethodID, *mut jlocation) -> jvmtiError>(18)(self.vtable, thread, depth, method_ptr, location_ptr)
3461        }
3462    }
3463
3464    /// When the frame that is currently at depth is popped from the stack,
3465    /// generate a `FramePop` event. See the `FramePop` event for details.
3466    /// Only frames corresponding to non-native Java programming language methods can receive notification.
3467    ///
3468    /// The specified thread must be suspended or must be the current thread.
3469    ///
3470    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#NotifyFramePop>
3471    ///
3472    /// # Safety
3473    /// `thread` must refer to a valid strong reference to a thread.
3474    pub unsafe fn NotifyFramePop(&self, thread: jthread, depth: jint) -> jvmtiError {
3475        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint) -> jvmtiError>(19)(self.vtable, thread, depth) }
3476    }
3477
3478    /// This function can be used to return from a method whose result type is Object or a subclass of Object.
3479    ///
3480    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ForceEarlyReturnObject>
3481    ///
3482    /// # Safety
3483    /// `thread` must refer to a valid strong reference to a thread.
3484    /// `value` must be a valid strong reference to a object or null.
3485    pub unsafe fn ForceEarlyReturnObject(&self, thread: jthread, value: jobject) -> jvmtiError {
3486        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jobject) -> jvmtiError>(80)(self.vtable, thread, value) }
3487    }
3488
3489    /// This function can be used to return from a method whose result type is int, short, char, byte, or boolean.
3490    ///
3491    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ForceEarlyReturnInt>
3492    ///
3493    /// # Safety
3494    /// `thread` must refer to a valid strong reference to a thread.
3495    pub unsafe fn ForceEarlyReturnInt(&self, thread: jthread, value: jint) -> jvmtiError {
3496        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint) -> jvmtiError>(81)(self.vtable, thread, value) }
3497    }
3498
3499    /// This function can be used to return from a method whose result type is long.
3500    ///
3501    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ForceEarlyReturnLong>
3502    ///
3503    /// # Safety
3504    /// `thread` must refer to a valid strong reference to a thread.
3505    pub unsafe fn ForceEarlyReturnLong(&self, thread: jthread, value: jlong) -> jvmtiError {
3506        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jlong) -> jvmtiError>(82)(self.vtable, thread, value) }
3507    }
3508
3509    /// This function can be used to return from a method whose result type is float.
3510    ///
3511    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ForceEarlyReturnFloat>
3512    ///
3513    /// # Safety
3514    /// `thread` must refer to a valid strong reference to a thread.
3515    pub unsafe fn ForceEarlyReturnFloat(&self, thread: jthread, value: jfloat) -> jvmtiError {
3516        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jfloat) -> jvmtiError>(83)(self.vtable, thread, value) }
3517    }
3518
3519    /// This function can be used to return from a method whose result type is double.
3520    ///
3521    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ForceEarlyReturnDouble>
3522    ///
3523    /// # Safety
3524    /// `thread` must refer to a valid strong reference to a thread.
3525    pub unsafe fn ForceEarlyReturnDouble(&self, thread: jthread, value: jdouble) -> jvmtiError {
3526        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jdouble) -> jvmtiError>(84)(self.vtable, thread, value) }
3527    }
3528
3529    /// This function can be used to return from a method with no result type. That is, the called method must be declared void.
3530    ///
3531    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ForceEarlyReturnVoid>
3532    ///
3533    /// # Safety
3534    /// `thread` must refer to a valid strong reference to a thread.
3535    pub unsafe fn ForceEarlyReturnVoid(&self, thread: jthread) -> jvmtiError {
3536        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread) -> jvmtiError>(85)(self.vtable, thread) }
3537    }
3538
3539    /// This function initiates a traversal over the objects that are directly and indirectly reachable from the specified object or, if `initial_object` is not specified, all objects reachable from the heap roots.
3540    ///
3541    /// The heap root are the set of system classes, JNI globals, references from platform thread stacks, and other objects used as roots for the purposes of garbage collection.
3542    ///
3543    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#FollowReferences>
3544    ///
3545    /// # Safety
3546    /// `klass` must be a valid strong reference to a class.
3547    /// `inital_object` must be a valid strong reference to a object.
3548    /// `callbacks` must not be a dangling pointer.
3549    pub unsafe fn FollowReferences(&self, heap_filter: jint, klass: jclass, initial_object: jobject, callbacks: *const jvmtiHeapCallbacks, user_data: *const c_void) -> jvmtiError {
3550        unsafe {
3551            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, jclass, jobject, *const jvmtiHeapCallbacks, *const c_void) -> jvmtiError>(114)(
3552                self.vtable,
3553                heap_filter,
3554                klass,
3555                initial_object,
3556                callbacks,
3557                user_data,
3558            )
3559        }
3560    }
3561
3562    /// Initiate an iteration over all objects in the heap. This includes both reachable and unreachable objects.
3563    ///
3564    /// Objects are visited in no particular order.
3565    ///
3566    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IterateThroughHeap>
3567    ///
3568    /// # Safety
3569    /// `klass` must refer to a valid strong reference to a class.
3570    /// `callbacks` must not be a dangling pointer.
3571    pub unsafe fn IterateThroughHeap(&self, heap_filter: jint, klass: jclass, callbacks: *const jvmtiHeapCallbacks, user_data: *const c_void) -> jvmtiError {
3572        unsafe {
3573            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, jclass, *const jvmtiHeapCallbacks, *const c_void) -> jvmtiError>(115)(
3574                self.vtable,
3575                heap_filter,
3576                klass,
3577                callbacks,
3578                user_data,
3579            )
3580        }
3581    }
3582
3583    /// Retrieve the tag associated with an object.
3584    ///
3585    /// The tag is a long value typically used to store a unique identifier or pointer to object information.
3586    /// The tag is set with `SetTag`. Objects for which no tags have been set return a tag value of zero.
3587    ///
3588    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetTag>
3589    ///
3590    /// # Safety
3591    /// `object` must refer to a valid strong reference to a class.
3592    /// `tag_ptr` must not be a dangling pointer.
3593    pub unsafe fn GetTag(&self, object: jobject, tag_ptr: *mut jlong) -> jvmtiError {
3594        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, *mut jlong) -> jvmtiError>(105)(self.vtable, object, tag_ptr) }
3595    }
3596
3597    /// Set the tag associated with an object.
3598    /// The tag is a long value typically used to store a unique identifier or pointer to object information.
3599    /// The tag is visible with `GetTag`.
3600    ///
3601    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetTag>
3602    ///
3603    /// # Safety
3604    /// `object` must refer to a valid strong reference to a class.
3605    pub unsafe fn SetTag(&self, object: jobject, tag: jlong) -> jvmtiError {
3606        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, jlong) -> jvmtiError>(106)(self.vtable, object, tag) }
3607    }
3608
3609    /// Return objects in the heap with the specified tags.
3610    ///
3611    /// The format is parallel arrays of objects and tags.
3612    ///
3613    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetObjectsWithTags>
3614    ///
3615    /// # Safety
3616    /// all pointer arguments must not be dangling.
3617    /// `tags` and `tag_count` must form a valid array.
3618    pub unsafe fn GetObjectsWithTags(
3619        &self,
3620        tag_count: jint,
3621        tags: *const jlong,
3622        count_ptr: *mut jint,
3623        object_result_ptr: *mut *mut jobject,
3624        tag_result_ptr: *mut *mut jlong,
3625    ) -> jvmtiError {
3626        unsafe {
3627            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, *const jlong, *mut jint, *mut *mut jobject, *mut *mut jlong) -> jvmtiError>(113)(
3628                self.vtable,
3629                tag_count,
3630                tags,
3631                count_ptr,
3632                object_result_ptr,
3633                tag_result_ptr,
3634            )
3635        }
3636    }
3637
3638    /// Force the VM to perform a garbage collection.
3639    ///
3640    /// The garbage collection is as complete as possible.
3641    /// This function does not cause finalizers to be run.
3642    /// This function does not return until the garbage collection is finished.
3643    ///
3644    /// Although garbage collection is as complete as possible there is no guarantee
3645    /// that all `ObjectFree` events will have been sent by the time that this function returns.
3646    /// In particular, an object may be prevented from being freed because it is awaiting finalization.
3647    ///
3648    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ForceGarbageCollection>
3649    ///
3650    /// # Safety
3651    /// JVM Implementation dependant
3652    pub unsafe fn ForceGarbageCollection(&self) -> jvmtiError {
3653        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable) -> jvmtiError>(107)(self.vtable) }
3654    }
3655
3656    /// This function iterates over all objects that are directly and indirectly reachable from the specified object.
3657    ///
3658    /// For each object A (known as the referrer) with a reference to object B the specified callback function is called to describe the object reference.
3659    /// The callback is called exactly once for each reference from a referrer; this is true even if there are reference cycles or multiple paths to the referrer.
3660    /// There may be more than one reference between a referrer and a referree, These may be distinguished by the `jvmtiObjectReferenceCallback.reference_kind` and `jvmtiObjectReferenceCallback.referrer_index`.
3661    /// The callback for an object will always occur after the callback for its referrer.
3662    ///
3663    /// See `FollowReferences` for the object references which are reported.
3664    /// During the execution of this function the state of the heap does not change: no objects are allocated, no objects are garbage collected, and the state of objects (including held values) does not change.
3665    /// As a result, threads executing Java programming language code, threads attempting to resume the execution of Java programming language code, and threads attempting to execute JNI functions are typically stalled.
3666    ///
3667    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IterateOverObjectsReachableFromObject>
3668    ///
3669    /// # Safety
3670    /// `object_reference_callback` must be valid.
3671    /// `object` must be a valid strong reference to a object.
3672    #[deprecated(
3673        note = "This function was introduced in the original JVM TI version 1.0. It has been superseded in JVM TI version 1.2 (Java SE 6) and will be changed to return an error in a future release."
3674    )]
3675    pub unsafe fn IterateOverObjectsReachableFromObject(&self, object: jobject, object_reference_callback: jvmtiObjectReferenceCallback, user_data: *const c_void) -> jvmtiError {
3676        unsafe {
3677            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, jvmtiObjectReferenceCallback, *const c_void) -> jvmtiError>(108)(
3678                self.vtable,
3679                object,
3680                object_reference_callback,
3681                user_data,
3682            )
3683        }
3684    }
3685
3686    /// This function iterates over the root objects and all objects that are directly and indirectly reachable from the root objects.
3687    ///
3688    /// The root objects comprise the set of system classes, JNI globals, references from platform thread stacks,
3689    /// and other objects used as roots for the purposes of garbage collection.
3690    ///
3691    /// For each root the `heap_root_callback` or `stack_ref_callback` callback is called.
3692    /// An object can be a root object for more than one reason and in that case the appropriate callback is called for each reason.
3693    ///
3694    /// For each object reference the `object_ref_callback` callback function is called to describe the object reference.
3695    /// The callback is called exactly once for each reference from a referrer.
3696    /// This is true even if there are reference cycles or multiple paths to the referrer.
3697    /// There may be more than one reference between a referrer and a referree,
3698    /// These may be distinguished by the `jvmtiObjectReferenceCallback.reference_kind` and `jvmtiObjectReferenceCallback.referrer_index`.
3699    /// The callback for an object will always occur after the callback for its referrer.
3700    ///
3701    /// See `FollowReferences` for the object references which are reported.
3702    ///
3703    /// Roots are always reported to the profiler before any object references are reported.
3704    /// In other words, the `object_ref_callback` callback will not be called until the appropriate callback has been called for all roots.
3705    /// If the `object_ref_callback` callback is specified as null then this function returns after reporting the root objects to the profiler.
3706    ///
3707    /// During the execution of this function the state of the heap does not change: no objects are allocated,
3708    /// no objects are garbage collected, and the state of objects (including held values) does not change.
3709    /// As a result, threads executing Java programming language code,
3710    /// threads attempting to resume the execution of Java programming language code,
3711    /// and threads attempting to execute JNI functions are typically stalled.
3712    ///
3713    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IterateOverReachableObjects>
3714    ///
3715    /// # Safety
3716    /// the callback functions must be valid.
3717    #[deprecated(
3718        note = "This function was introduced in the original JVM TI version 1.0. It has been superseded in JVM TI version 1.2 (Java SE 6) and will be changed to return an error in a future release."
3719    )]
3720    pub unsafe fn IterateOverReachableObjects(
3721        &self,
3722        heap_root_callback: Option<jvmtiHeapRootCallback>,
3723        stack_ref_callback: Option<jvmtiStackReferenceCallback>,
3724        object_ref_callback: Option<jvmtiObjectReferenceCallback>,
3725        user_data: *const c_void,
3726    ) -> jvmtiError {
3727        unsafe {
3728            self.jvmti::<extern "system" fn(
3729                JVMTIEnvVTable,
3730                Option<jvmtiHeapRootCallback>,
3731                Option<jvmtiStackReferenceCallback>,
3732                Option<jvmtiObjectReferenceCallback>,
3733                *const c_void,
3734            ) -> jvmtiError>(109)(self.vtable, heap_root_callback, stack_ref_callback, object_ref_callback, user_data)
3735        }
3736    }
3737
3738    /// Iterate over all objects in the heap. This includes both reachable and unreachable objects.
3739    ///
3740    /// The `object_filter` parameter indicates the objects for which the callback function is called.
3741    ///
3742    /// If this parameter is `JVMTI_HEAP_OBJECT_TAGGED` then the callback will only be called for every object that is tagged.
3743    ///
3744    /// If the parameter is `JVMTI_HEAP_OBJECT_UNTAGGED` then the callback will only be for objects that are not tagged.
3745    ///
3746    /// If the parameter is `JVMTI_HEAP_OBJECT_EITHER` then the callback will be called for every object in the heap, irrespective of whether it is tagged or not.
3747    /// During the execution of this function the state of the heap does not change: no objects are allocated, no objects are garbage collected,
3748    /// and the state of objects (including held values) does not change.
3749    ///
3750    /// As a result, threads executing Java programming language code, threads attempting to resume the execution of Java programming language code,
3751    /// and threads attempting to execute JNI functions are typically stalled.
3752    ///
3753    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IterateOverHeap>
3754    ///
3755    /// # Safety
3756    /// the callback functions must be valid.
3757    #[deprecated(
3758        note = "This function was introduced in the original JVM TI version 1.0. It has been superseded in JVM TI version 1.2 (Java SE 6) and will be changed to return an error in a future release."
3759    )]
3760    pub unsafe fn IterateOverHeap(&self, object_filter: jvmtiHeapObjectFilter, heap_object_callback: jvmtiHeapObjectCallback, user_data: *const c_void) -> jvmtiError {
3761        unsafe {
3762            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jvmtiHeapObjectFilter, jvmtiHeapObjectCallback, *const c_void) -> jvmtiError>(110)(
3763                self.vtable,
3764                object_filter,
3765                heap_object_callback,
3766                user_data,
3767            )
3768        }
3769    }
3770
3771    /// Iterate over all objects in the heap that are instances of the specified class.
3772    ///
3773    /// This includes direct instances of the specified class and instances of all subclasses of the specified class.
3774    /// This includes both reachable and unreachable objects.
3775    ///
3776    /// The `object_filter` parameter indicates the objects for which the callback function is called.
3777    ///
3778    /// If this parameter is `JVMTI_HEAP_OBJECT_TAGGED` then the callback will only be called for every object that is tagged.
3779    ///
3780    /// If the parameter is `JVMTI_HEAP_OBJECT_UNTAGGED` then the callback will only be called for objects that are not tagged.
3781    ///
3782    /// If the parameter is `JVMTI_HEAP_OBJECT_EITHER` then the callback will be called for every object in the heap, irrespective of whether it is tagged or not.
3783    ///
3784    /// During the execution of this function the state of the heap does not change: no objects are allocated, no objects are garbage collected, and the state of objects (including held values) does not change.
3785    /// As a result, threads executing Java programming language code, threads attempting to resume the execution of Java programming language code, and threads attempting to execute JNI functions are typically stalled.
3786    ///
3787    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IterateOverInstancesOfClass>
3788    ///
3789    /// # Safety
3790    /// the callback functions must be valid.
3791    /// `klaas` parameter must be a valid strong reference.
3792    #[deprecated(
3793        note = "This function was introduced in the original JVM TI version 1.0. It has been superseded in JVM TI version 1.2 (Java SE 6) and will be changed to return an error in a future release."
3794    )]
3795    pub unsafe fn IterateOverInstancesOfClass(
3796        &self,
3797        klass: jclass,
3798        object_filter: jvmtiHeapObjectFilter,
3799        heap_object_callback: jvmtiHeapObjectCallback,
3800        user_data: *const c_void,
3801    ) -> jvmtiError {
3802        unsafe {
3803            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, jvmtiHeapObjectFilter, jvmtiHeapObjectCallback, *const c_void) -> jvmtiError>(111)(
3804                self.vtable,
3805                klass,
3806                object_filter,
3807                heap_object_callback,
3808                user_data,
3809            )
3810        }
3811    }
3812
3813    /// This function can be used to retrieve the value of a local variable whose type is Object or a subclass of Object.
3814    ///
3815    /// The specified thread must be suspended or must be the current thread.
3816    ///
3817    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetLocalObject>
3818    ///
3819    /// # Safety
3820    /// `thread` is a valid strong reference to a thread.
3821    /// `value_ptr` is not a dangling pointer.
3822    pub unsafe fn GetLocalObject(&self, thread: jthread, depth: jint, slot: jint, value_ptr: *mut jobject) -> jvmtiError {
3823        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, *mut jobject) -> jvmtiError>(20)(self.vtable, thread, depth, slot, value_ptr) }
3824    }
3825
3826    /// This function can be used to retrieve the value of the local object variable at slot 0 (the "this" object) from non-static frames.
3827    ///
3828    /// This function can retrieve the "this" object from native method frames, whereas `GetLocalObject()` would return `JVMTI_ERROR_OPAQUE_FRAME` in those cases.
3829    /// The specified thread must be suspended or must be the current thread.
3830    ///
3831    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetLocalInstance>
3832    ///
3833    /// # Safety
3834    /// `thread` is a valid strong reference to a thread.
3835    /// `value_ptr` is not a dangling pointer.
3836    pub unsafe fn GetLocalInstance(&self, thread: jthread, depth: jint, value_ptr: *mut jobject) -> jvmtiError {
3837        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, *mut jobject) -> jvmtiError>(154)(self.vtable, thread, depth, value_ptr) }
3838    }
3839
3840    /// This function can be used to retrieve the value of a local variable whose type is int, short, char, byte, or boolean.
3841    ///
3842    /// The specified thread must be suspended or must be the current thread.
3843    ///
3844    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetLocalInt>
3845    ///
3846    /// # Safety
3847    /// `thread` is a valid strong reference to a thread.
3848    /// `value_ptr` is not a dangling pointer.
3849    pub unsafe fn GetLocalInt(&self, thread: jthread, depth: jint, slot: jint, value_ptr: *mut jint) -> jvmtiError {
3850        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, *mut jint) -> jvmtiError>(21)(self.vtable, thread, depth, slot, value_ptr) }
3851    }
3852
3853    /// This function can be used to retrieve the value of a local variable whose type is long.
3854    ///
3855    /// The specified thread must be suspended or must be the current thread.
3856    ///
3857    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetLocalLong>
3858    ///
3859    /// # Safety
3860    /// `thread` is a valid strong reference to a thread.
3861    /// `value_ptr` is not a dangling pointer.
3862    pub unsafe fn GetLocalLong(&self, thread: jthread, depth: jint, slot: jint, value_ptr: *mut jlong) -> jvmtiError {
3863        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, *mut jlong) -> jvmtiError>(22)(self.vtable, thread, depth, slot, value_ptr) }
3864    }
3865
3866    /// This function can be used to retrieve the value of a local variable whose type is float.
3867    ///
3868    /// The specified thread must be suspended or must be the current thread.
3869    ///
3870    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetLocalFloat>
3871    ///
3872    /// # Safety
3873    /// `thread` is a valid strong reference to a thread.
3874    /// `value_ptr` is not a dangling pointer.
3875    pub unsafe fn GetLocalFloat(&self, thread: jthread, depth: jint, slot: jint, value_ptr: *mut jfloat) -> jvmtiError {
3876        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, *mut jfloat) -> jvmtiError>(23)(self.vtable, thread, depth, slot, value_ptr) }
3877    }
3878
3879    /// This function can be used to retrieve the value of a local variable whose type is double.
3880    ///
3881    /// The specified thread must be suspended or must be the current thread.
3882    ///
3883    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetLocalDouble>
3884    ///
3885    /// # Safety
3886    /// `thread` is a valid strong reference to a thread.
3887    /// `value_ptr` is not a dangling pointer.
3888    pub unsafe fn GetLocalDouble(&self, thread: jthread, depth: jint, slot: jint, value_ptr: *mut jdouble) -> jvmtiError {
3889        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, *mut jdouble) -> jvmtiError>(24)(self.vtable, thread, depth, slot, value_ptr) }
3890    }
3891
3892    /// This function can be used to set the value of a local variable whose type is Object or a subclass of Object.
3893    ///
3894    /// The specified thread must be suspended or must be the current thread.
3895    ///
3896    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetLocalObject>
3897    ///
3898    /// # Safety
3899    /// `thread` is a valid strong reference to a thread.
3900    /// `value` is a valid strong reference or null.
3901    pub unsafe fn SetLocalObject(&self, thread: jthread, depth: jint, slot: jint, value: jobject) -> jvmtiError {
3902        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, jobject) -> jvmtiError>(25)(self.vtable, thread, depth, slot, value) }
3903    }
3904
3905    /// This function can be used to set the value of a local variable whose type is int, short, char, byte, or boolean.
3906    ///
3907    /// The specified thread must be suspended or must be the current thread.
3908    ///
3909    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetLocalInt>
3910    ///
3911    /// # Safety
3912    /// `thread` is a valid strong reference to a thread.
3913    pub unsafe fn SetLocalInt(&self, thread: jthread, depth: jint, slot: jint, value: jint) -> jvmtiError {
3914        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, jint) -> jvmtiError>(26)(self.vtable, thread, depth, slot, value) }
3915    }
3916
3917    /// This function can be used to set the value of a local variable whose type is long.
3918    ///
3919    /// The specified thread must be suspended or must be the current thread.
3920    ///
3921    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetLocalLong>
3922    ///
3923    /// # Safety
3924    /// `thread` is a valid strong reference to a thread.
3925    pub unsafe fn SetLocalLong(&self, thread: jthread, depth: jint, slot: jint, value: jlong) -> jvmtiError {
3926        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, jlong) -> jvmtiError>(27)(self.vtable, thread, depth, slot, value) }
3927    }
3928
3929    /// This function can be used to set the value of a local variable whose type is float.
3930    ///
3931    /// The specified thread must be suspended or must be the current thread.
3932    ///
3933    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetLocalFloat>
3934    ///
3935    /// # Safety
3936    /// `thread` is a valid strong reference to a thread.
3937    pub unsafe fn SetLocalFloat(&self, thread: jthread, depth: jint, slot: jint, value: jfloat) -> jvmtiError {
3938        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, jfloat) -> jvmtiError>(28)(self.vtable, thread, depth, slot, value) }
3939    }
3940
3941    /// This function can be used to set the value of a local variable whose type is double.
3942    ///
3943    /// The specified thread must be suspended or must be the current thread.
3944    ///
3945    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetLocalDouble>
3946    ///
3947    /// # Safety
3948    /// `thread` is a valid strong reference to a thread.
3949    pub unsafe fn SetLocalDouble(&self, thread: jthread, depth: jint, slot: jint, value: jdouble) -> jvmtiError {
3950        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, jdouble) -> jvmtiError>(29)(self.vtable, thread, depth, slot, value) }
3951    }
3952
3953    /// Set a breakpoint at the instruction indicated by method and location. An instruction can only have one breakpoint.
3954    /// Whenever the designated instruction is about to be executed, a Breakpoint event is generated.
3955    ///
3956    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetBreakpoint>
3957    ///
3958    /// # Safety
3959    /// `method` must be valid
3960    pub unsafe fn SetBreakpoint(&self, method: jmethodID, location: jlocation) -> jvmtiError {
3961        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, jlocation) -> jvmtiError>(37)(self.vtable, method, location) }
3962    }
3963
3964    /// Clear the breakpoint at the bytecode indicated by method and location.
3965    ///
3966    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ClearBreakpoint>
3967    ///
3968    /// # Safety
3969    /// `method` must be valid
3970    pub unsafe fn ClearBreakpoint(&self, method: jmethodID, location: jlocation) -> jvmtiError {
3971        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, jlocation) -> jvmtiError>(37)(self.vtable, method, location) }
3972    }
3973
3974    /// Generate a `FieldAccess` event when the field specified by klass and field is about to be accessed.
3975    ///
3976    /// An event will be generated for each access of the field until it is canceled with `ClearFieldAccessWatch`.
3977    /// Field accesses from Java programming language code or from JNI code are watched, fields modified by other means are not watched.
3978    /// Note that JVM TI users should be aware that their own field accesses will trigger the watch.
3979    /// A field can only have one field access watch set.
3980    /// Modification of a field is not considered an access--use `SetFieldModificationWatch` to monitor modifications.
3981    ///
3982    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetFieldAccessWatch>
3983    ///
3984    /// # Safety
3985    /// `klass` must be a valid strong reference to a class.
3986    /// `field` must be valid
3987    pub unsafe fn SetFieldAccessWatch(&self, klass: jclass, field: jfieldID) -> jvmtiError {
3988        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, jfieldID) -> jvmtiError>(40)(self.vtable, klass, field) }
3989    }
3990
3991    /// Cancel a field access watch previously set by `SetFieldAccessWatch`, on the field specified by klass and field.
3992    ///
3993    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ClearFieldAccessWatch>
3994    ///
3995    /// # Safety
3996    /// `klass` must be a valid strong reference to a class.
3997    /// `field` must be valid
3998    pub unsafe fn ClearFieldAccessWatch(&self, klass: jclass, field: jfieldID) -> jvmtiError {
3999        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, jfieldID) -> jvmtiError>(41)(self.vtable, klass, field) }
4000    }
4001
4002    /// Cancel a field modification watch previously set by `SetFieldModificationWatch`, on the field specified by klass and field.
4003    ///
4004    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetFieldModificationWatch>
4005    ///
4006    /// # Safety
4007    /// `klass` must be a valid strong reference to a class.
4008    /// `field` must be valid
4009    pub unsafe fn SetFieldModificationWatch(&self, klass: jclass, field: jfieldID) -> jvmtiError {
4010        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, jfieldID) -> jvmtiError>(42)(self.vtable, klass, field) }
4011    }
4012
4013    /// Cancel a field modification watch previously set by `SetFieldModificationWatch`, on the field specified by klass and field.
4014    ///
4015    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ClearFieldModificationWatch>
4016    ///
4017    /// # Safety
4018    /// `klass` must be a valid strong reference to a class.
4019    /// `field` must be valid
4020    pub unsafe fn ClearFieldModificationWatch(&self, klass: jclass, field: jfieldID) -> jvmtiError {
4021        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, jfieldID) -> jvmtiError>(43)(self.vtable, klass, field) }
4022    }
4023
4024    /// Return an array of all modules loaded in the virtual machine.
4025    /// The array includes the unnamed module for each class loader.
4026    /// The number of modules in the array is returned via `module_count_ptr`, and the array itself via `modules_ptr`.
4027    ///
4028    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetAllModules>
4029    ///
4030    /// # Safety
4031    /// all pointer parameters must not be dangling.
4032    pub unsafe fn GetAllModules(&self, module_count_ptr: *mut jint, modules_ptr: *mut *mut jobject) -> jvmtiError {
4033        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jint, *mut *mut jobject) -> jvmtiError>(2)(self.vtable, module_count_ptr, modules_ptr) }
4034    }
4035
4036    ///
4037    /// Return an array of all modules loaded in the virtual machine as a Vec.
4038    /// The array includes the unnamed module for each class loader.
4039    ///
4040    /// This convenience function automatically handles deallocating the memory using the jvmti allocator.
4041    ///
4042    /// # Safety
4043    /// JVM implementation specific
4044    ///
4045    /// # Errors
4046    /// If the call to `GetAllModules` fails.
4047    /// Errors of the JVMTI Deallocator are silently ignored and the memory is leaked.
4048    ///
4049    /// # Panics
4050    /// If JVMTI provides a negative number of modules without returning an error.
4051    /// If JVMTI provides a null array of modules with a count of more than 0 without return return an error.
4052    pub unsafe fn GetAllModules_as_vec(&self) -> Result<Vec<jobject>, jvmtiError> {
4053        unsafe {
4054            let mut count: jsize = 0;
4055            let mut classes_ptr = null_mut();
4056            self.GetAllModules(&raw mut count, &raw mut classes_ptr).into_result()?;
4057
4058            //We dont risk deallocating the array in the panic case.
4059            let count = usize::try_from(count).expect("JVMTI GetAllModules provided an array with a negative number of modules.");
4060            if count == 0 {
4061                if !classes_ptr.is_null() {
4062                    _ = self.Deallocate(classes_ptr);
4063                }
4064                return Ok(Vec::new());
4065            }
4066
4067            assert!(
4068                !classes_ptr.is_null(),
4069                "JVMTI GetAllModules returned a null pointer module array without returning an error"
4070            );
4071
4072            let result = core::slice::from_raw_parts(classes_ptr, count).to_vec();
4073            _ = self.Deallocate(classes_ptr);
4074
4075            Ok(result)
4076        }
4077    }
4078
4079    /// Return the java.lang.Module object for a named module defined to a class loader that contains a given package.
4080    ///
4081    /// The module is returned via `module_ptr`.
4082    /// If a named module is defined to the class loader and it contains the package then that named module is returned, otherwise null is returned.
4083    ///
4084    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetNamedModule>
4085    ///
4086    /// # Safety
4087    /// `class_loader` must be a valid strong reference or null
4088    /// all pointer parameters must not be dangling.
4089    pub unsafe fn GetNamedModule(&self, class_loader: jobject, package_name: impl UseCString, module_ptr: *mut jobject) -> jvmtiError {
4090        unsafe {
4091            package_name.use_as_const_c_char(|package_name| {
4092                self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, *const c_char, *mut jobject) -> jvmtiError>(39)(self.vtable, class_loader, package_name, module_ptr)
4093            })
4094        }
4095    }
4096
4097    /// Update a module to read another module.
4098    ///
4099    /// This function is a no-op when module is an unnamed module.
4100    /// This function facilitates the instrumentation of code in named modules where that instrumentation requires expanding the set of modules that a module reads.
4101    ///
4102    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#AddModuleReads>
4103    ///
4104    /// # Safety
4105    /// `module` must be a valid strong reference or null
4106    /// `to_module` must be a valid strong reference or null
4107    pub unsafe fn AddModuleReads(&self, module: jobject, to_module: jobject) -> jvmtiError {
4108        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, jobject) -> jvmtiError>(93)(self.vtable, module, to_module) }
4109    }
4110
4111    /// Update a module to export a package to another module.
4112    ///
4113    /// This function is a no-op when module is an unnamed module or an open module.
4114    /// This function facilitates the instrumentation of code in named modules where that instrumentation requires expanding the set of packages that a module exports.
4115    ///
4116    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#AddModuleExports>
4117    ///
4118    /// # Safety
4119    /// `module` must be a valid strong reference or null
4120    /// `to_module` must be a valid strong reference or null
4121    /// all pointer parameters must not be dangling.
4122    pub unsafe fn AddModuleExports(&self, module: jobject, pkg_name: impl UseCString, to_module: jobject) -> jvmtiError {
4123        unsafe {
4124            pkg_name.use_as_const_c_char(|pkg_name| {
4125                self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, *const c_char, jobject) -> jvmtiError>(94)(self.vtable, module, pkg_name, to_module)
4126            })
4127        }
4128    }
4129
4130    /// Update a module to open a package to another module.
4131    ///
4132    /// This function is a no-op when module is an unnamed module or an open module.
4133    /// This function facilitates the instrumentation of code in modules where that instrumentation requires expanding the set of packages that a module opens to other modules.
4134    ///
4135    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#AddModuleOpens>
4136    ///
4137    /// # Safety
4138    /// `module` must be a valid strong reference or null
4139    /// `to_module` must be a valid strong reference or null
4140    /// all pointer parameters must not be dangling.
4141    pub unsafe fn AddModuleOpens(&self, module: jobject, pkg_name: impl UseCString, to_module: jobject) -> jvmtiError {
4142        unsafe {
4143            pkg_name.use_as_const_c_char(|pkg_name| {
4144                self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, *const c_char, jobject) -> jvmtiError>(95)(self.vtable, module, pkg_name, to_module)
4145            })
4146        }
4147    }
4148
4149    /// Updates a module to add a service to the set of services that a module uses.
4150    ///
4151    /// This function is a no-op when the module is an unnamed module.
4152    /// This function facilitates the instrumentation of code in named modules where that instrumentation requires expanding the set of services that a module is using.
4153    ///
4154    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#AddModuleUses>
4155    ///
4156    /// # Safety
4157    /// `module` must be a valid strong reference or null
4158    /// `service` must be a valid strong reference or null
4159    pub unsafe fn AddModuleUses(&self, module: jobject, service: jclass) -> jvmtiError {
4160        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, jclass) -> jvmtiError>(96)(self.vtable, module, service) }
4161    }
4162
4163    /// Updates a module to add a service to the set of services that a module provides.
4164    ///
4165    /// This function is a no-op when the module is an unnamed module.
4166    /// This function facilitates the instrumentation of code in named modules where that instrumentation requires changes to the services that are provided.
4167    ///
4168    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#AddModuleProvides>
4169    ///
4170    /// # Safety
4171    /// `module` must be a valid strong reference or null
4172    /// `service` must be a valid strong reference or null
4173    /// `impl_class` must be a valid strong reference or null
4174    pub unsafe fn AddModuleProvides(&self, module: jobject, service: jclass, impl_class: jclass) -> jvmtiError {
4175        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, jclass, jclass) -> jvmtiError>(97)(self.vtable, module, service, impl_class) }
4176    }
4177
4178    /// Determines whether a module is modifiable.
4179    ///
4180    /// If a module is modifiable then this module can be updated with `AddModuleReads`, `AddModuleExports`, `AddModuleOpens`, `AddModuleUses`, and `AddModuleProvides`.
4181    /// If a module is not modifiable then the module can not be updated with these functions.
4182    /// The result of this function is always `JNI_TRUE` when called to determine if an unnamed module is modifiable.
4183    ///
4184    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IsModifiableModule>
4185    ///
4186    /// # Safety
4187    /// `module` must be a valid strong reference or null
4188    /// `service` must be a valid strong reference or null
4189    /// `impl_class` must be a valid strong reference or null
4190    /// `is_modifiable_module_ptr` must not be dangling
4191    pub unsafe fn IsModifiableModule(&self, module: jobject, is_modifiable_module_ptr: impl JBooleanMutPtr) -> jvmtiError {
4192        is_modifiable_module_ptr.use_jboolean_mut(|is_modifiable_module_ptr| unsafe {
4193            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, *mut jboolean) -> jvmtiError>(98)(self.vtable, module, is_modifiable_module_ptr)
4194        })
4195    }
4196
4197    /// Return an array of all classes loaded in the virtual machine.
4198    ///
4199    /// The number of classes in the array is returned via `class_count_ptr`, and the array itself via `classes_ptr`.
4200    ///
4201    /// A class or interface creation can be triggered by one of the following:
4202    /// * By loading and deriving a class from a class file representation using a class loader (see The Java™ Virtual Machine Specification, Chapter 5.3).
4203    /// * By invoking `Lookup::defineHiddenClass` that creates a hidden class or interface from a class file representation.
4204    /// * By invoking methods in certain Java SE Platform APIs such as reflection.
4205    ///
4206    /// An array class is created directly by the Java virtual machine. The creation can be triggered by using class loaders or by invoking methods in certain Java SE Platform APIs such as reflection.
4207    /// The returned list includes all classes and interfaces, including hidden classes or interfaces, and also array classes of all types (including arrays of primitive types). Primitive classes (for example, java.lang.Integer.TYPE) are not included in the returned list.
4208    ///
4209    /// The returned array should be freed with Deallocate. The objects returned by `classes_ptr` are JNI local references and must be managed.
4210    ///
4211    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetLoadedClasses>
4212    ///
4213    /// # Safety
4214    /// all pointer parameters must not be dangling.
4215    pub unsafe fn GetLoadedClasses(&self, count_ptr: *mut jint, classes_ptr: *mut *mut jclass) -> jvmtiError {
4216        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jint, *mut *mut jclass) -> jvmtiError>(77)(self.vtable, count_ptr, classes_ptr) }
4217    }
4218
4219    ///
4220    /// Return a Vec of all classes loaded in the virtual machine.
4221    /// This convenience function will internally call `GetLoadedClasses` and `Deallocate`
4222    /// to manage the JVMTI buffer for you.
4223    ///
4224    /// This function ignores errors returned by the `Deallocate` and just, presumably, leaks the jvmti buffer.
4225    ///
4226    /// A class or interface creation can be triggered by one of the following:
4227    /// * By loading and deriving a class from a class file representation using a class loader (see The Java™ Virtual Machine Specification, Chapter 5.3).
4228    /// * By invoking `Lookup::defineHiddenClass` that creates a hidden class or interface from a class file representation.
4229    /// * By invoking methods in certain Java SE Platform APIs such as reflection.
4230    ///
4231    /// An array class is created directly by the Java virtual machine. The creation can be triggered by using class loaders or by invoking methods in certain Java SE Platform APIs such as reflection.
4232    /// The returned list includes all classes and interfaces, including hidden classes or interfaces, and also array classes of all types (including arrays of primitive types). Primitive classes (for example, java.lang.Integer.TYPE) are not included in the returned list.
4233    ///
4234    /// The objects returned in the `Vec` are JNI local references and must be managed.
4235    ///
4236    /// # Safety
4237    /// JVM implementation specific
4238    ///
4239    /// # Errors
4240    /// If the call to `GetLoadedClasses` fails.
4241    ///
4242    /// # Panics
4243    /// If JVMTI provides a negative number of loaded classes without returning an error.
4244    /// If JVMTI provides a null array of loaded classes with a count of more than 0 without return return an error.
4245    pub unsafe fn GetLoadedClasses_as_vec(&self) -> Result<Vec<jclass>, jvmtiError> {
4246        unsafe {
4247            let mut count: jsize = 0;
4248            let mut classes_ptr = null_mut();
4249            self.GetLoadedClasses(&raw mut count, &raw mut classes_ptr).into_result()?;
4250
4251            //We dont risk deallocating the array in the panic case.
4252            let count = usize::try_from(count).expect("JVMTI provided an array with a negative number of loaded classes.");
4253            if count == 0 {
4254                if !classes_ptr.is_null() {
4255                    _ = self.Deallocate(classes_ptr);
4256                }
4257                return Ok(Vec::new());
4258            }
4259
4260            assert!(!classes_ptr.is_null(), "JVMTI returned a null pointer classes array without returning an error");
4261
4262            let result = core::slice::from_raw_parts(classes_ptr, count).to_vec();
4263            _ = self.Deallocate(classes_ptr);
4264
4265            Ok(result)
4266        }
4267    }
4268
4269    /// Returns an array of all classes which this class loader can find by name via `ClassLoader::loadClass`, `Class::forName` and bytecode linkage.
4270    ///
4271    /// That is, all classes for which `initiating_loader` has been recorded as an initiating loader.
4272    /// Each class in the returned array was created by this class loader, either by defining it directly or by delegation to another class loader.
4273    /// See The Java™ Virtual Machine Specification, Chapter 5.3.
4274    /// The returned list does not include hidden classes or interfaces or array classes whose element type is a hidden class or interface as they cannot be discovered by any class loader.
4275    /// The number of classes in the array is returned via `class_count_ptr`, and the array itself via `classes_ptr`.
4276    /// See `Lookup::defineHiddenClass`.
4277    ///
4278    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetClassLoaderClasses>
4279    ///
4280    /// # Safety
4281    /// `initiating_loader` must be a valid strong reference or null.
4282    /// all pointer parameters must not be dangling.
4283    pub unsafe fn GetClassLoaderClasses(&self, initiating_loader: jobject, count_ptr: *mut jint, classes_ptr: *mut *mut jclass) -> jvmtiError {
4284        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, *mut jint, *mut *mut jclass) -> jvmtiError>(78)(self.vtable, initiating_loader, count_ptr, classes_ptr) }
4285    }
4286
4287    /// Returns an Vec of all classes which this class loader can find by name via `ClassLoader::loadClass`, `Class::forName` and bytecode linkage.
4288    ///
4289    /// This convenience method takes care of deallocating the buffer returned by jvmti using the jvmti allocator.
4290    /// This method silently ignores errors from the jvmti allocator and leaks the memory in that case.
4291    ///
4292    /// That is, all classes for which `initiating_loader` has been recorded as an initiating loader.
4293    /// Each class in the returned array was created by this class loader, either by defining it directly or by delegation to another class loader.
4294    /// See The Java™ Virtual Machine Specification, Chapter 5.3.
4295    /// The returned list does not include hidden classes or interfaces or array classes whose element type is a hidden class or interface as they cannot be discovered by any class loader.
4296    /// The number of classes in the array is returned via `class_count_ptr`, and the array itself via `classes_ptr`.
4297    /// See `Lookup::defineHiddenClass`.
4298    ///
4299    /// # Errors
4300    /// If the call to `GetClassLoaderClasses` fails.
4301    ///
4302    /// # Panics
4303    /// If JVMTI provides a negative number of loaded classes without returning an error.
4304    /// If JVMTI provides a null array of loaded classes with a count of more than 0 without return return an error.
4305    ///
4306    /// # Safety
4307    /// `initiating_loader` must be a valid strong reference or null.
4308    pub unsafe fn GetClassLoaderClasses_as_vec(&self, initiating_loader: jobject) -> Result<Vec<jclass>, jvmtiError> {
4309        unsafe {
4310            let mut count: jsize = 0;
4311            let mut classes_ptr = null_mut();
4312            self.GetClassLoaderClasses(initiating_loader, &raw mut count, &raw mut classes_ptr).into_result()?;
4313
4314            //We dont risk deallocating the array in the panic case.
4315            let count = usize::try_from(count).expect("JVMTI GetClassLoaderClasses provided an array with a negative number of loaded classes.");
4316            if count == 0 {
4317                if !classes_ptr.is_null() {
4318                    _ = self.Deallocate(classes_ptr);
4319                }
4320                return Ok(Vec::new());
4321            }
4322
4323            assert!(
4324                !classes_ptr.is_null(),
4325                "JVMTI GetClassLoaderClasses returned a null pointer classes array without returning an error"
4326            );
4327
4328            let result = core::slice::from_raw_parts(classes_ptr, count).to_vec();
4329            _ = self.Deallocate(classes_ptr);
4330
4331            Ok(result)
4332        }
4333    }
4334
4335    /// Return the name and the generic signature of the class indicated by klass.
4336    ///
4337    /// If the class is a class or interface, then:
4338    /// - If the class or interface is not hidden, then the returned name is the JNI type signature.
4339    ///   For example, java.util.List is "Ljava/util/List;"
4340    /// - If the class or interface is hidden, then the returned name is a string of the form: "L" + N + "." + S + ";"
4341    ///   where N is the binary name encoded in internal form (JVMS 4.2.1) indicated by the class file passed to `Lookup::defineHiddenClass`,
4342    ///   and S is an unqualified name. The returned name is not a type descriptor and does not conform to JVMS 4.3.2.
4343    ///   For example, com.foo.Foo/AnySuffix is "Lcom/foo/Foo.AnySuffix;"
4344    ///
4345    /// If the class indicated by klass represents an array class, then the returned name is a string consisting of one or more "[" characters representing the depth of the array nesting, followed by the class signature of the element type. For example the class signature of java.lang.String[] is "[Ljava/lang/String;" and that of int[] is "[I".
4346    /// If the class indicated by klass represents primitive type or void, then the returned name is the type signature character of the corresponding primitive type. For example, java.lang.Integer.TYPE is "I".
4347    ///
4348    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetClassSignature>
4349    ///
4350    /// # Safety
4351    /// `klass` must be a valid strong reference or null.
4352    /// all pointer parameters must not be dangling.
4353    ///
4354    /// # Example
4355    /// ```rust
4356    /// use jni_simple::*;
4357    /// use std::ptr::null_mut;
4358    /// use std::ffi::CStr;
4359    ///
4360    /// // would return "Ljava/lang/String;" for the string class for ex.
4361    /// fn get_class_name(jvmti: JVMTIEnv, class_or_iface: jclass) -> String {
4362    ///     unsafe {
4363    ///         let mut class_name = null_mut();
4364    ///         assert!(jvmti.GetClassSignature(class_or_iface, &raw mut class_name, null_mut()).is_ok());
4365    ///         //Beware, the string is in CESU encoding which may not work for some class names.
4366    ///         let name : String = CStr::from_ptr(class_name).to_string_lossy().to_string();
4367    ///         assert!(jvmti.Deallocate(class_name).is_ok());
4368    ///         return name;
4369    ///     }
4370    /// }
4371    /// ```
4372    ///
4373    pub unsafe fn GetClassSignature(&self, klass: jclass, signature_ptr: *mut *mut c_char, generic_ptr: *mut *mut c_char) -> jvmtiError {
4374        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut *mut c_char, *mut *mut c_char) -> jvmtiError>(47)(self.vtable, klass, signature_ptr, generic_ptr) }
4375    }
4376
4377    /// Get the status of the class. Zero or more of the following bits can be set.
4378    ///
4379    /// - `JVMTI_CLASS_STATUS_VERIFIED` - Class bytecodes have been verified
4380    /// - `JVMTI_CLASS_STATUS_PREPARED` - Class preparation is complete
4381    /// - `JVMTI_CLASS_STATUS_INITIALIZED` - Class initialization is complete. Static initializer has been run.
4382    /// - `JVMTI_CLASS_STATUS_ERROR` - Error during initialization makes class unusable
4383    /// - `JVMTI_CLASS_STATUS_ARRAY` - Class is an array. If set, all other bits are zero.
4384    /// - `JVMTI_CLASS_STATUS_PRIMITIVE` - Class is a primitive class (for example, java.lang.Integer.TYPE). If set, all other bits are zero.
4385    ///
4386    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetClassStatus>
4387    ///
4388    /// # Safety
4389    /// `klass` must be a valid strong reference or null.
4390    /// `status_ptr` must not be dangling.
4391    ///
4392    /// # Example
4393    /// ```rust
4394    /// use jni_simple::*;
4395    ///
4396    /// fn is_primitive_class(jvmti: JVMTIEnv, klass: jclass) -> bool {
4397    ///     let mut status: jint = 0;
4398    ///     unsafe {
4399    ///         assert!(jvmti.GetClassStatus(klass, &raw mut status).is_ok());
4400    ///     }
4401    ///     status == JVMTI_CLASS_STATUS_PRIMITIVE
4402    /// }
4403    ///
4404    /// ```
4405    pub unsafe fn GetClassStatus(&self, klass: jclass, status_ptr: *mut jint) -> jvmtiError {
4406        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jint) -> jvmtiError>(48)(self.vtable, klass, status_ptr) }
4407    }
4408
4409    /// For the class indicated by klass, return the source file name via `source_name_ptr`.
4410    ///
4411    /// The returned string is a file name only and never contains a directory name.
4412    ///
4413    /// For primitive classes (for example, java.lang.Integer.TYPE) and for arrays this function returns `JVMTI_ERROR_ABSENT_INFORMATION`.
4414    ///
4415    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetSourceFileName>
4416    ///
4417    /// # Safety
4418    /// `klass` must be a valid strong reference or null.
4419    /// `source_name_ptr` must not be dangling.
4420    pub unsafe fn GetSourceFileName(&self, klass: jclass, source_name_ptr: *mut *mut c_char) -> jvmtiError {
4421        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut *mut c_char) -> jvmtiError>(49)(self.vtable, klass, source_name_ptr) }
4422    }
4423
4424    /// For the class indicated by klass, return the source file name as a String.
4425    ///
4426    /// The returned string is a file name only and never contains a directory name.
4427    ///
4428    /// For primitive classes (for example, java.lang.Integer.TYPE) and for arrays this function returns `JVMTI_ERROR_ABSENT_INFORMATION`.
4429    ///
4430    /// This function serves as a convinence wrapper function and automatically handles JVMTI memory for you.
4431    ///
4432    /// # Errors
4433    /// This function will return `Err(JVMTI_ERROR_NONE)` in case the file name contains
4434    /// supplementary characters in CESU-8 encoding. Otherwise Err values always come from the jvm.
4435    ///
4436    /// # Safety
4437    /// `klass` must be a valid strong reference or null.
4438    /// `source_name_ptr` must not be dangling.
4439    pub unsafe fn GetSourceFileName_as_string(&self, klass: jclass) -> Result<String, jvmtiError> {
4440        unsafe {
4441            let mut str = null_mut();
4442            let res = self.GetSourceFileName(klass, &raw mut str);
4443            if !res.is_ok() {
4444                if !str.is_null() {
4445                    _ = self.Deallocate(str);
4446                }
4447                return Err(res);
4448            }
4449
4450            if str.is_null() {
4451                //TODO should we panic here?
4452                return Ok(String::new());
4453            }
4454
4455            let Ok(val) = CStr::from_ptr(str).to_str() else {
4456                _ = self.Deallocate(str);
4457                //CESU-8 my old friend
4458                return Err(JVMTI_ERROR_NONE);
4459            };
4460
4461            let copy = val.to_string();
4462            _ = self.Deallocate(str);
4463
4464            Ok(copy)
4465        }
4466    }
4467
4468    /// For the class indicated by klass, return the access flags via `modifiers_ptr`.
4469    ///
4470    /// Access flags are defined in The Java™ Virtual Machine Specification, Chapter 4.
4471    ///
4472    /// If the class is an array class, then its public, private, and protected modifiers are the same as those of its component type.
4473    /// For arrays of primitives, this component type is represented by one of the primitive classes (for example, java.lang.Integer.TYPE).
4474    /// If the class is a primitive class, its public modifier is always true, and its protected and private modifiers are always false.
4475    /// If the class is an array class or a primitive class then its final modifier is always true and its interface modifier is always false.
4476    /// The values of its other modifiers are not determined by this specification.
4477    ///
4478    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetClassModifiers>
4479    ///
4480    /// # Safety
4481    /// `klass` must be a valid strong reference or null.
4482    /// `modifiers_ptr` must not be dangling.
4483    pub unsafe fn GetClassModifiers(&self, klass: jclass, modifiers_ptr: *mut jint) -> jvmtiError {
4484        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jint) -> jvmtiError>(50)(self.vtable, klass, modifiers_ptr) }
4485    }
4486
4487    /// For the class indicated by klass, return a count of methods via `method_count_ptr` and a list of method IDs via `methods_ptr`.
4488    ///
4489    /// The method list contains constructors and static initializers as well as true methods.
4490    /// Only directly declared methods are returned (not inherited methods).
4491    /// An empty method list is returned for array classes and primitive classes (for example, java.lang.Integer.TYPE).
4492    ///
4493    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetClassMethods>
4494    ///
4495    /// # Safety
4496    /// `klass` must be a valid strong reference or null.
4497    /// `method_count_ptr` and `methods_ptr` must not be dangling.
4498    pub unsafe fn GetClassMethods(&self, klass: jclass, method_count_ptr: *mut jint, methods_ptr: *mut *mut jmethodID) -> jvmtiError {
4499        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jint, *mut *mut jmethodID) -> jvmtiError>(51)(self.vtable, klass, method_count_ptr, methods_ptr) }
4500    }
4501
4502    /// Returns a Vec containing all methods of the class.
4503    /// This functions serves as a convenience function which calls `GetClassMethods`
4504    /// as well as free's the returned memory using the jvmti deallocator after copying the result
4505    /// to a Vec.
4506    ///
4507    /// The method list contains constructors and static initializers as well as true methods.
4508    /// Only directly declared methods are returned (not inherited methods).
4509    /// An empty method list is returned for array classes and primitive classes (for example, java.lang.Integer.TYPE).
4510    ///
4511    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetClassMethods>
4512    ///
4513    /// # Errors
4514    /// If `GetClassMethods` returns anything that is not `JVMTI_ERROR_NONE`
4515    /// Errors from the jvmti decallocator are silently ignored and the memory is leaked.
4516    ///
4517    /// # Panics
4518    /// if jvmti returns an array with a negative length or a null pointer array without
4519    /// returning an error code.
4520    ///
4521    /// # Safety
4522    /// `klass` must be a valid strong reference or null.
4523    pub unsafe fn GetClassMethods_as_vec(&self, klass: jclass) -> Result<Vec<jmethodID>, jvmtiError> {
4524        unsafe {
4525            let mut count: jsize = 0;
4526            let mut classes_ptr = null_mut();
4527            self.GetClassMethods(klass, &raw mut count, &raw mut classes_ptr).into_result()?;
4528
4529            //We dont risk deallocating the array in the panic case.
4530            let count = usize::try_from(count).expect("JVMTI GetClassMethods provided an array with a negative number of methods.");
4531            if count == 0 {
4532                if !classes_ptr.is_null() {
4533                    _ = self.Deallocate(classes_ptr);
4534                }
4535                return Ok(Vec::new());
4536            }
4537
4538            assert!(
4539                !classes_ptr.is_null(),
4540                "JVMTI GetClassMethods returned a null pointer method array without returning an error"
4541            );
4542
4543            let result = core::slice::from_raw_parts(classes_ptr, count).to_vec();
4544            _ = self.Deallocate(classes_ptr);
4545
4546            Ok(result)
4547        }
4548    }
4549
4550    /// For the class indicated by klass, return a count of fields via `field_count_ptr` and a list of field IDs via `fields_ptr`.
4551    ///
4552    /// Only directly declared fields are returned (not inherited fields).
4553    /// Fields are returned in the order they occur in the class file.
4554    /// An empty field list is returned for array classes and primitive classes (for example, java.lang.Integer.TYPE).
4555    /// Use JNI to determine the length of an array.
4556    ///
4557    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetClassFields>
4558    ///
4559    /// # Safety
4560    /// `klass` must be a valid strong reference or null.
4561    /// `field_count_ptr` and `fields_ptr` must not be dangling.
4562    pub unsafe fn GetClassFields(&self, klass: jclass, field_count_ptr: *mut jint, fields_ptr: *mut *mut jfieldID) -> jvmtiError {
4563        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jint, *mut *mut jfieldID) -> jvmtiError>(52)(self.vtable, klass, field_count_ptr, fields_ptr) }
4564    }
4565
4566    /// Returns a Vec containing all fields of the class.
4567    /// This functions serves as a convenience function which calls `GetClassFields`
4568    /// as well as free's the returned memory using the jvmti deallocator after copying the result
4569    /// to a Vec.
4570    ///
4571    /// Only directly declared fields are returned (not inherited fields).
4572    /// Fields are returned in the order they occur in the class file.
4573    /// An empty field list is returned for array classes and primitive classes (for example, java.lang.Integer.TYPE).
4574    /// Use JNI to determine the length of an array.
4575    ///
4576    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetClassFields>
4577    ///
4578    /// # Errors
4579    /// If `GetClassFields` returns anything that is not `JVMTI_ERROR_NONE`
4580    /// Errors from the jvmti decallocator are silently ignored and the memory is leaked.
4581    ///
4582    /// # Panics
4583    /// If jvmti returns an array with a negative length or a null pointer array without
4584    /// returning an error code.
4585    ///
4586    /// # Safety
4587    /// `klass` must be a valid strong reference or null.
4588    pub unsafe fn GetClassFields_as_vec(&self, klass: jclass) -> Result<Vec<jfieldID>, jvmtiError> {
4589        unsafe {
4590            let mut count: jsize = 0;
4591            let mut classes_ptr = null_mut();
4592            self.GetClassFields(klass, &raw mut count, &raw mut classes_ptr).into_result()?;
4593
4594            //We dont risk deallocating the array in the panic case.
4595            let count = usize::try_from(count).expect("JVMTI GetClassFields provided an array with a negative number of methods.");
4596            if count == 0 {
4597                if !classes_ptr.is_null() {
4598                    _ = self.Deallocate(classes_ptr);
4599                }
4600                return Ok(Vec::new());
4601            }
4602
4603            assert!(
4604                !classes_ptr.is_null(),
4605                "JVMTI GetClassFields returned a null pointer method array without returning an error"
4606            );
4607
4608            let result = core::slice::from_raw_parts(classes_ptr, count).to_vec();
4609            _ = self.Deallocate(classes_ptr);
4610
4611            Ok(result)
4612        }
4613    }
4614
4615    /// Return the direct super-interfaces of this class. For a class, this function returns the interfaces declared in its implements clause.
4616    ///
4617    /// For an interface, this function returns the interfaces declared in its extends clause.
4618    /// An empty interface list is returned for array classes and primitive classes (for example, java.lang.Integer.TYPE).
4619    ///
4620    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetImplementedInterfaces>
4621    ///
4622    /// # Safety
4623    /// `klass` must be a valid strong reference or null.
4624    /// `interface_count_ptr` and `interfaces_ptr` must not be dangling.
4625    pub unsafe fn GetImplementedInterfaces(&self, klass: jclass, interface_count_ptr: *mut jint, interfaces_ptr: *mut *mut jclass) -> jvmtiError {
4626        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jint, *mut *mut jclass) -> jvmtiError>(53)(self.vtable, klass, interface_count_ptr, interfaces_ptr) }
4627    }
4628
4629    /// Return the direct super-interfaces of this class. For a class, this function returns the interfaces declared in its implements clause.
4630    ///
4631    /// For an interface, this function returns the interfaces declared in its extends clause.
4632    /// An empty interface list is returned for array classes and primitive classes (for example, java.lang.Integer.TYPE).
4633    ///
4634    /// # Errors
4635    /// If `GetImplementedInterfaces` returns anything that is not `JVMTI_ERROR_NONE`
4636    /// Errors from the jvmti decallocator are silently ignored and the memory is leaked.
4637    ///
4638    /// # Panics
4639    /// If jvmti returns an array with a negative length or a null pointer array without
4640    /// returning an error code.
4641    ///
4642    /// # Safety
4643    /// `klass` must be a valid strong reference or null.
4644    pub unsafe fn GetImplementedInterfaces_as_vec(&self, klass: jclass) -> Result<Vec<jclass>, jvmtiError> {
4645        unsafe {
4646            let mut count: jsize = 0;
4647            let mut classes_ptr = null_mut();
4648            self.GetImplementedInterfaces(klass, &raw mut count, &raw mut classes_ptr).into_result()?;
4649
4650            //We dont risk deallocating the array in the panic case.
4651            let count = usize::try_from(count).expect("JVMTI GetImplementedInterfaces provided an array with a negative number of classes.");
4652            if count == 0 {
4653                if !classes_ptr.is_null() {
4654                    _ = self.Deallocate(classes_ptr);
4655                }
4656                return Ok(Vec::new());
4657            }
4658
4659            assert!(
4660                !classes_ptr.is_null(),
4661                "JVMTI GetImplementedInterfaces returned a null pointer class array without returning an error"
4662            );
4663
4664            let result = core::slice::from_raw_parts(classes_ptr, count).to_vec();
4665            _ = self.Deallocate(classes_ptr);
4666
4667            Ok(result)
4668        }
4669    }
4670
4671    /// For the class indicated by klass, return the minor and major version numbers, as defined in The Java™ Virtual Machine Specification, Chapter 4.
4672    ///
4673    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetClassVersionNumbers>
4674    ///
4675    /// # Safety
4676    /// `klass` must be a valid strong reference or null.
4677    /// `minor_version_ptr` and `major_version_ptr` must not be dangling.
4678    pub unsafe fn GetClassVersionNumbers(&self, klass: jclass, minor_version_ptr: *mut jint, major_version_ptr: *mut jint) -> jvmtiError {
4679        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jint, *mut jint) -> jvmtiError>(144)(self.vtable, klass, minor_version_ptr, major_version_ptr) }
4680    }
4681
4682    /// For the class indicated by klass, return the raw bytes of the constant pool in the format of the `constant_pool` item of The Java™ Virtual Machine Specification, Chapter 4.
4683    ///
4684    /// The format of the constant pool may differ between versions of the Class File Format, so, the minor and major class version numbers should be checked for compatibility.
4685    ///
4686    /// The returned constant pool might not have the same layout or contents as the constant pool in the defining class file.
4687    /// The constant pool returned by `GetConstantPool()` may have more or fewer entries than the defining constant pool.
4688    /// Entries may be in a different order. The constant pool returned by `GetConstantPool()` will match the constant pool used by `GetBytecodes()`.
4689    /// That is, the bytecodes returned by `GetBytecodes()` will have constant pool indices which refer to constant pool entries returned by `GetConstantPool()`.
4690    /// Note that since `RetransformClasses` and `RedefineClasses` can change the constant pool, the constant pool returned by this function can change accordingly.
4691    /// Thus, the correspondence between `GetConstantPool()` and `GetBytecodes()` does not hold if there is an intervening class retransformation or redefinition.
4692    /// The value of a constant pool entry used by a given bytecode will match that of the defining class file (even if the indices don't match).
4693    /// Constant pool entries which are not used directly or indirectly by bytecodes (for example, UTF-8 strings associated with annotations) are not required to exist in the returned constant pool.
4694    ///
4695    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetConstantPool>
4696    ///
4697    /// # Safety
4698    /// `klass` must be a valid strong reference or null.
4699    /// all pointer parameters must not be dangling.
4700    pub unsafe fn GetConstantPool(
4701        &self,
4702        klass: jclass,
4703        constant_pool_count_ptr: *mut jint,
4704        constant_pool_byte_count_ptr: *mut jint,
4705        constant_pool_bytes_ptr: *mut *mut c_uchar,
4706    ) -> jvmtiError {
4707        unsafe {
4708            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jint, *mut jint, *mut *mut c_uchar) -> jvmtiError>(145)(
4709                self.vtable,
4710                klass,
4711                constant_pool_count_ptr,
4712                constant_pool_byte_count_ptr,
4713                constant_pool_bytes_ptr,
4714            )
4715        }
4716    }
4717
4718    /// Determines whether a class object reference represents an interface.
4719    /// The jboolean result is `JNI_TRUE` if the "class" is actually an interface,
4720    /// `JNI_FALSE` otherwise.
4721    ///
4722    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IsInterface>
4723    ///
4724    /// # Safety
4725    /// `klass` must be a valid strong reference or null.
4726    /// all pointer parameters must not be dangling.
4727    pub unsafe fn IsInterface(&self, klass: jclass, is_interface_ptr: impl JBooleanMutPtr) -> jvmtiError {
4728        is_interface_ptr.use_jboolean_mut(|is_interface_ptr| unsafe {
4729            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jboolean) -> jvmtiError>(54)(self.vtable, klass, is_interface_ptr)
4730        })
4731    }
4732
4733    /// Determines whether a class object reference represents an array.
4734    /// The jboolean result is true if the class is an array, false otherwise.
4735    ///
4736    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IsArrayClass>
4737    ///
4738    /// # Safety
4739    /// `klass` must be a valid strong reference or null.
4740    /// all pointer parameters must not be dangling.
4741    pub unsafe fn IsArrayClass(&self, klass: jclass, is_array_class_ptr: impl JBooleanMutPtr) -> jvmtiError {
4742        is_array_class_ptr.use_jboolean_mut(|is_array_class_ptr| unsafe {
4743            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jboolean) -> jvmtiError>(55)(self.vtable, klass, is_array_class_ptr)
4744        })
4745    }
4746
4747    /// Determines whether a class is modifiable.
4748    ///
4749    /// If a class is modifiable (`is_modifiable_class_ptr` returns `JNI_TRUE`)
4750    /// the class can be redefined with `RedefineClasses` (assuming the agent possesses the `can_redefine_classes` capability)
4751    /// or retransformed with `RetransformClasses` (assuming the agent possesses the `can_retransform_classes` capability).
4752    /// If a class is not modifiable (`is_modifiable_class_ptr` returns `JNI_FALSE`) the class can be neither redefined nor retransformed.
4753    /// Primitive classes (for example, java.lang.Integer.TYPE), array classes, and some implementation defined classes are never modifiable.
4754    ///
4755    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IsModifiableClass>
4756    ///
4757    /// # Safety
4758    /// `klass` must be a valid strong reference or null.
4759    /// all pointer parameters must not be dangling.
4760    pub unsafe fn IsModifiableClass(&self, klass: jclass, is_modifiable_class_ptr: impl JBooleanMutPtr) -> jvmtiError {
4761        is_modifiable_class_ptr.use_jboolean_mut(|is_modifiable_class_ptr| unsafe {
4762            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jboolean) -> jvmtiError>(44)(self.vtable, klass, is_modifiable_class_ptr)
4763        })
4764    }
4765
4766    /// For the class indicated by klass, return via `classloader_ptr` a reference to the class loader for the class.
4767    ///
4768    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IsModifiableClass>
4769    ///
4770    /// # Safety
4771    /// `klass` must be a valid strong reference or null.
4772    /// all pointer parameters must not be dangling.
4773    pub unsafe fn GetClassLoader(&self, klass: jclass, classloader_ptr: *mut jobject) -> jvmtiError {
4774        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jobject) -> jvmtiError>(56)(self.vtable, klass, classloader_ptr) }
4775    }
4776
4777    /// For the class indicated by klass, return the debug extension via `source_debug_extension_ptr`.
4778    /// The returned string contains exactly the debug extension information present in the class file of klass.
4779    ///
4780    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetSourceDebugExtension>
4781    ///
4782    /// # Safety
4783    /// `klass` must be a valid strong reference or null.
4784    /// all pointer parameters must not be dangling.
4785    pub unsafe fn GetSourceDebugExtension(&self, klass: jclass, source_debug_extension_ptr: *mut *mut c_char) -> jvmtiError {
4786        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut *mut c_char) -> jvmtiError>(89)(self.vtable, klass, source_debug_extension_ptr) }
4787    }
4788
4789    /// This function facilitates the bytecode instrumentation of already loaded classes.
4790    ///
4791    /// To replace the class definition without reference to the existing bytecodes,
4792    /// as one might do when recompiling from source for fix-and-continue debugging,
4793    /// `RedefineClasses` function should be used instead.
4794    ///
4795    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#RetransformClasses>
4796    ///
4797    /// # Safety
4798    /// `klass` must be a valid strong reference or null.
4799    /// all pointer parameters must not be dangling.
4800    pub unsafe fn RetransformClasses(&self, class_count: jint, classes: *const jclass) -> jvmtiError {
4801        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, *const jclass) -> jvmtiError>(151)(self.vtable, class_count, classes) }
4802    }
4803
4804    /// All classes given are redefined according to the definitions supplied.
4805    ///
4806    /// This function is used to replace the definition of a class with a new definition, as might be needed in fix-and-continue debugging.
4807    /// Where the existing class file bytes are to be transformed, for example in bytecode instrumentation, `RetransformClasses` should be used.
4808    ///
4809    /// Redefinition can cause new versions of methods to be installed.
4810    /// Old method versions may become obsolete The new method version will be used on new invokes.
4811    /// If a method has active stack frames, those active frames continue to run the bytecodes of the original method version.
4812    /// If resetting of stack frames is desired, use `PopFrame` to pop frames with obsolete method versions.
4813    ///
4814    /// This function does not cause any initialization except that which would occur under the customary JVM semantics.
4815    /// In other words, redefining a class does not cause its initializers to be run.
4816    /// The values of static fields will remain as they were prior to the call.
4817    ///
4818    /// Threads need not be suspended.
4819    /// All breakpoints in the class are cleared.
4820    /// All attributes are updated.
4821    /// Instances of the redefined class are not affected, fields retain their previous values.
4822    /// Tags on the instances are also unaffected.
4823    /// In response to this call, the JVM TI event Class File Load Hook will be sent (if enabled),
4824    /// but no other JVM TI events will be sent.
4825    ///
4826    /// The redefinition may change method bodies, the constant pool and attributes (unless explicitly prohibited).
4827    /// The redefinition must not add, remove or rename fields or methods, change the signatures of methods, change modifiers, or change inheritance.
4828    /// The redefinition must not change the `NestHost`, `NestMembers`, `Record`, or `PermittedSubclasses` attributes.
4829    /// These restrictions may be lifted in future versions.
4830    /// See the error return description for information on error codes returned if an unsupported redefinition is attempted.
4831    /// The class file bytes are not verified or installed until they have passed through the chain of `ClassFileLoadHook` events,
4832    /// thus the returned error code reflects the result of the transformations applied to the bytes passed into `class_definitions`.
4833    ///
4834    /// If any error code is returned other than `JVMTI_ERROR_NONE`,
4835    /// none of the classes to be redefined will have a new definition installed.
4836    ///
4837    /// When this function returns (with the error code of `JVMTI_ERROR_NONE`)
4838    /// all of the classes to be redefined will have their new definitions installed.
4839    ///
4840    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#RedefineClasses>
4841    ///
4842    /// # Safety
4843    /// `class_count` and `class_definitions` must form a valid array.
4844    /// all pointer parameters must not be dangling.
4845    /// `class_definitions` must be internally consistent and valid. (no dangling pointers, size + byte pointer must match)
4846    pub unsafe fn RedefineClasses(&self, class_count: jint, class_definitions: *const jvmtiClassDefinition) -> jvmtiError {
4847        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, *const jvmtiClassDefinition) -> jvmtiError>(86)(self.vtable, class_count, class_definitions) }
4848    }
4849
4850    /// For the object indicated by object, return via `size_ptr` the size of the object.
4851    ///
4852    /// This size is an implementation-specific approximation of the amount of storage consumed by this object.
4853    /// It may include some or all of the object's overhead, and thus is useful for comparison within an implementation but not between implementations.
4854    /// The estimate may change during a single invocation of the JVM.
4855    ///
4856    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetObjectSize>
4857    ///
4858    /// # Safety
4859    /// `object` must be a valid strong reference or null.
4860    /// all pointer parameters must not be dangling.
4861    pub unsafe fn GetObjectSize(&self, object: jobject, size_ptr: *mut jlong) -> jvmtiError {
4862        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, *mut jlong) -> jvmtiError>(153)(self.vtable, object, size_ptr) }
4863    }
4864
4865    /// For the object indicated by object, return via `hash_code_ptr` a hash code.
4866    ///
4867    /// This hash code could be used to maintain a hash table of object references, however, on some implementations this can cause significant performance impacts,
4868    /// in most cases tags will be a more efficient means of associating information with objects.
4869    ///
4870    /// This function guarantees the same hash code value for a particular object throughout its life
4871    ///
4872    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetObjectHashCode>
4873    ///
4874    /// # Safety
4875    /// `object` must be a valid strong reference or null.
4876    /// all pointer parameters must not be dangling.
4877    pub unsafe fn GetObjectHashCode(&self, object: jobject, hash_code_ptr: *mut jint) -> jvmtiError {
4878        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, *mut jint) -> jvmtiError>(57)(self.vtable, object, hash_code_ptr) }
4879    }
4880
4881    /// Get information about the object's monitor. The fields of the jvmtiMonitorUsage structure are filled in with information about usage of the monitor.
4882    ///
4883    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetObjectMonitorUsage>
4884    ///
4885    /// # Safety
4886    /// `object` must be a valid strong reference or null.
4887    /// all pointer parameters must not be dangling.
4888    pub unsafe fn GetObjectMonitorUsage(&self, object: jobject, info_ptr: *mut jvmtiMonitorUsage) -> jvmtiError {
4889        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, *mut jvmtiMonitorUsage) -> jvmtiError>(58)(self.vtable, object, info_ptr) }
4890    }
4891
4892    /// For the field indicated by klass and field, return the field name via `name_ptr` and field signature via `signature_ptr`.
4893    ///
4894    /// Field signatures are defined in the JNI Specification and are referred to as field descriptors in The Java™ Virtual Machine Specification, Chapter 4.3.2.
4895    ///
4896    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetFieldName>
4897    ///
4898    /// # Safety
4899    /// `klass` must be a valid strong reference or null.
4900    /// `field` must be a valid field reference in the class referred to by `klass`
4901    /// all pointer parameters must not be dangling.
4902    pub unsafe fn GetFieldName(&self, klass: jclass, field: jfieldID, name_ptr: *mut *mut c_char, signature_ptr: *mut *mut c_char, generic_ptr: *mut *mut c_char) -> jvmtiError {
4903        unsafe {
4904            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, jfieldID, *mut *mut c_char, *mut *mut c_char, *mut *mut c_char) -> jvmtiError>(59)(
4905                self.vtable,
4906                klass,
4907                field,
4908                name_ptr,
4909                signature_ptr,
4910                generic_ptr,
4911            )
4912        }
4913    }
4914
4915    /// For the field indicated by klass and field return the class that defined it via `declaring_class_ptr`.
4916    /// The declaring class will either be klass, a superclass, or an implemented interface.
4917    ///
4918    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetFieldDeclaringClass>
4919    ///
4920    /// # Safety
4921    /// `klass` must be a valid strong reference or null.
4922    /// `field` must be a valid field reference in the class referred to by `klass`
4923    /// all pointer parameters must not be dangling.
4924    pub unsafe fn GetFieldDeclaringClass(&self, klass: jclass, field: jfieldID, declaring_class_ptr: *mut jclass) -> jvmtiError {
4925        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, jfieldID, *mut jclass) -> jvmtiError>(60)(self.vtable, klass, field, declaring_class_ptr) }
4926    }
4927
4928    /// For the field indicated by klass and field return the access flags via `modifiers_ptr`.
4929    ///
4930    /// Access flags are defined in The Java™ Virtual Machine Specification, Chapter 4.
4931    ///
4932    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetFieldModifiers>
4933    ///
4934    /// # Safety
4935    /// `klass` must be a valid strong reference or null.
4936    /// `field` must be a valid field reference in the class referred to by `klass`
4937    /// all pointer parameters must not be dangling.
4938    pub unsafe fn GetFieldModifiers(&self, klass: jclass, field: jfieldID, modifiers_ptr: *mut jint) -> jvmtiError {
4939        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, jfieldID, *mut jint) -> jvmtiError>(61)(self.vtable, klass, field, modifiers_ptr) }
4940    }
4941
4942    /// For the field indicated by klass and field, return a value indicating whether the field is synthetic via `is_synthetic_ptr`.
4943    ///
4944    /// Synthetic fields are generated by the compiler but not present in the original source code.
4945    ///
4946    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IsFieldSynthetic>
4947    ///
4948    /// # Safety
4949    /// `klass` must be a valid strong reference or null.
4950    /// `field` must be a valid field reference in the class referred to by `klass`
4951    /// all pointer parameters must not be dangling.
4952    pub unsafe fn IsFieldSynthetic(&self, klass: jclass, field: jfieldID, is_synthetic_ptr: impl JBooleanMutPtr) -> jvmtiError {
4953        is_synthetic_ptr.use_jboolean_mut(|is_synthetic_ptr| unsafe {
4954            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, jfieldID, *mut jboolean) -> jvmtiError>(62)(self.vtable, klass, field, is_synthetic_ptr)
4955        })
4956    }
4957
4958    /// For the method indicated by method, return the method name via `name_ptr` and method signature via `signature_ptr`.
4959    ///
4960    /// Method signatures are defined in the JNI Specification and are referred to as method descriptors in The Java™ Virtual Machine Specification, Chapter 4.3.3.
4961    /// Note this is different than method signatures as defined in the Java Language Specification.
4962    ///
4963    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetMethodName>
4964    ///
4965    /// # Safety
4966    /// `method` must be a valid methodID or null.
4967    /// all pointer parameters must not be dangling.
4968    pub unsafe fn GetMethodName(&self, method: jmethodID, name_ptr: *mut *mut c_char, signature_ptr: *mut *mut c_char, generic_ptr: *mut *mut c_char) -> jvmtiError {
4969        unsafe {
4970            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut *mut c_char, *mut *mut c_char, *mut *mut c_char) -> jvmtiError>(63)(
4971                self.vtable,
4972                method,
4973                name_ptr,
4974                signature_ptr,
4975                generic_ptr,
4976            )
4977        }
4978    }
4979
4980    /// For the method indicated by method, return the class that defined it via `declaring_class_ptr`.
4981    ///
4982    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetMethodDeclaringClass>
4983    ///
4984    /// # Safety
4985    /// `method` must be a valid methodID or null.
4986    /// all pointer parameters must not be dangling.
4987    pub unsafe fn GetMethodDeclaringClass(&self, method: jmethodID, declaring_class_ptr: *mut jclass) -> jvmtiError {
4988        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jclass) -> jvmtiError>(64)(self.vtable, method, declaring_class_ptr) }
4989    }
4990
4991    /// For the method indicated by method, return the access flags via `modifiers_ptr`.
4992    ///
4993    /// Access flags are defined in The Java™ Virtual Machine Specification, Chapter 4.
4994    ///
4995    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetMethodModifiers>
4996    ///
4997    /// # Safety
4998    /// `method` must be a valid methodID or null.
4999    /// all pointer parameters must not be dangling.
5000    pub unsafe fn GetMethodModifiers(&self, method: jmethodID, modifiers_ptr: *mut jint) -> jvmtiError {
5001        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jint) -> jvmtiError>(65)(self.vtable, method, modifiers_ptr) }
5002    }
5003
5004    /// For the method indicated by method, return the number of local variable slots used by the method,
5005    /// including the local variables used to pass parameters to the method on its invocation.
5006    ///
5007    /// See `max_locals` in The Java™ Virtual Machine Specification, Chapter 4.7.3.
5008    ///
5009    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetMaxLocals>
5010    ///
5011    /// # Safety
5012    /// `method` must be a valid methodID or null.
5013    /// all pointer parameters must not be dangling.
5014    pub unsafe fn GetMaxLocals(&self, method: jmethodID, max_ptr: *mut jint) -> jvmtiError {
5015        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jint) -> jvmtiError>(67)(self.vtable, method, max_ptr) }
5016    }
5017
5018    /// For the method indicated by method, return via `max_ptr` the number of local variable slots used by the method's arguments.
5019    ///
5020    /// Note that two-word arguments use two slots.
5021    ///
5022    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetArgumentsSize>
5023    ///
5024    /// # Safety
5025    /// `method` must be a valid methodID or null.
5026    /// all pointer parameters must not be dangling.
5027    pub unsafe fn GetArgumentsSize(&self, method: jmethodID, max_ptr: *mut jint) -> jvmtiError {
5028        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jint) -> jvmtiError>(68)(self.vtable, method, max_ptr) }
5029    }
5030
5031    /// For the method indicated by method, return a table of source line number entries.
5032    /// The size of the table is returned via `entry_count_ptr` and the table itself is returned via `table_ptr`.
5033    ///
5034    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetLineNumberTable>
5035    ///
5036    /// # Safety
5037    /// `method` must be a valid methodID or null.
5038    /// all pointer parameters must not be dangling.
5039    pub unsafe fn GetLineNumberTable(&self, method: jmethodID, entry_count_ptr: *mut jint, table_ptr: *mut *mut jvmtiLineNumberEntry) -> jvmtiError {
5040        unsafe {
5041            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jint, *mut *mut jvmtiLineNumberEntry) -> jvmtiError>(69)(
5042                self.vtable,
5043                method,
5044                entry_count_ptr,
5045                table_ptr,
5046            )
5047        }
5048    }
5049
5050    /// For the method indicated by method, return the beginning and ending addresses through `start_location_ptr` and `end_location_ptr`.
5051    /// In a conventional bytecode indexing scheme, `start_location_ptr` will always point to zero and `end_location_ptr` will always point to the bytecode count minus one.
5052    ///
5053    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetMethodLocation>
5054    ///
5055    /// # Safety
5056    /// `method` must be a valid methodID or null.
5057    /// all pointer parameters must not be dangling.
5058    pub unsafe fn GetMethodLocation(&self, method: jmethodID, start_location_ptr: *mut jlocation, end_location_ptr: *mut jlocation) -> jvmtiError {
5059        unsafe {
5060            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jlocation, *mut jlocation) -> jvmtiError>(70)(self.vtable, method, start_location_ptr, end_location_ptr)
5061        }
5062    }
5063
5064    /// Return local variable information.
5065    ///
5066    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetLocalVariableTable>
5067    ///
5068    /// # Safety
5069    /// `method` must be a valid methodID or null.
5070    /// all pointer parameters must not be dangling.
5071    pub unsafe fn GetLocalVariableTable(&self, method: jmethodID, entry_count_ptr: *mut jint, table_ptr: *mut *mut jvmtiLocalVariableEntry) -> jvmtiError {
5072        unsafe {
5073            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jint, *mut *mut jvmtiLocalVariableEntry) -> jvmtiError>(71)(
5074                self.vtable,
5075                method,
5076                entry_count_ptr,
5077                table_ptr,
5078            )
5079        }
5080    }
5081
5082    /// For the method indicated by method, return the bytecodes that implement the method. The number of bytecodes is returned via `bytecode_count_ptr`.
5083    ///
5084    /// The bytecodes themselves are returned via `bytecodes_ptr`.
5085    ///
5086    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetBytecodes>
5087    ///
5088    /// # Safety
5089    /// `method` must be a valid methodID or null.
5090    /// all pointer parameters must not be dangling.
5091    pub unsafe fn GetBytecodes(&self, method: jmethodID, bytecode_count_ptr: *mut jint, bytecodes_ptr: *mut *mut c_uchar) -> jvmtiError {
5092        unsafe {
5093            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jint, *mut *mut c_uchar) -> jvmtiError>(74)(self.vtable, method, bytecode_count_ptr, bytecodes_ptr)
5094        }
5095    }
5096
5097    /// For the method indicated by method, return a value indicating whether the method is native via `is_native_ptr`.
5098    ///
5099    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IsMethodNative>
5100    ///
5101    /// # Safety
5102    /// `method` must be a valid methodID or null.
5103    /// all pointer parameters must not be dangling.
5104    pub unsafe fn IsMethodNative(&self, method: jmethodID, is_native_ptr: impl JBooleanMutPtr) -> jvmtiError {
5105        is_native_ptr.use_jboolean_mut(|is_native_ptr| unsafe {
5106            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jboolean) -> jvmtiError>(75)(self.vtable, method, is_native_ptr)
5107        })
5108    }
5109
5110    /// For the method indicated by method, return a value indicating whether the method is synthetic via `is_synthetic_ptr`.
5111    ///
5112    /// Synthetic methods are generated by the compiler but not present in the original source code.
5113    ///
5114    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IsMethodSynthetic>
5115    ///
5116    /// # Safety
5117    /// `method` must be a valid methodID or null.
5118    /// all pointer parameters must not be dangling.
5119    pub unsafe fn IsMethodSynthetic(&self, method: jmethodID, is_synthetic_ptr: impl JBooleanMutPtr) -> jvmtiError {
5120        is_synthetic_ptr.use_jboolean_mut(|is_synthetic_ptr| unsafe {
5121            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jboolean) -> jvmtiError>(76)(self.vtable, method, is_synthetic_ptr)
5122        })
5123    }
5124
5125    /// Determine if a method ID refers to an obsolete method version.
5126    ///
5127    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IsMethodObsolete>
5128    ///
5129    /// # Safety
5130    /// `method` must be a valid methodID or null.
5131    /// all pointer parameters must not be dangling.
5132    pub unsafe fn IsMethodObsolete(&self, method: jmethodID, is_obsolete_ptr: impl JBooleanMutPtr) -> jvmtiError {
5133        is_obsolete_ptr.use_jboolean_mut(|is_obsolete_ptr| unsafe {
5134            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jboolean) -> jvmtiError>(90)(self.vtable, method, is_obsolete_ptr)
5135        })
5136    }
5137
5138    /// This function modifies the failure handling of native method resolution by allowing retry with a prefix applied to the name.
5139    ///
5140    /// When used with the `ClassFileLoadHook` event, it enables native methods to be instrumented.
5141    ///
5142    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetNativeMethodPrefix>
5143    ///
5144    /// # Safety
5145    /// `prefix` must be a rust string type or a valid zero terminated utf-8 string or null.
5146    /// all pointer parameters must not be dangling.
5147    pub unsafe fn SetNativeMethodPrefix(&self, prefix: impl UseCString) -> jvmtiError {
5148        unsafe { prefix.use_as_const_c_char(|prefix| self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const c_char) -> jvmtiError>(72)(self.vtable, prefix)) }
5149    }
5150
5151    /// For a normal agent, `SetNativeMethodPrefix` will provide all needed native method prefixing.
5152    /// For a meta-agent that performs multiple independent class file transformations (for example as a proxy for another layer of agents) this function allows each transformation to have its own prefix.
5153    /// The prefixes are applied in the order supplied and are processed in the same manner as described for the application of prefixes from multiple JVM TI environments in `SetNativeMethodPrefix`.
5154    ///
5155    /// Any previous prefixes are replaced. Thus, calling this function with a `prefix_count` of 0 disables prefixing in this environment.
5156    ///
5157    /// `SetNativeMethodPrefix` and this function are the two ways to set the prefixes.
5158    /// Calling `SetNativeMethodPrefix` with a prefix is the same as calling this function with `prefix_count` of 1.
5159    /// Calling `SetNativeMethodPrefix` with NULL is the same as calling this function with `prefix_count` of 0.
5160    ///
5161    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetNativeMethodPrefix>
5162    ///
5163    /// # Safety
5164    /// `prefixes` must contain valid zero terminated utf-8 strings.
5165    /// `prefix_count` and `prefixes` must form a valid array.
5166    /// all pointer parameters must not be dangling.
5167    pub unsafe fn SetNativeMethodPrefixes(&self, prefix_count: jint, prefixes: *mut *mut c_char) -> jvmtiError {
5168        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, *mut *mut c_char) -> jvmtiError>(73)(self.vtable, prefix_count, prefixes) }
5169    }
5170
5171    /// Create a raw monitor.
5172    ///
5173    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#CreateRawMonitor>
5174    ///
5175    /// For the `monitor_ptr` argument the following rust datatypes are supported:
5176    /// - `*mut jrawMonitorID`
5177    /// - `&mut jrawMonitorID`
5178    /// - `&AtomicPtr<jrawMonitorIDType>`
5179    ///
5180    /// # Usage Recommendation
5181    /// If you have access to a pure-rust based re-entrant mutex in your environment then
5182    /// there is not really a need to use jvmti raw monitors at all.
5183    /// jvmti raw monitors are probably only useful to you if your java agent does
5184    /// not use the rust standard library. (no-std)
5185    ///
5186    ///
5187    /// # Safety
5188    /// `name` must be a rust string type or a valid zero terminated utf-8 string or null.
5189    /// `monitor_ptr` must not be a dangling raw pointer
5190    ///
5191    /// # Example
5192    /// ```rust
5193    /// use std::ptr::null_mut;
5194    /// use std::sync::atomic::AtomicPtr;
5195    /// use std::time::Duration;
5196    /// use jni_simple::*;
5197    ///
5198    /// static JVMTI_MONITOR: AtomicPtr<jrawMonitorIDType> = AtomicPtr::new(null_mut());
5199    ///
5200    /// // called once when your jvmti agent loads.
5201    /// fn init_mutex(env: JVMTIEnv) {
5202    ///     unsafe {
5203    ///         assert!(env.CreateRawMonitor("monitor of my custom java debugger 123", &JVMTI_MONITOR).is_ok());
5204    ///     }
5205    /// }
5206    ///
5207    /// fn do_some_exclusive_work(env: JVMTIEnv) {
5208    ///     unsafe {
5209    ///          // The jvmti raw monitors are always re-entrant.
5210    ///          // Just call RawMonitorExit the same number of times you call RawMonitorEnter
5211    ///          assert!(env.RawMonitorEnter(&JVMTI_MONITOR).is_ok());
5212    ///
5213    ///          // Some jni/jvmti functions require some level of mutual exclusion
5214    ///          // Depending on the state of the jvm.
5215    ///          std::thread::sleep(Duration::from_millis(1000));
5216    ///
5217    ///          // I recommend doing this in a `defer!` block from either the `defer-lite` or `defer-heavy` crate.
5218    ///          // Its a bad idea to not do this due to either unwinding or the ? operator returning early.
5219    ///          assert!(env.RawMonitorExit(&JVMTI_MONITOR).is_ok());
5220    ///     }
5221    /// }
5222    ///
5223    /// ```
5224    ///
5225    pub unsafe fn CreateRawMonitor<T: ReceiveJrawMonitorID>(&self, name: impl UseCString, monitor_ptr: T) -> jvmtiError {
5226        unsafe {
5227            if T::is_direct() {
5228                //Raw pointer
5229                return name.use_as_const_c_char(|name| {
5230                    self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const c_char, *mut jrawMonitorID) -> jvmtiError>(30)(self.vtable, name, monitor_ptr.direct_arg())
5231                });
5232            }
5233
5234            let mut monitor: jrawMonitorID = null_mut();
5235            let ret = name.use_as_const_c_char(|name| {
5236                self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const c_char, *mut jrawMonitorID) -> jvmtiError>(30)(self.vtable, name, &raw mut monitor)
5237            });
5238            if ret == JVMTI_ERROR_NONE {
5239                monitor_ptr.receive(monitor);
5240            }
5241            ret
5242        }
5243    }
5244
5245    /// Destroy the raw monitor.
5246    ///
5247    /// If the monitor being destroyed has been entered by this thread, it will be exited before it is destroyed.
5248    /// If the monitor being destroyed has been entered by another thread, an error will be returned and the monitor will not be destroyed.
5249    ///
5250    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#DestroyRawMonitor>
5251    ///
5252    /// # Safety
5253    /// `monitor` must be a valid raw monitor
5254    pub unsafe fn DestroyRawMonitor(&self, monitor: impl AsJrawMonitorID) -> jvmtiError {
5255        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jrawMonitorID) -> jvmtiError>(31)(self.vtable, monitor.jraw_monitor_id()) }
5256    }
5257
5258    /// Gain exclusive ownership of a raw monitor.
5259    ///
5260    /// The same thread may enter a monitor more then once.
5261    /// The thread must exit the monitor the same number of times as it is entered.
5262    /// If a monitor is entered during `OnLoad` (before attached threads exist) and has not exited when attached threads come into existence,
5263    /// the enter is considered to have occurred on the main thread.
5264    ///
5265    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#RawMonitorEnter>
5266    ///
5267    /// # Safety
5268    /// `monitor` must be a valid raw monitor
5269    pub unsafe fn RawMonitorEnter(&self, monitor: impl AsJrawMonitorID) -> jvmtiError {
5270        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jrawMonitorID) -> jvmtiError>(32)(self.vtable, monitor.jraw_monitor_id()) }
5271    }
5272
5273    /// Release exclusive ownership of a raw monitor.
5274    ///
5275    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#RawMonitorExit>
5276    ///
5277    /// # Safety
5278    /// `monitor` must be a valid raw monitor
5279    pub unsafe fn RawMonitorExit(&self, monitor: impl AsJrawMonitorID) -> jvmtiError {
5280        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jrawMonitorID) -> jvmtiError>(33)(self.vtable, monitor.jraw_monitor_id()) }
5281    }
5282
5283    /// Wait for notification of the raw monitor.
5284    ///
5285    /// Causes the current thread to wait until either another thread calls `RawMonitorNotify` or `RawMonitorNotifyAll` for the specified raw monitor, or the specified timeout has elapsed.
5286    ///
5287    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#RawMonitorWait>
5288    ///
5289    /// # Safety
5290    /// `monitor` must be a valid raw monitor
5291    pub unsafe fn RawMonitorWait(&self, monitor: impl AsJrawMonitorID) -> jvmtiError {
5292        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jrawMonitorID) -> jvmtiError>(34)(self.vtable, monitor.jraw_monitor_id()) }
5293    }
5294
5295    /// Notify a single thread waiting on the raw monitor.
5296    ///
5297    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#RawMonitorNotify>
5298    ///
5299    /// # Safety
5300    /// `monitor` must be a valid raw monitor
5301    pub unsafe fn RawMonitorNotify(&self, monitor: impl AsJrawMonitorID) -> jvmtiError {
5302        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jrawMonitorID) -> jvmtiError>(35)(self.vtable, monitor.jraw_monitor_id()) }
5303    }
5304
5305    /// Notify all threads waiting on the raw monitor.
5306    ///
5307    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#RawMonitorNotifyAll>
5308    ///
5309    /// # Safety
5310    /// `monitor` must be a valid raw monitor
5311    pub unsafe fn RawMonitorNotifyAll(&self, monitor: impl AsJrawMonitorID) -> jvmtiError {
5312        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jrawMonitorID) -> jvmtiError>(36)(self.vtable, monitor.jraw_monitor_id()) }
5313    }
5314
5315    /// Set the JNI function table in all current and future JNI environments.
5316    ///
5317    /// As a result, all future JNI calls are directed to the specified functions.
5318    /// Use `GetJNIFunctionTable` to get the function table to pass to this function.
5319    /// For this function to take effect the updated table entries must be used by the JNI clients.
5320    /// The table is copied--changes to the local copy of the table have no effect.
5321    /// This function affects only the function table, all other aspects of the environment are unaffected.
5322    ///
5323    /// # Compiler Optimizations
5324    /// Since the table is defined const in the C headers some compilers may optimize away the access to the table,
5325    /// thus preventing this function from taking effect.
5326    /// This is entirely dependant on the compiler and its settings that was used to compile the JNI Client.
5327    /// The rust compiler settings used to compile the JVMTI agent have no effect on this.
5328    ///
5329    /// ## Rust Compiler Optimizations
5330    /// The rust compiler does not as of rust version 1.89 perform any optimization that prevents this function from taking effect with rust JNI Clients
5331    /// regardless of chosen rust compiler settings and flags.
5332    /// It is very unlikely that future versions of the rust compiler will change this behavior.
5333    ///
5334    ///
5335    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetJNIFunctionTable>
5336    ///
5337    /// # Safety
5338    /// `function_table` must be a valid initialized jni function table
5339    pub unsafe fn SetJNIFunctionTable(&self, function_table: jniNativeInterface) -> jvmtiError {
5340        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jniNativeInterface) -> jvmtiError>(119)(self.vtable, function_table) }
5341    }
5342
5343    /// Get the JNI function table. The JNI function table is copied into allocated memory.
5344    ///
5345    /// If `SetJNIFunctionTable` has been called, the modified (not the original) function table is returned.
5346    /// Only the function table is copied, no other aspects of the environment are copied.
5347    ///
5348    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetJNIFunctionTable>
5349    ///
5350    /// # Safety
5351    /// `function_table` must not be dangling
5352    pub unsafe fn GetJNIFunctionTable(&self, function_table: *mut jniNativeInterface) -> jvmtiError {
5353        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jniNativeInterface) -> jvmtiError>(120)(self.vtable, function_table) }
5354    }
5355
5356    /// Set the functions to be called for each event.
5357    ///
5358    /// The callbacks are specified by supplying a replacement function table.
5359    ///
5360    /// The function table is copied, changes to the local copy of the table have no effect.
5361    /// This is an atomic action, all callbacks are set at once.
5362    ///
5363    /// No events are sent before this function is called.
5364    /// When an entry is NULL or when the event is beyond `size_of_callbacks` no event is sent.
5365    /// Details on events are described later in this document.
5366    ///
5367    /// An event must be enabled and have a callback in order to be sent,
5368    /// the order in which this function and `SetEventNotificationMode` are called does not affect the result.
5369    ///
5370    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetEventCallbacks>
5371    ///
5372    /// # Safety
5373    /// `callbacks` must not be dangling
5374    #[expect(clippy::cast_possible_truncation)] // size_of::<jvmtiEventCallbacks>() will never be larger than jint::MAX
5375    #[expect(clippy::cast_possible_wrap)]
5376    pub unsafe fn SetEventCallbacks(&self, callbacks: *const jvmtiEventCallbacks) -> jvmtiError {
5377        unsafe {
5378            self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const jvmtiEventCallbacks, jint) -> jvmtiError>(121)(self.vtable, callbacks, size_of::<jvmtiEventCallbacks>() as jint)
5379        }
5380    }
5381
5382    /// Raw variant of `SetEventCallbacks` which allows for passing an arbitrary payload.
5383    /// This is useful when attempting to use a jvmti version that is newer than what jni-simple supports.
5384    ///
5385    /// # Safety
5386    /// The `callbacks` and `size_of_callbacks` must match what the jvm expects.
5387    pub unsafe fn SetEventCallbacks_raw(&self, callbacks: *const c_void, size_of_callbacks: jint) -> jvmtiError {
5388        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const jvmtiEventCallbacks, jint) -> jvmtiError>(121)(self.vtable, callbacks.cast(), size_of_callbacks) }
5389    }
5390
5391    /// Control the generation of events.
5392    ///
5393    /// Calling this function either enables or disables future generation of specific jvmti events.
5394    /// If `event_thread` is null then this control the behavior of event generation a global level.
5395    /// Otherwise changes are only made for the given thread.
5396    ///
5397    /// The following events cannot be controlled at the thread level through this function:
5398    /// - `VMInit`
5399    /// - `VMStart`
5400    /// - `VMDeath`
5401    /// - `ThreadStart`
5402    /// - `VirtualThreadStart`
5403    /// - `CompiledMethodLoad`
5404    /// - `CompiledMethodUnload`
5405    /// - `DynamicCodeGenerated`
5406    /// - `DataDumpRequest`
5407    ///
5408    /// Initially, no events are enabled at either the thread level or the global level.
5409    /// Any needed capabilities (see Event Enabling Capabilities below) must be possessed before calling this function.
5410    ///
5411    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetEventNotificationMode>
5412    ///
5413    /// # Safety
5414    /// `event_thread` must either be null or a valid strong reference to a jthread.
5415    /// The `callbacks` and `size_of_callbacks` must match what the jvm expects.
5416    pub unsafe fn SetEventNotificationMode(&self, mode: jvmtiEventMode, event_type: jvmtiEvent, event_thread: jthread) -> jvmtiError {
5417        unsafe { self.jvmti::<extern "C" fn(JVMTIEnvVTable, jvmtiEventMode, jvmtiEvent, jthread, ...) -> jvmtiError>(1)(self.vtable, mode, event_type, event_thread) }
5418    }
5419
5420    /// Allows for calling undocumented variadic extensions.
5421    /// The current jvmti specification only provides this function with the disclaimer
5422    /// "for future expansion"
5423    ///
5424    /// Since rust does support c-variadics yet calling this from rust is non trivial.
5425    ///
5426    /// # Safety
5427    /// There are a lot of things that can go wrong when calling this function, see the example.
5428    /// using this function requires deep knowledge of jvm implementation specific details.
5429    /// Use with care and only if necessary.
5430    ///
5431    /// # Example
5432    /// ```rust
5433    /// use std::ffi::{c_int, c_void};
5434    /// use core::ptr::null_mut;
5435    /// use jni_simple::*;
5436    ///
5437    /// fn enable_very_special_custom_event(env: JVMTIEnv) {
5438    ///   unsafe {
5439    ///     //NOTE: jvmtiEvent with a value 5 does not exist, this is just for illustrative purposes!
5440    ///     //This example assumes that the hypothetical global jni event 5 would want a jint extension parameter.
5441    ///     let _err : jvmtiError = env.SetEventNotificationMode_extension::<extern "C" fn(*mut c_void, jvmtiEventMode, c_int, jthread, ...) -> jvmtiError>()
5442    ///         (env.vtable(), jvmtiEventMode::JVMTI_ENABLE, 5, null_mut(), 4i32);
5443    ///   }
5444    /// }
5445    /// ```
5446    #[must_use]
5447    pub unsafe fn SetEventNotificationMode_extension<X>(&self) -> X {
5448        unsafe { self.jvmti::<X>(1) }
5449    }
5450
5451    /// Generate events to represent the current state of the VM.
5452    ///
5453    /// For example, if `event_type` is `JVMTI_EVENT_COMPILED_METHOD_LOAD`, a `CompiledMethodLoad` event will be sent for each currently compiled method.
5454    /// Methods that were loaded and now have been unloaded are not sent.
5455    /// The history of what events have previously been sent does not effect what events are sent by this function,
5456    /// for example, all currently compiled methods will be sent each time this function is called.
5457    ///
5458    /// This function is useful when events may have been missed due to the agent attaching after program execution begins; this function generates the missed events.
5459    ///
5460    /// Attempts to execute Java programming language code or JNI functions may be paused until this function returns,
5461    /// so neither should be called from the thread sending the event.
5462    ///
5463    /// This function returns only after the missed events have been sent, processed and have returned.
5464    ///
5465    /// The event may be sent on a different thread than the thread on which the event occurred.
5466    /// The callback for the event must be set with `SetEventCallbacks` and the event must be enabled with `SetEventNotificationMode` or the events will not occur.
5467    /// If the VM no longer has the information to generate some or all of the requested events, the events are simply not sent - no error is returned.
5468    ///
5469    /// Only the following events are supported:
5470    /// - `CompiledMethodLoad`
5471    /// - `DynamicCodeGenerated`
5472    ///
5473    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GenerateEvents>
5474    ///
5475    /// # Safety
5476    /// `function_table` must not be dangling
5477    pub unsafe fn GenerateEvents(&self, event_type: jvmtiEvent) -> jvmtiError {
5478        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jvmtiEvent) -> jvmtiError>(122)(self.vtable, event_type) }
5479    }
5480
5481    /// Returns the set of extension functions.
5482    ///
5483    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetExtensionFunctions>
5484    ///
5485    /// # Safety
5486    /// all pointer parameters must not be dangling
5487    pub unsafe fn GetExtensionFunctions(&self, extension_count_ptr: *mut jint, extensions: *mut *mut jvmtiExtensionFunctionInfo) -> jvmtiError {
5488        unsafe {
5489            self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jint, *mut *mut jvmtiExtensionFunctionInfo) -> jvmtiError>(123)(self.vtable, extension_count_ptr, extensions)
5490        }
5491    }
5492
5493    /// Returns the set of extension events.
5494    ///
5495    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetExtensionEvents>
5496    ///
5497    /// # Safety
5498    /// all pointer parameters must not be dangling
5499    pub unsafe fn GetExtensionEvents(&self, extension_count_ptr: *mut jint, extensions: *mut *mut jvmtiExtensionEventInfo) -> jvmtiError {
5500        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jint, *mut *mut jvmtiExtensionEventInfo) -> jvmtiError>(124)(self.vtable, extension_count_ptr, extensions) }
5501    }
5502
5503    /// Sets the callback function for an extension event and enables the event. Or, if the callback is NULL, disables the event.
5504    ///
5505    /// Note that unlike standard events, setting the callback and enabling the event are a single operation.
5506    ///
5507    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetExtensionEventCallback>
5508    ///
5509    /// # Safety
5510    /// all pointer parameters must not be dangling
5511    /// `callback` must match the function signature that the jvm implementation expects.
5512    pub unsafe fn SetExtensionEventCallback(&self, extension_event_index: jint, callback: jvmtiExtensionEvent) -> jvmtiError {
5513        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, jvmtiExtensionEvent) -> jvmtiError>(125)(self.vtable, extension_event_index, callback) }
5514    }
5515
5516    /// Get information about the `GetCurrentThreadCpuTime` timer.
5517    ///
5518    /// The fields of the jvmtiTimerInfo structure are filled in with details about the timer.
5519    ///
5520    /// This information is specific to the platform and the implementation of `GetCurrentThreadCpuTime` and thus does not vary by thread nor does it vary during a particular invocation of the VM.
5521    ///
5522    /// Note that the implementations of `GetCurrentThreadCpuTime` and `GetThreadCpuTime` may differ,
5523    /// and thus the values returned by `GetCurrentThreadCpuTimerInfo` and `GetThreadCpuTimerInfo` may differ,
5524    /// see `GetCurrentThreadCpuTime` for more information.
5525    ///
5526    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetCurrentThreadCpuTimerInfo>
5527    ///
5528    /// # Safety
5529    /// all pointer parameters must not be dangling
5530    pub unsafe fn GetCurrentThreadCpuTimerInfo(&self, info_ptr: *mut jvmtiTimerInfo) -> jvmtiError {
5531        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jvmtiTimerInfo) -> jvmtiError>(133)(self.vtable, info_ptr) }
5532    }
5533
5534    /// Return the CPU time utilized by the current thread.
5535    ///
5536    /// Note that the `GetThreadCpuTime` function provides CPU time for any thread, including the current thread.
5537    /// `GetCurrentThreadCpuTime` exists to support platforms which cannot supply CPU time for threads other than the current thread
5538    /// or which have more accurate information for the current thread (see `GetCurrentThreadCpuTimerInfo` vs `GetThreadCpuTimerInfo`).
5539    ///
5540    /// An implementation is not required to support this function when the current thread is a virtual thread, in which case `JVMTI_ERROR_UNSUPPORTED_OPERATION` will be returned.
5541    /// see `GetCurrentThreadCpuTime` for more information.
5542    ///
5543    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetCurrentThreadCpuTime>
5544    ///
5545    /// # Safety
5546    /// all pointer parameters must not be dangling
5547    pub unsafe fn GetCurrentThreadCpuTime(&self, nanos_ptr: *mut jlong) -> jvmtiError {
5548        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jlong) -> jvmtiError>(134)(self.vtable, nanos_ptr) }
5549    }
5550
5551    /// Get information about the `GetCurrentThreadCpuTime` timer.
5552    ///
5553    /// The fields of the jvmtiTimerInfo structure are filled in with details about the timer.
5554    ///
5555    /// This information is specific to the platform and the implementation of `GetCurrentThreadCpuTime` and thus does not vary by thread nor does it vary during a particular invocation of the VM.
5556    ///
5557    /// Note that the implementations of `GetCurrentThreadCpuTime` and `GetThreadCpuTime` may differ,
5558    /// and thus the values returned by `GetCurrentThreadCpuTimerInfo` and `GetThreadCpuTimerInfo` may differ,
5559    /// see `GetCurrentThreadCpuTime` for more information.
5560    ///
5561    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetCurrentThreadCpuTimerInfo>
5562    ///
5563    /// # Safety
5564    /// all pointer parameters must not be dangling
5565    pub unsafe fn GetThreadCpuTimerInfo(&self, info_ptr: *mut jvmtiTimerInfo) -> jvmtiError {
5566        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jvmtiTimerInfo) -> jvmtiError>(135)(self.vtable, info_ptr) }
5567    }
5568
5569    /// Return the CPU time utilized by the specified thread.
5570    ///
5571    /// Get information about this timer with `GetThreadCpuTimerInfo`.
5572    ///
5573    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetThreadCpuTime>
5574    ///
5575    /// # Safety
5576    /// all pointer parameters must not be dangling
5577    pub unsafe fn GetThreadCpuTime(&self, thread: jthread, nanos_ptr: *mut jlong) -> jvmtiError {
5578        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, *mut jlong) -> jvmtiError>(136)(self.vtable, thread, nanos_ptr) }
5579    }
5580
5581    /// Get information about the `GetTime` timer.
5582    ///
5583    /// The fields of the jvmtiTimerInfo structure are filled in with details about the timer.
5584    /// This information will not change during a particular invocation of the VM.
5585    ///
5586    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetTimerInfo>
5587    ///
5588    /// # Safety
5589    /// all pointer parameters must not be dangling
5590    pub unsafe fn GetTimerInfo(&self, info_ptr: *mut jvmtiTimerInfo) -> jvmtiError {
5591        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jvmtiTimerInfo) -> jvmtiError>(137)(self.vtable, info_ptr) }
5592    }
5593
5594    /// Return the current value of the system timer, in nanoseconds.
5595    ///
5596    /// The value returned represents nanoseconds since some fixed but arbitrary time (perhaps in the future, so values may be negative).
5597    ///
5598    /// This function provides nanosecond precision, but not necessarily nanosecond accuracy.
5599    ///
5600    /// No guarantees are made about how frequently values change.
5601    /// Get information about this timer with `GetTimerInfo`.
5602    ///
5603    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetTime>
5604    ///
5605    /// # Safety
5606    /// all pointer parameters must not be dangling
5607    pub unsafe fn GetTime(&self, nanos_ptr: *mut jlong) -> jvmtiError {
5608        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jlong) -> jvmtiError>(138)(self.vtable, nanos_ptr) }
5609    }
5610
5611    /// Returns the number of processors available to the Java virtual machine.
5612    ///
5613    /// This value may change during a particular invocation of the virtual machine.
5614    /// Applications that are sensitive to the number of available processors should therefore occasionally poll this property.
5615    ///
5616    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetAvailableProcessors>
5617    ///
5618    /// # Safety
5619    /// all pointer parameters must not be dangling
5620    pub unsafe fn GetAvailableProcessors(&self, processor_count_ptr: *mut jint) -> jvmtiError {
5621        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jint) -> jvmtiError>(143)(self.vtable, processor_count_ptr) }
5622    }
5623
5624    /// This function can be used to cause instrumentation classes to be defined by the bootstrap class loader.
5625    ///
5626    /// See The Java™ Virtual Machine Specification, Chapter 5.3.1. After the bootstrap class loader unsuccessfully searches for a class,
5627    /// the specified platform-dependent search path segment will be searched as well.
5628    ///
5629    /// Only one segment may be specified in the segment.
5630    /// This function may be called multiple times to add multiple segments, the segments will be searched in the order that this function was called.
5631    ///
5632    /// In the `OnLoad` phase the function may be used to specify any platform-dependent search path segment to be searched after the bootstrap class loader unsuccessfully searches for a class.
5633    /// The segment is typically a directory or JAR file.
5634    ///
5635    /// In the live phase the segment may be used to specify any platform-dependent path to a JAR file.
5636    /// The agent should take care that the JAR file does not contain any classes or resources other than those to be defined by the bootstrap class loader for the purposes of instrumentation.
5637    /// The Java™ Virtual Machine Specification specifies that a subsequent attempt to resolve a symbolic reference
5638    /// that the Java virtual machine has previously unsuccessfully attempted to resolve always fails with the same error that was thrown as a result of the initial resolution attempt.
5639    /// Consequently, if the JAR file contains an entry that corresponds to a class for which the Java virtual machine has unsuccessfully attempted to resolve a reference,
5640    /// then subsequent attempts to resolve that reference will fail with the same error as the initial attempt.
5641    ///
5642    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#AddToSystemClassLoaderSearch>
5643    ///
5644    /// # Safety
5645    /// `segment` must be a rust string, or a valid zero terminated utf-8 string or null
5646    pub unsafe fn AddToBootstrapClassLoaderSearch(&self, segment: impl UseCString) -> jvmtiError {
5647        unsafe { segment.use_as_const_c_char(|segment| self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const c_char) -> jvmtiError>(148)(self.vtable, segment)) }
5648    }
5649
5650    /// This function can be used to cause instrumentation classes to be defined by the system class loader. See The Java™ Virtual Machine Specification, Chapter 5.3.2.
5651    ///
5652    /// After the class loader unsuccessfully searches for a class, the specified platform-dependent search path segment will be searched as well.
5653    /// Only one segment may be specified in the segment. This function may be called multiple times to add multiple segments, the segments will be searched in the order that this function was called.
5654    ///
5655    /// In the `OnLoad` phase the function may be used to specify any platform-dependent search path segment to be searched after the system class loader unsuccessfully searches for a class.
5656    /// The segment is typically a directory or JAR file.
5657    ///
5658    /// In the live phase the segment is a platform-dependent path to a JAR file to be searched after the system class loader unsuccessfully searches for a class.
5659    /// The agent should take care that the JAR file does not contain any classes or resources other than those to be defined by the system class loader for the purposes of instrumentation.
5660    ///
5661    /// In the live phase the system class loader supports adding a JAR file to be searched if the system class loader implements a method name appendToClassPathForInstrumentation
5662    /// which takes a single parameter of type java.lang.String. The method is not required to have public access.
5663    ///
5664    /// The Java™ Virtual Machine Specification specifies that a subsequent attempt to resolve a symbolic reference that the Java virtual machine has previously unsuccessfully attempted to resolve
5665    /// always fails with the same error that was thrown as a result of the initial resolution attempt.
5666    /// Consequently, if the JAR file contains an entry that corresponds to a class for which the Java virtual machine has unsuccessfully attempted to resolve a reference,
5667    /// then subsequent attempts to resolve that reference will fail with the same error as the initial attempt.
5668    ///
5669    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#AddToSystemClassLoaderSearch>
5670    ///
5671    /// # Safety
5672    /// `segment` must be a rust string, or a valid zero terminated utf-8 string or null
5673    pub unsafe fn AddToSystemClassLoaderSearch(&self, segment: impl UseCString) -> jvmtiError {
5674        unsafe { segment.use_as_const_c_char(|segment| self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const c_char) -> jvmtiError>(150)(self.vtable, segment)) }
5675    }
5676
5677    /// Provides access to system properties defined by and used by the VM.
5678    ///
5679    /// Properties set on the command-line are included.
5680    /// This allows getting and setting of these properties before the VM even begins executing bytecodes.
5681    /// Since this is a VM view of system properties, the set of available properties will usually be different than that in java.lang.System.getProperties.
5682    /// JNI method invocation may be used to access java.lang.System.getProperties.
5683    /// The set of properties may grow during execution.
5684    ///
5685    /// The list of VM system property keys which may be used with `GetSystemProperty` is returned.
5686    /// It is strongly recommended that virtual machines provide the following property keys:
5687    /// - java.vm.vendor
5688    /// - java.vm.version
5689    /// - java.vm.name
5690    /// - java.vm.info
5691    /// - java.library.path
5692    /// - java.class.path
5693    ///
5694    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetSystemProperties>
5695    ///
5696    /// # Safety
5697    /// all pointer parameters must not be dangling
5698    pub unsafe fn GetSystemProperties(&self, count_ptr: *mut jint, property_ptr: *mut *mut *mut c_char) -> jvmtiError {
5699        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jint, *mut *mut *mut c_char) -> jvmtiError>(129)(self.vtable, count_ptr, property_ptr) }
5700    }
5701
5702    /// Return a VM system property value given the property key.
5703    ///
5704    /// The function `GetSystemProperties` returns the set of property keys which may be used.
5705    /// The properties which can be retrieved may grow during execution.
5706    ///
5707    /// Since this is a VM view of system properties, the values of properties may differ from that returned by java.lang.System.getProperty(String).
5708    /// A typical VM might copy the values of the VM system properties into the Properties held by java.lang.System during the initialization of that class.
5709    /// Thereafter any changes to the VM system properties (with `SetSystemProperty`) or the java.lang.System system properties (with java.lang.System.setProperty(String,String))
5710    /// would cause the values to diverge.
5711    /// JNI method invocation may be used to access java.lang.System.getProperty(String).
5712    ///
5713    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetSystemProperty>
5714    ///
5715    /// # Safety
5716    /// `property` must be a rust string, a valid utf-8 zero terminated string or null.
5717    /// all pointer parameters must not be dangling
5718    pub unsafe fn GetSystemProperty(&self, property: impl UseCString, value_ptr: *mut *mut c_char) -> jvmtiError {
5719        unsafe {
5720            property.use_as_const_c_char(|property| {
5721                self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const c_char, *mut *mut c_char) -> jvmtiError>(130)(self.vtable, property, value_ptr)
5722            })
5723        }
5724    }
5725
5726    /// Set a VM system property value.
5727    ///
5728    /// The function `GetSystemProperties` returns the set of property keys, some of these may be settable. See `GetSystemProperty`.
5729    ///
5730    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetSystemProperty>
5731    ///
5732    /// # Safety
5733    /// `property` must be a rust string, a valid utf-8 zero terminated string or null.
5734    /// all pointer parameters must not be dangling
5735    pub unsafe fn SetSystemProperty(&self, property: impl UseCString, value_ptr: impl UseCString) -> jvmtiError {
5736        unsafe {
5737            property.use_as_const_c_char(|property| {
5738                value_ptr.use_as_const_c_char(|value_ptr| {
5739                    self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const c_char, *const c_char) -> jvmtiError>(131)(self.vtable, property, value_ptr)
5740                })
5741            })
5742        }
5743    }
5744
5745    /// Shutdown a JVM TI connection created with JNI `GetEnv` (see JVM TI Environments).
5746    ///
5747    /// Dispose of any resources held by the environment.
5748    /// Threads suspended by this environment are not resumed by this call, this must be done explicitly by the agent.
5749    /// Memory allocated by this environment via calls to JVM TI functions is not released, this can be done explicitly by the agent by calling Deallocate.
5750    /// Raw monitors created by this environment are not destroyed, this can be done explicitly by the agent by calling `DestroyRawMonitor`.
5751    /// The state of threads waiting on raw monitors created by this environment are not affected.
5752    /// Any native method prefixes for this environment will be unset; the agent must remove any prefixed native methods before dispose is called.
5753    /// Any capabilities held by this environment are relinquished.
5754    /// Events enabled by this environment will no longer be sent, however event handlers currently running will continue to run.
5755    ///
5756    /// Caution must be exercised in the design of event handlers whose environment may be disposed and thus become invalid during their execution.
5757    /// This environment may not be used after this call. This call returns to the caller.
5758    ///
5759    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#DisposeEnvironment>
5760    ///
5761    /// # Safety
5762    /// The environment must not be used anymore after this call. Any call to any other function on this environment once this method is called is undefined behavior.
5763    pub unsafe fn DisposeEnvironment(&self) -> jvmtiError {
5764        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable) -> jvmtiError>(126)(self.vtable) }
5765    }
5766
5767    /// The VM stores a pointer value associated with each environment.
5768    ///
5769    /// This pointer value is called environment-local storage. This value is NULL unless set with this function.
5770    /// Agents can allocate memory in which they store environment specific information.
5771    /// By setting environment-local storage it can then be accessed with `GetEnvironmentLocalStorage`.
5772    /// Called by the agent to set the value of the JVM TI environment-local storage.
5773    /// JVM TI supplies to the agent a pointer-size environment-local storage that can be used to record per-environment information.
5774    ///
5775    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetEnvironmentLocalStorage>
5776    ///
5777    /// # Safety
5778    /// JVM implementation specific
5779    pub unsafe fn SetEnvironmentLocalStorage(&self, data: *const c_void) -> jvmtiError {
5780        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const c_void) -> jvmtiError>(147)(self.vtable, data) }
5781    }
5782
5783    /// The VM stores a pointer value associated with each environment.
5784    ///
5785    /// This pointer value is called environment-local storage. This value is NULL unless set with this function.
5786    /// Agents can allocate memory in which they store environment specific information.
5787    /// By setting environment-local storage it can then be accessed with `GetEnvironmentLocalStorage`.
5788    /// Called by the agent to set the value of the JVM TI environment-local storage.
5789    /// JVM TI supplies to the agent a pointer-size environment-local storage that can be used to record per-environment information.
5790    ///
5791    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetEnvironmentLocalStorage>
5792    ///
5793    /// # Safety
5794    /// all pointer parameters must not be dangling
5795    pub unsafe fn GetEnvironmentLocalStorage(&self, data: *mut *mut c_void) -> jvmtiError {
5796        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut *mut c_void) -> jvmtiError>(146)(self.vtable, data) }
5797    }
5798
5799    /// Return the symbolic name for an error code.
5800    ///
5801    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetErrorName>
5802    ///
5803    /// # Safety
5804    /// all pointer parameters must not be dangling
5805    pub unsafe fn GetErrorName(&self, error: impl Into<jvmtiError>, name_ptr: *mut *mut c_char) -> jvmtiError {
5806        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jvmtiError, *mut *mut c_char) -> jvmtiError>(127)(self.vtable, error.into(), name_ptr) }
5807    }
5808
5809    /// Control verbose output.
5810    ///
5811    /// This is the output which typically is sent to stderr.
5812    ///
5813    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetVerboseFlag>
5814    ///
5815    /// # Safety
5816    /// jvm implementation specific
5817    pub unsafe fn SetVerboseFlag(&self, flag: jvmtiVerboseFlag, value: jboolean) -> jvmtiError {
5818        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jvmtiVerboseFlag, jboolean) -> jvmtiError>(149)(self.vtable, flag, value) }
5819    }
5820
5821    /// This function describes the representation of jlocation used in this VM.
5822    ///
5823    /// If the returned format is `JVMTI_JLOCATION_JVMBCI`, jlocations can be used as in indices into the array returned by `GetBytecodes`.
5824    ///
5825    /// Although the greatest functionality is achieved with location information referencing the virtual machine bytecode index,
5826    /// the definition of jlocation has intentionally been left unconstrained to allow VM implementations that do not have this information.
5827    ///
5828    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetJLocationFormat>
5829    ///
5830    /// # Safety
5831    /// all pointer parameters must not be dangling
5832    pub unsafe fn GetJLocationFormat(&self, format_ptr: *mut jvmtiJlocationFormat) -> jvmtiError {
5833        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jvmtiJlocationFormat) -> jvmtiError>(128)(self.vtable, format_ptr) }
5834    }
5835
5836    /// Generate a `SampledObjectAlloc` event when objects are allocated.
5837    ///
5838    /// Each thread keeps a counter of bytes allocated. The event will only be generated when that counter exceeds an average of `sampling_interval` since the last sample.
5839    /// Setting `sampling_interval` to 0 will cause an event to be generated by each allocation supported by the system once the new interval is taken into account.
5840    /// Note that updating the new sampling interval might take various number of allocations to provoke internal data structure updates.
5841    /// Therefore it is important to consider the sampling interval as an average.
5842    /// This includes the interval 0, where events might not be generated straight away for each allocation.
5843    ///
5844    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetHeapSamplingInterval>
5845    ///
5846    /// # Safety
5847    /// all pointer parameters must not be dangling
5848    pub unsafe fn SetHeapSamplingInterval(&self, sampling_interval: jint) -> jvmtiError {
5849        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint) -> jvmtiError>(155)(self.vtable, sampling_interval) }
5850    }
5851}
5852
5853#[derive(Debug, Copy, Clone)]
5854#[repr(transparent)]
5855pub struct jniNativeInterface(SyncMutPtr<*mut c_void>);
5856
5857impl From<jniNativeInterface> for *mut c_void {
5858    fn from(value: jniNativeInterface) -> Self {
5859        value.0.inner().cast()
5860    }
5861}
5862
5863impl jniNativeInterface {
5864    ///
5865    /// Returns uninitialized jniNativeInterface.
5866    /// The interface must be initialized with a call to `JVMTIEnv::GetJNIFunctionTable`
5867    /// before it can be used in any way.
5868    ///
5869    /// # Undefined behavior of uninitialized `jniNativeInterface`
5870    /// Calling any jvmti fn is ub.
5871    /// Calling any unsafe fn is ub.
5872    #[must_use]
5873    pub const fn new_uninit() -> Self {
5874        Self(SyncMutPtr::null())
5875    }
5876
5877    /// Constructs a new jniNativeInterface from a raw pointer.
5878    ///
5879    /// # Safety
5880    /// Unless the raw pointer was constructed by an invocation on `JVMTIEnv::GetJNIFunctionTable`
5881    /// then the using the resulting `jniNativeInterface` in any way is UB.
5882    #[must_use]
5883    pub const unsafe fn from_raw_ptr(ptr: *mut c_void) -> Self {
5884        Self(SyncMutPtr::new(ptr.cast()))
5885    }
5886
5887    ///
5888    /// Overwrites function in this `jniNativeInterface`
5889    ///
5890    /// # Safety
5891    /// if value is not a function with a matching signature/calling convention
5892    /// then putting the `jniNativeInterface` into use will trigger UB once that linkage is later used.
5893    ///
5894    /// # Example
5895    /// ```rust
5896    /// use jni_simple::*;
5897    ///
5898    /// extern "system" fn hooked_get_version(_env: JNIEnv) -> jint {
5899    ///     println!("JNIEnv GetVersion was called!");
5900    ///     JNI_VERSION_1_8
5901    /// }
5902    ///
5903    /// fn install_hook(env: JVMTIEnv) {
5904    ///     unsafe {
5905    ///         let mut iface = jniNativeInterface::new_uninit();
5906    ///         assert_eq!(env.GetJNIFunctionTable(&mut iface), JVMTI_ERROR_NONE);
5907    ///         iface.set(JNILinkage::GetVersion, hooked_get_version as _);
5908    ///         assert_eq!(env.SetJNIFunctionTable(iface), JVMTI_ERROR_NONE);
5909    ///     }
5910    /// }
5911    /// ```
5912    ///
5913    pub unsafe fn set(&self, linkage: impl AsJNILinkage, value: *mut c_void) {
5914        unsafe {
5915            self.0.add(linkage.linkage()).write_volatile(value);
5916        }
5917    }
5918
5919    ///
5920    /// Returns a function in this `jniNativeInterface`
5921    /// This is usually used to retrieve the unhooked original function from a `jniNativeInterface`
5922    ///
5923    /// # Safety
5924    /// The size of X must be usize (a function pointer).
5925    ///
5926    /// # Example
5927    /// This example illustrates hooking of the `GetVersion` function.
5928    /// The hooked function calls the original function and prints the result to stdout.
5929    /// ```rust
5930    /// use std::ffi::c_void;
5931    /// use std::ops::DerefMut;
5932    /// use std::sync::OnceLock;
5933    /// use jni_simple::*;
5934    ///
5935    /// static ORIGINAL_FUNCTIONS: OnceLock<jniNativeInterface> = OnceLock::new();
5936    ///
5937    /// extern "system" fn hooked_get_version(env: JNIEnv) -> jint {
5938    ///     println!("JNIEnv GetVersion will be called!");
5939    ///     let guard = ORIGINAL_FUNCTIONS.get().unwrap();
5940    ///     let result = unsafe {
5941    ///         guard.get::<extern "system" fn(*mut c_void) -> jint>(JNILinkage::GetVersion)(env.vtable())
5942    ///     };
5943    ///
5944    ///     println!("JNIEnv GetVersion returned {result}!");
5945    ///     result
5946    /// }
5947    ///
5948    /// fn install_hook(env: JVMTIEnv) {
5949    ///     unsafe {
5950    ///         _= ORIGINAL_FUNCTIONS.get_or_init(|| {
5951    ///             let mut iface = jniNativeInterface::new_uninit();
5952    ///             assert_eq!(env.GetJNIFunctionTable(&mut iface), JVMTI_ERROR_NONE);
5953    ///             iface
5954    ///         });
5955    ///
5956    ///         let mut iface = jniNativeInterface::new_uninit();
5957    ///         assert_eq!(env.GetJNIFunctionTable(&mut iface), JVMTI_ERROR_NONE);
5958    ///         iface.set(JNILinkage::GetVersion, hooked_get_version as _);
5959    ///         assert_eq!(env.SetJNIFunctionTable(iface), JVMTI_ERROR_NONE);
5960    ///     }
5961    /// }
5962    /// ```
5963    ///
5964    pub unsafe fn get<X>(&self, linkage: impl AsJNILinkage) -> X {
5965        unsafe { core::mem::transmute_copy(&self.0.add(linkage.linkage()).read_volatile()) }
5966    }
5967}
5968
5969/// Enum of all known jni linkage numbers
5970/// This is mostly useful for use with jvmti when hooking jvm functions.
5971#[derive(Debug, Copy, Clone, Ord, PartialOrd, PartialEq, Eq, Default)]
5972#[repr(usize)]
5973pub enum JNILinkage {
5974    #[default]
5975    GetVersion = 4,
5976
5977    DefineClass = 5,
5978    FindClass = 6,
5979
5980    FromReflectedMethod = 7,
5981    FromReflectedField = 8,
5982    ToReflectedMethod = 9,
5983
5984    GetSuperclass = 10,
5985    IsAssignableFrom = 11,
5986
5987    ToReflectedField = 12,
5988
5989    Throw = 13,
5990    ThrowNew = 14,
5991    ExceptionOccurred = 15,
5992    ExceptionDescribe = 16,
5993    ExceptionClear = 17,
5994    FatalError = 18,
5995
5996    PushLocalFrame = 19,
5997    PopLocalFrame = 20,
5998
5999    NewGlobalRef = 21,
6000    DeleteGlobalRef = 22,
6001    DeleteLocalRef = 23,
6002    IsSameObject = 24,
6003    NewLocalRef = 25,
6004    EnsureLocalCapacity = 26,
6005
6006    AllocObject = 27,
6007    NewObject = 28,
6008    NewObjectV = 29,
6009    NewObjectA = 30,
6010
6011    GetObjectClass = 31,
6012    IsInstanceOf = 32,
6013
6014    GetMethodID = 33,
6015
6016    CallObjectMethod = 34,
6017    CallObjectMethodV = 35,
6018    CallObjectMethodA = 36,
6019    CallBooleanMethod = 37,
6020    CallBooleanMethodV = 38,
6021    CallBooleanMethodA = 39,
6022    CallByteMethod = 40,
6023    CallByteMethodV = 41,
6024    CallByteMethodA = 42,
6025    CallCharMethod = 43,
6026    CallCharMethodV = 44,
6027    CallCharMethodA = 45,
6028    CallShortMethod = 46,
6029    CallShortMethodV = 47,
6030    CallShortMethodA = 48,
6031    CallIntMethod = 49,
6032    CallIntMethodV = 50,
6033    CallIntMethodA = 51,
6034    CallLongMethod = 52,
6035    CallLongMethodV = 53,
6036    CallLongMethodA = 54,
6037    CallFloatMethod = 55,
6038    CallFloatMethodV = 56,
6039    CallFloatMethodA = 57,
6040    CallDoubleMethod = 58,
6041    CallDoubleMethodV = 59,
6042    CallDoubleMethodA = 60,
6043    CallVoidMethod = 61,
6044    CallVoidMethodV = 62,
6045    CallVoidMethodA = 63,
6046
6047    CallNonvirtualObjectMethod = 64,
6048    CallNonvirtualObjectMethodV = 65,
6049    CallNonvirtualObjectMethodA = 66,
6050    CallNonvirtualBooleanMethod = 67,
6051    CallNonvirtualBooleanMethodV = 68,
6052    CallNonvirtualBooleanMethodA = 69,
6053    CallNonvirtualByteMethod = 70,
6054    CallNonvirtualByteMethodV = 71,
6055    CallNonvirtualByteMethodA = 72,
6056    CallNonvirtualCharMethod = 73,
6057    CallNonvirtualCharMethodV = 74,
6058    CallNonvirtualCharMethodA = 75,
6059    CallNonvirtualShortMethod = 76,
6060    CallNonvirtualShortMethodV = 77,
6061    CallNonvirtualShortMethodA = 78,
6062    CallNonvirtualIntMethod = 79,
6063    CallNonvirtualIntMethodV = 80,
6064    CallNonvirtualIntMethodA = 81,
6065    CallNonvirtualLongMethod = 82,
6066    CallNonvirtualLongMethodV = 83,
6067    CallNonvirtualLongMethodA = 84,
6068    CallNonvirtualFloatMethod = 85,
6069    CallNonvirtualFloatMethodV = 86,
6070    CallNonvirtualFloatMethodA = 87,
6071    CallNonvirtualDoubleMethod = 88,
6072    CallNonvirtualDoubleMethodV = 89,
6073    CallNonvirtualDoubleMethodA = 90,
6074    CallNonvirtualVoidMethod = 91,
6075    CallNonvirtualVoidMethodV = 92,
6076    CallNonvirtualVoidMethodA = 93,
6077
6078    GetFieldID = 94,
6079
6080    GetObjectField = 95,
6081    GetBooleanField = 96,
6082    GetByteField = 97,
6083    GetCharField = 98,
6084    GetShortField = 99,
6085    GetIntField = 100,
6086    GetLongField = 101,
6087    GetFloatField = 102,
6088    GetDoubleField = 103,
6089    SetObjectField = 104,
6090    SetBooleanField = 105,
6091    SetByteField = 106,
6092    SetCharField = 107,
6093    SetShortField = 108,
6094    SetIntField = 109,
6095    SetLongField = 110,
6096    SetFloatField = 111,
6097    SetDoubleField = 112,
6098
6099    GetStaticMethodID = 113,
6100
6101    CallStaticObjectMethod = 114,
6102    CallStaticObjectMethodV = 115,
6103    CallStaticObjectMethodA = 116,
6104    CallStaticBooleanMethod = 117,
6105    CallStaticBooleanMethodV = 118,
6106    CallStaticBooleanMethodA = 119,
6107    CallStaticByteMethod = 120,
6108    CallStaticByteMethodV = 121,
6109    CallStaticByteMethodA = 122,
6110    CallStaticCharMethod = 123,
6111    CallStaticCharMethodV = 124,
6112    CallStaticCharMethodA = 125,
6113    CallStaticShortMethod = 126,
6114    CallStaticShortMethodV = 127,
6115    CallStaticShortMethodA = 128,
6116    CallStaticIntMethod = 129,
6117    CallStaticIntMethodV = 130,
6118    CallStaticIntMethodA = 131,
6119    CallStaticLongMethod = 132,
6120    CallStaticLongMethodV = 133,
6121    CallStaticLongMethodA = 134,
6122    CallStaticFloatMethod = 135,
6123    CallStaticFloatMethodV = 136,
6124    CallStaticFloatMethodA = 137,
6125    CallStaticDoubleMethod = 138,
6126    CallStaticDoubleMethodV = 139,
6127    CallStaticDoubleMethodA = 140,
6128    CallStaticVoidMethod = 141,
6129    CallStaticVoidMethodV = 142,
6130    CallStaticVoidMethodA = 143,
6131
6132    GetStaticFieldID = 144,
6133
6134    GetStaticObjectField = 145,
6135    GetStaticBooleanField = 146,
6136    GetStaticByteField = 147,
6137    GetStaticCharField = 148,
6138    GetStaticShortField = 149,
6139    GetStaticIntField = 150,
6140    GetStaticLongField = 151,
6141    GetStaticFloatField = 152,
6142    GetStaticDoubleField = 153,
6143
6144    SetStaticObjectField = 154,
6145    SetStaticBooleanField = 155,
6146    SetStaticByteField = 156,
6147    SetStaticCharField = 157,
6148    SetStaticShortField = 158,
6149    SetStaticIntField = 159,
6150    SetStaticLongField = 160,
6151    SetStaticFloatField = 161,
6152    SetStaticDoubleField = 162,
6153
6154    NewString = 163,
6155
6156    GetStringLength = 164,
6157    GetStringChars = 165,
6158    ReleaseStringChars = 166,
6159
6160    NewStringUTF = 167,
6161    GetStringUTFLength = 168,
6162    GetStringUTFChars = 169,
6163    ReleaseStringUTFChars = 170,
6164
6165    GetArrayLength = 171,
6166
6167    NewObjectArray = 172,
6168    GetObjectArrayElement = 173,
6169    SetObjectArrayElement = 174,
6170
6171    NewBooleanArray = 175,
6172    NewByteArray = 176,
6173    NewCharArray = 177,
6174    NewShortArray = 178,
6175    NewIntArray = 179,
6176    NewLongArray = 180,
6177    NewFloatArray = 181,
6178    NewDoubleArray = 182,
6179
6180    GetBooleanArrayElements = 183,
6181    GetByteArrayElements = 184,
6182    GetCharArrayElements = 185,
6183    GetShortArrayElements = 186,
6184    GetIntArrayElements = 187,
6185    GetLongArrayElements = 188,
6186    GetFloatArrayElements = 189,
6187    GetDoubleArrayElements = 190,
6188
6189    ReleaseBooleanArrayElements = 191,
6190    ReleaseByteArrayElements = 192,
6191    ReleaseCharArrayElements = 193,
6192    ReleaseShortArrayElements = 194,
6193    ReleaseIntArrayElements = 195,
6194    ReleaseLongArrayElements = 196,
6195    ReleaseFloatArrayElements = 197,
6196    ReleaseDoubleArrayElements = 198,
6197
6198    GetBooleanArrayRegion = 199,
6199    GetByteArrayRegion = 200,
6200    GetCharArrayRegion = 201,
6201    GetShortArrayRegion = 202,
6202    GetIntArrayRegion = 203,
6203    GetLongArrayRegion = 204,
6204    GetFloatArrayRegion = 205,
6205    GetDoubleArrayRegion = 206,
6206    SetBooleanArrayRegion = 207,
6207    SetByteArrayRegion = 208,
6208    SetCharArrayRegion = 209,
6209    SetShortArrayRegion = 210,
6210    SetIntArrayRegion = 211,
6211    SetLongArrayRegion = 212,
6212    SetFloatArrayRegion = 213,
6213    SetDoubleArrayRegion = 214,
6214
6215    RegisterNatives = 215,
6216    UnregisterNatives = 216,
6217
6218    MonitorEnter = 217,
6219    MonitorExit = 218,
6220
6221    GetJavaVM = 219,
6222
6223    GetStringRegion = 220,
6224    GetStringUTFRegion = 221,
6225
6226    GetPrimitiveArrayCritical = 222,
6227    ReleasePrimitiveArrayCritical = 223,
6228
6229    GetStringCritical = 224,
6230    ReleaseStringCritical = 225,
6231
6232    NewWeakGlobalRef = 226,
6233    DeleteWeakGlobalRef = 227,
6234
6235    ExceptionCheck = 228,
6236
6237    NewDirectByteBuffer = 229,
6238    GetDirectBufferAddress = 230,
6239    GetDirectBufferCapacity = 231,
6240
6241    GetObjectRefType = 232,
6242
6243    GetModule = 233,
6244
6245    IsVirtualThread = 234,
6246
6247    GetStringUTFLengthAsLong = 235,
6248}
6249
6250impl From<JNILinkage> for usize {
6251    fn from(value: JNILinkage) -> Self {
6252        value as Self
6253    }
6254}
6255
6256pub trait AsJNILinkage: SealedAsJNILinkage {}
6257
6258impl SealedAsJNILinkage for JNILinkage {
6259    fn linkage(self) -> usize {
6260        self as usize
6261    }
6262}
6263
6264impl AsJNILinkage for JNILinkage {}
6265
6266impl SealedAsJNILinkage for usize {
6267    fn linkage(self) -> usize {
6268        self
6269    }
6270}
6271
6272impl AsJNILinkage for usize {}
6273
6274impl SealedAsJNILinkage for i32 {
6275    fn linkage(self) -> usize {
6276        // Negative linkages dont exist, if someone passes a negative linkage
6277        // then its ub anyways and all bets are off.
6278        usize::try_from(self).unwrap_or_default()
6279    }
6280}
6281
6282/// The compiler unless you specify a suffix will assume i32.
6283/// This just makes it a bit easier to not have to write 6usize.
6284impl AsJNILinkage for i32 {}
6285
6286/// Vtable of `JNIEnv` is passed like this.
6287type JNIEnvVTable = *mut jniNativeInterface;
6288
6289#[derive(Debug, Clone, Copy)]
6290#[repr(transparent)]
6291pub struct JNIEnv {
6292    /// The vtable that contains all the functions
6293    vtable: JNIEnvVTable,
6294}
6295
6296impl SealedEnvVTable for JNIEnv {
6297    fn can_jni() -> bool {
6298        true
6299    }
6300
6301    fn can_jvmti() -> bool {
6302        false
6303    }
6304}
6305
6306impl From<*mut c_void> for JNIEnv {
6307    fn from(value: *mut c_void) -> Self {
6308        Self { vtable: value.cast() }
6309    }
6310}
6311
6312impl JNINativeMethod {
6313    #[must_use]
6314    pub const fn new(name: *const c_char, signature: *const c_char, function_pointer: *const c_void) -> Self {
6315        Self {
6316            name,
6317            signature,
6318            fnPtr: function_pointer,
6319        }
6320    }
6321
6322    #[must_use]
6323    pub const fn name(&self) -> *const c_char {
6324        self.name
6325    }
6326
6327    #[must_use]
6328    pub const fn signature(&self) -> *const c_char {
6329        self.signature
6330    }
6331
6332    #[must_use]
6333    pub const fn fnPtr(&self) -> *const c_void {
6334        self.fnPtr
6335    }
6336}
6337
6338impl JavaVMAttachArgs {
6339    pub const fn new(version: jint, name: *const c_char, group: jobject) -> Self {
6340        Self { version, name, group }
6341    }
6342
6343    #[must_use]
6344    pub const fn version(&self) -> jint {
6345        self.version
6346    }
6347    #[must_use]
6348    pub const fn name(&self) -> *const c_char {
6349        self.name
6350    }
6351    #[must_use]
6352    pub const fn group(&self) -> jobject {
6353        self.group
6354    }
6355}
6356
6357/// Helper trait that converts rusts various strings into a zero terminated c string for use with a JNI method.
6358///
6359/// This trait is implemented for:
6360/// `&str`, `String`, `&String`,
6361/// `CString`, `CStr`, `*const c_char`,
6362/// `&OsStr`, `OsString`, `&OsString`,
6363/// `&[u8]`, `Vec<u8>`,
6364///
6365/// If the String contains the equivalent of a 0 byte then the string stops at the 0 byte ignoring the rest of the string.
6366/// Any non Unicode characters in `OsString` and its derivatives will be replaced with the Unicode replacement character by using to `to_str_lossy` fn.
6367/// Using non utf-8 binary data in the u8 slices/Vec will not be checked for validity before being converted into a *const `c_char`!
6368///
6369/// Using invalid inputs on any call to JNI will result in undefined behavior.
6370///
6371pub trait UseCString: private::SealedUseCString {}
6372
6373/// The buffer is copied unless it contains a 0 byte.<br>
6374/// Fast case: last element is 0.
6375impl UseCString for &str {}
6376
6377impl private::SealedUseCString for &str {
6378    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
6379        self.as_bytes().use_as_const_c_char(func)
6380    }
6381}
6382
6383/// String is extended using `reserve_exact` if it doesnt contain a 0 element. <br>
6384/// Fastest case: last element is 0. <br>
6385/// Fast case: buffer has room for one more element.
6386impl UseCString for String {}
6387
6388impl private::SealedUseCString for String {
6389    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
6390        self.into_bytes().use_as_const_c_char(func)
6391    }
6392}
6393
6394/// The buffer is copied unless it contains a 0 byte.<br>
6395/// Fast case: last element is 0.
6396impl UseCString for &String {}
6397
6398impl private::SealedUseCString for &String {
6399    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
6400        self.as_bytes().use_as_const_c_char(func)
6401    }
6402}
6403
6404/// Passed to JNI as is.
6405impl UseCString for CString {}
6406
6407impl private::SealedUseCString for CString {
6408    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
6409        func(self.as_ptr())
6410    }
6411}
6412
6413/// Passed to JNI as is.
6414impl UseCString for &CString {}
6415
6416impl private::SealedUseCString for &CString {
6417    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
6418        func(self.as_ptr())
6419    }
6420}
6421
6422/// Passed to JNI as is.
6423impl UseCString for &CStr {}
6424
6425impl private::SealedUseCString for &CStr {
6426    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
6427        func(self.as_ptr())
6428    }
6429}
6430
6431/// Passed as is to the JVM
6432/// # Safety
6433/// Must either be null or point to a 0 terminated string.<br><br>
6434impl UseCString for *const i8 {}
6435
6436impl private::SealedUseCString for *const i8 {
6437    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
6438        #[cfg(feature = "asserts")]
6439        {
6440            if self.is_null() {
6441                return func(self.cast());
6442            }
6443
6444            //If we are called on a non 0 terminated pointer then all bets are off anyway.
6445            let mut size = 0usize;
6446            loop {
6447                unsafe {
6448                    if self.add(size).read_volatile() == 0 {
6449                        break;
6450                    }
6451                    size += 1;
6452                }
6453            }
6454
6455            unsafe {
6456                let to_check: &[u8] = core::slice::from_raw_parts(self.cast(), size);
6457                assert!(
6458                    core::str::from_utf8(to_check).is_ok(),
6459                    "use_as_const_c_char called on a non utf-8 *const i8. string was only checked until first 0 byte or end of string. data={to_check:?}"
6460                );
6461            }
6462        }
6463
6464        func(self.cast())
6465    }
6466}
6467
6468/// Passed as is to the JVM
6469/// # Safety
6470/// Must either be null or point to a 0 terminated string.<br><br>
6471impl UseCString for *const u8 {}
6472
6473impl private::SealedUseCString for *const u8 {
6474    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
6475        #[cfg(feature = "asserts")]
6476        {
6477            if self.is_null() {
6478                return func(self.cast());
6479            }
6480
6481            //If we are called on a non 0 terminated pointer then all bets are off anyway.
6482            let mut size = 0usize;
6483            loop {
6484                unsafe {
6485                    if self.add(size).read_volatile() == 0 {
6486                        break;
6487                    }
6488                    size += 1;
6489                }
6490            }
6491
6492            unsafe {
6493                let to_check = core::slice::from_raw_parts(self, size);
6494                assert!(
6495                    core::str::from_utf8(to_check).is_ok(),
6496                    "use_as_const_c_char called on a non utf-8 *const u8. string was only checked until first 0 byte or end of string. data={to_check:?}"
6497                );
6498            }
6499        }
6500
6501        func(self.cast())
6502    }
6503}
6504
6505/// Passed as is to the JVM
6506/// # Safety
6507/// Must either be null or point to a 0 terminated string.<br><br>
6508impl UseCString for *mut i8 {}
6509
6510impl private::SealedUseCString for *mut i8 {
6511    fn use_as_const_c_char<X>(self, param: impl FnOnce(*const c_char) -> X) -> X {
6512        self.cast_const().use_as_const_c_char(param)
6513    }
6514}
6515
6516/// Passed as is to the JVM
6517/// # Safety
6518/// Must either be null or point to a 0 terminated string.<br><br>
6519impl UseCString for *mut u8 {}
6520
6521impl private::SealedUseCString for *mut u8 {
6522    fn use_as_const_c_char<X>(self, param: impl FnOnce(*const c_char) -> X) -> X {
6523        self.cast_const().use_as_const_c_char(param)
6524    }
6525}
6526
6527/// The buffer is copied unless it contains a 0 byte.<br>
6528/// Fast case: last element is 0.
6529impl UseCString for Cow<'_, str> {}
6530
6531impl private::SealedUseCString for Cow<'_, str> {
6532    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
6533        self.as_ref().use_as_const_c_char(func)
6534    }
6535}
6536
6537/// The buffer is copied unless it contains a 0 byte.<br>
6538/// Fast case: last element is 0.
6539impl UseCString for &Cow<'_, str> {}
6540
6541impl private::SealedUseCString for &Cow<'_, str> {
6542    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
6543        self.as_ref().use_as_const_c_char(func)
6544    }
6545}
6546
6547/// The `OsString` is transformed to a String by calling `to_string_lossy`
6548/// and then used just like a `Cow<'_, str>` would be used.
6549#[cfg(feature = "std")]
6550impl UseCString for std::ffi::OsString {}
6551
6552#[cfg(feature = "std")]
6553impl private::SealedUseCString for std::ffi::OsString {
6554    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
6555        self.to_string_lossy().use_as_const_c_char(func)
6556    }
6557}
6558
6559/// The `OsString` is transformed to a String by calling `to_string_lossy`
6560/// and then used just like a `Cow<'_, str>` would be used.
6561#[cfg(feature = "std")]
6562impl UseCString for &std::ffi::OsString {}
6563
6564#[cfg(feature = "std")]
6565impl private::SealedUseCString for &std::ffi::OsString {
6566    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
6567        self.to_string_lossy().use_as_const_c_char(func)
6568    }
6569}
6570
6571/// The `OsString` is transformed to a String by calling `to_string_lossy`
6572/// and then used just like a `Cow<'_, str>` would be used.
6573#[cfg(feature = "std")]
6574impl UseCString for &std::ffi::OsStr {}
6575
6576#[cfg(feature = "std")]
6577impl private::SealedUseCString for &std::ffi::OsStr {
6578    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
6579        self.to_string_lossy().use_as_const_c_char(func)
6580    }
6581}
6582
6583/// Vec is extended using `reserve_exact` if it doesnt contain a 0 element. <br>
6584/// Fastest case: last element is 0. <br>
6585/// Fast case: buffer has room for one more element.
6586impl UseCString for Vec<u8> {}
6587
6588impl private::SealedUseCString for Vec<u8> {
6589    fn use_as_const_c_char<X>(mut self, func: impl FnOnce(*const c_char) -> X) -> X {
6590        #[cfg(feature = "asserts")]
6591        {
6592            //Check for valid UTF-8
6593            let len = self.iter().position(|r| *r == 0).unwrap_or(self.len());
6594            let to_check = &self[..len];
6595            assert!(
6596                core::str::from_utf8(to_check).is_ok(),
6597                "use_as_const_c_char called with non utf-8 string. string was only checked until first 0 byte or end of string. data={to_check:?}"
6598            );
6599        }
6600
6601        let Some(last) = self.last().copied() else {
6602            return func([0i8].as_ptr().cast()); //Edge case empty string.
6603        };
6604
6605        if last == 0 {
6606            return func(self.as_ptr().cast());
6607        }
6608
6609        if self.capacity() > self.len() {
6610            //We own the Vec, faster to push 0 in this case, no need to copy or check for intermittent bytes.
6611            self.push(0);
6612            return func(self.as_ptr().cast());
6613        }
6614
6615        for n in &self {
6616            if *n == 0 {
6617                return func(self.as_ptr().cast());
6618            }
6619        }
6620
6621        self.reserve_exact(1); //We know the Vec will be dropped at the end of the scope.
6622        self.push(0); //Oh well guess we will have to copy the Vec...
6623        func(self.as_ptr().cast())
6624    }
6625}
6626
6627/// The buffer is copied unless it contains a 0 byte.<br>
6628/// Fast case: last element is 0.
6629impl UseCString for &Vec<u8> {}
6630
6631impl private::SealedUseCString for &Vec<u8> {
6632    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
6633        self.as_slice().use_as_const_c_char(func)
6634    }
6635}
6636
6637/// The buffer is copied unless it contains a 0 byte.<br>
6638/// Fast case: last element is 0.
6639impl UseCString for &[u8] {}
6640
6641impl private::SealedUseCString for &[u8] {
6642    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
6643        #[cfg(feature = "asserts")]
6644        {
6645            //Check for valid UTF-8
6646            let len = self.iter().position(|r| *r == 0).unwrap_or(self.len());
6647            let to_check = &self[..len];
6648            assert!(
6649                core::str::from_utf8(to_check).is_ok(),
6650                "use_as_const_c_char called with non utf-8 string. string was only checked until first 0 byte or end of string. data={to_check:?}",
6651            );
6652        }
6653
6654        let Some(last) = self.last().copied() else {
6655            return func([0i8].as_ptr().cast()); //Edge case empty string/slice.
6656        };
6657
6658        // Fast case, last byte in slice is 0
6659        if last == 0 {
6660            //We get here if the caller appends \0 to their rust string literals.
6661            return func(self.as_ptr().cast());
6662        }
6663
6664        // Impl detail: CStr::from_bytes_until_nul
6665        // will iterate the string from beginning to end to look for 0 byte,
6666        // so checking if last byte is 0 byte makes sense, especially for longer strings.
6667        // We do not care if there is a second 0 byte already somewhere in the middle of the string.
6668        if let Ok(c_str) = CStr::from_bytes_until_nul(self) {
6669            return func(c_str.as_ptr());
6670        }
6671
6672        // There no 0 byte in the slice. We have to copy the slice, append a 0 byte and then call downstream.
6673        // This is the slowest path. Unfortunately all ordinary ""
6674        // rust strings get here unless the caller explicitly made sure to add \0 to the end.
6675        let mut vec = self.to_vec();
6676        vec.reserve_exact(1);
6677        vec.push(0);
6678        func(vec.as_ptr().cast())
6679    }
6680}
6681
6682/// Convenience implementation that transforms to a null pointer when used with JNI.
6683impl UseCString for () {}
6684
6685impl private::SealedUseCString for () {
6686    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
6687        func(null())
6688    }
6689}
6690
6691impl JNIEnv {
6692    ///
6693    /// Resolves the function pointer given its linkage index of the jni vtable.
6694    /// The indices are documented and guaranteed by the Oracle JVM Spec.
6695    ///
6696    #[inline(always)]
6697    unsafe fn jni<X>(&self, index: usize) -> X {
6698        unsafe {
6699            //We need the read_volatile because a java debugger may at any point in time exchange the jni function table at its convenience.
6700            core::mem::transmute_copy(&(self.vtable.read_volatile().0.add(index).read_volatile()))
6701        }
6702    }
6703
6704    ///
6705    /// Raw indexes the JNI vtable.
6706    /// This can be used to call future JNI methods that jni-simple in the used version is not aware of.
6707    /// It can also be used to call undocumented implementation specific jni functions,
6708    /// or functions defined in a native java debugger.
6709    ///
6710    /// 99% of programs do not need to use this function.
6711    /// Use this function as a last resort.
6712    ///
6713    /// # Generic Type X
6714    /// Almost always a "extern system" function signature.
6715    /// The first parameter is nearly universally a pointer to the raw vtable.
6716    ///
6717    /// # Safety
6718    /// This function is very unsafe. If index is too large, you cause UB due to out of bounds read.
6719    /// The actual size of the vtable cannot be known and is JVM implementation specific.
6720    ///
6721    /// If the generic type X is wrong for the given index then you either cause UB instantly depending
6722    /// on if your supplied X has the same size as `c_void` or not,
6723    /// or once you use the result.
6724    ///
6725    /// # Example
6726    /// This shows how to call the JNI Function `GetVersion` using the raw vtable call.
6727    /// ```rust
6728    /// use std::ffi::c_void;
6729    /// use jni_simple::*;
6730    ///
6731    /// fn some_func(env: JNIEnv) {
6732    ///     unsafe {
6733    ///         // The linkage index for GetVersion is 4. See oracle documentation for a list of linkage indexes as well as their signature.
6734    ///         // The calling convention is the "system" calling convention by default.
6735    ///         // This is the same as "C" on linux but on Windows 32 bit its different. See jni.h and rusts calling convention documentation.
6736    ///         let version: jint = env.index_vtable::<extern "system" fn(*mut c_void) -> jint>(4)(env.vtable());
6737    ///     }
6738    /// }
6739    ///
6740    /// ```
6741    ///
6742    pub unsafe fn index_vtable<X>(&self, index: impl AsJNILinkage) -> X {
6743        unsafe { self.jni::<X>(index.linkage()) }
6744    }
6745
6746    /// Returns the raw jni vtable.
6747    /// This is usefully in some rare situations, especially when used with the `index_vtable` function.
6748    #[must_use]
6749    pub const fn vtable(&self) -> *mut c_void {
6750        self.vtable.cast()
6751    }
6752
6753    ///
6754    /// Returns the version of the JNI interface.
6755    ///
6756    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetVersion>
6757    ///
6758    /// The returned value must be compared against a constant. (They start with `JNI_VERSION`_...)
6759    /// Not every java version has such a constant.
6760    /// Only java versions where a function in the JNI interface was added has one.
6761    ///
6762    ///
6763    /// # Panics
6764    /// if asserts feature is enabled and UB was detected
6765    ///
6766    /// # Safety
6767    ///
6768    /// Current thread must not be detached from JNI.
6769    ///
6770    /// Current thread does not hold a critical reference.
6771    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6772    ///
6773    /// Current thread is not currently throwing a Java exception.
6774    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
6775    ///
6776    ///
6777    /// # Example
6778    /// ```rust
6779    /// use jni_simple::{*};
6780    ///
6781    /// unsafe fn is_at_least_java10(env: JNIEnv) -> bool {
6782    ///     env.GetVersion() >= JNI_VERSION_10
6783    /// }
6784    /// ```
6785    ///
6786    #[must_use]
6787    pub unsafe fn GetVersion(&self) -> jint {
6788        unsafe {
6789            #[cfg(feature = "asserts")]
6790            {
6791                self.check_not_critical("GetVersion");
6792                self.check_no_exception("GetVersion");
6793            }
6794            self.jni::<extern "system" fn(JNIEnvVTable) -> jint>(4)(self.vtable)
6795        }
6796    }
6797
6798    ///
6799    /// Defines a class in the given classloader.
6800    ///
6801    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#DefineClass>
6802    ///
6803    /// # Arguments
6804    /// * `name` - name of the class
6805    /// * `classloader` - handle to the classloader java object. This can be null if the current JNI classloader should be used.
6806    /// * `data` - the binary content of the compiled java .class file.
6807    /// * `len` - the length of the data in bytes.
6808    ///
6809    /// # Returns
6810    /// A local ref handle to the java.lang.Class (jclass) object that was just defined.
6811    /// On error null is returned.
6812    ///
6813    /// # Throws Java Exception:
6814    /// * `ClassFormatError` - if the class data does not specify a valid class.
6815    /// * `ClassCircularityError` - if a class or interface would be its own superclass or superinterface.
6816    /// * `OutOfMemoryError` - if the system runs out of memory.
6817    /// * `SecurityException` - if the caller attempts to define a class in the "java" package tree.
6818    ///
6819    ///
6820    /// # Panics
6821    /// if asserts feature is enabled and UB was detected
6822    ///
6823    /// # Safety
6824    ///
6825    /// Current thread must not be detached from JNI.
6826    ///
6827    /// Current thread does not hold a critical reference.
6828    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6829    ///
6830    /// Current thread is not currently throwing a Java exception.
6831    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
6832    ///
6833    /// The `classloader` handle must be a valid handle if it is not null.
6834    /// `name` must be a valid pointer to a 0 terminated utf-8 string. It must not be null.
6835    /// `data` must not be null.
6836    /// `len` must not be larger than the actual length of the data.
6837    /// `len` must not be negative.
6838    ///
6839    /// # Example
6840    /// ```rust
6841    /// use std::ffi::CString;
6842    /// use core::ptr::null_mut;
6843    /// use jni_simple::{*};
6844    ///
6845    /// unsafe fn define_main_class(env: JNIEnv) -> jclass {
6846    ///     let class_blob = &[0u8]; // = include_bytes!("../my_java_project/src/main/java/org/example/Main.class");
6847    ///     let name = CString::new("org/example/Main").unwrap();
6848    ///     let class = env.DefineClass(name.as_ptr(), null_mut(), class_blob.as_ptr().cast(), class_blob.len() as i32);
6849    ///     if env.ExceptionCheck() {
6850    ///         env.ExceptionDescribe();
6851    ///         panic!("Failed to load main class check stderr for an error");
6852    ///     }
6853    ///     if class.is_null() {
6854    ///         panic!("Failed to load main class. JVM did not throw an exception!"); //Unlikely
6855    ///     }
6856    ///     class
6857    /// }
6858    /// ```
6859    ///
6860    pub unsafe fn DefineClass(&self, name: impl UseCString, classloader: jobject, data: *const jbyte, len: jsize) -> jclass {
6861        unsafe {
6862            name.use_as_const_c_char(|name| {
6863                #[cfg(feature = "asserts")]
6864                {
6865                    self.check_not_critical("DefineClass");
6866                    self.check_no_exception("DefineClass");
6867                    assert!(!name.is_null(), "DefineClass name is null");
6868                    self.check_is_classloader_or_null("DefineClass", classloader);
6869                    assert!(!data.is_null(), "DefineClass data is null");
6870                    assert!(len >= 0, "DefineClass len is negative {len}");
6871                }
6872
6873                self.jni::<extern "system" fn(JNIEnvVTable, *const c_char, jobject, *const jbyte, i32) -> jclass>(5)(self.vtable, name, classloader, data, len)
6874            })
6875        }
6876    }
6877
6878    ///
6879    /// Defines a class in the given classloader.
6880    ///
6881    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#DefineClass>
6882    ///
6883    /// # Arguments
6884    /// * `name` - name of the class
6885    /// * `classloader` - handle to the classloader java object. This can be null if the current JNI classloader should be used.
6886    /// * `data` - the binary content of the compiled java .class file.
6887    ///
6888    /// # Returns
6889    /// A local ref handle to the java.lang.Class (jclass) object that was just defined.
6890    /// On error null is returned.
6891    ///
6892    /// # Throws Java Exception:
6893    /// * `ClassFormatError` - if the class data does not specify a valid class.
6894    /// * `ClassCircularityError` - if a class or interface would be its own superclass or superinterface.
6895    /// * `OutOfMemoryError` - if the system runs out of memory.
6896    /// * `SecurityException` - if the caller attempts to define a class in the "java" package tree.
6897    ///
6898    ///
6899    /// # Panics
6900    /// if asserts feature is enabled and UB was detected
6901    ///
6902    /// # Safety
6903    ///
6904    /// Current thread must not be detached from JNI.
6905    ///
6906    /// Current thread does not hold a critical reference.
6907    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6908    ///
6909    /// Current thread is not currently throwing a Java exception.
6910    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
6911    ///
6912    /// The `classloader` handle must be a valid handle if it is not null.
6913    /// `name` must be a valid pointer to a 0 terminated utf-8 string. It must not be null.
6914    ///
6915    /// # Example
6916    /// ```rust
6917    /// use std::ffi::CString;
6918    /// use core::ptr::null_mut;
6919    /// use jni_simple::{*};
6920    ///
6921    /// unsafe fn define_main_class(env: JNIEnv) -> jclass {
6922    ///     let class_blob = &[0u8]; // = include_bytes!("../my_java_project/src/main/java/org/example/Main.class");
6923    ///     let name = CString::new("org/example/Main").unwrap();
6924    ///     let class = env.DefineClass_from_slice(name.as_ptr(), null_mut(), class_blob);
6925    ///     if env.ExceptionCheck() {
6926    ///         env.ExceptionDescribe();
6927    ///         panic!("Failed to load main class check stderr for an error");
6928    ///     }
6929    ///     if class.is_null() {
6930    ///         panic!("Failed to load main class. JVM did not throw an exception!"); //Unlikely
6931    ///     }
6932    ///     class
6933    /// }
6934    /// ```
6935    ///
6936    pub unsafe fn DefineClass_from_slice(&self, name: impl UseCString, classloader: jobject, data: impl AsRef<[u8]>) -> jclass {
6937        unsafe {
6938            let slice = data.as_ref();
6939            self.DefineClass(
6940                name,
6941                classloader,
6942                slice.as_ptr().cast::<jbyte>(),
6943                jsize::try_from(slice.len()).expect("data.len() > jsize::MAX"),
6944            )
6945        }
6946    }
6947
6948    ///
6949    /// Finds or loads a class.
6950    /// If the class was previously loaded by the current JNI Classloader then it is returned.
6951    /// If the class was not previously loaded then the current JNI Classloader will attempt to
6952    /// load it.
6953    ///
6954    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#FindClass>
6955    ///
6956    /// # Arguments
6957    /// * `name` - name of the class in jni notation (i.e: "java/lang/Object")
6958    ///
6959    /// # Returns
6960    /// A local ref handle to the java.lang.Class (jclass) object.
6961    /// On error null is returned.
6962    ///
6963    /// # Throws Java Exception:
6964    /// * `ClassFormatError` - if the class data does not specify a valid class.
6965    /// * `ClassCircularityError` - if a class or interface would be its own superclass or superinterface.
6966    /// * `OutOfMemoryError` - if the system runs out of memory.
6967    /// * `NoClassDefFoundError` -  if no definition for a requested class or interface can be found.
6968    ///
6969    ///
6970    /// # Panics
6971    /// if asserts feature is enabled and UB was detected
6972    ///
6973    /// # Safety
6974    ///
6975    /// Current thread must not be detached from JNI.
6976    ///
6977    /// Current thread does not hold a critical reference.
6978    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6979    ///
6980    /// Current thread is not currently throwing a Java exception.
6981    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
6982    ///
6983    /// `name` must be a valid pointer to a 0 terminated utf-8 string. It must not be null.
6984    ///
6985    /// # Example
6986    /// ```rust
6987    /// use std::ffi::CString;
6988    /// use jni_simple::{*};
6989    ///
6990    /// unsafe fn find_main_class(env: JNIEnv) -> jclass {
6991    ///     let name = CString::new("org/example/Main").unwrap();
6992    ///     let class = env.FindClass(name.as_ptr());
6993    ///     if env.ExceptionCheck() {
6994    ///         env.ExceptionDescribe();
6995    ///         panic!("Failed to find main class check stderr for an error");
6996    ///     }
6997    ///     if class.is_null() {
6998    ///         panic!("Failed to find main class. JVM did not throw an exception!"); //Unlikely
6999    ///     }
7000    ///     class
7001    /// }
7002    /// ```
7003    ///
7004    pub unsafe fn FindClass(&self, name: impl UseCString) -> jclass {
7005        unsafe {
7006            name.use_as_const_c_char(|name| {
7007                #[cfg(feature = "asserts")]
7008                {
7009                    self.check_not_critical("FindClass");
7010                    self.check_no_exception("FindClass");
7011                    assert!(!name.is_null(), "FindClass name is null");
7012                }
7013                self.jni::<extern "system" fn(JNIEnvVTable, *const c_char) -> jclass>(6)(self.vtable, name)
7014            })
7015        }
7016    }
7017
7018    ///
7019    /// Gets the superclass of the class `class`.
7020    ///
7021    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetSuperclass>
7022    ///
7023    /// # Arguments
7024    /// * `class` - handle to a class object. must not be null.
7025    ///
7026    /// # Returns
7027    /// A local ref handle to the superclass or null.
7028    /// If `class` refers to java.lang.Object class then null is returned.
7029    /// If `class` refers to any Interface then null is returned.
7030    ///
7031    ///
7032    ///
7033    /// # Panics
7034    /// if asserts feature is enabled and UB was detected
7035    ///
7036    /// # Safety
7037    ///
7038    /// Current thread must not be detached from JNI.
7039    ///
7040    /// Current thread does not hold a critical reference.
7041    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7042    ///
7043    /// Current thread is not currently throwing a Java exception.
7044    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
7045    ///
7046    /// `class` must be a valid non-null handle to a class object.
7047    ///
7048    /// # Example
7049    /// ```rust
7050    /// use jni_simple::{*};
7051    ///
7052    /// unsafe fn has_parent(env: JNIEnv, class: jclass) -> bool {
7053    ///     if class.is_null() {
7054    ///         return false;
7055    ///     }
7056    ///     let local = env.NewLocalRef(class);
7057    ///     let parent_or_null = env.GetSuperclass(local);
7058    ///     env.DeleteLocalRef(local);
7059    ///     if parent_or_null.is_null() {
7060    ///         return false;
7061    ///     }
7062    ///     env.DeleteLocalRef(parent_or_null);
7063    ///     true
7064    /// }
7065    /// ```
7066    ///
7067    pub unsafe fn GetSuperclass(&self, class: jclass) -> jclass {
7068        unsafe {
7069            #[cfg(feature = "asserts")]
7070            {
7071                self.check_not_critical("GetSuperclass");
7072                self.check_no_exception("GetSuperclass");
7073                self.check_is_class("GetSuperclass", class);
7074            }
7075            self.jni::<extern "system" fn(JNIEnvVTable, jclass) -> jclass>(10)(self.vtable, class)
7076        }
7077    }
7078
7079    ///
7080    /// Determines whether an object of clazz1 can be safely cast to clazz2.
7081    ///
7082    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#IsAssignableFrom>
7083    ///
7084    /// # Arguments
7085    /// * `class1` - handle to a class object. must not be null.
7086    /// * `class2` - handle to a class object. must not be null.
7087    ///
7088    /// # Returns
7089    /// true if either:
7090    /// * class1 and class2 refer to the same class.
7091    /// * class1 is a subclass of class2.
7092    /// * class1 has class2 as one of its interfaces.
7093    ///
7094    ///
7095    /// # Panics
7096    /// if asserts feature is enabled and UB was detected
7097    ///
7098    /// # Safety
7099    ///
7100    /// Current thread must not be detached from JNI.
7101    ///
7102    /// Current thread does not hold a critical reference.
7103    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7104    ///
7105    /// Current thread is not currently throwing a Java exception.
7106    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
7107    ///
7108    /// `class1` and `class2` must be valid non-null handles to class objects.
7109    ///
7110    /// # Example
7111    /// ```rust
7112    /// use jni_simple::{*};
7113    ///
7114    /// unsafe fn is_throwable_class(env: JNIEnv, class: jclass) -> bool {
7115    ///     let throwable_class = env.FindClass("java/lang/Throwable");
7116    ///     if throwable_class.is_null() {
7117    ///         env.ExceptionDescribe();
7118    ///         panic!("java/lang/Throwable not found! See stderr!");
7119    ///     }
7120    ///     let local = env.NewLocalRef(class);
7121    ///     if local.is_null() {
7122    ///         env.DeleteLocalRef(throwable_class);
7123    ///         return false;
7124    ///     }
7125    ///     let result = env.IsAssignableFrom(local, throwable_class);
7126    ///     env.DeleteLocalRef(local);
7127    ///     env.DeleteLocalRef(throwable_class);
7128    ///     result
7129    /// }
7130    /// ```
7131    ///
7132    pub unsafe fn IsAssignableFrom(&self, class1: jclass, class2: jclass) -> bool {
7133        unsafe {
7134            #[cfg(feature = "asserts")]
7135            {
7136                self.check_not_critical("IsAssignableFrom");
7137                self.check_no_exception("IsAssignableFrom");
7138                self.check_is_class("IsAssignableFrom", class1);
7139                self.check_is_class("IsAssignableFrom", class2);
7140            }
7141            self.jni::<extern "system" fn(JNIEnvVTable, jclass, jclass) -> jboolean>(11)(self.vtable, class1, class2).as_bool()
7142        }
7143    }
7144
7145    ///
7146    /// Throws a java.lang.Throwable. This is roughly equal to the throw keyword in Java.
7147    ///
7148    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Throw>
7149    ///
7150    /// # Arguments
7151    /// * `throwable` - handle to an object which is instanceof java.lang.Throwable. must not be null.
7152    ///
7153    /// # Returns
7154    /// `JNI_OK` on success. a negative value on failure.
7155    ///
7156    /// ## If `JNI_OK` was returned
7157    /// The JVM will be throwing an exception as a result of this call.
7158    ///
7159    /// When the current thread is throwing an exception you may only call the following JNI functions:
7160    /// * `ExceptionOccurred`
7161    /// * `ExceptionDescribe`
7162    /// * `ExceptionClear`
7163    /// * `ExceptionCheck`
7164    /// * `ReleaseStringChars`
7165    /// * `ReleaseStringUTFChars`
7166    /// * `ReleaseStringCritical`
7167    /// * `Release<Type>ArrayElements`
7168    /// * `ReleasePrimitiveArrayCritical`
7169    /// * `DeleteLocalRef`
7170    /// * `DeleteGlobalRef`
7171    /// * `DeleteWeakGlobalRef`
7172    /// * `MonitorExit`
7173    /// * `PushLocalFrame`
7174    /// * `PopLocalFrame`
7175    ///
7176    /// Calling any other JNI function is UB.
7177    ///
7178    ///
7179    ///
7180    /// # Panics
7181    /// if asserts feature is enabled and UB was detected
7182    ///
7183    /// # Safety
7184    ///
7185    /// Current thread must not be detached from JNI.
7186    ///
7187    /// Current thread does not hold a critical reference.
7188    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7189    ///
7190    /// Current thread is not currently throwing a Java exception.
7191    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
7192    ///
7193    /// `throwable` must be a valid non-null handle to an object which is instanceof java.lang.Throwable.
7194    ///
7195    /// # Example
7196    /// ```rust
7197    /// use jni_simple::{*};
7198    ///
7199    /// unsafe fn throw_null_pointer_exception(env: JNIEnv) {
7200    ///     let npe_class = env.FindClass("java/lang/NullPointerException");
7201    ///     if npe_class.is_null() {
7202    ///         env.ExceptionDescribe();
7203    ///         panic!("java/lang/NullPointerException not found!");
7204    ///     }
7205    ///     let npe_constructor = env.GetMethodID(npe_class, "<init>", "()V");
7206    ///     if npe_constructor.is_null() {
7207    ///         env.ExceptionDescribe();
7208    ///         env.DeleteLocalRef(npe_class);
7209    ///         panic!("java/lang/NullPointerException has no zero arg constructor!");
7210    ///     }
7211    ///
7212    ///     let npe_obj = env.NewObject0(npe_class, npe_constructor);
7213    ///     env.DeleteLocalRef(npe_class);
7214    ///     if npe_obj.is_null() {
7215    ///         env.ExceptionDescribe();
7216    ///         panic!("java/lang/NullPointerException failed to call zero arg constructor!");
7217    ///     }
7218    ///     env.Throw(npe_obj);
7219    ///     env.DeleteLocalRef(npe_obj);
7220    /// }
7221    /// ```
7222    ///
7223    pub unsafe fn Throw(&self, throwable: jthrowable) -> jint {
7224        unsafe {
7225            #[cfg(feature = "asserts")]
7226            {
7227                self.check_not_critical("Throw");
7228                self.check_no_exception("Throw");
7229                assert!(!throwable.is_null(), "Throw throwable is null");
7230            }
7231            self.jni::<extern "system" fn(JNIEnvVTable, jthrowable) -> jint>(13)(self.vtable, throwable)
7232        }
7233    }
7234
7235    ///
7236    /// Throws a new instance `class`. This is roughly equal to `throw new ...` in Java.
7237    ///
7238    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ThrowNew>
7239    ///
7240    /// # Arguments
7241    /// * `class` - handle to a non-abstract class instances of which can be cast to java.lang.Throwable. Must not be null.
7242    /// * `message` - the exception message. Must be null or a pointer to a 0 terminated utf-8 string.
7243    ///
7244    /// # Returns
7245    /// `JNI_OK` on success. a negative value on failure.
7246    ///
7247    /// ## If `JNI_OK` was returned
7248    /// The JVM will be throwing an exception as a result of this call.
7249    ///
7250    /// When the current thread is throwing an exception you may only call the following JNI functions:
7251    /// * `ExceptionOccurred`
7252    /// * `ExceptionDescribe`
7253    /// * `ExceptionClear`
7254    /// * `ExceptionCheck`
7255    /// * `ReleaseStringChars`
7256    /// * `ReleaseStringUTFChars`
7257    /// * `ReleaseStringCritical`
7258    /// * `Release<Type>ArrayElements`
7259    /// * `ReleasePrimitiveArrayCritical`
7260    /// * `DeleteLocalRef`
7261    /// * `DeleteGlobalRef`
7262    /// * `DeleteWeakGlobalRef`
7263    /// * `MonitorExit`
7264    /// * `PushLocalFrame`
7265    /// * `PopLocalFrame`
7266    ///
7267    /// Calling any other JNI function is UB.
7268    ///
7269    /// # Throws Java Exception:
7270    /// * `NoSuchMethodError` if the class has no suitable constructor for the argument supplied. Note: the return value remains `JNI_OK`!
7271    ///   - null `message`: no zero arg or one arg String constructor exists.
7272    ///   - non-null `message`: no one arg String constructor exists.
7273    ///
7274    ///
7275    /// # Panics
7276    /// if asserts feature is enabled and UB was detected
7277    ///
7278    /// # Safety
7279    ///
7280    /// Current thread must not be detached from JNI.
7281    ///
7282    /// Current thread does not hold a critical reference.
7283    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7284    ///
7285    /// Current thread is not currently throwing a Java exception.
7286    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
7287    ///
7288    /// `class` must be a valid non-null handle to a class which is:
7289    /// * Not abstract
7290    /// * Is a descendant of java.lang.Throwable (instances can be cast to Throwable)
7291    ///
7292    /// `message` must be a pointer to a 0 terminated utf-8 string or null.
7293    ///
7294    /// # Example
7295    /// ```rust
7296    /// use std::ffi::CString;
7297    /// use core::ptr::null;
7298    /// use jni_simple::{*};
7299    ///
7300    /// unsafe fn throw_illegal_argument_exception(env: JNIEnv, message: Option<&str>) {
7301    ///     let npe_class = env.FindClass("java/lang/IllegalArgumentException");
7302    ///     if npe_class.is_null() {
7303    ///         env.ExceptionDescribe();
7304    ///         panic!("java/lang/IllegalArgumentException not found!");
7305    ///     }
7306    ///     match message {
7307    ///         None => {
7308    ///             env.ThrowNew(npe_class, ());
7309    ///         }
7310    ///         Some(message) => {
7311    ///             let message = CString::new(message).expect("message contains 0 byte!");
7312    ///             env.ThrowNew(npe_class, message.as_ptr());
7313    ///         }
7314    ///     }
7315    ///     env.DeleteLocalRef(npe_class);
7316    /// }
7317    /// ```
7318    ///
7319    pub unsafe fn ThrowNew(&self, class: jclass, message: impl UseCString) -> jint {
7320        unsafe {
7321            message.use_as_const_c_char(|message| {
7322                #[cfg(feature = "asserts")]
7323                {
7324                    self.check_not_critical("ThrowNew");
7325                    self.check_no_exception("ThrowNew");
7326                    self.check_is_exception_class("ThrowNew", class);
7327                    self.check_is_not_abstract("ThrowNew", class);
7328                }
7329                self.jni::<extern "system" fn(JNIEnvVTable, jclass, *const c_char) -> jint>(14)(self.vtable, class, message)
7330            })
7331        }
7332    }
7333
7334    ///
7335    /// Returns a local reference to the exception currently being thrown.
7336    /// Calling this function does not clear the exception.
7337    /// It stays thrown until for example `ExceptionClear` is called.
7338    ///
7339    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ExceptionOccurred>
7340    ///
7341    /// # Returns
7342    /// A local ref to the throwable that is currently being thrown.
7343    /// null if no throwable is currently thrown.
7344    ///
7345    ///
7346    /// # Panics
7347    /// if asserts feature is enabled and UB was detected
7348    ///
7349    /// # Safety
7350    ///
7351    /// Current thread must not be detached from JNI.
7352    ///
7353    /// Current thread does not hold a critical reference.
7354    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7355    ///
7356    /// # Example
7357    /// ```rust
7358    /// use jni_simple::{*};
7359    ///
7360    ///
7361    /// unsafe fn test(env: JNIEnv) {
7362    ///     let special_exception = env.FindClass("org/example/SuperSpecialException");
7363    ///     if special_exception.is_null() {
7364    ///         unimplemented!("handle class not found")
7365    ///     }
7366    ///     let my_class = env.FindClass("org/example/TestClass");
7367    ///     if my_class.is_null() {
7368    ///         unimplemented!("handle class not found")
7369    ///     }
7370    ///     let my_zero_arg_constructor = env.GetMethodID(my_class, "<init>", "()V");
7371    ///     if my_zero_arg_constructor.is_null() {
7372    ///         unimplemented!("handle no zero arg constructor")
7373    ///     }
7374    ///     let my_object = env.NewObject0(my_class, my_zero_arg_constructor);
7375    ///     if env.ExceptionCheck() {
7376    ///         let exception_object = env.ExceptionOccurred();
7377    ///         env.ExceptionClear();
7378    ///         if env.IsInstanceOf(exception_object, special_exception) {
7379    ///             panic!("zero arg constructor threw SuperSpecialException!")
7380    ///         }
7381    ///
7382    ///         unimplemented!("handle other exceptions");
7383    ///     }
7384    ///     unimplemented!()
7385    /// }
7386    /// ```
7387    ///
7388    #[must_use]
7389    pub unsafe fn ExceptionOccurred(&self) -> jthrowable {
7390        unsafe {
7391            #[cfg(feature = "asserts")]
7392            {
7393                self.check_not_critical("ExceptionOccurred");
7394            }
7395            self.jni::<extern "system" fn(JNIEnvVTable) -> jthrowable>(15)(self.vtable)
7396        }
7397    }
7398
7399    ///
7400    /// Print the stacktrace and message currently thrown to STDOUT.
7401    /// A side effect of this function is that the exception is also cleared.
7402    /// This is roughly equivalent to calling `java.lang.Throwable#printStackTrace()` in java.
7403    ///
7404    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ExceptionDescribe>
7405    ///
7406    /// If no exception is currently thrown then this method is a no-op.
7407    ///
7408    ///
7409    /// # Panics
7410    /// if asserts feature is enabled and UB was detected
7411    ///
7412    /// # Safety
7413    ///
7414    /// Current thread must not be detached from JNI.
7415    ///
7416    /// Current thread does not hold a critical reference.
7417    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7418    ///
7419    /// # Example
7420    /// ```rust
7421    /// use jni_simple::{*};
7422    ///
7423    ///
7424    /// unsafe fn test(env: JNIEnv) {
7425    ///     let my_class = env.FindClass("org/example/TestClass");
7426    ///     if my_class.is_null() {
7427    ///         env.ExceptionDescribe();
7428    ///         panic!("Class not found check stderr");
7429    ///     }
7430    ///     unimplemented!()
7431    /// }
7432    /// ```
7433    ///
7434    pub unsafe fn ExceptionDescribe(&self) {
7435        unsafe {
7436            #[cfg(feature = "asserts")]
7437            {
7438                self.check_not_critical("ExceptionDescribe");
7439            }
7440            self.jni::<extern "system" fn(JNIEnvVTable)>(16)(self.vtable);
7441        }
7442    }
7443
7444    ///
7445    /// Print the stacktrace and message currently thrown to STDOUT.
7446    /// A side effect of this function is that the exception is also cleared.
7447    /// This is roughly equivalent to calling `java.lang.Throwable#printStackTrace()` in java.
7448    ///
7449    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ExceptionDescribe>
7450    ///
7451    /// If no exception is currently thrown then this method is a no-op.
7452    ///
7453    ///
7454    /// # Panics
7455    /// if asserts feature is enabled and UB was detected
7456    ///
7457    /// # Safety
7458    ///
7459    /// Current thread must not be detached from JNI.
7460    ///
7461    /// Current thread does not hold a critical reference.
7462    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7463    ///
7464    /// # Example
7465    /// ```rust
7466    /// use jni_simple::{*};
7467    ///
7468    ///
7469    /// unsafe fn test(env: JNIEnv) {
7470    ///     let mut my_class = env.FindClass("org/example/TestClass");
7471    ///     if my_class.is_null() {
7472    ///         env.ExceptionClear();
7473    ///         my_class = env.FindClass("org/example/FallbackClass");
7474    ///     }
7475    ///     unimplemented!()
7476    /// }
7477    /// ```
7478    ///
7479    pub unsafe fn ExceptionClear(&self) {
7480        unsafe {
7481            #[cfg(feature = "asserts")]
7482            {
7483                self.check_not_critical("ExceptionClear");
7484            }
7485            self.jni::<extern "system" fn(JNIEnvVTable)>(17)(self.vtable);
7486        }
7487    }
7488
7489    ///
7490    /// Raises a fatal error and does not expect the VM to recover. This function does not return.
7491    ///
7492    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#FatalError>
7493    ///
7494    /// # Arguments
7495    /// * `msg` - message that should be present in the error report. 0 terminated utf-8. Must not be null.
7496    ///
7497    ///
7498    /// # Panics
7499    /// if asserts feature is enabled and UB was detected
7500    ///
7501    /// # Safety
7502    ///
7503    /// Current thread must not be detached from JNI.
7504    ///
7505    /// `msg` must be a non-null pointer to a valid 0 terminated utf-8 string.
7506    ///
7507    pub unsafe fn FatalError(&self, msg: impl UseCString) -> ! {
7508        unsafe {
7509            msg.use_as_const_c_char(|msg| {
7510                #[cfg(feature = "asserts")]
7511                {
7512                    assert!(!msg.is_null(), "FatalError msg is null");
7513                }
7514                self.jni::<extern "system" fn(JNIEnvVTable, *const c_char)>(18)(self.vtable, msg);
7515                unreachable!("FatalError");
7516            })
7517        }
7518    }
7519
7520    ///
7521    /// Checks if an exception is thrown on the current thread.
7522    ///
7523    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ExceptionCheck>
7524    ///
7525    /// # Returns
7526    /// true if an exception is thrown on the current thread, false otherwise.
7527    ///
7528    ///
7529    /// # Panics
7530    /// if asserts feature is enabled and UB was detected
7531    ///
7532    /// # Safety
7533    ///
7534    /// Current thread must not be detached from JNI.
7535    ///
7536    /// Current thread does not hold a critical reference.
7537    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7538    ///
7539    /// # Example
7540    /// ```rust
7541    /// use jni_simple::{*};
7542    ///
7543    ///
7544    /// unsafe fn test(env: JNIEnv) {
7545    ///     let my_class = env.FindClass("org/example/TestClass");
7546    ///     if my_class.is_null() {
7547    ///         unimplemented!("handle class not found")
7548    ///     }
7549    ///     let my_zero_arg_constructor = env.GetMethodID(my_class, "<init>", "()V");
7550    ///     if my_zero_arg_constructor.is_null() {
7551    ///         unimplemented!("handle no zero arg constructor")
7552    ///     }
7553    ///     let my_object = env.NewObject0(my_class, my_zero_arg_constructor);
7554    ///     if env.ExceptionCheck() {
7555    ///         panic!("org/example/TestClass zero arg constructor threw an exception!");
7556    ///     }
7557    ///     unimplemented!()
7558    /// }
7559    /// ```
7560    ///
7561    #[must_use]
7562    pub unsafe fn ExceptionCheck(&self) -> bool {
7563        unsafe {
7564            #[cfg(feature = "asserts")]
7565            {
7566                self.check_not_critical("ExceptionCheck");
7567            }
7568            self.jni::<extern "system" fn(JNIEnvVTable) -> jboolean>(228)(self.vtable).as_bool()
7569        }
7570    }
7571
7572    ///
7573    /// Creates a new global reference from an existing reference.
7574    ///
7575    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewGlobalRef>
7576    ///
7577    /// # Arguments
7578    /// * `obj` - a valid reference or null.
7579    ///
7580    /// # Returns
7581    /// the newly created global reference or null.
7582    /// null is returned if:
7583    /// * the argument `obj` is null
7584    /// * the system ran out of memory
7585    /// * `obj` is a weak reference that has already been garbage collected.
7586    ///
7587    ///
7588    /// # Panics
7589    /// if asserts feature is enabled and UB was detected
7590    ///
7591    /// # Safety
7592    ///
7593    /// Current thread must not be detached from JNI.
7594    ///
7595    /// Current thread does not hold a critical reference.
7596    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7597    ///
7598    /// Current thread is not currently throwing a Java exception.
7599    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
7600    ///
7601    /// `obj` must not refer to a reference that has already been deleted by calling `DeleteLocalRef`, `DeleteGlobalRef`, `DeleteWeakGlobalRef`
7602    ///
7603    pub unsafe fn NewGlobalRef(&self, obj: jobject) -> jobject {
7604        unsafe {
7605            #[cfg(feature = "asserts")]
7606            {
7607                self.check_not_critical("NewGlobalRef");
7608                self.check_no_exception("NewGlobalRef");
7609            }
7610            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jobject>(21)(self.vtable, obj)
7611        }
7612    }
7613
7614    ///
7615    /// Deletes a global reference to an object allowing the garbage collector to free it if no more
7616    /// references to it exists.
7617    ///
7618    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#DeleteGlobalRef>
7619    ///
7620    /// # Arguments
7621    /// * `obj` - a valid non-null global reference.
7622    ///
7623    ///
7624    /// # Panics
7625    /// if asserts feature is enabled and UB was detected
7626    ///
7627    /// # Safety
7628    ///
7629    /// Current thread must not be detached from JNI.
7630    ///
7631    /// Current thread does not hold a critical reference.
7632    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7633    ///
7634    /// Current thread is not currently throwing a Java exception.
7635    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
7636    ///
7637    /// `obj` must not be null.
7638    /// `obj` must be a global reference.
7639    /// `obj` must not refer to an already deleted global reference. (Double free)
7640    ///
7641    pub unsafe fn DeleteGlobalRef(&self, obj: jobject) {
7642        unsafe {
7643            #[cfg(feature = "asserts")]
7644            {
7645                self.check_not_critical("DeleteGlobalRef");
7646                assert!(!obj.is_null(), "DeleteGlobalRef obj is null");
7647                match self.GetObjectRefType(obj) {
7648                    jobjectRefType::JNIInvalidRefType => panic!("DeleteGlobalRef invalid non null reference"),
7649                    jobjectRefType::JNILocalRefType => panic!("DeleteGlobalRef local reference passed"),
7650                    jobjectRefType::JNIWeakGlobalRefType => panic!("DeleteGlobalRef weak global reference passed"),
7651                    jobjectRefType::JNIGlobalRefType => {}
7652                }
7653            }
7654            self.jni::<extern "system" fn(JNIEnvVTable, jobject)>(22)(self.vtable, obj);
7655        }
7656    }
7657
7658    ///
7659    /// Deletes a local reference to an object allowing the garbage collector to free it if no more
7660    /// references to it exists.
7661    ///
7662    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#DeleteGlobalRef>
7663    ///
7664    /// # Arguments
7665    /// * `obj` - a valid non-null local reference.
7666    ///
7667    ///
7668    /// # Panics
7669    /// if asserts feature is enabled and UB was detected
7670    ///
7671    /// # Safety
7672    ///
7673    /// Current thread must not be detached from JNI.
7674    ///
7675    /// Current thread does not hold a critical reference.
7676    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7677    ///
7678    /// Current thread is not currently throwing a Java exception.
7679    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
7680    ///
7681    /// `obj` must not be null.
7682    /// `obj` must be a local reference.
7683    /// `obj` must not refer to an already deleted local reference. (Double free)
7684    ///
7685    pub unsafe fn DeleteLocalRef(&self, obj: jobject) {
7686        unsafe {
7687            #[cfg(feature = "asserts")]
7688            {
7689                self.check_not_critical("DeleteLocalRef");
7690                assert!(!obj.is_null(), "DeleteLocalRef obj is null");
7691                if !self.ExceptionCheck() {
7692                    match self.GetObjectRefType(obj) {
7693                        jobjectRefType::JNIInvalidRefType => panic!("DeleteLocalRef invalid non null reference"),
7694                        jobjectRefType::JNILocalRefType => {}
7695                        jobjectRefType::JNIGlobalRefType => panic!("DeleteLocalRef global reference passed"),
7696                        jobjectRefType::JNIWeakGlobalRefType => panic!("DeleteLocalRef weak global reference passed"),
7697                    }
7698                }
7699            }
7700            self.jni::<extern "system" fn(JNIEnvVTable, jobject)>(23)(self.vtable, obj);
7701        }
7702    }
7703
7704    ///
7705    /// The jvm guarantees that a native method can have at least 16 local references.
7706    /// Creating any more than 16 local references without calling this function is effectively UB.
7707    /// This function instructs the JVM to ensure that at least
7708    /// `capacity` amount of local references are available for allocation.
7709    /// This function can be called multiple times to increase the amount of required locals.
7710    ///
7711    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#EnsureLocalCapacity>
7712    ///
7713    ///
7714    /// # Arguments
7715    /// * `capacity` - amount of local references the jvm must provide. Must be larger than 0.
7716    ///
7717    /// # Returns
7718    /// 0 on success, negative value indicating the error.
7719    ///
7720    /// # Throws Java Exception
7721    /// * `OutOfMemoryError` - if the vm runs out of memory ensuring capacity. This is never the case when 0 is returned.
7722    ///
7723    ///
7724    /// # Panics
7725    /// if asserts feature is enabled and UB was detected
7726    ///
7727    /// # Safety
7728    ///
7729    /// Current thread must not be detached from JNI.
7730    ///
7731    /// Current thread does not hold a critical reference.
7732    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7733    ///
7734    /// Current thread is not currently throwing a Java exception.
7735    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
7736    ///
7737    /// `capacity` must not be 0 or negative.
7738    ///
7739    /// ## Observed UB when more locals are allocated than ensured
7740    /// This behavior depends heavily on the jvm used and the arguments used to start it. This list is incomplete
7741    /// * Heap/Stack corruption.
7742    /// * JVM calls `FatalError` and aborts the process.
7743    /// * JVM Functions that would return a local reference return null.
7744    /// * JVM simply allocates more locals than ensured. (starting the jvm with -verbose:jni will log this)
7745    ///
7746    #[must_use]
7747    pub unsafe fn EnsureLocalCapacity(&self, capacity: jint) -> jint {
7748        unsafe {
7749            #[cfg(feature = "asserts")]
7750            {
7751                self.check_not_critical("EnsureLocalCapacity");
7752                self.check_no_exception("EnsureLocalCapacity");
7753                assert!(capacity >= 0, "EnsureLocalCapacity capacity is negative");
7754            }
7755            self.jni::<extern "system" fn(JNIEnvVTable, jint) -> jint>(26)(self.vtable, capacity)
7756        }
7757    }
7758
7759    ///
7760    /// Creates a new local reference frame, in which at least a given number of local references can be created.
7761    /// Note that local references already created in previous local frames are still valid in the current local frame.
7762    /// This method should be called by code that is called from unknown code where it is not known if enough
7763    /// local capacity is available. This method is superior to just increasing the capacity by calling `EnsureLocalCapacity`
7764    /// because that requires at least a rough knowledge of how many locals the caller itself has used and still needs.
7765    ///
7766    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#PushLocalFrame>
7767    ///
7768    ///
7769    /// # Arguments
7770    /// * `capacity` - amount of local references the jvm must provide. Must be larger than 0.
7771    ///
7772    /// # Returns
7773    /// 0 on success, negative value indicating the error.
7774    ///
7775    /// # Throws Java Exception
7776    /// * `OutOfMemoryError` - if the vm runs out of memory ensuring capacity. This is never the case when 0 is returned.
7777    ///
7778    ///
7779    /// # Panics
7780    /// if asserts feature is enabled and UB was detected
7781    ///
7782    /// # Safety
7783    ///
7784    /// Current thread must not be detached from JNI.
7785    ///
7786    /// Current thread does not hold a critical reference.
7787    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7788    ///
7789    /// Current thread is not currently throwing a Java exception.
7790    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
7791    ///
7792    /// `capacity` must not be 0 or negative.
7793    ///
7794    /// returning back to java code without cleaning up all created local reference frames by calling `PopLocalFrame` is UB.
7795    ///
7796    /// ## Observed UB when more locals are allocated than ensured
7797    /// This behavior depends heavily on the jvm used and the arguments used to start it. This list is incomplete
7798    /// * Heap/Stack corruption.
7799    /// * JVM calls `FatalError` and aborts the process.
7800    /// * JVM Functions that would return a local reference return null.
7801    /// * JVM simply allocates more locals than ensured. (starting the jvm with -verbose:jni will log this)
7802    ///
7803    #[must_use]
7804    pub unsafe fn PushLocalFrame(&self, capacity: jint) -> jint {
7805        unsafe {
7806            #[cfg(feature = "asserts")]
7807            {
7808                self.check_not_critical("PushLocalFrame");
7809            }
7810            self.jni::<extern "system" fn(JNIEnvVTable, jint) -> jint>(19)(self.vtable, capacity)
7811        }
7812    }
7813
7814    ///
7815    /// Pops a local reference frame created with `PushLocalFrame`
7816    /// All local references created within this reference frame are freed automatically
7817    /// and are no longer valid when this call returns.
7818    ///
7819    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#PopLocalFrame>
7820    ///
7821    /// # Arguments
7822    /// * result - arbitrary jni reference that should be moved to the parent reference frame.
7823    ///   this is similar to a "return" value and may be null if no such result is needed.
7824    ///   the local reference this function returns is valid within the parent local reference frame.
7825    ///
7826    /// # Returns
7827    /// A valid local reference that points to the same object as the reference `result`. Is null if `result` is null.
7828    ///
7829    ///
7830    /// # Panics
7831    /// if asserts feature is enabled and UB was detected
7832    ///
7833    /// # Safety
7834    ///
7835    /// Current thread must not be detached from JNI.
7836    ///
7837    /// Current thread does not hold a critical reference.
7838    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7839    ///
7840    /// result must be a valid reference or null
7841    ///
7842    ///
7843    pub unsafe fn PopLocalFrame(&self, result: jobject) -> jobject {
7844        unsafe {
7845            #[cfg(feature = "asserts")]
7846            {
7847                self.check_not_critical("PopLocalFrame");
7848                self.check_ref_obj_permit_null("PopLocalFrame", result);
7849            }
7850            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jobject>(20)(self.vtable, result)
7851        }
7852    }
7853
7854    ///
7855    /// Creates a new local reference from the given jobject.
7856    ///
7857    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewLocalRef>
7858    ///
7859    /// # Arguments
7860    /// * obj - arbitrary valid jni reference or null
7861    ///
7862    /// # Returns
7863    /// A valid local reference that points to the same object as the reference `obj`. Is null if `obj` is null.
7864    ///
7865    ///
7866    /// # Panics
7867    /// if asserts feature is enabled and UB was detected
7868    ///
7869    /// # Safety
7870    ///
7871    /// Current thread must not be detached from JNI.
7872    ///
7873    /// Current thread must not be throwing an exception.
7874    ///
7875    /// Current thread does not hold a critical reference.
7876    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7877    ///
7878    /// `obj` must be a valid reference or null
7879    ///
7880    pub unsafe fn NewLocalRef(&self, obj: jobject) -> jobject {
7881        unsafe {
7882            #[cfg(feature = "asserts")]
7883            {
7884                self.check_not_critical("NewLocalRef");
7885                self.check_no_exception("NewLocalRef");
7886                self.check_ref_obj_permit_null("NewLocalRef", obj);
7887            }
7888            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jobject>(25)(self.vtable, obj)
7889        }
7890    }
7891
7892    ///
7893    /// Creates a new weak global reference from the given jobject.
7894    ///
7895    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewWeakGlobalRef>
7896    ///
7897    /// # Arguments
7898    /// * obj - arbitrary valid jni reference or null
7899    ///
7900    /// # Returns
7901    /// A valid local weak global reference that points to the same object as the reference `obj`. Is null if `obj` is null.
7902    ///
7903    /// # Throws Java Exception
7904    /// If the JVM runs out of memory, an `OutOfMemoryError` will be thrown.
7905    ///
7906    ///
7907    /// # Panics
7908    /// if asserts feature is enabled and UB was detected
7909    ///
7910    /// # Safety
7911    ///
7912    /// Current thread must not be detached from JNI.
7913    ///
7914    /// Current thread must not be throwing an exception.
7915    ///
7916    /// Current thread does not hold a critical reference.
7917    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7918    ///
7919    /// `obj` must be a valid reference or null
7920    ///
7921    pub unsafe fn NewWeakGlobalRef(&self, obj: jobject) -> jweak {
7922        unsafe {
7923            #[cfg(feature = "asserts")]
7924            {
7925                self.check_not_critical("NewWeakGlobalRef");
7926                self.check_no_exception("NewWeakGlobalRef");
7927            }
7928            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jweak>(226)(self.vtable, obj)
7929        }
7930    }
7931
7932    ///
7933    /// Deletes a weak global reference.
7934    ///
7935    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#DeleteWeakGlobalRef>
7936    ///
7937    /// # Arguments
7938    /// * obj - a weak global reference.
7939    ///     * must not already be deleted.
7940    ///     * must not be null.
7941    ///     * If the referred obj has been garbage collected by the JVM already or not is irrelevant.
7942    ///
7943    /// # Returns
7944    /// A valid local weak global reference that points to the same object as the reference `obj`. Is null if `obj` is null.
7945    ///
7946    ///
7947    /// # Panics
7948    /// if asserts feature is enabled and UB was detected
7949    ///
7950    /// # Safety
7951    ///
7952    /// Current thread must not be detached from JNI.
7953    ///
7954    /// Current thread does not hold a critical reference.
7955    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7956    ///
7957    /// `obj` must not be null and be a valid weak reference that has not yet been deleted.
7958    ///
7959    pub unsafe fn DeleteWeakGlobalRef(&self, obj: jweak) {
7960        unsafe {
7961            #[cfg(feature = "asserts")]
7962            {
7963                self.check_not_critical("DeleteWeakGlobalRef");
7964                assert!(!obj.is_null(), "DeleteWeakGlobalRef obj is null");
7965                if !self.ExceptionCheck() {
7966                    match self.GetObjectRefType(obj) {
7967                        jobjectRefType::JNIInvalidRefType => panic!("DeleteWeakGlobalRef invalid non null reference"),
7968                        jobjectRefType::JNILocalRefType => panic!("DeleteWeakGlobalRef local reference passed"),
7969                        jobjectRefType::JNIGlobalRefType => panic!("DeleteWeakGlobalRef strong global reference passed"),
7970                        jobjectRefType::JNIWeakGlobalRefType => {}
7971                    }
7972                }
7973            }
7974
7975            self.jni::<extern "system" fn(JNIEnvVTable, jobject)>(227)(self.vtable, obj);
7976        }
7977    }
7978
7979    ///
7980    /// Allocates a new direct instance of the given class without calling any constructor.
7981    ///
7982    /// Every field in the instance will be the JVM default value for the type.
7983    /// * Every numeric is 0,
7984    /// * Every reference/object is null,
7985    /// * Every boolean is false,
7986    /// * Every array is null
7987    ///
7988    /// This will also not perform default initialization of types so a field that is initialized like this in java:
7989    /// ```java
7990    /// private int x = 5;
7991    /// ```
7992    /// This field would not be 5 but be 0 in the instance returned by `AllocObject`.
7993    ///
7994    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#AllocObject>
7995    ///
7996    /// # Note
7997    /// Be aware that the created instance may be initially in a state that is invalid for the given java object.
7998    /// Any object constructed using `AllocObject` should be brought into a valid state by essentially performing duties similar to
7999    /// what the constructor of that object would do. Handling errors during the subsequent initialization process can
8000    /// be especially tricky concerning object finalization. As part of error handling the object will likely be freed which
8001    /// then causes the JVM may run the finalization implementation on the object that is from a java point of view in an invalid state.
8002    /// This might cause undefined behavior in the jvm, depending on what the finalization implementation of the object does.
8003    /// Future Java releases have commited to removing object finalization. This restriction is known to apply to java 21 and lower.
8004    ///
8005    /// Calling any java methods on or with the partially initialized object should be avoided,
8006    /// as the jvm may for example have made assumptions about not yet initialized final fields.
8007    /// How the jvm reacts to this is entirely dependent on which jvm implementation you use and how it was started.
8008    ///
8009    /// # Arguments
8010    /// * `clazz` - reference to a class.
8011    ///     * must not be null
8012    ///     * must be valid
8013    ///     * must not be already garbage collected
8014    ///
8015    /// # Returns
8016    /// A local reference to the newly created object or null if the object could not be created.
8017    ///
8018    /// # Throws Java Exception
8019    /// * `OutOfMemoryError`
8020    ///     * if the jvm runs out of memory.
8021    /// * `InstantiationException`
8022    ///     * if the class is an interface or an abstract class.
8023    ///
8024    ///
8025    ///
8026    /// # Panics
8027    /// if asserts feature is enabled and UB was detected
8028    ///
8029    /// # Safety
8030    ///
8031    /// Current thread must not be detached from JNI.
8032    ///
8033    /// Current thread does not hold a critical reference.
8034    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8035    ///
8036    /// `clazz` must not be null and be a valid reference that has not yet been deleted or garbage collected.
8037    ///
8038    ///
8039    pub unsafe fn AllocObject(&self, clazz: jclass) -> jobject {
8040        unsafe {
8041            #[cfg(feature = "asserts")]
8042            {
8043                assert!(!clazz.is_null(), "AllocObject clazz is null");
8044                self.check_not_critical("AllocObject");
8045                self.check_no_exception("AllocObject");
8046                self.check_is_class("AllocObject", clazz);
8047            }
8048            self.jni::<extern "system" fn(JNIEnvVTable, jclass) -> jobject>(27)(self.vtable, clazz)
8049        }
8050    }
8051
8052    ///
8053    /// Allocates an object by calling a constructor.
8054    ///
8055    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewObject>
8056    ///
8057    ///
8058    /// # Arguments
8059    /// * `clazz` - reference to a class.
8060    ///     * must not be null
8061    ///     * must be valid
8062    ///     * must not be already garbage collected
8063    ///
8064    /// * `constructor` - jmethodID of a constructor
8065    ///     * must be a constructor (`<init>` method name)
8066    ///     * must be a constructor of `clazz`
8067    ///
8068    /// * args - java method parameters
8069    ///     * can be null for 0 arg constructors.
8070    ///     * must be a valid pointer into a jtype array with at least the same length as the java method has parameters.
8071    ///     * the parameters must be valid types.
8072    ///
8073    /// # Returns
8074    /// A local reference to the newly created object or null if the object could not be created.
8075    ///
8076    /// # Throws Java Exception
8077    /// * `OutOfMemoryError`
8078    ///     * if the jvm runs out of memory.
8079    /// * `InstantiationException`
8080    ///     * if the class is an interface or an abstract class.
8081    /// * Any exception thrown by the constructor
8082    ///
8083    ///
8084    /// # Panics
8085    /// if asserts feature is enabled and UB was detected
8086    ///
8087    /// # Safety
8088    ///
8089    /// Current thread must not be detached from JNI.
8090    ///
8091    /// Current thread does not hold a critical reference.
8092    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8093    ///
8094    /// `clazz` must not be null and be a valid reference that has not yet been deleted or garbage collected.
8095    ///
8096    /// `constructor` must be a valid non-static methodID of `clazz` that is a constructor.
8097    ///
8098    /// `args` must be valid, have enough length and contain valid parameters for the method.
8099    /// * for example calling a java constructor that needs a String as parameter, with an 'int' instead is UB.
8100    ///
8101    pub unsafe fn NewObjectA(&self, clazz: jclass, constructor: jmethodID, args: *const jtype) -> jobject {
8102        unsafe {
8103            #[cfg(feature = "asserts")]
8104            {
8105                self.check_not_critical("NewObjectA");
8106                self.check_no_exception("NewObjectA");
8107                assert!(!constructor.is_null(), "NewObjectA constructor is null");
8108                self.check_is_class("NewObjectA", clazz);
8109                //TODO check if constructor is actually constructor or just a normal method.
8110                //TODO check arguments match constructor
8111            }
8112            self.jni::<extern "system" fn(JNIEnvVTable, jclass, jmethodID, *const jtype) -> jobject>(30)(self.vtable, clazz, constructor, args)
8113        }
8114    }
8115
8116    ///
8117    /// Creates a new object instance by calling the zero arg constructor.
8118    ///
8119    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewObject>
8120    ///
8121    ///
8122    /// # Arguments
8123    /// * `clazz` - reference to a class.
8124    ///     * must not be null
8125    ///     * must be valid
8126    ///     * must not be already garbage collected
8127    /// * `constructor` - jmethodID of a constructor
8128    ///     * must be a constructor
8129    ///     * must be a constructor of `clazz`
8130    ///     * must have 0 args
8131    ///
8132    /// # Returns
8133    /// A local reference to the newly created object or null if the object could not be created.
8134    ///
8135    /// # Throws Java Exception
8136    /// * `OutOfMemoryError`
8137    ///     * if the jvm runs out of memory.
8138    /// * `InstantiationException`
8139    ///     * if the class is an interface or an abstract class.
8140    /// * Any exception thrown by the constructor
8141    ///
8142    ///
8143    /// # Panics
8144    /// if asserts feature is enabled and UB was detected
8145    ///
8146    /// # Safety
8147    ///
8148    /// Current thread must not be detached from JNI.
8149    ///
8150    /// Current thread does not hold a critical reference.
8151    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8152    ///
8153    /// `clazz` must not be null and be a valid reference that has not yet been deleted or garbage collected.
8154    ///
8155    /// `constructor` must be a valid non-static methodID of `clazz` that is a constructor.
8156    ///
8157    /// `constructor` must have 0 arguments.
8158    ///
8159    pub unsafe fn NewObject0(&self, clazz: jclass, constructor: jmethodID) -> jobject {
8160        unsafe {
8161            #[cfg(feature = "asserts")]
8162            {
8163                self.check_not_critical("NewObject0");
8164                self.check_no_exception("NewObject0");
8165                assert!(!constructor.is_null(), "NewObject0 constructor is null");
8166                self.check_is_class("NewObject0", clazz);
8167                //TODO check if constructor is actually constructor or just a normal method.
8168                //TODO check zero arg.
8169            }
8170            self.jni::<extern "C" fn(JNIEnvVTable, jclass, jmethodID) -> jobject>(28)(self.vtable, clazz, constructor)
8171        }
8172    }
8173
8174    ///
8175    /// Creates a new object instance by calling the one arg constructor.
8176    ///
8177    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewObject>
8178    ///
8179    ///
8180    /// # Arguments
8181    /// * `clazz` - reference to a class.
8182    ///     * must not be null
8183    ///     * must be valid
8184    ///     * must not be already garbage collected
8185    ///
8186    /// * `constructor` - jmethodID of a constructor
8187    ///     * must be a constructor
8188    ///     * must be a constructor of `clazz`
8189    ///     * must have 1 arg
8190    ///
8191    /// * `arg1` - the argument
8192    ///     * must be of the exact type that the constructor needs to be called with.
8193    ///
8194    /// # Returns
8195    /// A local reference to the newly created object or null if the object could not be created.
8196    ///
8197    /// # Throws Java Exception
8198    /// * `OutOfMemoryError`
8199    ///     * if the jvm runs out of memory.
8200    /// * `InstantiationException`
8201    ///     * if the class is an interface or an abstract class.
8202    /// * Any exception thrown by the constructor
8203    ///
8204    ///
8205    /// # Panics
8206    /// if asserts feature is enabled and UB was detected
8207    ///
8208    /// # Safety
8209    ///
8210    /// Current thread must not be detached from JNI.
8211    ///
8212    /// Current thread does not hold a critical reference.
8213    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8214    ///
8215    /// `clazz` must not be null and be a valid reference that has not yet been deleted or garbage collected.
8216    ///
8217    /// `constructor` must be a valid non-static methodID of `clazz` that is a constructor.
8218    ///
8219    /// `constructor` must have 1 argument.
8220    ///
8221    /// `JType` of `arg1` must match the argument type of the java method exactly.
8222    /// * absolutely no coercion is performed. Not even between trivially coercible types such as for example jint->jlong.
8223    ///     * ex: calling a constructor that expects a jlong with a jint is UB.
8224    ///
8225    pub unsafe fn NewObject1<A: JType>(&self, clazz: jclass, constructor: jmethodID, arg1: A) -> jobject {
8226        unsafe {
8227            #[cfg(feature = "asserts")]
8228            {
8229                self.check_not_critical("NewObject1");
8230                self.check_no_exception("NewObject1");
8231                assert!(!constructor.is_null(), "NewObject1 constructor is null");
8232                self.check_is_class("NewObject1", clazz);
8233                //TODO check if constructor is actually constructor or just a normal method.
8234                self.check_parameter_types_constructor("NewObject1", clazz, constructor, arg1, 0, 1);
8235            }
8236            self.jni::<extern "C" fn(JNIEnvVTable, jclass, jmethodID, ...) -> jobject>(28)(self.vtable, clazz, constructor, arg1)
8237        }
8238    }
8239
8240    ///
8241    /// Creates a new object instance by calling the two arg constructor.
8242    ///
8243    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewObject>
8244    ///
8245    ///
8246    /// # Arguments
8247    /// * `clazz` - reference to a class.
8248    ///     * must not be null
8249    ///     * must be valid
8250    ///     * must not be already garbage collected
8251    ///
8252    /// * `constructor` - jmethodID of a constructor
8253    ///     * must be a constructor
8254    ///     * must be a constructor of `clazz`
8255    ///     * must have 2 args
8256    /// * `arg1` & `arg2` - the arguments
8257    ///     * must be of the exact type that the constructor needs to be called with.
8258    ///
8259    /// # Returns
8260    /// A local reference to the newly created object or null if the object could not be created.
8261    ///
8262    /// # Throws Java Exception
8263    /// * `OutOfMemoryError`
8264    ///     * if the jvm runs out of memory.
8265    /// * `InstantiationException`
8266    ///     * if the class is an interface or an abstract class.
8267    /// * Any exception thrown by the constructor
8268    ///
8269    ///
8270    /// # Panics
8271    /// if asserts feature is enabled and UB was detected
8272    ///
8273    /// # Safety
8274    ///
8275    /// Current thread must not be detached from JNI.
8276    ///
8277    /// Current thread does not hold a critical reference.
8278    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8279    ///
8280    /// `clazz` must not be null and be a valid reference that has not yet been deleted or garbage collected.
8281    ///
8282    /// `constructor` must be a valid non-static methodID of `clazz` that is a constructor.
8283    ///
8284    /// `constructor` must have 2 arguments.
8285    ///
8286    /// `JType` of `arg1` & `arg2` must match the argument type of the java method exactly.
8287    /// * absolutely no coercion is performed. Not even between trivially coercible types such as for example jint->jlong.
8288    ///     * ex: calling a constructor that expects a jlong with a jint is UB.
8289    ///
8290    pub unsafe fn NewObject2<A: JType, B: JType>(&self, clazz: jclass, constructor: jmethodID, arg1: A, arg2: B) -> jobject {
8291        unsafe {
8292            #[cfg(feature = "asserts")]
8293            {
8294                self.check_not_critical("NewObject2");
8295                self.check_no_exception("NewObject2");
8296                assert!(!constructor.is_null(), "NewObject2 constructor is null");
8297                self.check_is_class("NewObject2", clazz);
8298                //TODO check if constructor is actually constructor or just a normal method.
8299                self.check_parameter_types_constructor("NewObject2", clazz, constructor, arg1, 0, 2);
8300                self.check_parameter_types_constructor("NewObject2", clazz, constructor, arg2, 1, 2);
8301            }
8302            self.jni::<extern "C" fn(JNIEnvVTable, jclass, jmethodID, ...) -> jobject>(28)(self.vtable, clazz, constructor, arg1, arg2)
8303        }
8304    }
8305
8306    ///
8307    /// Creates a new object instance by calling the three arg constructor.
8308    ///
8309    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewObject>
8310    ///
8311    ///
8312    /// # Arguments
8313    /// * `clazz` - reference to a class.
8314    ///     * must not be null
8315    ///     * must be valid
8316    ///     * must not be already garbage collected
8317    ///
8318    /// * `constructor` - jmethodID of a constructor
8319    ///     * must be a constructor (`<init>` method name)
8320    ///     * must be a constructor of `clazz`
8321    ///     * must have 3 args
8322    ///
8323    /// * `arg1` & `arg2` & `arg3` - the arguments
8324    ///     * must be of the exact type that the constructor needs to be called with.
8325    ///
8326    /// # Returns
8327    /// A local reference to the newly created object or null if the object could not be created.
8328    ///
8329    /// # Throws Java Exception
8330    /// * `OutOfMemoryError`
8331    ///     * if the jvm runs out of memory.
8332    /// * `InstantiationException`
8333    ///     * if the class is an interface or an abstract class.
8334    /// * Any exception thrown by the constructor
8335    ///
8336    ///
8337    /// # Panics
8338    /// if asserts feature is enabled and UB was detected
8339    ///
8340    /// # Safety
8341    ///
8342    /// Current thread must not be detached from JNI.
8343    ///
8344    /// Current thread does not hold a critical reference.
8345    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8346    ///
8347    /// `clazz` must not be null and be a valid reference that has not yet been deleted or garbage collected.
8348    ///
8349    /// `constructor` must be a valid non-static methodID of `clazz` that is a constructor
8350    ///
8351    /// `constructor` must have 2 arguments.
8352    ///
8353    /// `JType` of `arg1` & `arg2` & `arg3` must match the argument type of the java method exactly.
8354    /// * absolutely no coercion is performed. Not even between trivially coercible types such as for example jint->jlong.
8355    ///     * ex: calling a constructor that expects a jlong with a jint is UB.
8356    ///
8357    pub unsafe fn NewObject3<A: JType, B: JType, C: JType>(&self, clazz: jclass, constructor: jmethodID, arg1: A, arg2: B, arg3: C) -> jobject {
8358        unsafe {
8359            #[cfg(feature = "asserts")]
8360            {
8361                self.check_not_critical("NewObject3");
8362                self.check_no_exception("NewObject3");
8363                assert!(!constructor.is_null(), "NewObject3 constructor is null");
8364                self.check_is_class("NewObject3", clazz);
8365                //TODO check if constructor is actually constructor or just a normal method.
8366                self.check_parameter_types_constructor("NewObject3", clazz, constructor, arg1, 0, 3);
8367                self.check_parameter_types_constructor("NewObject3", clazz, constructor, arg2, 1, 3);
8368                self.check_parameter_types_constructor("NewObject3", clazz, constructor, arg3, 2, 3);
8369            }
8370            self.jni::<extern "C" fn(JNIEnvVTable, jclass, jmethodID, ...) -> jobject>(28)(self.vtable, clazz, constructor, arg1, arg2, arg3)
8371        }
8372    }
8373
8374    ///
8375    /// Gets the class of an object instance.
8376    ///
8377    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetObjectClass>
8378    ///
8379    ///
8380    /// # Arguments
8381    /// * `obj` - reference to a object.
8382    ///     * must not be null
8383    ///     * must be valid
8384    ///     * must not be already garbage collected
8385    ///
8386    /// # Returns
8387    /// A local reference to the class of the object.
8388    ///
8389    ///
8390    /// # Panics
8391    /// if asserts feature is enabled and UB was detected
8392    ///
8393    /// # Safety
8394    ///
8395    /// Current thread must not be detached from JNI.
8396    ///
8397    /// Current thread must not be currently throwing an exception.
8398    ///
8399    /// Current thread does not hold a critical reference.
8400    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8401    ///
8402    /// `obj` must not be null and be a valid reference that has not yet been deleted or garbage collected.
8403    ///
8404    pub unsafe fn GetObjectClass(&self, obj: jobject) -> jclass {
8405        unsafe {
8406            #[cfg(feature = "asserts")]
8407            {
8408                self.check_not_critical("GetObjectClass");
8409                self.check_no_exception("GetObjectClass");
8410                self.check_ref_obj("GetObjectClass", obj);
8411            }
8412            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jobject>(31)(self.vtable, obj)
8413        }
8414    }
8415
8416    ///
8417    /// Gets the type of reference
8418    ///
8419    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetObjectRefType>
8420    ///
8421    ///
8422    /// # Arguments
8423    /// * `obj` - reference to an object.
8424    ///     * must be valid or null
8425    ///
8426    /// # Returns
8427    /// The type of reference
8428    /// `JNIInvalidRefType` is returned for null inputs.
8429    ///
8430    ///
8431    /// # Panics
8432    /// if asserts feature is enabled and UB was detected
8433    ///
8434    /// # Safety
8435    ///
8436    /// Current thread must not be detached from JNI.
8437    ///
8438    /// Current thread must not be currently throwing an exception.
8439    ///
8440    /// Current thread does not hold a critical reference.
8441    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8442    ///
8443    /// `obj` must be a valid reference.
8444    ///
8445    /// Calling this fn with an obj that has already been manually deleted using `DeleteLocalRef` for example is UB.
8446    ///
8447    pub unsafe fn GetObjectRefType(&self, obj: jobject) -> jobjectRefType {
8448        unsafe {
8449            #[cfg(feature = "asserts")]
8450            {
8451                self.check_not_critical("GetObjectRefType");
8452                self.check_no_exception("GetObjectRefType");
8453            }
8454            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jobjectRefType>(232)(self.vtable, obj)
8455        }
8456    }
8457
8458    ///
8459    /// Checks if the obj is instanceof the given class
8460    ///
8461    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#IsInstanceOf>
8462    ///
8463    ///
8464    /// # Arguments
8465    /// * `obj` - reference to an object.
8466    ///     * must be valid or null
8467    ///     * must not be already garbage collected
8468    /// * `clazz` - reference to the class.
8469    ///     * must be a valid reference to a class
8470    ///     * must not be null
8471    ///     * must not be already garbage collected
8472    ///
8473    /// # Returns
8474    /// true if `obj` is instanceof `clazz`, false otherwise
8475    /// if `obj` is null then this fn returns false for any `clazz` input
8476    ///
8477    ///
8478    /// # Panics
8479    /// if asserts feature is enabled and UB was detected
8480    ///
8481    /// # Safety
8482    ///
8483    /// Current thread must not be detached from JNI.
8484    ///
8485    /// Current thread must not be currently throwing an exception.
8486    ///
8487    /// Current thread does not hold a critical reference.
8488    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8489    ///
8490    /// `obj` must be null or a valid reference that is not already garbage collected.
8491    /// `clazz` must be a valid non-null reference to a class that is not already garbage collected.
8492    ///
8493    pub unsafe fn IsInstanceOf(&self, obj: jobject, clazz: jclass) -> bool {
8494        unsafe {
8495            #[cfg(feature = "asserts")]
8496            {
8497                self.check_not_critical("IsInstanceOf");
8498                self.check_no_exception("IsInstanceOf");
8499                self.check_is_class("IsInstanceOf", clazz);
8500                self.check_ref_obj_permit_null("IsInstanceOf", obj);
8501            }
8502            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass) -> jboolean>(32)(self.vtable, obj, clazz).as_bool()
8503        }
8504    }
8505
8506    ///
8507    /// this is the java == operator on 2 java objects.
8508    /// The opaque handles of the 2 objects could be different but refer to the same underlying object.
8509    /// This fn exists in order to be able to check this.
8510    ///
8511    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#IsSameObject>
8512    ///
8513    ///
8514    /// # Arguments
8515    /// * `obj1` - reference to an object.
8516    ///     * must be valid or null
8517    ///     * must not be already garbage collected
8518    /// * `obj2` - reference to the class.
8519    ///     * must be valid or null
8520    ///     * must not be already garbage collected
8521    ///
8522    /// # Returns
8523    /// true if `obj1` == `obj2`, false otherwise
8524    ///
8525    ///
8526    ///
8527    /// # Panics
8528    /// if asserts feature is enabled and UB was detected
8529    ///
8530    /// # Safety
8531    ///
8532    /// Current thread must not be detached from JNI.
8533    ///
8534    /// Current thread must not be currently throwing an exception.
8535    ///
8536    /// Current thread does not hold a critical reference.
8537    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8538    ///
8539    /// `obj1` must be null or a valid reference that is not already garbage collected.
8540    /// `obj2` must be null or a valid reference that is not already garbage collected.
8541    ///
8542    pub unsafe fn IsSameObject(&self, obj1: jobject, obj2: jobject) -> bool {
8543        unsafe {
8544            #[cfg(feature = "asserts")]
8545            {
8546                self.check_not_critical("IsSameObject");
8547                self.check_no_exception("IsSameObject");
8548                self.check_ref_obj_permit_null("IsSameObject obj1", obj1);
8549                self.check_ref_obj_permit_null("IsSameObject obj2", obj2);
8550            }
8551            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jobject) -> jboolean>(24)(self.vtable, obj1, obj2).as_bool()
8552        }
8553    }
8554
8555    ///
8556    /// Gets the field id of a non-static field
8557    ///
8558    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetFieldID>
8559    ///
8560    ///
8561    /// # Arguments
8562    /// * `clazz` - reference to the clazz where the field is declared in.
8563    ///     * must be valid
8564    ///     * must not be null
8565    ///     * must not be already garbage collected
8566    /// * `name` - name of the field
8567    ///     * must not be null
8568    ///     * must be zero terminated utf-8
8569    /// * `sig` - jni signature of the field
8570    ///     * must not be null
8571    ///     * must be zero terminated utf-8
8572    ///
8573    /// # Returns
8574    /// A non-null field handle or null on error.
8575    /// The field handle can be assumed to be constant for the given class and must not be freed.
8576    /// It can also be safely shared with any thread or stored in a constant.
8577    ///
8578    /// # Throws Java Exception
8579    /// * `NoSuchFieldError` - field with the given name and sig doesnt exist in the class
8580    /// * `ExceptionInInitializerError` - Exception occurs in initializer of the class
8581    /// * `OutOfMemoryError` - if the jvm runs out of memory
8582    ///
8583    ///
8584    /// # Panics
8585    /// if asserts feature is enabled and UB was detected
8586    ///
8587    /// # Safety
8588    ///
8589    /// Current thread must not be detached from JNI.
8590    ///
8591    /// Current thread must not be currently throwing an exception.
8592    ///
8593    /// Current thread does not hold a critical reference.
8594    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8595    ///
8596    /// `clazz` must a valid reference to a class that is not already garbage collected.
8597    /// `name` must be non-null and zero terminated utf-8.
8598    /// `sig` must be non-null and zero terminated utf-8.
8599    ///
8600    pub unsafe fn GetFieldID(&self, clazz: jclass, name: impl UseCString, sig: impl UseCString) -> jfieldID {
8601        unsafe {
8602            name.use_as_const_c_char(|name| {
8603                sig.use_as_const_c_char(|sig| {
8604                    #[cfg(feature = "asserts")]
8605                    {
8606                        self.check_not_critical("GetFieldID");
8607                        self.check_no_exception("GetFieldID");
8608                        assert!(!name.is_null(), "GetFieldID name is null");
8609                        assert!(!sig.is_null(), "GetFieldID sig is null");
8610                        self.check_is_class("GetFieldID", clazz);
8611                    }
8612                    self.jni::<extern "system" fn(JNIEnvVTable, jclass, *const c_char, *const c_char) -> jfieldID>(94)(self.vtable, clazz, name, sig)
8613                })
8614            })
8615        }
8616    }
8617
8618    ///
8619    /// Returns a local reference from a field in an object.
8620    ///
8621    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines>
8622    ///
8623    ///
8624    /// # Arguments
8625    /// * `obj` - reference to the object the field is in
8626    ///     * must be valid
8627    ///     * must not be null
8628    ///     * must not be already garbage collected
8629    /// * `fieldID` - the field to get
8630    ///     * must be valid
8631    ///     * must be a object field
8632    ///
8633    /// # Returns
8634    /// A local reference to the fields value or null if the field is null
8635    ///
8636    ///
8637    /// # Panics
8638    /// if asserts feature is enabled and UB was detected
8639    ///
8640    /// # Safety
8641    ///
8642    /// Current thread must not be detached from JNI.
8643    ///
8644    /// Current thread must not be currently throwing an exception.
8645    ///
8646    /// Current thread does not hold a critical reference.
8647    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8648    ///
8649    /// `obj` must a valid reference to the object that is not already garbage collected.
8650    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
8651    /// `fieldID` must not be from a static field
8652    /// `fieldID` must refer to a field that is an object and not a primitive.
8653    ///
8654    pub unsafe fn GetObjectField(&self, obj: jobject, fieldID: jfieldID) -> jobject {
8655        unsafe {
8656            #[cfg(feature = "asserts")]
8657            {
8658                self.check_not_critical("GetObjectField");
8659                self.check_no_exception("GetObjectField");
8660                self.check_field_type_object("GetObjectField", obj, fieldID, "object");
8661            }
8662            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jobject>(95)(self.vtable, obj, fieldID)
8663        }
8664    }
8665
8666    ///
8667    /// Returns a boolean field value
8668    ///
8669    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines>
8670    ///
8671    ///
8672    /// # Arguments
8673    /// * `obj` - reference to the object the field is in
8674    ///     * must be valid
8675    ///     * must not be null
8676    ///     * must not be already garbage collected
8677    /// * `fieldID` - the field to get
8678    ///     * must be valid
8679    ///     * must be a boolean field
8680    ///
8681    /// # Returns
8682    /// The boolean field value
8683    ///
8684    ///
8685    /// # Panics
8686    /// if asserts feature is enabled and UB was detected
8687    ///
8688    /// # Safety
8689    ///
8690    /// Current thread must not be detached from JNI.
8691    ///
8692    /// Current thread must not be currently throwing an exception.
8693    ///
8694    /// Current thread does not hold a critical reference.
8695    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8696    ///
8697    /// `obj` must a valid reference to the object that is not already garbage collected.
8698    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
8699    /// `fieldID` must not be from a static field
8700    /// `fieldID` must refer to a field that is a boolean and not something else.
8701    ///
8702    pub unsafe fn GetBooleanField(&self, obj: jobject, fieldID: jfieldID) -> bool {
8703        unsafe {
8704            #[cfg(feature = "asserts")]
8705            {
8706                self.check_not_critical("GetBooleanField");
8707                self.check_no_exception("GetBooleanField");
8708                self.check_field_type_object("GetBooleanField", obj, fieldID, "boolean");
8709            }
8710            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jboolean>(96)(self.vtable, obj, fieldID).as_bool()
8711        }
8712    }
8713
8714    ///
8715    /// Returns a byte field value
8716    ///
8717    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines>
8718    ///
8719    ///
8720    /// # Arguments
8721    /// * `obj` - reference to the object the field is in
8722    ///     * must be valid
8723    ///     * must not be null
8724    ///     * must not be already garbage collected
8725    /// * `fieldID` - the field to get
8726    ///     * must be valid
8727    ///     * must be a byte field
8728    ///
8729    /// # Returns
8730    /// The byte field value
8731    ///
8732    ///
8733    /// # Panics
8734    /// if asserts feature is enabled and UB was detected
8735    ///
8736    /// # Safety
8737    ///
8738    /// Current thread must not be detached from JNI.
8739    ///
8740    /// Current thread must not be currently throwing an exception.
8741    ///
8742    /// Current thread does not hold a critical reference.
8743    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8744    ///
8745    /// `obj` must a valid reference to the object that is not already garbage collected.
8746    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
8747    /// `fieldID` must not be from a static field
8748    /// `fieldID` must refer to a field that is a byte and not something else.
8749    ///
8750    pub unsafe fn GetByteField(&self, obj: jobject, fieldID: jfieldID) -> jbyte {
8751        unsafe {
8752            #[cfg(feature = "asserts")]
8753            {
8754                self.check_not_critical("GetByteField");
8755                self.check_no_exception("GetByteField");
8756                self.check_field_type_object("GetByteField", obj, fieldID, "byte");
8757            }
8758            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jbyte>(97)(self.vtable, obj, fieldID)
8759        }
8760    }
8761
8762    ///
8763    /// Returns a char field value
8764    ///
8765    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines>
8766    ///
8767    ///
8768    /// # Arguments
8769    /// * `obj` - reference to the object the field is in
8770    ///     * must be valid
8771    ///     * must not be null
8772    ///     * must not be already garbage collected
8773    /// * `fieldID` - the field to get
8774    ///     * must be valid
8775    ///     * must be a char field
8776    ///
8777    /// # Returns
8778    /// The char field value
8779    ///
8780    ///
8781    /// # Panics
8782    /// if asserts feature is enabled and UB was detected
8783    ///
8784    /// # Safety
8785    ///
8786    /// Current thread must not be detached from JNI.
8787    ///
8788    /// Current thread must not be currently throwing an exception.
8789    ///
8790    /// Current thread does not hold a critical reference.
8791    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8792    ///
8793    /// `obj` must a valid reference to the object that is not already garbage collected.
8794    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
8795    /// `fieldID` must not be from a static field
8796    /// `fieldID` must refer to a field that is a char and not something else.
8797    ///
8798    pub unsafe fn GetCharField(&self, obj: jobject, fieldID: jfieldID) -> jchar {
8799        unsafe {
8800            #[cfg(feature = "asserts")]
8801            {
8802                self.check_not_critical("GetCharField");
8803                self.check_no_exception("GetCharField");
8804                self.check_field_type_object("GetCharField", obj, fieldID, "char");
8805            }
8806            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jchar>(98)(self.vtable, obj, fieldID)
8807        }
8808    }
8809
8810    ///
8811    /// Returns a short field value
8812    ///
8813    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines>
8814    ///
8815    ///
8816    /// # Arguments
8817    /// * `obj` - reference to the object the field is in
8818    ///     * must be valid
8819    ///     * must not be null
8820    ///     * must not be already garbage collected
8821    /// * `fieldID` - the field to get
8822    ///     * must be valid
8823    ///     * must be a short field
8824    ///
8825    /// # Returns
8826    /// The short field value
8827    ///
8828    ///
8829    /// # Panics
8830    /// if asserts feature is enabled and UB was detected
8831    ///
8832    /// # Safety
8833    ///
8834    /// Current thread must not be detached from JNI.
8835    ///
8836    /// Current thread must not be currently throwing an exception.
8837    ///
8838    /// Current thread does not hold a critical reference.
8839    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8840    ///
8841    /// `obj` must a valid reference to the object that is not already garbage collected.
8842    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
8843    /// `fieldID` must not be from a static field
8844    /// `fieldID` must refer to a field that is a short and not something else.
8845    ///
8846    pub unsafe fn GetShortField(&self, obj: jobject, fieldID: jfieldID) -> jshort {
8847        unsafe {
8848            #[cfg(feature = "asserts")]
8849            {
8850                self.check_not_critical("GetShortField");
8851                self.check_no_exception("GetShortField");
8852                self.check_field_type_object("GetShortField", obj, fieldID, "short");
8853            }
8854            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jshort>(99)(self.vtable, obj, fieldID)
8855        }
8856    }
8857
8858    ///
8859    /// Returns a int field value
8860    ///
8861    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines>
8862    ///
8863    ///
8864    /// # Arguments
8865    /// * `obj` - reference to the object the field is in
8866    ///     * must be valid
8867    ///     * must not be null
8868    ///     * must not be already garbage collected
8869    /// * `fieldID` - the field to get
8870    ///     * must be valid
8871    ///     * must be a int field
8872    ///
8873    /// # Returns
8874    /// The int field value
8875    ///
8876    ///
8877    /// # Panics
8878    /// if asserts feature is enabled and UB was detected
8879    ///
8880    /// # Safety
8881    ///
8882    /// Current thread must not be detached from JNI.
8883    ///
8884    /// Current thread must not be currently throwing an exception.
8885    ///
8886    /// Current thread does not hold a critical reference.
8887    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8888    ///
8889    /// `obj` must a valid reference to the object that is not already garbage collected.
8890    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
8891    /// `fieldID` must not be from a static field
8892    /// `fieldID` must refer to a field that is a int and not something else.
8893    ///
8894    pub unsafe fn GetIntField(&self, obj: jobject, fieldID: jfieldID) -> jint {
8895        unsafe {
8896            #[cfg(feature = "asserts")]
8897            {
8898                self.check_not_critical("GetIntField");
8899                self.check_no_exception("GetIntField");
8900                self.check_field_type_object("GetIntField", obj, fieldID, "int");
8901            }
8902            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jint>(100)(self.vtable, obj, fieldID)
8903        }
8904    }
8905
8906    ///
8907    /// Returns a int field value
8908    ///
8909    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines>
8910    ///
8911    ///
8912    /// # Arguments
8913    /// * `obj` - reference to the object the field is in
8914    ///     * must be valid
8915    ///     * must not be null
8916    ///     * must not be already garbage collected
8917    /// * `fieldID` - the field to get
8918    ///     * must be valid
8919    ///     * must be a long field
8920    ///
8921    /// # Returns
8922    /// The long field value
8923    ///
8924    ///
8925    /// # Panics
8926    /// if asserts feature is enabled and UB was detected
8927    ///
8928    /// # Safety
8929    ///
8930    /// Current thread must not be detached from JNI.
8931    ///
8932    /// Current thread must not be currently throwing an exception.
8933    ///
8934    /// Current thread does not hold a critical reference.
8935    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8936    ///
8937    /// `obj` must a valid reference to the object that is not already garbage collected.
8938    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
8939    /// `fieldID` must not be from a static field
8940    /// `fieldID` must refer to a field that is a long and not something else.
8941    ///
8942    pub unsafe fn GetLongField(&self, obj: jobject, fieldID: jfieldID) -> jlong {
8943        unsafe {
8944            #[cfg(feature = "asserts")]
8945            {
8946                self.check_not_critical("GetLongField");
8947                self.check_no_exception("GetLongField");
8948                self.check_field_type_object("GetLongField", obj, fieldID, "long");
8949            }
8950            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jlong>(101)(self.vtable, obj, fieldID)
8951        }
8952    }
8953
8954    ///
8955    /// Returns a float field value
8956    ///
8957    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines>
8958    ///
8959    ///
8960    /// # Arguments
8961    /// * `obj` - reference to the object the field is in
8962    ///     * must be valid
8963    ///     * must not be null
8964    ///     * must not be already garbage collected
8965    /// * `fieldID` - the field to get
8966    ///     * must be valid
8967    ///     * must be a long field
8968    ///
8969    /// # Returns
8970    /// The float field value
8971    ///
8972    ///
8973    /// # Panics
8974    /// if asserts feature is enabled and UB was detected
8975    ///
8976    /// # Safety
8977    ///
8978    /// Current thread must not be detached from JNI.
8979    ///
8980    /// Current thread must not be currently throwing an exception.
8981    ///
8982    /// Current thread does not hold a critical reference.
8983    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8984    ///
8985    /// `obj` must a valid reference to the object that is not already garbage collected.
8986    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
8987    /// `fieldID` must not be from a static field
8988    /// `fieldID` must refer to a field that is a float and not something else.
8989    ///
8990    pub unsafe fn GetFloatField(&self, obj: jobject, fieldID: jfieldID) -> jfloat {
8991        unsafe {
8992            #[cfg(feature = "asserts")]
8993            {
8994                self.check_not_critical("GetFloatField");
8995                self.check_no_exception("GetFloatField");
8996                self.check_field_type_object("GetFloatField", obj, fieldID, "float");
8997            }
8998            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jfloat>(102)(self.vtable, obj, fieldID)
8999        }
9000    }
9001
9002    ///
9003    /// Returns a double field value
9004    ///
9005    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines>
9006    ///
9007    ///
9008    /// # Arguments
9009    /// * `obj` - reference to the object the field is in
9010    ///     * must be valid
9011    ///     * must not be null
9012    ///     * must not be already garbage collected
9013    /// * `fieldID` - the field to get
9014    ///     * must be valid
9015    ///     * must be a double field
9016    ///
9017    /// # Returns
9018    /// The double field value
9019    ///
9020    ///
9021    /// # Panics
9022    /// if asserts feature is enabled and UB was detected
9023    ///
9024    /// # Safety
9025    ///
9026    /// Current thread must not be detached from JNI.
9027    ///
9028    /// Current thread must not be currently throwing an exception.
9029    ///
9030    /// Current thread does not hold a critical reference.
9031    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9032    ///
9033    /// `obj` must a valid reference to the object that is not already garbage collected.
9034    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
9035    /// `fieldID` must not be from a static field
9036    /// `fieldID` must refer to a field that is a double and not something else.
9037    ///
9038    pub unsafe fn GetDoubleField(&self, obj: jobject, fieldID: jfieldID) -> jdouble {
9039        unsafe {
9040            #[cfg(feature = "asserts")]
9041            {
9042                self.check_not_critical("GetDoubleField");
9043                self.check_no_exception("GetDoubleField");
9044                self.check_field_type_object("GetDoubleField", obj, fieldID, "double");
9045            }
9046            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jdouble>(103)(self.vtable, obj, fieldID)
9047        }
9048    }
9049
9050    ///
9051    /// Sets a object field to a given value
9052    ///
9053    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_type_Field_routines>
9054    ///
9055    /// # Arguments
9056    /// * `obj` - reference to the object the field is in
9057    ///     * must be valid
9058    ///     * must not be null
9059    ///     * must not be already garbage collected
9060    ///
9061    /// * `fieldID` - the field to set
9062    ///     * must be valid
9063    ///     * must be a object field
9064    ///     * must reside in the object `obj`
9065    ///
9066    /// * `value`
9067    ///     * must be null or valid
9068    ///     * must not be already garbage collected (if non-null)
9069    ///     * must be assignable to the field type (if non-null)
9070    ///
9071    ///
9072    /// # Panics
9073    /// if asserts feature is enabled and UB was detected
9074    ///
9075    /// # Safety
9076    ///
9077    /// Current thread must not be detached from JNI.
9078    ///
9079    /// Current thread must not be currently throwing an exception.
9080    ///
9081    /// Current thread does not hold a critical reference.
9082    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9083    ///
9084    /// `obj` must be a valid reference to the object that is not already garbage collected.
9085    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
9086    /// `fieldID` must not be from a static field
9087    /// `fieldID` must refer to a field that is an object and not a primitive.
9088    /// `value` must be a valid reference to the object that is not already garbage collected or it must be null.
9089    /// `value` must be assignable to the field type (i.e. if it's a String field setting to an `ArrayList` for example is UB)
9090    ///
9091    pub unsafe fn SetObjectField(&self, obj: jobject, fieldID: jfieldID, value: jobject) {
9092        unsafe {
9093            #[cfg(feature = "asserts")]
9094            {
9095                self.check_not_critical("SetObjectField");
9096                self.check_no_exception("SetObjectField");
9097                self.check_field_type_object("SetObjectField", obj, fieldID, "object");
9098                self.check_ref_obj_permit_null("SetObjectField", value);
9099            }
9100            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jobject)>(104)(self.vtable, obj, fieldID, value);
9101        }
9102    }
9103
9104    ///
9105    /// Sets a boolean field to a given value
9106    ///
9107    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_type_Field_routines>
9108    ///
9109    /// # Arguments
9110    /// * `obj` - reference to the object the field is in
9111    ///     * must be valid
9112    ///     * must not be null
9113    ///     * must not be already garbage collected
9114    ///
9115    /// * `fieldID` - the field to set
9116    ///     * must be valid
9117    ///     * must be a object field
9118    ///     * must reside in the object `obj`
9119    ///
9120    /// * `value` - the value to set
9121    ///
9122    ///
9123    /// # Panics
9124    /// if asserts feature is enabled and UB was detected
9125    ///
9126    /// # Safety
9127    ///
9128    /// Current thread must not be detached from JNI.
9129    ///
9130    /// Current thread must not be currently throwing an exception.
9131    ///
9132    /// Current thread does not hold a critical reference.
9133    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9134    ///
9135    /// `obj` must be a valid reference to the object that is not already garbage collected.
9136    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
9137    /// `fieldID` must not be from a static field
9138    /// `fieldID` must refer to a field that is a boolean.
9139    ///
9140    pub unsafe fn SetBooleanField(&self, obj: jobject, fieldID: jfieldID, value: impl Into<jboolean>) {
9141        let value = value.into();
9142        unsafe {
9143            #[cfg(feature = "asserts")]
9144            {
9145                self.check_not_critical("SetBooleanField");
9146                self.check_no_exception("SetBooleanField");
9147                self.check_field_type_object("SetBooleanField", obj, fieldID, "boolean");
9148                assert!(!value.is_wide(), "SetBooleanField with wide boolean value");
9149            }
9150            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jboolean)>(105)(self.vtable, obj, fieldID, value);
9151        }
9152    }
9153
9154    ///
9155    /// Sets a byte field to a given value
9156    ///
9157    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_type_Field_routines>
9158    ///
9159    /// # Arguments
9160    /// * `obj` - reference to the object the field is in
9161    ///     * must be valid
9162    ///     * must not be null
9163    ///     * must not be already garbage collected
9164    ///
9165    /// * `fieldID` - the field to set
9166    ///     * must be valid
9167    ///     * must be a object field
9168    ///     * must reside in the object `obj`
9169    ///
9170    /// * `value` - the value to set
9171    ///
9172    ///
9173    /// # Panics
9174    /// if asserts feature is enabled and UB was detected
9175    ///
9176    /// # Safety
9177    ///
9178    /// Current thread must not be detached from JNI.
9179    ///
9180    /// Current thread must not be currently throwing an exception.
9181    ///
9182    /// Current thread does not hold a critical reference.
9183    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9184    ///
9185    /// `obj` must be a valid reference to the object that is not already garbage collected.
9186    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
9187    /// `fieldID` must not be from a static field
9188    /// `fieldID` must refer to a field that is a byte.
9189    ///
9190    pub unsafe fn SetByteField(&self, obj: jobject, fieldID: jfieldID, value: jbyte) {
9191        unsafe {
9192            #[cfg(feature = "asserts")]
9193            {
9194                self.check_not_critical("SetByteField");
9195                self.check_no_exception("SetByteField");
9196                self.check_field_type_object("SetByteField", obj, fieldID, "byte");
9197            }
9198            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jbyte)>(106)(self.vtable, obj, fieldID, value);
9199        }
9200    }
9201
9202    ///
9203    /// Sets a char field to a given value
9204    ///
9205    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_type_Field_routines>
9206    ///
9207    /// # Arguments
9208    /// * `obj` - reference to the object the field is in
9209    ///     * must be valid
9210    ///     * must not be null
9211    ///     * must not be already garbage collected
9212    ///
9213    /// * `fieldID` - the field to set
9214    ///     * must be valid
9215    ///     * must be a object field
9216    ///     * must reside in the object `obj`
9217    ///
9218    /// * `value` - the value to set
9219    ///
9220    ///
9221    /// # Panics
9222    /// if asserts feature is enabled and UB was detected
9223    ///
9224    /// # Safety
9225    ///
9226    /// Current thread must not be detached from JNI.
9227    ///
9228    /// Current thread must not be currently throwing an exception.
9229    ///
9230    /// Current thread does not hold a critical reference.
9231    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9232    ///
9233    /// `obj` must be a valid reference to the object that is not already garbage collected.
9234    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
9235    /// `fieldID` must not be from a static field
9236    /// `fieldID` must refer to a field that is a char.
9237    ///
9238    pub unsafe fn SetCharField(&self, obj: jobject, fieldID: jfieldID, value: jchar) {
9239        unsafe {
9240            #[cfg(feature = "asserts")]
9241            {
9242                self.check_not_critical("SetCharField");
9243                self.check_no_exception("SetCharField");
9244                self.check_field_type_object("SetCharField", obj, fieldID, "char");
9245            }
9246            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jchar)>(107)(self.vtable, obj, fieldID, value);
9247        }
9248    }
9249
9250    ///
9251    /// Sets a short field to a given value
9252    ///
9253    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_type_Field_routines>
9254    ///
9255    /// # Arguments
9256    /// * `obj` - reference to the object the field is in
9257    ///     * must be valid
9258    ///     * must not be null
9259    ///     * must not be already garbage collected
9260    ///
9261    /// * `fieldID` - the field to set
9262    ///     * must be valid
9263    ///     * must be a object field
9264    ///     * must reside in the object `obj`
9265    ///
9266    /// * `value` - the value to set
9267    ///
9268    ///
9269    /// # Panics
9270    /// if asserts feature is enabled and UB was detected
9271    ///
9272    /// # Safety
9273    ///
9274    /// Current thread must not be detached from JNI.
9275    ///
9276    /// Current thread must not be currently throwing an exception.
9277    ///
9278    /// Current thread does not hold a critical reference.
9279    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9280    ///
9281    /// `obj` must be a valid reference to the object that is not already garbage collected.
9282    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
9283    /// `fieldID` must not be from a static field
9284    /// `fieldID` must refer to a field that is a short.
9285    ///
9286    pub unsafe fn SetShortField(&self, obj: jobject, fieldID: jfieldID, value: jshort) {
9287        unsafe {
9288            #[cfg(feature = "asserts")]
9289            {
9290                self.check_not_critical("SetShortField");
9291                self.check_no_exception("SetShortField");
9292                self.check_field_type_object("SetShortField", obj, fieldID, "short");
9293            }
9294            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jshort)>(108)(self.vtable, obj, fieldID, value);
9295        }
9296    }
9297
9298    ///
9299    /// Sets a int field to a given value
9300    ///
9301    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_type_Field_routines>
9302    ///
9303    /// # Arguments
9304    /// * `obj` - reference to the object the field is in
9305    ///     * must be valid
9306    ///     * must not be null
9307    ///     * must not be already garbage collected
9308    ///
9309    /// * `fieldID` - the field to set
9310    ///     * must be valid
9311    ///     * must be a object field
9312    ///     * must reside in the object `obj`
9313    ///
9314    /// * `value` - the value to set
9315    ///
9316    ///
9317    /// # Panics
9318    /// if asserts feature is enabled and UB was detected
9319    ///
9320    /// # Safety
9321    ///
9322    /// Current thread must not be detached from JNI.
9323    ///
9324    /// Current thread must not be currently throwing an exception.
9325    ///
9326    /// Current thread does not hold a critical reference.
9327    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9328    ///
9329    /// `obj` must be a valid reference to the object that is not already garbage collected.
9330    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
9331    /// `fieldID` must not be from a static field
9332    /// `fieldID` must refer to a field that is a int.
9333    ///
9334    pub unsafe fn SetIntField(&self, obj: jobject, fieldID: jfieldID, value: jint) {
9335        unsafe {
9336            #[cfg(feature = "asserts")]
9337            {
9338                self.check_not_critical("SetIntField");
9339                self.check_no_exception("SetIntField");
9340                self.check_field_type_object("SetIntField", obj, fieldID, "int");
9341            }
9342            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jint)>(109)(self.vtable, obj, fieldID, value);
9343        }
9344    }
9345
9346    ///
9347    /// Sets a long field to a given value
9348    ///
9349    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_type_Field_routines>
9350    ///
9351    /// # Arguments
9352    /// * `obj` - reference to the object the field is in
9353    ///     * must be valid
9354    ///     * must not be null
9355    ///     * must not be already garbage collected
9356    ///
9357    /// * `fieldID` - the field to set
9358    ///     * must be valid
9359    ///     * must be a object field
9360    ///     * must reside in the object `obj`
9361    ///
9362    /// * `value` - the value to set
9363    ///
9364    ///
9365    /// # Panics
9366    /// if asserts feature is enabled and UB was detected
9367    ///
9368    /// # Safety
9369    ///
9370    /// Current thread must not be detached from JNI.
9371    ///
9372    /// Current thread must not be currently throwing an exception.
9373    ///
9374    /// Current thread does not hold a critical reference.
9375    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9376    ///
9377    /// `obj` must be a valid reference to the object that is not already garbage collected.
9378    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
9379    /// `fieldID` must not be from a static field
9380    /// `fieldID` must refer to a field that is a long.
9381    ///
9382    pub unsafe fn SetLongField(&self, obj: jobject, fieldID: jfieldID, value: jlong) {
9383        unsafe {
9384            #[cfg(feature = "asserts")]
9385            {
9386                self.check_not_critical("SetLongField");
9387                self.check_no_exception("SetLongField");
9388                self.check_field_type_object("SetLongField", obj, fieldID, "long");
9389            }
9390            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jlong)>(110)(self.vtable, obj, fieldID, value);
9391        }
9392    }
9393
9394    ///
9395    /// Sets a float field to a given value
9396    ///
9397    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_type_Field_routines>
9398    ///
9399    /// # Arguments
9400    /// * `obj` - reference to the object the field is in
9401    ///     * must be valid
9402    ///     * must not be null
9403    ///     * must not be already garbage collected
9404    ///
9405    /// * `fieldID` - the field to set
9406    ///     * must be valid
9407    ///     * must be a object field
9408    ///     * must reside in the object `obj`
9409    ///
9410    /// * `value` - the value to set
9411    ///
9412    ///
9413    /// # Panics
9414    /// if asserts feature is enabled and UB was detected
9415    ///
9416    /// # Safety
9417    ///
9418    /// Current thread must not be detached from JNI.
9419    ///
9420    /// Current thread must not be currently throwing an exception.
9421    ///
9422    /// Current thread does not hold a critical reference.
9423    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9424    ///
9425    /// `obj` must be a valid reference to the object that is not already garbage collected.
9426    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
9427    /// `fieldID` must not be from a static field
9428    /// `fieldID` must refer to a field that is a float.
9429    ///
9430    pub unsafe fn SetFloatField(&self, obj: jobject, fieldID: jfieldID, value: jfloat) {
9431        unsafe {
9432            #[cfg(feature = "asserts")]
9433            {
9434                self.check_not_critical("SetFloatField");
9435                self.check_no_exception("SetFloatField");
9436                self.check_field_type_object("SetFloatField", obj, fieldID, "float");
9437            }
9438            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jfloat)>(111)(self.vtable, obj, fieldID, value);
9439        }
9440    }
9441
9442    ///
9443    /// Sets a double field to a given value
9444    ///
9445    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_type_Field_routines>
9446    ///
9447    /// # Arguments
9448    /// * `obj` - reference to the object the field is in
9449    ///     * must be valid
9450    ///     * must not be null
9451    ///     * must not be already garbage collected
9452    ///
9453    /// * `fieldID` - the field to set
9454    ///     * must be valid
9455    ///     * must be a object field
9456    ///     * must reside in the object `obj`
9457    ///
9458    /// * `value` - the value to set
9459    ///
9460    ///
9461    /// # Panics
9462    /// if asserts feature is enabled and UB was detected
9463    ///
9464    /// # Safety
9465    ///
9466    /// Current thread must not be detached from JNI.
9467    ///
9468    /// Current thread must not be currently throwing an exception.
9469    ///
9470    /// Current thread does not hold a critical reference.
9471    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9472    ///
9473    /// `obj` must be a valid reference to the object that is not already garbage collected.
9474    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
9475    /// `fieldID` must not be from a static field
9476    /// `fieldID` must refer to a field that is a double.
9477    ///
9478    pub unsafe fn SetDoubleField(&self, obj: jobject, fieldID: jfieldID, value: jdouble) {
9479        unsafe {
9480            #[cfg(feature = "asserts")]
9481            {
9482                self.check_not_critical("SetDoubleField");
9483                self.check_no_exception("SetDoubleField");
9484                self.check_field_type_object("SetDoubleField", obj, fieldID, "double");
9485            }
9486            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jdouble)>(112)(self.vtable, obj, fieldID, value);
9487        }
9488    }
9489
9490    ///
9491    /// Gets the method id of a non-static method
9492    ///
9493    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetMethodID>
9494    ///
9495    ///
9496    /// # Arguments
9497    /// * `clazz` - reference to the clazz where the field is declared in.
9498    ///     * must be valid
9499    ///     * must not be null
9500    ///     * must not be already garbage collected
9501    /// * `name` - name of the method
9502    ///     * must not be null
9503    ///     * must be zero terminated utf-8
9504    /// * `sig` - jni signature of the method
9505    ///     * must not be null
9506    ///     * must be zero terminated utf-8
9507    ///
9508    /// # Returns
9509    /// A non-null field handle or null on error.
9510    /// The field handle can be assumed to be constant for the given class and must not be freed.
9511    /// It can also be safely shared with any thread or stored in a constant.
9512    ///
9513    /// # Throws Java Exception
9514    /// * `NoSuchMethodError` - method with the given name and sig doesn't exist in the class
9515    /// * `ExceptionInInitializerError` - Exception occurs in initializer of the class
9516    /// * `OutOfMemoryError` - if the jvm runs out of memory
9517    ///
9518    ///
9519    /// # Panics
9520    /// if asserts feature is enabled and UB was detected
9521    ///
9522    /// # Safety
9523    ///
9524    /// Current thread must not be detached from JNI.
9525    ///
9526    /// Current thread must not be currently throwing an exception.
9527    ///
9528    /// Current thread does not hold a critical reference.
9529    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9530    ///
9531    /// `clazz` must a valid reference to a class that is not already garbage collected.
9532    /// `name` must be non-null and zero terminated utf-8.
9533    /// `sig` must be non-null and zero terminated utf-8.
9534    ///
9535    pub unsafe fn GetMethodID(&self, class: jclass, name: impl UseCString, sig: impl UseCString) -> jmethodID {
9536        unsafe {
9537            name.use_as_const_c_char(|name| {
9538                sig.use_as_const_c_char(|sig| {
9539                    #[cfg(feature = "asserts")]
9540                    {
9541                        self.check_not_critical("GetMethodID");
9542                        self.check_no_exception("GetMethodID");
9543                        assert!(!name.is_null(), "GetMethodID name is null");
9544                        assert!(!sig.is_null(), "GetMethodID sig is null");
9545                        self.check_is_class("GetMethodID", class);
9546                    }
9547                    self.jni::<extern "system" fn(JNIEnvVTable, jobject, *const c_char, *const c_char) -> jmethodID>(33)(self.vtable, class, name, sig)
9548                })
9549            })
9550        }
9551    }
9552
9553    ///
9554    /// Calls a non-static java method that returns void
9555    ///
9556    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9557    ///
9558    ///
9559    /// # Arguments
9560    /// * `obj` - which object the method should be called on
9561    ///     * must be valid
9562    ///     * must not be null
9563    ///     * must not be already garbage collected
9564    ///
9565    /// * `methodID` - method id of the method
9566    ///     * must not be null
9567    ///     * must be valid
9568    ///     * must not be a static
9569    ///     * must actually be a method of `obj`
9570    ///
9571    /// * `args` - argument pointer
9572    ///     * can be null if the method has no arguments
9573    ///     * must not be null otherwise and point to the exact number of arguments the method expects
9574    ///
9575    /// # Throws Java Exception
9576    /// * Whatever the method threw
9577    ///
9578    ///
9579    /// # Panics
9580    /// if asserts feature is enabled and UB was detected
9581    ///
9582    /// # Safety
9583    ///
9584    /// Current thread must not be detached from JNI.
9585    ///
9586    /// Current thread must not be currently throwing an exception.
9587    ///
9588    /// Current thread does not hold a critical reference.
9589    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9590    ///
9591    /// `obj` must a valid and not already garbage collected.
9592    /// `methodID` must be valid, non-static and actually be a method of `obj` and return void
9593    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
9594    /// `args` union must contain types that match the java methods parameters.
9595    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
9596    ///
9597    pub unsafe fn CallVoidMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) {
9598        unsafe {
9599            #[cfg(feature = "asserts")]
9600            {
9601                self.check_not_critical("CallVoidMethodA");
9602                self.check_no_exception("CallVoidMethodA");
9603                self.check_return_type_object("CallVoidMethodA", obj, methodID, "void");
9604            }
9605            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype)>(63)(self.vtable, obj, methodID, args);
9606        }
9607    }
9608
9609    ///
9610    /// Calls a non-static java method that has 0 arguments and returns void
9611    ///
9612    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9613    ///
9614    ///
9615    /// # Arguments
9616    /// * `obj` - which object the method should be called on
9617    ///     * must be valid
9618    ///     * must not be null
9619    ///     * must not be already garbage collected
9620    ///
9621    /// * `methodID` - method id of the method
9622    ///     * must not be null
9623    ///     * must be valid
9624    ///     * must not be a static
9625    ///     * must actually be a method of `obj`
9626    ///     * must refer to a method with 0 arguments
9627    ///
9628    /// # Throws Java Exception
9629    /// * Whatever the method threw
9630    ///
9631    ///
9632    /// # Panics
9633    /// if asserts feature is enabled and UB was detected
9634    ///
9635    /// # Safety
9636    ///
9637    /// Current thread must not be detached from JNI.
9638    ///
9639    /// Current thread must not be currently throwing an exception.
9640    ///
9641    /// Current thread does not hold a critical reference.
9642    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9643    ///
9644    /// `obj` must a valid and not already garbage collected.
9645    /// `methodID` must be valid, non-static and actually be a method of `obj`, return void and have no parameters
9646    ///
9647    pub unsafe fn CallVoidMethod0(&self, obj: jobject, methodID: jmethodID) {
9648        unsafe {
9649            #[cfg(feature = "asserts")]
9650            {
9651                self.check_not_critical("CallVoidMethod");
9652                self.check_no_exception("CallVoidMethod");
9653                self.check_return_type_object("CallVoidMethod", obj, methodID, "void");
9654            }
9655            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID)>(61)(self.vtable, obj, methodID);
9656        }
9657    }
9658
9659    ///
9660    /// Calls a non-static java method that has 1 arguments and returns void
9661    ///
9662    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9663    ///
9664    ///
9665    /// # Arguments
9666    /// * `obj` - which object the method should be called on
9667    ///     * must be valid
9668    ///     * must not be null
9669    ///     * must not be already garbage collected
9670    ///
9671    /// * `methodID` - method id of the method
9672    ///     * must not be null
9673    ///     * must be valid
9674    ///     * must not be a static
9675    ///     * must actually be a method of `obj`
9676    ///     * must refer to a method with 1 arguments
9677    ///
9678    /// # Throws Java Exception
9679    /// * Whatever the method threw
9680    ///
9681    ///
9682    /// # Panics
9683    /// if asserts feature is enabled and UB was detected
9684    ///
9685    /// # Safety
9686    ///
9687    /// Current thread must not be detached from JNI.
9688    ///
9689    /// Current thread must not be currently throwing an exception.
9690    ///
9691    /// Current thread does not hold a critical reference.
9692    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9693    ///
9694    /// `obj` must a valid and not already garbage collected.
9695    /// `methodID` must be valid, non-static and actually be a method of `obj`, return void and have 1 arguments
9696    ///
9697    pub unsafe fn CallVoidMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) {
9698        unsafe {
9699            #[cfg(feature = "asserts")]
9700            {
9701                self.check_not_critical("CallVoidMethod");
9702                self.check_no_exception("CallVoidMethod");
9703                self.check_return_type_object("CallVoidMethod", obj, methodID, "void");
9704                self.check_parameter_types_object("CallVoidMethod", obj, methodID, arg1, 0, 1);
9705            }
9706            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...)>(61)(self.vtable, obj, methodID, arg1);
9707        }
9708    }
9709
9710    ///
9711    /// Calls a non-static java method that has 2 arguments and returns void
9712    ///
9713    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9714    ///
9715    ///
9716    /// # Arguments
9717    /// * `obj` - which object the method should be called on
9718    ///     * must be valid
9719    ///     * must not be null
9720    ///     * must not be already garbage collected
9721    ///
9722    /// * `methodID` - method id of the method
9723    ///     * must not be null
9724    ///     * must be valid
9725    ///     * must not be a static
9726    ///     * must actually be a method of `obj`
9727    ///     * must refer to a method with 2 arguments
9728    ///
9729    /// # Throws Java Exception
9730    /// * Whatever the method threw
9731    ///
9732    ///
9733    /// # Panics
9734    /// if asserts feature is enabled and UB was detected
9735    ///
9736    /// # Safety
9737    ///
9738    /// Current thread must not be detached from JNI.
9739    ///
9740    /// Current thread must not be currently throwing an exception.
9741    ///
9742    /// Current thread does not hold a critical reference.
9743    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9744    ///
9745    /// `obj` must a valid and not already garbage collected.
9746    /// `methodID` must be valid, non-static and actually be a method of `obj`, return void and have 2 arguments
9747    ///
9748    pub unsafe fn CallVoidMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) {
9749        unsafe {
9750            #[cfg(feature = "asserts")]
9751            {
9752                self.check_not_critical("CallVoidMethod");
9753                self.check_no_exception("CallVoidMethod");
9754                self.check_return_type_object("CallVoidMethod", obj, methodID, "void");
9755                self.check_parameter_types_object("CallVoidMethod", obj, methodID, arg1, 0, 2);
9756                self.check_parameter_types_object("CallVoidMethod", obj, methodID, arg2, 1, 2);
9757            }
9758            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...)>(61)(self.vtable, obj, methodID, arg1, arg2);
9759        }
9760    }
9761
9762    ///
9763    /// Calls a non-static java method that has 3 arguments and returns void
9764    ///
9765    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9766    ///
9767    ///
9768    /// # Arguments
9769    /// * `obj` - which object the method should be called on
9770    ///     * must be valid
9771    ///     * must not be null
9772    ///     * must not be already garbage collected
9773    ///
9774    /// * `methodID` - method id of the method
9775    ///     * must not be null
9776    ///     * must be valid
9777    ///     * must not be a static
9778    ///     * must actually be a method of `obj`
9779    ///     * must refer to a method with 3 arguments
9780    ///
9781    /// # Throws Java Exception
9782    /// * Whatever the method threw
9783    ///
9784    ///
9785    /// # Panics
9786    /// if asserts feature is enabled and UB was detected
9787    ///
9788    /// # Safety
9789    ///
9790    /// Current thread must not be detached from JNI.
9791    ///
9792    /// Current thread must not be currently throwing an exception.
9793    ///
9794    /// Current thread does not hold a critical reference.
9795    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9796    ///
9797    /// `obj` must a valid and not already garbage collected.
9798    /// `methodID` must be valid, non-static and actually be a method of `obj`, return void and have 3 arguments
9799    ///
9800    pub unsafe fn CallVoidMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) {
9801        unsafe {
9802            #[cfg(feature = "asserts")]
9803            {
9804                self.check_not_critical("CallVoidMethod");
9805                self.check_no_exception("CallVoidMethod");
9806                self.check_return_type_object("CallVoidMethod", obj, methodID, "void");
9807                self.check_parameter_types_object("CallVoidMethod", obj, methodID, arg1, 0, 3);
9808                self.check_parameter_types_object("CallVoidMethod", obj, methodID, arg2, 1, 3);
9809                self.check_parameter_types_object("CallVoidMethod", obj, methodID, arg3, 2, 3);
9810            }
9811            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...)>(61)(self.vtable, obj, methodID, arg1, arg2, arg3);
9812        }
9813    }
9814
9815    ///
9816    /// Calls a non-static java method that returns an object
9817    ///
9818    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9819    ///
9820    ///
9821    /// # Arguments
9822    /// * `obj` - which object the method should be called on
9823    ///     * must be valid
9824    ///     * must not be null
9825    ///     * must not be already garbage collected
9826    ///
9827    /// * `methodID` - method id of the method
9828    ///     * must not be null
9829    ///     * must be valid
9830    ///     * must not be a static
9831    ///     * must actually be a method of `obj`
9832    ///
9833    /// * `args` - argument pointer
9834    ///     * can be null if the method has no arguments
9835    ///     * must not be null otherwise and point to the exact number of arguments the method expects
9836    ///
9837    /// # Returns
9838    /// Whatever the method returned or null if it threw
9839    ///
9840    /// # Throws Java Exception
9841    /// * Whatever the method threw
9842    ///
9843    ///
9844    /// # Panics
9845    /// if asserts feature is enabled and UB was detected
9846    ///
9847    /// # Safety
9848    ///
9849    /// Current thread must not be detached from JNI.
9850    ///
9851    /// Current thread must not be currently throwing an exception.
9852    ///
9853    /// Current thread does not hold a critical reference.
9854    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9855    ///
9856    /// `obj` must a valid and not already garbage collected.
9857    /// `methodID` must be valid, non-static and actually be a method of `obj` and return an object
9858    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
9859    /// `args` union must contain types that match the java methods parameters.
9860    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
9861    ///
9862    pub unsafe fn CallObjectMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) -> jobject {
9863        unsafe {
9864            #[cfg(feature = "asserts")]
9865            {
9866                self.check_not_critical("CallObjectMethodA");
9867                self.check_no_exception("CallObjectMethodA");
9868                self.check_return_type_object("CallObjectMethodA", obj, methodID, "object");
9869            }
9870            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, obj, methodID, args)
9871        }
9872    }
9873
9874    ///
9875    /// Calls a non-static java method that has 0 arguments and returns an object
9876    ///
9877    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9878    ///
9879    ///
9880    /// # Arguments
9881    /// * `obj` - which object the method should be called on
9882    ///     * must be valid
9883    ///     * must not be null
9884    ///     * must not be already garbage collected
9885    ///
9886    /// * `methodID` - method id of the method
9887    ///     * must not be null
9888    ///     * must be valid
9889    ///     * must not be a static
9890    ///     * must actually be a method of `obj`
9891    ///     * must refer to a method with 0 arguments
9892    ///
9893    /// # Returns
9894    /// Whatever the method returned or null if it threw
9895    ///
9896    /// # Throws Java Exception
9897    /// * Whatever the method threw
9898    ///
9899    ///
9900    /// # Panics
9901    /// if asserts feature is enabled and UB was detected
9902    ///
9903    /// # Safety
9904    ///
9905    /// Current thread must not be detached from JNI.
9906    ///
9907    /// Current thread must not be currently throwing an exception.
9908    ///
9909    /// Current thread does not hold a critical reference.
9910    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9911    ///
9912    /// `obj` must a valid and not already garbage collected.
9913    /// `methodID` must be valid, non-static and actually be a method of `obj`, return an object and have no parameters
9914    ///
9915    pub unsafe fn CallObjectMethod0(&self, obj: jobject, methodID: jmethodID) -> jobject {
9916        unsafe {
9917            #[cfg(feature = "asserts")]
9918            {
9919                self.check_not_critical("CallObjectMethod");
9920                self.check_no_exception("CallObjectMethod");
9921                self.check_return_type_object("CallObjectMethod", obj, methodID, "object");
9922            }
9923            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jobject>(34)(self.vtable, obj, methodID)
9924        }
9925    }
9926
9927    ///
9928    /// Calls a non-static java method that has 1 arguments and returns an object
9929    ///
9930    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9931    ///
9932    ///
9933    /// # Arguments
9934    /// * `obj` - which object the method should be called on
9935    ///     * must be valid
9936    ///     * must not be null
9937    ///     * must not be already garbage collected
9938    ///
9939    /// * `methodID` - method id of the method
9940    ///     * must not be null
9941    ///     * must be valid
9942    ///     * must not be a static
9943    ///     * must actually be a method of `obj`
9944    ///     * must refer to a method with 1 arguments
9945    ///
9946    /// # Returns
9947    /// Whatever the method returned or null if it threw
9948    ///
9949    /// # Throws Java Exception
9950    /// * Whatever the method threw
9951    ///
9952    ///
9953    /// # Panics
9954    /// if asserts feature is enabled and UB was detected
9955    ///
9956    /// # Safety
9957    ///
9958    /// Current thread must not be detached from JNI.
9959    ///
9960    /// Current thread must not be currently throwing an exception.
9961    ///
9962    /// Current thread does not hold a critical reference.
9963    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9964    ///
9965    /// `obj` must a valid and not already garbage collected.
9966    /// `methodID` must be valid, non-static and actually be a method of `obj`, return an object and have 1 arguments
9967    ///
9968    pub unsafe fn CallObjectMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) -> jobject {
9969        unsafe {
9970            #[cfg(feature = "asserts")]
9971            {
9972                self.check_not_critical("CallObjectMethod");
9973                self.check_no_exception("CallObjectMethod");
9974                self.check_return_type_object("CallObjectMethod", obj, methodID, "object");
9975                self.check_parameter_types_object("CallObjectMethod", obj, methodID, arg1, 0, 1);
9976            }
9977            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jobject>(34)(self.vtable, obj, methodID, arg1)
9978        }
9979    }
9980
9981    ///
9982    /// Calls a non-static java method that has 2 arguments and returns an object
9983    ///
9984    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9985    ///
9986    ///
9987    /// # Arguments
9988    /// * `obj` - which object the method should be called on
9989    ///     * must be valid
9990    ///     * must not be null
9991    ///     * must not be already garbage collected
9992    ///
9993    /// * `methodID` - method id of the method
9994    ///     * must not be null
9995    ///     * must be valid
9996    ///     * must not be a static
9997    ///     * must actually be a method of `obj`
9998    ///     * must refer to a method with 2 arguments
9999    ///
10000    /// # Returns
10001    /// Whatever the method returned or null if it threw
10002    ///
10003    /// # Throws Java Exception
10004    /// * Whatever the method threw
10005    ///
10006    ///
10007    /// # Panics
10008    /// if asserts feature is enabled and UB was detected
10009    ///
10010    /// # Safety
10011    ///
10012    /// Current thread must not be detached from JNI.
10013    ///
10014    /// Current thread must not be currently throwing an exception.
10015    ///
10016    /// Current thread does not hold a critical reference.
10017    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10018    ///
10019    /// `obj` must a valid and not already garbage collected.
10020    /// `methodID` must be valid, non-static and actually be a method of `obj`, return an object and have 2 arguments
10021    ///
10022    pub unsafe fn CallObjectMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) -> jobject {
10023        unsafe {
10024            #[cfg(feature = "asserts")]
10025            {
10026                self.check_not_critical("CallObjectMethod");
10027                self.check_no_exception("CallObjectMethod");
10028                self.check_return_type_object("CallObjectMethod", obj, methodID, "object");
10029                self.check_parameter_types_object("CallObjectMethod", obj, methodID, arg1, 0, 2);
10030                self.check_parameter_types_object("CallObjectMethod", obj, methodID, arg2, 1, 2);
10031            }
10032            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jobject>(34)(self.vtable, obj, methodID, arg1, arg2)
10033        }
10034    }
10035
10036    ///
10037    /// Calls a non-static java method that has 3 arguments and returns an object
10038    ///
10039    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10040    ///
10041    ///
10042    /// # Arguments
10043    /// * `obj` - which object the method should be called on
10044    ///     * must be valid
10045    ///     * must not be null
10046    ///     * must not be already garbage collected
10047    ///
10048    /// * `methodID` - method id of the method
10049    ///     * must not be null
10050    ///     * must be valid
10051    ///     * must not be a static
10052    ///     * must actually be a method of `obj`
10053    ///     * must refer to a method with 3 arguments
10054    ///
10055    /// # Returns
10056    /// Whatever the method returned or null if it threw
10057    ///
10058    /// # Throws Java Exception
10059    /// * Whatever the method threw
10060    ///
10061    ///
10062    /// # Panics
10063    /// if asserts feature is enabled and UB was detected
10064    ///
10065    /// # Safety
10066    ///
10067    /// Current thread must not be detached from JNI.
10068    ///
10069    /// Current thread must not be currently throwing an exception.
10070    ///
10071    /// Current thread does not hold a critical reference.
10072    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10073    ///
10074    /// `obj` must a valid and not already garbage collected.
10075    /// `methodID` must be valid, non-static and actually be a method of `obj`, return an object and have 3 arguments
10076    ///
10077    pub unsafe fn CallObjectMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jobject {
10078        unsafe {
10079            #[cfg(feature = "asserts")]
10080            {
10081                self.check_not_critical("CallObjectMethod");
10082                self.check_no_exception("CallObjectMethod");
10083                self.check_return_type_object("CallObjectMethod", obj, methodID, "object");
10084                self.check_parameter_types_object("CallObjectMethod", obj, methodID, arg1, 0, 3);
10085                self.check_parameter_types_object("CallObjectMethod", obj, methodID, arg2, 1, 3);
10086                self.check_parameter_types_object("CallObjectMethod", obj, methodID, arg3, 2, 3);
10087            }
10088            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jobject>(34)(self.vtable, obj, methodID, arg1, arg2, arg3)
10089        }
10090    }
10091
10092    ///
10093    /// Calls a non-static java method that returns a boolean
10094    ///
10095    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10096    ///
10097    ///
10098    /// # Arguments
10099    /// * `obj` - which object the method should be called on
10100    ///     * must be valid
10101    ///     * must not be null
10102    ///     * must not be already garbage collected
10103    ///
10104    /// * `methodID` - method id of the method
10105    ///     * must not be null
10106    ///     * must be valid
10107    ///     * must not be a static
10108    ///     * must actually be a method of `obj`
10109    ///
10110    /// * `args` - argument pointer
10111    ///     * can be null if the method has no arguments
10112    ///     * must not be null otherwise and point to the exact number of arguments the method expects
10113    ///
10114    /// # Returns
10115    /// Whatever the method returned or false if it threw
10116    ///
10117    /// # Throws Java Exception
10118    /// * Whatever the method threw
10119    ///
10120    ///
10121    /// # Panics
10122    /// if asserts feature is enabled and UB was detected
10123    ///
10124    /// # Safety
10125    ///
10126    /// Current thread must not be detached from JNI.
10127    ///
10128    /// Current thread must not be currently throwing an exception.
10129    ///
10130    /// Current thread does not hold a critical reference.
10131    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10132    ///
10133    /// `obj` must a valid and not already garbage collected.
10134    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a boolean
10135    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
10136    /// `args` union must contain types that match the java methods parameters.
10137    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
10138    ///
10139    pub unsafe fn CallBooleanMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) -> bool {
10140        unsafe {
10141            #[cfg(feature = "asserts")]
10142            {
10143                self.check_not_critical("CallBooleanMethodA");
10144                self.check_no_exception("CallBooleanMethodA");
10145                self.check_return_type_object("CallBooleanMethodA", obj, methodID, "boolean");
10146            }
10147            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jboolean>(39)(self.vtable, obj, methodID, args).as_bool()
10148        }
10149    }
10150
10151    ///
10152    /// Calls a non-static java method that has 0 arguments and returns boolean
10153    ///
10154    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10155    ///
10156    ///
10157    /// # Arguments
10158    /// * `obj` - which object the method should be called on
10159    ///     * must be valid
10160    ///     * must not be null
10161    ///     * must not be already garbage collected
10162    ///
10163    /// * `methodID` - method id of the method
10164    ///     * must not be null
10165    ///     * must be valid
10166    ///     * must not be a static
10167    ///     * must actually be a method of `obj`
10168    ///     * must refer to a method with 0 arguments
10169    ///
10170    /// # Returns
10171    /// Whatever the method returned or false if it threw
10172    ///
10173    /// # Throws Java Exception
10174    /// * Whatever the method threw
10175    ///
10176    ///
10177    /// # Panics
10178    /// if asserts feature is enabled and UB was detected
10179    ///
10180    /// # Safety
10181    ///
10182    /// Current thread must not be detached from JNI.
10183    ///
10184    /// Current thread must not be currently throwing an exception.
10185    ///
10186    /// Current thread does not hold a critical reference.
10187    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10188    ///
10189    /// `obj` must a valid and not already garbage collected.
10190    /// `methodID` must be valid, non-static and actually be a method of `obj`, return boolean and have no parameters
10191    ///
10192    pub unsafe fn CallBooleanMethod0(&self, obj: jobject, methodID: jmethodID) -> bool {
10193        unsafe {
10194            #[cfg(feature = "asserts")]
10195            {
10196                self.check_not_critical("CallBooleanMethod");
10197                self.check_no_exception("CallBooleanMethod");
10198                self.check_return_type_object("CallBooleanMethod", obj, methodID, "boolean");
10199            }
10200            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jboolean>(37)(self.vtable, obj, methodID).as_bool()
10201        }
10202    }
10203
10204    ///
10205    /// Calls a non-static java method that has 1 arguments and returns boolean
10206    ///
10207    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10208    ///
10209    ///
10210    /// # Arguments
10211    /// * `obj` - which object the method should be called on
10212    ///     * must be valid
10213    ///     * must not be null
10214    ///     * must not be already garbage collected
10215    ///
10216    /// * `methodID` - method id of the method
10217    ///     * must not be null
10218    ///     * must be valid
10219    ///     * must not be a static
10220    ///     * must actually be a method of `obj`
10221    ///     * must refer to a method with 1 arguments
10222    ///
10223    /// # Returns
10224    /// Whatever the method returned or false if it threw
10225    ///
10226    /// # Throws Java Exception
10227    /// * Whatever the method threw
10228    ///
10229    ///
10230    /// # Panics
10231    /// if asserts feature is enabled and UB was detected
10232    ///
10233    /// # Safety
10234    ///
10235    /// Current thread must not be detached from JNI.
10236    ///
10237    /// Current thread must not be currently throwing an exception.
10238    ///
10239    /// Current thread does not hold a critical reference.
10240    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10241    ///
10242    /// `obj` must a valid and not already garbage collected.
10243    /// `methodID` must be valid, non-static and actually be a method of `obj`, return boolean and have 1 parameter
10244    /// The parameter types must exactly match the java method parameters.
10245    ///
10246    pub unsafe fn CallBooleanMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) -> bool {
10247        unsafe {
10248            #[cfg(feature = "asserts")]
10249            {
10250                self.check_not_critical("CallBooleanMethod");
10251                self.check_no_exception("CallBooleanMethod");
10252                self.check_return_type_object("CallBooleanMethod", obj, methodID, "boolean");
10253                self.check_parameter_types_object("CallBooleanMethod", obj, methodID, arg1, 0, 1);
10254            }
10255            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jboolean>(37)(self.vtable, obj, methodID, arg1).as_bool()
10256        }
10257    }
10258
10259    ///
10260    /// Calls a non-static java method that has 2 arguments and returns boolean
10261    ///
10262    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10263    ///
10264    ///
10265    /// # Arguments
10266    /// * `obj` - which object the method should be called on
10267    ///     * must be valid
10268    ///     * must not be null
10269    ///     * must not be already garbage collected
10270    ///
10271    /// * `methodID` - method id of the method
10272    ///     * must not be null
10273    ///     * must be valid
10274    ///     * must not be a static
10275    ///     * must actually be a method of `obj`
10276    ///     * must refer to a method with 2 arguments
10277    ///
10278    /// # Returns
10279    /// Whatever the method returned or false if it threw
10280    ///
10281    /// # Throws Java Exception
10282    /// * Whatever the method threw
10283    ///
10284    ///
10285    /// # Panics
10286    /// if asserts feature is enabled and UB was detected
10287    ///
10288    /// # Safety
10289    ///
10290    /// Current thread must not be detached from JNI.
10291    ///
10292    /// Current thread must not be currently throwing an exception.
10293    ///
10294    /// Current thread does not hold a critical reference.
10295    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10296    ///
10297    /// `obj` must a valid and not already garbage collected.
10298    /// `methodID` must be valid, non-static and actually be a method of `obj`, return boolean and have 2 parameter
10299    /// The parameter types must exactly match the java method parameters.
10300    ///
10301    pub unsafe fn CallBooleanMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) -> bool {
10302        unsafe {
10303            #[cfg(feature = "asserts")]
10304            {
10305                self.check_not_critical("CallBooleanMethod");
10306                self.check_no_exception("CallBooleanMethod");
10307                self.check_return_type_object("CallBooleanMethod", obj, methodID, "boolean");
10308                self.check_parameter_types_object("CallBooleanMethod", obj, methodID, arg1, 0, 2);
10309                self.check_parameter_types_object("CallBooleanMethod", obj, methodID, arg2, 1, 2);
10310            }
10311            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jboolean>(37)(self.vtable, obj, methodID, arg1, arg2).as_bool()
10312        }
10313    }
10314
10315    ///
10316    /// Calls a non-static java method that has 3 arguments and returns boolean
10317    ///
10318    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10319    ///
10320    ///
10321    /// # Arguments
10322    /// * `obj` - which object the method should be called on
10323    ///     * must be valid
10324    ///     * must not be null
10325    ///     * must not be already garbage collected
10326    ///
10327    /// * `methodID` - method id of the method
10328    ///     * must not be null
10329    ///     * must be valid
10330    ///     * must not be a static
10331    ///     * must actually be a method of `obj`
10332    ///     * must refer to a method with 3 arguments
10333    ///
10334    /// # Returns
10335    /// Whatever the method returned or false if it threw
10336    ///
10337    /// # Throws Java Exception
10338    /// * Whatever the method threw
10339    ///
10340    ///
10341    /// # Panics
10342    /// if asserts feature is enabled and UB was detected
10343    ///
10344    /// # Safety
10345    ///
10346    /// Current thread must not be detached from JNI.
10347    ///
10348    /// Current thread must not be currently throwing an exception.
10349    ///
10350    /// Current thread does not hold a critical reference.
10351    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10352    ///
10353    /// `obj` must a valid and not already garbage collected.
10354    /// `methodID` must be valid, non-static and actually be a method of `obj`, return boolean and have 3 parameter
10355    /// The parameter types must exactly match the java method parameters.
10356    ///
10357    pub unsafe fn CallBooleanMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> bool {
10358        unsafe {
10359            #[cfg(feature = "asserts")]
10360            {
10361                self.check_not_critical("CallBooleanMethod");
10362                self.check_no_exception("CallBooleanMethod");
10363                self.check_return_type_object("CallBooleanMethod", obj, methodID, "boolean");
10364                self.check_parameter_types_object("CallBooleanMethod", obj, methodID, arg1, 0, 3);
10365                self.check_parameter_types_object("CallBooleanMethod", obj, methodID, arg2, 1, 3);
10366                self.check_parameter_types_object("CallBooleanMethod", obj, methodID, arg3, 2, 3);
10367            }
10368            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jboolean>(37)(self.vtable, obj, methodID, arg1, arg2, arg3).as_bool()
10369        }
10370    }
10371
10372    ///
10373    /// Calls a non-static java method that returns a byte
10374    ///
10375    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10376    ///
10377    ///
10378    /// # Arguments
10379    /// * `obj` - which object the method should be called on
10380    ///     * must be valid
10381    ///     * must not be null
10382    ///     * must not be already garbage collected
10383    ///
10384    /// * `methodID` - method id of the method
10385    ///     * must not be null
10386    ///     * must be valid
10387    ///     * must not be a static
10388    ///     * must actually be a method of `obj`
10389    ///
10390    /// * `args` - argument pointer
10391    ///     * can be null if the method has no arguments
10392    ///     * must not be null otherwise and point to the exact number of arguments the method expects
10393    ///
10394    /// # Returns
10395    /// Whatever the method returned or 0 if it threw
10396    ///
10397    /// # Throws Java Exception
10398    /// * Whatever the method threw
10399    ///
10400    ///
10401    /// # Panics
10402    /// if asserts feature is enabled and UB was detected
10403    ///
10404    /// # Safety
10405    ///
10406    /// Current thread must not be detached from JNI.
10407    ///
10408    /// Current thread must not be currently throwing an exception.
10409    ///
10410    /// Current thread does not hold a critical reference.
10411    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10412    ///
10413    /// `obj` must a valid and not already garbage collected.
10414    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a byte
10415    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
10416    /// `args` union must contain types that match the java methods parameters.
10417    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
10418    ///
10419    pub unsafe fn CallByteMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) -> jbyte {
10420        unsafe {
10421            #[cfg(feature = "asserts")]
10422            {
10423                self.check_not_critical("CallByteMethodA");
10424                self.check_no_exception("CallByteMethodA");
10425                self.check_return_type_object("CallByteMethodA", obj, methodID, "byte");
10426            }
10427            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jbyte>(42)(self.vtable, obj, methodID, args)
10428        }
10429    }
10430
10431    ///
10432    /// Calls a non-static java method that has 0 arguments and returns byte
10433    ///
10434    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10435    ///
10436    ///
10437    /// # Arguments
10438    /// * `obj` - which object the method should be called on
10439    ///     * must be valid
10440    ///     * must not be null
10441    ///     * must not be already garbage collected
10442    ///
10443    /// * `methodID` - method id of the method
10444    ///     * must not be null
10445    ///     * must be valid
10446    ///     * must not be a static
10447    ///     * must actually be a method of `obj`
10448    ///     * must refer to a method with 0 arguments
10449    ///
10450    /// # Returns
10451    /// Whatever the method returned or 0 if it threw
10452    ///
10453    /// # Throws Java Exception
10454    /// * Whatever the method threw
10455    ///
10456    ///
10457    /// # Panics
10458    /// if asserts feature is enabled and UB was detected
10459    ///
10460    /// # Safety
10461    ///
10462    /// Current thread must not be detached from JNI.
10463    ///
10464    /// Current thread must not be currently throwing an exception.
10465    ///
10466    /// Current thread does not hold a critical reference.
10467    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10468    ///
10469    /// `obj` must a valid and not already garbage collected.
10470    /// `methodID` must be valid, non-static and actually be a method of `obj`, return byte and have no parameters
10471    ///
10472    pub unsafe fn CallByteMethod0(&self, obj: jobject, methodID: jmethodID) -> jbyte {
10473        unsafe {
10474            #[cfg(feature = "asserts")]
10475            {
10476                self.check_not_critical("CallByteMethod0");
10477                self.check_no_exception("CallByteMethod0");
10478                self.check_return_type_object("CallByteMethod0", obj, methodID, "byte");
10479            }
10480            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jbyte>(40)(self.vtable, obj, methodID)
10481        }
10482    }
10483
10484    ///
10485    /// Calls a non-static java method that has 1 arguments and returns byte
10486    ///
10487    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10488    ///
10489    ///
10490    /// # Arguments
10491    /// * `obj` - which object the method should be called on
10492    ///     * must be valid
10493    ///     * must not be null
10494    ///     * must not be already garbage collected
10495    ///
10496    /// * `methodID` - method id of the method
10497    ///     * must not be null
10498    ///     * must be valid
10499    ///     * must not be a static
10500    ///     * must actually be a method of `obj`
10501    ///     * must refer to a method with 1 arguments
10502    ///
10503    /// # Returns
10504    /// Whatever the method returned or 0 if it threw
10505    ///
10506    /// # Throws Java Exception
10507    /// * Whatever the method threw
10508    ///
10509    ///
10510    /// # Panics
10511    /// if asserts feature is enabled and UB was detected
10512    ///
10513    /// # Safety
10514    ///
10515    /// Current thread must not be detached from JNI.
10516    ///
10517    /// Current thread must not be currently throwing an exception.
10518    ///
10519    /// Current thread does not hold a critical reference.
10520    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10521    ///
10522    /// `obj` must a valid and not already garbage collected.
10523    /// `methodID` must be valid, non-static and actually be a method of `obj`, return byte and have 1 parameter
10524    /// The parameter types must exactly match the java method parameters.
10525    ///
10526    pub unsafe fn CallByteMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) -> jbyte {
10527        unsafe {
10528            #[cfg(feature = "asserts")]
10529            {
10530                self.check_not_critical("CallByteMethod1");
10531                self.check_no_exception("CallByteMethod1");
10532                self.check_return_type_object("CallByteMethod1", obj, methodID, "byte");
10533                self.check_parameter_types_object("CallByteMethod1", obj, methodID, arg1, 0, 1);
10534            }
10535            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jbyte>(40)(self.vtable, obj, methodID, arg1)
10536        }
10537    }
10538
10539    ///
10540    /// Calls a non-static java method that has 2 arguments and returns byte
10541    ///
10542    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10543    ///
10544    ///
10545    /// # Arguments
10546    /// * `obj` - which object the method should be called on
10547    ///     * must be valid
10548    ///     * must not be null
10549    ///     * must not be already garbage collected
10550    ///
10551    /// * `methodID` - method id of the method
10552    ///     * must not be null
10553    ///     * must be valid
10554    ///     * must not be a static
10555    ///     * must actually be a method of `obj`
10556    ///     * must refer to a method with 2 arguments
10557    ///
10558    /// # Returns
10559    /// Whatever the method returned or 0 if it threw
10560    ///
10561    /// # Throws Java Exception
10562    /// * Whatever the method threw
10563    ///
10564    ///
10565    /// # Panics
10566    /// if asserts feature is enabled and UB was detected
10567    ///
10568    /// # Safety
10569    ///
10570    /// Current thread must not be detached from JNI.
10571    ///
10572    /// Current thread must not be currently throwing an exception.
10573    ///
10574    /// Current thread does not hold a critical reference.
10575    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10576    ///
10577    /// `obj` must a valid and not already garbage collected.
10578    /// `methodID` must be valid, non-static and actually be a method of `obj`, return byte and have 2 parameter
10579    /// The parameter types must exactly match the java method parameters.
10580    ///
10581    pub unsafe fn CallByteMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) -> jbyte {
10582        unsafe {
10583            #[cfg(feature = "asserts")]
10584            {
10585                self.check_not_critical("CallByteMethod2");
10586                self.check_no_exception("CallByteMethod2");
10587                self.check_return_type_object("CallByteMethod2", obj, methodID, "byte");
10588                self.check_parameter_types_object("CallByteMethod2", obj, methodID, arg1, 0, 2);
10589                self.check_parameter_types_object("CallByteMethod2", obj, methodID, arg2, 1, 2);
10590            }
10591            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jbyte>(40)(self.vtable, obj, methodID, arg1, arg2)
10592        }
10593    }
10594
10595    ///
10596    /// Calls a non-static java method that has 3 arguments and returns byte
10597    ///
10598    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10599    ///
10600    ///
10601    /// # Arguments
10602    /// * `obj` - which object the method should be called on
10603    ///     * must be valid
10604    ///     * must not be null
10605    ///     * must not be already garbage collected
10606    ///
10607    /// * `methodID` - method id of the method
10608    ///     * must not be null
10609    ///     * must be valid
10610    ///     * must not be a static
10611    ///     * must actually be a method of `obj`
10612    ///     * must refer to a method with 3 arguments
10613    ///
10614    /// # Returns
10615    /// Whatever the method returned or 0 if it threw
10616    ///
10617    /// # Throws Java Exception
10618    /// * Whatever the method threw
10619    ///
10620    ///
10621    /// # Panics
10622    /// if asserts feature is enabled and UB was detected
10623    ///
10624    /// # Safety
10625    ///
10626    /// Current thread must not be detached from JNI.
10627    ///
10628    /// Current thread must not be currently throwing an exception.
10629    ///
10630    /// Current thread does not hold a critical reference.
10631    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10632    ///
10633    /// `obj` must a valid and not already garbage collected.
10634    /// `methodID` must be valid, non-static and actually be a method of `obj`, return byte and have 3 parameter
10635    /// The parameter types must exactly match the java method parameters.
10636    ///
10637    pub unsafe fn CallByteMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jbyte {
10638        unsafe {
10639            #[cfg(feature = "asserts")]
10640            {
10641                self.check_not_critical("CallByteMethod3");
10642                self.check_no_exception("CallByteMethod3");
10643                self.check_return_type_object("CallByteMethod3", obj, methodID, "byte");
10644                self.check_parameter_types_object("CallByteMethod3", obj, methodID, arg1, 0, 3);
10645                self.check_parameter_types_object("CallByteMethod3", obj, methodID, arg2, 1, 3);
10646                self.check_parameter_types_object("CallByteMethod3", obj, methodID, arg3, 2, 3);
10647            }
10648            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jbyte>(40)(self.vtable, obj, methodID, arg1, arg2, arg3)
10649        }
10650    }
10651
10652    ///
10653    /// Calls a non-static java method that returns a char
10654    ///
10655    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10656    ///
10657    ///
10658    /// # Arguments
10659    /// * `obj` - which object the method should be called on
10660    ///     * must be valid
10661    ///     * must not be null
10662    ///     * must not be already garbage collected
10663    ///
10664    /// * `methodID` - method id of the method
10665    ///     * must not be null
10666    ///     * must be valid
10667    ///     * must not be a static
10668    ///     * must actually be a method of `obj`
10669    ///
10670    /// * `args` - argument pointer
10671    ///     * can be null if the method has no arguments
10672    ///     * must not be null otherwise and point to the exact number of arguments the method expects
10673    ///
10674    /// # Returns
10675    /// Whatever the method returned or 0 if it threw
10676    ///
10677    /// # Throws Java Exception
10678    /// * Whatever the method threw
10679    ///
10680    ///
10681    /// # Panics
10682    /// if asserts feature is enabled and UB was detected
10683    ///
10684    /// # Safety
10685    ///
10686    /// Current thread must not be detached from JNI.
10687    ///
10688    /// Current thread must not be currently throwing an exception.
10689    ///
10690    /// Current thread does not hold a critical reference.
10691    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10692    ///
10693    /// `obj` must a valid and not already garbage collected.
10694    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a char
10695    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
10696    /// `args` union must contain types that match the java methods parameters.
10697    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
10698    ///
10699    pub unsafe fn CallCharMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) -> jchar {
10700        unsafe {
10701            #[cfg(feature = "asserts")]
10702            {
10703                self.check_not_critical("CallCharMethodA");
10704                self.check_no_exception("CallCharMethodA");
10705                self.check_return_type_object("CallCharMethodA", obj, methodID, "char");
10706            }
10707            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jchar>(45)(self.vtable, obj, methodID, args)
10708        }
10709    }
10710
10711    ///
10712    /// Calls a non-static java method that has 0 arguments and returns char
10713    ///
10714    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10715    ///
10716    ///
10717    /// # Arguments
10718    /// * `obj` - which object the method should be called on
10719    ///     * must be valid
10720    ///     * must not be null
10721    ///     * must not be already garbage collected
10722    ///
10723    /// * `methodID` - method id of the method
10724    ///     * must not be null
10725    ///     * must be valid
10726    ///     * must not be a static
10727    ///     * must actually be a method of `obj`
10728    ///     * must refer to a method with 0 arguments
10729    ///
10730    /// # Returns
10731    /// Whatever the method returned or 0 if it threw
10732    ///
10733    /// # Throws Java Exception
10734    /// * Whatever the method threw
10735    ///
10736    ///
10737    /// # Panics
10738    /// if asserts feature is enabled and UB was detected
10739    ///
10740    /// # Safety
10741    ///
10742    /// Current thread must not be detached from JNI.
10743    ///
10744    /// Current thread must not be currently throwing an exception.
10745    ///
10746    /// Current thread does not hold a critical reference.
10747    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10748    ///
10749    /// `obj` must a valid and not already garbage collected.
10750    /// `methodID` must be valid, non-static and actually be a method of `obj`, return char and have no parameters
10751    ///
10752    pub unsafe fn CallCharMethod0(&self, obj: jobject, methodID: jmethodID) -> jchar {
10753        unsafe {
10754            #[cfg(feature = "asserts")]
10755            {
10756                self.check_not_critical("CallCharMethod");
10757                self.check_no_exception("CallCharMethod");
10758                self.check_return_type_object("CallCharMethod", obj, methodID, "char");
10759            }
10760            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jchar>(43)(self.vtable, obj, methodID)
10761        }
10762    }
10763
10764    ///
10765    /// Calls a non-static java method that has 1 arguments and returns char
10766    ///
10767    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10768    ///
10769    ///
10770    /// # Arguments
10771    /// * `obj` - which object the method should be called on
10772    ///     * must be valid
10773    ///     * must not be null
10774    ///     * must not be already garbage collected
10775    ///
10776    /// * `methodID` - method id of the method
10777    ///     * must not be null
10778    ///     * must be valid
10779    ///     * must not be a static
10780    ///     * must actually be a method of `obj`
10781    ///     * must refer to a method with 1 arguments
10782    ///
10783    /// # Returns
10784    /// Whatever the method returned or 0 if it threw
10785    ///
10786    /// # Throws Java Exception
10787    /// * Whatever the method threw
10788    ///
10789    ///
10790    /// # Panics
10791    /// if asserts feature is enabled and UB was detected
10792    ///
10793    /// # Safety
10794    ///
10795    /// Current thread must not be detached from JNI.
10796    ///
10797    /// Current thread must not be currently throwing an exception.
10798    ///
10799    /// Current thread does not hold a critical reference.
10800    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10801    ///
10802    /// `obj` must a valid and not already garbage collected.
10803    /// `methodID` must be valid, non-static and actually be a method of `obj`, return char and have 1 parameter
10804    /// The parameter types must exactly match the java method parameters.
10805    ///
10806    pub unsafe fn CallCharMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) -> jchar {
10807        unsafe {
10808            #[cfg(feature = "asserts")]
10809            {
10810                self.check_not_critical("CallCharMethod");
10811                self.check_no_exception("CallCharMethod");
10812                self.check_return_type_object("CallCharMethod", obj, methodID, "char");
10813                self.check_parameter_types_object("CallCharMethod", obj, methodID, arg1, 0, 1);
10814            }
10815            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jchar>(43)(self.vtable, obj, methodID, arg1)
10816        }
10817    }
10818
10819    ///
10820    /// Calls a non-static java method that has 2 arguments and returns char
10821    ///
10822    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10823    ///
10824    ///
10825    /// # Arguments
10826    /// * `obj` - which object the method should be called on
10827    ///     * must be valid
10828    ///     * must not be null
10829    ///     * must not be already garbage collected
10830    ///
10831    /// * `methodID` - method id of the method
10832    ///     * must not be null
10833    ///     * must be valid
10834    ///     * must not be a static
10835    ///     * must actually be a method of `obj`
10836    ///     * must refer to a method with 2 arguments
10837    ///
10838    /// # Returns
10839    /// Whatever the method returned or 0 if it threw
10840    ///
10841    /// # Throws Java Exception
10842    /// * Whatever the method threw
10843    ///
10844    ///
10845    /// # Panics
10846    /// if asserts feature is enabled and UB was detected
10847    ///
10848    /// # Safety
10849    ///
10850    /// Current thread must not be detached from JNI.
10851    ///
10852    /// Current thread must not be currently throwing an exception.
10853    ///
10854    /// Current thread does not hold a critical reference.
10855    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10856    ///
10857    /// `obj` must a valid and not already garbage collected.
10858    /// `methodID` must be valid, non-static and actually be a method of `obj`, return char and have 2 parameter
10859    /// The parameter types must exactly match the java method parameters.
10860    ///
10861    pub unsafe fn CallCharMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) -> jchar {
10862        unsafe {
10863            #[cfg(feature = "asserts")]
10864            {
10865                self.check_not_critical("CallCharMethod");
10866                self.check_no_exception("CallCharMethod");
10867                self.check_return_type_object("CallCharMethod", obj, methodID, "char");
10868                self.check_parameter_types_object("CallCharMethod", obj, methodID, arg1, 0, 2);
10869                self.check_parameter_types_object("CallCharMethod", obj, methodID, arg2, 1, 2);
10870            }
10871            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jchar>(43)(self.vtable, obj, methodID, arg1, arg2)
10872        }
10873    }
10874
10875    ///
10876    /// Calls a non-static java method that has 3 arguments and returns char
10877    ///
10878    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10879    ///
10880    ///
10881    /// # Arguments
10882    /// * `obj` - which object the method should be called on
10883    ///     * must be valid
10884    ///     * must not be null
10885    ///     * must not be already garbage collected
10886    ///
10887    /// * `methodID` - method id of the method
10888    ///     * must not be null
10889    ///     * must be valid
10890    ///     * must not be a static
10891    ///     * must actually be a method of `obj`
10892    ///     * must refer to a method with 3 arguments
10893    ///
10894    /// # Returns
10895    /// Whatever the method returned or 0 if it threw
10896    ///
10897    /// # Throws Java Exception
10898    /// * Whatever the method threw
10899    ///
10900    ///
10901    /// # Panics
10902    /// if asserts feature is enabled and UB was detected
10903    ///
10904    /// # Safety
10905    ///
10906    /// Current thread must not be detached from JNI.
10907    ///
10908    /// Current thread must not be currently throwing an exception.
10909    ///
10910    /// Current thread does not hold a critical reference.
10911    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10912    ///
10913    /// `obj` must a valid and not already garbage collected.
10914    /// `methodID` must be valid, non-static and actually be a method of `obj`, return char and have 3 parameter
10915    /// The parameter types must exactly match the java method parameters.
10916    ///
10917    pub unsafe fn CallCharMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jchar {
10918        unsafe {
10919            #[cfg(feature = "asserts")]
10920            {
10921                self.check_not_critical("CallCharMethod");
10922                self.check_no_exception("CallCharMethod");
10923                self.check_return_type_object("CallCharMethod", obj, methodID, "char");
10924                self.check_parameter_types_object("CallCharMethod", obj, methodID, arg1, 0, 3);
10925                self.check_parameter_types_object("CallCharMethod", obj, methodID, arg2, 1, 3);
10926                self.check_parameter_types_object("CallCharMethod", obj, methodID, arg3, 2, 3);
10927            }
10928            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jchar>(43)(self.vtable, obj, methodID, arg1, arg2, arg3)
10929        }
10930    }
10931
10932    ///
10933    /// Calls a non-static java method that returns a short
10934    ///
10935    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10936    ///
10937    ///
10938    /// # Arguments
10939    /// * `obj` - which object the method should be called on
10940    ///     * must be valid
10941    ///     * must not be null
10942    ///     * must not be already garbage collected
10943    ///
10944    /// * `methodID` - method id of the method
10945    ///     * must not be null
10946    ///     * must be valid
10947    ///     * must not be a static
10948    ///     * must actually be a method of `obj`
10949    ///
10950    /// * `args` - argument pointer
10951    ///     * can be null if the method has no arguments
10952    ///     * must not be null otherwise and point to the exact number of arguments the method expects
10953    ///
10954    /// # Returns
10955    /// Whatever the method returned or 0 if it threw
10956    ///
10957    /// # Throws Java Exception
10958    /// * Whatever the method threw
10959    ///
10960    ///
10961    /// # Panics
10962    /// if asserts feature is enabled and UB was detected
10963    ///
10964    /// # Safety
10965    ///
10966    /// Current thread must not be detached from JNI.
10967    ///
10968    /// Current thread must not be currently throwing an exception.
10969    ///
10970    /// Current thread does not hold a critical reference.
10971    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10972    ///
10973    /// `obj` must a valid and not already garbage collected.
10974    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a short
10975    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
10976    /// `args` union must contain types that match the java methods parameters.
10977    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
10978    ///
10979    pub unsafe fn CallShortMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) -> jshort {
10980        unsafe {
10981            #[cfg(feature = "asserts")]
10982            {
10983                self.check_not_critical("CallShortMethodA");
10984                self.check_no_exception("CallShortMethodA");
10985                self.check_return_type_object("CallShortMethodA", obj, methodID, "short");
10986            }
10987            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jshort>(48)(self.vtable, obj, methodID, args)
10988        }
10989    }
10990
10991    ///
10992    /// Calls a non-static java method that has 0 arguments and returns short
10993    ///
10994    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10995    ///
10996    ///
10997    /// # Arguments
10998    /// * `obj` - which object the method should be called on
10999    ///     * must be valid
11000    ///     * must not be null
11001    ///     * must not be already garbage collected
11002    ///
11003    /// * `methodID` - method id of the method
11004    ///     * must not be null
11005    ///     * must be valid
11006    ///     * must not be a static
11007    ///     * must actually be a method of `obj`
11008    ///     * must refer to a method with 0 arguments
11009    ///
11010    /// # Returns
11011    /// Whatever the method returned or 0 if it threw
11012    ///
11013    /// # Throws Java Exception
11014    /// * Whatever the method threw
11015    ///
11016    ///
11017    /// # Panics
11018    /// if asserts feature is enabled and UB was detected
11019    ///
11020    /// # Safety
11021    ///
11022    /// Current thread must not be detached from JNI.
11023    ///
11024    /// Current thread must not be currently throwing an exception.
11025    ///
11026    /// Current thread does not hold a critical reference.
11027    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11028    ///
11029    /// `obj` must a valid and not already garbage collected.
11030    /// `methodID` must be valid, non-static and actually be a method of `obj`, return short and have no parameters
11031    ///
11032    pub unsafe fn CallShortMethod0(&self, obj: jobject, methodID: jmethodID) -> jshort {
11033        unsafe {
11034            #[cfg(feature = "asserts")]
11035            {
11036                self.check_not_critical("CallShortMethod");
11037                self.check_no_exception("CallShortMethod");
11038                self.check_return_type_object("CallShortMethod", obj, methodID, "short");
11039            }
11040            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jshort>(46)(self.vtable, obj, methodID)
11041        }
11042    }
11043
11044    ///
11045    /// Calls a non-static java method that has 1 arguments and returns short
11046    ///
11047    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11048    ///
11049    ///
11050    /// # Arguments
11051    /// * `obj` - which object the method should be called on
11052    ///     * must be valid
11053    ///     * must not be null
11054    ///     * must not be already garbage collected
11055    ///
11056    /// * `methodID` - method id of the method
11057    ///     * must not be null
11058    ///     * must be valid
11059    ///     * must not be a static
11060    ///     * must actually be a method of `obj`
11061    ///     * must refer to a method with 1 arguments
11062    ///
11063    /// # Returns
11064    /// Whatever the method returned or 0 if it threw
11065    ///
11066    /// # Throws Java Exception
11067    /// * Whatever the method threw
11068    ///
11069    ///
11070    /// # Panics
11071    /// if asserts feature is enabled and UB was detected
11072    ///
11073    /// # Safety
11074    ///
11075    /// Current thread must not be detached from JNI.
11076    ///
11077    /// Current thread must not be currently throwing an exception.
11078    ///
11079    /// Current thread does not hold a critical reference.
11080    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11081    ///
11082    /// `obj` must a valid and not already garbage collected.
11083    /// `methodID` must be valid, non-static and actually be a method of `obj`, return short and have 1 parameter
11084    /// The parameter types must exactly match the java method parameters.
11085    ///
11086    pub unsafe fn CallShortMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) -> jshort {
11087        unsafe {
11088            #[cfg(feature = "asserts")]
11089            {
11090                self.check_not_critical("CallShortMethod");
11091                self.check_no_exception("CallShortMethod");
11092                self.check_return_type_object("CallShortMethod", obj, methodID, "short");
11093                self.check_parameter_types_object("CallShortMethod", obj, methodID, arg1, 0, 1);
11094            }
11095            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jshort>(46)(self.vtable, obj, methodID, arg1)
11096        }
11097    }
11098
11099    ///
11100    /// Calls a non-static java method that has 2 arguments and returns short
11101    ///
11102    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11103    ///
11104    ///
11105    /// # Arguments
11106    /// * `obj` - which object the method should be called on
11107    ///     * must be valid
11108    ///     * must not be null
11109    ///     * must not be already garbage collected
11110    ///
11111    /// * `methodID` - method id of the method
11112    ///     * must not be null
11113    ///     * must be valid
11114    ///     * must not be a static
11115    ///     * must actually be a method of `obj`
11116    ///     * must refer to a method with 2 arguments
11117    ///
11118    /// # Returns
11119    /// Whatever the method returned or 0 if it threw
11120    ///
11121    /// # Throws Java Exception
11122    /// * Whatever the method threw
11123    ///
11124    ///
11125    /// # Panics
11126    /// if asserts feature is enabled and UB was detected
11127    ///
11128    /// # Safety
11129    ///
11130    /// Current thread must not be detached from JNI.
11131    ///
11132    /// Current thread must not be currently throwing an exception.
11133    ///
11134    /// Current thread does not hold a critical reference.
11135    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11136    ///
11137    /// `obj` must a valid and not already garbage collected.
11138    /// `methodID` must be valid, non-static and actually be a method of `obj`, return short and have 2 parameter
11139    /// The parameter types must exactly match the java method parameters.
11140    ///
11141    pub unsafe fn CallShortMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) -> jshort {
11142        unsafe {
11143            #[cfg(feature = "asserts")]
11144            {
11145                self.check_not_critical("CallShortMethod");
11146                self.check_no_exception("CallShortMethod");
11147                self.check_return_type_object("CallShortMethod", obj, methodID, "short");
11148                self.check_parameter_types_object("CallShortMethod", obj, methodID, arg1, 0, 2);
11149                self.check_parameter_types_object("CallShortMethod", obj, methodID, arg2, 1, 2);
11150            }
11151            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jshort>(46)(self.vtable, obj, methodID, arg1, arg2)
11152        }
11153    }
11154
11155    ///
11156    /// Calls a non-static java method that has 3 arguments and returns short
11157    ///
11158    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11159    ///
11160    ///
11161    /// # Arguments
11162    /// * `obj` - which object the method should be called on
11163    ///     * must be valid
11164    ///     * must not be null
11165    ///     * must not be already garbage collected
11166    ///
11167    /// * `methodID` - method id of the method
11168    ///     * must not be null
11169    ///     * must be valid
11170    ///     * must not be a static
11171    ///     * must actually be a method of `obj`
11172    ///     * must refer to a method with 3 arguments
11173    ///
11174    /// # Returns
11175    /// Whatever the method returned or 0 if it threw
11176    ///
11177    /// # Throws Java Exception
11178    /// * Whatever the method threw
11179    ///
11180    ///
11181    /// # Panics
11182    /// if asserts feature is enabled and UB was detected
11183    ///
11184    /// # Safety
11185    ///
11186    /// Current thread must not be detached from JNI.
11187    ///
11188    /// Current thread must not be currently throwing an exception.
11189    ///
11190    /// Current thread does not hold a critical reference.
11191    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11192    ///
11193    /// `obj` must a valid and not already garbage collected.
11194    /// `methodID` must be valid, non-static and actually be a method of `obj`, return short and have 3 parameter
11195    /// The parameter types must exactly match the java method parameters.
11196    ///
11197    pub unsafe fn CallShortMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jshort {
11198        unsafe {
11199            #[cfg(feature = "asserts")]
11200            {
11201                self.check_not_critical("CallShortMethod");
11202                self.check_no_exception("CallShortMethod");
11203                self.check_return_type_object("CallShortMethod", obj, methodID, "short");
11204                self.check_parameter_types_object("CallShortMethod", obj, methodID, arg1, 0, 3);
11205                self.check_parameter_types_object("CallShortMethod", obj, methodID, arg2, 1, 3);
11206                self.check_parameter_types_object("CallShortMethod", obj, methodID, arg3, 2, 3);
11207            }
11208            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jshort>(46)(self.vtable, obj, methodID, arg1, arg2, arg3)
11209        }
11210    }
11211
11212    ///
11213    /// Calls a non-static java method that returns a int
11214    ///
11215    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11216    ///
11217    ///
11218    /// # Arguments
11219    /// * `obj` - which object the method should be called on
11220    ///     * must be valid
11221    ///     * must not be null
11222    ///     * must not be already garbage collected
11223    ///
11224    /// * `methodID` - method id of the method
11225    ///     * must not be null
11226    ///     * must be valid
11227    ///     * must not be a static
11228    ///     * must actually be a method of `obj`
11229    ///
11230    /// * `args` - argument pointer
11231    ///     * can be null if the method has no arguments
11232    ///     * must not be null otherwise and point to the exact number of arguments the method expects
11233    ///
11234    /// # Returns
11235    /// Whatever the method returned or 0 if it threw
11236    ///
11237    /// # Throws Java Exception
11238    /// * Whatever the method threw
11239    ///
11240    ///
11241    /// # Panics
11242    /// if asserts feature is enabled and UB was detected
11243    ///
11244    /// # Safety
11245    ///
11246    /// Current thread must not be detached from JNI.
11247    ///
11248    /// Current thread must not be currently throwing an exception.
11249    ///
11250    /// Current thread does not hold a critical reference.
11251    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11252    ///
11253    /// `obj` must a valid and not already garbage collected.
11254    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a int
11255    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
11256    /// `args` union must contain types that match the java methods parameters.
11257    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
11258    ///
11259    pub unsafe fn CallIntMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) -> jint {
11260        unsafe {
11261            #[cfg(feature = "asserts")]
11262            {
11263                self.check_not_critical("CallIntMethodA");
11264                self.check_no_exception("CallIntMethodA");
11265                self.check_return_type_object("CallIntMethodA", obj, methodID, "int");
11266            }
11267            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jint>(51)(self.vtable, obj, methodID, args)
11268        }
11269    }
11270
11271    ///
11272    /// Calls a non-static java method that has 0 arguments and returns int
11273    ///
11274    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11275    ///
11276    ///
11277    /// # Arguments
11278    /// * `obj` - which object the method should be called on
11279    ///     * must be valid
11280    ///     * must not be null
11281    ///     * must not be already garbage collected
11282    ///
11283    /// * `methodID` - method id of the method
11284    ///     * must not be null
11285    ///     * must be valid
11286    ///     * must not be a static
11287    ///     * must actually be a method of `obj`
11288    ///     * must refer to a method with 0 arguments
11289    ///
11290    /// # Returns
11291    /// Whatever the method returned or 0 if it threw
11292    ///
11293    /// # Throws Java Exception
11294    /// * Whatever the method threw
11295    ///
11296    ///
11297    /// # Panics
11298    /// if asserts feature is enabled and UB was detected
11299    ///
11300    /// # Safety
11301    ///
11302    /// Current thread must not be detached from JNI.
11303    ///
11304    /// Current thread must not be currently throwing an exception.
11305    ///
11306    /// Current thread does not hold a critical reference.
11307    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11308    ///
11309    /// `obj` must a valid and not already garbage collected.
11310    /// `methodID` must be valid, non-static and actually be a method of `obj`, return int and have no parameters
11311    ///
11312    pub unsafe fn CallIntMethod0(&self, obj: jobject, methodID: jmethodID) -> jint {
11313        unsafe {
11314            #[cfg(feature = "asserts")]
11315            {
11316                self.check_not_critical("CallIntMethod");
11317                self.check_no_exception("CallIntMethod");
11318                self.check_return_type_object("CallIntMethod", obj, methodID, "int");
11319            }
11320            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jint>(49)(self.vtable, obj, methodID)
11321        }
11322    }
11323
11324    ///
11325    /// Calls a non-static java method that has 1 arguments and returns int
11326    ///
11327    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11328    ///
11329    ///
11330    /// # Arguments
11331    /// * `obj` - which object the method should be called on
11332    ///     * must be valid
11333    ///     * must not be null
11334    ///     * must not be already garbage collected
11335    ///
11336    /// * `methodID` - method id of the method
11337    ///     * must not be null
11338    ///     * must be valid
11339    ///     * must not be a static
11340    ///     * must actually be a method of `obj`
11341    ///     * must refer to a method with 1 arguments
11342    ///
11343    /// # Returns
11344    /// Whatever the method returned or 0 if it threw
11345    ///
11346    /// # Throws Java Exception
11347    /// * Whatever the method threw
11348    ///
11349    ///
11350    /// # Panics
11351    /// if asserts feature is enabled and UB was detected
11352    ///
11353    /// # Safety
11354    ///
11355    /// Current thread must not be detached from JNI.
11356    ///
11357    /// Current thread must not be currently throwing an exception.
11358    ///
11359    /// Current thread does not hold a critical reference.
11360    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11361    ///
11362    /// `obj` must a valid and not already garbage collected.
11363    /// `methodID` must be valid, non-static and actually be a method of `obj`, return int and have 1 parameter
11364    /// The parameter types must exactly match the java method parameters.
11365    ///
11366    pub unsafe fn CallIntMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) -> jint {
11367        unsafe {
11368            #[cfg(feature = "asserts")]
11369            {
11370                self.check_not_critical("CallIntMethod");
11371                self.check_no_exception("CallIntMethod");
11372                self.check_return_type_object("CallIntMethod", obj, methodID, "int");
11373                self.check_parameter_types_object("CallIntMethod", obj, methodID, arg1, 0, 1);
11374            }
11375            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jint>(49)(self.vtable, obj, methodID, arg1)
11376        }
11377    }
11378
11379    ///
11380    /// Calls a non-static java method that has 2 arguments and returns int
11381    ///
11382    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11383    ///
11384    ///
11385    /// # Arguments
11386    /// * `obj` - which object the method should be called on
11387    ///     * must be valid
11388    ///     * must not be null
11389    ///     * must not be already garbage collected
11390    ///
11391    /// * `methodID` - method id of the method
11392    ///     * must not be null
11393    ///     * must be valid
11394    ///     * must not be a static
11395    ///     * must actually be a method of `obj`
11396    ///     * must refer to a method with 2 arguments
11397    ///
11398    /// # Returns
11399    /// Whatever the method returned or 0 if it threw
11400    ///
11401    /// # Throws Java Exception
11402    /// * Whatever the method threw
11403    ///
11404    ///
11405    /// # Panics
11406    /// if asserts feature is enabled and UB was detected
11407    ///
11408    /// # Safety
11409    ///
11410    /// Current thread must not be detached from JNI.
11411    ///
11412    /// Current thread must not be currently throwing an exception.
11413    ///
11414    /// Current thread does not hold a critical reference.
11415    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11416    ///
11417    /// `obj` must a valid and not already garbage collected.
11418    /// `methodID` must be valid, non-static and actually be a method of `obj`, return int and have 2 parameter
11419    /// The parameter types must exactly match the java method parameters.
11420    ///
11421    pub unsafe fn CallIntMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) -> jint {
11422        unsafe {
11423            #[cfg(feature = "asserts")]
11424            {
11425                self.check_not_critical("CallIntMethod");
11426                self.check_no_exception("CallIntMethod");
11427                self.check_return_type_object("CallIntMethod", obj, methodID, "int");
11428                self.check_parameter_types_object("CallIntMethod", obj, methodID, arg1, 0, 2);
11429                self.check_parameter_types_object("CallIntMethod", obj, methodID, arg2, 1, 2);
11430            }
11431            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jint>(49)(self.vtable, obj, methodID, arg1, arg2)
11432        }
11433    }
11434
11435    ///
11436    /// Calls a non-static java method that has 3 arguments and returns int
11437    ///
11438    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11439    ///
11440    ///
11441    /// # Arguments
11442    /// * `obj` - which object the method should be called on
11443    ///     * must be valid
11444    ///     * must not be null
11445    ///     * must not be already garbage collected
11446    /// * `methodID` - method id of the method
11447    ///     * must not be null
11448    ///     * must be valid
11449    ///     * must not be a static
11450    ///     * must actually be a method of `obj`
11451    ///     * must refer to a method with 3 arguments
11452    ///
11453    /// # Returns
11454    /// Whatever the method returned or 0 if it threw
11455    ///
11456    /// # Throws Java Exception
11457    /// * Whatever the method threw
11458    ///
11459    ///
11460    /// # Panics
11461    /// if asserts feature is enabled and UB was detected
11462    ///
11463    /// # Safety
11464    ///
11465    /// Current thread must not be detached from JNI.
11466    ///
11467    /// Current thread must not be currently throwing an exception.
11468    ///
11469    /// Current thread does not hold a critical reference.
11470    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11471    ///
11472    /// `obj` must a valid and not already garbage collected.
11473    /// `methodID` must be valid, non-static and actually be a method of `obj`, return int and have 3 parameter
11474    /// The parameter types must exactly match the java method parameters.
11475    ///
11476    pub unsafe fn CallIntMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jint {
11477        unsafe {
11478            #[cfg(feature = "asserts")]
11479            {
11480                self.check_not_critical("CallIntMethod");
11481                self.check_no_exception("CallIntMethod");
11482                self.check_return_type_object("CallIntMethod", obj, methodID, "int");
11483                self.check_parameter_types_object("CallIntMethod", obj, methodID, arg1, 0, 3);
11484                self.check_parameter_types_object("CallIntMethod", obj, methodID, arg2, 1, 3);
11485                self.check_parameter_types_object("CallIntMethod", obj, methodID, arg3, 2, 3);
11486            }
11487            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jint>(49)(self.vtable, obj, methodID, arg1, arg2, arg3)
11488        }
11489    }
11490
11491    ///
11492    /// Calls a non-static java method that returns a long
11493    ///
11494    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11495    ///
11496    ///
11497    /// # Arguments
11498    /// * `obj` - which object the method should be called on
11499    ///     * must be valid
11500    ///     * must not be null
11501    ///     * must not be already garbage collected
11502    /// * `methodID` - method id of the method
11503    ///     * must not be null
11504    ///     * must be valid
11505    ///     * must not be a static
11506    ///     * must actually be a method of `obj`
11507    /// * `args` - argument pointer
11508    ///     * can be null if the method has no arguments
11509    ///     * must not be null otherwise and point to the exact number of arguments the method expects
11510    ///
11511    /// # Returns
11512    /// Whatever the method returned or 0 if it threw
11513    ///
11514    /// # Throws Java Exception
11515    /// * Whatever the method threw
11516    ///
11517    ///
11518    /// # Panics
11519    /// if asserts feature is enabled and UB was detected
11520    ///
11521    /// # Safety
11522    ///
11523    /// Current thread must not be detached from JNI.
11524    ///
11525    /// Current thread must not be currently throwing an exception.
11526    ///
11527    /// Current thread does not hold a critical reference.
11528    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11529    ///
11530    /// `obj` must a valid and not already garbage collected.
11531    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a long
11532    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
11533    /// `args` union must contain types that match the java methods parameters.
11534    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
11535    ///
11536    pub unsafe fn CallLongMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) -> jlong {
11537        unsafe {
11538            #[cfg(feature = "asserts")]
11539            {
11540                self.check_not_critical("CallLongMethodA");
11541                self.check_no_exception("CallLongMethodA");
11542                self.check_return_type_object("CallLongMethodA", obj, methodID, "long");
11543            }
11544            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jlong>(54)(self.vtable, obj, methodID, args)
11545        }
11546    }
11547
11548    ///
11549    /// Calls a non-static java method that has 0 arguments and returns long
11550    ///
11551    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11552    ///
11553    ///
11554    /// # Arguments
11555    /// * `obj` - which object the method should be called on
11556    ///     * must be valid
11557    ///     * must not be null
11558    ///     * must not be already garbage collected
11559    /// * `methodID` - method id of the method
11560    ///     * must not be null
11561    ///     * must be valid
11562    ///     * must not be a static
11563    ///     * must actually be a method of `obj`
11564    ///     * must refer to a method with 0 arguments
11565    ///
11566    /// # Returns
11567    /// Whatever the method returned or 0 if it threw
11568    ///
11569    /// # Throws Java Exception
11570    /// * Whatever the method threw
11571    ///
11572    ///
11573    /// # Panics
11574    /// if asserts feature is enabled and UB was detected
11575    ///
11576    /// # Safety
11577    ///
11578    /// Current thread must not be detached from JNI.
11579    ///
11580    /// Current thread must not be currently throwing an exception.
11581    ///
11582    /// Current thread does not hold a critical reference.
11583    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11584    ///
11585    /// `obj` must a valid and not already garbage collected.
11586    /// `methodID` must be valid, non-static and actually be a method of `obj`, return long and have no parameters
11587    ///
11588    pub unsafe fn CallLongMethod0(&self, obj: jobject, methodID: jmethodID) -> jlong {
11589        unsafe {
11590            #[cfg(feature = "asserts")]
11591            {
11592                self.check_not_critical("CallLongMethod");
11593                self.check_no_exception("CallLongMethod");
11594                self.check_return_type_object("CallLongMethod", obj, methodID, "long");
11595            }
11596            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jlong>(52)(self.vtable, obj, methodID)
11597        }
11598    }
11599
11600    ///
11601    /// Calls a non-static java method that has 1 arguments and returns long
11602    ///
11603    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11604    ///
11605    ///
11606    /// # Arguments
11607    /// * `obj` - which object the method should be called on
11608    ///     * must be valid
11609    ///     * must not be null
11610    ///     * must not be already garbage collected
11611    /// * `methodID` - method id of the method
11612    ///     * must not be null
11613    ///     * must be valid
11614    ///     * must not be a static
11615    ///     * must actually be a method of `obj`
11616    ///     * must refer to a method with 1 arguments
11617    ///
11618    /// # Returns
11619    /// Whatever the method returned or 0 if it threw
11620    ///
11621    /// # Throws Java Exception
11622    /// * Whatever the method threw
11623    ///
11624    ///
11625    /// # Panics
11626    /// if asserts feature is enabled and UB was detected
11627    ///
11628    /// # Safety
11629    ///
11630    /// Current thread must not be detached from JNI.
11631    ///
11632    /// Current thread must not be currently throwing an exception.
11633    ///
11634    /// Current thread does not hold a critical reference.
11635    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11636    ///
11637    /// `obj` must a valid and not already garbage collected.
11638    /// `methodID` must be valid, non-static and actually be a method of `obj`, return long and have 1 parameter
11639    /// The parameter types must exactly match the java method parameters.
11640    ///
11641    pub unsafe fn CallLongMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) -> jlong {
11642        unsafe {
11643            #[cfg(feature = "asserts")]
11644            {
11645                self.check_not_critical("CallLongMethod");
11646                self.check_no_exception("CallLongMethod");
11647                self.check_return_type_object("CallLongMethod", obj, methodID, "long");
11648                self.check_parameter_types_object("CallLongMethod", obj, methodID, arg1, 0, 1);
11649            }
11650            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jlong>(52)(self.vtable, obj, methodID, arg1)
11651        }
11652    }
11653
11654    ///
11655    /// Calls a non-static java method that has 2 arguments and returns long
11656    ///
11657    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11658    ///
11659    ///
11660    /// # Arguments
11661    /// * `obj` - which object the method should be called on
11662    ///     * must be valid
11663    ///     * must not be null
11664    ///     * must not be already garbage collected
11665    /// * `methodID` - method id of the method
11666    ///     * must not be null
11667    ///     * must be valid
11668    ///     * must not be a static
11669    ///     * must actually be a method of `obj`
11670    ///     * must refer to a method with 2 arguments
11671    ///
11672    /// # Returns
11673    /// Whatever the method returned or 0 if it threw
11674    ///
11675    /// # Throws Java Exception
11676    /// * Whatever the method threw
11677    ///
11678    ///
11679    /// # Panics
11680    /// if asserts feature is enabled and UB was detected
11681    ///
11682    /// # Safety
11683    ///
11684    /// Current thread must not be detached from JNI.
11685    ///
11686    /// Current thread must not be currently throwing an exception.
11687    ///
11688    /// Current thread does not hold a critical reference.
11689    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11690    ///
11691    /// `obj` must a valid and not already garbage collected.
11692    /// `methodID` must be valid, non-static and actually be a method of `obj`, return long and have 2 parameter
11693    /// The parameter types must exactly match the java method parameters.
11694    ///
11695    pub unsafe fn CallLongMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) -> jlong {
11696        unsafe {
11697            #[cfg(feature = "asserts")]
11698            {
11699                self.check_not_critical("CallLongMethod");
11700                self.check_no_exception("CallLongMethod");
11701                self.check_return_type_object("CallLongMethod", obj, methodID, "long");
11702                self.check_parameter_types_object("CallLongMethod", obj, methodID, arg1, 0, 2);
11703                self.check_parameter_types_object("CallLongMethod", obj, methodID, arg2, 1, 2);
11704            }
11705            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jlong>(52)(self.vtable, obj, methodID, arg1, arg2)
11706        }
11707    }
11708
11709    ///
11710    /// Calls a non-static java method that has 3 arguments and returns long
11711    ///
11712    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11713    ///
11714    ///
11715    /// # Arguments
11716    /// * `obj` - which object the method should be called on
11717    ///     * must be valid
11718    ///     * must not be null
11719    ///     * must not be already garbage collected
11720    /// * `methodID` - method id of the method
11721    ///     * must not be null
11722    ///     * must be valid
11723    ///     * must not be a static
11724    ///     * must actually be a method of `obj`
11725    ///     * must refer to a method with 3 arguments
11726    ///
11727    /// # Returns
11728    /// Whatever the method returned or 0 if it threw
11729    ///
11730    /// # Throws Java Exception
11731    /// * Whatever the method threw
11732    ///
11733    ///
11734    /// # Panics
11735    /// if asserts feature is enabled and UB was detected
11736    ///
11737    /// # Safety
11738    ///
11739    /// Current thread must not be detached from JNI.
11740    ///
11741    /// Current thread must not be currently throwing an exception.
11742    ///
11743    /// Current thread does not hold a critical reference.
11744    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11745    ///
11746    /// `obj` must a valid and not already garbage collected.
11747    /// `methodID` must be valid, non-static and actually be a method of `obj`, return long and have 3 parameter
11748    /// The parameter types must exactly match the java method parameters.
11749    ///
11750    pub unsafe fn CallLongMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jlong {
11751        unsafe {
11752            #[cfg(feature = "asserts")]
11753            {
11754                self.check_not_critical("CallLongMethod");
11755                self.check_no_exception("CallLongMethod");
11756                self.check_return_type_object("CallLongMethod", obj, methodID, "long");
11757                self.check_parameter_types_object("CallLongMethod", obj, methodID, arg1, 0, 3);
11758                self.check_parameter_types_object("CallLongMethod", obj, methodID, arg2, 1, 3);
11759                self.check_parameter_types_object("CallLongMethod", obj, methodID, arg3, 2, 3);
11760            }
11761            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jlong>(52)(self.vtable, obj, methodID, arg1, arg2, arg3)
11762        }
11763    }
11764
11765    ///
11766    /// Calls a non-static java method that returns a float
11767    ///
11768    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11769    ///
11770    ///
11771    /// # Arguments
11772    /// * `obj` - which object the method should be called on
11773    ///     * must be valid
11774    ///     * must not be null
11775    ///     * must not be already garbage collected
11776    /// * `methodID` - method id of the method
11777    ///     * must not be null
11778    ///     * must be valid
11779    ///     * must not be a static
11780    ///     * must actually be a method of `obj`
11781    /// * `args` - argument pointer
11782    ///     * can be null if the method has no arguments
11783    ///     * must not be null otherwise and point to the exact number of arguments the method expects
11784    ///
11785    /// # Returns
11786    /// Whatever the method returned or 0 if it threw
11787    ///
11788    /// # Throws Java Exception
11789    /// * Whatever the method threw
11790    ///
11791    ///
11792    /// # Panics
11793    /// if asserts feature is enabled and UB was detected
11794    ///
11795    /// # Safety
11796    ///
11797    /// Current thread must not be detached from JNI.
11798    ///
11799    /// Current thread must not be currently throwing an exception.
11800    ///
11801    /// Current thread does not hold a critical reference.
11802    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11803    ///
11804    /// `obj` must a valid and not already garbage collected.
11805    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a float
11806    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
11807    /// `args` union must contain types that match the java methods parameters.
11808    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
11809    ///
11810    pub unsafe fn CallFloatMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) -> jfloat {
11811        unsafe {
11812            #[cfg(feature = "asserts")]
11813            {
11814                self.check_not_critical("CallFloatMethodA");
11815                self.check_no_exception("CallFloatMethodA");
11816                self.check_return_type_object("CallFloatMethodA", obj, methodID, "float");
11817            }
11818            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jfloat>(57)(self.vtable, obj, methodID, args)
11819        }
11820    }
11821
11822    ///
11823    /// Calls a non-static java method that has 0 arguments and returns float
11824    ///
11825    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11826    ///
11827    ///
11828    /// # Arguments
11829    /// * `obj` - which object the method should be called on
11830    ///     * must be valid
11831    ///     * must not be null
11832    ///     * must not be already garbage collected
11833    /// * `methodID` - method id of the method
11834    ///     * must not be null
11835    ///     * must be valid
11836    ///     * must not be a static
11837    ///     * must actually be a method of `obj`
11838    ///     * must refer to a method with 0 arguments
11839    ///
11840    /// # Returns
11841    /// Whatever the method returned or 0 if it threw
11842    ///
11843    /// # Throws Java Exception
11844    /// * Whatever the method threw
11845    ///
11846    ///
11847    /// # Panics
11848    /// if asserts feature is enabled and UB was detected
11849    ///
11850    /// # Safety
11851    ///
11852    /// Current thread must not be detached from JNI.
11853    ///
11854    /// Current thread must not be currently throwing an exception.
11855    ///
11856    /// Current thread does not hold a critical reference.
11857    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11858    ///
11859    /// `obj` must a valid and not already garbage collected.
11860    /// `methodID` must be valid, non-static and actually be a method of `obj`, return float and have no parameters
11861    ///
11862    pub unsafe fn CallFloatMethod0(&self, obj: jobject, methodID: jmethodID) -> jfloat {
11863        unsafe {
11864            #[cfg(feature = "asserts")]
11865            {
11866                self.check_not_critical("CallFloatMethod");
11867                self.check_no_exception("CallFloatMethod");
11868                self.check_return_type_object("CallFloatMethod", obj, methodID, "float");
11869            }
11870            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jfloat>(55)(self.vtable, obj, methodID)
11871        }
11872    }
11873
11874    ///
11875    /// Calls a non-static java method that has 1 arguments and returns float
11876    ///
11877    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11878    ///
11879    ///
11880    /// # Arguments
11881    /// * `obj` - which object the method should be called on
11882    ///     * must be valid
11883    ///     * must not be null
11884    ///     * must not be already garbage collected
11885    /// * `methodID` - method id of the method
11886    ///     * must not be null
11887    ///     * must be valid
11888    ///     * must not be a static
11889    ///     * must actually be a method of `obj`
11890    ///     * must refer to a method with 1 arguments
11891    ///
11892    /// # Returns
11893    /// Whatever the method returned or 0 if it threw
11894    ///
11895    /// # Throws Java Exception
11896    /// * Whatever the method threw
11897    ///
11898    ///
11899    /// # Panics
11900    /// if asserts feature is enabled and UB was detected
11901    ///
11902    /// # Safety
11903    ///
11904    /// Current thread must not be detached from JNI.
11905    ///
11906    /// Current thread must not be currently throwing an exception.
11907    ///
11908    /// Current thread does not hold a critical reference.
11909    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11910    ///
11911    /// `obj` must a valid and not already garbage collected.
11912    /// `methodID` must be valid, non-static and actually be a method of `obj`, return float and have 1 parameter
11913    /// The parameter types must exactly match the java method parameters.
11914    ///
11915    pub unsafe fn CallFloatMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) -> jfloat {
11916        unsafe {
11917            #[cfg(feature = "asserts")]
11918            {
11919                self.check_not_critical("CallFloatMethod");
11920                self.check_no_exception("CallFloatMethod");
11921                self.check_return_type_object("CallFloatMethod", obj, methodID, "float");
11922                self.check_parameter_types_object("CallFloatMethod", obj, methodID, arg1, 0, 1);
11923            }
11924            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jfloat>(55)(self.vtable, obj, methodID, arg1)
11925        }
11926    }
11927
11928    ///
11929    /// Calls a non-static java method that has 2 arguments and returns float
11930    ///
11931    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11932    ///
11933    ///
11934    /// # Arguments
11935    /// * `obj` - which object the method should be called on
11936    ///     * must be valid
11937    ///     * must not be null
11938    ///     * must not be already garbage collected
11939    /// * `methodID` - method id of the method
11940    ///     * must not be null
11941    ///     * must be valid
11942    ///     * must not be a static
11943    ///     * must actually be a method of `obj`
11944    ///     * must refer to a method with 2 arguments
11945    ///
11946    /// # Returns
11947    /// Whatever the method returned or 0 if it threw
11948    ///
11949    /// # Throws Java Exception
11950    /// * Whatever the method threw
11951    ///
11952    ///
11953    /// # Panics
11954    /// if asserts feature is enabled and UB was detected
11955    ///
11956    /// # Safety
11957    ///
11958    /// Current thread must not be detached from JNI.
11959    ///
11960    /// Current thread must not be currently throwing an exception.
11961    ///
11962    /// Current thread does not hold a critical reference.
11963    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11964    ///
11965    /// `obj` must a valid and not already garbage collected.
11966    /// `methodID` must be valid, non-static and actually be a method of `obj`, return float and have 2 parameter
11967    /// The parameter types must exactly match the java method parameters.
11968    ///
11969    pub unsafe fn CallFloatMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) -> jfloat {
11970        unsafe {
11971            #[cfg(feature = "asserts")]
11972            {
11973                self.check_not_critical("CallFloatMethod");
11974                self.check_no_exception("CallFloatMethod");
11975                self.check_return_type_object("CallFloatMethod", obj, methodID, "float");
11976                self.check_parameter_types_object("CallFloatMethod", obj, methodID, arg1, 0, 2);
11977                self.check_parameter_types_object("CallFloatMethod", obj, methodID, arg2, 1, 2);
11978            }
11979            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jfloat>(55)(self.vtable, obj, methodID, arg1, arg2)
11980        }
11981    }
11982
11983    ///
11984    /// Calls a non-static java method that has 3 arguments and returns float
11985    ///
11986    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11987    ///
11988    ///
11989    /// # Arguments
11990    /// * `obj` - which object the method should be called on
11991    ///     * must be valid
11992    ///     * must not be null
11993    ///     * must not be already garbage collected
11994    /// * `methodID` - method id of the method
11995    ///     * must not be null
11996    ///     * must be valid
11997    ///     * must not be a static
11998    ///     * must actually be a method of `obj`
11999    ///     * must refer to a method with 3 arguments
12000    ///
12001    /// # Returns
12002    /// Whatever the method returned or 0 if it threw
12003    ///
12004    /// # Throws Java Exception
12005    /// * Whatever the method threw
12006    ///
12007    ///
12008    /// # Panics
12009    /// if asserts feature is enabled and UB was detected
12010    ///
12011    /// # Safety
12012    ///
12013    /// Current thread must not be detached from JNI.
12014    ///
12015    /// Current thread must not be currently throwing an exception.
12016    ///
12017    /// Current thread does not hold a critical reference.
12018    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12019    ///
12020    /// `obj` must a valid and not already garbage collected.
12021    /// `methodID` must be valid, non-static and actually be a method of `obj`, return float and have 3 parameter
12022    /// The parameter types must exactly match the java method parameters.
12023    ///
12024    pub unsafe fn CallFloatMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jfloat {
12025        unsafe {
12026            #[cfg(feature = "asserts")]
12027            {
12028                self.check_not_critical("CallFloatMethod");
12029                self.check_no_exception("CallFloatMethod");
12030                self.check_return_type_object("CallFloatMethod", obj, methodID, "float");
12031                self.check_parameter_types_object("CallFloatMethod", obj, methodID, arg1, 0, 3);
12032                self.check_parameter_types_object("CallFloatMethod", obj, methodID, arg2, 1, 3);
12033                self.check_parameter_types_object("CallFloatMethod", obj, methodID, arg3, 2, 3);
12034            }
12035            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jfloat>(55)(self.vtable, obj, methodID, arg1, arg2, arg3)
12036        }
12037    }
12038
12039    ///
12040    /// Calls a non-static java method that returns a double
12041    ///
12042    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
12043    ///
12044    ///
12045    /// # Arguments
12046    /// * `obj` - which object the method should be called on
12047    ///     * must be valid
12048    ///     * must not be null
12049    ///     * must not be already garbage collected
12050    /// * `methodID` - method id of the method
12051    ///     * must not be null
12052    ///     * must be valid
12053    ///     * must not be a static
12054    ///     * must actually be a method of `obj`
12055    /// * `args` - argument pointer
12056    ///     * can be null if the method has no arguments
12057    ///     * must not be null otherwise and point to the exact number of arguments the method expects
12058    ///
12059    /// # Returns
12060    /// Whatever the method returned or 0 if it threw
12061    ///
12062    /// # Throws Java Exception
12063    /// * Whatever the method threw
12064    ///
12065    ///
12066    /// # Panics
12067    /// if asserts feature is enabled and UB was detected
12068    ///
12069    /// # Safety
12070    ///
12071    /// Current thread must not be detached from JNI.
12072    ///
12073    /// Current thread must not be currently throwing an exception.
12074    ///
12075    /// Current thread does not hold a critical reference.
12076    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12077    ///
12078    /// `obj` must a valid and not already garbage collected.
12079    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a double
12080    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
12081    /// `args` union must contain types that match the java methods parameters.
12082    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
12083    ///
12084    pub unsafe fn CallDoubleMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) -> jdouble {
12085        unsafe {
12086            #[cfg(feature = "asserts")]
12087            {
12088                self.check_not_critical("CallDoubleMethodA");
12089                self.check_no_exception("CallDoubleMethodA");
12090                self.check_return_type_object("CallDoubleMethodA", obj, methodID, "double");
12091            }
12092            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jdouble>(60)(self.vtable, obj, methodID, args)
12093        }
12094    }
12095
12096    ///
12097    /// Calls a non-static java method that has 0 arguments and returns double
12098    ///
12099    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
12100    ///
12101    ///
12102    /// # Arguments
12103    /// * `obj` - which object the method should be called on
12104    ///     * must be valid
12105    ///     * must not be null
12106    ///     * must not be already garbage collected
12107    /// * `methodID` - method id of the method
12108    ///     * must not be null
12109    ///     * must be valid
12110    ///     * must not be a static
12111    ///     * must actually be a method of `obj`
12112    ///     * must refer to a method with 0 arguments
12113    ///
12114    /// # Returns
12115    /// Whatever the method returned or 0 if it threw
12116    ///
12117    /// # Throws Java Exception
12118    /// * Whatever the method threw
12119    ///
12120    ///
12121    /// # Panics
12122    /// if asserts feature is enabled and UB was detected
12123    ///
12124    /// # Safety
12125    ///
12126    /// Current thread must not be detached from JNI.
12127    ///
12128    /// Current thread must not be currently throwing an exception.
12129    ///
12130    /// Current thread does not hold a critical reference.
12131    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12132    ///
12133    /// `obj` must a valid and not already garbage collected.
12134    /// `methodID` must be valid, non-static and actually be a method of `obj`, return double and have no parameters
12135    ///
12136    pub unsafe fn CallDoubleMethod0(&self, obj: jobject, methodID: jmethodID) -> jdouble {
12137        unsafe {
12138            #[cfg(feature = "asserts")]
12139            {
12140                self.check_not_critical("CallDoubleMethod");
12141                self.check_no_exception("CallDoubleMethod");
12142                self.check_return_type_object("CallDoubleMethod", obj, methodID, "double");
12143            }
12144            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jdouble>(58)(self.vtable, obj, methodID)
12145        }
12146    }
12147
12148    ///
12149    /// Calls a non-static java method that has 1 arguments and returns double
12150    ///
12151    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
12152    ///
12153    ///
12154    /// # Arguments
12155    /// * `obj` - which object the method should be called on
12156    ///     * must be valid
12157    ///     * must not be null
12158    ///     * must not be already garbage collected
12159    /// * `methodID` - method id of the method
12160    ///     * must not be null
12161    ///     * must be valid
12162    ///     * must not be a static
12163    ///     * must actually be a method of `obj`
12164    ///     * must refer to a method with 1 arguments
12165    ///
12166    /// # Returns
12167    /// Whatever the method returned or 0 if it threw
12168    ///
12169    /// # Throws Java Exception
12170    /// * Whatever the method threw
12171    ///
12172    ///
12173    /// # Panics
12174    /// if asserts feature is enabled and UB was detected
12175    ///
12176    /// # Safety
12177    ///
12178    /// Current thread must not be detached from JNI.
12179    ///
12180    /// Current thread must not be currently throwing an exception.
12181    ///
12182    /// Current thread does not hold a critical reference.
12183    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12184    ///
12185    /// `obj` must a valid and not already garbage collected.
12186    /// `methodID` must be valid, non-static and actually be a method of `obj`, return double and have 1 parameter
12187    /// The parameter types must exactly match the java method parameters.
12188    ///
12189    pub unsafe fn CallDoubleMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) -> jdouble {
12190        unsafe {
12191            #[cfg(feature = "asserts")]
12192            {
12193                self.check_not_critical("CallDoubleMethod");
12194                self.check_no_exception("CallDoubleMethod");
12195                self.check_return_type_object("CallDoubleMethod", obj, methodID, "double");
12196                self.check_parameter_types_object("CallDoubleMethod", obj, methodID, arg1, 0, 1);
12197            }
12198            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jdouble>(58)(self.vtable, obj, methodID, arg1)
12199        }
12200    }
12201
12202    ///
12203    /// Calls a non-static java method that has 2 arguments and returns double
12204    ///
12205    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
12206    ///
12207    ///
12208    /// # Arguments
12209    /// * `obj` - which object the method should be called on
12210    ///     * must be valid
12211    ///     * must not be null
12212    ///     * must not be already garbage collected
12213    /// * `methodID` - method id of the method
12214    ///     * must not be null
12215    ///     * must be valid
12216    ///     * must not be a static
12217    ///     * must actually be a method of `obj`
12218    ///     * must refer to a method with 2 arguments
12219    ///
12220    /// # Returns
12221    /// Whatever the method returned or 0 if it threw
12222    ///
12223    /// # Throws Java Exception
12224    /// * Whatever the method threw
12225    ///
12226    ///
12227    /// # Panics
12228    /// if asserts feature is enabled and UB was detected
12229    ///
12230    /// # Safety
12231    ///
12232    /// Current thread must not be detached from JNI.
12233    ///
12234    /// Current thread must not be currently throwing an exception.
12235    ///
12236    /// Current thread does not hold a critical reference.
12237    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12238    ///
12239    /// `obj` must a valid and not already garbage collected.
12240    /// `methodID` must be valid, non-static and actually be a method of `obj`, return double and have 2 parameter
12241    /// The parameter types must exactly match the java method parameters.
12242    ///
12243    pub unsafe fn CallDoubleMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) -> jdouble {
12244        unsafe {
12245            #[cfg(feature = "asserts")]
12246            {
12247                self.check_not_critical("CallDoubleMethod");
12248                self.check_no_exception("CallDoubleMethod");
12249                self.check_return_type_object("CallDoubleMethod", obj, methodID, "double");
12250                self.check_parameter_types_object("CallDoubleMethod", obj, methodID, arg1, 0, 2);
12251                self.check_parameter_types_object("CallDoubleMethod", obj, methodID, arg2, 1, 2);
12252            }
12253            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jdouble>(58)(self.vtable, obj, methodID, arg1, arg2)
12254        }
12255    }
12256
12257    ///
12258    /// Calls a non-static java method that has 3 arguments and returns double
12259    ///
12260    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
12261    ///
12262    ///
12263    /// # Arguments
12264    /// * `obj` - which object the method should be called on
12265    ///     * must be valid
12266    ///     * must not be null
12267    ///     * must not be already garbage collected
12268    /// * `methodID` - method id of the method
12269    ///     * must not be null
12270    ///     * must be valid
12271    ///     * must not be a static
12272    ///     * must actually be a method of `obj`
12273    ///     * must refer to a method with 3 arguments
12274    ///
12275    /// # Returns
12276    /// Whatever the method returned or 0 if it threw
12277    ///
12278    /// # Throws Java Exception
12279    /// * Whatever the method threw
12280    ///
12281    ///
12282    /// # Panics
12283    /// if asserts feature is enabled and UB was detected
12284    ///
12285    /// # Safety
12286    ///
12287    /// Current thread must not be detached from JNI.
12288    ///
12289    /// Current thread must not be currently throwing an exception.
12290    ///
12291    /// Current thread does not hold a critical reference.
12292    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12293    ///
12294    /// `obj` must a valid and not already garbage collected.
12295    /// `methodID` must be valid, non-static and actually be a method of `obj`, return double and have 3 parameter
12296    /// The parameter types must exactly match the java method parameters.
12297    ///
12298    pub unsafe fn CallDoubleMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jdouble {
12299        unsafe {
12300            #[cfg(feature = "asserts")]
12301            {
12302                self.check_not_critical("CallDoubleMethod");
12303                self.check_no_exception("CallDoubleMethod");
12304                self.check_return_type_object("CallDoubleMethod", obj, methodID, "double");
12305                self.check_parameter_types_object("CallDoubleMethod", obj, methodID, arg1, 0, 3);
12306                self.check_parameter_types_object("CallDoubleMethod", obj, methodID, arg2, 1, 3);
12307                self.check_parameter_types_object("CallDoubleMethod", obj, methodID, arg3, 2, 3);
12308            }
12309            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jdouble>(58)(self.vtable, obj, methodID, arg1, arg2, arg3)
12310        }
12311    }
12312
12313    ///
12314    /// Calls a non-static java method that returns void without using the objects vtable to look up the method.
12315    /// This means that should the object be a subclass of the class that the method is declared in
12316    /// then the base method that the methodID refers to is invoked instead of a potencially overwritten one.
12317    ///
12318    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12319    ///
12320    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12321    ///
12322    ///
12323    /// # Arguments
12324    /// * `obj` - which object the method should be called on
12325    ///     * must be valid
12326    ///     * must not be null
12327    ///     * must not be already garbage collected
12328    /// * `methodID` - method id of the method
12329    ///     * must not be null
12330    ///     * must be valid
12331    ///     * must not be a static
12332    ///     * must actually be a method of `obj`
12333    /// * `args` - argument pointer
12334    ///     * can be null if the method has no arguments
12335    ///     * must not be null otherwise and point to the exact number of arguments the method expects
12336    ///
12337    /// # Throws Java Exception
12338    /// * Whatever the method threw
12339    ///
12340    ///
12341    /// # Panics
12342    /// if asserts feature is enabled and UB was detected
12343    ///
12344    /// # Safety
12345    ///
12346    /// Current thread must not be detached from JNI.
12347    ///
12348    /// Current thread must not be currently throwing an exception.
12349    ///
12350    /// Current thread does not hold a critical reference.
12351    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12352    ///
12353    /// `obj` must a valid and not already garbage collected.
12354    /// `methodID` must be valid, non-static and actually be a method of `obj` and return void
12355    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
12356    /// `args` union must contain types that match the java methods parameters.
12357    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
12358    ///
12359    pub unsafe fn CallNonvirtualVoidMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) {
12360        unsafe {
12361            #[cfg(feature = "asserts")]
12362            {
12363                self.check_not_critical("CallNonvirtualVoidMethodA");
12364                self.check_no_exception("CallNonvirtualVoidMethodA");
12365                self.check_return_type_object("CallNonvirtualVoidMethodA", obj, methodID, "void");
12366                self.check_is_class("CallNonvirtualVoidMethodA", class);
12367            }
12368            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype)>(93)(self.vtable, obj, class, methodID, args);
12369        }
12370    }
12371
12372    ///
12373    /// Calls a non-static java method with 0 arguments that returns void without using the objects vtable to look up the method.
12374    /// This means that should the object be a subclass of the class that the method is declared in
12375    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12376    ///
12377    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12378    ///
12379    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12380    ///
12381    ///
12382    /// # Arguments
12383    /// * `obj` - which object the method should be called on
12384    ///     * must be valid
12385    ///     * must not be null
12386    ///     * must not be already garbage collected
12387    /// * `methodID` - method id of the method
12388    ///     * must not be null
12389    ///     * must be valid
12390    ///     * must not be a static
12391    ///     * must actually be a method of `obj`
12392    ///     * must refer to a method with 0 arguments
12393    ///
12394    /// # Throws Java Exception
12395    /// * Whatever the method threw
12396    ///
12397    ///
12398    /// # Panics
12399    /// if asserts feature is enabled and UB was detected
12400    ///
12401    /// # Safety
12402    ///
12403    /// Current thread must not be detached from JNI.
12404    ///
12405    /// Current thread must not be currently throwing an exception.
12406    ///
12407    /// Current thread does not hold a critical reference.
12408    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12409    ///
12410    /// `obj` must a valid and not already garbage collected.
12411    /// `methodID` must be valid, non-static and actually be a method of `obj`, return void and have no parameters
12412    ///
12413    pub unsafe fn CallNonvirtualVoidMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) {
12414        unsafe {
12415            #[cfg(feature = "asserts")]
12416            {
12417                self.check_not_critical("CallNonvirtualVoidMethod");
12418                self.check_no_exception("CallNonvirtualVoidMethod");
12419                self.check_return_type_object("CallNonvirtualVoidMethod", obj, methodID, "void");
12420                self.check_is_class("CallNonvirtualVoidMethod", class);
12421            }
12422            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID)>(91)(self.vtable, obj, class, methodID);
12423        }
12424    }
12425
12426    ///
12427    /// Calls a non-static java method with 1 arguments that returns void without using the objects vtable to look up the method.
12428    /// This means that should the object be a subclass of the class that the method is declared in
12429    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12430    ///
12431    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12432    ///
12433    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12434    ///
12435    ///
12436    /// # Arguments
12437    /// * `obj` - which object the method should be called on
12438    ///     * must be valid
12439    ///     * must not be null
12440    ///     * must not be already garbage collected
12441    /// * `methodID` - method id of the method
12442    ///     * must not be null
12443    ///     * must be valid
12444    ///     * must not be a static
12445    ///     * must actually be a method of `obj`
12446    ///     * must refer to a method with 1 arguments
12447    ///
12448    /// # Throws Java Exception
12449    /// * Whatever the method threw
12450    ///
12451    ///
12452    /// # Panics
12453    /// if asserts feature is enabled and UB was detected
12454    ///
12455    /// # Safety
12456    ///
12457    /// Current thread must not be detached from JNI.
12458    ///
12459    /// Current thread must not be currently throwing an exception.
12460    ///
12461    /// Current thread does not hold a critical reference.
12462    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12463    ///
12464    /// `obj` must a valid and not already garbage collected.
12465    /// `methodID` must be valid, non-static and actually be a method of `obj`, return void and have 1 argument
12466    ///
12467    pub unsafe fn CallNonvirtualVoidMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) {
12468        unsafe {
12469            #[cfg(feature = "asserts")]
12470            {
12471                self.check_not_critical("CallNonvirtualVoidMethod");
12472                self.check_no_exception("CallNonvirtualVoidMethod");
12473                self.check_return_type_object("CallNonvirtualVoidMethod", obj, methodID, "void");
12474                self.check_is_class("CallNonvirtualVoidMethod", class);
12475                self.check_parameter_types_object("CallNonvirtualVoidMethod", obj, methodID, arg1, 0, 1);
12476            }
12477            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...)>(91)(self.vtable, obj, class, methodID, arg1);
12478        }
12479    }
12480
12481    ///
12482    /// Calls a non-static java method with 2 arguments that returns void without using the objects vtable to look up the method.
12483    /// This means that should the object be a subclass of the class that the method is declared in
12484    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12485    ///
12486    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12487    ///
12488    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12489    ///
12490    ///
12491    /// # Arguments
12492    /// * `obj` - which object the method should be called on
12493    ///     * must be valid
12494    ///     * must not be null
12495    ///     * must not be already garbage collected
12496    /// * `methodID` - method id of the method
12497    ///     * must not be null
12498    ///     * must be valid
12499    ///     * must not be a static
12500    ///     * must actually be a method of `obj`
12501    ///     * must refer to a method with 2 arguments
12502    ///
12503    /// # Throws Java Exception
12504    /// * Whatever the method threw
12505    ///
12506    ///
12507    /// # Panics
12508    /// if asserts feature is enabled and UB was detected
12509    ///
12510    /// # Safety
12511    ///
12512    /// Current thread must not be detached from JNI.
12513    ///
12514    /// Current thread must not be currently throwing an exception.
12515    ///
12516    /// Current thread does not hold a critical reference.
12517    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12518    ///
12519    /// `obj` must a valid and not already garbage collected.
12520    /// `methodID` must be valid, non-static and actually be a method of `obj`, return void and have 2 arguments
12521    ///
12522    pub unsafe fn CallNonvirtualVoidMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) {
12523        unsafe {
12524            #[cfg(feature = "asserts")]
12525            {
12526                self.check_not_critical("CallNonvirtualVoidMethod");
12527                self.check_no_exception("CallNonvirtualVoidMethod");
12528                self.check_return_type_object("CallNonvirtualVoidMethod", obj, methodID, "void");
12529                self.check_is_class("CallNonvirtualVoidMethod", class);
12530                self.check_parameter_types_object("CallNonvirtualVoidMethod", obj, methodID, arg1, 0, 2);
12531                self.check_parameter_types_object("CallNonvirtualVoidMethod", obj, methodID, arg2, 1, 2);
12532            }
12533            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...)>(91)(self.vtable, obj, class, methodID, arg1, arg2);
12534        }
12535    }
12536
12537    ///
12538    /// Calls a non-static java method with 3 arguments that returns void without using the objects vtable to look up the method.
12539    /// This means that should the object be a subclass of the class that the method is declared in
12540    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12541    ///
12542    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12543    ///
12544    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12545    ///
12546    ///
12547    /// # Arguments
12548    /// * `obj` - which object the method should be called on
12549    ///     * must be valid
12550    ///     * must not be null
12551    ///     * must not be already garbage collected
12552    /// * `methodID` - method id of the method
12553    ///     * must not be null
12554    ///     * must be valid
12555    ///     * must not be a static
12556    ///     * must actually be a method of `obj`
12557    ///     * must refer to a method with 3 arguments
12558    ///
12559    /// # Throws Java Exception
12560    /// * Whatever the method threw
12561    ///
12562    ///
12563    /// # Panics
12564    /// if asserts feature is enabled and UB was detected
12565    ///
12566    /// # Safety
12567    ///
12568    /// Current thread must not be detached from JNI.
12569    ///
12570    /// Current thread must not be currently throwing an exception.
12571    ///
12572    /// Current thread does not hold a critical reference.
12573    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12574    ///
12575    /// `obj` must a valid and not already garbage collected.
12576    /// `methodID` must be valid, non-static and actually be a method of `obj`, return void and have 3 arguments
12577    ///
12578    pub unsafe fn CallNonvirtualVoidMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) {
12579        unsafe {
12580            #[cfg(feature = "asserts")]
12581            {
12582                self.check_not_critical("CallNonvirtualVoidMethod");
12583                self.check_no_exception("CallNonvirtualVoidMethod");
12584                self.check_return_type_object("CallNonvirtualVoidMethod", obj, methodID, "void");
12585                self.check_is_class("CallNonvirtualVoidMethod", class);
12586                self.check_parameter_types_object("CallNonvirtualVoidMethod", obj, methodID, arg1, 0, 3);
12587                self.check_parameter_types_object("CallNonvirtualVoidMethod", obj, methodID, arg2, 1, 3);
12588                self.check_parameter_types_object("CallNonvirtualVoidMethod", obj, methodID, arg3, 2, 3);
12589            }
12590            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...)>(91)(self.vtable, obj, class, methodID, arg1, arg2, arg3);
12591        }
12592    }
12593
12594    ///
12595    /// Calls a non-static java method that returns object without using the objects vtable to look up the method.
12596    /// This means that should the object be a subclass of the class that the method is declared in
12597    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12598    ///
12599    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12600    ///
12601    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12602    ///
12603    ///
12604    /// # Arguments
12605    /// * `obj` - which object the method should be called on
12606    ///     * must be valid
12607    ///     * must not be null
12608    ///     * must not be already garbage collected
12609    /// * `methodID` - method id of the method
12610    ///     * must not be null
12611    ///     * must be valid
12612    ///     * must not be a static
12613    ///     * must actually be a method of `obj`
12614    /// * `args` - argument pointer
12615    ///     * can be null if the method has no arguments
12616    ///     * must not be null otherwise and point to the exact number of arguments the method expects
12617    ///
12618    /// # Returns
12619    /// Whatever the method returned or null if it threw
12620    ///
12621    /// # Throws Java Exception
12622    /// * Whatever the method threw
12623    ///
12624    ///
12625    /// # Panics
12626    /// if asserts feature is enabled and UB was detected
12627    ///
12628    /// # Safety
12629    ///
12630    /// Current thread must not be detached from JNI.
12631    ///
12632    /// Current thread must not be currently throwing an exception.
12633    ///
12634    /// Current thread does not hold a critical reference.
12635    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12636    ///
12637    /// `obj` must a valid and not already garbage collected.
12638    /// `methodID` must be valid, non-static and actually be a method of `obj` and return an object
12639    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
12640    /// `args` union must contain types that match the java methods parameters.
12641    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
12642    ///
12643    pub unsafe fn CallNonvirtualObjectMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) -> jobject {
12644        unsafe {
12645            #[cfg(feature = "asserts")]
12646            {
12647                self.check_not_critical("CallNonvirtualObjectMethodA");
12648                self.check_no_exception("CallNonvirtualObjectMethodA");
12649                self.check_return_type_object("CallNonvirtualObjectMethodA", obj, methodID, "object");
12650                self.check_is_class("CallNonvirtualObjectMethodA", class);
12651            }
12652            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype) -> jobject>(66)(self.vtable, obj, class, methodID, args)
12653        }
12654    }
12655
12656    ///
12657    /// Calls a non-static java method with 0 arguments that returns object without using the objects vtable to look up the method.
12658    /// This means that should the object be a subclass of the class that the method is declared in
12659    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12660    ///
12661    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12662    ///
12663    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12664    ///
12665    ///
12666    /// # Arguments
12667    /// * `obj` - which object the method should be called on
12668    ///     * must be valid
12669    ///     * must not be null
12670    ///     * must not be already garbage collected
12671    /// * `methodID` - method id of the method
12672    ///     * must not be null
12673    ///     * must be valid
12674    ///     * must not be a static
12675    ///     * must actually be a method of `obj`
12676    ///     * must refer to a method with 0 arguments
12677    ///
12678    /// # Returns
12679    /// Whatever the method returned or null if it threw
12680    ///
12681    /// # Throws Java Exception
12682    /// * Whatever the method threw
12683    ///
12684    ///
12685    /// # Panics
12686    /// if asserts feature is enabled and UB was detected
12687    ///
12688    /// # Safety
12689    ///
12690    /// Current thread must not be detached from JNI.
12691    ///
12692    /// Current thread must not be currently throwing an exception.
12693    ///
12694    /// Current thread does not hold a critical reference.
12695    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12696    ///
12697    /// `obj` must a valid and not already garbage collected.
12698    /// `methodID` must be valid, non-static and actually be a method of `obj`, return an object and have no parameters
12699    ///
12700    pub unsafe fn CallNonvirtualObjectMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) -> jobject {
12701        unsafe {
12702            #[cfg(feature = "asserts")]
12703            {
12704                self.check_not_critical("CallNonvirtualObjectMethod");
12705                self.check_no_exception("CallNonvirtualObjectMethod");
12706                self.check_return_type_object("CallNonvirtualObjectMethod", obj, methodID, "object");
12707                self.check_is_class("CallNonvirtualObjectMethod", class);
12708            }
12709            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID) -> jobject>(64)(self.vtable, obj, class, methodID)
12710        }
12711    }
12712
12713    ///
12714    /// Calls a non-static java method with 1 arguments that returns object without using the objects vtable to look up the method.
12715    /// This means that should the object be a subclass of the class that the method is declared in
12716    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12717    ///
12718    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12719    ///
12720    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12721    ///
12722    ///
12723    /// # Arguments
12724    /// * `obj` - which object the method should be called on
12725    ///     * must be valid
12726    ///     * must not be null
12727    ///     * must not be already garbage collected
12728    /// * `methodID` - method id of the method
12729    ///     * must not be null
12730    ///     * must be valid
12731    ///     * must not be a static
12732    ///     * must actually be a method of `obj`
12733    ///     * must refer to a method with 1 arguments
12734    ///
12735    /// # Returns
12736    /// Whatever the method returned or null if it threw
12737    ///
12738    /// # Throws Java Exception
12739    /// * Whatever the method threw
12740    ///
12741    ///
12742    /// # Panics
12743    /// if asserts feature is enabled and UB was detected
12744    ///
12745    /// # Safety
12746    ///
12747    /// Current thread must not be detached from JNI.
12748    ///
12749    /// Current thread must not be currently throwing an exception.
12750    ///
12751    /// Current thread does not hold a critical reference.
12752    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12753    ///
12754    /// `obj` must a valid and not already garbage collected.
12755    /// `methodID` must be valid, non-static and actually be a method of `obj`, return an object and have 1 arguments
12756    ///
12757    pub unsafe fn CallNonvirtualObjectMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) -> jobject {
12758        unsafe {
12759            #[cfg(feature = "asserts")]
12760            {
12761                self.check_not_critical("CallNonvirtualObjectMethod");
12762                self.check_no_exception("CallNonvirtualObjectMethod");
12763                self.check_return_type_object("CallNonvirtualObjectMethod", obj, methodID, "object");
12764                self.check_is_class("CallNonvirtualObjectMethod", class);
12765                self.check_parameter_types_object("CallNonvirtualObjectMethod", obj, methodID, arg1, 0, 1);
12766            }
12767            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jobject>(64)(self.vtable, obj, class, methodID, arg1)
12768        }
12769    }
12770
12771    ///
12772    /// Calls a non-static java method with 2 arguments that returns object without using the objects vtable to look up the method.
12773    /// This means that should the object be a subclass of the class that the method is declared in
12774    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12775    ///
12776    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12777    ///
12778    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12779    ///
12780    ///
12781    /// # Arguments
12782    /// * `obj` - which object the method should be called on
12783    ///     * must be valid
12784    ///     * must not be null
12785    ///     * must not be already garbage collected
12786    /// * `methodID` - method id of the method
12787    ///     * must not be null
12788    ///     * must be valid
12789    ///     * must not be a static
12790    ///     * must actually be a method of `obj`
12791    ///     * must refer to a method with 2 arguments
12792    ///
12793    /// # Returns
12794    /// Whatever the method returned or null if it threw
12795    ///
12796    /// # Throws Java Exception
12797    /// * Whatever the method threw
12798    ///
12799    ///
12800    /// # Panics
12801    /// if asserts feature is enabled and UB was detected
12802    ///
12803    /// # Safety
12804    ///
12805    /// Current thread must not be detached from JNI.
12806    ///
12807    /// Current thread must not be currently throwing an exception.
12808    ///
12809    /// Current thread does not hold a critical reference.
12810    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12811    ///
12812    /// `obj` must a valid and not already garbage collected.
12813    /// `methodID` must be valid, non-static and actually be a method of `obj`, return an object and have 2 arguments
12814    ///
12815    pub unsafe fn CallNonvirtualObjectMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jobject {
12816        unsafe {
12817            #[cfg(feature = "asserts")]
12818            {
12819                self.check_not_critical("CallNonvirtualObjectMethod");
12820                self.check_no_exception("CallNonvirtualObjectMethod");
12821                self.check_return_type_object("CallNonvirtualObjectMethod", obj, methodID, "object");
12822                self.check_is_class("CallNonvirtualObjectMethod", class);
12823                self.check_parameter_types_object("CallNonvirtualObjectMethod", obj, methodID, arg1, 0, 2);
12824                self.check_parameter_types_object("CallNonvirtualObjectMethod", obj, methodID, arg2, 1, 2);
12825            }
12826            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jobject>(64)(self.vtable, obj, class, methodID, arg1, arg2)
12827        }
12828    }
12829
12830    ///
12831    /// Calls a non-static java method with 3 arguments that returns object without using the objects vtable to look up the method.
12832    /// This means that should the object be a subclass of the class that the method is declared in
12833    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12834    ///
12835    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12836    ///
12837    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12838    ///
12839    ///
12840    /// # Arguments
12841    /// * `obj` - which object the method should be called on
12842    ///     * must be valid
12843    ///     * must not be null
12844    ///     * must not be already garbage collected
12845    /// * `methodID` - method id of the method
12846    ///     * must not be null
12847    ///     * must be valid
12848    ///     * must not be a static
12849    ///     * must actually be a method of `obj`
12850    ///     * must refer to a method with 3 arguments
12851    ///
12852    /// # Returns
12853    /// Whatever the method returned or null if it threw
12854    ///
12855    /// # Throws Java Exception
12856    /// * Whatever the method threw
12857    ///
12858    ///
12859    /// # Panics
12860    /// if asserts feature is enabled and UB was detected
12861    ///
12862    /// # Safety
12863    ///
12864    /// Current thread must not be detached from JNI.
12865    ///
12866    /// Current thread must not be currently throwing an exception.
12867    ///
12868    /// Current thread does not hold a critical reference.
12869    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12870    ///
12871    /// `obj` must a valid and not already garbage collected.
12872    /// `methodID` must be valid, non-static and actually be a method of `obj`, return an object and have 3 arguments
12873    ///
12874    pub unsafe fn CallNonvirtualObjectMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jobject {
12875        unsafe {
12876            #[cfg(feature = "asserts")]
12877            {
12878                self.check_not_critical("CallNonvirtualObjectMethod");
12879                self.check_no_exception("CallNonvirtualObjectMethod");
12880                self.check_return_type_object("CallNonvirtualObjectMethod", obj, methodID, "object");
12881                self.check_is_class("CallNonvirtualObjectMethod", class);
12882                self.check_parameter_types_object("CallNonvirtualObjectMethod", obj, methodID, arg1, 0, 3);
12883                self.check_parameter_types_object("CallNonvirtualObjectMethod", obj, methodID, arg2, 1, 3);
12884                self.check_parameter_types_object("CallNonvirtualObjectMethod", obj, methodID, arg3, 2, 3);
12885            }
12886            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jobject>(64)(self.vtable, obj, class, methodID, arg1, arg2, arg3)
12887        }
12888    }
12889
12890    ///
12891    /// Calls a non-static java method that returns boolean without using the objects vtable to look up the method.
12892    /// This means that should the object be a subclass of the class that the method is declared in
12893    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12894    ///
12895    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12896    ///
12897    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12898    ///
12899    ///
12900    /// # Arguments
12901    /// * `obj` - which object the method should be called on
12902    ///     * must be valid
12903    ///     * must not be null
12904    ///     * must not be already garbage collected
12905    /// * `methodID` - method id of the method
12906    ///     * must not be null
12907    ///     * must be valid
12908    ///     * must not be a static
12909    ///     * must actually be a method of `obj`
12910    /// * `args` - argument pointer
12911    ///     * can be null if the method has no arguments
12912    ///     * must not be null otherwise and point to the exact number of arguments the method expects
12913    ///
12914    /// # Returns
12915    /// Whatever the method returned or false if it threw
12916    ///
12917    /// # Throws Java Exception
12918    /// * Whatever the method threw
12919    ///
12920    ///
12921    /// # Panics
12922    /// if asserts feature is enabled and UB was detected
12923    ///
12924    /// # Safety
12925    ///
12926    /// Current thread must not be detached from JNI.
12927    ///
12928    /// Current thread must not be currently throwing an exception.
12929    ///
12930    /// Current thread does not hold a critical reference.
12931    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12932    ///
12933    /// `obj` must a valid and not already garbage collected.
12934    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a boolean
12935    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
12936    /// `args` union must contain types that match the java methods parameters.
12937    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
12938    ///
12939    pub unsafe fn CallNonvirtualBooleanMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) -> bool {
12940        unsafe {
12941            #[cfg(feature = "asserts")]
12942            {
12943                self.check_not_critical("CallNonvirtualBooleanMethodA");
12944                self.check_no_exception("CallNonvirtualBooleanMethodA");
12945                self.check_return_type_object("CallNonvirtualBooleanMethodA", obj, methodID, "boolean");
12946                self.check_is_class("CallNonvirtualBooleanMethodA", class);
12947            }
12948            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype) -> jboolean>(69)(self.vtable, obj, class, methodID, args).as_bool()
12949        }
12950    }
12951
12952    ///
12953    /// Calls a non-static java method with 0 arguments that returns boolean without using the objects vtable to look up the method.
12954    /// This means that should the object be a subclass of the class that the method is declared in
12955    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12956    ///
12957    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12958    ///
12959    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12960    ///
12961    ///
12962    /// # Arguments
12963    /// * `obj` - which object the method should be called on
12964    ///     * must be valid
12965    ///     * must not be null
12966    ///     * must not be already garbage collected
12967    /// * `methodID` - method id of the method
12968    ///     * must not be null
12969    ///     * must be valid
12970    ///     * must not be a static
12971    ///     * must actually be a method of `obj`
12972    ///     * must refer to a method with 0 arguments
12973    ///
12974    /// # Returns
12975    /// Whatever the method returned or false if it threw
12976    ///
12977    /// # Throws Java Exception
12978    /// * Whatever the method threw
12979    ///
12980    ///
12981    /// # Panics
12982    /// if asserts feature is enabled and UB was detected
12983    ///
12984    /// # Safety
12985    ///
12986    /// Current thread must not be detached from JNI.
12987    ///
12988    /// Current thread must not be currently throwing an exception.
12989    ///
12990    /// Current thread does not hold a critical reference.
12991    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12992    ///
12993    /// `obj` must a valid and not already garbage collected.
12994    /// `methodID` must be valid, non-static and actually be a method of `obj`, return boolean and have no parameters
12995    ///
12996    pub unsafe fn CallNonvirtualBooleanMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) -> bool {
12997        unsafe {
12998            #[cfg(feature = "asserts")]
12999            {
13000                self.check_not_critical("CallNonvirtualBooleanMethod");
13001                self.check_no_exception("CallNonvirtualBooleanMethod");
13002                self.check_return_type_object("CallNonvirtualBooleanMethod", obj, methodID, "boolean");
13003                self.check_is_class("CallNonvirtualBooleanMethod", class);
13004            }
13005            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID) -> jboolean>(67)(self.vtable, obj, class, methodID).as_bool()
13006        }
13007    }
13008
13009    ///
13010    /// Calls a non-static java method with 1 arguments that returns boolean without using the objects vtable to look up the method.
13011    /// This means that should the object be a subclass of the class that the method is declared in
13012    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13013    ///
13014    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13015    ///
13016    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13017    ///
13018    ///
13019    /// # Arguments
13020    /// * `obj` - which object the method should be called on
13021    ///     * must be valid
13022    ///     * must not be null
13023    ///     * must not be already garbage collected
13024    /// * `methodID` - method id of the method
13025    ///     * must not be null
13026    ///     * must be valid
13027    ///     * must not be a static
13028    ///     * must actually be a method of `obj`
13029    ///     * must refer to a method with 1 arguments
13030    ///
13031    /// # Returns
13032    /// Whatever the method returned or false if it threw
13033    ///
13034    /// # Throws Java Exception
13035    /// * Whatever the method threw
13036    ///
13037    ///
13038    /// # Panics
13039    /// if asserts feature is enabled and UB was detected
13040    ///
13041    /// # Safety
13042    ///
13043    /// Current thread must not be detached from JNI.
13044    ///
13045    /// Current thread must not be currently throwing an exception.
13046    ///
13047    /// Current thread does not hold a critical reference.
13048    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13049    ///
13050    /// `obj` must a valid and not already garbage collected.
13051    /// `methodID` must be valid, non-static and actually be a method of `obj`, return boolean and have 1 arguments
13052    ///
13053    pub unsafe fn CallNonvirtualBooleanMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) -> bool {
13054        unsafe {
13055            #[cfg(feature = "asserts")]
13056            {
13057                self.check_not_critical("CallNonvirtualBooleanMethod");
13058                self.check_no_exception("CallNonvirtualBooleanMethod");
13059                self.check_return_type_object("CallNonvirtualBooleanMethod", obj, methodID, "boolean");
13060                self.check_is_class("CallNonvirtualBooleanMethod", class);
13061                self.check_parameter_types_object("CallNonvirtualBooleanMethod", obj, methodID, arg1, 0, 1);
13062            }
13063            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jboolean>(67)(self.vtable, obj, class, methodID, arg1).as_bool()
13064        }
13065    }
13066
13067    ///
13068    /// Calls a non-static java method with 2 arguments that returns boolean without using the objects vtable to look up the method.
13069    /// This means that should the object be a subclass of the class that the method is declared in
13070    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13071    ///
13072    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13073    ///
13074    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13075    ///
13076    ///
13077    /// # Arguments
13078    /// * `obj` - which object the method should be called on
13079    ///     * must be valid
13080    ///     * must not be null
13081    ///     * must not be already garbage collected
13082    /// * `methodID` - method id of the method
13083    ///     * must not be null
13084    ///     * must be valid
13085    ///     * must not be a static
13086    ///     * must actually be a method of `obj`
13087    ///     * must refer to a method with 2 arguments
13088    ///
13089    /// # Returns
13090    /// Whatever the method returned or false if it threw
13091    ///
13092    /// # Throws Java Exception
13093    /// * Whatever the method threw
13094    ///
13095    ///
13096    /// # Panics
13097    /// if asserts feature is enabled and UB was detected
13098    ///
13099    /// # Safety
13100    ///
13101    /// Current thread must not be detached from JNI.
13102    ///
13103    /// Current thread must not be currently throwing an exception.
13104    ///
13105    /// Current thread does not hold a critical reference.
13106    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13107    ///
13108    /// `obj` must a valid and not already garbage collected.
13109    /// `methodID` must be valid, non-static and actually be a method of `obj`, return boolean and have 2 arguments
13110    ///
13111    pub unsafe fn CallNonvirtualBooleanMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) -> bool {
13112        unsafe {
13113            #[cfg(feature = "asserts")]
13114            {
13115                self.check_not_critical("CallNonvirtualBooleanMethod");
13116                self.check_no_exception("CallNonvirtualBooleanMethod");
13117                self.check_return_type_object("CallNonvirtualBooleanMethod", obj, methodID, "boolean");
13118                self.check_is_class("CallNonvirtualBooleanMethod", class);
13119                self.check_parameter_types_object("CallNonvirtualBooleanMethod", obj, methodID, arg1, 0, 2);
13120                self.check_parameter_types_object("CallNonvirtualBooleanMethod", obj, methodID, arg2, 1, 2);
13121            }
13122            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jboolean>(67)(self.vtable, obj, class, methodID, arg1, arg2).as_bool()
13123        }
13124    }
13125
13126    ///
13127    /// Calls a non-static java method with 3 arguments that returns boolean without using the objects vtable to look up the method.
13128    /// This means that should the object be a subclass of the class that the method is declared in
13129    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13130    ///
13131    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13132    ///
13133    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13134    ///
13135    ///
13136    /// # Arguments
13137    /// * `obj` - which object the method should be called on
13138    ///     * must be valid
13139    ///     * must not be null
13140    ///     * must not be already garbage collected
13141    /// * `methodID` - method id of the method
13142    ///     * must not be null
13143    ///     * must be valid
13144    ///     * must not be a static
13145    ///     * must actually be a method of `obj`
13146    ///     * must refer to a method with 3 arguments
13147    ///
13148    /// # Returns
13149    /// Whatever the method returned or false if it threw
13150    ///
13151    /// # Throws Java Exception
13152    /// * Whatever the method threw
13153    ///
13154    ///
13155    /// # Panics
13156    /// if asserts feature is enabled and UB was detected
13157    ///
13158    /// # Safety
13159    ///
13160    /// Current thread must not be detached from JNI.
13161    ///
13162    /// Current thread must not be currently throwing an exception.
13163    ///
13164    /// Current thread does not hold a critical reference.
13165    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13166    ///
13167    /// `obj` must a valid and not already garbage collected.
13168    /// `methodID` must be valid, non-static and actually be a method of `obj`, return boolean and have 3 arguments
13169    ///
13170    pub unsafe fn CallNonvirtualBooleanMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> bool {
13171        unsafe {
13172            #[cfg(feature = "asserts")]
13173            {
13174                self.check_not_critical("CallNonvirtualBooleanMethod");
13175                self.check_no_exception("CallNonvirtualBooleanMethod");
13176                self.check_return_type_object("CallNonvirtualBooleanMethod", obj, methodID, "boolean");
13177                self.check_is_class("CallNonvirtualBooleanMethod", class);
13178                self.check_parameter_types_object("CallNonvirtualBooleanMethod", obj, methodID, arg1, 0, 3);
13179                self.check_parameter_types_object("CallNonvirtualBooleanMethod", obj, methodID, arg2, 1, 3);
13180                self.check_parameter_types_object("CallNonvirtualBooleanMethod", obj, methodID, arg3, 2, 3);
13181            }
13182            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jboolean>(67)(self.vtable, obj, class, methodID, arg1, arg2, arg3).as_bool()
13183        }
13184    }
13185
13186    ///
13187    /// Calls a non-static java method that returns byte without using the objects vtable to look up the method.
13188    /// This means that should the object be a subclass of the class that the method is declared in
13189    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13190    ///
13191    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13192    ///
13193    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13194    ///
13195    ///
13196    /// # Arguments
13197    /// * `obj` - which object the method should be called on
13198    ///     * must be valid
13199    ///     * must not be null
13200    ///     * must not be already garbage collected
13201    /// * `methodID` - method id of the method
13202    ///     * must not be null
13203    ///     * must be valid
13204    ///     * must not be a static
13205    ///     * must actually be a method of `obj`
13206    /// * `args` - argument pointer
13207    ///     * can be null if the method has no arguments
13208    ///     * must not be null otherwise and point to the exact number of arguments the method expects
13209    ///
13210    /// # Returns
13211    /// Whatever the method returned or 0 if it threw
13212    ///
13213    /// # Throws Java Exception
13214    /// * Whatever the method threw
13215    ///
13216    ///
13217    /// # Panics
13218    /// if asserts feature is enabled and UB was detected
13219    ///
13220    /// # Safety
13221    ///
13222    /// Current thread must not be detached from JNI.
13223    ///
13224    /// Current thread must not be currently throwing an exception.
13225    ///
13226    /// Current thread does not hold a critical reference.
13227    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13228    ///
13229    /// `obj` must a valid and not already garbage collected.
13230    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a byte
13231    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
13232    /// `args` union must contain types that match the java methods parameters.
13233    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
13234    ///
13235    pub unsafe fn CallNonvirtualByteMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) -> jbyte {
13236        unsafe {
13237            #[cfg(feature = "asserts")]
13238            {
13239                self.check_not_critical("CallNonvirtualByteMethodA");
13240                self.check_no_exception("CallNonvirtualByteMethodA");
13241                self.check_return_type_object("CallNonvirtualByteMethodA", obj, methodID, "byte");
13242                self.check_is_class("CallNonvirtualByteMethodA", class);
13243            }
13244            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype) -> jbyte>(72)(self.vtable, obj, class, methodID, args)
13245        }
13246    }
13247
13248    ///
13249    /// Calls a non-static java method with 0 arguments that returns byte without using the objects vtable to look up the method.
13250    /// This means that should the object be a subclass of the class that the method is declared in
13251    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13252    ///
13253    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13254    ///
13255    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13256    ///
13257    ///
13258    /// # Arguments
13259    /// * `obj` - which object the method should be called on
13260    ///     * must be valid
13261    ///     * must not be null
13262    ///     * must not be already garbage collected
13263    /// * `methodID` - method id of the method
13264    ///     * must not be null
13265    ///     * must be valid
13266    ///     * must not be a static
13267    ///     * must actually be a method of `obj`
13268    ///     * must refer to a method with 0 arguments
13269    ///
13270    /// # Returns
13271    /// Whatever the method returned or 0 if it threw
13272    ///
13273    /// # Throws Java Exception
13274    /// * Whatever the method threw
13275    ///
13276    ///
13277    /// # Panics
13278    /// if asserts feature is enabled and UB was detected
13279    ///
13280    /// # Safety
13281    ///
13282    /// Current thread must not be detached from JNI.
13283    ///
13284    /// Current thread must not be currently throwing an exception.
13285    ///
13286    /// Current thread does not hold a critical reference.
13287    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13288    ///
13289    /// `obj` must a valid and not already garbage collected.
13290    /// `methodID` must be valid, non-static and actually be a method of `obj`, return byte and have 0 arguments
13291    ///
13292    pub unsafe fn CallNonvirtualByteMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) -> jbyte {
13293        unsafe {
13294            #[cfg(feature = "asserts")]
13295            {
13296                self.check_not_critical("CallNonvirtualByteMethod");
13297                self.check_no_exception("CallNonvirtualByteMethod");
13298                self.check_return_type_object("CallNonvirtualByteMethod", obj, methodID, "byte");
13299                self.check_is_class("CallNonvirtualByteMethod", class);
13300            }
13301            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID) -> jbyte>(70)(self.vtable, obj, class, methodID)
13302        }
13303    }
13304
13305    ///
13306    /// Calls a non-static java method with 1 arguments that returns byte without using the objects vtable to look up the method.
13307    /// This means that should the object be a subclass of the class that the method is declared in
13308    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13309    ///
13310    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13311    ///
13312    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13313    ///
13314    ///
13315    /// # Arguments
13316    /// * `obj` - which object the method should be called on
13317    ///     * must be valid
13318    ///     * must not be null
13319    ///     * must not be already garbage collected
13320    /// * `methodID` - method id of the method
13321    ///     * must not be null
13322    ///     * must be valid
13323    ///     * must not be a static
13324    ///     * must actually be a method of `obj`
13325    ///     * must refer to a method with 1 arguments
13326    ///
13327    /// # Returns
13328    /// Whatever the method returned or 0 if it threw
13329    ///
13330    /// # Throws Java Exception
13331    /// * Whatever the method threw
13332    ///
13333    ///
13334    /// # Panics
13335    /// if asserts feature is enabled and UB was detected
13336    ///
13337    /// # Safety
13338    ///
13339    /// Current thread must not be detached from JNI.
13340    ///
13341    /// Current thread must not be currently throwing an exception.
13342    ///
13343    /// Current thread does not hold a critical reference.
13344    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13345    ///
13346    /// `obj` must a valid and not already garbage collected.
13347    /// `methodID` must be valid, non-static and actually be a method of `obj`, return byte and have 1 arguments
13348    ///
13349    pub unsafe fn CallNonvirtualByteMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) -> jbyte {
13350        unsafe {
13351            #[cfg(feature = "asserts")]
13352            {
13353                self.check_not_critical("CallNonvirtualByteMethod");
13354                self.check_no_exception("CallNonvirtualByteMethod");
13355                self.check_return_type_object("CallNonvirtualByteMethod", obj, methodID, "byte");
13356                self.check_is_class("CallNonvirtualByteMethod", class);
13357                self.check_parameter_types_object("CallNonvirtualByteMethod", obj, methodID, arg1, 0, 1);
13358            }
13359            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jbyte>(70)(self.vtable, obj, class, methodID, arg1)
13360        }
13361    }
13362
13363    ///
13364    /// Calls a non-static java method with 2 arguments that returns byte without using the objects vtable to look up the method.
13365    /// This means that should the object be a subclass of the class that the method is declared in
13366    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13367    ///
13368    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13369    ///
13370    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13371    ///
13372    ///
13373    /// # Arguments
13374    /// * `obj` - which object the method should be called on
13375    ///     * must be valid
13376    ///     * must not be null
13377    ///     * must not be already garbage collected
13378    /// * `methodID` - method id of the method
13379    ///     * must not be null
13380    ///     * must be valid
13381    ///     * must not be a static
13382    ///     * must actually be a method of `obj`
13383    ///     * must refer to a method with 0 arguments
13384    ///
13385    /// # Returns
13386    /// Whatever the method returned or 2 if it threw
13387    ///
13388    /// # Throws Java Exception
13389    /// * Whatever the method threw
13390    ///
13391    ///
13392    /// # Panics
13393    /// if asserts feature is enabled and UB was detected
13394    ///
13395    /// # Safety
13396    ///
13397    /// Current thread must not be detached from JNI.
13398    ///
13399    /// Current thread must not be currently throwing an exception.
13400    ///
13401    /// Current thread does not hold a critical reference.
13402    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13403    ///
13404    /// `obj` must a valid and not already garbage collected.
13405    /// `methodID` must be valid, non-static and actually be a method of `obj`, return byte and have 2 arguments
13406    ///
13407    pub unsafe fn CallNonvirtualByteMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jbyte {
13408        unsafe {
13409            #[cfg(feature = "asserts")]
13410            {
13411                self.check_not_critical("CallNonvirtualByteMethod");
13412                self.check_no_exception("CallNonvirtualByteMethod");
13413                self.check_return_type_object("CallNonvirtualByteMethod", obj, methodID, "byte");
13414                self.check_is_class("CallNonvirtualByteMethod", class);
13415                self.check_parameter_types_object("CallNonvirtualByteMethod", obj, methodID, arg1, 0, 2);
13416                self.check_parameter_types_object("CallNonvirtualByteMethod", obj, methodID, arg2, 1, 2);
13417            }
13418            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jbyte>(70)(self.vtable, obj, class, methodID, arg1, arg2)
13419        }
13420    }
13421
13422    ///
13423    /// Calls a non-static java method with 3 arguments that returns byte without using the objects vtable to look up the method.
13424    /// This means that should the object be a subclass of the class that the method is declared in
13425    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13426    ///
13427    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13428    ///
13429    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13430    ///
13431    ///
13432    /// # Arguments
13433    /// * `obj` - which object the method should be called on
13434    ///     * must be valid
13435    ///     * must not be null
13436    ///     * must not be already garbage collected
13437    /// * `methodID` - method id of the method
13438    ///     * must not be null
13439    ///     * must be valid
13440    ///     * must not be a static
13441    ///     * must actually be a method of `obj`
13442    ///     * must refer to a method with 0 arguments
13443    ///
13444    /// # Returns
13445    /// Whatever the method returned or 3 if it threw
13446    ///
13447    /// # Throws Java Exception
13448    /// * Whatever the method threw
13449    ///
13450    ///
13451    /// # Panics
13452    /// if asserts feature is enabled and UB was detected
13453    ///
13454    /// # Safety
13455    ///
13456    /// Current thread must not be detached from JNI.
13457    ///
13458    /// Current thread must not be currently throwing an exception.
13459    ///
13460    /// Current thread does not hold a critical reference.
13461    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13462    ///
13463    /// `obj` must a valid and not already garbage collected.
13464    /// `methodID` must be valid, non-static and actually be a method of `obj`, return byte and have 3 arguments
13465    ///
13466    pub unsafe fn CallNonvirtualByteMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jbyte {
13467        unsafe {
13468            #[cfg(feature = "asserts")]
13469            {
13470                self.check_not_critical("CallNonvirtualByteMethod");
13471                self.check_no_exception("CallNonvirtualByteMethod");
13472                self.check_return_type_object("CallNonvirtualByteMethod", obj, methodID, "byte");
13473                self.check_is_class("CallNonvirtualByteMethod", class);
13474                self.check_parameter_types_object("CallNonvirtualByteMethod", obj, methodID, arg1, 0, 3);
13475                self.check_parameter_types_object("CallNonvirtualByteMethod", obj, methodID, arg2, 1, 3);
13476                self.check_parameter_types_object("CallNonvirtualByteMethod", obj, methodID, arg3, 2, 3);
13477            }
13478            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jbyte>(70)(self.vtable, obj, class, methodID, arg1, arg2, arg3)
13479        }
13480    }
13481
13482    ///
13483    /// Calls a non-static java method with 3 arguments that returns char without using the objects vtable to look up the method.
13484    /// This means that should the object be a subclass of the class that the method is declared in
13485    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13486    ///
13487    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13488    ///
13489    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13490    ///
13491    ///
13492    /// # Arguments
13493    /// * `obj` - which object the method should be called on
13494    ///     * must be valid
13495    ///     * must not be null
13496    ///     * must not be already garbage collected
13497    /// * `methodID` - method id of the method
13498    ///     * must not be null
13499    ///     * must be valid
13500    ///     * must not be a static
13501    ///     * must actually be a method of `obj`
13502    /// * `args` - argument pointer
13503    ///     * can be null if the method has no arguments
13504    ///     * must not be null otherwise and point to the exact number of arguments the method expects
13505    ///
13506    /// # Returns
13507    /// Whatever the method returned or 0 if it threw
13508    ///
13509    /// # Throws Java Exception
13510    /// * Whatever the method threw
13511    ///
13512    ///
13513    /// # Panics
13514    /// if asserts feature is enabled and UB was detected
13515    ///
13516    /// # Safety
13517    ///
13518    /// Current thread must not be detached from JNI.
13519    ///
13520    /// Current thread must not be currently throwing an exception.
13521    ///
13522    /// Current thread does not hold a critical reference.
13523    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13524    ///
13525    /// `obj` must a valid and not already garbage collected.
13526    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a char
13527    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
13528    /// `args` union must contain types that match the java methods parameters.
13529    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
13530    ///
13531    pub unsafe fn CallNonvirtualCharMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) -> jchar {
13532        unsafe {
13533            #[cfg(feature = "asserts")]
13534            {
13535                self.check_not_critical("CallNonvirtualCharMethodA");
13536                self.check_no_exception("CallNonvirtualCharMethodA");
13537                self.check_return_type_object("CallNonvirtualCharMethodA", obj, methodID, "char");
13538                self.check_is_class("CallNonvirtualCharMethodA", class);
13539            }
13540            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype) -> jchar>(75)(self.vtable, obj, class, methodID, args)
13541        }
13542    }
13543
13544    ///
13545    /// Calls a non-static java method with 0 arguments that returns char without using the objects vtable to look up the method.
13546    /// This means that should the object be a subclass of the class that the method is declared in
13547    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13548    ///
13549    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13550    ///
13551    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13552    ///
13553    ///
13554    /// # Arguments
13555    /// * `obj` - which object the method should be called on
13556    ///     * must be valid
13557    ///     * must not be null
13558    ///     * must not be already garbage collected
13559    /// * `methodID` - method id of the method
13560    ///     * must not be null
13561    ///     * must be valid
13562    ///     * must not be a static
13563    ///     * must actually be a method of `obj`
13564    ///     * must refer to a method with 0 arguments
13565    ///
13566    /// # Returns
13567    /// Whatever the method returned or 0 if it threw
13568    ///
13569    /// # Throws Java Exception
13570    /// * Whatever the method threw
13571    ///
13572    ///
13573    /// # Panics
13574    /// if asserts feature is enabled and UB was detected
13575    ///
13576    /// # Safety
13577    ///
13578    /// Current thread must not be detached from JNI.
13579    ///
13580    /// Current thread must not be currently throwing an exception.
13581    ///
13582    /// Current thread does not hold a critical reference.
13583    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13584    ///
13585    /// `obj` must a valid and not already garbage collected.
13586    /// `methodID` must be valid, non-static and actually be a method of `obj`, return char and have 0 arguments
13587    ///
13588    pub unsafe fn CallNonvirtualCharMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) -> jchar {
13589        unsafe {
13590            #[cfg(feature = "asserts")]
13591            {
13592                self.check_not_critical("CallNonvirtualCharMethod");
13593                self.check_no_exception("CallNonvirtualCharMethod");
13594                self.check_return_type_object("CallNonvirtualCharMethod", obj, methodID, "char");
13595                self.check_is_class("CallNonvirtualCharMethod", class);
13596            }
13597            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID) -> jchar>(73)(self.vtable, obj, class, methodID)
13598        }
13599    }
13600
13601    ///
13602    /// Calls a non-static java method with 1 arguments that returns char without using the objects vtable to look up the method.
13603    /// This means that should the object be a subclass of the class that the method is declared in
13604    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13605    ///
13606    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13607    ///
13608    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13609    ///
13610    ///
13611    /// # Arguments
13612    /// * `obj` - which object the method should be called on
13613    ///     * must be valid
13614    ///     * must not be null
13615    ///     * must not be already garbage collected
13616    /// * `methodID` - method id of the method
13617    ///     * must not be null
13618    ///     * must be valid
13619    ///     * must not be a static
13620    ///     * must actually be a method of `obj`
13621    ///     * must refer to a method with 1 arguments
13622    ///
13623    /// # Returns
13624    /// Whatever the method returned or 0 if it threw
13625    ///
13626    /// # Throws Java Exception
13627    /// * Whatever the method threw
13628    ///
13629    ///
13630    /// # Panics
13631    /// if asserts feature is enabled and UB was detected
13632    ///
13633    /// # Safety
13634    ///
13635    /// Current thread must not be detached from JNI.
13636    ///
13637    /// Current thread must not be currently throwing an exception.
13638    ///
13639    /// Current thread does not hold a critical reference.
13640    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13641    ///
13642    /// `obj` must a valid and not already garbage collected.
13643    /// `methodID` must be valid, non-static and actually be a method of `obj`, return char and have 1 arguments
13644    ///
13645    pub unsafe fn CallNonvirtualCharMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) -> jchar {
13646        unsafe {
13647            #[cfg(feature = "asserts")]
13648            {
13649                self.check_not_critical("CallNonvirtualCharMethod");
13650                self.check_no_exception("CallNonvirtualCharMethod");
13651                self.check_return_type_object("CallNonvirtualCharMethod", obj, methodID, "char");
13652                self.check_is_class("CallNonvirtualCharMethod", class);
13653                self.check_parameter_types_object("CallNonvirtualCharMethod", obj, methodID, arg1, 0, 1);
13654            }
13655            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jchar>(73)(self.vtable, obj, class, methodID, arg1)
13656        }
13657    }
13658
13659    ///
13660    /// Calls a non-static java method with 2 arguments that returns char without using the objects vtable to look up the method.
13661    /// This means that should the object be a subclass of the class that the method is declared in
13662    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13663    ///
13664    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13665    ///
13666    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13667    ///
13668    ///
13669    /// # Arguments
13670    /// * `obj` - which object the method should be called on
13671    ///     * must be valid
13672    ///     * must not be null
13673    ///     * must not be already garbage collected
13674    /// * `methodID` - method id of the method
13675    ///     * must not be null
13676    ///     * must be valid
13677    ///     * must not be a static
13678    ///     * must actually be a method of `obj`
13679    ///     * must refer to a method with 2 arguments
13680    ///
13681    /// # Returns
13682    /// Whatever the method returned or 0 if it threw
13683    ///
13684    /// # Throws Java Exception
13685    /// * Whatever the method threw
13686    ///
13687    ///
13688    /// # Panics
13689    /// if asserts feature is enabled and UB was detected
13690    ///
13691    /// # Safety
13692    ///
13693    /// Current thread must not be detached from JNI.
13694    ///
13695    /// Current thread must not be currently throwing an exception.
13696    ///
13697    /// Current thread does not hold a critical reference.
13698    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13699    ///
13700    /// `obj` must a valid and not already garbage collected.
13701    /// `methodID` must be valid, non-static and actually be a method of `obj`, return char and have 2 arguments
13702    ///
13703    pub unsafe fn CallNonvirtualCharMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jchar {
13704        unsafe {
13705            #[cfg(feature = "asserts")]
13706            {
13707                self.check_not_critical("CallNonvirtualCharMethod");
13708                self.check_no_exception("CallNonvirtualCharMethod");
13709                self.check_return_type_object("CallNonvirtualCharMethod", obj, methodID, "char");
13710                self.check_is_class("CallNonvirtualCharMethod", class);
13711                self.check_parameter_types_object("CallNonvirtualCharMethod", obj, methodID, arg1, 0, 2);
13712                self.check_parameter_types_object("CallNonvirtualCharMethod", obj, methodID, arg2, 1, 2);
13713            }
13714            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jchar>(73)(self.vtable, obj, class, methodID, arg1, arg2)
13715        }
13716    }
13717
13718    ///
13719    /// Calls a non-static java method with 3 arguments that returns char without using the objects vtable to look up the method.
13720    /// This means that should the object be a subclass of the class that the method is declared in
13721    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13722    ///
13723    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13724    ///
13725    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13726    ///
13727    ///
13728    /// # Arguments
13729    /// * `obj` - which object the method should be called on
13730    ///     * must be valid
13731    ///     * must not be null
13732    ///     * must not be already garbage collected
13733    /// * `methodID` - method id of the method
13734    ///     * must not be null
13735    ///     * must be valid
13736    ///     * must not be a static
13737    ///     * must actually be a method of `obj`
13738    ///     * must refer to a method with 3 arguments
13739    ///
13740    /// # Returns
13741    /// Whatever the method returned or 0 if it threw
13742    ///
13743    /// # Throws Java Exception
13744    /// * Whatever the method threw
13745    ///
13746    ///
13747    /// # Panics
13748    /// if asserts feature is enabled and UB was detected
13749    ///
13750    /// # Safety
13751    ///
13752    /// Current thread must not be detached from JNI.
13753    ///
13754    /// Current thread must not be currently throwing an exception.
13755    ///
13756    /// Current thread does not hold a critical reference.
13757    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13758    ///
13759    /// `obj` must a valid and not already garbage collected.
13760    /// `methodID` must be valid, non-static and actually be a method of `obj`, return char and have 3 arguments
13761    ///
13762    pub unsafe fn CallNonvirtualCharMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jchar {
13763        unsafe {
13764            #[cfg(feature = "asserts")]
13765            {
13766                self.check_not_critical("CallNonvirtualCharMethod");
13767                self.check_no_exception("CallNonvirtualCharMethod");
13768                self.check_return_type_object("CallNonvirtualCharMethod", obj, methodID, "char");
13769                self.check_is_class("CallNonvirtualCharMethod", class);
13770                self.check_parameter_types_object("CallNonvirtualCharMethod", obj, methodID, arg1, 0, 3);
13771                self.check_parameter_types_object("CallNonvirtualCharMethod", obj, methodID, arg2, 1, 3);
13772                self.check_parameter_types_object("CallNonvirtualCharMethod", obj, methodID, arg3, 2, 3);
13773            }
13774            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jchar>(73)(self.vtable, obj, class, methodID, arg1, arg2, arg3)
13775        }
13776    }
13777
13778    ///
13779    /// Calls a non-static java method with 3 arguments that returns short without using the objects vtable to look up the method.
13780    /// This means that should the object be a subclass of the class that the method is declared in
13781    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13782    ///
13783    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13784    ///
13785    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13786    ///
13787    ///
13788    /// # Arguments
13789    /// * `obj` - which object the method should be called on
13790    ///     * must be valid
13791    ///     * must not be null
13792    ///     * must not be already garbage collected
13793    /// * `methodID` - method id of the method
13794    ///     * must not be null
13795    ///     * must be valid
13796    ///     * must not be a static
13797    ///     * must actually be a method of `obj`
13798    /// * `args` - argument pointer
13799    ///     * can be null if the method has no arguments
13800    ///     * must not be null otherwise and point to the exact number of arguments the method expects
13801    ///
13802    /// # Returns
13803    /// Whatever the method returned or 0 if it threw
13804    ///
13805    /// # Throws Java Exception
13806    /// * Whatever the method threw
13807    ///
13808    ///
13809    /// # Panics
13810    /// if asserts feature is enabled and UB was detected
13811    ///
13812    /// # Safety
13813    ///
13814    /// Current thread must not be detached from JNI.
13815    ///
13816    /// Current thread must not be currently throwing an exception.
13817    ///
13818    /// Current thread does not hold a critical reference.
13819    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13820    ///
13821    /// `obj` must a valid and not already garbage collected.
13822    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a short
13823    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
13824    /// `args` union must contain types that match the java methods parameters.
13825    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
13826    ///
13827    pub unsafe fn CallNonvirtualShortMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) -> jshort {
13828        unsafe {
13829            #[cfg(feature = "asserts")]
13830            {
13831                self.check_not_critical("CallNonvirtualShortMethodA");
13832                self.check_no_exception("CallNonvirtualShortMethodA");
13833                self.check_return_type_object("CallNonvirtualShortMethodA", obj, methodID, "short");
13834                self.check_is_class("CallNonvirtualShortMethodA", class);
13835            }
13836            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype) -> jshort>(78)(self.vtable, obj, class, methodID, args)
13837        }
13838    }
13839
13840    ///
13841    /// Calls a non-static java method with 0 arguments that returns short without using the objects vtable to look up the method.
13842    /// This means that should the object be a subclass of the class that the method is declared in
13843    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13844    ///
13845    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13846    ///
13847    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13848    ///
13849    ///
13850    /// # Arguments
13851    /// * `obj` - which object the method should be called on
13852    ///     * must be valid
13853    ///     * must not be null
13854    ///     * must not be already garbage collected
13855    /// * `methodID` - method id of the method
13856    ///     * must not be null
13857    ///     * must be valid
13858    ///     * must not be a static
13859    ///     * must actually be a method of `obj`
13860    ///     * must refer to a method with 0 arguments
13861    ///
13862    /// # Returns
13863    /// Whatever the method returned or 0 if it threw
13864    ///
13865    /// # Throws Java Exception
13866    /// * Whatever the method threw
13867    ///
13868    ///
13869    /// # Panics
13870    /// if asserts feature is enabled and UB was detected
13871    ///
13872    /// # Safety
13873    ///
13874    /// Current thread must not be detached from JNI.
13875    ///
13876    /// Current thread must not be currently throwing an exception.
13877    ///
13878    /// Current thread does not hold a critical reference.
13879    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13880    ///
13881    /// `obj` must a valid and not already garbage collected.
13882    /// `methodID` must be valid, non-static and actually be a method of `obj`, return short and have 0 arguments
13883    ///
13884    pub unsafe fn CallNonvirtualShortMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) -> jshort {
13885        unsafe {
13886            #[cfg(feature = "asserts")]
13887            {
13888                self.check_not_critical("CallNonvirtualShortMethod");
13889                self.check_no_exception("CallNonvirtualShortMethod");
13890                self.check_return_type_object("CallNonvirtualShortMethod", obj, methodID, "short");
13891                self.check_is_class("CallNonvirtualShortMethod", class);
13892            }
13893            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID) -> jshort>(76)(self.vtable, obj, class, methodID)
13894        }
13895    }
13896
13897    ///
13898    /// Calls a non-static java method with 1 arguments that returns short without using the objects vtable to look up the method.
13899    /// This means that should the object be a subclass of the class that the method is declared in
13900    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13901    ///
13902    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13903    ///
13904    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13905    ///
13906    ///
13907    /// # Arguments
13908    /// * `obj` - which object the method should be called on
13909    ///     * must be valid
13910    ///     * must not be null
13911    ///     * must not be already garbage collected
13912    /// * `methodID` - method id of the method
13913    ///     * must not be null
13914    ///     * must be valid
13915    ///     * must not be a static
13916    ///     * must actually be a method of `obj`
13917    ///     * must refer to a method with 1 arguments
13918    ///
13919    /// # Returns
13920    /// Whatever the method returned or 0 if it threw
13921    ///
13922    /// # Throws Java Exception
13923    /// * Whatever the method threw
13924    ///
13925    ///
13926    /// # Panics
13927    /// if asserts feature is enabled and UB was detected
13928    ///
13929    /// # Safety
13930    ///
13931    /// Current thread must not be detached from JNI.
13932    ///
13933    /// Current thread must not be currently throwing an exception.
13934    ///
13935    /// Current thread does not hold a critical reference.
13936    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13937    ///
13938    /// `obj` must a valid and not already garbage collected.
13939    /// `methodID` must be valid, non-static and actually be a method of `obj`, return short and have 1 arguments
13940    ///
13941    pub unsafe fn CallNonvirtualShortMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) -> jshort {
13942        unsafe {
13943            #[cfg(feature = "asserts")]
13944            {
13945                self.check_not_critical("CallNonvirtualShortMethod");
13946                self.check_no_exception("CallNonvirtualShortMethod");
13947                self.check_return_type_object("CallNonvirtualShortMethod", obj, methodID, "short");
13948                self.check_is_class("CallNonvirtualShortMethod", class);
13949                self.check_parameter_types_object("CallNonvirtualShortMethod", obj, methodID, arg1, 0, 1);
13950            }
13951            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jshort>(76)(self.vtable, obj, class, methodID, arg1)
13952        }
13953    }
13954
13955    ///
13956    /// Calls a non-static java method with 2 arguments that returns short without using the objects vtable to look up the method.
13957    /// This means that should the object be a subclass of the class that the method is declared in
13958    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13959    ///
13960    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13961    ///
13962    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13963    ///
13964    ///
13965    /// # Arguments
13966    /// * `obj` - which object the method should be called on
13967    ///     * must be valid
13968    ///     * must not be null
13969    ///     * must not be already garbage collected
13970    /// * `methodID` - method id of the method
13971    ///     * must not be null
13972    ///     * must be valid
13973    ///     * must not be a static
13974    ///     * must actually be a method of `obj`
13975    ///     * must refer to a method with 2 arguments
13976    ///
13977    /// # Returns
13978    /// Whatever the method returned or 0 if it threw
13979    ///
13980    /// # Throws Java Exception
13981    /// * Whatever the method threw
13982    ///
13983    ///
13984    /// # Panics
13985    /// if asserts feature is enabled and UB was detected
13986    ///
13987    /// # Safety
13988    ///
13989    /// Current thread must not be detached from JNI.
13990    ///
13991    /// Current thread must not be currently throwing an exception.
13992    ///
13993    /// Current thread does not hold a critical reference.
13994    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13995    ///
13996    /// `obj` must a valid and not already garbage collected.
13997    /// `methodID` must be valid, non-static and actually be a method of `obj`, return short and have 2 arguments
13998    ///
13999    pub unsafe fn CallNonvirtualShortMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jshort {
14000        unsafe {
14001            #[cfg(feature = "asserts")]
14002            {
14003                self.check_not_critical("CallNonvirtualShortMethod");
14004                self.check_no_exception("CallNonvirtualShortMethod");
14005                self.check_return_type_object("CallNonvirtualShortMethod", obj, methodID, "short");
14006                self.check_is_class("CallNonvirtualShortMethod", class);
14007                self.check_parameter_types_object("CallNonvirtualShortMethod", obj, methodID, arg1, 0, 2);
14008                self.check_parameter_types_object("CallNonvirtualShortMethod", obj, methodID, arg2, 1, 2);
14009            }
14010            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jshort>(76)(self.vtable, obj, class, methodID, arg1, arg2)
14011        }
14012    }
14013
14014    ///
14015    /// Calls a non-static java method with 3 arguments that returns short without using the objects vtable to look up the method.
14016    /// This means that should the object be a subclass of the class that the method is declared in
14017    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14018    ///
14019    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14020    ///
14021    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14022    ///
14023    ///
14024    /// # Arguments
14025    /// * `obj` - which object the method should be called on
14026    ///     * must be valid
14027    ///     * must not be null
14028    ///     * must not be already garbage collected
14029    /// * `methodID` - method id of the method
14030    ///     * must not be null
14031    ///     * must be valid
14032    ///     * must not be a static
14033    ///     * must actually be a method of `obj`
14034    ///     * must refer to a method with 3 arguments
14035    ///
14036    /// # Returns
14037    /// Whatever the method returned or 0 if it threw
14038    ///
14039    /// # Throws Java Exception
14040    /// * Whatever the method threw
14041    ///
14042    ///
14043    /// # Panics
14044    /// if asserts feature is enabled and UB was detected
14045    ///
14046    /// # Safety
14047    ///
14048    /// Current thread must not be detached from JNI.
14049    ///
14050    /// Current thread must not be currently throwing an exception.
14051    ///
14052    /// Current thread does not hold a critical reference.
14053    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14054    ///
14055    /// `obj` must a valid and not already garbage collected.
14056    /// `methodID` must be valid, non-static and actually be a method of `obj`, return short and have 3 arguments
14057    ///
14058    pub unsafe fn CallNonvirtualShortMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jshort {
14059        unsafe {
14060            #[cfg(feature = "asserts")]
14061            {
14062                self.check_not_critical("CallNonvirtualShortMethod");
14063                self.check_no_exception("CallNonvirtualShortMethod");
14064                self.check_return_type_object("CallNonvirtualShortMethod", obj, methodID, "short");
14065                self.check_is_class("CallNonvirtualShortMethod", class);
14066                self.check_parameter_types_object("CallNonvirtualShortMethod", obj, methodID, arg1, 0, 3);
14067                self.check_parameter_types_object("CallNonvirtualShortMethod", obj, methodID, arg2, 1, 3);
14068                self.check_parameter_types_object("CallNonvirtualShortMethod", obj, methodID, arg3, 2, 3);
14069            }
14070            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jshort>(76)(self.vtable, obj, class, methodID, arg1, arg2, arg3)
14071        }
14072    }
14073
14074    ///
14075    /// Calls a non-static java method with 3 arguments that returns int without using the objects vtable to look up the method.
14076    /// This means that should the object be a subclass of the class that the method is declared in
14077    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14078    ///
14079    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14080    ///
14081    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14082    ///
14083    ///
14084    /// # Arguments
14085    /// * `obj` - which object the method should be called on
14086    ///     * must be valid
14087    ///     * must not be null
14088    ///     * must not be already garbage collected
14089    /// * `methodID` - method id of the method
14090    ///     * must not be null
14091    ///     * must be valid
14092    ///     * must not be a static
14093    ///     * must actually be a method of `obj`
14094    /// * `args` - argument pointer
14095    ///     * can be null if the method has no arguments
14096    ///     * must not be null otherwise and point to the exact number of arguments the method expects
14097    ///
14098    /// # Returns
14099    /// Whatever the method returned or 0 if it threw
14100    ///
14101    /// # Throws Java Exception
14102    /// * Whatever the method threw
14103    ///
14104    ///
14105    /// # Panics
14106    /// if asserts feature is enabled and UB was detected
14107    ///
14108    /// # Safety
14109    ///
14110    /// Current thread must not be detached from JNI.
14111    ///
14112    /// Current thread must not be currently throwing an exception.
14113    ///
14114    /// Current thread does not hold a critical reference.
14115    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14116    ///
14117    /// `obj` must a valid and not already garbage collected.
14118    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a int
14119    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
14120    /// `args` union must contain types that match the java methods parameters.
14121    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
14122    ///
14123    pub unsafe fn CallNonvirtualIntMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) -> jint {
14124        unsafe {
14125            #[cfg(feature = "asserts")]
14126            {
14127                self.check_not_critical("CallNonvirtualIntMethodA");
14128                self.check_no_exception("CallNonvirtualIntMethodA");
14129                self.check_return_type_object("CallNonvirtualIntMethodA", obj, methodID, "int");
14130                self.check_is_class("CallNonvirtualIntMethodA", class);
14131            }
14132            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype) -> jint>(81)(self.vtable, obj, class, methodID, args)
14133        }
14134    }
14135
14136    ///
14137    /// Calls a non-static java method with 0 arguments that returns short without using the objects vtable to look up the method.
14138    /// This means that should the object be a subclass of the class that the method is declared in
14139    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14140    ///
14141    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14142    ///
14143    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14144    ///
14145    ///
14146    /// # Arguments
14147    /// * `obj` - which object the method should be called on
14148    ///     * must be valid
14149    ///     * must not be null
14150    ///     * must not be already garbage collected
14151    /// * `methodID` - method id of the method
14152    ///     * must not be null
14153    ///     * must be valid
14154    ///     * must not be a static
14155    ///     * must actually be a method of `obj`
14156    ///     * must refer to a method with 0 arguments
14157    ///
14158    /// # Returns
14159    /// Whatever the method returned or 0 if it threw
14160    ///
14161    /// # Throws Java Exception
14162    /// * Whatever the method threw
14163    ///
14164    ///
14165    /// # Panics
14166    /// if asserts feature is enabled and UB was detected
14167    ///
14168    /// # Safety
14169    ///
14170    /// Current thread must not be detached from JNI.
14171    ///
14172    /// Current thread must not be currently throwing an exception.
14173    ///
14174    /// Current thread does not hold a critical reference.
14175    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14176    ///
14177    /// `obj` must a valid and not already garbage collected.
14178    /// `methodID` must be valid, non-static and actually be a method of `obj`, return int and have 0 arguments
14179    ///
14180    pub unsafe fn CallNonvirtualIntMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) -> jint {
14181        unsafe {
14182            #[cfg(feature = "asserts")]
14183            {
14184                self.check_not_critical("CallNonvirtualIntMethod");
14185                self.check_no_exception("CallNonvirtualIntMethod");
14186                self.check_return_type_object("CallNonvirtualIntMethod", obj, methodID, "int");
14187                self.check_is_class("CallNonvirtualIntMethod", class);
14188            }
14189            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID) -> jint>(79)(self.vtable, obj, class, methodID)
14190        }
14191    }
14192
14193    ///
14194    /// Calls a non-static java method with 1 arguments that returns int without using the objects vtable to look up the method.
14195    /// This means that should the object be a subclass of the class that the method is declared in
14196    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14197    ///
14198    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14199    ///
14200    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14201    ///
14202    ///
14203    /// # Arguments
14204    /// * `obj` - which object the method should be called on
14205    ///     * must be valid
14206    ///     * must not be null
14207    ///     * must not be already garbage collected
14208    /// * `methodID` - method id of the method
14209    ///     * must not be null
14210    ///     * must be valid
14211    ///     * must not be a static
14212    ///     * must actually be a method of `obj`
14213    ///     * must refer to a method with 1 arguments
14214    ///
14215    /// # Returns
14216    /// Whatever the method returned or 0 if it threw
14217    ///
14218    /// # Throws Java Exception
14219    /// * Whatever the method threw
14220    ///
14221    ///
14222    /// # Panics
14223    /// if asserts feature is enabled and UB was detected
14224    ///
14225    /// # Safety
14226    ///
14227    /// Current thread must not be detached from JNI.
14228    ///
14229    /// Current thread must not be currently throwing an exception.
14230    ///
14231    /// Current thread does not hold a critical reference.
14232    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14233    ///
14234    /// `obj` must a valid and not already garbage collected.
14235    /// `methodID` must be valid, non-static and actually be a method of `obj`, return int and have 1 arguments
14236    ///
14237    pub unsafe fn CallNonvirtualIntMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) -> jint {
14238        unsafe {
14239            #[cfg(feature = "asserts")]
14240            {
14241                self.check_not_critical("CallNonvirtualIntMethod");
14242                self.check_no_exception("CallNonvirtualIntMethod");
14243                self.check_return_type_object("CallNonvirtualIntMethod", obj, methodID, "int");
14244                self.check_is_class("CallNonvirtualIntMethod", class);
14245                self.check_parameter_types_object("CallNonvirtualIntMethod", obj, methodID, arg1, 0, 1);
14246            }
14247            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jint>(79)(self.vtable, obj, class, methodID, arg1)
14248        }
14249    }
14250
14251    ///
14252    /// Calls a non-static java method with 2 arguments that returns int without using the objects vtable to look up the method.
14253    /// This means that should the object be a subclass of the class that the method is declared in
14254    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14255    ///
14256    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14257    ///
14258    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14259    ///
14260    ///
14261    /// # Arguments
14262    /// * `obj` - which object the method should be called on
14263    ///     * must be valid
14264    ///     * must not be null
14265    ///     * must not be already garbage collected
14266    /// * `methodID` - method id of the method
14267    ///     * must not be null
14268    ///     * must be valid
14269    ///     * must not be a static
14270    ///     * must actually be a method of `obj`
14271    ///     * must refer to a method with 2 arguments
14272    ///
14273    /// # Returns
14274    /// Whatever the method returned or 0 if it threw
14275    ///
14276    /// # Throws Java Exception
14277    /// * Whatever the method threw
14278    ///
14279    ///
14280    /// # Panics
14281    /// if asserts feature is enabled and UB was detected
14282    ///
14283    /// # Safety
14284    ///
14285    /// Current thread must not be detached from JNI.
14286    ///
14287    /// Current thread must not be currently throwing an exception.
14288    ///
14289    /// Current thread does not hold a critical reference.
14290    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14291    ///
14292    /// `obj` must a valid and not already garbage collected.
14293    /// `methodID` must be valid, non-static and actually be a method of `obj`, return int and have 2 arguments
14294    ///
14295    pub unsafe fn CallNonvirtualIntMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jint {
14296        unsafe {
14297            #[cfg(feature = "asserts")]
14298            {
14299                self.check_not_critical("CallNonvirtualIntMethod");
14300                self.check_no_exception("CallNonvirtualIntMethod");
14301                self.check_return_type_object("CallNonvirtualIntMethod", obj, methodID, "int");
14302                self.check_is_class("CallNonvirtualIntMethod", class);
14303                self.check_parameter_types_object("CallNonvirtualIntMethod", obj, methodID, arg1, 0, 2);
14304                self.check_parameter_types_object("CallNonvirtualIntMethod", obj, methodID, arg2, 1, 2);
14305            }
14306            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jint>(79)(self.vtable, obj, class, methodID, arg1, arg2)
14307        }
14308    }
14309
14310    ///
14311    /// Calls a non-static java method with 3 arguments that returns int without using the objects vtable to look up the method.
14312    /// This means that should the object be a subclass of the class that the method is declared in
14313    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14314    ///
14315    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14316    ///
14317    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14318    ///
14319    ///
14320    /// # Arguments
14321    /// * `obj` - which object the method should be called on
14322    ///     * must be valid
14323    ///     * must not be null
14324    ///     * must not be already garbage collected
14325    /// * `methodID` - method id of the method
14326    ///     * must not be null
14327    ///     * must be valid
14328    ///     * must not be a static
14329    ///     * must actually be a method of `obj`
14330    ///     * must refer to a method with 3 arguments
14331    ///
14332    /// # Returns
14333    /// Whatever the method returned or 0 if it threw
14334    ///
14335    /// # Throws Java Exception
14336    /// * Whatever the method threw
14337    ///
14338    ///
14339    /// # Panics
14340    /// if asserts feature is enabled and UB was detected
14341    ///
14342    /// # Safety
14343    ///
14344    /// Current thread must not be detached from JNI.
14345    ///
14346    /// Current thread must not be currently throwing an exception.
14347    ///
14348    /// Current thread does not hold a critical reference.
14349    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14350    ///
14351    /// `obj` must a valid and not already garbage collected.
14352    /// `methodID` must be valid, non-static and actually be a method of `obj`, return int and have 3 arguments
14353    ///
14354    pub unsafe fn CallNonvirtualIntMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jint {
14355        unsafe {
14356            #[cfg(feature = "asserts")]
14357            {
14358                self.check_not_critical("CallNonvirtualIntMethod");
14359                self.check_no_exception("CallNonvirtualIntMethod");
14360                self.check_return_type_object("CallNonvirtualIntMethod", obj, methodID, "int");
14361                self.check_is_class("CallNonvirtualIntMethod", class);
14362                self.check_parameter_types_object("CallNonvirtualIntMethod", obj, methodID, arg1, 0, 3);
14363                self.check_parameter_types_object("CallNonvirtualIntMethod", obj, methodID, arg2, 1, 3);
14364                self.check_parameter_types_object("CallNonvirtualIntMethod", obj, methodID, arg3, 2, 3);
14365            }
14366            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jint>(79)(self.vtable, obj, class, methodID, arg1, arg2, arg3)
14367        }
14368    }
14369
14370    ///
14371    /// Calls a non-static java method with 3 arguments that returns long without using the objects vtable to look up the method.
14372    /// This means that should the object be a subclass of the class that the method is declared in
14373    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14374    ///
14375    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14376    ///
14377    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14378    ///
14379    ///
14380    /// # Arguments
14381    /// * `obj` - which object the method should be called on
14382    ///     * must be valid
14383    ///     * must not be null
14384    ///     * must not be already garbage collected
14385    /// * `methodID` - method id of the method
14386    ///     * must not be null
14387    ///     * must be valid
14388    ///     * must not be a static
14389    ///     * must actually be a method of `obj`
14390    /// * `args` - argument pointer
14391    ///     * can be null if the method has no arguments
14392    ///     * must not be null otherwise and point to the exact number of arguments the method expects
14393    ///
14394    /// # Returns
14395    /// Whatever the method returned or 0 if it threw
14396    ///
14397    /// # Throws Java Exception
14398    /// * Whatever the method threw
14399    ///
14400    ///
14401    /// # Panics
14402    /// if asserts feature is enabled and UB was detected
14403    ///
14404    /// # Safety
14405    ///
14406    /// Current thread must not be detached from JNI.
14407    ///
14408    /// Current thread must not be currently throwing an exception.
14409    ///
14410    /// Current thread does not hold a critical reference.
14411    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14412    ///
14413    /// `obj` must a valid and not already garbage collected.
14414    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a long
14415    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
14416    /// `args` union must contain types that match the java methods parameters.
14417    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
14418    ///
14419    pub unsafe fn CallNonvirtualLongMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) -> jlong {
14420        unsafe {
14421            #[cfg(feature = "asserts")]
14422            {
14423                self.check_not_critical("CallNonvirtualLongMethodA");
14424                self.check_no_exception("CallNonvirtualLongMethodA");
14425                self.check_return_type_object("CallNonvirtualLongMethodA", obj, methodID, "long");
14426                self.check_is_class("CallNonvirtualLongMethodA", class);
14427            }
14428            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype) -> jlong>(84)(self.vtable, obj, class, methodID, args)
14429        }
14430    }
14431
14432    ///
14433    /// Calls a non-static java method with 0 arguments that returns long without using the objects vtable to look up the method.
14434    /// This means that should the object be a subclass of the class that the method is declared in
14435    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14436    ///
14437    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14438    ///
14439    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14440    ///
14441    ///
14442    /// # Arguments
14443    /// * `obj` - which object the method should be called on
14444    ///     * must be valid
14445    ///     * must not be null
14446    ///     * must not be already garbage collected
14447    /// * `methodID` - method id of the method
14448    ///     * must not be null
14449    ///     * must be valid
14450    ///     * must not be a static
14451    ///     * must actually be a method of `obj`
14452    ///     * must refer to a method with 0 arguments
14453    ///
14454    /// # Returns
14455    /// Whatever the method returned or 0 if it threw
14456    ///
14457    /// # Throws Java Exception
14458    /// * Whatever the method threw
14459    ///
14460    ///
14461    /// # Panics
14462    /// if asserts feature is enabled and UB was detected
14463    ///
14464    /// # Safety
14465    ///
14466    /// Current thread must not be detached from JNI.
14467    ///
14468    /// Current thread must not be currently throwing an exception.
14469    ///
14470    /// Current thread does not hold a critical reference.
14471    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14472    ///
14473    /// `obj` must a valid and not already garbage collected.
14474    /// `methodID` must be valid, non-static and actually be a method of `obj`, return long and have 0 arguments
14475    ///
14476    pub unsafe fn CallNonvirtualLongMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) -> jlong {
14477        unsafe {
14478            #[cfg(feature = "asserts")]
14479            {
14480                self.check_not_critical("CallNonvirtualLongMethod");
14481                self.check_no_exception("CallNonvirtualLongMethod");
14482                self.check_return_type_object("CallNonvirtualLongMethod", obj, methodID, "long");
14483                self.check_is_class("CallNonvirtualLongMethod", class);
14484            }
14485            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID) -> jlong>(82)(self.vtable, obj, class, methodID)
14486        }
14487    }
14488
14489    ///
14490    /// Calls a non-static java method with 1 arguments that returns long without using the objects vtable to look up the method.
14491    /// This means that should the object be a subclass of the class that the method is declared in
14492    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14493    ///
14494    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14495    ///
14496    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14497    ///
14498    ///
14499    /// # Arguments
14500    /// * `obj` - which object the method should be called on
14501    ///     * must be valid
14502    ///     * must not be null
14503    ///     * must not be already garbage collected
14504    /// * `methodID` - method id of the method
14505    ///     * must not be null
14506    ///     * must be valid
14507    ///     * must not be a static
14508    ///     * must actually be a method of `obj`
14509    ///     * must refer to a method with 1 arguments
14510    ///
14511    /// # Returns
14512    /// Whatever the method returned or 0 if it threw
14513    ///
14514    /// # Throws Java Exception
14515    /// * Whatever the method threw
14516    ///
14517    ///
14518    /// # Panics
14519    /// if asserts feature is enabled and UB was detected
14520    ///
14521    /// # Safety
14522    ///
14523    /// Current thread must not be detached from JNI.
14524    ///
14525    /// Current thread must not be currently throwing an exception.
14526    ///
14527    /// Current thread does not hold a critical reference.
14528    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14529    ///
14530    /// `obj` must a valid and not already garbage collected.
14531    /// `methodID` must be valid, non-static and actually be a method of `obj`, return long and have 1 arguments
14532    ///
14533    pub unsafe fn CallNonvirtualLongMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) -> jlong {
14534        unsafe {
14535            #[cfg(feature = "asserts")]
14536            {
14537                self.check_not_critical("CallNonvirtualLongMethod");
14538                self.check_no_exception("CallNonvirtualLongMethod");
14539                self.check_return_type_object("CallNonvirtualLongMethod", obj, methodID, "long");
14540                self.check_is_class("CallNonvirtualLongMethod", class);
14541                self.check_parameter_types_object("CallNonvirtualLongMethod", obj, methodID, arg1, 0, 1);
14542            }
14543            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jlong>(82)(self.vtable, obj, class, methodID, arg1)
14544        }
14545    }
14546
14547    ///
14548    /// Calls a non-static java method with 2 arguments that returns long without using the objects vtable to look up the method.
14549    /// This means that should the object be a subclass of the class that the method is declared in
14550    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14551    ///
14552    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14553    ///
14554    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14555    ///
14556    ///
14557    /// # Arguments
14558    /// * `obj` - which object the method should be called on
14559    ///     * must be valid
14560    ///     * must not be null
14561    ///     * must not be already garbage collected
14562    /// * `methodID` - method id of the method
14563    ///     * must not be null
14564    ///     * must be valid
14565    ///     * must not be a static
14566    ///     * must actually be a method of `obj`
14567    ///     * must refer to a method with 2 arguments
14568    ///
14569    /// # Returns
14570    /// Whatever the method returned or 0 if it threw
14571    ///
14572    /// # Throws Java Exception
14573    /// * Whatever the method threw
14574    ///
14575    ///
14576    /// # Panics
14577    /// if asserts feature is enabled and UB was detected
14578    ///
14579    /// # Safety
14580    ///
14581    /// Current thread must not be detached from JNI.
14582    ///
14583    /// Current thread must not be currently throwing an exception.
14584    ///
14585    /// Current thread does not hold a critical reference.
14586    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14587    ///
14588    /// `obj` must a valid and not already garbage collected.
14589    /// `methodID` must be valid, non-static and actually be a method of `obj`, return long and have 2 arguments
14590    ///
14591    pub unsafe fn CallNonvirtualLongMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jlong {
14592        unsafe {
14593            #[cfg(feature = "asserts")]
14594            {
14595                self.check_not_critical("CallNonvirtualLongMethod");
14596                self.check_no_exception("CallNonvirtualLongMethod");
14597                self.check_return_type_object("CallNonvirtualLongMethod", obj, methodID, "long");
14598                self.check_is_class("CallNonvirtualLongMethod", class);
14599                self.check_parameter_types_object("CallNonvirtualLongMethod", obj, methodID, arg1, 0, 2);
14600                self.check_parameter_types_object("CallNonvirtualLongMethod", obj, methodID, arg2, 1, 2);
14601            }
14602            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jlong>(82)(self.vtable, obj, class, methodID, arg1, arg2)
14603        }
14604    }
14605
14606    ///
14607    /// Calls a non-static java method with 3 arguments that returns long without using the objects vtable to look up the method.
14608    /// This means that should the object be a subclass of the class that the method is declared in
14609    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14610    ///
14611    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14612    ///
14613    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14614    ///
14615    ///
14616    /// # Arguments
14617    /// * `obj` - which object the method should be called on
14618    ///     * must be valid
14619    ///     * must not be null
14620    ///     * must not be already garbage collected
14621    /// * `methodID` - method id of the method
14622    ///     * must not be null
14623    ///     * must be valid
14624    ///     * must not be a static
14625    ///     * must actually be a method of `obj`
14626    ///     * must refer to a method with 3 arguments
14627    ///
14628    /// # Returns
14629    /// Whatever the method returned or 0 if it threw
14630    ///
14631    /// # Throws Java Exception
14632    /// * Whatever the method threw
14633    ///
14634    ///
14635    /// # Panics
14636    /// if asserts feature is enabled and UB was detected
14637    ///
14638    /// # Safety
14639    ///
14640    /// Current thread must not be detached from JNI.
14641    ///
14642    /// Current thread must not be currently throwing an exception.
14643    ///
14644    /// Current thread does not hold a critical reference.
14645    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14646    ///
14647    /// `obj` must a valid and not already garbage collected.
14648    /// `methodID` must be valid, non-static and actually be a method of `obj`, return long and have 3 arguments
14649    ///
14650    pub unsafe fn CallNonvirtualLongMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jlong {
14651        unsafe {
14652            #[cfg(feature = "asserts")]
14653            {
14654                self.check_not_critical("CallNonvirtualLongMethod");
14655                self.check_no_exception("CallNonvirtualLongMethod");
14656                self.check_return_type_object("CallNonvirtualLongMethod", obj, methodID, "long");
14657                self.check_is_class("CallNonvirtualLongMethod", class);
14658                self.check_parameter_types_object("CallNonvirtualLongMethod", obj, methodID, arg1, 0, 3);
14659                self.check_parameter_types_object("CallNonvirtualLongMethod", obj, methodID, arg2, 1, 3);
14660                self.check_parameter_types_object("CallNonvirtualLongMethod", obj, methodID, arg3, 2, 3);
14661            }
14662            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jlong>(82)(self.vtable, obj, class, methodID, arg1, arg2, arg3)
14663        }
14664    }
14665
14666    ///
14667    /// Calls a non-static java method with 3 arguments that returns float without using the objects vtable to look up the method.
14668    /// This means that should the object be a subclass of the class that the method is declared in
14669    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14670    ///
14671    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14672    ///
14673    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14674    ///
14675    ///
14676    /// # Arguments
14677    /// * `obj` - which object the method should be called on
14678    ///     * must be valid
14679    ///     * must not be null
14680    ///     * must not be already garbage collected
14681    /// * `methodID` - method id of the method
14682    ///     * must not be null
14683    ///     * must be valid
14684    ///     * must not be a static
14685    ///     * must actually be a method of `obj`
14686    /// * `args` - argument pointer
14687    ///     * can be null if the method has no arguments
14688    ///     * must not be null otherwise and point to the exact number of arguments the method expects
14689    ///
14690    /// # Returns
14691    /// Whatever the method returned or 0 if it threw
14692    ///
14693    /// # Throws Java Exception
14694    /// * Whatever the method threw
14695    ///
14696    ///
14697    /// # Panics
14698    /// if asserts feature is enabled and UB was detected
14699    ///
14700    /// # Safety
14701    ///
14702    /// Current thread must not be detached from JNI.
14703    ///
14704    /// Current thread must not be currently throwing an exception.
14705    ///
14706    /// Current thread does not hold a critical reference.
14707    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14708    ///
14709    /// `obj` must a valid and not already garbage collected.
14710    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a float
14711    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
14712    /// `args` union must contain types that match the java methods parameters.
14713    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
14714    ///
14715    pub unsafe fn CallNonvirtualFloatMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) -> jfloat {
14716        unsafe {
14717            #[cfg(feature = "asserts")]
14718            {
14719                self.check_not_critical("CallNonvirtualFloatMethodA");
14720                self.check_no_exception("CallNonvirtualFloatMethodA");
14721                self.check_return_type_object("CallNonvirtualFloatMethodA", obj, methodID, "float");
14722                self.check_is_class("CallNonvirtualFloatMethodA", class);
14723            }
14724            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype) -> jfloat>(87)(self.vtable, obj, class, methodID, args)
14725        }
14726    }
14727
14728    ///
14729    /// Calls a non-static java method with 0 arguments that returns float without using the objects vtable to look up the method.
14730    /// This means that should the object be a subclass of the class that the method is declared in
14731    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14732    ///
14733    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14734    ///
14735    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14736    ///
14737    ///
14738    /// # Arguments
14739    /// * `obj` - which object the method should be called on
14740    ///     * must be valid
14741    ///     * must not be null
14742    ///     * must not be already garbage collected
14743    /// * `methodID` - method id of the method
14744    ///     * must not be null
14745    ///     * must be valid
14746    ///     * must not be a static
14747    ///     * must actually be a method of `obj`
14748    ///     * must refer to a method with 0 arguments
14749    ///
14750    /// # Returns
14751    /// Whatever the method returned or 0 if it threw
14752    ///
14753    /// # Throws Java Exception
14754    /// * Whatever the method threw
14755    ///
14756    ///
14757    /// # Panics
14758    /// if asserts feature is enabled and UB was detected
14759    ///
14760    /// # Safety
14761    ///
14762    /// Current thread must not be detached from JNI.
14763    ///
14764    /// Current thread must not be currently throwing an exception.
14765    ///
14766    /// Current thread does not hold a critical reference.
14767    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14768    ///
14769    /// `obj` must a valid and not already garbage collected.
14770    /// `methodID` must be valid, non-static and actually be a method of `obj`, return float and have 0 arguments
14771    ///
14772    pub unsafe fn CallNonvirtualFloatMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) -> jfloat {
14773        unsafe {
14774            #[cfg(feature = "asserts")]
14775            {
14776                self.check_not_critical("CallNonvirtualFloatMethod");
14777                self.check_no_exception("CallNonvirtualFloatMethod");
14778                self.check_return_type_object("CallNonvirtualFloatMethod", obj, methodID, "float");
14779                self.check_is_class("CallNonvirtualFloatMethod", class);
14780            }
14781            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID) -> jfloat>(85)(self.vtable, obj, class, methodID)
14782        }
14783    }
14784
14785    ///
14786    /// Calls a non-static java method with 1 arguments that returns float without using the objects vtable to look up the method.
14787    /// This means that should the object be a subclass of the class that the method is declared in
14788    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14789    ///
14790    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14791    ///
14792    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14793    ///
14794    ///
14795    /// # Arguments
14796    /// * `obj` - which object the method should be called on
14797    ///     * must be valid
14798    ///     * must not be null
14799    ///     * must not be already garbage collected
14800    /// * `methodID` - method id of the method
14801    ///     * must not be null
14802    ///     * must be valid
14803    ///     * must not be a static
14804    ///     * must actually be a method of `obj`
14805    ///     * must refer to a method with 1 arguments
14806    ///
14807    /// # Returns
14808    /// Whatever the method returned or 0 if it threw
14809    ///
14810    /// # Throws Java Exception
14811    /// * Whatever the method threw
14812    ///
14813    ///
14814    /// # Panics
14815    /// if asserts feature is enabled and UB was detected
14816    ///
14817    /// # Safety
14818    ///
14819    /// Current thread must not be detached from JNI.
14820    ///
14821    /// Current thread must not be currently throwing an exception.
14822    ///
14823    /// Current thread does not hold a critical reference.
14824    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14825    ///
14826    /// `obj` must a valid and not already garbage collected.
14827    /// `methodID` must be valid, non-static and actually be a method of `obj`, return float and have 1 arguments
14828    ///
14829    pub unsafe fn CallNonvirtualFloatMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) -> jfloat {
14830        unsafe {
14831            #[cfg(feature = "asserts")]
14832            {
14833                self.check_not_critical("CallNonvirtualFloatMethod");
14834                self.check_no_exception("CallNonvirtualFloatMethod");
14835                self.check_return_type_object("CallNonvirtualFloatMethod", obj, methodID, "float");
14836                self.check_is_class("CallNonvirtualFloatMethod", class);
14837                self.check_parameter_types_object("CallNonvirtualFloatMethod", obj, methodID, arg1, 0, 1);
14838            }
14839            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jfloat>(85)(self.vtable, obj, class, methodID, arg1)
14840        }
14841    }
14842
14843    ///
14844    /// Calls a non-static java method with 2 arguments that returns float without using the objects vtable to look up the method.
14845    /// This means that should the object be a subclass of the class that the method is declared in
14846    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14847    ///
14848    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14849    ///
14850    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14851    ///
14852    ///
14853    /// # Arguments
14854    /// * `obj` - which object the method should be called on
14855    ///     * must be valid
14856    ///     * must not be null
14857    ///     * must not be already garbage collected
14858    /// * `methodID` - method id of the method
14859    ///     * must not be null
14860    ///     * must be valid
14861    ///     * must not be a static
14862    ///     * must actually be a method of `obj`
14863    ///     * must refer to a method with 2 arguments
14864    ///
14865    /// # Returns
14866    /// Whatever the method returned or 0 if it threw
14867    ///
14868    /// # Throws Java Exception
14869    /// * Whatever the method threw
14870    ///
14871    ///
14872    /// # Panics
14873    /// if asserts feature is enabled and UB was detected
14874    ///
14875    /// # Safety
14876    ///
14877    /// Current thread must not be detached from JNI.
14878    ///
14879    /// Current thread must not be currently throwing an exception.
14880    ///
14881    /// Current thread does not hold a critical reference.
14882    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14883    ///
14884    /// `obj` must a valid and not already garbage collected.
14885    /// `methodID` must be valid, non-static and actually be a method of `obj`, return float and have 2 arguments
14886    ///
14887    pub unsafe fn CallNonvirtualFloatMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jfloat {
14888        unsafe {
14889            #[cfg(feature = "asserts")]
14890            {
14891                self.check_not_critical("CallNonvirtualFloatMethod");
14892                self.check_no_exception("CallNonvirtualFloatMethod");
14893                self.check_return_type_object("CallNonvirtualFloatMethod", obj, methodID, "float");
14894                self.check_is_class("CallNonvirtualFloatMethod", class);
14895                self.check_parameter_types_object("CallNonvirtualFloatMethod", obj, methodID, arg1, 0, 2);
14896                self.check_parameter_types_object("CallNonvirtualFloatMethod", obj, methodID, arg2, 1, 2);
14897            }
14898            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jfloat>(85)(self.vtable, obj, class, methodID, arg1, arg2)
14899        }
14900    }
14901
14902    ///
14903    /// Calls a non-static java method with 3 arguments that returns float without using the objects vtable to look up the method.
14904    /// This means that should the object be a subclass of the class that the method is declared in
14905    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14906    ///
14907    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14908    ///
14909    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14910    ///
14911    ///
14912    /// # Arguments
14913    /// * `obj` - which object the method should be called on
14914    ///     * must be valid
14915    ///     * must not be null
14916    ///     * must not be already garbage collected
14917    /// * `methodID` - method id of the method
14918    ///     * must not be null
14919    ///     * must be valid
14920    ///     * must not be a static
14921    ///     * must actually be a method of `obj`
14922    ///     * must refer to a method with 3 arguments
14923    ///
14924    /// # Returns
14925    /// Whatever the method returned or 0 if it threw
14926    ///
14927    /// # Throws Java Exception
14928    /// * Whatever the method threw
14929    ///
14930    ///
14931    /// # Panics
14932    /// if asserts feature is enabled and UB was detected
14933    ///
14934    /// # Safety
14935    ///
14936    /// Current thread must not be detached from JNI.
14937    ///
14938    /// Current thread must not be currently throwing an exception.
14939    ///
14940    /// Current thread does not hold a critical reference.
14941    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14942    ///
14943    /// `obj` must a valid and not already garbage collected.
14944    /// `methodID` must be valid, non-static and actually be a method of `obj`, return float and have 3 arguments
14945    ///
14946    pub unsafe fn CallNonvirtualFloatMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jfloat {
14947        unsafe {
14948            #[cfg(feature = "asserts")]
14949            {
14950                self.check_not_critical("CallNonvirtualFloatMethod");
14951                self.check_no_exception("CallNonvirtualFloatMethod");
14952                self.check_return_type_object("CallNonvirtualFloatMethod", obj, methodID, "float");
14953                self.check_is_class("CallNonvirtualFloatMethod", class);
14954                self.check_parameter_types_object("CallNonvirtualFloatMethod", obj, methodID, arg1, 0, 3);
14955                self.check_parameter_types_object("CallNonvirtualFloatMethod", obj, methodID, arg2, 1, 3);
14956                self.check_parameter_types_object("CallNonvirtualFloatMethod", obj, methodID, arg3, 2, 3);
14957            }
14958            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jfloat>(85)(self.vtable, obj, class, methodID, arg1, arg2, arg3)
14959        }
14960    }
14961
14962    ///
14963    /// Calls a non-static java method with 3 arguments that returns double without using the objects vtable to look up the method.
14964    /// This means that should the object be a subclass of the class that the method is declared in
14965    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14966    ///
14967    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14968    ///
14969    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14970    ///
14971    ///
14972    /// # Arguments
14973    /// * `obj` - which object the method should be called on
14974    ///     * must be valid
14975    ///     * must not be null
14976    ///     * must not be already garbage collected
14977    /// * `methodID` - method id of the method
14978    ///     * must not be null
14979    ///     * must be valid
14980    ///     * must not be a static
14981    ///     * must actually be a method of `obj`
14982    /// * `args` - argument pointer
14983    ///     * can be null if the method has no arguments
14984    ///     * must not be null otherwise and point to the exact number of arguments the method expects
14985    ///
14986    /// # Returns
14987    /// Whatever the method returned or 0 if it threw
14988    ///
14989    /// # Throws Java Exception
14990    /// * Whatever the method threw
14991    ///
14992    ///
14993    /// # Panics
14994    /// if asserts feature is enabled and UB was detected
14995    ///
14996    /// # Safety
14997    ///
14998    /// Current thread must not be detached from JNI.
14999    ///
15000    /// Current thread must not be currently throwing an exception.
15001    ///
15002    /// Current thread does not hold a critical reference.
15003    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15004    ///
15005    /// `obj` must a valid and not already garbage collected.
15006    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a double
15007    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
15008    /// `args` union must contain types that match the java methods parameters.
15009    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
15010    ///
15011    pub unsafe fn CallNonvirtualDoubleMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) -> jdouble {
15012        unsafe {
15013            #[cfg(feature = "asserts")]
15014            {
15015                self.check_not_critical("CallNonvirtualDoubleMethodA");
15016                self.check_no_exception("CallNonvirtualDoubleMethodA");
15017                self.check_return_type_object("CallNonvirtualDoubleMethodA", obj, methodID, "double");
15018                self.check_is_class("CallNonvirtualDoubleMethodA", class);
15019            }
15020            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype) -> jdouble>(90)(self.vtable, obj, class, methodID, args)
15021        }
15022    }
15023
15024    ///
15025    /// Calls a non-static java method with 0 arguments that returns double without using the objects vtable to look up the method.
15026    /// This means that should the object be a subclass of the class that the method is declared in
15027    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
15028    ///
15029    /// This is roughly equivalent to calling "super.someMethod(...)" in java
15030    ///
15031    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
15032    ///
15033    ///
15034    /// # Arguments
15035    /// * `obj` - which object the method should be called on
15036    ///     * must be valid
15037    ///     * must not be null
15038    ///     * must not be already garbage collected
15039    /// * `methodID` - method id of the method
15040    ///     * must not be null
15041    ///     * must be valid
15042    ///     * must not be a static
15043    ///     * must actually be a method of `obj`
15044    ///     * must refer to a method with 0 arguments
15045    ///
15046    /// # Returns
15047    /// Whatever the method returned or 0 if it threw
15048    ///
15049    /// # Throws Java Exception
15050    /// * Whatever the method threw
15051    ///
15052    ///
15053    /// # Panics
15054    /// if asserts feature is enabled and UB was detected
15055    ///
15056    /// # Safety
15057    ///
15058    /// Current thread must not be detached from JNI.
15059    ///
15060    /// Current thread must not be currently throwing an exception.
15061    ///
15062    /// Current thread does not hold a critical reference.
15063    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15064    ///
15065    /// `obj` must a valid and not already garbage collected.
15066    /// `methodID` must be valid, non-static and actually be a method of `obj`, return double and have 0 arguments
15067    ///
15068    pub unsafe fn CallNonvirtualDoubleMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) -> jdouble {
15069        unsafe {
15070            #[cfg(feature = "asserts")]
15071            {
15072                self.check_not_critical("CallNonvirtualDoubleMethod");
15073                self.check_no_exception("CallNonvirtualDoubleMethod");
15074                self.check_return_type_object("CallNonvirtualDoubleMethod", obj, methodID, "double");
15075                self.check_is_class("CallNonvirtualDoubleMethod", class);
15076            }
15077            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID) -> jdouble>(88)(self.vtable, obj, class, methodID)
15078        }
15079    }
15080
15081    ///
15082    /// Calls a non-static java method with 1 arguments that returns double without using the objects vtable to look up the method.
15083    /// This means that should the object be a subclass of the class that the method is declared in
15084    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
15085    ///
15086    /// This is roughly equivalent to calling "super.someMethod(...)" in java
15087    ///
15088    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
15089    ///
15090    ///
15091    /// # Arguments
15092    /// * `obj` - which object the method should be called on
15093    ///     * must be valid
15094    ///     * must not be null
15095    ///     * must not be already garbage collected
15096    /// * `methodID` - method id of the method
15097    ///     * must not be null
15098    ///     * must be valid
15099    ///     * must not be a static
15100    ///     * must actually be a method of `obj`
15101    ///     * must refer to a method with 1 arguments
15102    ///
15103    /// # Returns
15104    /// Whatever the method returned or 0 if it threw
15105    ///
15106    /// # Throws Java Exception
15107    /// * Whatever the method threw
15108    ///
15109    ///
15110    /// # Panics
15111    /// if asserts feature is enabled and UB was detected
15112    ///
15113    /// # Safety
15114    ///
15115    /// Current thread must not be detached from JNI.
15116    ///
15117    /// Current thread must not be currently throwing an exception.
15118    ///
15119    /// Current thread does not hold a critical reference.
15120    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15121    ///
15122    /// `obj` must a valid and not already garbage collected.
15123    /// `methodID` must be valid, non-static and actually be a method of `obj`, return double and have 1 arguments
15124    ///
15125    pub unsafe fn CallNonvirtualDoubleMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) -> jdouble {
15126        unsafe {
15127            #[cfg(feature = "asserts")]
15128            {
15129                self.check_not_critical("CallNonvirtualDoubleMethod");
15130                self.check_no_exception("CallNonvirtualDoubleMethod");
15131                self.check_return_type_object("CallNonvirtualDoubleMethod", obj, methodID, "double");
15132                self.check_is_class("CallNonvirtualDoubleMethod", class);
15133                self.check_parameter_types_object("CallNonvirtualDoubleMethod", obj, methodID, arg1, 0, 1);
15134            }
15135            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jdouble>(88)(self.vtable, obj, class, methodID, arg1)
15136        }
15137    }
15138
15139    ///
15140    /// Calls a non-static java method with 2 arguments that returns double without using the objects vtable to look up the method.
15141    /// This means that should the object be a subclass of the class that the method is declared in
15142    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
15143    ///
15144    /// This is roughly equivalent to calling "super.someMethod(...)" in java
15145    ///
15146    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
15147    ///
15148    ///
15149    /// # Arguments
15150    /// * `obj` - which object the method should be called on
15151    ///     * must be valid
15152    ///     * must not be null
15153    ///     * must not be already garbage collected
15154    /// * `methodID` - method id of the method
15155    ///     * must not be null
15156    ///     * must be valid
15157    ///     * must not be a static
15158    ///     * must actually be a method of `obj`
15159    ///     * must refer to a method with 2 arguments
15160    ///
15161    /// # Returns
15162    /// Whatever the method returned or 0 if it threw
15163    ///
15164    /// # Throws Java Exception
15165    /// * Whatever the method threw
15166    ///
15167    ///
15168    /// # Panics
15169    /// if asserts feature is enabled and UB was detected
15170    ///
15171    /// # Safety
15172    ///
15173    /// Current thread must not be detached from JNI.
15174    ///
15175    /// Current thread must not be currently throwing an exception.
15176    ///
15177    /// Current thread does not hold a critical reference.
15178    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15179    ///
15180    /// `obj` must a valid and not already garbage collected.
15181    /// `methodID` must be valid, non-static and actually be a method of `obj`, return double and have 2 arguments
15182    ///
15183    pub unsafe fn CallNonvirtualDoubleMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jdouble {
15184        unsafe {
15185            #[cfg(feature = "asserts")]
15186            {
15187                self.check_not_critical("CallNonvirtualDoubleMethod");
15188                self.check_no_exception("CallNonvirtualDoubleMethod");
15189                self.check_return_type_object("CallNonvirtualDoubleMethod", obj, methodID, "double");
15190                self.check_is_class("CallNonvirtualDoubleMethod", class);
15191                self.check_parameter_types_object("CallNonvirtualDoubleMethod", obj, methodID, arg1, 0, 2);
15192                self.check_parameter_types_object("CallNonvirtualDoubleMethod", obj, methodID, arg2, 1, 2);
15193            }
15194            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jdouble>(88)(self.vtable, obj, class, methodID, arg1, arg2)
15195        }
15196    }
15197
15198    ///
15199    /// Calls a non-static java method with 3 arguments that returns double without using the objects vtable to look up the method.
15200    /// This means that should the object be a subclass of the class that the method is declared in
15201    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
15202    ///
15203    /// This is roughly equivalent to calling "super.someMethod(...)" in java
15204    ///
15205    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
15206    ///
15207    ///
15208    /// # Arguments
15209    /// * `obj` - which object the method should be called on
15210    ///     * must be valid
15211    ///     * must not be null
15212    ///     * must not be already garbage collected
15213    /// * `methodID` - method id of the method
15214    ///     * must not be null
15215    ///     * must be valid
15216    ///     * must not be a static
15217    ///     * must actually be a method of `obj`
15218    ///     * must refer to a method with 3 arguments
15219    ///
15220    /// # Returns
15221    /// Whatever the method returned or 0 if it threw
15222    ///
15223    /// # Throws Java Exception
15224    /// * Whatever the method threw
15225    ///
15226    ///
15227    /// # Panics
15228    /// if asserts feature is enabled and UB was detected
15229    ///
15230    /// # Safety
15231    ///
15232    /// Current thread must not be detached from JNI.
15233    ///
15234    /// Current thread must not be currently throwing an exception.
15235    ///
15236    /// Current thread does not hold a critical reference.
15237    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15238    ///
15239    /// `obj` must a valid and not already garbage collected.
15240    /// `methodID` must be valid, non-static and actually be a method of `obj`, return double and have 3 arguments
15241    ///
15242    pub unsafe fn CallNonvirtualDoubleMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jdouble {
15243        unsafe {
15244            #[cfg(feature = "asserts")]
15245            {
15246                self.check_not_critical("CallNonvirtualDoubleMethod");
15247                self.check_no_exception("CallNonvirtualDoubleMethod");
15248                self.check_return_type_object("CallNonvirtualDoubleMethod", obj, methodID, "double");
15249                self.check_is_class("CallNonvirtualDoubleMethod", class);
15250                self.check_parameter_types_object("CallNonvirtualDoubleMethod", obj, methodID, arg1, 0, 3);
15251                self.check_parameter_types_object("CallNonvirtualDoubleMethod", obj, methodID, arg2, 1, 3);
15252                self.check_parameter_types_object("CallNonvirtualDoubleMethod", obj, methodID, arg3, 2, 3);
15253            }
15254            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jdouble>(88)(self.vtable, obj, class, methodID, arg1, arg2, arg3)
15255        }
15256    }
15257
15258    ///
15259    /// Gets the field id of a static field
15260    ///
15261    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStaticFieldID>
15262    ///
15263    ///
15264    /// # Arguments
15265    /// * `clazz` - reference to the clazz where the field is declared in.
15266    ///     * must be valid
15267    ///     * must not be null
15268    ///     * must not be already garbage collected
15269    /// * `name` - name of the field
15270    ///     * must not be null
15271    ///     * must be zero terminated utf-8
15272    /// * `sig` - jni signature of the field
15273    ///     * must not be null
15274    ///     * must be zero terminated utf-8
15275    ///
15276    /// # Returns
15277    /// A non-null field handle or null on error.
15278    /// The field handle can be assumed to be constant for the given class and must not be freed.
15279    /// It can also be safely shared with any thread or stored in a constant.
15280    ///
15281    /// # Throws Java Exception
15282    /// * `NoSuchFieldError` - field with the given name and sig doesn't exist in the class
15283    /// * `ExceptionInInitializerError` - Exception occurs in initializer of the class
15284    /// * `OutOfMemoryError` - if the jvm runs out of memory
15285    ///
15286    ///
15287    /// # Panics
15288    /// if asserts feature is enabled and UB was detected
15289    ///
15290    /// # Safety
15291    ///
15292    /// Current thread must not be detached from JNI.
15293    ///
15294    /// Current thread must not be currently throwing an exception.
15295    ///
15296    /// Current thread does not hold a critical reference.
15297    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15298    ///
15299    /// `clazz` must a valid reference to a class that is not already garbage collected.
15300    /// `name` must be non-null and zero terminated utf-8.
15301    /// `sig` must be non-null and zero terminated utf-8.
15302    ///
15303    pub unsafe fn GetStaticFieldID(&self, clazz: jclass, name: impl UseCString, sig: impl UseCString) -> jfieldID {
15304        unsafe {
15305            name.use_as_const_c_char(|name| {
15306                sig.use_as_const_c_char(|sig| {
15307                    #[cfg(feature = "asserts")]
15308                    {
15309                        self.check_not_critical("GetStaticFieldID");
15310                        self.check_no_exception("GetStaticFieldID");
15311                        assert!(!name.is_null(), "GetStaticFieldID name is null");
15312                        assert!(!sig.is_null(), "GetStaticFieldID sig is null");
15313                        self.check_is_class("GetStaticFieldID", clazz);
15314                    }
15315                    self.jni::<extern "system" fn(JNIEnvVTable, jclass, *const c_char, *const c_char) -> jfieldID>(144)(self.vtable, clazz, name, sig)
15316                })
15317            })
15318        }
15319    }
15320
15321    ///
15322    /// Returns a local reference from a static field.
15323    ///
15324    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStatic_type_Field_routines>
15325    ///
15326    ///
15327    /// # Arguments
15328    /// * `obj` - reference to the class the field is in
15329    ///     * must be valid
15330    ///     * must not be null
15331    ///     * must not be already garbage collected
15332    /// * `fieldID` - the field to get
15333    ///     * must be valid
15334    ///     * must be an object field
15335    ///
15336    /// # Returns
15337    /// A local reference to the fields value or null if the field is null
15338    ///
15339    ///
15340    /// # Panics
15341    /// if asserts feature is enabled and UB was detected
15342    ///
15343    /// # Safety
15344    ///
15345    /// Current thread must not be detached from JNI.
15346    ///
15347    /// Current thread must not be currently throwing an exception.
15348    ///
15349    /// Current thread does not hold a critical reference.
15350    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15351    ///
15352    /// `obj` must a valid reference to a class that is not already garbage collected.
15353    /// `fieldID` must be a fieldID of a field located in `obj` class and not some other unrelated class
15354    /// `fieldID` must be from a static field
15355    /// `fieldID` must refer to a field that is an object and not a primitive.
15356    ///
15357    pub unsafe fn GetStaticObjectField(&self, obj: jclass, fieldID: jfieldID) -> jobject {
15358        unsafe {
15359            #[cfg(feature = "asserts")]
15360            {
15361                self.check_not_critical("GetStaticObjectField");
15362                self.check_no_exception("GetStaticObjectField");
15363                self.check_field_type_static("GetStaticObjectField", obj, fieldID, "object");
15364            }
15365            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jobject>(145)(self.vtable, obj, fieldID)
15366        }
15367    }
15368
15369    ///
15370    /// Returns a boolean from a static field.
15371    ///
15372    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStatic_type_Field_routines>
15373    ///
15374    ///
15375    /// # Arguments
15376    /// * `obj` - reference to the class the field is in
15377    ///     * must be valid
15378    ///     * must not be null
15379    ///     * must not be already garbage collected
15380    /// * `fieldID` - the field to get
15381    ///     * must be valid
15382    ///     * must be a boolean field
15383    ///
15384    /// # Returns
15385    /// The value of the field
15386    ///
15387    ///
15388    /// # Panics
15389    /// if asserts feature is enabled and UB was detected
15390    ///
15391    /// # Safety
15392    ///
15393    /// Current thread must not be detached from JNI.
15394    ///
15395    /// Current thread must not be currently throwing an exception.
15396    ///
15397    /// Current thread does not hold a critical reference.
15398    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15399    ///
15400    /// `obj` must a valid reference to a class that is not already garbage collected.
15401    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
15402    /// `fieldID` must be from a static field
15403    /// `fieldID` must refer to a field that is a boolean.
15404    ///
15405    pub unsafe fn GetStaticBooleanField(&self, obj: jclass, fieldID: jfieldID) -> bool {
15406        unsafe {
15407            #[cfg(feature = "asserts")]
15408            {
15409                self.check_not_critical("GetStaticBooleanField");
15410                self.check_no_exception("GetStaticBooleanField");
15411                self.check_field_type_static("GetStaticBooleanField", obj, fieldID, "boolean");
15412            }
15413            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jboolean>(146)(self.vtable, obj, fieldID).as_bool()
15414        }
15415    }
15416
15417    ///
15418    /// Returns a byte from a static field.
15419    ///
15420    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStatic_type_Field_routines>
15421    ///
15422    ///
15423    /// # Arguments
15424    /// * `obj` - reference to the class the field is in
15425    ///     * must be valid
15426    ///     * must not be null
15427    ///     * must not be already garbage collected
15428    /// * `fieldID` - the field to get
15429    ///     * must be valid
15430    ///     * must be a byte field
15431    ///
15432    /// # Returns
15433    /// The value of the field
15434    ///
15435    ///
15436    /// # Panics
15437    /// if asserts feature is enabled and UB was detected
15438    ///
15439    /// # Safety
15440    ///
15441    /// Current thread must not be detached from JNI.
15442    ///
15443    /// Current thread must not be currently throwing an exception.
15444    ///
15445    /// Current thread does not hold a critical reference.
15446    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15447    ///
15448    /// `obj` must a valid reference to a class that is not already garbage collected.
15449    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
15450    /// `fieldID` must be from a static field
15451    /// `fieldID` must refer to a field that is a byte.
15452    ///
15453    pub unsafe fn GetStaticByteField(&self, obj: jclass, fieldID: jfieldID) -> jbyte {
15454        unsafe {
15455            #[cfg(feature = "asserts")]
15456            {
15457                self.check_not_critical("GetStaticByteField");
15458                self.check_no_exception("GetStaticByteField");
15459                self.check_field_type_static("GetStaticByteField", obj, fieldID, "byte");
15460            }
15461            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jbyte>(147)(self.vtable, obj, fieldID)
15462        }
15463    }
15464
15465    ///
15466    /// Returns a char from a static field.
15467    ///
15468    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStatic_type_Field_routines>
15469    ///
15470    ///
15471    /// # Arguments
15472    /// * `obj` - reference to the class the field is in
15473    ///     * must be valid
15474    ///     * must not be null
15475    ///     * must not be already garbage collected
15476    /// * `fieldID` - the field to get
15477    ///     * must be valid
15478    ///     * must be a char field
15479    ///
15480    /// # Returns
15481    /// The value of the field
15482    ///
15483    ///
15484    /// # Panics
15485    /// if asserts feature is enabled and UB was detected
15486    ///
15487    /// # Safety
15488    ///
15489    /// Current thread must not be detached from JNI.
15490    ///
15491    /// Current thread must not be currently throwing an exception.
15492    ///
15493    /// Current thread does not hold a critical reference.
15494    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15495    ///
15496    /// `obj` must a valid reference to a class that is not already garbage collected.
15497    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
15498    /// `fieldID` must be from a static field
15499    /// `fieldID` must refer to a field that is a char.
15500    ///
15501    pub unsafe fn GetStaticCharField(&self, obj: jclass, fieldID: jfieldID) -> jchar {
15502        unsafe {
15503            #[cfg(feature = "asserts")]
15504            {
15505                self.check_not_critical("GetStaticCharField");
15506                self.check_no_exception("GetStaticCharField");
15507                self.check_field_type_static("GetStaticCharField", obj, fieldID, "char");
15508            }
15509            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jchar>(148)(self.vtable, obj, fieldID)
15510        }
15511    }
15512
15513    ///
15514    /// Returns a short from a static field.
15515    ///
15516    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStatic_type_Field_routines>
15517    ///
15518    ///
15519    /// # Arguments
15520    /// * `obj` - reference to the class the field is in
15521    ///     * must be valid
15522    ///     * must not be null
15523    ///     * must not be already garbage collected
15524    /// * `fieldID` - the field to get
15525    ///     * must be valid
15526    ///     * must be a short field
15527    ///
15528    /// # Returns
15529    /// The value of the field
15530    ///
15531    ///
15532    /// # Panics
15533    /// if asserts feature is enabled and UB was detected
15534    ///
15535    /// # Safety
15536    ///
15537    /// Current thread must not be detached from JNI.
15538    ///
15539    /// Current thread must not be currently throwing an exception.
15540    ///
15541    /// Current thread does not hold a critical reference.
15542    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15543    ///
15544    /// `obj` must a valid reference to a class that is not already garbage collected.
15545    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
15546    /// `fieldID` must be from a static field
15547    /// `fieldID` must refer to a field that is a short.
15548    ///
15549    pub unsafe fn GetStaticShortField(&self, obj: jclass, fieldID: jfieldID) -> jshort {
15550        unsafe {
15551            #[cfg(feature = "asserts")]
15552            {
15553                self.check_not_critical("GetStaticShortField");
15554                self.check_no_exception("GetStaticShortField");
15555                self.check_field_type_static("GetStaticShortField", obj, fieldID, "short");
15556            }
15557            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jshort>(149)(self.vtable, obj, fieldID)
15558        }
15559    }
15560
15561    ///
15562    /// Returns a int from a static field.
15563    ///
15564    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStatic_type_Field_routines>
15565    ///
15566    ///
15567    /// # Arguments
15568    /// * `obj` - reference to the class the field is in
15569    ///     * must be valid
15570    ///     * must not be null
15571    ///     * must not be already garbage collected
15572    /// * `fieldID` - the field to get
15573    ///     * must be valid
15574    ///     * must be a int field
15575    ///
15576    /// # Returns
15577    /// The value of the field
15578    ///
15579    ///
15580    /// # Panics
15581    /// if asserts feature is enabled and UB was detected
15582    ///
15583    /// # Safety
15584    ///
15585    /// Current thread must not be detached from JNI.
15586    ///
15587    /// Current thread must not be currently throwing an exception.
15588    ///
15589    /// Current thread does not hold a critical reference.
15590    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15591    ///
15592    /// `obj` must a valid reference to a class that is not already garbage collected.
15593    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
15594    /// `fieldID` must be from a static field
15595    /// `fieldID` must refer to a field that is a int.
15596    ///
15597    pub unsafe fn GetStaticIntField(&self, obj: jclass, fieldID: jfieldID) -> jint {
15598        unsafe {
15599            #[cfg(feature = "asserts")]
15600            {
15601                self.check_not_critical("GetStaticIntField");
15602                self.check_no_exception("GetStaticIntField");
15603                self.check_field_type_static("GetStaticIntField", obj, fieldID, "int");
15604            }
15605            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jint>(150)(self.vtable, obj, fieldID)
15606        }
15607    }
15608
15609    ///
15610    /// Returns a long from a static field.
15611    ///
15612    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStatic_type_Field_routines>
15613    ///
15614    ///
15615    /// # Arguments
15616    /// * `obj` - reference to the class the field is in
15617    ///     * must be valid
15618    ///     * must not be null
15619    ///     * must not be already garbage collected
15620    ///
15621    /// * `fieldID` - the field to get
15622    ///     * must be valid
15623    ///     * must be a long field
15624    ///
15625    /// # Returns
15626    /// The value of the field
15627    ///
15628    ///
15629    /// # Panics
15630    /// if asserts feature is enabled and UB was detected
15631    ///
15632    /// # Safety
15633    ///
15634    /// Current thread must not be detached from JNI.
15635    ///
15636    /// Current thread must not be currently throwing an exception.
15637    ///
15638    /// Current thread does not hold a critical reference.
15639    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15640    ///
15641    /// `obj` must a valid reference to a class that is not already garbage collected.
15642    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
15643    /// `fieldID` must be from a static field
15644    /// `fieldID` must refer to a field that is a long.
15645    ///
15646    pub unsafe fn GetStaticLongField(&self, obj: jclass, fieldID: jfieldID) -> jlong {
15647        unsafe {
15648            #[cfg(feature = "asserts")]
15649            {
15650                self.check_not_critical("GetStaticLongField");
15651                self.check_no_exception("GetStaticLongField");
15652                self.check_field_type_static("GetStaticLongField", obj, fieldID, "long");
15653            }
15654            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jlong>(151)(self.vtable, obj, fieldID)
15655        }
15656    }
15657
15658    ///
15659    /// Returns a float from a static field.
15660    ///
15661    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStatic_type_Field_routines>
15662    ///
15663    ///
15664    /// # Arguments
15665    /// * `obj` - reference to the class the field is in
15666    ///     * must be valid
15667    ///     * must not be null
15668    ///     * must not be already garbage collected
15669    ///
15670    /// * `fieldID` - the field to get
15671    ///     * must be valid
15672    ///     * must be a float field
15673    ///
15674    /// # Returns
15675    /// The value of the field
15676    ///
15677    ///
15678    /// # Panics
15679    /// if asserts feature is enabled and UB was detected
15680    ///
15681    /// # Safety
15682    ///
15683    /// Current thread must not be detached from JNI.
15684    ///
15685    /// Current thread must not be currently throwing an exception.
15686    ///
15687    /// Current thread does not hold a critical reference.
15688    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15689    ///
15690    /// `obj` must a valid reference to a class that is not already garbage collected.
15691    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
15692    /// `fieldID` must be from a static field
15693    /// `fieldID` must refer to a field that is a float.
15694    ///
15695    pub unsafe fn GetStaticFloatField(&self, obj: jclass, fieldID: jfieldID) -> jfloat {
15696        unsafe {
15697            #[cfg(feature = "asserts")]
15698            {
15699                self.check_not_critical("GetStaticFloatField");
15700                self.check_no_exception("GetStaticFloatField");
15701                self.check_field_type_static("GetStaticFloatField", obj, fieldID, "float");
15702            }
15703            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jfloat>(152)(self.vtable, obj, fieldID)
15704        }
15705    }
15706
15707    ///
15708    /// Returns a double from a static field.
15709    ///
15710    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStatic_type_Field_routines>
15711    ///
15712    ///
15713    /// # Arguments
15714    /// * `obj` - reference to the class the field is in
15715    ///     * must be valid
15716    ///     * must not be null
15717    ///     * must not be already garbage collected
15718    ///
15719    /// * `fieldID` - the field to get
15720    ///     * must be valid
15721    ///     * must be a double field
15722    ///
15723    /// # Returns
15724    /// The value of the field
15725    ///
15726    ///
15727    /// # Panics
15728    /// if asserts feature is enabled and UB was detected
15729    ///
15730    /// # Safety
15731    ///
15732    /// Current thread must not be detached from JNI.
15733    ///
15734    /// Current thread must not be currently throwing an exception.
15735    ///
15736    /// Current thread does not hold a critical reference.
15737    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15738    ///
15739    /// `obj` must a valid reference to a class that is not already garbage collected.
15740    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
15741    /// `fieldID` must be from a static field
15742    /// `fieldID` must refer to a field that is a double.
15743    ///
15744    pub unsafe fn GetStaticDoubleField(&self, obj: jclass, fieldID: jfieldID) -> jdouble {
15745        unsafe {
15746            #[cfg(feature = "asserts")]
15747            {
15748                self.check_not_critical("GetStaticDoubleField");
15749                self.check_no_exception("GetStaticDoubleField");
15750                self.check_field_type_static("GetStaticDoubleField", obj, fieldID, "double");
15751            }
15752            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jdouble>(153)(self.vtable, obj, fieldID)
15753        }
15754    }
15755
15756    ///
15757    /// Sets a static object field to a given value
15758    ///
15759    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#SetStatic_type_Field_routines>
15760    ///
15761    /// # Arguments
15762    /// * `obj` - reference to the object the field is in
15763    ///     * must be valid
15764    ///     * must not be null
15765    ///     * must not be already garbage collected
15766    ///
15767    /// * `fieldID` - the field to set
15768    ///     * must be valid
15769    ///     * must be a object field
15770    ///     * must reside in the object `obj`
15771    ///
15772    /// * `value`
15773    ///     * must be null or valid
15774    ///     * must not be already garbage collected (if non-null)
15775    ///     * must be assignable to the field type (if non-null)
15776    ///
15777    ///
15778    /// # Panics
15779    /// if asserts feature is enabled and UB was detected
15780    ///
15781    /// # Safety
15782    ///
15783    /// Current thread must not be detached from JNI.
15784    ///
15785    /// Current thread must not be currently throwing an exception.
15786    ///
15787    /// Current thread does not hold a critical reference.
15788    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15789    ///
15790    /// `obj` must be a valid reference to the class the field is in that is not already garbage collected.
15791    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
15792    /// `fieldID` must be from a static field
15793    /// `fieldID` must refer to a field that is an object and not a primitive.
15794    /// `value` must be a valid reference to the object that is not already garbage collected or it must be null.
15795    /// `value` must be assignable to the field type (i.e. if it's a String field setting to an `ArrayList` for example is UB)
15796    ///
15797    pub unsafe fn SetStaticObjectField(&self, obj: jclass, fieldID: jfieldID, value: jobject) {
15798        unsafe {
15799            #[cfg(feature = "asserts")]
15800            {
15801                self.check_not_critical("SetStaticObjectField");
15802                self.check_no_exception("SetStaticObjectField");
15803                self.check_field_type_static("SetStaticObjectField", obj, fieldID, "object");
15804            }
15805            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jobject)>(154)(self.vtable, obj, fieldID, value);
15806        }
15807    }
15808
15809    ///
15810    /// Sets a static boolean field to a given value
15811    ///
15812    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#SetStatic_type_Field_routines>
15813    ///
15814    /// # Arguments
15815    /// * `obj` - reference to the object the field is in
15816    ///     * must be valid
15817    ///     * must not be null
15818    ///     * must not be already garbage collected
15819    ///
15820    /// * `fieldID` - the field to set
15821    ///     * must be valid
15822    ///     * must be a object field
15823    ///     * must reside in the object `obj`
15824    ///
15825    /// * `value` - that value to set
15826    ///
15827    ///
15828    /// # Panics
15829    /// if asserts feature is enabled and UB was detected
15830    ///
15831    /// # Safety
15832    ///
15833    /// Current thread must not be detached from JNI.
15834    ///
15835    /// Current thread must not be currently throwing an exception.
15836    ///
15837    /// Current thread does not hold a critical reference.
15838    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15839    ///
15840    /// `obj` must be a valid reference to the class the field is in that is not already garbage collected.
15841    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
15842    /// `fieldID` must be from a static field
15843    /// `fieldID` must refer to a field that is a boolean.
15844    ///
15845    pub unsafe fn SetStaticBooleanField(&self, obj: jclass, fieldID: jfieldID, value: impl Into<jboolean>) {
15846        let value = value.into();
15847        unsafe {
15848            #[cfg(feature = "asserts")]
15849            {
15850                self.check_not_critical("SetStaticBooleanField");
15851                self.check_no_exception("SetStaticBooleanField");
15852                self.check_field_type_static("SetStaticBooleanField", obj, fieldID, "boolean");
15853                assert!(!value.is_wide(), "SetStaticBooleanField with wide boolean value");
15854            }
15855            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jboolean)>(155)(self.vtable, obj, fieldID, value);
15856        }
15857    }
15858
15859    ///
15860    /// Sets a static byte field to a given value
15861    ///
15862    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#SetStatic_type_Field_routines>
15863    ///
15864    /// # Arguments
15865    /// * `obj` - reference to the object the field is in
15866    ///     * must be valid
15867    ///     * must not be null
15868    ///     * must not be already garbage collected
15869    ///
15870    /// * `fieldID` - the field to set
15871    ///     * must be valid
15872    ///     * must be a object field
15873    ///     * must reside in the object `obj`
15874    ///
15875    /// * `value` - that value to set
15876    ///
15877    ///
15878    /// # Panics
15879    /// if asserts feature is enabled and UB was detected
15880    ///
15881    /// # Safety
15882    ///
15883    /// Current thread must not be detached from JNI.
15884    ///
15885    /// Current thread must not be currently throwing an exception.
15886    ///
15887    /// Current thread does not hold a critical reference.
15888    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15889    ///
15890    /// `obj` must be a valid reference to the class the field is in that is not already garbage collected.
15891    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
15892    /// `fieldID` must be from a static field
15893    /// `fieldID` must refer to a field that is a byte.
15894    ///
15895    pub unsafe fn SetStaticByteField(&self, obj: jclass, fieldID: jfieldID, value: jbyte) {
15896        unsafe {
15897            #[cfg(feature = "asserts")]
15898            {
15899                self.check_not_critical("SetStaticByteField");
15900                self.check_no_exception("SetStaticByteField");
15901                self.check_field_type_static("SetStaticByteField", obj, fieldID, "byte");
15902            }
15903            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jbyte)>(156)(self.vtable, obj, fieldID, value);
15904        }
15905    }
15906
15907    ///
15908    /// Sets a static char field to a given value
15909    ///
15910    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#SetStatic_type_Field_routines>
15911    ///
15912    /// # Arguments
15913    /// * `obj` - reference to the object the field is in
15914    ///     * must be valid
15915    ///     * must not be null
15916    ///     * must not be already garbage collected
15917    ///
15918    /// * `fieldID` - the field to set
15919    ///     * must be valid
15920    ///     * must be a object field
15921    ///     * must reside in the object `obj`
15922    ///
15923    /// * `value` - that value to set
15924    ///
15925    ///
15926    /// # Panics
15927    /// if asserts feature is enabled and UB was detected
15928    ///
15929    /// # Safety
15930    ///
15931    /// Current thread must not be detached from JNI.
15932    ///
15933    /// Current thread must not be currently throwing an exception.
15934    ///
15935    /// Current thread does not hold a critical reference.
15936    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15937    ///
15938    /// `obj` must be a valid reference to the class the field is in that is not already garbage collected.
15939    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
15940    /// `fieldID` must be from a static field
15941    /// `fieldID` must refer to a field that is a char.
15942    ///
15943    pub unsafe fn SetStaticCharField(&self, obj: jclass, fieldID: jfieldID, value: jchar) {
15944        unsafe {
15945            #[cfg(feature = "asserts")]
15946            {
15947                self.check_not_critical("SetStaticCharField");
15948                self.check_no_exception("SetStaticCharField");
15949                self.check_field_type_static("SetStaticCharField", obj, fieldID, "char");
15950            }
15951            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jchar)>(157)(self.vtable, obj, fieldID, value);
15952        }
15953    }
15954
15955    ///
15956    /// Sets a static short field to a given value
15957    ///
15958    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#SetStatic_type_Field_routines>
15959    ///
15960    /// # Arguments
15961    /// * `obj` - reference to the object the field is in
15962    ///     * must be valid
15963    ///     * must not be null
15964    ///     * must not be already garbage collected
15965    ///
15966    /// * `fieldID` - the field to set
15967    ///     * must be valid
15968    ///     * must be a object field
15969    ///     * must reside in the object `obj`
15970    ///
15971    /// * `value` - that value to set
15972    ///
15973    ///
15974    /// # Panics
15975    /// if asserts feature is enabled and UB was detected
15976    ///
15977    /// # Safety
15978    ///
15979    /// Current thread must not be detached from JNI.
15980    ///
15981    /// Current thread must not be currently throwing an exception.
15982    ///
15983    /// Current thread does not hold a critical reference.
15984    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15985    ///
15986    /// `obj` must be a valid reference to the class the field is in that is not already garbage collected.
15987    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
15988    /// `fieldID` must be from a static field
15989    /// `fieldID` must refer to a field that is a short.
15990    ///
15991    pub unsafe fn SetStaticShortField(&self, obj: jclass, fieldID: jfieldID, value: jshort) {
15992        unsafe {
15993            #[cfg(feature = "asserts")]
15994            {
15995                self.check_not_critical("SetStaticShortField");
15996                self.check_no_exception("SetStaticShortField");
15997                self.check_field_type_static("SetStaticShortField", obj, fieldID, "short");
15998            }
15999            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jshort)>(158)(self.vtable, obj, fieldID, value);
16000        }
16001    }
16002
16003    ///
16004    /// Sets a static int field to a given value
16005    ///
16006    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#SetStatic_type_Field_routines>
16007    ///
16008    /// # Arguments
16009    /// * `obj` - reference to the object the field is in
16010    ///     * must be valid
16011    ///     * must not be null
16012    ///     * must not be already garbage collected
16013    ///
16014    /// * `fieldID` - the field to set
16015    ///     * must be valid
16016    ///     * must be a object field
16017    ///     * must reside in the object `obj`
16018    ///
16019    /// * `value` - that value to set
16020    ///
16021    ///
16022    /// # Panics
16023    /// if asserts feature is enabled and UB was detected
16024    ///
16025    /// # Safety
16026    ///
16027    /// Current thread must not be detached from JNI.
16028    ///
16029    /// Current thread must not be currently throwing an exception.
16030    ///
16031    /// Current thread does not hold a critical reference.
16032    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16033    ///
16034    /// `obj` must be a valid reference to the class the field is in that is not already garbage collected.
16035    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
16036    /// `fieldID` must be from a static field
16037    /// `fieldID` must refer to a field that is a int.
16038    ///
16039    pub unsafe fn SetStaticIntField(&self, obj: jclass, fieldID: jfieldID, value: jint) {
16040        unsafe {
16041            #[cfg(feature = "asserts")]
16042            {
16043                self.check_not_critical("SetStaticIntField");
16044                self.check_no_exception("SetStaticIntField");
16045                self.check_field_type_static("SetStaticIntField", obj, fieldID, "int");
16046            }
16047            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jint)>(159)(self.vtable, obj, fieldID, value);
16048        }
16049    }
16050
16051    ///
16052    /// Sets a static long field to a given value
16053    ///
16054    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#SetStatic_type_Field_routines>
16055    ///
16056    /// # Arguments
16057    /// * `obj` - reference to the object the field is in
16058    ///     * must be valid
16059    ///     * must not be null
16060    ///     * must not be already garbage collected
16061    ///
16062    /// * `fieldID` - the field to set
16063    ///     * must be valid
16064    ///     * must be a object field
16065    ///     * must reside in the object `obj`
16066    ///
16067    /// * `value` - that value to set
16068    ///
16069    ///
16070    /// # Panics
16071    /// if asserts feature is enabled and UB was detected
16072    ///
16073    /// # Safety
16074    ///
16075    /// Current thread must not be detached from JNI.
16076    ///
16077    /// Current thread must not be currently throwing an exception.
16078    ///
16079    /// Current thread does not hold a critical reference.
16080    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16081    ///
16082    /// `obj` must be a valid reference to the class the field is in that is not already garbage collected.
16083    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
16084    /// `fieldID` must be from a static field
16085    /// `fieldID` must refer to a field that is a long.
16086    ///
16087    pub unsafe fn SetStaticLongField(&self, obj: jclass, fieldID: jfieldID, value: jlong) {
16088        unsafe {
16089            #[cfg(feature = "asserts")]
16090            {
16091                self.check_not_critical("SetStaticLongField");
16092                self.check_no_exception("SetStaticLongField");
16093                self.check_field_type_static("SetStaticLongField", obj, fieldID, "long");
16094            }
16095            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jlong)>(160)(self.vtable, obj, fieldID, value);
16096        }
16097    }
16098
16099    ///
16100    /// Sets a static float field to a given value
16101    ///
16102    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#SetStatic_type_Field_routines>
16103    ///
16104    /// # Arguments
16105    /// * `obj` - reference to the object the field is in
16106    ///     * must be valid
16107    ///     * must not be null
16108    ///     * must not be already garbage collected
16109    ///
16110    /// * `fieldID` - the field to set
16111    ///     * must be valid
16112    ///     * must be a object field
16113    ///     * must reside in the object `obj`
16114    ///
16115    /// * `value` - that value to set
16116    ///
16117    ///
16118    /// # Panics
16119    /// if asserts feature is enabled and UB was detected
16120    ///
16121    /// # Safety
16122    ///
16123    /// Current thread must not be detached from JNI.
16124    ///
16125    /// Current thread must not be currently throwing an exception.
16126    ///
16127    /// Current thread does not hold a critical reference.
16128    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16129    ///
16130    /// `obj` must be a valid reference to the class the field is in that is not already garbage collected.
16131    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
16132    /// `fieldID` must be from a static field
16133    /// `fieldID` must refer to a field that is a float.
16134    ///
16135    pub unsafe fn SetStaticFloatField(&self, obj: jclass, fieldID: jfieldID, value: jfloat) {
16136        unsafe {
16137            #[cfg(feature = "asserts")]
16138            {
16139                self.check_not_critical("SetStaticFloatField");
16140                self.check_no_exception("SetStaticFloatField");
16141                self.check_field_type_static("SetStaticFloatField", obj, fieldID, "float");
16142            }
16143            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jfloat)>(161)(self.vtable, obj, fieldID, value);
16144        }
16145    }
16146
16147    ///
16148    /// Sets a static double field to a given value
16149    ///
16150    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#SetStatic_type_Field_routines>
16151    ///
16152    /// # Arguments
16153    /// * `obj` - reference to the object the field is in
16154    ///     * must be valid
16155    ///     * must not be null
16156    ///     * must not be already garbage collected
16157    ///
16158    /// * `fieldID` - the field to set
16159    ///     * must be valid
16160    ///     * must be a object field
16161    ///     * must reside in the object `obj`
16162    ///
16163    /// * `value` - that value to set
16164    ///
16165    ///
16166    /// # Panics
16167    /// if asserts feature is enabled and UB was detected
16168    ///
16169    /// # Safety
16170    ///
16171    /// Current thread must not be detached from JNI.
16172    ///
16173    /// Current thread must not be currently throwing an exception.
16174    ///
16175    /// Current thread does not hold a critical reference.
16176    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16177    ///
16178    /// `obj` must be a valid reference to the class the field is in that is not already garbage collected.
16179    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
16180    /// `fieldID` must be from a static field
16181    /// `fieldID` must refer to a field that is a double.
16182    ///
16183    pub unsafe fn SetStaticDoubleField(&self, obj: jclass, fieldID: jfieldID, value: jdouble) {
16184        unsafe {
16185            #[cfg(feature = "asserts")]
16186            {
16187                self.check_not_critical("SetStaticDoubleField");
16188                self.check_no_exception("SetStaticDoubleField");
16189                self.check_field_type_static("SetStaticDoubleField", obj, fieldID, "double");
16190            }
16191            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jdouble)>(162)(self.vtable, obj, fieldID, value);
16192        }
16193    }
16194
16195    ///
16196    /// Gets the method id of a static method
16197    ///
16198    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetMethodID>
16199    ///
16200    ///
16201    /// # Arguments
16202    /// * `clazz` - reference to the clazz where the field is declared in.
16203    ///     * must be valid
16204    ///     * must not be null
16205    ///     * must not be already garbage collected
16206    /// * `name` - name of the method
16207    ///     * must not be null
16208    ///     * must be zero terminated utf-8
16209    /// * `sig` - jni signature of the method
16210    ///     * must not be null
16211    ///     * must be zero terminated utf-8
16212    ///
16213    /// # Returns
16214    /// A non-null field handle or null on error.
16215    /// The field handle can be assumed to be constant for the given class and must not be freed.
16216    /// It can also be safely shared with any thread or stored in a constant.
16217    ///
16218    /// # Throws Java Exception
16219    /// * `NoSuchMethodError` - method with the given name and sig doesn't exist in the class
16220    /// * `ExceptionInInitializerError` - Exception occurs in initializer of the class
16221    /// * `OutOfMemoryError` - if the jvm runs out of memory
16222    ///
16223    ///
16224    /// # Panics
16225    /// if asserts feature is enabled and UB was detected
16226    ///
16227    /// # Safety
16228    ///
16229    /// Current thread must not be detached from JNI.
16230    ///
16231    /// Current thread must not be currently throwing an exception.
16232    ///
16233    /// Current thread does not hold a critical reference.
16234    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16235    ///
16236    /// `clazz` must a valid reference to a class that is not already garbage collected.
16237    /// `name` must be non-null and zero terminated utf-8.
16238    /// `sig` must be non-null and zero terminated utf-8.
16239    ///
16240    pub unsafe fn GetStaticMethodID(&self, class: jclass, name: impl UseCString, sig: impl UseCString) -> jmethodID {
16241        unsafe {
16242            name.use_as_const_c_char(|name| {
16243                sig.use_as_const_c_char(|sig| {
16244                    #[cfg(feature = "asserts")]
16245                    {
16246                        self.check_not_critical("GetStaticMethodID");
16247                        self.check_no_exception("GetStaticMethodID");
16248                        self.check_is_class("GetStaticMethodID", class);
16249                        assert!(!name.is_null(), "GetStaticMethodID name is null");
16250                        assert!(!sig.is_null(), "GetStaticMethodID sig is null");
16251                    }
16252
16253                    self.jni::<extern "system" fn(JNIEnvVTable, jobject, *const c_char, *const c_char) -> jmethodID>(113)(self.vtable, class, name, sig)
16254                })
16255            })
16256        }
16257    }
16258
16259    ///
16260    /// Calls a static java method that returns void
16261    ///
16262    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16263    ///
16264    ///
16265    /// # Arguments
16266    /// * `obj` - which object the method should be called on
16267    ///     * must be valid
16268    ///     * must not be null
16269    ///     * must not be already garbage collected
16270    ///
16271    /// * `methodID` - method id of the method
16272    ///     * must not be null
16273    ///     * must be valid
16274    ///     * must not be a static
16275    ///     * must actually be a method of `obj`
16276    ///
16277    /// * `args` - argument pointer
16278    ///     * can be null if the method has no arguments
16279    ///     * must not be null otherwise and point to the exact number of arguments the method expects
16280    ///
16281    /// # Throws Java Exception
16282    /// * Whatever the method threw
16283    ///
16284    ///
16285    /// # Panics
16286    /// if asserts feature is enabled and UB was detected
16287    ///
16288    /// # Safety
16289    ///
16290    /// Current thread must not be detached from JNI.
16291    ///
16292    /// Current thread must not be currently throwing an exception.
16293    ///
16294    /// Current thread does not hold a critical reference.
16295    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16296    ///
16297    /// `obj` must a valid and not already garbage collected.
16298    /// `methodID` must be valid, static and actually be a method of `obj` class and return void
16299    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
16300    /// `args` union must contain types that match the java methods parameters.
16301    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
16302    ///
16303    pub unsafe fn CallStaticVoidMethodA(&self, clazz: jclass, methodID: jmethodID, args: *const jtype) {
16304        unsafe {
16305            #[cfg(feature = "asserts")]
16306            {
16307                self.check_not_critical("CallStaticVoidMethodA");
16308                self.check_no_exception("CallStaticVoidMethodA");
16309                self.check_return_type_static("CallStaticVoidMethodA", clazz, methodID, "void");
16310            }
16311            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype)>(143)(self.vtable, clazz, methodID, args);
16312        }
16313    }
16314
16315    ///
16316    /// Calls a static java method that has 0 arguments and returns void
16317    ///
16318    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16319    ///
16320    ///
16321    /// # Arguments
16322    /// * `obj` - which object the method should be called on
16323    ///     * must be valid
16324    ///     * must not be null
16325    ///     * must not be already garbage collected
16326    ///
16327    /// * `methodID` - method id of the method
16328    ///     * must not be null
16329    ///     * must be valid
16330    ///     * must be a static
16331    ///     * must actually be a method of `obj`
16332    ///     * must refer to a method with 0 arguments
16333    ///
16334    /// # Throws Java Exception
16335    /// * Whatever the method threw
16336    ///
16337    ///
16338    /// # Panics
16339    /// if asserts feature is enabled and UB was detected
16340    ///
16341    /// # Safety
16342    ///
16343    /// Current thread must not be detached from JNI.
16344    ///
16345    /// Current thread must not be currently throwing an exception.
16346    ///
16347    /// Current thread does not hold a critical reference.
16348    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16349    ///
16350    /// `clazz` must a valid and not already garbage collected.
16351    /// `methodID` must be valid, static and actually be a method of `obj`, return void and have 0 arguments
16352    ///
16353    pub unsafe fn CallStaticVoidMethod0(&self, clazz: jclass, methodID: jmethodID) {
16354        unsafe {
16355            #[cfg(feature = "asserts")]
16356            {
16357                self.check_not_critical("CallStaticVoidMethod");
16358                self.check_no_exception("CallStaticVoidMethod");
16359                self.check_return_type_static("CallStaticVoidMethod", clazz, methodID, "void");
16360            }
16361            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID)>(141)(self.vtable, clazz, methodID);
16362        }
16363    }
16364
16365    ///
16366    /// Calls a static java method that has 1 arguments and returns void
16367    ///
16368    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16369    ///
16370    ///
16371    /// # Arguments
16372    /// * `obj` - which object the method should be called on
16373    ///     * must be valid
16374    ///     * must not be null
16375    ///     * must not be already garbage collected
16376    ///
16377    /// * `methodID` - method id of the method
16378    ///     * must not be null
16379    ///     * must be valid
16380    ///     * must be a static
16381    ///     * must actually be a method of `obj`
16382    ///     * must refer to a method with 1 arguments
16383    ///
16384    /// # Throws Java Exception
16385    /// * Whatever the method threw
16386    ///
16387    ///
16388    /// # Panics
16389    /// if asserts feature is enabled and UB was detected
16390    ///
16391    /// # Safety
16392    ///
16393    /// Current thread must not be detached from JNI.
16394    ///
16395    /// Current thread must not be currently throwing an exception.
16396    ///
16397    /// Current thread does not hold a critical reference.
16398    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16399    ///
16400    /// `clazz` must a valid and not already garbage collected.
16401    /// `methodID` must be valid, static and actually be a method of `obj`, return void and have 1 arguments
16402    ///
16403    pub unsafe fn CallStaticVoidMethod1<A: JType>(&self, clazz: jclass, methodID: jmethodID, arg1: A) {
16404        unsafe {
16405            #[cfg(feature = "asserts")]
16406            {
16407                self.check_not_critical("CallStaticVoidMethod");
16408                self.check_no_exception("CallStaticVoidMethod");
16409                self.check_return_type_static("CallStaticVoidMethod", clazz, methodID, "void");
16410                self.check_parameter_types_static("CallStaticVoidMethod", clazz, methodID, arg1, 0, 1);
16411            }
16412            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...)>(141)(self.vtable, clazz, methodID, arg1);
16413        }
16414    }
16415
16416    ///
16417    /// Calls a static java method that has 2 arguments and returns void
16418    ///
16419    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16420    ///
16421    ///
16422    /// # Arguments
16423    /// * `obj` - which object the method should be called on
16424    ///     * must be valid
16425    ///     * must not be null
16426    ///     * must not be already garbage collected
16427    ///
16428    /// * `methodID` - method id of the method
16429    ///     * must not be null
16430    ///     * must be valid
16431    ///     * must be a static
16432    ///     * must actually be a method of `obj`
16433    ///     * must refer to a method with 2 arguments
16434    ///
16435    /// # Throws Java Exception
16436    /// * Whatever the method threw
16437    ///
16438    ///
16439    /// # Panics
16440    /// if asserts feature is enabled and UB was detected
16441    ///
16442    /// # Safety
16443    ///
16444    /// Current thread must not be detached from JNI.
16445    ///
16446    /// Current thread must not be currently throwing an exception.
16447    ///
16448    /// Current thread does not hold a critical reference.
16449    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16450    ///
16451    /// `obj` must a valid and not already garbage collected.
16452    /// `methodID` must be valid, static and actually be a method of `obj`, return void and have 2 arguments
16453    ///
16454    pub unsafe fn CallStaticVoidMethod2<A: JType, B: JType>(&self, clazz: jclass, methodID: jmethodID, arg1: A, arg2: B) {
16455        unsafe {
16456            #[cfg(feature = "asserts")]
16457            {
16458                self.check_not_critical("CallStaticVoidMethod");
16459                self.check_no_exception("CallStaticVoidMethod");
16460                self.check_return_type_static("CallStaticVoidMethod", clazz, methodID, "void");
16461                self.check_parameter_types_static("CallStaticVoidMethod", clazz, methodID, arg1, 0, 2);
16462                self.check_parameter_types_static("CallStaticVoidMethod", clazz, methodID, arg2, 1, 2);
16463            }
16464            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...)>(141)(self.vtable, clazz, methodID, arg1, arg2);
16465        }
16466    }
16467
16468    ///
16469    /// Calls a static java method that has 3 arguments and returns void
16470    ///
16471    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16472    ///
16473    ///
16474    /// # Arguments
16475    /// * `obj` - which object the method should be called on
16476    ///     * must be valid
16477    ///     * must not be null
16478    ///     * must not be already garbage collected
16479    ///
16480    /// * `methodID` - method id of the method
16481    ///     * must not be null
16482    ///     * must be valid
16483    ///     * must be a static
16484    ///     * must actually be a method of `obj`
16485    ///     * must refer to a method with 3 arguments
16486    ///
16487    /// # Throws Java Exception
16488    /// * Whatever the method threw
16489    ///
16490    ///
16491    /// # Panics
16492    /// if asserts feature is enabled and UB was detected
16493    ///
16494    /// # Safety
16495    ///
16496    /// Current thread must not be detached from JNI.
16497    ///
16498    /// Current thread must not be currently throwing an exception.
16499    ///
16500    /// Current thread does not hold a critical reference.
16501    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16502    ///
16503    /// `obj` must a valid and not already garbage collected.
16504    /// `methodID` must be valid, static and actually be a method of `obj`, return void and have 3 arguments
16505    ///
16506    pub unsafe fn CallStaticVoidMethod3<A: JType, B: JType, C: JType>(&self, clazz: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) {
16507        unsafe {
16508            #[cfg(feature = "asserts")]
16509            {
16510                self.check_not_critical("CallStaticVoidMethod");
16511                self.check_no_exception("CallStaticVoidMethod");
16512                self.check_return_type_static("CallStaticVoidMethod", clazz, methodID, "void");
16513                self.check_parameter_types_static("CallStaticVoidMethod", clazz, methodID, arg1, 0, 3);
16514                self.check_parameter_types_static("CallStaticVoidMethod", clazz, methodID, arg2, 1, 3);
16515                self.check_parameter_types_static("CallStaticVoidMethod", clazz, methodID, arg3, 2, 3);
16516            }
16517            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...)>(141)(self.vtable, clazz, methodID, arg1, arg2, arg3);
16518        }
16519    }
16520
16521    ///
16522    /// Calls a static java method that returns an object
16523    ///
16524    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16525    ///
16526    ///
16527    /// # Arguments
16528    /// * `obj` - which object the method should be called on
16529    ///     * must be valid
16530    ///     * must not be null
16531    ///     * must not be already garbage collected
16532    ///
16533    /// * `methodID` - method id of the method
16534    ///     * must not be null
16535    ///     * must be valid
16536    ///     * must not be a static
16537    ///     * must actually be a method of `obj`
16538    ///
16539    /// * `args` - argument pointer
16540    ///     * can be null if the method has no arguments
16541    ///     * must not be null otherwise and point to the exact number of arguments the method expects
16542    ///
16543    /// # Returns
16544    /// Whatever the method returned or null if it threw
16545    ///
16546    /// # Throws Java Exception
16547    /// * Whatever the method threw
16548    ///
16549    ///
16550    /// # Panics
16551    /// if asserts feature is enabled and UB was detected
16552    ///
16553    /// # Safety
16554    ///
16555    /// Current thread must not be detached from JNI.
16556    ///
16557    /// Current thread must not be currently throwing an exception.
16558    ///
16559    /// Current thread does not hold a critical reference.
16560    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16561    ///
16562    /// `obj` must a valid and not already garbage collected.
16563    /// `methodID` must be valid, static and actually be a method of `obj` class and return an object
16564    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
16565    /// `args` union must contain types that match the java methods parameters.
16566    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
16567    ///
16568    pub unsafe fn CallStaticObjectMethodA(&self, obj: jclass, methodID: jmethodID, args: *const jtype) -> jobject {
16569        unsafe {
16570            #[cfg(feature = "asserts")]
16571            {
16572                self.check_not_critical("CallStaticObjectMethodA");
16573                self.check_no_exception("CallStaticObjectMethodA");
16574                self.check_return_type_static("CallStaticBooleanMethodA", obj, methodID, "object");
16575            }
16576            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(116)(self.vtable, obj, methodID, args)
16577        }
16578    }
16579
16580    ///
16581    /// Calls a static java method that has 0 arguments and returns an object
16582    ///
16583    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16584    ///
16585    ///
16586    /// # Arguments
16587    /// * `obj` - which object the method should be called on
16588    ///     * must be valid
16589    ///     * must not be null
16590    ///     * must not be already garbage collected
16591    ///
16592    /// * `methodID` - method id of the method
16593    ///     * must not be null
16594    ///     * must be valid
16595    ///     * must be a static
16596    ///     * must actually be a method of `obj`
16597    ///     * must refer to a method with 0 arguments
16598    ///
16599    /// # Returns
16600    /// Whatever the method returned or null if it threw
16601    ///
16602    /// # Throws Java Exception
16603    /// * Whatever the method threw
16604    ///
16605    ///
16606    /// # Panics
16607    /// if asserts feature is enabled and UB was detected
16608    ///
16609    /// # Safety
16610    ///
16611    /// Current thread must not be detached from JNI.
16612    ///
16613    /// Current thread must not be currently throwing an exception.
16614    ///
16615    /// Current thread does not hold a critical reference.
16616    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16617    ///
16618    /// `obj` must a valid and not already garbage collected.
16619    /// `methodID` must be valid, static and actually be a method of `obj`, return an object and have 0 arguments
16620    ///
16621    pub unsafe fn CallStaticObjectMethod0(&self, obj: jclass, methodID: jmethodID) -> jobject {
16622        unsafe {
16623            #[cfg(feature = "asserts")]
16624            {
16625                self.check_not_critical("CallStaticObjectMethod");
16626                self.check_no_exception("CallStaticObjectMethod");
16627                self.check_return_type_static("CallStaticObjectMethod", obj, methodID, "object");
16628            }
16629            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jobject>(114)(self.vtable, obj, methodID)
16630        }
16631    }
16632
16633    ///
16634    /// Calls a static java method that has 1 arguments and returns an object
16635    ///
16636    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16637    ///
16638    ///
16639    /// # Arguments
16640    /// * `obj` - which object the method should be called on
16641    ///     * must be valid
16642    ///     * must not be null
16643    ///     * must not be already garbage collected
16644    ///
16645    /// * `methodID` - method id of the method
16646    ///     * must not be null
16647    ///     * must be valid
16648    ///     * must be a static
16649    ///     * must actually be a method of `obj`
16650    ///     * must refer to a method with 1 arguments
16651    ///
16652    /// # Returns
16653    /// Whatever the method returned or null if it threw
16654    ///
16655    /// # Throws Java Exception
16656    /// * Whatever the method threw
16657    ///
16658    ///
16659    /// # Panics
16660    /// if asserts feature is enabled and UB was detected
16661    ///
16662    /// # Safety
16663    ///
16664    /// Current thread must not be detached from JNI.
16665    ///
16666    /// Current thread must not be currently throwing an exception.
16667    ///
16668    /// Current thread does not hold a critical reference.
16669    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16670    ///
16671    /// `obj` must a valid and not already garbage collected.
16672    /// `methodID` must be valid, static and actually be a method of `obj`, return an object and have 1 arguments
16673    ///
16674    pub unsafe fn CallStaticObjectMethod1<A: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A) -> jobject {
16675        unsafe {
16676            #[cfg(feature = "asserts")]
16677            {
16678                self.check_not_critical("CallStaticObjectMethod");
16679                self.check_no_exception("CallStaticObjectMethod");
16680                self.check_return_type_static("CallStaticObjectMethod", obj, methodID, "object");
16681                self.check_parameter_types_static("CallStaticObjectMethod", obj, methodID, arg1, 0, 1);
16682            }
16683            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jobject>(114)(self.vtable, obj, methodID, arg1)
16684        }
16685    }
16686
16687    ///
16688    /// Calls a static java method that has 2 arguments and returns an object
16689    ///
16690    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16691    ///
16692    ///
16693    /// # Arguments
16694    /// * `obj` - which object the method should be called on
16695    ///     * must be valid
16696    ///     * must not be null
16697    ///     * must not be already garbage collected
16698    ///
16699    /// * `methodID` - method id of the method
16700    ///     * must not be null
16701    ///     * must be valid
16702    ///     * must be a static
16703    ///     * must actually be a method of `obj`
16704    ///     * must refer to a method with 2 arguments
16705    ///
16706    /// # Returns
16707    /// Whatever the method returned or null if it threw
16708    ///
16709    /// # Throws Java Exception
16710    /// * Whatever the method threw
16711    ///
16712    ///
16713    /// # Panics
16714    /// if asserts feature is enabled and UB was detected
16715    ///
16716    /// # Safety
16717    ///
16718    /// Current thread must not be detached from JNI.
16719    ///
16720    /// Current thread must not be currently throwing an exception.
16721    ///
16722    /// Current thread does not hold a critical reference.
16723    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16724    ///
16725    /// `obj` must a valid and not already garbage collected.
16726    /// `methodID` must be valid, static and actually be a method of `obj`, return an object and have 2 arguments
16727    ///
16728    pub unsafe fn CallStaticObjectMethod2<A: JType, B: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jobject {
16729        unsafe {
16730            #[cfg(feature = "asserts")]
16731            {
16732                self.check_not_critical("CallStaticObjectMethod");
16733                self.check_no_exception("CallStaticObjectMethod");
16734                self.check_return_type_static("CallStaticObjectMethod", obj, methodID, "object");
16735                self.check_parameter_types_static("CallStaticObjectMethod", obj, methodID, arg1, 0, 2);
16736                self.check_parameter_types_static("CallStaticObjectMethod", obj, methodID, arg2, 1, 2);
16737            }
16738            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jobject>(114)(self.vtable, obj, methodID, arg1, arg2)
16739        }
16740    }
16741
16742    ///
16743    /// Calls a static java method that has 3 arguments and returns an object
16744    ///
16745    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16746    ///
16747    ///
16748    /// # Arguments
16749    /// * `obj` - which object the method should be called on
16750    ///     * must be valid
16751    ///     * must not be null
16752    ///     * must not be already garbage collected
16753    ///
16754    /// * `methodID` - method id of the method
16755    ///     * must not be null
16756    ///     * must be valid
16757    ///     * must be a static
16758    ///     * must actually be a method of `obj`
16759    ///     * must refer to a method with 3 arguments
16760    ///
16761    /// # Returns
16762    /// Whatever the method returned or null if it threw
16763    ///
16764    /// # Throws Java Exception
16765    /// * Whatever the method threw
16766    ///
16767    ///
16768    /// # Panics
16769    /// if asserts feature is enabled and UB was detected
16770    ///
16771    /// # Safety
16772    ///
16773    /// Current thread must not be detached from JNI.
16774    ///
16775    /// Current thread must not be currently throwing an exception.
16776    ///
16777    /// Current thread does not hold a critical reference.
16778    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16779    ///
16780    /// `obj` must a valid and not already garbage collected.
16781    /// `methodID` must be valid, static and actually be a method of `obj`, return an object and have 3 arguments
16782    ///
16783    pub unsafe fn CallStaticObjectMethod3<A: JType, B: JType, C: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jobject {
16784        unsafe {
16785            #[cfg(feature = "asserts")]
16786            {
16787                self.check_not_critical("CallStaticObjectMethod");
16788                self.check_no_exception("CallStaticObjectMethod");
16789                self.check_return_type_static("CallStaticObjectMethod", obj, methodID, "object");
16790                self.check_parameter_types_static("CallStaticObjectMethod", obj, methodID, arg1, 0, 3);
16791                self.check_parameter_types_static("CallStaticObjectMethod", obj, methodID, arg2, 1, 3);
16792                self.check_parameter_types_static("CallStaticObjectMethod", obj, methodID, arg3, 2, 3);
16793            }
16794            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jobject>(114)(self.vtable, obj, methodID, arg1, arg2, arg3)
16795        }
16796    }
16797
16798    ///
16799    /// Calls a static java method that returns a boolean
16800    ///
16801    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16802    ///
16803    ///
16804    /// # Arguments
16805    /// * `obj` - which object the method should be called on
16806    ///     * must be valid
16807    ///     * must not be null
16808    ///     * must not be already garbage collected
16809    ///
16810    /// * `methodID` - method id of the method
16811    ///     * must not be null
16812    ///     * must be valid
16813    ///     * must not be a static
16814    ///     * must actually be a method of `obj`
16815    ///
16816    /// * `args` - argument pointer
16817    ///     * can be null if the method has no arguments
16818    ///     * must not be null otherwise and point to the exact number of arguments the method expects
16819    ///
16820    /// # Returns
16821    /// Whatever the method returned or null if it threw
16822    ///
16823    /// # Throws Java Exception
16824    /// * Whatever the method threw
16825    ///
16826    ///
16827    /// # Panics
16828    /// if asserts feature is enabled and UB was detected
16829    ///
16830    /// # Safety
16831    ///
16832    /// Current thread must not be detached from JNI.
16833    ///
16834    /// Current thread must not be currently throwing an exception.
16835    ///
16836    /// Current thread does not hold a critical reference.
16837    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16838    ///
16839    /// `obj` must a valid and not already garbage collected.
16840    /// `methodID` must be valid, static and actually be a method of `obj` class and return a boolean
16841    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
16842    /// `args` union must contain types that match the java methods parameters.
16843    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
16844    ///
16845    pub unsafe fn CallStaticBooleanMethodA(&self, obj: jclass, methodID: jmethodID, args: *const jtype) -> bool {
16846        unsafe {
16847            #[cfg(feature = "asserts")]
16848            {
16849                self.check_not_critical("CallStaticBooleanMethodA");
16850                self.check_no_exception("CallStaticBooleanMethodA");
16851                self.check_return_type_static("CallStaticBooleanMethodA", obj, methodID, "boolean");
16852            }
16853            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jboolean>(119)(self.vtable, obj, methodID, args).as_bool()
16854        }
16855    }
16856
16857    ///
16858    /// Calls a static java method that has 0 arguments and returns boolean
16859    ///
16860    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16861    ///
16862    ///
16863    /// # Arguments
16864    /// * `obj` - which object the method should be called on
16865    ///     * must be valid
16866    ///     * must not be null
16867    ///     * must not be already garbage collected
16868    ///
16869    /// * `methodID` - method id of the method
16870    ///     * must not be null
16871    ///     * must be valid
16872    ///     * must be a static
16873    ///     * must actually be a method of `obj`
16874    ///     * must refer to a method with 0 arguments
16875    ///
16876    /// # Returns
16877    /// Whatever the method returned or false if it threw
16878    ///
16879    /// # Throws Java Exception
16880    /// * Whatever the method threw
16881    ///
16882    ///
16883    /// # Panics
16884    /// if asserts feature is enabled and UB was detected
16885    ///
16886    /// # Safety
16887    ///
16888    /// Current thread must not be detached from JNI.
16889    ///
16890    /// Current thread must not be currently throwing an exception.
16891    ///
16892    /// Current thread does not hold a critical reference.
16893    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16894    ///
16895    /// `obj` must a valid and not already garbage collected.
16896    /// `methodID` must be valid, static and actually be a method of `obj`, return boolean and have 0 arguments
16897    ///
16898    pub unsafe fn CallStaticBooleanMethod0(&self, obj: jclass, methodID: jmethodID) -> bool {
16899        unsafe {
16900            #[cfg(feature = "asserts")]
16901            {
16902                self.check_not_critical("CallStaticBooleanMethod");
16903                self.check_no_exception("CallStaticBooleanMethod");
16904                self.check_return_type_static("CallStaticBooleanMethod", obj, methodID, "boolean");
16905            }
16906            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jboolean>(117)(self.vtable, obj, methodID).as_bool()
16907        }
16908    }
16909
16910    ///
16911    /// Calls a static java method that has 1 arguments and returns boolean
16912    ///
16913    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16914    ///
16915    ///
16916    /// # Arguments
16917    /// * `obj` - which object the method should be called on
16918    ///     * must be valid
16919    ///     * must not be null
16920    ///     * must not be already garbage collected
16921    ///
16922    /// * `methodID` - method id of the method
16923    ///     * must not be null
16924    ///     * must be valid
16925    ///     * must be a static
16926    ///     * must actually be a method of `obj`
16927    ///     * must refer to a method with 1 arguments
16928    ///
16929    /// # Returns
16930    /// Whatever the method returned or false if it threw
16931    ///
16932    /// # Throws Java Exception
16933    /// * Whatever the method threw
16934    ///
16935    ///
16936    /// # Panics
16937    /// if asserts feature is enabled and UB was detected
16938    ///
16939    /// # Safety
16940    ///
16941    /// Current thread must not be detached from JNI.
16942    ///
16943    /// Current thread must not be currently throwing an exception.
16944    ///
16945    /// Current thread does not hold a critical reference.
16946    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16947    ///
16948    /// `obj` must a valid and not already garbage collected.
16949    /// `methodID` must be valid, static and actually be a method of `obj`, return boolean and have 1 arguments
16950    ///
16951    pub unsafe fn CallStaticBooleanMethod1<A: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A) -> bool {
16952        unsafe {
16953            #[cfg(feature = "asserts")]
16954            {
16955                self.check_not_critical("CallStaticBooleanMethod");
16956                self.check_no_exception("CallStaticBooleanMethod");
16957                self.check_return_type_static("CallStaticBooleanMethod", obj, methodID, "boolean");
16958                self.check_parameter_types_static("CallStaticBooleanMethod", obj, methodID, arg1, 0, 1);
16959            }
16960            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jboolean>(117)(self.vtable, obj, methodID, arg1).as_bool()
16961        }
16962    }
16963
16964    ///
16965    /// Calls a static java method that has 2 arguments and returns boolean
16966    ///
16967    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16968    ///
16969    ///
16970    /// # Arguments
16971    /// * `obj` - which object the method should be called on
16972    ///     * must be valid
16973    ///     * must not be null
16974    ///     * must not be already garbage collected
16975    ///
16976    /// * `methodID` - method id of the method
16977    ///     * must not be null
16978    ///     * must be valid
16979    ///     * must be a static
16980    ///     * must actually be a method of `obj`
16981    ///     * must refer to a method with 2 arguments
16982    ///
16983    /// # Returns
16984    /// Whatever the method returned or false if it threw
16985    ///
16986    /// # Throws Java Exception
16987    /// * Whatever the method threw
16988    ///
16989    ///
16990    /// # Panics
16991    /// if asserts feature is enabled and UB was detected
16992    ///
16993    /// # Safety
16994    ///
16995    /// Current thread must not be detached from JNI.
16996    ///
16997    /// Current thread must not be currently throwing an exception.
16998    ///
16999    /// Current thread does not hold a critical reference.
17000    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17001    ///
17002    /// `obj` must a valid and not already garbage collected.
17003    /// `methodID` must be valid, static and actually be a method of `obj`, return boolean and have 2 arguments
17004    ///
17005    pub unsafe fn CallStaticBooleanMethod2<A: JType, B: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B) -> bool {
17006        unsafe {
17007            #[cfg(feature = "asserts")]
17008            {
17009                self.check_not_critical("CallStaticBooleanMethod");
17010                self.check_no_exception("CallStaticBooleanMethod");
17011                self.check_return_type_static("CallStaticBooleanMethod", obj, methodID, "boolean");
17012                self.check_parameter_types_static("CallStaticBooleanMethod", obj, methodID, arg1, 0, 2);
17013                self.check_parameter_types_static("CallStaticBooleanMethod", obj, methodID, arg2, 1, 2);
17014            }
17015            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jboolean>(117)(self.vtable, obj, methodID, arg1, arg2).as_bool()
17016        }
17017    }
17018
17019    ///
17020    /// Calls a static java method that has 3 arguments and returns boolean
17021    ///
17022    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17023    ///
17024    ///
17025    /// # Arguments
17026    /// * `obj` - which object the method should be called on
17027    ///     * must be valid
17028    ///     * must not be null
17029    ///     * must not be already garbage collected
17030    ///
17031    /// * `methodID` - method id of the method
17032    ///     * must not be null
17033    ///     * must be valid
17034    ///     * must be a static
17035    ///     * must actually be a method of `obj`
17036    ///     * must refer to a method with 3 arguments
17037    ///
17038    /// # Returns
17039    /// Whatever the method returned or false if it threw
17040    ///
17041    /// # Throws Java Exception
17042    /// * Whatever the method threw
17043    ///
17044    ///
17045    /// # Panics
17046    /// if asserts feature is enabled and UB was detected
17047    ///
17048    /// # Safety
17049    ///
17050    /// Current thread must not be detached from JNI.
17051    ///
17052    /// Current thread must not be currently throwing an exception.
17053    ///
17054    /// Current thread does not hold a critical reference.
17055    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17056    ///
17057    /// `obj` must a valid and not already garbage collected.
17058    /// `methodID` must be valid, static and actually be a method of `obj`, return boolean and have 3 arguments
17059    ///
17060    pub unsafe fn CallStaticBooleanMethod3<A: JType, B: JType, C: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> bool {
17061        unsafe {
17062            #[cfg(feature = "asserts")]
17063            {
17064                self.check_not_critical("CallStaticBooleanMethod");
17065                self.check_no_exception("CallStaticBooleanMethod");
17066                self.check_return_type_static("CallStaticBooleanMethod", obj, methodID, "boolean");
17067                self.check_parameter_types_static("CallStaticBooleanMethod", obj, methodID, arg1, 0, 3);
17068                self.check_parameter_types_static("CallStaticBooleanMethod", obj, methodID, arg2, 1, 3);
17069                self.check_parameter_types_static("CallStaticBooleanMethod", obj, methodID, arg3, 2, 3);
17070            }
17071            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jboolean>(117)(self.vtable, obj, methodID, arg1, arg2, arg3).as_bool()
17072        }
17073    }
17074
17075    ///
17076    /// Calls a static java method that returns a byte
17077    ///
17078    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17079    ///
17080    ///
17081    /// # Arguments
17082    /// * `obj` - which object the method should be called on
17083    ///     * must be valid
17084    ///     * must not be null
17085    ///     * must not be already garbage collected
17086    ///
17087    /// * `methodID` - method id of the method
17088    ///     * must not be null
17089    ///     * must be valid
17090    ///     * must not be a static
17091    ///     * must actually be a method of `obj`
17092    ///
17093    /// * `args` - argument pointer
17094    ///     * can be null if the method has no arguments
17095    ///     * must not be null otherwise and point to the exact number of arguments the method expects
17096    ///
17097    /// # Returns
17098    /// Whatever the method returned or 0 if it threw
17099    ///
17100    /// # Throws Java Exception
17101    /// * Whatever the method threw
17102    ///
17103    ///
17104    /// # Panics
17105    /// if asserts feature is enabled and UB was detected
17106    ///
17107    /// # Safety
17108    ///
17109    /// Current thread must not be detached from JNI.
17110    ///
17111    /// Current thread must not be currently throwing an exception.
17112    ///
17113    /// Current thread does not hold a critical reference.
17114    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17115    ///
17116    /// `obj` must a valid and not already garbage collected.
17117    /// `methodID` must be valid, static and actually be a method of `obj` class and return a byte
17118    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
17119    /// `args` union must contain types that match the java methods parameters.
17120    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
17121    ///
17122    pub unsafe fn CallStaticByteMethodA(&self, obj: jclass, methodID: jmethodID, args: *const jtype) -> jbyte {
17123        unsafe {
17124            #[cfg(feature = "asserts")]
17125            {
17126                self.check_not_critical("CallStaticByteMethodA");
17127                self.check_no_exception("CallStaticByteMethodA");
17128                self.check_return_type_static("CallStaticByteMethodA", obj, methodID, "byte");
17129            }
17130            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jbyte>(122)(self.vtable, obj, methodID, args)
17131        }
17132    }
17133
17134    ///
17135    /// Calls a static java method that has 0 arguments and returns byte
17136    ///
17137    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17138    ///
17139    ///
17140    /// # Arguments
17141    /// * `obj` - which object the method should be called on
17142    ///     * must be valid
17143    ///     * must not be null
17144    ///     * must not be already garbage collected
17145    ///
17146    /// * `methodID` - method id of the method
17147    ///     * must not be null
17148    ///     * must be valid
17149    ///     * must be a static
17150    ///     * must actually be a method of `obj`
17151    ///     * must refer to a method with 0 arguments
17152    ///
17153    /// # Returns
17154    /// Whatever the method returned or 0 if it threw
17155    ///
17156    /// # Throws Java Exception
17157    /// * Whatever the method threw
17158    ///
17159    ///
17160    /// # Panics
17161    /// if asserts feature is enabled and UB was detected
17162    ///
17163    /// # Safety
17164    ///
17165    /// Current thread must not be detached from JNI.
17166    ///
17167    /// Current thread must not be currently throwing an exception.
17168    ///
17169    /// Current thread does not hold a critical reference.
17170    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17171    ///
17172    /// `obj` must a valid and not already garbage collected.
17173    /// `methodID` must be valid, static and actually be a method of `obj`, return byte and have 0 arguments
17174    ///
17175    pub unsafe fn CallStaticByteMethod0(&self, obj: jclass, methodID: jmethodID) -> jbyte {
17176        unsafe {
17177            #[cfg(feature = "asserts")]
17178            {
17179                self.check_not_critical("CallStaticByteMethod");
17180                self.check_no_exception("CallStaticByteMethod");
17181                self.check_return_type_static("CallStaticByteMethod", obj, methodID, "byte");
17182            }
17183            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jbyte>(120)(self.vtable, obj, methodID)
17184        }
17185    }
17186
17187    ///
17188    /// Calls a static java method that has 1 arguments and returns byte
17189    ///
17190    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17191    ///
17192    ///
17193    /// # Arguments
17194    /// * `obj` - which object the method should be called on
17195    ///     * must be valid
17196    ///     * must not be null
17197    ///     * must not be already garbage collected
17198    ///
17199    /// * `methodID` - method id of the method
17200    ///     * must not be null
17201    ///     * must be valid
17202    ///     * must be a static
17203    ///     * must actually be a method of `obj`
17204    ///     * must refer to a method with 1 arguments
17205    ///
17206    /// # Returns
17207    /// Whatever the method returned or 0 if it threw
17208    ///
17209    /// # Throws Java Exception
17210    /// * Whatever the method threw
17211    ///
17212    ///
17213    /// # Panics
17214    /// if asserts feature is enabled and UB was detected
17215    ///
17216    /// # Safety
17217    ///
17218    /// Current thread must not be detached from JNI.
17219    ///
17220    /// Current thread must not be currently throwing an exception.
17221    ///
17222    /// Current thread does not hold a critical reference.
17223    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17224    ///
17225    /// `obj` must a valid and not already garbage collected.
17226    /// `methodID` must be valid, static and actually be a method of `obj`, return byte and have 1 arguments
17227    ///
17228    pub unsafe fn CallStaticByteMethod1<A: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A) -> jbyte {
17229        unsafe {
17230            #[cfg(feature = "asserts")]
17231            {
17232                self.check_not_critical("CallStaticByteMethod");
17233                self.check_no_exception("CallStaticByteMethod");
17234                self.check_return_type_static("CallStaticByteMethod", obj, methodID, "byte");
17235                self.check_parameter_types_static("CallStaticByteMethod", obj, methodID, arg1, 0, 1);
17236            }
17237            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jbyte>(120)(self.vtable, obj, methodID, arg1)
17238        }
17239    }
17240
17241    ///
17242    /// Calls a static java method that has 2 arguments and returns byte
17243    ///
17244    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17245    ///
17246    ///
17247    /// # Arguments
17248    /// * `obj` - which object the method should be called on
17249    ///     * must be valid
17250    ///     * must not be null
17251    ///     * must not be already garbage collected
17252    ///
17253    /// * `methodID` - method id of the method
17254    ///     * must not be null
17255    ///     * must be valid
17256    ///     * must be a static
17257    ///     * must actually be a method of `obj`
17258    ///     * must refer to a method with 2 arguments
17259    ///
17260    /// # Returns
17261    /// Whatever the method returned or 0 if it threw
17262    ///
17263    /// # Throws Java Exception
17264    /// * Whatever the method threw
17265    ///
17266    ///
17267    /// # Panics
17268    /// if asserts feature is enabled and UB was detected
17269    ///
17270    /// # Safety
17271    ///
17272    /// Current thread must not be detached from JNI.
17273    ///
17274    /// Current thread must not be currently throwing an exception.
17275    ///
17276    /// Current thread does not hold a critical reference.
17277    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17278    ///
17279    /// `obj` must a valid and not already garbage collected.
17280    /// `methodID` must be valid, static and actually be a method of `obj`, return byte and have 2 arguments
17281    ///
17282    pub unsafe fn CallStaticByteMethod2<A: JType, B: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jbyte {
17283        unsafe {
17284            #[cfg(feature = "asserts")]
17285            {
17286                self.check_not_critical("CallStaticByteMethod");
17287                self.check_no_exception("CallStaticByteMethod");
17288                self.check_return_type_static("CallStaticByteMethod", obj, methodID, "byte");
17289                self.check_parameter_types_static("CallStaticByteMethod", obj, methodID, arg1, 0, 2);
17290                self.check_parameter_types_static("CallStaticByteMethod", obj, methodID, arg2, 1, 2);
17291            }
17292            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jbyte>(120)(self.vtable, obj, methodID, arg1, arg2)
17293        }
17294    }
17295
17296    ///
17297    /// Calls a static java method that has 3 arguments and returns byte
17298    ///
17299    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17300    ///
17301    ///
17302    /// # Arguments
17303    /// * `obj` - which object the method should be called on
17304    ///     * must be valid
17305    ///     * must not be null
17306    ///     * must not be already garbage collected
17307    ///
17308    /// * `methodID` - method id of the method
17309    ///     * must not be null
17310    ///     * must be valid
17311    ///     * must be a static
17312    ///     * must actually be a method of `obj`
17313    ///     * must refer to a method with 3 arguments
17314    ///
17315    /// # Returns
17316    /// Whatever the method returned or 0 if it threw
17317    ///
17318    /// # Throws Java Exception
17319    /// * Whatever the method threw
17320    ///
17321    ///
17322    /// # Panics
17323    /// if asserts feature is enabled and UB was detected
17324    ///
17325    /// # Safety
17326    ///
17327    /// Current thread must not be detached from JNI.
17328    ///
17329    /// Current thread must not be currently throwing an exception.
17330    ///
17331    /// Current thread does not hold a critical reference.
17332    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17333    ///
17334    /// `obj` must a valid and not already garbage collected.
17335    /// `methodID` must be valid, static and actually be a method of `obj`, return byte and have 3 arguments
17336    ///
17337    pub unsafe fn CallStaticByteMethod3<A: JType, B: JType, C: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jbyte {
17338        unsafe {
17339            #[cfg(feature = "asserts")]
17340            {
17341                self.check_not_critical("CallStaticByteMethod");
17342                self.check_no_exception("CallStaticByteMethod");
17343                self.check_return_type_static("CallStaticByteMethod", obj, methodID, "byte");
17344                self.check_parameter_types_static("CallStaticByteMethod", obj, methodID, arg1, 0, 3);
17345                self.check_parameter_types_static("CallStaticByteMethod", obj, methodID, arg2, 1, 3);
17346                self.check_parameter_types_static("CallStaticByteMethod", obj, methodID, arg3, 2, 3);
17347            }
17348            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jbyte>(120)(self.vtable, obj, methodID, arg1, arg2, arg3)
17349        }
17350    }
17351
17352    ///
17353    /// Calls a static java method that returns a char
17354    ///
17355    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17356    ///
17357    ///
17358    /// # Arguments
17359    /// * `obj` - which object the method should be called on
17360    ///     * must be valid
17361    ///     * must not be null
17362    ///     * must not be already garbage collected
17363    ///
17364    /// * `methodID` - method id of the method
17365    ///     * must not be null
17366    ///     * must be valid
17367    ///     * must not be a static
17368    ///     * must actually be a method of `obj`
17369    ///
17370    /// * `args` - argument pointer
17371    ///     * can be null if the method has no arguments
17372    ///     * must not be null otherwise and point to the exact number of arguments the method expects
17373    ///
17374    /// # Returns
17375    /// Whatever the method returned or 0 if it threw
17376    ///
17377    /// # Throws Java Exception
17378    /// * Whatever the method threw
17379    ///
17380    ///
17381    /// # Panics
17382    /// if asserts feature is enabled and UB was detected
17383    ///
17384    /// # Safety
17385    ///
17386    /// Current thread must not be detached from JNI.
17387    ///
17388    /// Current thread must not be currently throwing an exception.
17389    ///
17390    /// Current thread does not hold a critical reference.
17391    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17392    ///
17393    /// `obj` must a valid and not already garbage collected.
17394    /// `methodID` must be valid, static and actually be a method of `obj` class and return a char
17395    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
17396    /// `args` union must contain types that match the java methods parameters.
17397    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
17398    ///
17399    pub unsafe fn CallStaticCharMethodA(&self, obj: jclass, methodID: jmethodID, args: *const jtype) -> jchar {
17400        unsafe {
17401            #[cfg(feature = "asserts")]
17402            {
17403                self.check_not_critical("CallStaticCharMethodA");
17404                self.check_no_exception("CallStaticCharMethodA");
17405                self.check_return_type_static("CallStaticCharMethodA", obj, methodID, "char");
17406            }
17407            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jchar>(125)(self.vtable, obj, methodID, args)
17408        }
17409    }
17410
17411    ///
17412    /// Calls a static java method that has 0 arguments and returns char
17413    ///
17414    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17415    ///
17416    ///
17417    /// # Arguments
17418    /// * `obj` - which object the method should be called on
17419    ///     * must be valid
17420    ///     * must not be null
17421    ///     * must not be already garbage collected
17422    ///
17423    /// * `methodID` - method id of the method
17424    ///     * must not be null
17425    ///     * must be valid
17426    ///     * must be a static
17427    ///     * must actually be a method of `obj`
17428    ///     * must refer to a method with 0 arguments
17429    ///
17430    /// # Returns
17431    /// Whatever the method returned or 0 if it threw
17432    ///
17433    /// # Throws Java Exception
17434    /// * Whatever the method threw
17435    ///
17436    ///
17437    /// # Panics
17438    /// if asserts feature is enabled and UB was detected
17439    ///
17440    /// # Safety
17441    ///
17442    /// Current thread must not be detached from JNI.
17443    ///
17444    /// Current thread must not be currently throwing an exception.
17445    ///
17446    /// Current thread does not hold a critical reference.
17447    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17448    ///
17449    /// `obj` must a valid and not already garbage collected.
17450    /// `methodID` must be valid, static and actually be a method of `obj`, return char and have 0 arguments
17451    ///
17452    pub unsafe fn CallStaticCharMethod0(&self, obj: jclass, methodID: jmethodID) -> jchar {
17453        unsafe {
17454            #[cfg(feature = "asserts")]
17455            {
17456                self.check_not_critical("CallStaticCharMethod");
17457                self.check_no_exception("CallStaticCharMethod");
17458                self.check_return_type_static("CallStaticCharMethod", obj, methodID, "char");
17459            }
17460            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jchar>(123)(self.vtable, obj, methodID)
17461        }
17462    }
17463
17464    ///
17465    /// Calls a static java method that has 1 arguments and returns char
17466    ///
17467    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17468    ///
17469    ///
17470    /// # Arguments
17471    /// * `obj` - which object the method should be called on
17472    ///     * must be valid
17473    ///     * must not be null
17474    ///     * must not be already garbage collected
17475    ///
17476    /// * `methodID` - method id of the method
17477    ///     * must not be null
17478    ///     * must be valid
17479    ///     * must be a static
17480    ///     * must actually be a method of `obj`
17481    ///     * must refer to a method with 1 arguments
17482    ///
17483    /// # Returns
17484    /// Whatever the method returned or 0 if it threw
17485    ///
17486    /// # Throws Java Exception
17487    /// * Whatever the method threw
17488    ///
17489    ///
17490    /// # Panics
17491    /// if asserts feature is enabled and UB was detected
17492    ///
17493    /// # Safety
17494    ///
17495    /// Current thread must not be detached from JNI.
17496    ///
17497    /// Current thread must not be currently throwing an exception.
17498    ///
17499    /// Current thread does not hold a critical reference.
17500    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17501    ///
17502    /// `obj` must a valid and not already garbage collected.
17503    /// `methodID` must be valid, static and actually be a method of `obj`, return char and have 1 arguments
17504    ///
17505    pub unsafe fn CallStaticCharMethod1<A: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A) -> jchar {
17506        unsafe {
17507            #[cfg(feature = "asserts")]
17508            {
17509                self.check_not_critical("CallStaticCharMethod");
17510                self.check_no_exception("CallStaticCharMethod");
17511                self.check_return_type_static("CallStaticCharMethod", obj, methodID, "char");
17512                self.check_parameter_types_static("CallStaticCharMethod", obj, methodID, arg1, 0, 1);
17513            }
17514            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jchar>(123)(self.vtable, obj, methodID, arg1)
17515        }
17516    }
17517
17518    ///
17519    /// Calls a static java method that has 2 arguments and returns char
17520    ///
17521    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17522    ///
17523    ///
17524    /// # Arguments
17525    /// * `obj` - which object the method should be called on
17526    ///     * must be valid
17527    ///     * must not be null
17528    ///     * must not be already garbage collected
17529    ///
17530    /// * `methodID` - method id of the method
17531    ///     * must not be null
17532    ///     * must be valid
17533    ///     * must be a static
17534    ///     * must actually be a method of `obj`
17535    ///     * must refer to a method with 2 arguments
17536    ///
17537    /// # Returns
17538    /// Whatever the method returned or 0 if it threw
17539    ///
17540    /// # Throws Java Exception
17541    /// * Whatever the method threw
17542    ///
17543    ///
17544    /// # Panics
17545    /// if asserts feature is enabled and UB was detected
17546    ///
17547    /// # Safety
17548    ///
17549    /// Current thread must not be detached from JNI.
17550    ///
17551    /// Current thread must not be currently throwing an exception.
17552    ///
17553    /// Current thread does not hold a critical reference.
17554    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17555    ///
17556    /// `obj` must a valid and not already garbage collected.
17557    /// `methodID` must be valid, static and actually be a method of `obj`, return char and have 2 arguments
17558    ///
17559    pub unsafe fn CallStaticCharMethod2<A: JType, B: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jchar {
17560        unsafe {
17561            #[cfg(feature = "asserts")]
17562            {
17563                self.check_not_critical("CallStaticCharMethod");
17564                self.check_no_exception("CallStaticCharMethod");
17565                self.check_return_type_static("CallStaticCharMethod", obj, methodID, "char");
17566                self.check_parameter_types_static("CallStaticCharMethod", obj, methodID, arg1, 0, 2);
17567                self.check_parameter_types_static("CallStaticCharMethod", obj, methodID, arg2, 1, 2);
17568            }
17569            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jchar>(123)(self.vtable, obj, methodID, arg1, arg2)
17570        }
17571    }
17572
17573    ///
17574    /// Calls a static java method that has 3 arguments and returns char
17575    ///
17576    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17577    ///
17578    ///
17579    /// # Arguments
17580    /// * `obj` - which object the method should be called on
17581    ///     * must be valid
17582    ///     * must not be null
17583    ///     * must not be already garbage collected
17584    ///
17585    /// * `methodID` - method id of the method
17586    ///     * must not be null
17587    ///     * must be valid
17588    ///     * must be a static
17589    ///     * must actually be a method of `obj`
17590    ///     * must refer to a method with 3 arguments
17591    ///
17592    /// # Returns
17593    /// Whatever the method returned or 0 if it threw
17594    ///
17595    /// # Throws Java Exception
17596    /// * Whatever the method threw
17597    ///
17598    ///
17599    /// # Panics
17600    /// if asserts feature is enabled and UB was detected
17601    ///
17602    /// # Safety
17603    ///
17604    /// Current thread must not be detached from JNI.
17605    ///
17606    /// Current thread must not be currently throwing an exception.
17607    ///
17608    /// Current thread does not hold a critical reference.
17609    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17610    ///
17611    /// `obj` must a valid and not already garbage collected.
17612    /// `methodID` must be valid, static and actually be a method of `obj`, return char and have 3 arguments
17613    ///
17614    pub unsafe fn CallStaticCharMethod3<A: JType, B: JType, C: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jchar {
17615        unsafe {
17616            #[cfg(feature = "asserts")]
17617            {
17618                self.check_not_critical("CallStaticCharMethod");
17619                self.check_no_exception("CallStaticCharMethod");
17620                self.check_return_type_static("CallStaticCharMethod", obj, methodID, "char");
17621                self.check_parameter_types_static("CallStaticCharMethod", obj, methodID, arg1, 0, 3);
17622                self.check_parameter_types_static("CallStaticCharMethod", obj, methodID, arg2, 1, 3);
17623                self.check_parameter_types_static("CallStaticCharMethod", obj, methodID, arg3, 2, 3);
17624            }
17625            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jchar>(123)(self.vtable, obj, methodID, arg1, arg2, arg3)
17626        }
17627    }
17628
17629    ///
17630    /// Calls a static java method that returns a short
17631    ///
17632    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17633    ///
17634    ///
17635    /// # Arguments
17636    /// * `obj` - which object the method should be called on
17637    ///     * must be valid
17638    ///     * must not be null
17639    ///     * must not be already garbage collected
17640    ///
17641    /// * `methodID` - method id of the method
17642    ///     * must not be null
17643    ///     * must be valid
17644    ///     * must not be a static
17645    ///     * must actually be a method of `obj`
17646    ///
17647    /// * `args` - argument pointer
17648    ///     * can be null if the method has no arguments
17649    ///     * must not be null otherwise and point to the exact number of arguments the method expects
17650    ///
17651    /// # Returns
17652    /// Whatever the method returned or 0 if it threw
17653    ///
17654    /// # Throws Java Exception
17655    /// * Whatever the method threw
17656    ///
17657    ///
17658    /// # Panics
17659    /// if asserts feature is enabled and UB was detected
17660    ///
17661    /// # Safety
17662    ///
17663    /// Current thread must not be detached from JNI.
17664    ///
17665    /// Current thread must not be currently throwing an exception.
17666    ///
17667    /// Current thread does not hold a critical reference.
17668    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17669    ///
17670    /// `obj` must a valid and not already garbage collected.
17671    /// `methodID` must be valid, static and actually be a method of `obj` class and return a short
17672    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
17673    /// `args` union must contain types that match the java methods parameters.
17674    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
17675    ///
17676    pub unsafe fn CallStaticShortMethodA(&self, obj: jclass, methodID: jmethodID, args: *const jtype) -> jshort {
17677        unsafe {
17678            #[cfg(feature = "asserts")]
17679            {
17680                self.check_not_critical("CallStaticShortMethodA");
17681                self.check_no_exception("CallStaticShortMethodA");
17682                self.check_return_type_static("CallStaticShortMethodA", obj, methodID, "short");
17683            }
17684            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jshort>(128)(self.vtable, obj, methodID, args)
17685        }
17686    }
17687
17688    ///
17689    /// Calls a static java method that has 0 arguments and returns short
17690    ///
17691    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17692    ///
17693    ///
17694    /// # Arguments
17695    /// * `obj` - which object the method should be called on
17696    ///     * must be valid
17697    ///     * must not be null
17698    ///     * must not be already garbage collected
17699    ///
17700    /// * `methodID` - method id of the method
17701    ///     * must not be null
17702    ///     * must be valid
17703    ///     * must be a static
17704    ///     * must actually be a method of `obj`
17705    ///     * must refer to a method with 0 arguments
17706    ///
17707    /// # Returns
17708    /// Whatever the method returned or 0 if it threw
17709    ///
17710    /// # Throws Java Exception
17711    /// * Whatever the method threw
17712    ///
17713    ///
17714    /// # Panics
17715    /// if asserts feature is enabled and UB was detected
17716    ///
17717    /// # Safety
17718    ///
17719    /// Current thread must not be detached from JNI.
17720    ///
17721    /// Current thread must not be currently throwing an exception.
17722    ///
17723    /// Current thread does not hold a critical reference.
17724    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17725    ///
17726    /// `obj` must a valid and not already garbage collected.
17727    /// `methodID` must be valid, static and actually be a method of `obj`, return short and have 0 arguments
17728    ///
17729    pub unsafe fn CallStaticShortMethod0(&self, obj: jclass, methodID: jmethodID) -> jshort {
17730        unsafe {
17731            #[cfg(feature = "asserts")]
17732            {
17733                self.check_not_critical("CallStaticShortMethod");
17734                self.check_no_exception("CallStaticShortMethod");
17735                self.check_return_type_static("CallStaticShortMethod", obj, methodID, "short");
17736            }
17737            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jshort>(126)(self.vtable, obj, methodID)
17738        }
17739    }
17740
17741    ///
17742    /// Calls a static java method that has 1 arguments and returns short
17743    ///
17744    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17745    ///
17746    ///
17747    /// # Arguments
17748    /// * `obj` - which object the method should be called on
17749    ///     * must be valid
17750    ///     * must not be null
17751    ///     * must not be already garbage collected
17752    ///
17753    /// * `methodID` - method id of the method
17754    ///     * must not be null
17755    ///     * must be valid
17756    ///     * must be a static
17757    ///     * must actually be a method of `obj`
17758    ///     * must refer to a method with 1 arguments
17759    ///
17760    /// # Returns
17761    /// Whatever the method returned or 0 if it threw
17762    ///
17763    /// # Throws Java Exception
17764    /// * Whatever the method threw
17765    ///
17766    ///
17767    /// # Panics
17768    /// if asserts feature is enabled and UB was detected
17769    ///
17770    /// # Safety
17771    ///
17772    /// Current thread must not be detached from JNI.
17773    ///
17774    /// Current thread must not be currently throwing an exception.
17775    ///
17776    /// Current thread does not hold a critical reference.
17777    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17778    ///
17779    /// `obj` must a valid and not already garbage collected.
17780    /// `methodID` must be valid, static and actually be a method of `obj`, return short and have 1 arguments
17781    ///
17782    pub unsafe fn CallStaticShortMethod1<A: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A) -> jshort {
17783        unsafe {
17784            #[cfg(feature = "asserts")]
17785            {
17786                self.check_not_critical("CallStaticShortMethod");
17787                self.check_no_exception("CallStaticShortMethod");
17788                self.check_return_type_static("CallStaticShortMethod", obj, methodID, "short");
17789                self.check_parameter_types_static("CallStaticShortMethod", obj, methodID, arg1, 0, 1);
17790            }
17791            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jshort>(126)(self.vtable, obj, methodID, arg1)
17792        }
17793    }
17794
17795    ///
17796    /// Calls a static java method that has 2 arguments and returns short
17797    ///
17798    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17799    ///
17800    ///
17801    /// # Arguments
17802    /// * `obj` - which object the method should be called on
17803    ///     * must be valid
17804    ///     * must not be null
17805    ///     * must not be already garbage collected
17806    ///
17807    /// * `methodID` - method id of the method
17808    ///     * must not be null
17809    ///     * must be valid
17810    ///     * must be a static
17811    ///     * must actually be a method of `obj`
17812    ///     * must refer to a method with 2 arguments
17813    ///
17814    /// # Returns
17815    /// Whatever the method returned or 0 if it threw
17816    ///
17817    /// # Throws Java Exception
17818    /// * Whatever the method threw
17819    ///
17820    ///
17821    /// # Panics
17822    /// if asserts feature is enabled and UB was detected
17823    ///
17824    /// # Safety
17825    ///
17826    /// Current thread must not be detached from JNI.
17827    ///
17828    /// Current thread must not be currently throwing an exception.
17829    ///
17830    /// Current thread does not hold a critical reference.
17831    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17832    ///
17833    /// `obj` must a valid and not already garbage collected.
17834    /// `methodID` must be valid, static and actually be a method of `obj`, return short and have 2 arguments
17835    ///
17836    pub unsafe fn CallStaticShortMethod2<A: JType, B: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jshort {
17837        unsafe {
17838            #[cfg(feature = "asserts")]
17839            {
17840                self.check_not_critical("CallStaticShortMethod");
17841                self.check_no_exception("CallStaticShortMethod");
17842                self.check_return_type_static("CallStaticShortMethod", obj, methodID, "short");
17843                self.check_parameter_types_static("CallStaticShortMethod", obj, methodID, arg1, 0, 2);
17844                self.check_parameter_types_static("CallStaticShortMethod", obj, methodID, arg2, 1, 2);
17845            }
17846            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jshort>(126)(self.vtable, obj, methodID, arg1, arg2)
17847        }
17848    }
17849
17850    ///
17851    /// Calls a static java method that has 3 arguments and returns short
17852    ///
17853    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17854    ///
17855    ///
17856    /// # Arguments
17857    /// * `obj` - which object the method should be called on
17858    ///     * must be valid
17859    ///     * must not be null
17860    ///     * must not be already garbage collected
17861    ///
17862    /// * `methodID` - method id of the method
17863    ///     * must not be null
17864    ///     * must be valid
17865    ///     * must be a static
17866    ///     * must actually be a method of `obj`
17867    ///     * must refer to a method with 3 arguments
17868    ///
17869    /// # Returns
17870    /// Whatever the method returned or 0 if it threw
17871    ///
17872    /// # Throws Java Exception
17873    /// * Whatever the method threw
17874    ///
17875    ///
17876    /// # Panics
17877    /// if asserts feature is enabled and UB was detected
17878    ///
17879    /// # Safety
17880    ///
17881    /// Current thread must not be detached from JNI.
17882    ///
17883    /// Current thread must not be currently throwing an exception.
17884    ///
17885    /// Current thread does not hold a critical reference.
17886    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17887    ///
17888    /// `obj` must a valid and not already garbage collected.
17889    /// `methodID` must be valid, static and actually be a method of `obj`, return short and have 3 arguments
17890    ///
17891    pub unsafe fn CallStaticShortMethod3<A: JType, B: JType, C: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jshort {
17892        unsafe {
17893            #[cfg(feature = "asserts")]
17894            {
17895                self.check_not_critical("CallStaticShortMethod");
17896                self.check_no_exception("CallStaticShortMethod");
17897                self.check_return_type_static("CallStaticShortMethod", obj, methodID, "short");
17898                self.check_parameter_types_static("CallStaticShortMethod", obj, methodID, arg1, 0, 3);
17899                self.check_parameter_types_static("CallStaticShortMethod", obj, methodID, arg2, 1, 3);
17900                self.check_parameter_types_static("CallStaticShortMethod", obj, methodID, arg3, 2, 3);
17901            }
17902            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jshort>(126)(self.vtable, obj, methodID, arg1, arg2, arg3)
17903        }
17904    }
17905
17906    ///
17907    /// Calls a static java method that returns a int
17908    ///
17909    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17910    ///
17911    ///
17912    /// # Arguments
17913    /// * `obj` - which object the method should be called on
17914    ///     * must be valid
17915    ///     * must not be null
17916    ///     * must not be already garbage collected
17917    ///
17918    /// * `methodID` - method id of the method
17919    ///     * must not be null
17920    ///     * must be valid
17921    ///     * must not be a static
17922    ///     * must actually be a method of `obj`
17923    ///
17924    /// * `args` - argument pointer
17925    ///     * can be null if the method has no arguments
17926    ///     * must not be null otherwise and point to the exact number of arguments the method expects
17927    ///
17928    /// # Returns
17929    /// Whatever the method returned or 0 if it threw
17930    ///
17931    /// # Throws Java Exception
17932    /// * Whatever the method threw
17933    ///
17934    ///
17935    /// # Panics
17936    /// if asserts feature is enabled and UB was detected
17937    ///
17938    /// # Safety
17939    ///
17940    /// Current thread must not be detached from JNI.
17941    ///
17942    /// Current thread must not be currently throwing an exception.
17943    ///
17944    /// Current thread does not hold a critical reference.
17945    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17946    ///
17947    /// `obj` must a valid and not already garbage collected.
17948    /// `methodID` must be valid, static and actually be a method of `obj` class and return a int
17949    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
17950    /// `args` union must contain types that match the java methods parameters.
17951    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
17952    ///
17953    pub unsafe fn CallStaticIntMethodA(&self, obj: jclass, methodID: jmethodID, args: *const jtype) -> jint {
17954        unsafe {
17955            #[cfg(feature = "asserts")]
17956            {
17957                self.check_not_critical("CallStaticIntMethodA");
17958                self.check_no_exception("CallStaticIntMethodA");
17959                self.check_return_type_static("CallStaticIntMethodA", obj, methodID, "int");
17960            }
17961            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jint>(131)(self.vtable, obj, methodID, args)
17962        }
17963    }
17964
17965    ///
17966    /// Calls a static java method that has 0 arguments and returns int
17967    ///
17968    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17969    ///
17970    ///
17971    /// # Arguments
17972    /// * `obj` - which object the method should be called on
17973    ///     * must be valid
17974    ///     * must not be null
17975    ///     * must not be already garbage collected
17976    ///
17977    /// * `methodID` - method id of the method
17978    ///     * must not be null
17979    ///     * must be valid
17980    ///     * must be a static
17981    ///     * must actually be a method of `obj`
17982    ///     * must refer to a method with 0 arguments
17983    ///
17984    /// # Returns
17985    /// Whatever the method returned or 0 if it threw
17986    ///
17987    /// # Throws Java Exception
17988    /// * Whatever the method threw
17989    ///
17990    ///
17991    /// # Panics
17992    /// if asserts feature is enabled and UB was detected
17993    ///
17994    /// # Safety
17995    ///
17996    /// Current thread must not be detached from JNI.
17997    ///
17998    /// Current thread must not be currently throwing an exception.
17999    ///
18000    /// Current thread does not hold a critical reference.
18001    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18002    ///
18003    /// `obj` must a valid and not already garbage collected.
18004    /// `methodID` must be valid, static and actually be a method of `obj`, return int and have 0 arguments
18005    ///
18006    pub unsafe fn CallStaticIntMethod0(&self, obj: jclass, methodID: jmethodID) -> jint {
18007        unsafe {
18008            #[cfg(feature = "asserts")]
18009            {
18010                self.check_not_critical("CallStaticIntMethod");
18011                self.check_no_exception("CallStaticIntMethod");
18012                self.check_return_type_static("CallStaticIntMethod", obj, methodID, "int");
18013            }
18014            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jint>(129)(self.vtable, obj, methodID)
18015        }
18016    }
18017
18018    ///
18019    /// Calls a static java method that has 1 arguments and returns int
18020    ///
18021    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
18022    ///
18023    ///
18024    /// # Arguments
18025    /// * `obj` - which object the method should be called on
18026    ///     * must be valid
18027    ///     * must not be null
18028    ///     * must not be already garbage collected
18029    ///
18030    /// * `methodID` - method id of the method
18031    ///     * must not be null
18032    ///     * must be valid
18033    ///     * must be a static
18034    ///     * must actually be a method of `obj`
18035    ///     * must refer to a method with 1 arguments
18036    ///
18037    /// # Returns
18038    /// Whatever the method returned or 0 if it threw
18039    ///
18040    /// # Throws Java Exception
18041    /// * Whatever the method threw
18042    ///
18043    ///
18044    /// # Panics
18045    /// if asserts feature is enabled and UB was detected
18046    ///
18047    /// # Safety
18048    ///
18049    /// Current thread must not be detached from JNI.
18050    ///
18051    /// Current thread must not be currently throwing an exception.
18052    ///
18053    /// Current thread does not hold a critical reference.
18054    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18055    ///
18056    /// `obj` must a valid and not already garbage collected.
18057    /// `methodID` must be valid, static and actually be a method of `obj`, return int and have 1 arguments
18058    ///
18059    pub unsafe fn CallStaticIntMethod1<A: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A) -> jint {
18060        unsafe {
18061            #[cfg(feature = "asserts")]
18062            {
18063                self.check_not_critical("CallStaticIntMethod");
18064                self.check_no_exception("CallStaticIntMethod");
18065                self.check_return_type_static("CallStaticIntMethod", obj, methodID, "int");
18066                self.check_parameter_types_static("CallStaticIntMethod", obj, methodID, arg1, 0, 1);
18067            }
18068            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jint>(129)(self.vtable, obj, methodID, arg1)
18069        }
18070    }
18071
18072    ///
18073    /// Calls a static java method that has 2 arguments and returns int
18074    ///
18075    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
18076    ///
18077    ///
18078    /// # Arguments
18079    /// * `obj` - which object the method should be called on
18080    ///     * must be valid
18081    ///     * must not be null
18082    ///     * must not be already garbage collected
18083    ///
18084    /// * `methodID` - method id of the method
18085    ///     * must not be null
18086    ///     * must be valid
18087    ///     * must be a static
18088    ///     * must actually be a method of `obj`
18089    ///     * must refer to a method with 2 arguments
18090    ///
18091    /// # Returns
18092    /// Whatever the method returned or 0 if it threw
18093    ///
18094    /// # Throws Java Exception
18095    /// * Whatever the method threw
18096    ///
18097    ///
18098    /// # Panics
18099    /// if asserts feature is enabled and UB was detected
18100    ///
18101    /// # Safety
18102    ///
18103    /// Current thread must not be detached from JNI.
18104    ///
18105    /// Current thread must not be currently throwing an exception.
18106    ///
18107    /// Current thread does not hold a critical reference.
18108    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18109    ///
18110    /// `obj` must a valid and not already garbage collected.
18111    /// `methodID` must be valid, static and actually be a method of `obj`, return int and have 2 arguments
18112    ///
18113    pub unsafe fn CallStaticIntMethod2<A: JType, B: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jint {
18114        unsafe {
18115            #[cfg(feature = "asserts")]
18116            {
18117                self.check_not_critical("CallStaticIntMethod");
18118                self.check_no_exception("CallStaticIntMethod");
18119                self.check_return_type_static("CallStaticIntMethod", obj, methodID, "int");
18120                self.check_parameter_types_static("CallStaticIntMethod", obj, methodID, arg1, 0, 2);
18121                self.check_parameter_types_static("CallStaticIntMethod", obj, methodID, arg2, 1, 2);
18122            }
18123            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jint>(129)(self.vtable, obj, methodID, arg1, arg2)
18124        }
18125    }
18126
18127    ///
18128    /// Calls a static java method that has 3 arguments and returns int
18129    ///
18130    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
18131    ///
18132    ///
18133    /// # Arguments
18134    /// * `obj` - which object the method should be called on
18135    ///     * must be valid
18136    ///     * must not be null
18137    ///     * must not be already garbage collected
18138    ///
18139    /// * `methodID` - method id of the method
18140    ///     * must not be null
18141    ///     * must be valid
18142    ///     * must be a static
18143    ///     * must actually be a method of `obj`
18144    ///     * must refer to a method with 3 arguments
18145    ///
18146    /// # Returns
18147    /// Whatever the method returned or 0 if it threw
18148    ///
18149    /// # Throws Java Exception
18150    /// * Whatever the method threw
18151    ///
18152    ///
18153    /// # Panics
18154    /// if asserts feature is enabled and UB was detected
18155    ///
18156    /// # Safety
18157    ///
18158    /// Current thread must not be detached from JNI.
18159    ///
18160    /// Current thread must not be currently throwing an exception.
18161    ///
18162    /// Current thread does not hold a critical reference.
18163    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18164    ///
18165    /// `obj` must a valid and not already garbage collected.
18166    /// `methodID` must be valid, static and actually be a method of `obj`, return int and have 3 arguments
18167    ///
18168    pub unsafe fn CallStaticIntMethod3<A: JType, B: JType, C: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jint {
18169        unsafe {
18170            #[cfg(feature = "asserts")]
18171            {
18172                self.check_not_critical("CallStaticIntMethod");
18173                self.check_no_exception("CallStaticIntMethod");
18174                self.check_return_type_static("CallStaticIntMethod", obj, methodID, "int");
18175                self.check_parameter_types_static("CallStaticIntMethod", obj, methodID, arg1, 0, 3);
18176                self.check_parameter_types_static("CallStaticIntMethod", obj, methodID, arg2, 1, 3);
18177                self.check_parameter_types_static("CallStaticIntMethod", obj, methodID, arg3, 2, 3);
18178            }
18179            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jint>(129)(self.vtable, obj, methodID, arg1, arg2, arg3)
18180        }
18181    }
18182
18183    ///
18184    /// Calls a static java method that returns a long
18185    ///
18186    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
18187    ///
18188    ///
18189    /// # Arguments
18190    /// * `obj` - which object the method should be called on
18191    ///     * must be valid
18192    ///     * must not be null
18193    ///     * must not be already garbage collected
18194    ///
18195    /// * `methodID` - method id of the method
18196    ///     * must not be null
18197    ///     * must be valid
18198    ///     * must not be a static
18199    ///     * must actually be a method of `obj`
18200    ///
18201    /// * `args` - argument pointer
18202    ///     * can be null if the method has no arguments
18203    ///     * must not be null otherwise and point to the exact number of arguments the method expects
18204    ///
18205    /// # Returns
18206    /// Whatever the method returned or 0 if it threw
18207    ///
18208    /// # Throws Java Exception
18209    /// * Whatever the method threw
18210    ///
18211    ///
18212    /// # Panics
18213    /// if asserts feature is enabled and UB was detected
18214    ///
18215    /// # Safety
18216    ///
18217    /// Current thread must not be detached from JNI.
18218    ///
18219    /// Current thread must not be currently throwing an exception.
18220    ///
18221    /// Current thread does not hold a critical reference.
18222    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18223    ///
18224    /// `obj` must a valid and not already garbage collected.
18225    /// `methodID` must be valid, static and actually be a method of `obj` class and return a long
18226    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
18227    /// `args` union must contain types that match the java methods parameters.
18228    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
18229    ///
18230    pub unsafe fn CallStaticLongMethodA(&self, obj: jclass, methodID: jmethodID, args: *const jtype) -> jlong {
18231        unsafe {
18232            #[cfg(feature = "asserts")]
18233            {
18234                self.check_not_critical("CallStaticLongMethodA");
18235                self.check_no_exception("CallStaticLongMethodA");
18236                self.check_return_type_static("CallStaticLongMethodA", obj, methodID, "long");
18237            }
18238            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jlong>(134)(self.vtable, obj, methodID, args)
18239        }
18240    }
18241
18242    ///
18243    /// Calls a static java method that has 0 arguments and returns long
18244    ///
18245    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
18246    ///
18247    ///
18248    /// # Arguments
18249    /// * `obj` - which object the method should be called on
18250    ///     * must be valid
18251    ///     * must not be null
18252    ///     * must not be already garbage collected
18253    ///
18254    /// * `methodID` - method id of the method
18255    ///     * must not be null
18256    ///     * must be valid
18257    ///     * must be a static
18258    ///     * must actually be a method of `obj`
18259    ///     * must refer to a method with 0 arguments
18260    ///
18261    /// # Returns
18262    /// Whatever the method returned or 0 if it threw
18263    ///
18264    /// # Throws Java Exception
18265    /// * Whatever the method threw
18266    ///
18267    ///
18268    /// # Panics
18269    /// if asserts feature is enabled and UB was detected
18270    ///
18271    /// # Safety
18272    ///
18273    /// Current thread must not be detached from JNI.
18274    ///
18275    /// Current thread must not be currently throwing an exception.
18276    ///
18277    /// Current thread does not hold a critical reference.
18278    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18279    ///
18280    /// `obj` must a valid and not already garbage collected.
18281    /// `methodID` must be valid, static and actually be a method of `obj`, return long and have 0 arguments
18282    ///
18283    pub unsafe fn CallStaticLongMethod0(&self, obj: jclass, methodID: jmethodID) -> jlong {
18284        unsafe {
18285            #[cfg(feature = "asserts")]
18286            {
18287                self.check_not_critical("CallStaticLongMethod");
18288                self.check_no_exception("CallStaticLongMethod");
18289                self.check_return_type_static("CallStaticLongMethod", obj, methodID, "long");
18290            }
18291            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jlong>(132)(self.vtable, obj, methodID)
18292        }
18293    }
18294
18295    ///
18296    /// Calls a static java method that has 1 arguments and returns long
18297    ///
18298    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
18299    ///
18300    ///
18301    /// # Arguments
18302    /// * `obj` - which object the method should be called on
18303    ///     * must be valid
18304    ///     * must not be null
18305    ///     * must not be already garbage collected
18306    ///
18307    /// * `methodID` - method id of the method
18308    ///     * must not be null
18309    ///     * must be valid
18310    ///     * must be a static
18311    ///     * must actually be a method of `obj`
18312    ///     * must refer to a method with 1 arguments
18313    ///
18314    /// # Returns
18315    /// Whatever the method returned or 0 if it threw
18316    ///
18317    /// # Throws Java Exception
18318    /// * Whatever the method threw
18319    ///
18320    ///
18321    /// # Panics
18322    /// if asserts feature is enabled and UB was detected
18323    ///
18324    /// # Safety
18325    ///
18326    /// Current thread must not be detached from JNI.
18327    ///
18328    /// Current thread must not be currently throwing an exception.
18329    ///
18330    /// Current thread does not hold a critical reference.
18331    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18332    ///
18333    /// `obj` must a valid and not already garbage collected.
18334    /// `methodID` must be valid, static and actually be a method of `obj`, return long and have 1 arguments
18335    ///
18336    pub unsafe fn CallStaticLongMethod1<A: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A) -> jlong {
18337        unsafe {
18338            #[cfg(feature = "asserts")]
18339            {
18340                self.check_not_critical("CallStaticLongMethod");
18341                self.check_no_exception("CallStaticLongMethod");
18342                self.check_return_type_static("CallStaticLongMethod", obj, methodID, "long");
18343                self.check_parameter_types_static("CallStaticLongMethod", obj, methodID, arg1, 0, 1);
18344            }
18345            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jlong>(132)(self.vtable, obj, methodID, arg1)
18346        }
18347    }
18348
18349    ///
18350    /// Calls a static java method that has 2 arguments and returns long
18351    ///
18352    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
18353    ///
18354    ///
18355    /// # Arguments
18356    /// * `obj` - which object the method should be called on
18357    ///     * must be valid
18358    ///     * must not be null
18359    ///     * must not be already garbage collected
18360    ///
18361    /// * `methodID` - method id of the method
18362    ///     * must not be null
18363    ///     * must be valid
18364    ///     * must be a static
18365    ///     * must actually be a method of `obj`
18366    ///     * must refer to a method with 2 arguments
18367    ///
18368    /// # Returns
18369    /// Whatever the method returned or 0 if it threw
18370    ///
18371    /// # Throws Java Exception
18372    /// * Whatever the method threw
18373    ///
18374    ///
18375    /// # Panics
18376    /// if asserts feature is enabled and UB was detected
18377    ///
18378    /// # Safety
18379    ///
18380    /// Current thread must not be detached from JNI.
18381    ///
18382    /// Current thread must not be currently throwing an exception.
18383    ///
18384    /// Current thread does not hold a critical reference.
18385    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18386    ///
18387    /// `obj` must a valid and not already garbage collected.
18388    /// `methodID` must be valid, static and actually be a method of `obj`, return long and have 2 arguments
18389    ///
18390    pub unsafe fn CallStaticLongMethod2<A: JType, B: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jlong {
18391        unsafe {
18392            #[cfg(feature = "asserts")]
18393            {
18394                self.check_not_critical("CallStaticLongMethod");
18395                self.check_no_exception("CallStaticLongMethod");
18396                self.check_return_type_static("CallStaticLongMethod", obj, methodID, "long");
18397                self.check_parameter_types_static("CallStaticLongMethod", obj, methodID, arg1, 0, 2);
18398                self.check_parameter_types_static("CallStaticLongMethod", obj, methodID, arg2, 1, 2);
18399            }
18400            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jlong>(132)(self.vtable, obj, methodID, arg1, arg2)
18401        }
18402    }
18403
18404    ///
18405    /// Calls a static java method that has 3 arguments and returns long
18406    ///
18407    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
18408    ///
18409    ///
18410    /// # Arguments
18411    /// * `obj` - which object the method should be called on
18412    ///     * must be valid
18413    ///     * must not be null
18414    ///     * must not be already garbage collected
18415    ///
18416    /// * `methodID` - method id of the method
18417    ///     * must not be null
18418    ///     * must be valid
18419    ///     * must be a static
18420    ///     * must actually be a method of `obj`
18421    ///     * must refer to a method with 3 arguments
18422    ///
18423    /// # Returns
18424    /// Whatever the method returned or 0 if it threw
18425    ///
18426    /// # Throws Java Exception
18427    /// * Whatever the method threw
18428    ///
18429    ///
18430    /// # Panics
18431    /// if asserts feature is enabled and UB was detected
18432    ///
18433    /// # Safety
18434    ///
18435    /// Current thread must not be detached from JNI.
18436    ///
18437    /// Current thread must not be currently throwing an exception.
18438    ///
18439    /// Current thread does not hold a critical reference.
18440    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18441    ///
18442    /// `obj` must a valid and not already garbage collected.
18443    /// `methodID` must be valid, static and actually be a method of `obj`, return long and have 3 arguments
18444    ///
18445    pub unsafe fn CallStaticLongMethod3<A: JType, B: JType, C: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jlong {
18446        unsafe {
18447            #[cfg(feature = "asserts")]
18448            {
18449                self.check_not_critical("CallStaticLongMethod");
18450                self.check_no_exception("CallStaticLongMethod");
18451                self.check_return_type_static("CallStaticLongMethod", obj, methodID, "long");
18452                self.check_parameter_types_static("CallStaticLongMethod", obj, methodID, arg1, 0, 3);
18453                self.check_parameter_types_static("CallStaticLongMethod", obj, methodID, arg2, 1, 3);
18454                self.check_parameter_types_static("CallStaticLongMethod", obj, methodID, arg3, 2, 3);
18455            }
18456            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jlong>(132)(self.vtable, obj, methodID, arg1, arg2, arg3)
18457        }
18458    }
18459
18460    ///
18461    /// Calls a static java method that returns a float
18462    ///
18463    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
18464    ///
18465    ///
18466    /// # Arguments
18467    /// * `obj` - which object the method should be called on
18468    ///     * must be valid
18469    ///     * must not be null
18470    ///     * must not be already garbage collected
18471    ///
18472    /// * `methodID` - method id of the method
18473    ///     * must not be null
18474    ///     * must be valid
18475    ///     * must not be a static
18476    ///     * must actually be a method of `obj`
18477    ///
18478    /// * `args` - argument pointer
18479    ///     * can be null if the method has no arguments
18480    ///     * must not be null otherwise and point to the exact number of arguments the method expects
18481    ///
18482    /// # Returns
18483    /// Whatever the method returned or 0 if it threw
18484    ///
18485    /// # Throws Java Exception
18486    /// * Whatever the method threw
18487    ///
18488    ///
18489    /// # Panics
18490    /// if asserts feature is enabled and UB was detected
18491    ///
18492    /// # Safety
18493    ///
18494    /// Current thread must not be detached from JNI.
18495    ///
18496    /// Current thread must not be currently throwing an exception.
18497    ///
18498    /// Current thread does not hold a critical reference.
18499    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18500    ///
18501    /// `obj` must a valid and not already garbage collected.
18502    /// `methodID` must be valid, static and actually be a method of `obj` class and return a float
18503    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
18504    /// `args` union must contain types that match the java methods parameters.
18505    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
18506    ///
18507    pub unsafe fn CallStaticFloatMethodA(&self, obj: jclass, methodID: jmethodID, args: *const jtype) -> jfloat {
18508        unsafe {
18509            #[cfg(feature = "asserts")]
18510            {
18511                self.check_not_critical("CallStaticFloatMethodA");
18512                self.check_no_exception("CallStaticFloatMethodA");
18513                self.check_return_type_static("CallStaticFloatMethodA", obj, methodID, "float");
18514            }
18515            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jfloat>(137)(self.vtable, obj, methodID, args)
18516        }
18517    }
18518
18519    ///
18520    /// Calls a static java method that has 0 arguments and returns double
18521    ///
18522    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
18523    ///
18524    ///
18525    /// # Arguments
18526    /// * `obj` - which object the method should be called on
18527    ///     * must be valid
18528    ///     * must not be null
18529    ///     * must not be already garbage collected
18530    ///
18531    /// * `methodID` - method id of the method
18532    ///     * must not be null
18533    ///     * must be valid
18534    ///     * must be a static
18535    ///     * must actually be a method of `obj`
18536    ///     * must refer to a method with 0 arguments
18537    ///
18538    /// # Returns
18539    /// Whatever the method returned or 0 if it threw
18540    ///
18541    /// # Throws Java Exception
18542    /// * Whatever the method threw
18543    ///
18544    ///
18545    /// # Panics
18546    /// if asserts feature is enabled and UB was detected
18547    ///
18548    /// # Safety
18549    ///
18550    /// Current thread must not be detached from JNI.
18551    ///
18552    /// Current thread must not be currently throwing an exception.
18553    ///
18554    /// Current thread does not hold a critical reference.
18555    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18556    ///
18557    /// `obj` must a valid and not already garbage collected.
18558    /// `methodID` must be valid, static and actually be a method of `obj`, return float and have 0 arguments
18559    ///
18560    pub unsafe fn CallStaticFloatMethod0(&self, obj: jclass, methodID: jmethodID) -> jfloat {
18561        unsafe {
18562            #[cfg(feature = "asserts")]
18563            {
18564                self.check_not_critical("CallStaticFloatMethod");
18565                self.check_no_exception("CallStaticFloatMethod");
18566                self.check_return_type_static("CallStaticFloatMethod", obj, methodID, "float");
18567            }
18568            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jfloat>(135)(self.vtable, obj, methodID)
18569        }
18570    }
18571
18572    ///
18573    /// Calls a static java method that has 1 arguments and returns double
18574    ///
18575    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
18576    ///
18577    ///
18578    /// # Arguments
18579    /// * `obj` - which object the method should be called on
18580    ///     * must be valid
18581    ///     * must not be null
18582    ///     * must not be already garbage collected
18583    ///
18584    /// * `methodID` - method id of the method
18585    ///     * must not be null
18586    ///     * must be valid
18587    ///     * must be a static
18588    ///     * must actually be a method of `obj`
18589    ///     * must refer to a method with 1 arguments
18590    ///
18591    /// # Returns
18592    /// Whatever the method returned or 0 if it threw
18593    ///
18594    /// # Throws Java Exception
18595    /// * Whatever the method threw
18596    ///
18597    ///
18598    /// # Panics
18599    /// if asserts feature is enabled and UB was detected
18600    ///
18601    /// # Safety
18602    ///
18603    /// Current thread must not be detached from JNI.
18604    ///
18605    /// Current thread must not be currently throwing an exception.
18606    ///
18607    /// Current thread does not hold a critical reference.
18608    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18609    ///
18610    /// `obj` must a valid and not already garbage collected.
18611    /// `methodID` must be valid, static and actually be a method of `obj`, return float and have 1 arguments
18612    ///
18613    pub unsafe fn CallStaticFloatMethod1<A: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A) -> jfloat {
18614        unsafe {
18615            #[cfg(feature = "asserts")]
18616            {
18617                self.check_not_critical("CallStaticFloatMethod");
18618                self.check_no_exception("CallStaticFloatMethod");
18619                self.check_return_type_static("CallStaticFloatMethod", obj, methodID, "float");
18620                self.check_parameter_types_static("CallStaticFloatMethod", obj, methodID, arg1, 0, 1);
18621            }
18622            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jfloat>(135)(self.vtable, obj, methodID, arg1)
18623        }
18624    }
18625
18626    ///
18627    /// Calls a static java method that has 2 arguments and returns double
18628    ///
18629    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
18630    ///
18631    ///
18632    /// # Arguments
18633    /// * `obj` - which object the method should be called on
18634    ///     * must be valid
18635    ///     * must not be null
18636    ///     * must not be already garbage collected
18637    ///
18638    /// * `methodID` - method id of the method
18639    ///     * must not be null
18640    ///     * must be valid
18641    ///     * must be a static
18642    ///     * must actually be a method of `obj`
18643    ///     * must refer to a method with 2 arguments
18644    ///
18645    /// # Returns
18646    /// Whatever the method returned or 0 if it threw
18647    ///
18648    /// # Throws Java Exception
18649    /// * Whatever the method threw
18650    ///
18651    ///
18652    /// # Panics
18653    /// if asserts feature is enabled and UB was detected
18654    ///
18655    /// # Safety
18656    ///
18657    /// Current thread must not be detached from JNI.
18658    ///
18659    /// Current thread must not be currently throwing an exception.
18660    ///
18661    /// Current thread does not hold a critical reference.
18662    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18663    ///
18664    /// `obj` must a valid and not already garbage collected.
18665    /// `methodID` must be valid, static and actually be a method of `obj`, return float and have 2 arguments
18666    ///
18667    pub unsafe fn CallStaticFloatMethod2<A: JType, B: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jfloat {
18668        unsafe {
18669            #[cfg(feature = "asserts")]
18670            {
18671                self.check_not_critical("CallStaticFloatMethod");
18672                self.check_no_exception("CallStaticFloatMethod");
18673                self.check_return_type_static("CallStaticFloatMethod", obj, methodID, "float");
18674                self.check_parameter_types_static("CallStaticFloatMethod", obj, methodID, arg1, 0, 2);
18675                self.check_parameter_types_static("CallStaticFloatMethod", obj, methodID, arg2, 1, 2);
18676            }
18677            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jfloat>(135)(self.vtable, obj, methodID, arg1, arg2)
18678        }
18679    }
18680
18681    ///
18682    /// Calls a static java method that has 3 arguments and returns double
18683    ///
18684    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
18685    ///
18686    ///
18687    /// # Arguments
18688    /// * `obj` - which object the method should be called on
18689    ///     * must be valid
18690    ///     * must not be null
18691    ///     * must not be already garbage collected
18692    ///
18693    /// * `methodID` - method id of the method
18694    ///     * must not be null
18695    ///     * must be valid
18696    ///     * must be a static
18697    ///     * must actually be a method of `obj`
18698    ///     * must refer to a method with 3 arguments
18699    ///
18700    /// # Returns
18701    /// Whatever the method returned or 0 if it threw
18702    ///
18703    /// # Throws Java Exception
18704    /// * Whatever the method threw
18705    ///
18706    ///
18707    /// # Panics
18708    /// if asserts feature is enabled and UB was detected
18709    ///
18710    /// # Safety
18711    ///
18712    /// Current thread must not be detached from JNI.
18713    ///
18714    /// Current thread must not be currently throwing an exception.
18715    ///
18716    /// Current thread does not hold a critical reference.
18717    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18718    ///
18719    /// `obj` must a valid and not already garbage collected.
18720    /// `methodID` must be valid, static and actually be a method of `obj`, return float and have 3 arguments
18721    ///
18722    pub unsafe fn CallStaticFloatMethod3<A: JType, B: JType, C: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jfloat {
18723        unsafe {
18724            #[cfg(feature = "asserts")]
18725            {
18726                self.check_not_critical("CallStaticFloatMethod");
18727                self.check_no_exception("CallStaticFloatMethod");
18728                self.check_return_type_static("CallStaticFloatMethod", obj, methodID, "float");
18729                self.check_parameter_types_static("CallStaticFloatMethod", obj, methodID, arg1, 0, 3);
18730                self.check_parameter_types_static("CallStaticFloatMethod", obj, methodID, arg2, 1, 3);
18731                self.check_parameter_types_static("CallStaticFloatMethod", obj, methodID, arg3, 2, 3);
18732            }
18733            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jfloat>(135)(self.vtable, obj, methodID, arg1, arg2, arg3)
18734        }
18735    }
18736
18737    ///
18738    /// Calls a static java method that returns a double
18739    ///
18740    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
18741    ///
18742    ///
18743    /// # Arguments
18744    /// * `obj` - which object the method should be called on
18745    ///     * must be valid
18746    ///     * must not be null
18747    ///     * must not be already garbage collected
18748    ///
18749    /// * `methodID` - method id of the method
18750    ///     * must not be null
18751    ///     * must be valid
18752    ///     * must not be a static
18753    ///     * must actually be a method of `obj`
18754    ///
18755    /// * `args` - argument pointer
18756    ///     * can be null if the method has no arguments
18757    ///     * must not be null otherwise and point to the exact number of arguments the method expects
18758    ///
18759    /// # Returns
18760    /// Whatever the method returned or 0 if it threw
18761    ///
18762    /// # Throws Java Exception
18763    /// * Whatever the method threw
18764    ///
18765    ///
18766    /// # Panics
18767    /// if asserts feature is enabled and UB was detected
18768    ///
18769    /// # Safety
18770    ///
18771    /// Current thread must not be detached from JNI.
18772    ///
18773    /// Current thread must not be currently throwing an exception.
18774    ///
18775    /// Current thread does not hold a critical reference.
18776    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18777    ///
18778    /// `obj` must a valid and not already garbage collected.
18779    /// `methodID` must be valid, static and actually be a method of `obj` class and return a double
18780    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
18781    /// `args` union must contain types that match the java methods parameters.
18782    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
18783    ///
18784    pub unsafe fn CallStaticDoubleMethodA(&self, obj: jclass, methodID: jmethodID, args: *const jtype) -> jdouble {
18785        unsafe {
18786            #[cfg(feature = "asserts")]
18787            {
18788                self.check_not_critical("CallStaticDoubleMethodA");
18789                self.check_no_exception("CallStaticDoubleMethodA");
18790                self.check_return_type_static("CallStaticDoubleMethodA", obj, methodID, "double");
18791            }
18792            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jdouble>(140)(self.vtable, obj, methodID, args)
18793        }
18794    }
18795
18796    ///
18797    /// Calls a static java method that has 0 arguments and returns double
18798    ///
18799    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
18800    ///
18801    ///
18802    /// # Arguments
18803    /// * `obj` - which object the method should be called on
18804    ///     * must be valid
18805    ///     * must not be null
18806    ///     * must not be already garbage collected
18807    ///
18808    /// * `methodID` - method id of the method
18809    ///     * must not be null
18810    ///     * must be valid
18811    ///     * must be a static
18812    ///     * must actually be a method of `obj`
18813    ///     * must refer to a method with 0 arguments
18814    ///
18815    /// # Returns
18816    /// Whatever the method returned or 0 if it threw
18817    ///
18818    /// # Throws Java Exception
18819    /// * Whatever the method threw
18820    ///
18821    ///
18822    /// # Panics
18823    /// if asserts feature is enabled and UB was detected
18824    ///
18825    /// # Safety
18826    ///
18827    /// Current thread must not be detached from JNI.
18828    ///
18829    /// Current thread must not be currently throwing an exception.
18830    ///
18831    /// Current thread does not hold a critical reference.
18832    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18833    ///
18834    /// `obj` must a valid and not already garbage collected.
18835    /// `methodID` must be valid, static and actually be a method of `obj`, return double and have 0 arguments
18836    ///
18837    pub unsafe fn CallStaticDoubleMethod0(&self, obj: jclass, methodID: jmethodID) -> jdouble {
18838        unsafe {
18839            #[cfg(feature = "asserts")]
18840            {
18841                self.check_not_critical("CallStaticDoubleMethod");
18842                self.check_no_exception("CallStaticDoubleMethod");
18843                self.check_return_type_static("CallStaticDoubleMethod", obj, methodID, "double");
18844            }
18845            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jdouble>(138)(self.vtable, obj, methodID)
18846        }
18847    }
18848
18849    ///
18850    /// Calls a static java method that has 1 arguments and returns double
18851    ///
18852    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
18853    ///
18854    ///
18855    /// # Arguments
18856    /// * `obj` - which object the method should be called on
18857    ///     * must be valid
18858    ///     * must not be null
18859    ///     * must not be already garbage collected
18860    ///
18861    /// * `methodID` - method id of the method
18862    ///     * must not be null
18863    ///     * must be valid
18864    ///     * must be a static
18865    ///     * must actually be a method of `obj`
18866    ///     * must refer to a method with 1 arguments
18867    ///
18868    /// # Returns
18869    /// Whatever the method returned or 0 if it threw
18870    ///
18871    /// # Throws Java Exception
18872    /// * Whatever the method threw
18873    ///
18874    ///
18875    /// # Panics
18876    /// if asserts feature is enabled and UB was detected
18877    ///
18878    /// # Safety
18879    ///
18880    /// Current thread must not be detached from JNI.
18881    ///
18882    /// Current thread must not be currently throwing an exception.
18883    ///
18884    /// Current thread does not hold a critical reference.
18885    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18886    ///
18887    /// `obj` must a valid and not already garbage collected.
18888    /// `methodID` must be valid, static and actually be a method of `obj`, return double and have 1 arguments
18889    ///
18890    pub unsafe fn CallStaticDoubleMethod1<A: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A) -> jdouble {
18891        unsafe {
18892            #[cfg(feature = "asserts")]
18893            {
18894                self.check_not_critical("CallStaticDoubleMethod");
18895                self.check_no_exception("CallStaticDoubleMethod");
18896                self.check_return_type_static("CallStaticDoubleMethod", obj, methodID, "double");
18897                self.check_parameter_types_static("CallStaticDoubleMethod", obj, methodID, arg1, 0, 1);
18898            }
18899            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jdouble>(138)(self.vtable, obj, methodID, arg1)
18900        }
18901    }
18902
18903    ///
18904    /// Calls a static java method that has 2 arguments and returns double
18905    ///
18906    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
18907    ///
18908    ///
18909    /// # Arguments
18910    /// * `obj` - which object the method should be called on
18911    ///     * must be valid
18912    ///     * must not be null
18913    ///     * must not be already garbage collected
18914    ///
18915    /// * `methodID` - method id of the method
18916    ///     * must not be null
18917    ///     * must be valid
18918    ///     * must be a static
18919    ///     * must actually be a method of `obj`
18920    ///     * must refer to a method with 2 arguments
18921    ///
18922    /// # Returns
18923    /// Whatever the method returned or 0 if it threw
18924    ///
18925    /// # Throws Java Exception
18926    /// * Whatever the method threw
18927    ///
18928    ///
18929    /// # Panics
18930    /// if asserts feature is enabled and UB was detected
18931    ///
18932    /// # Safety
18933    ///
18934    /// Current thread must not be detached from JNI.
18935    ///
18936    /// Current thread must not be currently throwing an exception.
18937    ///
18938    /// Current thread does not hold a critical reference.
18939    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18940    ///
18941    /// `obj` must a valid and not already garbage collected.
18942    /// `methodID` must be valid, static and actually be a method of `obj`, return double and have 2 arguments
18943    ///
18944    pub unsafe fn CallStaticDoubleMethod2<A: JType, B: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jdouble {
18945        unsafe {
18946            #[cfg(feature = "asserts")]
18947            {
18948                self.check_not_critical("CallStaticDoubleMethod");
18949                self.check_no_exception("CallStaticDoubleMethod");
18950                self.check_return_type_static("CallStaticDoubleMethod", obj, methodID, "double");
18951                self.check_parameter_types_static("CallStaticDoubleMethod", obj, methodID, arg1, 0, 2);
18952                self.check_parameter_types_static("CallStaticDoubleMethod", obj, methodID, arg2, 1, 2);
18953            }
18954            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jdouble>(138)(self.vtable, obj, methodID, arg1, arg2)
18955        }
18956    }
18957
18958    ///
18959    /// Calls a static java method that has 3 arguments and returns double
18960    ///
18961    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
18962    ///
18963    ///
18964    /// # Arguments
18965    /// * `obj` - which object the method should be called on
18966    ///     * must be valid
18967    ///     * must not be null
18968    ///     * must not be already garbage collected
18969    ///
18970    /// * `methodID` - method id of the method
18971    ///     * must not be null
18972    ///     * must be valid
18973    ///     * must be a static
18974    ///     * must actually be a method of `obj`
18975    ///     * must refer to a method with 3 arguments
18976    ///
18977    /// # Returns
18978    /// Whatever the method returned or 0 if it threw
18979    ///
18980    /// # Throws Java Exception
18981    /// * Whatever the method threw
18982    ///
18983    ///
18984    /// # Panics
18985    /// if asserts feature is enabled and UB was detected
18986    ///
18987    /// # Safety
18988    ///
18989    /// Current thread must not be detached from JNI.
18990    ///
18991    /// Current thread must not be currently throwing an exception.
18992    ///
18993    /// Current thread does not hold a critical reference.
18994    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18995    ///
18996    /// `obj` must a valid and not already garbage collected.
18997    /// `methodID` must be valid, static and actually be a method of `obj`, return double and have 3 arguments
18998    ///
18999    pub unsafe fn CallStaticDoubleMethod3<A: JType, B: JType, C: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jdouble {
19000        unsafe {
19001            #[cfg(feature = "asserts")]
19002            {
19003                self.check_not_critical("CallStaticDoubleMethod");
19004                self.check_no_exception("CallStaticDoubleMethod");
19005                self.check_return_type_static("CallStaticDoubleMethod", obj, methodID, "double");
19006                self.check_parameter_types_static("CallStaticDoubleMethod", obj, methodID, arg1, 0, 3);
19007                self.check_parameter_types_static("CallStaticDoubleMethod", obj, methodID, arg2, 1, 3);
19008                self.check_parameter_types_static("CallStaticDoubleMethod", obj, methodID, arg3, 2, 3);
19009            }
19010            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jdouble>(138)(self.vtable, obj, methodID, arg1, arg2, arg3)
19011        }
19012    }
19013
19014    ///
19015    /// Create a new String form a jchar array.
19016    ///
19017    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewString>
19018    ///
19019    ///
19020    /// # Arguments
19021    /// * `unicodeChars` - pointer to the jchar array
19022    ///     * must not be null
19023    /// * `len` - amount of elements in the jchar array
19024    ///
19025    /// # Returns
19026    /// A local reference to the newly created String or null on error
19027    ///
19028    /// # Throws Java Exception
19029    /// * `OutOfMemoryError` - if the jvm ran out of memory allocating the String
19030    ///
19031    ///
19032    /// # Panics
19033    /// if asserts feature is enabled and UB was detected
19034    ///
19035    /// # Safety
19036    ///
19037    /// Current thread must not be detached from JNI.
19038    ///
19039    /// Current thread must not be currently throwing an exception.
19040    ///
19041    /// Current thread does not hold a critical reference.
19042    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19043    ///
19044    /// `unicodeChars` must not be 0.
19045    /// `unicodeChars` must be equal or larger than `len` suggests.
19046    ///
19047    #[must_use]
19048    pub unsafe fn NewString(&self, unicodeChars: *const jchar, len: jsize) -> jstring {
19049        unsafe {
19050            #[cfg(feature = "asserts")]
19051            {
19052                self.check_not_critical("NewString");
19053                self.check_no_exception("NewString");
19054                assert!(!unicodeChars.is_null(), "NewString string must not be null");
19055                assert!(len >= 0, "NewString len must not be negative");
19056            }
19057            self.jni::<extern "system" fn(JNIEnvVTable, *const jchar, jsize) -> jstring>(163)(self.vtable, unicodeChars, len)
19058        }
19059    }
19060
19061    /// Convenience function to create a `jstring` from any rust string.
19062    ///
19063    /// This function will, after performing some transformations, call `NewString`.
19064    /// This function is quite slow compared to all other alternatives but unlike for example `NewStringUTF`,
19065    /// it works with strings that contain 0 characters or supplementary characters.
19066    ///
19067    /// This function will always be slower than `NewStringUTF`.
19068    ///
19069    /// # Returns
19070    /// return value of `NewString`
19071    ///
19072    /// # Safety
19073    /// Same as the `NewString` fn
19074    ///
19075    /// # Panics
19076    /// If the string is too long to be represented in Java:
19077    /// * This always the case if the `string.chars().count()` is more than `i32::MAX`.
19078    /// * This might be the case if `string.chars().count()` is between `i32::MAX` and `i32::MAX / 2`
19079    ///   if the string contains enough characters that would require 32 bit encoding in utf-16.
19080    /// * This is never the case if `string.chars().count()` is less than `i32::MAX / 2`.
19081    ///
19082    /// Sidenote: This function does not call `string.chars().count()`.
19083    ///
19084    /// # Example
19085    /// ```rust
19086    /// use jni_simple::{jstring, JNIEnv};
19087    ///
19088    /// fn example(env: JNIEnv) {
19089    ///     unsafe {
19090    ///         let my_string = "𝕊"; //U+1D54A MATHEMATICAL DOUBLE-STRUCK CAPITAL S
19091    ///         let java_string: jstring = env.NewString_from_str(my_string);
19092    ///         let and_back_again: String = env.GetStringChars_as_string(java_string).unwrap();
19093    ///         assert_eq!(my_string, and_back_again.as_str());
19094    ///     }
19095    /// }
19096    /// ```
19097    ///
19098    pub unsafe fn NewString_from_str(&self, string: impl AsRef<str>) -> jstring {
19099        let mut utf16 = Vec::new();
19100        let str = string.as_ref();
19101
19102        //This over allocates up to 4 times capacity depending on how many 2,3,4 byte utf-8 charactes the string contains.
19103        //We cap the allocation at 64k (128k bytes) just in case.
19104        utf16.reserve(str.len().min(0x1_00_00));
19105
19106        for utf in string.as_ref().encode_utf16() {
19107            utf16.push(utf);
19108        }
19109
19110        let len = utf16.len();
19111        let Ok(len) = jsize::try_from(len) else {
19112            panic!(
19113                "string was too long to represent in java. It requires {len} utf-16 characters to represent, but java only supports up to {} characters in a String.",
19114                jsize::MAX
19115            );
19116        };
19117
19118        unsafe { self.NewString(utf16.as_ptr(), len) }
19119    }
19120
19121    ///
19122    /// Returns the string length in jchar's. This is neither the amount of bytes in utf-8 encoding nor the amount of characters.
19123    /// 3 and 4 byte utf-8 characters take 2 jchars to encode. This is equivalent to calling `String.length()` in java.
19124    ///
19125    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStringLength>
19126    ///
19127    /// # Arguments
19128    /// * `string`
19129    ///     * must not be null
19130    ///     * must refer to a string
19131    ///     * must not be already garbage collected
19132    ///
19133    /// # Returns
19134    /// the amount of jchar's in the String
19135    ///
19136    ///
19137    /// # Panics
19138    /// if asserts feature is enabled and UB was detected
19139    ///
19140    /// # Safety
19141    ///
19142    /// Current thread must not be detached from JNI.
19143    ///
19144    /// Current thread must not be currently throwing an exception.
19145    ///
19146    /// Current thread does not hold a critical reference.
19147    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19148    ///
19149    /// `string` must be a valid reference that is not yet garbage collected and refer to a String.
19150    ///
19151    pub unsafe fn GetStringLength(&self, string: jstring) -> jsize {
19152        unsafe {
19153            #[cfg(feature = "asserts")]
19154            {
19155                self.check_not_critical("GetStringLength");
19156                self.check_no_exception("GetStringLength");
19157                assert!(!string.is_null(), "GetStringLength string must not be null");
19158                self.check_if_arg_is_string("GetStringLength", string);
19159            }
19160            self.jni::<extern "system" fn(JNIEnvVTable, jstring) -> jsize>(164)(self.vtable, string)
19161        }
19162    }
19163
19164    ///
19165    /// Returns the string's jchar arrays representation.
19166    ///
19167    /// Note: This fn will almost always to return a copy of the data for newer JVM's.
19168    ///
19169    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStringChars>
19170    ///
19171    /// # Arguments
19172    /// * `string`
19173    ///     * must not be null
19174    ///     * must refer to a string
19175    ///     * must not be already garbage collected
19176    /// * `isCopy` - optional pointer to a boolean flag for the vm to indicate if it copied the data or not.
19177    ///     * may be null
19178    ///
19179    /// # Returns
19180    /// a pointer to index 0 of a jchar array.
19181    ///
19182    ///
19183    /// # Panics
19184    /// if asserts feature is enabled and UB was detected
19185    ///
19186    /// # Safety
19187    ///
19188    /// Current thread must not be detached from JNI.
19189    ///
19190    /// Current thread must not be currently throwing an exception.
19191    ///
19192    /// Current thread does not hold a critical reference.
19193    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19194    ///
19195    /// `string` must be a valid reference that is not yet garbage collected and refer to a String.
19196    /// `isCopy` must be null or valid.
19197    ///
19198    pub unsafe fn GetStringChars(&self, string: jstring, isCopy: impl JBooleanMutPtr) -> *const jchar {
19199        unsafe {
19200            #[cfg(feature = "asserts")]
19201            {
19202                self.check_not_critical("GetStringChars");
19203                self.check_no_exception("GetStringChars");
19204                assert!(!string.is_null(), "GetStringChars string must not be null");
19205                self.check_if_arg_is_string("GetStringChars", string);
19206            }
19207            isCopy.use_jboolean_mut(|isCopy| self.jni::<extern "system" fn(JNIEnvVTable, jstring, *mut jboolean) -> *const jchar>(165)(self.vtable, string, isCopy))
19208        }
19209    }
19210
19211    /// Convenience method that calls `GetStringChars` & `GetStringLength`, copies the result
19212    /// into a rust String and then calls `ReleaseStringChars`.
19213    ///
19214    /// This function calls `ReleaseStringChars` in all error cases where it has to be called!
19215    ///
19216    /// # Returns
19217    /// On failure this method return None.
19218    /// There are 3 different causes for returning None:
19219    /// 1. `GetStringLength` returns a negative number.
19220    ///     * This is unlikely unless something has gone horribly wrong.
19221    /// 2. `GetStringChars` fails, in this case more information should be gathered from `ExceptionCheck`.
19222    /// 3. The characters returned by the JVM are not valid utf-16. In this case `ExceptionCheck` should yield None.
19223    ///
19224    /// # Panics
19225    /// if asserts feature is enabled and UB was detected
19226    ///
19227    /// # Safety
19228    /// Current thread must not be detached from JNI.
19229    ///
19230    /// Current thread must not be currently throwing an exception.
19231    ///
19232    /// Current thread does not hold a critical reference.
19233    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19234    ///
19235    /// `string` must not be null, must refer to a string and not already be garbage collected.
19236    ///
19237    pub unsafe fn GetStringChars_as_string(&self, string: jstring) -> Option<String> {
19238        unsafe {
19239            #[cfg(feature = "asserts")]
19240            {
19241                self.check_not_critical("GetStringChars_as_string");
19242                self.check_no_exception("GetStringChars_as_string");
19243                assert!(!string.is_null(), "GetStringChars_as_string string must not be null");
19244                self.check_if_arg_is_string("GetStringChars_as_string", string);
19245            }
19246
19247            let Ok(len) = usize::try_from(self.GetStringLength(string)) else {
19248                //Unlikely
19249                return None;
19250            };
19251
19252            if len == 0 {
19253                //Empty string, we are done.
19254                return Some(String::new());
19255            }
19256
19257            let str = self.GetStringChars(string, ());
19258            if str.is_null() {
19259                return None;
19260            }
19261
19262            let parsed = String::from_utf16(core::slice::from_raw_parts(str, len));
19263            self.ReleaseStringChars(string, str);
19264            parsed.ok()
19265        }
19266    }
19267
19268    ///
19269    /// Frees a char array returned by `GetStringChars`.
19270    ///
19271    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ReleaseStringChars>
19272    ///
19273    /// # Arguments
19274    /// * `string`
19275    ///     * must not be null
19276    ///     * must refer to a string
19277    ///     * must not be already garbage collected
19278    /// * `chars` - the pointer returned by `GetStringChars`
19279    ///     * must not be null
19280    ///
19281    ///
19282    /// # Panics
19283    /// if asserts feature is enabled and UB was detected
19284    ///
19285    /// # Safety
19286    ///
19287    /// Current thread must not be detached from JNI.
19288    ///
19289    /// Current thread does not hold a critical reference.
19290    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19291    ///
19292    /// `string` must be a valid reference that is not yet garbage collected and refer to a String.
19293    /// `chars` must not be null.
19294    /// `chars` must be the result of a call to `GetStringChars` of the String `string`
19295    ///
19296    pub unsafe fn ReleaseStringChars(&self, string: jstring, chars: *const jchar) {
19297        unsafe {
19298            #[cfg(feature = "asserts")]
19299            {
19300                self.check_not_critical("ReleaseStringChars");
19301                assert!(!string.is_null(), "ReleaseStringChars string must not be null");
19302                assert!(!chars.is_null(), "ReleaseStringChars chars must not be null");
19303                self.check_if_arg_is_string("ReleaseStringChars", string);
19304            }
19305            self.jni::<extern "system" fn(JNIEnvVTable, jstring, *const jchar)>(166)(self.vtable, string, chars);
19306        }
19307    }
19308
19309    ///
19310    /// Create a new String form a utf-8 zero terminated c string.
19311    ///
19312    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewString>
19313    ///
19314    /// # IMPORTANT
19315    /// Java uses a modified utf-8 encoding for strings. If your rust string contains any
19316    /// supplementary characters then the resulting java string will not contain the same characters.
19317    /// If this is a concern for you use the much slower method `NewString_from_str` which
19318    /// will properly handle all characters. Using this method despite it containing
19319    /// supplementary does NOT cause UB, it just creates a java string that contains 'random'
19320    /// characters.
19321    ///
19322    /// # Arguments
19323    /// * `bytes` - pointer to the c like zero terminated utf-8 string
19324    ///     * must not be null
19325    ///
19326    /// # Returns
19327    /// A local reference to the newly created String or null on error
19328    ///
19329    /// # Throws Java Exception
19330    /// * `OutOfMemoryError` - if the jvm ran out of memory allocating the String
19331    ///
19332    ///
19333    /// # Panics
19334    /// if asserts feature is enabled and UB was detected
19335    ///
19336    /// # Safety
19337    ///
19338    /// Current thread must not be detached from JNI.
19339    ///
19340    /// Current thread must not be currently throwing an exception.
19341    ///
19342    /// Current thread does not hold a critical reference.
19343    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19344    ///
19345    /// `bytes` must not be null.
19346    /// `bytes` must be zero terminated.
19347    ///
19348    pub unsafe fn NewStringUTF(&self, bytes: impl UseCString) -> jstring {
19349        unsafe {
19350            bytes.use_as_const_c_char(|bytes| {
19351                #[cfg(feature = "asserts")]
19352                {
19353                    self.check_not_critical("NewStringUTF");
19354                    self.check_no_exception("NewStringUTF");
19355                    assert!(!bytes.is_null(), "NewStringUTF string must not be null");
19356                }
19357                self.jni::<extern "system" fn(JNIEnvVTable, *const c_char) -> jstring>(167)(self.vtable, bytes)
19358            })
19359        }
19360    }
19361
19362    ///
19363    /// Returns the length of a String in bytes if it were to be used with `GetStringUTFChars`.
19364    ///
19365    /// Note: For Java 24 or newer this function is deprecated. use `GetStringUTFLengthAsLong` instead.
19366    ///
19367    /// Note: Usage of this function should be carefully evaluated. For most jvms (especially for JVMS older than Java 17)
19368    /// it is faster to just call `GetStringUTFChars` and use a function equivalent to the c function `strlen()` on its return value.
19369    /// Some newer jvm's may, depending on how the vm was started, know this value for most strings,
19370    /// and therefore it is faster to call this fn than to do
19371    /// the approach above if you do not also need the `UTFChars` themselves.
19372    ///
19373    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStringUTFLength>
19374    ///
19375    ///
19376    /// # Arguments
19377    /// * `string`
19378    ///     * must not be null
19379    ///     * must refer to a string
19380    ///     * must not be already garbage collected
19381    ///
19382    /// # Returns
19383    /// The amount of bytes the array returned by `GetStringUTFChars` would have for this string.
19384    ///
19385    ///
19386    /// # Panics
19387    /// if asserts feature is enabled and UB was detected
19388    ///
19389    /// # Safety
19390    ///
19391    /// Current thread must not be detached from JNI.
19392    ///
19393    /// Current thread must not be currently throwing an exception.
19394    ///
19395    /// Current thread does not hold a critical reference.
19396    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19397    ///
19398    /// `string` must not be null, must refer to a string and not already be garbage collected.
19399    ///
19400    pub unsafe fn GetStringUTFLength(&self, string: jstring) -> jsize {
19401        unsafe {
19402            #[cfg(feature = "asserts")]
19403            {
19404                self.check_not_critical("GetStringUTFLength");
19405                self.check_no_exception("GetStringUTFLength");
19406                assert!(!string.is_null(), "GetStringUTFLength string must not be null");
19407                self.check_if_arg_is_string("GetStringUTFLength", string);
19408            }
19409
19410            self.jni::<extern "system" fn(JNIEnvVTable, jstring) -> jsize>(168)(self.vtable, string)
19411        }
19412    }
19413
19414    ///
19415    /// Returns the length of a String in bytes if it were to be used with `GetStringUTFChars`.
19416    /// Beware that this function is only available on Java 24 or newer!
19417    ///
19418    /// <https://docs.oracle.com/en/java/javase/24/docs/specs/jni/functions.html#getstringutflengthaslong>
19419    ///
19420    ///
19421    /// # Arguments
19422    /// * `string`
19423    ///     * must not be null
19424    ///     * must refer to a string
19425    ///     * must not be already garbage collected
19426    ///
19427    /// # Returns
19428    /// The amount of bytes the array returned by `GetStringUTFChars` would have for this string.
19429    ///
19430    /// # Panics
19431    /// if asserts feature is enabled and UB was detected
19432    ///
19433    /// # Safety
19434    ///
19435    /// Current thread must not be detached from JNI.
19436    ///
19437    /// Current thread must not be currently throwing an exception.
19438    ///
19439    /// Current thread does not hold a critical reference.
19440    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19441    ///
19442    /// `string` must not be null, must refer to a string and not already be garbage collected.
19443    ///
19444    /// The JVM must be a Java 24 VM or newer
19445    ///
19446    pub unsafe fn GetStringUTFLengthAsLong(&self, string: jstring) -> jsize {
19447        unsafe {
19448            #[cfg(feature = "asserts")]
19449            {
19450                self.check_not_critical("GetStringUTFLengthAsLong");
19451                self.check_no_exception("GetStringUTFLengthAsLong");
19452                assert!(!string.is_null(), "GetStringUTFLengthAsLong string must not be null");
19453                self.check_if_arg_is_string("GetStringUTFLengthAsLong", string);
19454                assert!(self.GetVersion() >= JNI_VERSION_24);
19455            }
19456
19457            self.jni::<extern "system" fn(JNIEnvVTable, jstring) -> jsize>(235)(self.vtable, string)
19458        }
19459    }
19460
19461    ///
19462    /// Returns the 0 terminated utf-8 representation of the String.
19463    /// The returned string can be used with the "rust" `CStr` struct from the `std::ffi` module.
19464    ///
19465    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStringUTFChars>
19466    ///
19467    ///
19468    /// # Arguments
19469    /// * `string`
19470    ///     * must not be null
19471    ///     * must refer to a string
19472    ///     * must not be already garbage collected
19473    /// * `isCopy` - optional flag for the jvm to indicate if the string is a copy of the data or not.
19474    ///     * can be null
19475    ///
19476    /// # Returns
19477    /// A pointer to the zero terminated utf-8 string or null on error.
19478    ///
19479    /// # Throws Java Exception
19480    /// * `OutOfMemoryError` - if the jvm ran out of memory allocating the utf-8 string
19481    ///
19482    ///
19483    /// # Panics
19484    /// if asserts feature is enabled and UB was detected
19485    ///
19486    /// # Safety
19487    ///
19488    /// Current thread must not be detached from JNI.
19489    ///
19490    /// Current thread must not be currently throwing an exception.
19491    ///
19492    /// Current thread does not hold a critical reference.
19493    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19494    ///
19495    /// `string` must not be null, must refer to a string and not already be garbage collected.
19496    ///
19497    pub unsafe fn GetStringUTFChars(&self, string: jstring, isCopy: impl JBooleanMutPtr) -> *const c_char {
19498        unsafe {
19499            #[cfg(feature = "asserts")]
19500            {
19501                self.check_not_critical("GetStringUTFChars");
19502                assert!(!string.is_null(), "GetStringUTFChars string must not be null");
19503                self.check_if_arg_is_string("GetStringUTFChars", string);
19504            }
19505            isCopy.use_jboolean_mut(|isCopy| self.jni::<extern "system" fn(JNIEnvVTable, jstring, *mut jboolean) -> *const c_char>(169)(self.vtable, string, isCopy))
19506        }
19507    }
19508
19509    /// Convenience method that calls `GetStringUTFChars`, copies the result
19510    /// into a rust String and then calls `ReleaseStringUTFChars`.
19511    ///
19512    /// This function calls `ReleaseStringUTFChars` in all error cases where it has to be called!
19513    ///
19514    /// # IMPORTANT
19515    /// This function parses the bytes using `CStr::from_ptr(...).to_str()`
19516    ///
19517    /// This function may return None or rust strings that contain
19518    /// unexpected characters which are not actually present in the Java String. <br>
19519    /// This happens when the utf-8 and the modified-utf-8 encoding differ.<br>
19520    /// See <https://docs.oracle.com/en/java/javase/23/docs/api/java.base/java/io/DataInput.html#modified-utf-8> <br>
19521    /// This is the case when the string contains one of the following characters:
19522    /// * \0, null character 0 byte.
19523    /// * any supplementary character. (Any character that would require 4 bytes in normal utf-8 encoding)
19524    ///
19525    /// While this may cause an unexpected return value, it will still never cause UB regardless
19526    /// of what characters the java string contains. Only use this function if you have understood this caveat.
19527    ///
19528    /// An alternative, but slower version of this function is called `GetStringChars_as_string` which does not have this problem
19529    /// because instead of using the utf-8 representation of the string it uses the utf-16 representation,
19530    /// but it is much slower than this function with java 17 or newer. If your application is expected to process Strings containing
19531    /// the problematic characters then accepting the performance penalty is probably worth it.
19532    ///
19533    /// # Returns
19534    /// On failure this method return None.
19535    /// There are 2 different causes for returning None:
19536    /// 1. `GetStringUTFChars` fails, in this case more information should be gathered from `ExceptionCheck`.
19537    /// 2. The String returned by the JVM is not valid utf-8. In this case `ExceptionCheck` should yield None.
19538    ///     * see the IMPORTANT section for when this happens.
19539    ///
19540    /// # Panics
19541    /// if asserts feature is enabled and UB was detected
19542    ///
19543    /// # Safety
19544    /// Current thread must not be detached from JNI.
19545    ///
19546    /// Current thread must not be currently throwing an exception.
19547    ///
19548    /// Current thread does not hold a critical reference.
19549    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19550    ///
19551    /// `string` must not be null, must refer to a string and not already be garbage collected.
19552    ///
19553    pub unsafe fn GetStringUTFChars_as_string(&self, string: jstring) -> Option<String> {
19554        unsafe {
19555            #[cfg(feature = "asserts")]
19556            {
19557                self.check_not_critical("GetStringUTFChars_as_string");
19558                self.check_no_exception("GetStringUTFChars_as_string");
19559                assert!(!string.is_null(), "GetStringUTFChars_as_string string must not be null");
19560                self.check_if_arg_is_string("GetStringUTFChars_as_string", string);
19561            }
19562
19563            let str = self.GetStringUTFChars(string, ());
19564            if str.is_null() {
19565                return None;
19566            }
19567
19568            let parsed = CStr::from_ptr(str).to_str();
19569            if let Ok(parsed) = parsed {
19570                let copy = parsed.to_string();
19571                self.ReleaseStringUTFChars(string, str);
19572                return Some(copy);
19573            }
19574
19575            self.ReleaseStringUTFChars(string, str);
19576            None
19577        }
19578    }
19579
19580    ///
19581    /// Frees the utf-8 string returned by `GetStringUTFChars`.
19582    /// After this method is called the pointer returned by `GetStringUTFChars` becomes invalid
19583    ///
19584    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStringUTFChars>
19585    ///
19586    ///
19587    /// # Arguments
19588    /// * `string` - the string refercence used in `GetStringUTFChars`
19589    ///     * must not be null
19590    ///     * must refer to a string
19591    ///     * must not be already garbage collected
19592    /// * `utf` - the raw utf8 data returned by `GetStringUTFChars`
19593    ///     * must not be null
19594    ///     * must be the exact return value of `GetStringUTFChars`
19595    ///
19596    ///
19597    /// # Panics
19598    /// if asserts feature is enabled and UB was detected
19599    ///
19600    /// # Safety
19601    ///
19602    /// Current thread must not be detached from JNI.
19603    ///
19604    /// Current thread does not hold a critical reference.
19605    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19606    ///
19607    /// `string` must not be null, must refer to a string and not already be garbage collected.
19608    ///
19609    pub unsafe fn ReleaseStringUTFChars(&self, string: jstring, utf: *const c_char) {
19610        unsafe {
19611            #[cfg(feature = "asserts")]
19612            {
19613                self.check_not_critical("ReleaseStringUTFChars");
19614                assert!(!string.is_null(), "ReleaseStringUTFChars string must not be null");
19615                assert!(!utf.is_null(), "ReleaseStringUTFChars utf must not be null");
19616                self.check_if_arg_is_string("ReleaseStringUTFChars", string);
19617            }
19618
19619            self.jni::<extern "system" fn(JNIEnvVTable, jstring, *const c_char)>(170)(self.vtable, string, utf);
19620        }
19621    }
19622
19623    ///
19624    /// Copies a part of the string into a provided jchar buffer
19625    ///
19626    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStringRegion>
19627    ///
19628    ///
19629    /// # Arguments
19630    /// * `string` - the string reference used in `GetStringUTFChars`
19631    ///     * must not be null
19632    ///     * must refer to a string
19633    ///     * must not be already garbage collected
19634    /// * `start` - the index of the first jchar to copy
19635    /// * `len` - the amount of jchar's to copy
19636    ///     * if len is 0 then the function will not fail unless `start` is larger than the length of the string.
19637    /// * `buffer` - the target buffer where the jchar's should be copied to
19638    ///     * must not be null
19639    ///
19640    /// # Throws Java Exception
19641    /// * `StringIndexOutOfBoundsException` - if start or start + len is out of bounds
19642    ///     * The state of the output buffer is undefined if this exception is thrown.
19643    ///
19644    ///
19645    /// # Panics
19646    /// if asserts feature is enabled and UB was detected
19647    ///
19648    /// # Safety
19649    ///
19650    /// Current thread must not be detached from JNI.
19651    ///
19652    /// Current thread must not be currently throwing an exception.
19653    ///
19654    /// Current thread does not hold a critical reference.
19655    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19656    ///
19657    /// `string` must not be null, must refer to a string and not already be garbage collected.
19658    /// `buffer` must be valid
19659    /// `buffer` must be aligned to jchar
19660    /// `buffer` must be large enough to hold the requested amount of jchar's
19661    ///
19662    pub unsafe fn GetStringRegion(&self, string: jstring, start: jsize, len: jsize, buffer: *mut jchar) {
19663        unsafe {
19664            #[cfg(feature = "asserts")]
19665            {
19666                self.check_not_critical("GetStringRegion");
19667                self.check_no_exception("GetStringRegion");
19668                assert!(!string.is_null(), "GetStringRegion string must not be null");
19669                assert!(!buffer.is_null(), "GetStringRegion buffer must not be null");
19670                assert!(buffer.is_aligned(), "GetStringRegion buffer is not aligned properly!");
19671                self.check_if_arg_is_string("GetStringRegion", string);
19672            }
19673
19674            self.jni::<extern "system" fn(JNIEnvVTable, jstring, jsize, jsize, *mut jchar)>(220)(self.vtable, string, start, len, buffer);
19675        }
19676    }
19677
19678    ///
19679    /// Copies a part of the string into a provided jchar buffer
19680    ///
19681    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStringRegion>
19682    ///
19683    ///
19684    /// # Arguments
19685    /// * `string` - the string reference used in `GetStringUTFChars`
19686    ///     * must not be null
19687    ///     * must refer to a string
19688    ///     * must not be already garbage collected
19689    /// * `start` - the index of the first jchar to copy
19690    /// * `buffer` - the target buffer where the jchar's should be copied to
19691    ///
19692    /// # Throws Java Exception
19693    /// * `StringIndexOutOfBoundsException` - if start or start + `buffer.len()` is out of bounds
19694    ///     * The state of the output buffer is undefined if this exception is thrown.
19695    ///
19696    ///
19697    /// # Panics
19698    /// if asserts feature is enabled and UB was detected
19699    ///
19700    /// # Safety
19701    ///
19702    /// Current thread must not be detached from JNI.
19703    ///
19704    /// Current thread must not be currently throwing an exception.
19705    ///
19706    /// Current thread does not hold a critical reference.
19707    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19708    ///
19709    /// `string` must not be null, must refer to a string and not already be garbage collected.
19710    ///
19711    pub unsafe fn GetStringRegion_into_slice(&self, string: jstring, start: jsize, buffer: &mut [jchar]) {
19712        unsafe {
19713            self.GetStringRegion(string, start, jsize::try_from(buffer.len()).expect("buf.len() > jsize::MAX"), buffer.as_mut_ptr());
19714        }
19715    }
19716
19717    ///
19718    /// Copies a part of the string into a provided `c_char` buffer
19719    /// This fn always appends a '0' byte to the output `c_char` buffer!
19720    ///
19721    /// This fn is not recommended for use. It is prone for out of bounds problems because
19722    /// the size of the buffer cannot be predicted easily because the `len` parameter is the amount of jchar's
19723    /// to copy and each jchar may turn into 1-4 bytes of output.
19724    /// The only "safe" way to call this fn is to ensure buffer is len*4+1 bytes large. +1 for the trailing 0 byte.
19725    ///
19726    /// The speed of this fn is also questionable on newer jvm's (at least since java17)
19727    /// as their internal represetation of String makes perform this operation very expensive.
19728    ///
19729    /// This fn may be usefull on newer jvm's if you need to copy from the start of the string as that should be reasonably efficient,
19730    /// and you can predict the buffer sizes with certaining because you know the requrested characters are only ascii for example.
19731    ///
19732    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStringUTFRegion>
19733    ///
19734    ///
19735    /// # Arguments
19736    /// * `string` - the string reference used in `GetStringUTFChars`
19737    ///     * must not be null
19738    ///     * must refer to a string
19739    ///     * must not be already garbage collected
19740    /// * `start` - the index of the first jchar to copy
19741    /// * `len` - the amount of java chars to copy. This has no relation to the output buffer size.
19742    /// * `buffer` - the target buffer where the jchar's should be copied to as utf-8
19743    ///
19744    /// # Throws Java Exception
19745    /// * `StringIndexOutOfBoundsException` - if start or start + len is out of bounds
19746    ///     * The state of the output buffer is undefined if this exception is thrown.
19747    ///
19748    ///
19749    /// # Panics
19750    /// if asserts feature is enabled and UB was detected
19751    ///
19752    /// # Safety
19753    ///
19754    /// Current thread must not be detached from JNI.
19755    ///
19756    /// Current thread must not be currently throwing an exception.
19757    ///
19758    /// Current thread does not hold a critical reference.
19759    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19760    ///
19761    /// `string` must not be null, must refer to a string and not already be garbage collected.
19762    /// `buffer` must be valid
19763    /// `buffer` must be large enough to hold the requested amount of jchar's
19764    ///
19765    pub unsafe fn GetStringUTFRegion(&self, string: jstring, start: jsize, len: jsize, buffer: *mut c_char) {
19766        unsafe {
19767            #[cfg(feature = "asserts")]
19768            {
19769                self.check_not_critical("GetStringUTFRegion");
19770                self.check_no_exception("GetStringUTFRegion");
19771                assert!(!string.is_null(), "GetStringUTFRegion string must not be null");
19772                self.check_if_arg_is_string("GetStringUTFRegion", string);
19773            }
19774
19775            self.jni::<extern "system" fn(JNIEnvVTable, jstring, jsize, jsize, *mut c_char)>(221)(self.vtable, string, start, len, buffer);
19776        }
19777    }
19778
19779    #[cfg(feature = "asserts")]
19780    #[cfg(feature = "std")]
19781    std::thread_local! {
19782        //The "Critical Section" created by GetStringCritical has a lot of restrictions placed upon it.
19783        //This attempts to track "some" of them on a best effort basis.
19784        static CRITICAL_STRINGS: core::cell::RefCell<std::collections::HashMap<*const jchar, usize>> = core::cell::RefCell::new(std::collections::HashMap::new());
19785    }
19786
19787    ///
19788    /// Obtains a critical pointer into a primitive java String.
19789    /// This pointer must be released by calling `ReleaseStringCritical`.
19790    /// No other JNI functions can be called in the current thread.
19791    /// The only exception being multiple consecutive calls to `GetStringCritical` & `GetPrimitiveArrayCritical` to obtain multiple critical
19792    /// pointers at the same time.
19793    ///
19794    /// This method will return NULL to indicate error.
19795    /// The JVM will most likely throw an Exception, probably an `OOMError`.
19796    /// If you obtain multiple critical pointers, you MUST release all successfully obtained critical pointers
19797    /// before being able to check for the exception.
19798    ///
19799    /// Special care must be taken to avoid blocking the current thread with a dependency on another JVM thread.
19800    /// I.e. Do not read from a pipe that is filled by another JVM thread for example.
19801    ///
19802    /// It is also ill-advised to hold onto critical pointers for long periods of time even if no dependency on another JVM Thread is made.
19803    /// The JVM may decide among other things to suspend garbage collection while a critical pointer is held.
19804    /// So reading from a Socket with a long timeout while holding a critical pointer is unlikely to be a good idea.
19805    /// As it may cause unintended side effects in the rest of the JVM (like running out of memory because the GC doesn't run)
19806    ///
19807    /// Failure to release critical pointers before returning execution back to Java Code should be treated as UB
19808    /// even tho the JVM spec fails to mention this detail.
19809    ///
19810    /// Releasing critical pointers in another thread other than the thread that created it should be treated as UB
19811    /// even tho the JVM spec only mentions this detail indirectly.
19812    ///
19813    /// I recommend against using this method for almost every use case.
19814    /// Due to newer JVM's using UTF-8 internal representation this method is likely slower than
19815    /// just copying out the UTF-8 string directly for newer JVMs.
19816    ///
19817    /// # Returns
19818    /// A pointer to the jchar array of the string.
19819    ///
19820    ///
19821    /// # Panics
19822    /// if asserts feature is enabled and UB was detected
19823    ///
19824    /// # Safety
19825    /// Writing to the returned `*const jchar` in any way is UB.
19826    /// `string` must be non-null, valid, actually refer to a string and not yet be garbage collected.
19827    ///
19828    pub unsafe fn GetStringCritical(&self, string: jstring, isCopy: impl JBooleanMutPtr) -> *const jchar {
19829        unsafe {
19830            #[cfg(feature = "asserts")]
19831            {
19832                assert!(!string.is_null(), "GetStringCritical string must not be null");
19833                #[cfg(feature = "std")]
19834                {
19835                    Self::CRITICAL_POINTERS.with(|set| {
19836                        if set.borrow().is_empty() {
19837                            Self::CRITICAL_STRINGS.with(|strings| {
19838                                if strings.borrow().is_empty() {
19839                                    //We can only do this check if we have not yet obtained a unreleased critical on the current thread.
19840                                    //For subsequent calls we cannot do this check.
19841                                    self.check_no_exception("GetStringCritical");
19842                                    self.check_if_arg_is_string("GetStringCritical", string);
19843                                }
19844                            });
19845                        }
19846                    });
19847                }
19848            }
19849
19850            let crit = isCopy.use_jboolean_mut(|isCopy| self.jni::<extern "system" fn(JNIEnvVTable, jstring, *mut jboolean) -> *const jchar>(224)(self.vtable, string, isCopy));
19851
19852            #[cfg(all(feature = "asserts", feature = "std"))]
19853            {
19854                if !crit.is_null() {
19855                    Self::CRITICAL_STRINGS.with(|set| {
19856                        let mut rm = set.borrow_mut();
19857                        let n = rm.remove(&crit).unwrap_or(0) + 1;
19858                        rm.insert(crit, n);
19859                    });
19860                }
19861            }
19862
19863            crit
19864        }
19865    }
19866
19867    ///
19868    /// This fn ends a critical string section.
19869    /// After the call ends the underlying jchar array may be freed, moved by the jvm or garbage collected.
19870    ///
19871    ///
19872    /// # Panics
19873    /// if asserts feature is enabled and UB was detected
19874    ///
19875    /// # Safety
19876    /// `string` must be non-null and valid
19877    /// `cstring` must be non-null and the result of a `GetStringCritical` call
19878    ///
19879    pub unsafe fn ReleaseStringCritical(&self, string: jstring, cstring: *const jchar) {
19880        unsafe {
19881            #[cfg(feature = "asserts")]
19882            {
19883                assert!(!string.is_null(), "ReleaseStringCritical string must not be null");
19884                assert!(!cstring.is_null(), "ReleaseStringCritical cstring must not be null");
19885                #[cfg(feature = "std")]
19886                {
19887                    Self::CRITICAL_STRINGS.with(|set| {
19888                        let mut rm = set.borrow_mut();
19889                        let mut n = rm.remove(&cstring).expect("ReleaseStringCritical cstring is not valid");
19890                        if n == 0 {
19891                            unreachable!();
19892                        }
19893
19894                        n -= 1;
19895
19896                        if n >= 1 {
19897                            rm.insert(cstring, n);
19898                        }
19899                    });
19900                }
19901            }
19902
19903            self.jni::<extern "system" fn(JNIEnvVTable, jstring, *const jchar)>(225)(self.vtable, string, cstring);
19904        }
19905    }
19906
19907    ///
19908    /// Returns the size of an array
19909    ///
19910    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetArrayLength>
19911    ///
19912    ///
19913    /// # Arguments
19914    /// * `array`
19915    ///     * must not be null
19916    ///     * must refer to an array of any primitve type or Object[]
19917    ///     * must not be already garbage collected
19918    /// # Returns
19919    /// the size of the array in elements
19920    ///
19921    ///
19922    /// # Panics
19923    /// if asserts feature is enabled and UB was detected
19924    ///
19925    /// # Safety
19926    ///
19927    /// Current thread must not be detached from JNI.
19928    ///
19929    /// Current thread must not be currently throwing an exception.
19930    ///
19931    /// Current thread does not hold a critical reference.
19932    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19933    ///
19934    /// `array` must not be null, must refer to a array and not already be garbage collected.
19935    ///
19936    pub unsafe fn GetArrayLength(&self, array: jarray) -> jsize {
19937        unsafe {
19938            #[cfg(feature = "asserts")]
19939            {
19940                self.check_not_critical("GetArrayLength");
19941                self.check_no_exception("GetArrayLength");
19942                assert!(!array.is_null(), "GetArrayLength array must not be null");
19943                self.check_is_array(array, "GetArrayLength");
19944            }
19945
19946            self.jni::<extern "system" fn(JNIEnvVTable, jarray) -> jsize>(171)(self.vtable, array)
19947        }
19948    }
19949
19950    ///
19951    /// Creates a new array of Objects
19952    ///
19953    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewObjectArray>
19954    ///
19955    /// # Arguments
19956    /// * `len` - capcity of the new array
19957    ///     * must not be negative
19958    /// * `elementClass` - the class of the elements in the array
19959    ///     * must not be null
19960    ///     * must refer to a class
19961    ///     * must not be already garbage collected
19962    /// * `initialElement` - the initial value of all elements in the array
19963    ///     * may be null
19964    ///     * must be an instance of the class referred to by `elementClass`
19965    ///     * must not be already garbage collected
19966    ///
19967    ///
19968    /// # Returns
19969    /// A reference to the new array or null on failure
19970    ///
19971    /// # Throws Java Exception
19972    /// `OutOfMemoryError` - if the jvm runs out of memory allocating the array.
19973    ///
19974    /// # Panics
19975    /// if asserts feature is enabled and UB was detected
19976    ///
19977    /// # Safety
19978    ///
19979    /// Current thread must not be detached from JNI.
19980    ///
19981    /// Current thread must not be currently throwing an exception.
19982    ///
19983    /// Current thread does not hold a critical reference.
19984    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19985    ///
19986    /// `elementClass` must not be null, must refer to a class and not already be garbage collected.
19987    /// `len` must not be negative
19988    /// `initialElement` must be null or an instance of the class referred to by `elementClass` and not already be garbage collected.
19989    ///
19990    pub unsafe fn NewObjectArray(&self, len: jsize, elementClass: jclass, initialElement: jobject) -> jobjectArray {
19991        unsafe {
19992            #[cfg(feature = "asserts")]
19993            {
19994                self.check_not_critical("NewObjectArray");
19995                self.check_no_exception("NewObjectArray");
19996                assert!(!elementClass.is_null(), "NewObjectArray elementClass must not be null");
19997                assert!(len >= 0, "NewObjectArray len mot not be negative {len}");
19998            }
19999
20000            self.jni::<extern "system" fn(JNIEnvVTable, jsize, jclass, jobject) -> jobjectArray>(172)(self.vtable, len, elementClass, initialElement)
20001        }
20002    }
20003
20004    ///
20005    /// Returns a local reference to a single element in the given object array.
20006    ///
20007    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetObjectArrayElement>
20008    ///
20009    /// # Arguments
20010    /// * `array` - the object array
20011    ///     * must not be null
20012    ///     * must be an array
20013    ///     * must not already be garbage collected
20014    /// * `index` - the index of the element to get
20015    ///
20016    /// # Returns
20017    /// A local reference to the element at the index in the array or null if the element was null or an error occured.
20018    ///
20019    /// # Throws Java Exception
20020    /// * `ArrayIndexOutOfBoundsException` - if the index is out of bounds
20021    ///
20022    /// # Panics
20023    /// if asserts feature is enabled and UB was detected
20024    ///
20025    /// # Safety
20026    ///
20027    /// Current thread must not be detached from JNI.
20028    ///
20029    /// Current thread must not be currently throwing an exception.
20030    ///
20031    /// Current thread does not hold a critical reference.
20032    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20033    ///
20034    /// `array` must not be null, must refer to a array and not already be garbage collected.
20035    ///
20036    pub unsafe fn GetObjectArrayElement(&self, array: jobjectArray, index: jsize) -> jobject {
20037        unsafe {
20038            #[cfg(feature = "asserts")]
20039            {
20040                self.check_not_critical("GetObjectArrayElement");
20041                self.check_no_exception("GetObjectArrayElement");
20042                assert!(!array.is_null(), "GetObjectArrayElement array must not be null");
20043            }
20044
20045            self.jni::<extern "system" fn(JNIEnvVTable, jobjectArray, jsize) -> jobject>(173)(self.vtable, array, index)
20046        }
20047    }
20048
20049    ///
20050    /// Set a single element in a object array
20051    ///
20052    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetObjectArrayElement>
20053    ///
20054    /// # Arguments
20055    /// * `array` - the object array
20056    ///     * must not be null
20057    ///     * must be an array
20058    ///     * must not already be garbage collected
20059    /// * `index` - the index of the element to get
20060    /// * `value` - the new value of the element
20061    ///     * may be null
20062    ///     * must match the type of the array
20063    ///     * must not be already garbage collected
20064    ///
20065    /// # Throws Java Exception
20066    /// * `ArrayIndexOutOfBoundsException` - if the index is out of bounds
20067    ///
20068    /// # Panics
20069    /// if asserts feature is enabled and UB was detected
20070    ///
20071    /// # Safety
20072    ///
20073    /// Current thread must not be detached from JNI.
20074    ///
20075    /// Current thread must not be currently throwing an exception.
20076    ///
20077    /// Current thread does not hold a critical reference.
20078    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20079    ///
20080    /// `array` must not be null, must refer to a array and not already be garbage collected.
20081    /// `value` must be null or an instance of the type contained inside the array and not already be garbage collected.
20082    ///
20083    pub unsafe fn SetObjectArrayElement(&self, array: jobjectArray, index: jsize, value: jobject) {
20084        unsafe {
20085            #[cfg(feature = "asserts")]
20086            {
20087                self.check_not_critical("SetObjectArrayElement");
20088                self.check_no_exception("SetObjectArrayElement");
20089                assert!(!array.is_null(), "SetObjectArrayElement array must not be null");
20090                //TODO check array component type matches value
20091            }
20092
20093            self.jni::<extern "system" fn(JNIEnvVTable, jobjectArray, jsize, jobject)>(174)(self.vtable, array, index, value);
20094        }
20095    }
20096
20097    ///
20098    /// Creates a new boolean array
20099    ///
20100    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewBooleanArray>
20101    ///
20102    /// # Arguments
20103    /// * `size` - capacity of the new array
20104    ///     * must not be negative
20105    ///
20106    ///
20107    /// # Returns
20108    /// A reference to the new array or null on failure
20109    ///
20110    /// # Throws Java Exception
20111    /// `OutOfMemoryError` - if the jvm runs out of memory allocating the array.
20112    ///
20113    /// # Panics
20114    /// if asserts feature is enabled and UB was detected
20115    ///
20116    /// # Safety
20117    ///
20118    /// Current thread must not be detached from JNI.
20119    ///
20120    /// Current thread must not be currently throwing an exception.
20121    ///
20122    /// Current thread does not hold a critical reference.
20123    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20124    ///
20125    /// `size` must not be negative
20126    ///
20127    #[must_use]
20128    pub unsafe fn NewBooleanArray(&self, size: jsize) -> jbooleanArray {
20129        unsafe {
20130            #[cfg(feature = "asserts")]
20131            {
20132                self.check_not_critical("NewBooleanArray");
20133                self.check_no_exception("NewBooleanArray");
20134                assert!(size >= 0, "NewBooleanArray size must not be negative {size}");
20135            }
20136
20137            self.jni::<extern "system" fn(JNIEnvVTable, jsize) -> jobject>(175)(self.vtable, size)
20138        }
20139    }
20140
20141    ///
20142    /// Creates a new byte array
20143    ///
20144    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewByteArray>
20145    ///
20146    /// # Arguments
20147    /// * `size` - capacity of the new array
20148    ///     * must not be negative
20149    ///
20150    ///
20151    /// # Returns
20152    /// A reference to the new array or null on failure
20153    ///
20154    /// # Throws Java Exception
20155    /// `OutOfMemoryError` - if the jvm runs out of memory allocating the array.
20156    ///
20157    /// # Panics
20158    /// if asserts feature is enabled and UB was detected
20159    ///
20160    /// # Safety
20161    ///
20162    /// Current thread must not be detached from JNI.
20163    ///
20164    /// Current thread must not be currently throwing an exception.
20165    ///
20166    /// Current thread does not hold a critical reference.
20167    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20168    ///
20169    /// `size` must not be negative
20170    ///
20171    #[must_use]
20172    pub unsafe fn NewByteArray(&self, size: jsize) -> jbyteArray {
20173        unsafe {
20174            #[cfg(feature = "asserts")]
20175            {
20176                self.check_not_critical("NewByteArray");
20177                self.check_no_exception("NewByteArray");
20178                assert!(size >= 0, "NewByteArray size must not be negative {size}");
20179            }
20180
20181            self.jni::<extern "system" fn(JNIEnvVTable, jsize) -> jbyteArray>(176)(self.vtable, size)
20182        }
20183    }
20184
20185    ///
20186    /// Creates a new char array
20187    ///
20188    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewCharArray>
20189    ///
20190    /// # Arguments
20191    /// * `size` - capacity of the new array
20192    ///     * must not be negative
20193    ///
20194    ///
20195    /// # Returns
20196    /// A reference to the new array or null on failure
20197    ///
20198    /// # Throws Java Exception
20199    /// `OutOfMemoryError` - if the jvm runs out of memory allocating the array.
20200    ///
20201    /// # Panics
20202    /// if asserts feature is enabled and UB was detected
20203    ///
20204    /// # Safety
20205    ///
20206    /// Current thread must not be detached from JNI.
20207    ///
20208    /// Current thread must not be currently throwing an exception.
20209    ///
20210    /// Current thread does not hold a critical reference.
20211    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20212    ///
20213    /// `size` must not be negative
20214    ///
20215    #[must_use]
20216    pub unsafe fn NewCharArray(&self, size: jsize) -> jcharArray {
20217        unsafe {
20218            #[cfg(feature = "asserts")]
20219            {
20220                self.check_not_critical("NewCharArray");
20221                self.check_no_exception("NewCharArray");
20222                assert!(size >= 0, "NewCharArray size must not be negative {size}");
20223            }
20224
20225            self.jni::<extern "system" fn(JNIEnvVTable, jsize) -> jcharArray>(177)(self.vtable, size)
20226        }
20227    }
20228
20229    ///
20230    /// Creates a new short array
20231    ///
20232    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewShortArray>
20233    ///
20234    /// # Arguments
20235    /// * `size` - capacity of the new array
20236    ///     * must not be negative
20237    ///
20238    ///
20239    /// # Returns
20240    /// A reference to the new array or null on failure
20241    ///
20242    /// # Throws Java Exception
20243    /// `OutOfMemoryError` - if the jvm runs out of memory allocating the array.
20244    ///
20245    /// # Panics
20246    /// if asserts feature is enabled and UB was detected
20247    ///
20248    /// # Safety
20249    ///
20250    /// Current thread must not be detached from JNI.
20251    ///
20252    /// Current thread must not be currently throwing an exception.
20253    ///
20254    /// Current thread does not hold a critical reference.
20255    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20256    ///
20257    /// `size` must not be negative
20258    ///
20259    #[must_use]
20260    pub unsafe fn NewShortArray(&self, size: jsize) -> jshortArray {
20261        unsafe {
20262            #[cfg(feature = "asserts")]
20263            {
20264                self.check_not_critical("NewShortArray");
20265                self.check_no_exception("NewShortArray");
20266                assert!(size >= 0, "NewShortArray size must not be negative {size}");
20267            }
20268
20269            self.jni::<extern "system" fn(JNIEnvVTable, jsize) -> jshortArray>(178)(self.vtable, size)
20270        }
20271    }
20272
20273    ///
20274    /// Creates a new int array
20275    ///
20276    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewIntArray>
20277    ///
20278    /// # Arguments
20279    /// * `size` - capacity of the new array
20280    ///     * must not be negative
20281    ///
20282    ///
20283    /// # Returns
20284    /// A reference to the new array or null on failure
20285    ///
20286    /// # Throws Java Exception
20287    /// `OutOfMemoryError` - if the jvm runs out of memory allocating the array.
20288    ///
20289    /// # Panics
20290    /// if asserts feature is enabled and UB was detected
20291    ///
20292    /// # Safety
20293    ///
20294    /// Current thread must not be detached from JNI.
20295    ///
20296    /// Current thread must not be currently throwing an exception.
20297    ///
20298    /// Current thread does not hold a critical reference.
20299    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20300    ///
20301    /// `size` must not be negative
20302    ///
20303    #[must_use]
20304    pub unsafe fn NewIntArray(&self, size: jsize) -> jintArray {
20305        unsafe {
20306            #[cfg(feature = "asserts")]
20307            {
20308                self.check_not_critical("NewIntArray");
20309                self.check_no_exception("NewIntArray");
20310                assert!(size >= 0, "NewIntArray size must not be negative {size}");
20311            }
20312
20313            self.jni::<extern "system" fn(JNIEnvVTable, jsize) -> jintArray>(179)(self.vtable, size)
20314        }
20315    }
20316
20317    ///
20318    /// Creates a new long array
20319    ///
20320    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewLongArray>
20321    ///
20322    /// # Arguments
20323    /// * `size` - capacity of the new array
20324    ///     * must not be negative
20325    ///
20326    ///
20327    /// # Returns
20328    /// A reference to the new array or null on failure
20329    ///
20330    /// # Throws Java Exception
20331    /// `OutOfMemoryError` - if the jvm runs out of memory allocating the array.
20332    ///
20333    /// # Panics
20334    /// if asserts feature is enabled and UB was detected
20335    ///
20336    /// # Safety
20337    ///
20338    /// Current thread must not be detached from JNI.
20339    ///
20340    /// Current thread must not be currently throwing an exception.
20341    ///
20342    /// Current thread does not hold a critical reference.
20343    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20344    ///
20345    /// `size` must not be negative
20346    ///
20347    #[must_use]
20348    pub unsafe fn NewLongArray(&self, size: jsize) -> jlongArray {
20349        unsafe {
20350            #[cfg(feature = "asserts")]
20351            {
20352                self.check_not_critical("NewLongArray");
20353                self.check_no_exception("NewLongArray");
20354                assert!(size >= 0, "NewLongArray size must not be negative {size}");
20355            }
20356
20357            self.jni::<extern "system" fn(JNIEnvVTable, jsize) -> jlongArray>(180)(self.vtable, size)
20358        }
20359    }
20360
20361    ///
20362    /// Creates a new float array
20363    ///
20364    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewFloatArray>
20365    ///
20366    /// # Arguments
20367    /// * `size` - capacity of the new array
20368    ///     * must not be negative
20369    ///
20370    ///
20371    /// # Returns
20372    /// A reference to the new array or null on failure
20373    ///
20374    /// # Throws Java Exception
20375    /// `OutOfMemoryError` - if the jvm runs out of memory allocating the array.
20376    ///
20377    /// # Panics
20378    /// if asserts feature is enabled and UB was detected
20379    ///
20380    /// # Safety
20381    ///
20382    /// Current thread must not be detached from JNI.
20383    ///
20384    /// Current thread must not be currently throwing an exception.
20385    ///
20386    /// Current thread does not hold a critical reference.
20387    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20388    ///
20389    /// `size` must not be negative
20390    ///
20391    #[must_use]
20392    pub unsafe fn NewFloatArray(&self, size: jsize) -> jfloatArray {
20393        unsafe {
20394            #[cfg(feature = "asserts")]
20395            {
20396                self.check_not_critical("NewFloatArray");
20397                self.check_no_exception("NewFloatArray");
20398                assert!(size >= 0, "NewFloatArray size must not be negative {size}");
20399            }
20400
20401            self.jni::<extern "system" fn(JNIEnvVTable, jsize) -> jfloatArray>(181)(self.vtable, size)
20402        }
20403    }
20404
20405    ///
20406    /// Creates a new double array
20407    ///
20408    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewDoubleArray>
20409    ///
20410    /// # Arguments
20411    /// * `size` - capacity of the new array
20412    ///     * must not be negative
20413    ///
20414    ///
20415    /// # Returns
20416    /// A reference to the new array or null on failure
20417    ///
20418    /// # Throws Java Exception
20419    /// `OutOfMemoryError` - if the jvm runs out of memory allocating the array.
20420    ///
20421    /// # Panics
20422    /// if asserts feature is enabled and UB was detected
20423    ///
20424    /// # Safety
20425    ///
20426    /// Current thread must not be detached from JNI.
20427    ///
20428    /// Current thread must not be currently throwing an exception.
20429    ///
20430    /// Current thread does not hold a critical reference.
20431    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20432    ///
20433    /// `size` must not be negative
20434    ///
20435    #[must_use]
20436    pub unsafe fn NewDoubleArray(&self, size: jsize) -> jdoubleArray {
20437        unsafe {
20438            #[cfg(feature = "asserts")]
20439            {
20440                self.check_not_critical("NewDoubleArray");
20441                self.check_no_exception("NewDoubleArray");
20442                assert!(size >= 0, "NewDoubleArray size must not be negative {size}");
20443            }
20444
20445            self.jni::<extern "system" fn(JNIEnvVTable, jsize) -> jdoubleArray>(182)(self.vtable, size)
20446        }
20447    }
20448
20449    ///
20450    /// Get the boolean content inside the array
20451    ///
20452    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetBooleanArrayElements>
20453    ///
20454    /// # Arguments
20455    /// * `array` - the array
20456    ///     * must not be null
20457    ///     * must be an array
20458    ///     * must not already be garbage collected
20459    /// * `isCopy` - optional flag for the jvm to indicate if the data is a copy or not.
20460    ///     * can be null
20461    ///
20462    /// # Returns
20463    /// A pointer to the elements or null if an error occured.
20464    ///
20465    /// # Throws Java Exception
20466    /// * `OutOfMemoryError` - if the jvm ran out of memory.
20467    ///
20468    /// # Panics
20469    /// if asserts feature is enabled and UB was detected
20470    ///
20471    /// # Safety
20472    ///
20473    /// Current thread must not be detached from JNI.
20474    ///
20475    /// Current thread must not be currently throwing an exception.
20476    ///
20477    /// Current thread does not hold a critical reference.
20478    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20479    ///
20480    /// `array` must not be null, must refer to a array and not already be garbage collected.
20481    ///
20482    pub unsafe fn GetBooleanArrayElements(&self, array: jbooleanArray, is_copy: impl JBooleanMutPtr) -> *mut jboolean {
20483        unsafe {
20484            #[cfg(feature = "asserts")]
20485            {
20486                self.check_not_critical("GetBooleanArrayElements");
20487                self.check_no_exception("GetBooleanArrayElements");
20488                assert!(!array.is_null(), "GetBooleanArrayElements jarray must not be null");
20489            }
20490            is_copy.use_jboolean_mut(|is_copy| self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, *mut jboolean) -> *mut jboolean>(183)(self.vtable, array, is_copy))
20491        }
20492    }
20493
20494    ///
20495    /// Get the byte content inside the array
20496    ///
20497    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetByteArrayElements>
20498    ///
20499    /// # Arguments
20500    /// * `array` - the array
20501    ///     * must not be null
20502    ///     * must be an array
20503    ///     * must not already be garbage collected
20504    /// * `isCopy` - optional flag for the jvm to indicate if the data is a copy or not.
20505    ///     * can be null
20506    ///
20507    /// # Returns
20508    /// A pointer to the elements or null if an error occured.
20509    ///
20510    /// # Throws Java Exception
20511    /// * `OutOfMemoryError` - if the jvm ran out of memory.
20512    ///
20513    /// # Panics
20514    /// if asserts feature is enabled and UB was detected
20515    ///
20516    /// # Safety
20517    ///
20518    /// Current thread must not be detached from JNI.
20519    ///
20520    /// Current thread must not be currently throwing an exception.
20521    ///
20522    /// Current thread does not hold a critical reference.
20523    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20524    ///
20525    /// `array` must not be null, must refer to a array and not already be garbage collected.
20526    ///
20527    pub unsafe fn GetByteArrayElements(&self, array: jbyteArray, is_copy: impl JBooleanMutPtr) -> *mut jbyte {
20528        unsafe {
20529            #[cfg(feature = "asserts")]
20530            {
20531                self.check_not_critical("GetByteArrayElements");
20532                self.check_no_exception("GetByteArrayElements");
20533                assert!(!array.is_null(), "GetByteArrayElements jarray must not be null");
20534            }
20535
20536            is_copy.use_jboolean_mut(|is_copy| self.jni::<extern "system" fn(JNIEnvVTable, jbyteArray, *mut jboolean) -> *mut jbyte>(184)(self.vtable, array, is_copy))
20537        }
20538    }
20539
20540    ///
20541    /// Get the char content inside the array
20542    ///
20543    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetCharArrayElements>
20544    ///
20545    /// # Arguments
20546    /// * `array` - the array
20547    ///     * must not be null
20548    ///     * must be an array
20549    ///     * must not already be garbage collected
20550    /// * `isCopy` - optional flag for the jvm to indicate if the data is a copy or not.
20551    ///     * can be null
20552    ///
20553    /// # Returns
20554    /// A pointer to the elements or null if an error occured.
20555    ///
20556    /// # Throws Java Exception
20557    /// * `OutOfMemoryError` - if the jvm ran out of memory.
20558    ///
20559    /// # Panics
20560    /// if asserts feature is enabled and UB was detected
20561    ///
20562    /// # Safety
20563    ///
20564    /// Current thread must not be detached from JNI.
20565    ///
20566    /// Current thread must not be currently throwing an exception.
20567    ///
20568    /// Current thread does not hold a critical reference.
20569    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20570    ///
20571    /// `array` must not be null, must refer to a array and not already be garbage collected.
20572    ///
20573    pub unsafe fn GetCharArrayElements(&self, array: jcharArray, is_copy: impl JBooleanMutPtr) -> *mut jchar {
20574        unsafe {
20575            #[cfg(feature = "asserts")]
20576            {
20577                self.check_not_critical("GetCharArrayElements");
20578                self.check_no_exception("GetCharArrayElements");
20579                assert!(!array.is_null(), "GetCharArrayElements jarray must not be null");
20580            }
20581
20582            is_copy.use_jboolean_mut(|is_copy| self.jni::<extern "system" fn(JNIEnvVTable, jcharArray, *mut jboolean) -> *mut jchar>(185)(self.vtable, array, is_copy))
20583        }
20584    }
20585
20586    ///
20587    /// Get the short content inside the array
20588    ///
20589    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetShortArrayElements>
20590    ///
20591    /// # Arguments
20592    /// * `array` - the array
20593    ///     * must not be null
20594    ///     * must be an array
20595    ///     * must not already be garbage collected
20596    /// * `isCopy` - optional flag for the jvm to indicate if the data is a copy or not.
20597    ///     * can be null
20598    ///
20599    /// # Returns
20600    /// A pointer to the elements or null if an error occured.
20601    ///
20602    /// # Throws Java Exception
20603    /// * `OutOfMemoryError` - if the jvm ran out of memory.
20604    ///
20605    /// # Panics
20606    /// if asserts feature is enabled and UB was detected
20607    ///
20608    /// # Safety
20609    ///
20610    /// Current thread must not be detached from JNI.
20611    ///
20612    /// Current thread must not be currently throwing an exception.
20613    ///
20614    /// Current thread does not hold a critical reference.
20615    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20616    ///
20617    /// `array` must not be null, must refer to a array and not already be garbage collected.
20618    ///
20619    pub unsafe fn GetShortArrayElements(&self, array: jshortArray, is_copy: impl JBooleanMutPtr) -> *mut jshort {
20620        unsafe {
20621            #[cfg(feature = "asserts")]
20622            {
20623                self.check_not_critical("GetShortArrayElements");
20624                self.check_no_exception("GetShortArrayElements");
20625                assert!(!array.is_null(), "GetShortArrayElements jarray must not be null");
20626            }
20627
20628            is_copy.use_jboolean_mut(|is_copy| self.jni::<extern "system" fn(JNIEnvVTable, jshortArray, *mut jboolean) -> *mut jshort>(186)(self.vtable, array, is_copy))
20629        }
20630    }
20631
20632    ///
20633    /// Get the int content inside the array
20634    ///
20635    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetIntArrayElements>
20636    ///
20637    /// # Arguments
20638    /// * `array` - the array
20639    ///     * must not be null
20640    ///     * must be an array
20641    ///     * must not already be garbage collected
20642    /// * `isCopy` - optional flag for the jvm to indicate if the data is a copy or not.
20643    ///     * can be null
20644    ///
20645    /// # Returns
20646    /// A pointer to the elements or null if an error occured.
20647    ///
20648    /// # Throws Java Exception
20649    /// * `OutOfMemoryError` - if the jvm ran out of memory.
20650    ///
20651    /// # Panics
20652    /// if asserts feature is enabled and UB was detected
20653    ///
20654    /// # Safety
20655    ///
20656    /// Current thread must not be detached from JNI.
20657    ///
20658    /// Current thread must not be currently throwing an exception.
20659    ///
20660    /// Current thread does not hold a critical reference.
20661    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20662    ///
20663    /// `array` must not be null, must refer to a array and not already be garbage collected.
20664    ///
20665    pub unsafe fn GetIntArrayElements(&self, array: jintArray, is_copy: impl JBooleanMutPtr) -> *mut jint {
20666        unsafe {
20667            #[cfg(feature = "asserts")]
20668            {
20669                self.check_not_critical("GetIntArrayElements");
20670                self.check_no_exception("GetIntArrayElements");
20671                assert!(!array.is_null(), "GetIntArrayElements jarray must not be null");
20672            }
20673
20674            is_copy.use_jboolean_mut(|is_copy| self.jni::<extern "system" fn(JNIEnvVTable, jintArray, *mut jboolean) -> *mut jint>(187)(self.vtable, array, is_copy))
20675        }
20676    }
20677
20678    ///
20679    /// Get the long content inside the array
20680    ///
20681    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetLongArrayElements>
20682    ///
20683    /// # Arguments
20684    /// * `array` - the array
20685    ///     * must not be null
20686    ///     * must be an array
20687    ///     * must not already be garbage collected
20688    /// * `isCopy` - optional flag for the jvm to indicate if the data is a copy or not.
20689    ///     * can be null
20690    ///
20691    /// # Returns
20692    /// A pointer to the elements or null if an error occured.
20693    ///
20694    /// # Throws Java Exception
20695    /// * `OutOfMemoryError` - if the jvm ran out of memory.
20696    ///
20697    /// # Panics
20698    /// if asserts feature is enabled and UB was detected
20699    ///
20700    /// # Safety
20701    ///
20702    /// Current thread must not be detached from JNI.
20703    ///
20704    /// Current thread must not be currently throwing an exception.
20705    ///
20706    /// Current thread does not hold a critical reference.
20707    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20708    ///
20709    /// `array` must not be null, must refer to a array and not already be garbage collected.
20710    ///
20711    pub unsafe fn GetLongArrayElements(&self, array: jlongArray, is_copy: impl JBooleanMutPtr) -> *mut jlong {
20712        unsafe {
20713            #[cfg(feature = "asserts")]
20714            {
20715                self.check_not_critical("GetLongArrayElements");
20716                self.check_no_exception("GetLongArrayElements");
20717                assert!(!array.is_null(), "GetLongArrayElements jarray must not be null");
20718            }
20719
20720            is_copy.use_jboolean_mut(|is_copy| self.jni::<extern "system" fn(JNIEnvVTable, jlongArray, *mut jboolean) -> *mut jlong>(188)(self.vtable, array, is_copy))
20721        }
20722    }
20723
20724    ///
20725    /// Get the float content inside the array
20726    ///
20727    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetFloatArrayElements>
20728    ///
20729    /// # Arguments
20730    /// * `array` - the array
20731    ///     * must not be null
20732    ///     * must be an array
20733    ///     * must not already be garbage collected
20734    /// * `isCopy` - optional flag for the jvm to indicate if the data is a copy or not.
20735    ///     * can be null
20736    ///
20737    /// # Returns
20738    /// A pointer to the elements or null if an error occured.
20739    ///
20740    /// # Throws Java Exception
20741    /// * `OutOfMemoryError` - if the jvm ran out of memory.
20742    ///
20743    /// # Panics
20744    /// if asserts feature is enabled and UB was detected
20745    ///
20746    /// # Safety
20747    ///
20748    /// Current thread must not be detached from JNI.
20749    ///
20750    /// Current thread must not be currently throwing an exception.
20751    ///
20752    /// Current thread does not hold a critical reference.
20753    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20754    ///
20755    /// `array` must not be null, must refer to a array and not already be garbage collected.
20756    ///
20757    pub unsafe fn GetFloatArrayElements(&self, array: jfloatArray, is_copy: impl JBooleanMutPtr) -> *mut jfloat {
20758        unsafe {
20759            #[cfg(feature = "asserts")]
20760            {
20761                self.check_not_critical("GetFloatArrayElements");
20762                self.check_no_exception("GetFloatArrayElements");
20763                assert!(!array.is_null(), "GetFloatArrayElements jarray must not be null");
20764            }
20765
20766            is_copy.use_jboolean_mut(|is_copy| self.jni::<extern "system" fn(JNIEnvVTable, jfloatArray, *mut jboolean) -> *mut jfloat>(189)(self.vtable, array, is_copy))
20767        }
20768    }
20769
20770    ///
20771    /// Get the double content inside the array
20772    ///
20773    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetDoubleArrayElements>
20774    ///
20775    /// # Arguments
20776    /// * `array` - the array
20777    ///     * must not be null
20778    ///     * must be an array
20779    ///     * must not already be garbage collected
20780    /// * `isCopy` - optional flag for the jvm to indicate if the data is a copy or not.
20781    ///     * can be null
20782    ///
20783    /// # Returns
20784    /// A pointer to the elements or null if an error occured.
20785    ///
20786    /// # Throws Java Exception
20787    /// * `OutOfMemoryError` - if the jvm ran out of memory.
20788    ///
20789    /// # Panics
20790    /// if asserts feature is enabled and UB was detected
20791    ///
20792    /// # Safety
20793    ///
20794    /// Current thread must not be detached from JNI.
20795    ///
20796    /// Current thread must not be currently throwing an exception.
20797    ///
20798    /// Current thread does not hold a critical reference.
20799    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20800    ///
20801    /// `array` must not be null, must refer to a array and not already be garbage collected.
20802    ///
20803    pub unsafe fn GetDoubleArrayElements(&self, array: jdoubleArray, is_copy: impl JBooleanMutPtr) -> *mut jdouble {
20804        unsafe {
20805            #[cfg(feature = "asserts")]
20806            {
20807                self.check_not_critical("GetDoubleArrayElements");
20808                self.check_no_exception("GetDoubleArrayElements");
20809                assert!(!array.is_null(), "GetDoubleArrayElements jarray must not be null");
20810            }
20811
20812            is_copy.use_jboolean_mut(|is_copy| self.jni::<extern "system" fn(JNIEnvVTable, jdoubleArray, *mut jboolean) -> *mut jdouble>(190)(self.vtable, array, is_copy))
20813        }
20814    }
20815
20816    ///
20817    /// Releases the boolean array elements back to the jvm
20818    ///
20819    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ReleaseBooleanArrayElements>
20820    ///
20821    /// # Arguments
20822    /// * `array` - the array
20823    ///     * must not be null
20824    ///     * must be an array
20825    ///     * must not already be garbage collected
20826    /// * `elems`
20827    ///     * must not be null
20828    /// * `mode`
20829    ///     * must be one of the following constants:
20830    ///         * `JNI_OK` - release the array, copy back the contents into the internal buffer if it was a copy
20831    ///         * `JNI_COMMIT` - do not release the array, copy back the contents into the internal buffer if it was a copy
20832    ///         * `JNI_ABORT` - release the array, do not copy back the contents into the internal buffer if it was a copy
20833    ///         * Note: if data was not a copy then `JNI_OK` and `JNI_ABORT` do the same.
20834    ///
20835    /// # Panics
20836    /// if asserts feature is enabled and UB was detected
20837    ///
20838    /// # Safety
20839    ///
20840    /// Current thread must not be detached from JNI.
20841    ///
20842    /// Current thread does not hold a critical reference.
20843    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20844    ///
20845    /// `array` must not be null, must refer to a array and not already be garbage collected.
20846    /// `elems` must be the buffer of the same `array` reference
20847    /// `mode` must be one of the constants
20848    ///
20849    pub unsafe fn ReleaseBooleanArrayElements(&self, array: jbooleanArray, elems: *mut jboolean, mode: jint) {
20850        unsafe {
20851            #[cfg(feature = "asserts")]
20852            {
20853                self.check_not_critical("ReleaseBooleanArrayElements");
20854                assert!(!array.is_null(), "ReleaseBooleanArrayElements jarray must not be null");
20855                assert!(!elems.is_null(), "ReleaseBooleanArrayElements elems must not be null");
20856                assert!(
20857                    mode == JNI_OK || mode == JNI_COMMIT || mode == JNI_ABORT,
20858                    "ReleaseBooleanArrayElements mode is invalid {mode}"
20859                );
20860            }
20861
20862            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, *mut jboolean, jint)>(191)(self.vtable, array, elems, mode);
20863        }
20864    }
20865
20866    ///
20867    /// Releases the byte array elements back to the jvm
20868    ///
20869    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ReleaseByteArrayElements>
20870    ///
20871    /// # Arguments
20872    /// * `array` - the array
20873    ///     * must not be null
20874    ///     * must be an array
20875    ///     * must not already be garbage collected
20876    /// * `elems`
20877    ///     * must not be null
20878    /// * `mode`
20879    ///     * must be one of the following constants:
20880    ///         * `JNI_OK` - release the array, copy back the contents into the internal buffer if it was a copy
20881    ///         * `JNI_COMMIT` - do not release the array, copy back the contents into the internal buffer if it was a copy
20882    ///         * `JNI_ABORT` - release the array, do not copy back the contents into the internal buffer if it was a copy
20883    ///         * Note: if data was not a copy then `JNI_OK` and `JNI_ABORT` do the same.
20884    ///
20885    /// # Panics
20886    /// if asserts feature is enabled and UB was detected
20887    ///
20888    /// # Safety
20889    ///
20890    /// Current thread must not be detached from JNI.
20891    ///
20892    /// Current thread does not hold a critical reference.
20893    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20894    ///
20895    /// `array` must not be null, must refer to a array and not already be garbage collected.
20896    /// `elems` must be the buffer of the same `array` reference
20897    /// `mode` must be one of the constants
20898    ///
20899    pub unsafe fn ReleaseByteArrayElements(&self, array: jbyteArray, elems: *mut jbyte, mode: jint) {
20900        unsafe {
20901            #[cfg(feature = "asserts")]
20902            {
20903                self.check_not_critical("ReleaseByteArrayElements");
20904                assert!(!array.is_null(), "ReleaseByteArrayElements jarray must not be null");
20905                assert!(!elems.is_null(), "ReleaseByteArrayElements elems must not be null");
20906                assert!(mode == JNI_OK || mode == JNI_COMMIT || mode == JNI_ABORT, "ReleaseByteArrayElements mode is invalid {mode}");
20907            }
20908
20909            self.jni::<extern "system" fn(JNIEnvVTable, jbyteArray, *mut jbyte, jint)>(192)(self.vtable, array, elems, mode);
20910        }
20911    }
20912
20913    ///
20914    /// Releases the char array elements back to the jvm
20915    ///
20916    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ReleaseCharArrayElements>
20917    ///
20918    /// # Arguments
20919    /// * `array` - the array
20920    ///     * must not be null
20921    ///     * must be an array
20922    ///     * must not already be garbage collected
20923    /// * `elems`
20924    ///     * must not be null
20925    /// * `mode`
20926    ///     * must be one of the following constants:
20927    ///         * `JNI_OK` - release the array, copy back the contents into the internal buffer if it was a copy
20928    ///         * `JNI_COMMIT` - do not release the array, copy back the contents into the internal buffer if it was a copy
20929    ///         * `JNI_ABORT` - release the array, do not copy back the contents into the internal buffer if it was a copy
20930    ///         * Note: if data was not a copy then `JNI_OK` and `JNI_ABORT` do the same.
20931    ///
20932    ///
20933    /// # Panics
20934    /// if asserts feature is enabled and UB was detected
20935    ///
20936    /// # Safety
20937    ///
20938    /// Current thread must not be detached from JNI.
20939    ///
20940    /// Current thread does not hold a critical reference.
20941    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20942    ///
20943    /// `array` must not be null, must refer to a array and not already be garbage collected.
20944    /// `elems` must be the buffer of the same `array` reference
20945    /// `mode` must be one of the constants
20946    ///
20947    pub unsafe fn ReleaseCharArrayElements(&self, array: jcharArray, elems: *mut jchar, mode: jint) {
20948        unsafe {
20949            #[cfg(feature = "asserts")]
20950            {
20951                self.check_not_critical("ReleaseCharArrayElements");
20952                assert!(!array.is_null(), "ReleaseCharArrayElements jarray must not be null");
20953                assert!(!elems.is_null(), "ReleaseCharArrayElements elems must not be null");
20954                assert!(mode == JNI_OK || mode == JNI_COMMIT || mode == JNI_ABORT, "ReleaseCharArrayElements mode is invalid {mode}");
20955            }
20956
20957            self.jni::<extern "system" fn(JNIEnvVTable, jcharArray, *mut jchar, jint)>(193)(self.vtable, array, elems, mode);
20958        }
20959    }
20960
20961    ///
20962    /// Releases the short array elements back to the jvm
20963    ///
20964    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ReleaseShortArrayElements>
20965    ///
20966    /// # Arguments
20967    /// * `array` - the array
20968    ///     * must not be null
20969    ///     * must be an array
20970    ///     * must not already be garbage collected
20971    /// * `elems`
20972    ///     * must not be null
20973    /// * `mode`
20974    ///     * must be one of the following constants:
20975    ///         * `JNI_OK` - release the array, copy back the contents into the internal buffer if it was a copy
20976    ///         * `JNI_COMMIT` - do not release the array, copy back the contents into the internal buffer if it was a copy
20977    ///         * `JNI_ABORT` - release the array, do not copy back the contents into the internal buffer if it was a copy
20978    ///         * Note: if data was not a copy then `JNI_OK` and `JNI_ABORT` do the same.
20979    ///
20980    ///
20981    /// # Panics
20982    /// if asserts feature is enabled and UB was detected
20983    ///
20984    /// # Safety
20985    ///
20986    /// Current thread must not be detached from JNI.
20987    ///
20988    /// Current thread does not hold a critical reference.
20989    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20990    ///
20991    /// `array` must not be null, must refer to a array and not already be garbage collected.
20992    /// `elems` must be the buffer of the same `array` reference
20993    /// `mode` must be one of the constants
20994    ///
20995    pub unsafe fn ReleaseShortArrayElements(&self, array: jshortArray, elems: *mut jshort, mode: jint) {
20996        unsafe {
20997            #[cfg(feature = "asserts")]
20998            {
20999                self.check_not_critical("ReleaseShortArrayElements");
21000                assert!(!array.is_null(), "ReleaseShortArrayElements jarray must not be null");
21001                assert!(!elems.is_null(), "ReleaseShortArrayElements elems must not be null");
21002                assert!(
21003                    mode == JNI_OK || mode == JNI_COMMIT || mode == JNI_ABORT,
21004                    "ReleaseShortArrayElements mode is invalid {mode}"
21005                );
21006            }
21007
21008            self.jni::<extern "system" fn(JNIEnvVTable, jshortArray, *mut jshort, jint)>(194)(self.vtable, array, elems, mode);
21009        }
21010    }
21011
21012    ///
21013    /// Releases the int array elements back to the jvm
21014    ///
21015    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ReleaseIntArrayElements>
21016    ///
21017    /// # Arguments
21018    /// * `array` - the array
21019    ///     * must not be null
21020    ///     * must be an array
21021    ///     * must not already be garbage collected
21022    /// * `elems`
21023    ///     * must not be null
21024    /// * `mode`
21025    ///     * must be one of the following constants:
21026    ///         * `JNI_OK` - release the array, copy back the contents into the internal buffer if it was a copy
21027    ///         * `JNI_COMMIT` - do not release the array, copy back the contents into the internal buffer if it was a copy
21028    ///         * `JNI_ABORT` - release the array, do not copy back the contents into the internal buffer if it was a copy
21029    ///         * Note: if data was not a copy then `JNI_OK` and `JNI_ABORT` do the same.
21030    ///
21031    ///
21032    /// # Panics
21033    /// if asserts feature is enabled and UB was detected
21034    ///
21035    /// # Safety
21036    ///
21037    /// Current thread must not be detached from JNI.
21038    ///
21039    /// Current thread does not hold a critical reference.
21040    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21041    ///
21042    /// `array` must not be null, must refer to a array and not already be garbage collected.
21043    /// `elems` must be the buffer of the same `array` reference
21044    /// `mode` must be one of the constants
21045    ///
21046    pub unsafe fn ReleaseIntArrayElements(&self, array: jintArray, elems: *mut jint, mode: jint) {
21047        unsafe {
21048            #[cfg(feature = "asserts")]
21049            {
21050                self.check_not_critical("ReleaseIntArrayElements");
21051                assert!(!array.is_null(), "ReleaseIntArrayElements jarray must not be null");
21052                assert!(!elems.is_null(), "ReleaseIntArrayElements elems must not be null");
21053                assert!(mode == JNI_OK || mode == JNI_COMMIT || mode == JNI_ABORT, "ReleaseIntArrayElements mode is invalid {mode}");
21054            }
21055
21056            self.jni::<extern "system" fn(JNIEnvVTable, jintArray, *mut jint, jint)>(195)(self.vtable, array, elems, mode);
21057        }
21058    }
21059
21060    ///
21061    /// Releases the long array elements back to the jvm
21062    ///
21063    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ReleaseLongArrayElements>
21064    ///
21065    /// # Arguments
21066    /// * `array` - the array
21067    ///     * must not be null
21068    ///     * must be an array
21069    ///     * must not already be garbage collected
21070    /// * `elems`
21071    ///     * must not be null
21072    /// * `mode`
21073    ///     * must be one of the following constants:
21074    ///         * `JNI_OK` - release the array, copy back the contents into the internal buffer if it was a copy
21075    ///         * `JNI_COMMIT` - do not release the array, copy back the contents into the internal buffer if it was a copy
21076    ///         * `JNI_ABORT` - release the array, do not copy back the contents into the internal buffer if it was a copy
21077    ///         * Note: if data was not a copy then `JNI_OK` and `JNI_ABORT` do the same.
21078    ///
21079    ///
21080    /// # Panics
21081    /// if asserts feature is enabled and UB was detected
21082    ///
21083    /// # Safety
21084    ///
21085    /// Current thread must not be detached from JNI.
21086    ///
21087    /// Current thread does not hold a critical reference.
21088    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21089    ///
21090    /// `array` must not be null, must refer to a array and not already be garbage collected.
21091    /// `elems` must be the buffer of the same `array` reference
21092    /// `mode` must be one of the constants
21093    ///
21094    pub unsafe fn ReleaseLongArrayElements(&self, array: jlongArray, elems: *mut jlong, mode: jint) {
21095        unsafe {
21096            #[cfg(feature = "asserts")]
21097            {
21098                self.check_not_critical("ReleaseLongArrayElements");
21099                assert!(!array.is_null(), "ReleaseLongArrayElements jarray must not be null");
21100                assert!(!elems.is_null(), "ReleaseLongArrayElements elems must not be null");
21101                assert!(mode == JNI_OK || mode == JNI_COMMIT || mode == JNI_ABORT, "ReleaseLongArrayElements mode is invalid {mode}");
21102            }
21103
21104            self.jni::<extern "system" fn(JNIEnvVTable, jlongArray, *mut jlong, jint)>(196)(self.vtable, array, elems, mode);
21105        }
21106    }
21107
21108    ///
21109    /// Releases the float array elements back to the jvm
21110    ///
21111    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ReleaseFloatArrayElements>
21112    ///
21113    /// # Arguments
21114    /// * `array` - the array
21115    ///     * must not be null
21116    ///     * must be an array
21117    ///     * must not already be garbage collected
21118    /// * `elems`
21119    ///     * must not be null
21120    /// * `mode`
21121    ///     * must be one of the following constants:
21122    ///         * `JNI_OK` - release the array, copy back the contents into the internal buffer if it was a copy
21123    ///         * `JNI_COMMIT` - do not release the array, copy back the contents into the internal buffer if it was a copy
21124    ///         * `JNI_ABORT` - release the array, do not copy back the contents into the internal buffer if it was a copy
21125    ///         * Note: if data was not a copy then `JNI_OK` and `JNI_ABORT` do the same.
21126    ///
21127    ///
21128    /// # Panics
21129    /// if asserts feature is enabled and UB was detected
21130    ///
21131    /// # Safety
21132    ///
21133    /// Current thread must not be detached from JNI.
21134    ///
21135    /// Current thread does not hold a critical reference.
21136    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21137    ///
21138    /// `array` must not be null, must refer to a array and not already be garbage collected.
21139    /// `elems` must be the buffer of the same `array` reference
21140    /// `mode` must be one of the constants
21141    ///
21142    pub unsafe fn ReleaseFloatArrayElements(&self, array: jfloatArray, elems: *mut jfloat, mode: jint) {
21143        unsafe {
21144            #[cfg(feature = "asserts")]
21145            {
21146                self.check_not_critical("ReleaseFloatArrayElements");
21147                assert!(!array.is_null(), "ReleaseFloatArrayElements jarray must not be null");
21148                assert!(!elems.is_null(), "ReleaseFloatArrayElements elems must not be null");
21149                assert!(
21150                    mode == JNI_OK || mode == JNI_COMMIT || mode == JNI_ABORT,
21151                    "ReleaseFloatArrayElements mode is invalid {mode}"
21152                );
21153            }
21154
21155            self.jni::<extern "system" fn(JNIEnvVTable, jfloatArray, *mut jfloat, jint)>(197)(self.vtable, array, elems, mode);
21156        }
21157    }
21158
21159    ///
21160    /// Releases the double array elements back to the jvm
21161    ///
21162    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ReleaseDoubleArrayElements>
21163    ///
21164    /// # Arguments
21165    /// * `array` - the array
21166    ///     * must not be null
21167    ///     * must be an array
21168    ///     * must not already be garbage collected
21169    /// * `elems`
21170    ///     * must not be null
21171    /// * `mode`
21172    ///     * must be one of the following constants:
21173    ///         * `JNI_OK` - release the array, copy back the contents into the internal buffer if it was a copy
21174    ///         * `JNI_COMMIT` - do not release the array, copy back the contents into the internal buffer if it was a copy
21175    ///         * `JNI_ABORT` - release the array, do not copy back the contents into the internal buffer if it was a copy
21176    ///         * Note: if data was not a copy then `JNI_OK` and `JNI_ABORT` do the same.
21177    ///
21178    ///
21179    /// # Panics
21180    /// if asserts feature is enabled and UB was detected
21181    ///
21182    /// # Safety
21183    ///
21184    /// Current thread must not be detached from JNI.
21185    ///
21186    /// Current thread does not hold a critical reference.
21187    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21188    ///
21189    /// `array` must not be null, must refer to a array and not already be garbage collected.
21190    /// `elems` must be the buffer of the same `array` reference
21191    /// `mode` must be one of the constants
21192    ///
21193    pub unsafe fn ReleaseDoubleArrayElements(&self, array: jdoubleArray, elems: *mut jdouble, mode: jint) {
21194        unsafe {
21195            #[cfg(feature = "asserts")]
21196            {
21197                self.check_not_critical("ReleaseDoubleArrayElements");
21198                assert!(!array.is_null(), "ReleaseDoubleArrayElements jarray must not be null");
21199                assert!(!elems.is_null(), "ReleaseDoubleArrayElements elems must not be null");
21200                assert!(
21201                    mode == JNI_OK || mode == JNI_COMMIT || mode == JNI_ABORT,
21202                    "ReleaseDoubleArrayElements mode is invalid {mode}"
21203                );
21204            }
21205
21206            self.jni::<extern "system" fn(JNIEnvVTable, jdoubleArray, *mut jdouble, jint)>(198)(self.vtable, array, elems, mode);
21207        }
21208    }
21209
21210    ///
21211    /// Copies data from the jbooleanArray `array` starting from the given `start` index into the slice `buf`.
21212    ///
21213    /// # Arguments
21214    /// * `array` - handle to a Java jbooleanArray.
21215    /// * `start` - the index of the first element to copy in the Java jbooleanArray
21216    /// * `buf` - the slice to copy data into
21217    ///
21218    /// # Throws Java Exception:
21219    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
21220    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21221    ///
21222    /// It is JVM implementation specific what is stored inside buf if this function throws an exception.
21223    /// * Data partially written
21224    /// * No data written
21225    ///
21226    /// # Panics
21227    /// if asserts feature is enabled and UB was detected
21228    /// if the `buf.len()` is larger than `jsize::MAX`
21229    ///
21230    /// # Safety
21231    /// Current thread must not be detached from JNI.
21232    ///
21233    /// Current thread must not be currently throwing an exception.
21234    ///
21235    /// Current thread does not hold a critical reference.
21236    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21237    ///
21238    /// `array` must be a valid non-null reference to a jbooleanArray.
21239    ///
21240    /// # Example
21241    /// ```rust
21242    /// use jni_simple::{*};
21243    ///
21244    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
21245    ///         array: jbooleanArray, chunk_buffer: &mut [jboolean], chunk_offset: usize) -> bool {
21246    ///     if array.is_null() {
21247    ///         panic!("Java Array is null")
21248    ///     }
21249    ///
21250    ///     env.GetBooleanArrayRegion_into_slice(array, chunk_offset as jsize, chunk_buffer);
21251    ///     if env.ExceptionCheck() {
21252    ///         //ArrayIndexOutOfBoundsException
21253    ///         env.ExceptionClear();
21254    ///         return false;
21255    ///     }
21256    ///     true
21257    /// }
21258    /// ```
21259    ///
21260    pub unsafe fn GetBooleanArrayRegion_into_slice(&self, array: jbooleanArray, start: jsize, buf: &mut [jboolean]) {
21261        unsafe {
21262            self.GetBooleanArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_mut_ptr());
21263        }
21264    }
21265
21266    ///
21267    /// Copies data from the slice `buf` into the jbooleanArray `array` starting at the given `start` index.
21268    ///
21269    /// # Arguments
21270    /// * `array` - handle to a Java jbooleanArray.
21271    /// * `start` - the index where the first element should be coped into in the Java jybteArray
21272    /// * `buf` - the slice where data is copied from
21273    ///
21274    /// # Throws Java Exception:
21275    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
21276    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21277    ///
21278    /// It is JVM implementation specific what is stored inside `array` if this function throws an exception.
21279    /// * Data partially written
21280    /// * No data written
21281    ///
21282    /// # Panics
21283    /// if asserts feature is enabled and UB was detected
21284    ///
21285    /// # Safety
21286    /// Current thread must not be detached from JNI.
21287    ///
21288    /// Current thread must not be currently throwing an exception.
21289    ///
21290    /// Current thread does not hold a critical reference.
21291    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21292    ///
21293    /// `array` must be a valid non-null reference to a jbooleanArray.
21294    ///
21295    /// # Example
21296    /// ```rust
21297    /// use jni_simple::{*};
21298    ///
21299    /// unsafe fn copy_chunk_from_rust_to_java(env: JNIEnv,
21300    ///         array: jbooleanArray, chunk_buffer: &[i8], chunk_offset: usize) -> bool {
21301    ///     if array.is_null() {
21302    ///         panic!("Java Array is null")
21303    ///     }
21304    ///
21305    ///     env.SetByteArrayRegion_from_slice(array, chunk_offset as jsize, chunk_buffer);
21306    ///     if env.ExceptionCheck() {
21307    ///         //ArrayIndexOutOfBoundsException
21308    ///         env.ExceptionClear();
21309    ///         return false;
21310    ///     }
21311    ///     true
21312    /// }
21313    /// ```
21314    ///
21315    pub unsafe fn SetBooleanArrayRegion_from_slice(&self, array: jbooleanArray, start: jsize, buf: &[impl JBooleanInputLayout]) {
21316        let ptr: *const jboolean = buf.as_ptr().cast();
21317        unsafe {
21318            self.SetBooleanArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), ptr);
21319        }
21320    }
21321
21322    ///
21323    /// Copies data from a Java jbooleanArray `array` into a new `Vec<jboolean>`
21324    ///
21325    /// # Arguments
21326    /// * `array` - handle to a Java jbooleanArray.
21327    /// * `start` - the index of the first element to copy in the Java jbooleanArray
21328    /// * `len` - the amount of data that should be copied. If `None` then all remaining elements in the array are copied.
21329    ///
21330    /// # Returns:
21331    /// a new `Vec<jboolean>` that contains the copied data.
21332    ///
21333    /// # Returns empty Vec:
21334    /// * When the array in fact was empty or len was zero.
21335    /// * When this function throws a Java Exception.
21336    ///
21337    /// # Throws Java Exception:
21338    /// * `ArrayIndexOutOfBoundsException` - if `len` is negative.
21339    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the array.
21340    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative.
21341    /// * `ArrayIndexOutOfBoundsException` - if `start` is larget than `env.GetArrayLength(array)`.
21342    /// * `ArrayIndexOutOfBoundsException` - if `start` equals env.GetArrayLength(array) and `len` is larger than 0.
21343    ///
21344    /// # Panics
21345    /// if asserts feature is enabled and UB was detected
21346    ///
21347    /// # Safety
21348    /// Current thread must not be detached from JNI.
21349    ///
21350    /// Current thread must not be currently throwing an exception.
21351    ///
21352    /// Current thread does not hold a critical reference.
21353    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21354    ///
21355    /// `array` must be a valid non-null reference to a jbooleanArray.
21356    ///
21357    /// # Example
21358    /// ```rust
21359    /// use jni_simple::{*};
21360    ///
21361    /// unsafe fn copy_entire_java_array_to_rust(env: JNIEnv, array: jbooleanArray) -> Vec<jboolean> {
21362    ///     if array.is_null() {
21363    ///         panic!("Java Array is null")
21364    ///     }
21365    ///     env.GetBooleanArrayRegion_as_vec(array, 0, None)
21366    /// }
21367    /// ```
21368    ///
21369    pub unsafe fn GetBooleanArrayRegion_as_vec(&self, array: jbyteArray, start: jsize, len: Option<jsize>) -> Vec<jboolean> {
21370        unsafe {
21371            let len = len.unwrap_or_else(|| self.GetArrayLength(array).saturating_sub(start.max(0)).max(0));
21372            if let Ok(len) = usize::try_from(len) {
21373                let mut data = vec![jboolean::FALSE; len]; //We could un-init this, but better play it safe...
21374                self.GetBooleanArrayRegion_into_slice(array, start, data.as_mut_slice());
21375                if self.ExceptionCheck() {
21376                    return Vec::new();
21377                }
21378                return data;
21379            }
21380
21381            //Negative len
21382            let mut sentinel_buffer = [jboolean::FALSE];
21383            self.GetBooleanArrayRegion(array, start, len.min(-1), sentinel_buffer.as_mut_ptr());
21384            Vec::new()
21385        }
21386    }
21387
21388    ///
21389    /// Copies data from a Java jbooleanArray `array` into a new `Vec<bool>`
21390    ///
21391    /// # Arguments
21392    /// * `array` - handle to a Java jbooleanArray.
21393    /// * `start` - the index of the first element to copy in the Java jbooleanArray
21394    /// * `len` - the amount of data that should be copied. If `None` then all remaining elements in the array are copied.
21395    ///
21396    /// # Returns:
21397    /// a new `Vec<bool>` that contains the copied data.
21398    ///
21399    /// # Returns empty Vec:
21400    /// * When the array in fact was empty or len was zero.
21401    /// * When this function throws a Java Exception.
21402    ///
21403    /// # Throws Java Exception:
21404    /// * `ArrayIndexOutOfBoundsException` - if `len` is negative.
21405    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the array.
21406    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative.
21407    /// * `ArrayIndexOutOfBoundsException` - if `start` is larget than `env.GetArrayLength(array)`.
21408    /// * `ArrayIndexOutOfBoundsException` - if `start` equals env.GetArrayLength(array) and `len` is larger than 0.
21409    ///
21410    /// # Panics
21411    /// if asserts feature is enabled and UB was detected
21412    ///
21413    /// # Safety
21414    /// Current thread must not be detached from JNI.
21415    ///
21416    /// Current thread must not be currently throwing an exception.
21417    ///
21418    /// Current thread does not hold a critical reference.
21419    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21420    ///
21421    /// `array` must be a valid non-null reference to a jbooleanArray.
21422    ///
21423    /// # Example
21424    /// ```rust
21425    /// use jni_simple::{*};
21426    ///
21427    /// unsafe fn copy_entire_java_array_to_rust(env: JNIEnv, array: jbooleanArray) -> Vec<bool> {
21428    ///     if array.is_null() {
21429    ///         panic!("Java Array is null")
21430    ///     }
21431    ///     env.GetBooleanArrayRegion_as_bool_vec(array, 0, None)
21432    /// }
21433    /// ```
21434    ///
21435    pub unsafe fn GetBooleanArrayRegion_as_bool_vec(&self, array: jbyteArray, start: jsize, len: Option<jsize>) -> Vec<bool> {
21436        unsafe {
21437            let len = len.unwrap_or_else(|| self.GetArrayLength(array).saturating_sub(start.max(0)).max(0));
21438            if let Ok(len) = usize::try_from(len) {
21439                let mut data = vec![jboolean::FALSE; len]; //We could un-init this, but better play it safe...
21440                self.GetBooleanArrayRegion_into_slice(array, start, data.as_mut_slice());
21441                if self.ExceptionCheck() {
21442                    return Vec::new();
21443                }
21444
21445                return jboolean::narrow_vec(data);
21446            }
21447
21448            //Negative len
21449            let mut sentinel_buffer = [jboolean::FALSE];
21450            self.GetBooleanArrayRegion(array, start, len.min(-1), sentinel_buffer.as_mut_ptr());
21451            Vec::new()
21452        }
21453    }
21454
21455    ///
21456    /// Copies data from the jbooleanArray `array` starting from the given `start` index into the memory pointed to by `buf`.
21457    ///
21458    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_PrimitiveType_ArrayRegion_routines>
21459    ///
21460    /// # Arguments
21461    /// * `array` - handle to a Java jbooleanArray
21462    /// * `start` - the index of the first element to copy in the Java jbooleanArray
21463    /// * `len` - amount of data to be copied
21464    /// * `buf` - pointer to memory where the data should be copied to
21465    ///
21466    /// # Throws Java Exception:
21467    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the `array`.
21468    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21469    ///
21470    /// It is JVM implementation specific what is written into `buf` if this function throws an exception.
21471    /// * Data partially written
21472    /// * No data written
21473    ///
21474    /// # Panics
21475    /// if asserts feature is enabled and UB was detected
21476    ///
21477    /// # Safety
21478    /// Current thread must not be detached from JNI.
21479    ///
21480    /// Current thread must not be currently throwing an exception.
21481    ///
21482    /// Current thread does not hold a critical reference.
21483    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21484    ///
21485    /// `array` must be a valid non-null reference to a jbooleanArray.
21486    /// `buf` must be valid non-null pointer to memory with enough capacity to store `len` bytes.
21487    ///
21488    /// # Example
21489    /// ```rust
21490    /// use jni_simple::{*};
21491    ///
21492    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
21493    ///         array: jbooleanArray, chunk_buffer: &mut [jboolean], chunk_offset: usize) -> bool {
21494    ///     if array.is_null() {
21495    ///         panic!("Java Array is null")
21496    ///     }
21497    ///     env.GetBooleanArrayRegion(array, chunk_offset as jsize, chunk_buffer.len() as jsize, chunk_buffer.as_mut_ptr());
21498    ///     if env.ExceptionCheck() {
21499    ///         //ArrayIndexOutOfBoundsException
21500    ///         env.ExceptionClear();
21501    ///         return false;
21502    ///     }
21503    ///     true
21504    /// }
21505    /// ```
21506    ///
21507    pub unsafe fn GetBooleanArrayRegion(&self, array: jbooleanArray, start: jsize, len: jsize, buf: *mut jboolean) {
21508        unsafe {
21509            #[cfg(feature = "asserts")]
21510            {
21511                self.check_not_critical("GetBooleanArrayRegion");
21512                self.check_no_exception("GetBooleanArrayRegion");
21513                assert!(!array.is_null(), "GetBooleanArrayRegion jarray must not be null");
21514                assert!(!buf.is_null(), "GetBooleanArrayRegion buf must not be null");
21515            }
21516            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, jsize, jsize, *mut jboolean)>(199)(self.vtable, array, start, len, buf);
21517        }
21518    }
21519
21520    ///
21521    /// Copies data from the jbyteArray `array` starting from the given `start` index into the memory pointed to by `buf`.
21522    ///
21523    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_PrimitiveType_ArrayRegion_routines>
21524    ///
21525    /// # Arguments
21526    /// * `array` - handle to a Java jbyteArray
21527    /// * `start` - the index of the first element to copy in the Java jbyteArray
21528    /// * `len` - amount of data to be copied
21529    /// * `buf` - pointer to memory where the data should be copied to
21530    ///
21531    /// # Throws Java Exception:
21532    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the `array`.
21533    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21534    ///
21535    /// It is JVM implementation specific what is written into `buf` if this function throws an exception.
21536    /// * Data partially written
21537    /// * No data written
21538    ///
21539    /// # Panics
21540    /// if asserts feature is enabled and UB was detected
21541    ///
21542    /// # Safety
21543    /// Current thread must not be detached from JNI.
21544    ///
21545    /// Current thread must not be currently throwing an exception.
21546    ///
21547    /// Current thread does not hold a critical reference.
21548    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21549    ///
21550    /// `array` must be a valid non-null reference to a jbyteArray.
21551    /// `buf` must be valid non-null pointer to memory with enough capacity to store `len` bytes.
21552    ///
21553    /// # Example
21554    /// ```rust
21555    /// use jni_simple::{*};
21556    ///
21557    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
21558    ///         array: jbyteArray, chunk_buffer: &mut [i8], chunk_offset: usize) -> bool {
21559    ///     if array.is_null() {
21560    ///         panic!("Java Array is null")
21561    ///     }
21562    ///
21563    ///     env.GetByteArrayRegion(array, chunk_offset as jsize, chunk_buffer.len() as jsize, chunk_buffer.as_mut_ptr());
21564    ///     if env.ExceptionCheck() {
21565    ///         //ArrayIndexOutOfBoundsException
21566    ///         env.ExceptionClear();
21567    ///         return false;
21568    ///     }
21569    ///     true
21570    /// }
21571    /// ```
21572    ///
21573    pub unsafe fn GetByteArrayRegion(&self, array: jbyteArray, start: jsize, len: jsize, buf: *mut jbyte) {
21574        unsafe {
21575            #[cfg(feature = "asserts")]
21576            {
21577                self.check_not_critical("GetByteArrayRegion");
21578                self.check_no_exception("GetByteArrayRegion");
21579                assert!(!array.is_null(), "GetByteArrayRegion jarray must not be null");
21580                assert!(!buf.is_null(), "GetByteArrayRegion buf must not be null");
21581            }
21582
21583            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, jsize, jsize, *mut jbyte)>(200)(self.vtable, array, start, len, buf);
21584        }
21585    }
21586
21587    ///
21588    /// Copies data from the jbyteArray `array` starting from the given `start` index into the slice `buf`.
21589    ///
21590    /// # Arguments
21591    /// * `array` - handle to a Java jbyteArray.
21592    /// * `start` - the index of the first element to copy in the Java jbyteArray
21593    /// * `buf` - the slice to copy data into
21594    ///
21595    /// # Throws Java Exception:
21596    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
21597    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21598    ///
21599    /// It is JVM implementation specific what is stored inside buf if this function throws an exception.
21600    /// * Data partially written
21601    /// * No data written
21602    ///
21603    /// # Panics
21604    /// if asserts feature is enabled and UB was detected
21605    /// if the `buf.len()` is larger than `jsize::MAX`
21606    ///
21607    /// # Safety
21608    /// Current thread must not be detached from JNI.
21609    ///
21610    /// Current thread must not be currently throwing an exception.
21611    ///
21612    /// Current thread does not hold a critical reference.
21613    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21614    ///
21615    /// `array` must be a valid non-null reference to a jbyteArray.
21616    ///
21617    /// # Example
21618    /// ```rust
21619    /// use jni_simple::{*};
21620    ///
21621    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
21622    ///         array: jbyteArray, chunk_buffer: &mut [jbyte], chunk_offset: usize) -> bool {
21623    ///     if array.is_null() {
21624    ///         panic!("Java Array is null")
21625    ///     }
21626    ///
21627    ///     env.GetByteArrayRegion_into_slice(array, chunk_offset as jsize, chunk_buffer);
21628    ///     if env.ExceptionCheck() {
21629    ///         //ArrayIndexOutOfBoundsException
21630    ///         env.ExceptionClear();
21631    ///         return false;
21632    ///     }
21633    ///     true
21634    /// }
21635    /// ```
21636    ///
21637    pub unsafe fn GetByteArrayRegion_into_slice(&self, array: jbyteArray, start: jsize, buf: &mut [jbyte]) {
21638        unsafe {
21639            self.GetByteArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_mut_ptr());
21640        }
21641    }
21642
21643    ///
21644    /// Copies data from the slice `buf` into the jbyteArray `array` starting at the given `start` index.
21645    ///
21646    /// # Arguments
21647    /// * `array` - handle to a Java jbyteArray.
21648    /// * `start` - the index where the first element should be coped into in the Java jybteArray
21649    /// * `buf` - the slice where data is copied from
21650    ///
21651    /// # Throws Java Exception:
21652    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
21653    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21654    ///
21655    /// It is JVM implementation specific what is stored inside `array` if this function throws an exception.
21656    /// * Data partially written
21657    /// * No data written
21658    ///
21659    /// # Panics
21660    /// if asserts feature is enabled and UB was detected
21661    ///
21662    /// # Safety
21663    /// Current thread must not be detached from JNI.
21664    ///
21665    /// Current thread must not be currently throwing an exception.
21666    ///
21667    /// Current thread does not hold a critical reference.
21668    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21669    ///
21670    /// `array` must be a valid non-null reference to a jbyteArray.
21671    ///
21672    /// # Example
21673    /// ```rust
21674    /// use jni_simple::{*};
21675    ///
21676    /// unsafe fn copy_chunk_from_rust_to_java(env: JNIEnv,
21677    ///         array: jbyteArray, chunk_buffer: &[jbyte], chunk_offset: usize) -> bool {
21678    ///     if array.is_null() {
21679    ///         panic!("Java Array is null")
21680    ///     }
21681    ///
21682    ///     env.SetByteArrayRegion_from_slice(array, chunk_offset as jsize, chunk_buffer);
21683    ///     if env.ExceptionCheck() {
21684    ///         //ArrayIndexOutOfBoundsException
21685    ///         env.ExceptionClear();
21686    ///         return false;
21687    ///     }
21688    ///     true
21689    /// }
21690    /// ```
21691    ///
21692    pub unsafe fn SetByteArrayRegion_from_slice(&self, array: jbyteArray, start: jsize, buf: &[jbyte]) {
21693        unsafe {
21694            self.SetByteArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_ptr());
21695        }
21696    }
21697
21698    ///
21699    /// Copies data from a Java jbyteArray `array` into a new `Vec<jbyte>`
21700    ///
21701    /// # Arguments
21702    /// * `array` - handle to a Java jbyteArray.
21703    /// * `start` - the index of the first element to copy in the Java jbyteArray
21704    /// * `len` - the amount of data that should be copied. If `None` then all remaining elements in the array are copied.
21705    ///
21706    /// # Returns:
21707    /// a new `Vec<jbyte>` that contains the copied data.
21708    ///
21709    /// # Returns empty Vec:
21710    /// * When the array in fact was empty or len was zero.
21711    /// * When this function throws a Java Exception.
21712    ///
21713    /// # Throws Java Exception:
21714    /// * `ArrayIndexOutOfBoundsException` - if `len` is negative.
21715    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the array.
21716    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative.
21717    /// * `ArrayIndexOutOfBoundsException` - if `start` is larget than `env.GetArrayLength(array)`.
21718    /// * `ArrayIndexOutOfBoundsException` - if `start` equals env.GetArrayLength(array) and `len` is larger than 0.
21719    ///
21720    /// # Panics
21721    /// if asserts feature is enabled and UB was detected
21722    ///
21723    /// # Safety
21724    /// Current thread must not be detached from JNI.
21725    ///
21726    /// Current thread must not be currently throwing an exception.
21727    ///
21728    /// Current thread does not hold a critical reference.
21729    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21730    ///
21731    /// `array` must be a valid non-null reference to a jbyteArray.
21732    ///
21733    /// # Example
21734    /// ```rust
21735    /// use jni_simple::{*};
21736    ///
21737    /// unsafe fn copy_entire_java_array_to_rust(env: JNIEnv, array: jbyteArray) -> Vec<jbyte> {
21738    ///     if array.is_null() {
21739    ///         panic!("Java Array is null")
21740    ///     }
21741    ///     env.GetByteArrayRegion_as_vec(array, 0, None)
21742    /// }
21743    /// ```
21744    ///
21745    pub unsafe fn GetByteArrayRegion_as_vec(&self, array: jbyteArray, start: jsize, len: Option<jsize>) -> Vec<jbyte> {
21746        unsafe {
21747            let len = len.unwrap_or_else(|| self.GetArrayLength(array).saturating_sub(start.max(0)).max(0));
21748            if let Ok(len) = usize::try_from(len) {
21749                let mut data = vec![0i8; len]; //We could un-init this, but better play it safe...
21750                self.GetByteArrayRegion_into_slice(array, start, data.as_mut_slice());
21751                if self.ExceptionCheck() {
21752                    return Vec::new();
21753                }
21754                return data;
21755            }
21756
21757            //Negative len
21758            let mut sentinel_buffer = [0];
21759            self.GetByteArrayRegion(array, start, len.min(-1), sentinel_buffer.as_mut_ptr());
21760            Vec::new()
21761        }
21762    }
21763
21764    ///
21765    /// Copies data from the jcharArray `array` starting from the given `start` index into the memory pointed to by `buf`.
21766    ///
21767    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_PrimitiveType_ArrayRegion_routines>
21768    ///
21769    /// # Arguments
21770    /// * `array` - handle to a Java jcharArray
21771    /// * `start` - the index of the first element to copy in the Java jcharArray
21772    /// * `len` - amount of data to be copied
21773    /// * `buf` - pointer to memory where the data should be copied to
21774    ///
21775    /// # Throws Java Exception:
21776    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the `array`.
21777    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21778    ///
21779    /// It is JVM implementation specific what is written into `buf` if this function throws an exception.
21780    /// * Data partially written
21781    /// * No data written
21782    ///
21783    /// # Panics
21784    /// if asserts feature is enabled and UB was detected
21785    ///
21786    /// # Safety
21787    /// Current thread must not be detached from JNI.
21788    ///
21789    /// Current thread must not be currently throwing an exception.
21790    ///
21791    /// Current thread does not hold a critical reference.
21792    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21793    ///
21794    /// `array` must be a valid non-null reference to a jcharArray.
21795    /// `buf` must be valid non-null pointer to memory with enough capacity and proper alignment to store `len` jchar's.
21796    ///
21797    /// # Example
21798    /// ```rust
21799    /// use jni_simple::{*};
21800    ///
21801    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
21802    ///         array: jcharArray, chunk_buffer: &mut [jchar], chunk_offset: usize) -> bool {
21803    ///     if array.is_null() {
21804    ///         panic!("Java Array is null")
21805    ///     }
21806    ///
21807    ///     env.GetCharArrayRegion(array, chunk_offset as jsize, chunk_buffer.len() as jsize, chunk_buffer.as_mut_ptr());
21808    ///     if env.ExceptionCheck() {
21809    ///         //ArrayIndexOutOfBoundsException
21810    ///         env.ExceptionClear();
21811    ///         return false;
21812    ///     }
21813    ///     true
21814    /// }
21815    /// ```
21816    ///
21817    pub unsafe fn GetCharArrayRegion(&self, array: jcharArray, start: jsize, len: jsize, buf: *mut jchar) {
21818        unsafe {
21819            #[cfg(feature = "asserts")]
21820            {
21821                self.check_not_critical("GetCharArrayRegion");
21822                self.check_no_exception("GetCharArrayRegion");
21823                assert!(!array.is_null(), "GetCharArrayRegion jarray must not be null");
21824                assert!(!buf.is_null(), "GetCharArrayRegion buf must not be null");
21825                assert_eq!(0, buf.align_offset(align_of::<jchar>()), "GetCharArrayRegion buf pointer is not aligned");
21826            }
21827
21828            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, jsize, jsize, *mut jchar)>(201)(self.vtable, array, start, len, buf);
21829        }
21830    }
21831
21832    ///
21833    /// Copies data from the jcharArray `array` starting from the given `start` index into the slice `buf`.
21834    ///
21835    /// # Arguments
21836    /// * `array` - handle to a Java jcharArray.
21837    /// * `start` - the index of the first element to copy in the Java jcharArray
21838    /// * `buf` - the slice to copy data into
21839    ///
21840    /// # Throws Java Exception:
21841    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
21842    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21843    ///
21844    /// It is JVM implementation specific what is stored inside buf if this function throws an exception.
21845    /// * Data partially written
21846    /// * No data written
21847    ///
21848    /// # Panics
21849    /// if asserts feature is enabled and UB was detected
21850    /// if the `buf.len()` is larger than `jsize::MAX`
21851    ///
21852    /// # Safety
21853    /// Current thread must not be detached from JNI.
21854    ///
21855    /// Current thread must not be currently throwing an exception.
21856    ///
21857    /// Current thread does not hold a critical reference.
21858    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21859    ///
21860    /// `array` must be a valid non-null reference to a jcharArray.
21861    ///
21862    /// # Example
21863    /// ```rust
21864    /// use jni_simple::{*};
21865    ///
21866    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
21867    ///         array: jcharArray, chunk_buffer: &mut [jchar], chunk_offset: usize) -> bool {
21868    ///     if array.is_null() {
21869    ///         panic!("Java Array is null")
21870    ///     }
21871    ///
21872    ///     env.GetCharArrayRegion_into_slice(array, chunk_offset as jsize, chunk_buffer);
21873    ///     if env.ExceptionCheck() {
21874    ///         //ArrayIndexOutOfBoundsException
21875    ///         env.ExceptionClear();
21876    ///         return false;
21877    ///     }
21878    ///     true
21879    /// }
21880    /// ```
21881    ///
21882    pub unsafe fn GetCharArrayRegion_into_slice(&self, array: jcharArray, start: jsize, buf: &mut [jchar]) {
21883        unsafe {
21884            self.GetCharArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_mut_ptr());
21885        }
21886    }
21887
21888    ///
21889    /// Copies data from the slice `buf` into the jcharArray `array` starting at the given `start` index.
21890    ///
21891    /// # Arguments
21892    /// * `array` - handle to a Java jcharArray.
21893    /// * `start` - the index where the first element should be coped into in the Java jcharArray
21894    /// * `buf` - the slice where data is copied from
21895    ///
21896    /// # Throws Java Exception:
21897    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
21898    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21899    ///
21900    /// It is JVM implementation specific what is stored inside `array` if this function throws an exception.
21901    /// * Data partially written
21902    /// * No data written
21903    ///
21904    /// # Panics
21905    /// if asserts feature is enabled and UB was detected
21906    ///
21907    /// # Safety
21908    /// Current thread must not be detached from JNI.
21909    ///
21910    /// Current thread must not be currently throwing an exception.
21911    ///
21912    /// Current thread does not hold a critical reference.
21913    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21914    ///
21915    /// `array` must be a valid non-null reference to a jcharArray.
21916    ///
21917    /// # Example
21918    /// ```rust
21919    /// use jni_simple::{*};
21920    ///
21921    /// unsafe fn copy_chunk_from_rust_to_java(env: JNIEnv,
21922    ///         array: jcharArray, chunk_buffer: &[u16], chunk_offset: usize) -> bool {
21923    ///     if array.is_null() {
21924    ///         panic!("Java Array is null")
21925    ///     }
21926    ///
21927    ///     env.SetCharArrayRegion_from_slice(array, chunk_offset as jsize, chunk_buffer);
21928    ///     if env.ExceptionCheck() {
21929    ///         //ArrayIndexOutOfBoundsException
21930    ///         env.ExceptionClear();
21931    ///         return false;
21932    ///     }
21933    ///     true
21934    /// }
21935    /// ```
21936    ///
21937    pub unsafe fn SetCharArrayRegion_from_slice(&self, array: jcharArray, start: jsize, buf: &[jchar]) {
21938        unsafe {
21939            self.SetCharArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_ptr());
21940        }
21941    }
21942
21943    ///
21944    /// Copies data from a Java jcharArray `array` into a new `Vec<jchar>`
21945    ///
21946    /// # Arguments
21947    /// * `array` - handle to a Java jcharArray.
21948    /// * `start` - the index of the first element to copy in the Java jcharArray
21949    /// * `len` - the amount of data that should be copied. If `None` then all remaining elements in the array are copied.
21950    ///
21951    /// # Returns:
21952    /// a new `Vec<jchar>` that contains the copied data.
21953    ///
21954    /// # Returns empty Vec:
21955    /// * When the array in fact was empty or len was zero.
21956    /// * When this function throws a Java Exception.
21957    ///
21958    /// # Throws Java Exception:
21959    /// * `ArrayIndexOutOfBoundsException` - if `len` is negative.
21960    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the array.
21961    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative.
21962    /// * `ArrayIndexOutOfBoundsException` - if `start` is larget than `env.GetArrayLength(array)`.
21963    /// * `ArrayIndexOutOfBoundsException` - if `start` equals env.GetArrayLength(array) and `len` is larger than 0.
21964    ///
21965    /// # Panics
21966    /// if asserts feature is enabled and UB was detected
21967    ///
21968    /// # Safety
21969    /// Current thread must not be detached from JNI.
21970    ///
21971    /// Current thread must not be currently throwing an exception.
21972    ///
21973    /// Current thread does not hold a critical reference.
21974    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21975    ///
21976    /// `array` must be a valid non-null reference to a jcharArray.
21977    ///
21978    /// # Example
21979    /// ```rust
21980    /// use jni_simple::{*};
21981    ///
21982    /// unsafe fn copy_entire_java_array_to_rust(env: JNIEnv, array: jcharArray) -> Vec<jchar> {
21983    ///     if array.is_null() {
21984    ///         panic!("Java Array is null")
21985    ///     }
21986    ///     env.GetCharArrayRegion_as_vec(array, 0, None)
21987    /// }
21988    /// ```
21989    ///
21990    pub unsafe fn GetCharArrayRegion_as_vec(&self, array: jcharArray, start: jsize, len: Option<jsize>) -> Vec<jchar> {
21991        unsafe {
21992            let len = len.unwrap_or_else(|| self.GetArrayLength(array).saturating_sub(start.max(0)).max(0));
21993            if let Ok(len) = usize::try_from(len) {
21994                let mut data = vec![0u16; len]; //We could un-init this, but better play it safe...
21995                self.GetCharArrayRegion_into_slice(array, start, data.as_mut_slice());
21996                if self.ExceptionCheck() {
21997                    return Vec::new();
21998                }
21999                return data;
22000            }
22001
22002            //Negative len
22003            let mut sentinel_buffer = [0];
22004            self.GetCharArrayRegion(array, start, len.min(-1), sentinel_buffer.as_mut_ptr());
22005            Vec::new()
22006        }
22007    }
22008
22009    ///
22010    /// Copies data from the jshortArray `array` starting from the given `start` index into the memory pointed to by `buf`.
22011    ///
22012    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_PrimitiveType_ArrayRegion_routines>
22013    ///
22014    /// # Arguments
22015    /// * `array` - handle to a Java jshortArray
22016    /// * `start` - the index of the first element to copy in the Java jshortArray
22017    /// * `len` - amount of data to be copied
22018    /// * `buf` - pointer to memory where the data should be copied to
22019    ///
22020    /// # Throws Java Exception:
22021    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the `array`.
22022    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
22023    ///
22024    /// It is JVM implementation specific what is written into `buf` if this function throws an exception.
22025    /// * Data partially written
22026    /// * No data written
22027    ///
22028    /// # Panics
22029    /// if asserts feature is enabled and UB was detected
22030    ///
22031    /// # Safety
22032    /// Current thread must not be detached from JNI.
22033    ///
22034    /// Current thread must not be currently throwing an exception.
22035    ///
22036    /// Current thread does not hold a critical reference.
22037    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22038    ///
22039    /// `array` must be a valid non-null reference to a jshortArray.
22040    /// `buf` must be valid non-null pointer to memory with enough capacity and proper alignment to store `len` jshort's.
22041    ///
22042    /// # Example
22043    /// ```rust
22044    /// use jni_simple::{*};
22045    ///
22046    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
22047    ///         array: jshortArray, chunk_buffer: &mut [jshort], chunk_offset: usize) -> bool {
22048    ///     if array.is_null() {
22049    ///         panic!("Java Array is null")
22050    ///     }
22051    ///
22052    ///     env.GetShortArrayRegion(array, chunk_offset as jsize, chunk_buffer.len() as jsize, chunk_buffer.as_mut_ptr());
22053    ///     if env.ExceptionCheck() {
22054    ///         //ArrayIndexOutOfBoundsException
22055    ///         env.ExceptionClear();
22056    ///         return false;
22057    ///     }
22058    ///     true
22059    /// }
22060    /// ```
22061    ///
22062    pub unsafe fn GetShortArrayRegion(&self, array: jshortArray, start: jsize, len: jsize, buf: *mut jshort) {
22063        unsafe {
22064            #[cfg(feature = "asserts")]
22065            {
22066                self.check_not_critical("GetShortArrayRegion");
22067                self.check_no_exception("GetShortArrayRegion");
22068                assert!(!array.is_null(), "GetShortArrayRegion jarray must not be null");
22069                assert!(!buf.is_null(), "GetShortArrayRegion buf must not be null");
22070                assert_eq!(0, buf.align_offset(align_of::<jshort>()), "GetShortArrayRegion buf pointer is not aligned");
22071            }
22072
22073            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, jsize, jsize, *mut jshort)>(202)(self.vtable, array, start, len, buf);
22074        }
22075    }
22076
22077    ///
22078    /// Copies data from the jshortArray `array` starting from the given `start` index into the slice `buf`.
22079    ///
22080    /// # Arguments
22081    /// * `array` - handle to a Java jshortArray.
22082    /// * `start` - the index of the first element to copy in the Java jshortArray
22083    /// * `buf` - the slice to copy data into
22084    ///
22085    /// # Throws Java Exception:
22086    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
22087    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
22088    ///
22089    /// It is JVM implementation specific what is stored inside buf if this function throws an exception.
22090    /// * Data partially written
22091    /// * No data written
22092    ///
22093    /// # Panics
22094    /// if asserts feature is enabled and UB was detected
22095    /// if the `buf.len()` is larger than `jsize::MAX`
22096    ///
22097    /// # Safety
22098    /// Current thread must not be detached from JNI.
22099    ///
22100    /// Current thread must not be currently throwing an exception.
22101    ///
22102    /// Current thread does not hold a critical reference.
22103    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22104    ///
22105    /// `array` must be a valid non-null reference to a jshortArray.
22106    ///
22107    /// # Example
22108    /// ```rust
22109    /// use jni_simple::{*};
22110    ///
22111    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
22112    ///         array: jshortArray, chunk_buffer: &mut [jshort], chunk_offset: usize) -> bool {
22113    ///     if array.is_null() {
22114    ///         panic!("Java Array is null")
22115    ///     }
22116    ///
22117    ///     env.GetShortArrayRegion_into_slice(array, chunk_offset as jsize, chunk_buffer);
22118    ///     if env.ExceptionCheck() {
22119    ///         //ArrayIndexOutOfBoundsException
22120    ///         env.ExceptionClear();
22121    ///         return false;
22122    ///     }
22123    ///     true
22124    /// }
22125    /// ```
22126    ///
22127    pub unsafe fn GetShortArrayRegion_into_slice(&self, array: jshortArray, start: jsize, buf: &mut [jshort]) {
22128        unsafe {
22129            self.GetShortArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_mut_ptr());
22130        }
22131    }
22132
22133    ///
22134    /// Copies data from the slice `buf` into the jshortArray `array` starting at the given `start` index.
22135    ///
22136    /// # Arguments
22137    /// * `array` - handle to a Java jshortArray.
22138    /// * `start` - the index where the first element should be coped into in the Java jshortArray
22139    /// * `buf` - the slice where data is copied from
22140    ///
22141    /// # Throws Java Exception:
22142    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
22143    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
22144    ///
22145    /// It is JVM implementation specific what is stored inside `array` if this function throws an exception.
22146    /// * Data partially written
22147    /// * No data written
22148    ///
22149    /// # Panics
22150    /// if asserts feature is enabled and UB was detected
22151    ///
22152    /// # Safety
22153    /// Current thread must not be detached from JNI.
22154    ///
22155    /// Current thread must not be currently throwing an exception.
22156    ///
22157    /// Current thread does not hold a critical reference.
22158    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22159    ///
22160    /// `array` must be a valid non-null reference to a jshortArray.
22161    ///
22162    /// # Example
22163    /// ```rust
22164    /// use jni_simple::{*};
22165    ///
22166    /// unsafe fn copy_chunk_from_rust_to_java(env: JNIEnv,
22167    ///         array: jshortArray, chunk_buffer: &[jshort], chunk_offset: usize) -> bool {
22168    ///     if array.is_null() {
22169    ///         panic!("Java Array is null")
22170    ///     }
22171    ///
22172    ///     env.SetShortArrayRegion_from_slice(array, chunk_offset as jsize, chunk_buffer);
22173    ///     if env.ExceptionCheck() {
22174    ///         //ArrayIndexOutOfBoundsException
22175    ///         env.ExceptionClear();
22176    ///         return false;
22177    ///     }
22178    ///     true
22179    /// }
22180    /// ```
22181    ///
22182    pub unsafe fn SetShortArrayRegion_from_slice(&self, array: jshortArray, start: jsize, buf: &[jshort]) {
22183        unsafe {
22184            self.SetShortArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_ptr());
22185        }
22186    }
22187
22188    ///
22189    /// Copies data from a Java jshortArray `array` into a new `Vec<jshort>`
22190    ///
22191    /// # Arguments
22192    /// * `array` - handle to a Java jshortArray.
22193    /// * `start` - the index of the first element to copy in the Java jshortArray
22194    /// * `len` - the amount of data that should be copied. If `None` then all remaining elements in the array are copied.
22195    ///
22196    /// # Returns:
22197    /// a new `Vec<jshort>` that contains the copied data.
22198    ///
22199    /// # Returns empty Vec:
22200    /// * When the array in fact was empty or len was zero.
22201    /// * When this function throws a Java Exception.
22202    ///
22203    /// # Throws Java Exception:
22204    /// * `ArrayIndexOutOfBoundsException` - if `len` is negative.
22205    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the array.
22206    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative.
22207    /// * `ArrayIndexOutOfBoundsException` - if `start` is larget than `env.GetArrayLength(array)`.
22208    /// * `ArrayIndexOutOfBoundsException` - if `start` equals env.GetArrayLength(array) and `len` is larger than 0.
22209    ///
22210    /// # Panics
22211    /// if asserts feature is enabled and UB was detected
22212    ///
22213    /// # Safety
22214    /// Current thread must not be detached from JNI.
22215    ///
22216    /// Current thread must not be currently throwing an exception.
22217    ///
22218    /// Current thread does not hold a critical reference.
22219    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22220    ///
22221    /// `array` must be a valid non-null reference to a jshortArray.
22222    ///
22223    /// # Example
22224    /// ```rust
22225    /// use jni_simple::{*};
22226    ///
22227    /// unsafe fn copy_entire_java_array_to_rust(env: JNIEnv, array: jshortArray) -> Vec<jshort> {
22228    ///     if array.is_null() {
22229    ///         panic!("Java Array is null")
22230    ///     }
22231    ///     env.GetShortArrayRegion_as_vec(array, 0, None)
22232    /// }
22233    /// ```
22234    ///
22235    pub unsafe fn GetShortArrayRegion_as_vec(&self, array: jshortArray, start: jsize, len: Option<jsize>) -> Vec<jshort> {
22236        unsafe {
22237            let len = len.unwrap_or_else(|| self.GetArrayLength(array).saturating_sub(start.max(0)).max(0));
22238            if let Ok(len) = usize::try_from(len) {
22239                let mut data = vec![0i16; len]; //We could un-init this, but better play it safe...
22240                self.GetShortArrayRegion_into_slice(array, start, data.as_mut_slice());
22241                if self.ExceptionCheck() {
22242                    return Vec::new();
22243                }
22244                return data;
22245            }
22246
22247            //Negative len
22248            let mut sentinel_buffer = [0];
22249            self.GetShortArrayRegion(array, start, len.min(-1), sentinel_buffer.as_mut_ptr());
22250            Vec::new()
22251        }
22252    }
22253
22254    ///
22255    /// Copies data from the jintArray `array` starting from the given `start` index into the memory pointed to by `buf`.
22256    ///
22257    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_PrimitiveType_ArrayRegion_routines>
22258    ///
22259    /// # Arguments
22260    /// * `array` - handle to a Java jintArray
22261    /// * `start` - the index of the first element to copy in the Java jintArray
22262    /// * `len` - amount of data to be copied
22263    /// * `buf` - pointer to memory where the data should be copied to
22264    ///
22265    /// # Throws Java Exception:
22266    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the `array`.
22267    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
22268    ///
22269    /// It is JVM implementation specific what is written into `buf` if this function throws an exception.
22270    /// * Data partially written
22271    /// * No data written
22272    ///
22273    /// # Panics
22274    /// if asserts feature is enabled and UB was detected
22275    ///
22276    /// # Safety
22277    /// Current thread must not be detached from JNI.
22278    ///
22279    /// Current thread must not be currently throwing an exception.
22280    ///
22281    /// Current thread does not hold a critical reference.
22282    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22283    ///
22284    /// `array` must be a valid non-null reference to a jintArray.
22285    /// `buf` must be valid non-null pointer to memory with enough capacity and proper alignment to store `len` jint's.
22286    ///
22287    /// # Example
22288    /// ```rust
22289    /// use jni_simple::{*};
22290    ///
22291    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
22292    ///         array: jintArray, chunk_buffer: &mut [jint], chunk_offset: usize) -> bool {
22293    ///     if array.is_null() {
22294    ///         panic!("Java Array is null")
22295    ///     }
22296    ///
22297    ///     env.GetIntArrayRegion(array, chunk_offset as jsize, chunk_buffer.len() as jsize, chunk_buffer.as_mut_ptr());
22298    ///     if env.ExceptionCheck() {
22299    ///         //ArrayIndexOutOfBoundsException
22300    ///         env.ExceptionClear();
22301    ///         return false;
22302    ///     }
22303    ///     true
22304    /// }
22305    /// ```
22306    ///
22307    pub unsafe fn GetIntArrayRegion(&self, array: jintArray, start: jsize, len: jsize, buf: *mut jint) {
22308        unsafe {
22309            #[cfg(feature = "asserts")]
22310            {
22311                self.check_not_critical("GetIntArrayRegion");
22312                self.check_no_exception("GetIntArrayRegion");
22313                assert!(!array.is_null(), "GetIntArrayRegion jarray must not be null");
22314                assert!(!buf.is_null(), "GetIntArrayRegion buf must not be null");
22315                assert_eq!(0, buf.align_offset(align_of::<jint>()), "GetIntArrayRegion buf pointer is not aligned");
22316            }
22317
22318            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, jsize, jsize, *mut jint)>(203)(self.vtable, array, start, len, buf);
22319        }
22320    }
22321
22322    ///
22323    /// Copies data from the jintArray `array` starting from the given `start` index into the slice `buf`.
22324    ///
22325    /// # Arguments
22326    /// * `array` - handle to a Java jintArray.
22327    /// * `start` - the index of the first element to copy in the Java jintArray
22328    /// * `buf` - the slice to copy data into
22329    ///
22330    /// # Throws Java Exception:
22331    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
22332    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
22333    ///
22334    /// It is JVM implementation specific what is stored inside buf if this function throws an exception.
22335    /// * Data partially written
22336    /// * No data written
22337    ///
22338    /// # Panics
22339    /// if asserts feature is enabled and UB was detected
22340    /// if the `buf.len()` is larger than `jsize::MAX`
22341    ///
22342    /// # Safety
22343    /// Current thread must not be detached from JNI.
22344    ///
22345    /// Current thread must not be currently throwing an exception.
22346    ///
22347    /// Current thread does not hold a critical reference.
22348    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22349    ///
22350    /// `array` must be a valid non-null reference to a jintArray.
22351    ///
22352    /// # Example
22353    /// ```rust
22354    /// use jni_simple::{*};
22355    ///
22356    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
22357    ///         array: jintArray, chunk_buffer: &mut [jint], chunk_offset: usize) -> bool {
22358    ///     if array.is_null() {
22359    ///         panic!("Java Array is null")
22360    ///     }
22361    ///
22362    ///     env.GetIntArrayRegion_into_slice(array, chunk_offset as jsize, chunk_buffer);
22363    ///     if env.ExceptionCheck() {
22364    ///         //ArrayIndexOutOfBoundsException
22365    ///         env.ExceptionClear();
22366    ///         return false;
22367    ///     }
22368    ///     true
22369    /// }
22370    /// ```
22371    ///
22372    pub unsafe fn GetIntArrayRegion_into_slice(&self, array: jshortArray, start: jsize, buf: &mut [jint]) {
22373        unsafe {
22374            self.GetIntArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_mut_ptr());
22375        }
22376    }
22377
22378    ///
22379    /// Copies data from the slice `buf` into the jintArray `array` starting at the given `start` index.
22380    ///
22381    /// # Arguments
22382    /// * `array` - handle to a Java jintArray.
22383    /// * `start` - the index where the first element should be coped into in the Java jintArray
22384    /// * `buf` - the slice where data is copied from
22385    ///
22386    /// # Throws Java Exception:
22387    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
22388    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
22389    ///
22390    /// It is JVM implementation specific what is stored inside `array` if this function throws an exception.
22391    /// * Data partially written
22392    /// * No data written
22393    ///
22394    /// # Panics
22395    /// if asserts feature is enabled and UB was detected
22396    ///
22397    /// # Safety
22398    /// Current thread must not be detached from JNI.
22399    ///
22400    /// Current thread must not be currently throwing an exception.
22401    ///
22402    /// Current thread does not hold a critical reference.
22403    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22404    ///
22405    /// `array` must be a valid non-null reference to a jintArray.
22406    ///
22407    /// # Example
22408    /// ```rust
22409    /// use jni_simple::{*};
22410    ///
22411    /// unsafe fn copy_chunk_from_rust_to_java(env: JNIEnv,
22412    ///         array: jintArray, chunk_buffer: &[jint], chunk_offset: usize) -> bool {
22413    ///     if array.is_null() {
22414    ///         panic!("Java Array is null")
22415    ///     }
22416    ///
22417    ///     env.SetIntArrayRegion_from_slice(array, chunk_offset as jsize, chunk_buffer);
22418    ///     if env.ExceptionCheck() {
22419    ///         //ArrayIndexOutOfBoundsException
22420    ///         env.ExceptionClear();
22421    ///         return false;
22422    ///     }
22423    ///     true
22424    /// }
22425    /// ```
22426    ///
22427    pub unsafe fn SetIntArrayRegion_from_slice(&self, array: jintArray, start: jsize, buf: &[jint]) {
22428        unsafe {
22429            self.SetIntArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_ptr());
22430        }
22431    }
22432
22433    ///
22434    /// Copies data from a Java jintArray `array` into a new `Vec<jint>`
22435    ///
22436    /// # Arguments
22437    /// * `array` - handle to a Java jintArray.
22438    /// * `start` - the index of the first element to copy in the Java jintArray
22439    /// * `len` - the amount of data that should be copied. If `None` then all remaining elements in the array are copied.
22440    ///
22441    /// # Returns:
22442    /// a new `Vec<jint>` that contains the copied data.
22443    ///
22444    /// # Returns empty Vec:
22445    /// * When the array in fact was empty or len was zero.
22446    /// * When this function throws a Java Exception.
22447    ///
22448    /// # Throws Java Exception:
22449    /// * `ArrayIndexOutOfBoundsException` - if `len` is negative.
22450    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the array.
22451    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative.
22452    /// * `ArrayIndexOutOfBoundsException` - if `start` is larget than `env.GetArrayLength(array)`.
22453    /// * `ArrayIndexOutOfBoundsException` - if `start` equals env.GetArrayLength(array) and `len` is larger than 0.
22454    ///
22455    /// # Panics
22456    /// if asserts feature is enabled and UB was detected
22457    ///
22458    /// # Safety
22459    /// Current thread must not be detached from JNI.
22460    ///
22461    /// Current thread must not be currently throwing an exception.
22462    ///
22463    /// Current thread does not hold a critical reference.
22464    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22465    ///
22466    /// `array` must be a valid non-null reference to a jintArray.
22467    ///
22468    /// # Example
22469    /// ```rust
22470    /// use jni_simple::{*};
22471    ///
22472    /// unsafe fn copy_entire_java_array_to_rust(env: JNIEnv, array: jintArray) -> Vec<jint> {
22473    ///     if array.is_null() {
22474    ///         panic!("Java Array is null")
22475    ///     }
22476    ///     env.GetIntArrayRegion_as_vec(array, 0, None)
22477    /// }
22478    /// ```
22479    ///
22480    pub unsafe fn GetIntArrayRegion_as_vec(&self, array: jintArray, start: jsize, len: Option<jsize>) -> Vec<jint> {
22481        unsafe {
22482            let len = len.unwrap_or_else(|| self.GetArrayLength(array).saturating_sub(start.max(0)).max(0));
22483            if let Ok(len) = usize::try_from(len) {
22484                let mut data = vec![0i32; len]; //We could un-init this, but better play it safe...
22485                self.GetIntArrayRegion_into_slice(array, start, data.as_mut_slice());
22486                if self.ExceptionCheck() {
22487                    return Vec::new();
22488                }
22489                return data;
22490            }
22491
22492            //Negative len
22493            let mut sentinel_buffer = [0];
22494            self.GetIntArrayRegion(array, start, len.min(-1), sentinel_buffer.as_mut_ptr());
22495            Vec::new()
22496        }
22497    }
22498
22499    ///
22500    /// Copies data from the jlongArray `array` starting from the given `start` index into the memory pointed to by `buf`.
22501    ///
22502    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_PrimitiveType_ArrayRegion_routines>
22503    ///
22504    /// # Arguments
22505    /// * `array` - handle to a Java jlongArray
22506    /// * `start` - the index of the first element to copy in the Java jlongArray
22507    /// * `len` - amount of data to be copied
22508    /// * `buf` - pointer to memory where the data should be copied to
22509    ///
22510    /// # Throws Java Exception:
22511    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the `array`.
22512    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
22513    ///
22514    /// It is JVM implementation specific what is written into `buf` if this function throws an exception.
22515    /// * Data partially written
22516    /// * No data written
22517    ///
22518    /// # Panics
22519    /// if asserts feature is enabled and UB was detected
22520    ///
22521    /// # Safety
22522    /// Current thread must not be detached from JNI.
22523    ///
22524    /// Current thread must not be currently throwing an exception.
22525    ///
22526    /// Current thread does not hold a critical reference.
22527    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22528    ///
22529    /// `array` must be a valid non-null reference to a jlongArray.
22530    /// `buf` must be valid non-null pointer to memory with enough capacity and proper alignment to store `len` jlong's.
22531    ///
22532    /// # Example
22533    /// ```rust
22534    /// use jni_simple::{*};
22535    ///
22536    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
22537    ///         array: jlongArray, chunk_buffer: &mut [jlong], chunk_offset: usize) -> bool {
22538    ///     if array.is_null() {
22539    ///         panic!("Java Array is null")
22540    ///     }
22541    ///
22542    ///     env.GetLongArrayRegion(array, chunk_offset as jsize, chunk_buffer.len() as jsize, chunk_buffer.as_mut_ptr());
22543    ///     if env.ExceptionCheck() {
22544    ///         //ArrayIndexOutOfBoundsException
22545    ///         env.ExceptionClear();
22546    ///         return false;
22547    ///     }
22548    ///     true
22549    /// }
22550    /// ```
22551    ///
22552    pub unsafe fn GetLongArrayRegion(&self, array: jlongArray, start: jsize, len: jsize, buf: *mut jlong) {
22553        unsafe {
22554            #[cfg(feature = "asserts")]
22555            {
22556                self.check_not_critical("GetLongArrayRegion");
22557                self.check_no_exception("GetLongArrayRegion");
22558                assert!(!array.is_null(), "GetLongArrayRegion jarray must not be null");
22559                assert!(!buf.is_null(), "GetLongArrayRegion buf must not be null");
22560                assert_eq!(0, buf.align_offset(align_of::<jlong>()), "GetLongArrayRegion buf pointer is not aligned");
22561            }
22562
22563            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, jsize, jsize, *mut jlong)>(204)(self.vtable, array, start, len, buf);
22564        }
22565    }
22566
22567    ///
22568    /// Copies data from the jlongArray `array` starting from the given `start` index into the slice `buf`.
22569    ///
22570    /// # Arguments
22571    /// * `array` - handle to a Java jlongArray.
22572    /// * `start` - the index of the first element to copy in the Java jlongArray
22573    /// * `buf` - the slice to copy data into
22574    ///
22575    /// # Throws Java Exception:
22576    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
22577    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
22578    ///
22579    /// It is JVM implementation specific what is stored inside buf if this function throws an exception.
22580    /// * Data partially written
22581    /// * No data written
22582    ///
22583    /// # Panics
22584    /// if asserts feature is enabled and UB was detected
22585    /// if the `buf.len()` is larger than `jsize::MAX`
22586    ///
22587    /// # Safety
22588    /// Current thread must not be detached from JNI.
22589    ///
22590    /// Current thread must not be currently throwing an exception.
22591    ///
22592    /// Current thread does not hold a critical reference.
22593    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22594    ///
22595    /// `array` must be a valid non-null reference to a jlongArray.
22596    ///
22597    /// # Example
22598    /// ```rust
22599    /// use jni_simple::{*};
22600    ///
22601    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
22602    ///         array: jlongArray, chunk_buffer: &mut [jlong], chunk_offset: usize) -> bool {
22603    ///     if array.is_null() {
22604    ///         panic!("Java Array is null")
22605    ///     }
22606    ///
22607    ///     env.GetLongArrayRegion_into_slice(array, chunk_offset as jsize, chunk_buffer);
22608    ///     if env.ExceptionCheck() {
22609    ///         //ArrayIndexOutOfBoundsException
22610    ///         env.ExceptionClear();
22611    ///         return false;
22612    ///     }
22613    ///     true
22614    /// }
22615    /// ```
22616    ///
22617    pub unsafe fn GetLongArrayRegion_into_slice(&self, array: jlongArray, start: jsize, buf: &mut [i64]) {
22618        unsafe {
22619            self.GetLongArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_mut_ptr());
22620        }
22621    }
22622
22623    ///
22624    /// Copies data from the slice `buf` into the jlongArray `array` starting at the given `start` index.
22625    ///
22626    /// # Arguments
22627    /// * `array` - handle to a Java jlongArray.
22628    /// * `start` - the index where the first element should be coped into in the Java jlongArray
22629    /// * `buf` - the slice where data is copied from
22630    ///
22631    /// # Throws Java Exception:
22632    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
22633    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
22634    ///
22635    /// It is JVM implementation specific what is stored inside `array` if this function throws an exception.
22636    /// * Data partially written
22637    /// * No data written
22638    ///
22639    /// # Panics
22640    /// if asserts feature is enabled and UB was detected
22641    ///
22642    /// # Safety
22643    /// Current thread must not be detached from JNI.
22644    ///
22645    /// Current thread must not be currently throwing an exception.
22646    ///
22647    /// Current thread does not hold a critical reference.
22648    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22649    ///
22650    /// `array` must be a valid non-null reference to a jlongArray.
22651    ///
22652    /// # Example
22653    /// ```rust
22654    /// use jni_simple::{*};
22655    ///
22656    /// unsafe fn copy_chunk_from_rust_to_java(env: JNIEnv,
22657    ///         array: jlongArray, chunk_buffer: &[jlong], chunk_offset: usize) -> bool {
22658    ///     if array.is_null() {
22659    ///         panic!("Java Array is null")
22660    ///     }
22661    ///
22662    ///     env.SetLongArrayRegion_from_slice(array, chunk_offset as jsize, chunk_buffer);
22663    ///     if env.ExceptionCheck() {
22664    ///         //ArrayIndexOutOfBoundsException
22665    ///         env.ExceptionClear();
22666    ///         return false;
22667    ///     }
22668    ///     true
22669    /// }
22670    /// ```
22671    ///
22672    pub unsafe fn SetLongArrayRegion_from_slice(&self, array: jlongArray, start: jsize, buf: &[jlong]) {
22673        unsafe {
22674            self.SetLongArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_ptr());
22675        }
22676    }
22677
22678    ///
22679    /// Copies data from a Java jlongArray `array` into a new `Vec<jlong>`
22680    ///
22681    /// # Arguments
22682    /// * `array` - handle to a Java jlongArray.
22683    /// * `start` - the index of the first element to copy in the Java jlongArray
22684    /// * `len` - the amount of data that should be copied. If `None` then all remaining elements in the array are copied.
22685    ///
22686    /// # Returns:
22687    /// a new `Vec<jlong>` that contains the copied data.
22688    ///
22689    /// # Returns empty Vec:
22690    /// * When the array in fact was empty or len was zero.
22691    /// * When this function throws a Java Exception.
22692    ///
22693    /// # Throws Java Exception:
22694    /// * `ArrayIndexOutOfBoundsException` - if `len` is negative.
22695    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the array.
22696    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative.
22697    /// * `ArrayIndexOutOfBoundsException` - if `start` is larget than `env.GetArrayLength(array)`.
22698    /// * `ArrayIndexOutOfBoundsException` - if `start` equals env.GetArrayLength(array) and `len` is larger than 0.
22699    ///
22700    /// # Panics
22701    /// if asserts feature is enabled and UB was detected
22702    ///
22703    /// # Safety
22704    /// Current thread must not be detached from JNI.
22705    ///
22706    /// Current thread must not be currently throwing an exception.
22707    ///
22708    /// Current thread does not hold a critical reference.
22709    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22710    ///
22711    /// `array` must be a valid non-null reference to a jlongArray.
22712    ///
22713    /// # Example
22714    /// ```rust
22715    /// use jni_simple::{*};
22716    ///
22717    /// unsafe fn copy_entire_java_array_to_rust(env: JNIEnv, array: jlongArray) -> Vec<jlong> {
22718    ///     if array.is_null() {
22719    ///         panic!("Java Array is null")
22720    ///     }
22721    ///     env.GetLongArrayRegion_as_vec(array, 0, None)
22722    /// }
22723    /// ```
22724    ///
22725    pub unsafe fn GetLongArrayRegion_as_vec(&self, array: jlongArray, start: jsize, len: Option<jsize>) -> Vec<jlong> {
22726        unsafe {
22727            let len = len.unwrap_or_else(|| self.GetArrayLength(array).saturating_sub(start.max(0)).max(0));
22728            if let Ok(len) = usize::try_from(len) {
22729                let mut data = vec![0i64; len]; //We could un-init this, but better play it safe...
22730                self.GetLongArrayRegion_into_slice(array, start, data.as_mut_slice());
22731                if self.ExceptionCheck() {
22732                    return Vec::new();
22733                }
22734                return data;
22735            }
22736
22737            //Negative len
22738            let mut sentinel_buffer = [0];
22739            self.GetLongArrayRegion(array, start, len.min(-1), sentinel_buffer.as_mut_ptr());
22740            Vec::new()
22741        }
22742    }
22743
22744    ///
22745    /// Copies data from the jfloatArray `array` starting from the given `start` index into the memory pointed to by `buf`.
22746    ///
22747    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_PrimitiveType_ArrayRegion_routines>
22748    ///
22749    /// # Arguments
22750    /// * `array` - handle to a Java jfloatArray
22751    /// * `start` - the index of the first element to copy in the Java jfloatArray
22752    /// * `len` - amount of data to be copied
22753    /// * `buf` - pointer to memory where the data should be copied to
22754    ///
22755    /// # Throws Java Exception:
22756    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the `array`.
22757    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
22758    ///
22759    /// It is JVM implementation specific what is written into `buf` if this function throws an exception.
22760    /// * Data partially written
22761    /// * No data written
22762    ///
22763    /// # Panics
22764    /// if asserts feature is enabled and UB was detected
22765    ///
22766    /// # Safety
22767    /// Current thread must not be detached from JNI.
22768    ///
22769    /// Current thread must not be currently throwing an exception.
22770    ///
22771    /// Current thread does not hold a critical reference.
22772    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22773    ///
22774    /// `array` must be a valid non-null reference to a jfloatArray.
22775    /// `buf` must be valid non-null pointer to memory with enough capacity and proper alignment to store `len` jfloat's.
22776    ///
22777    /// # Example
22778    /// ```rust
22779    /// use jni_simple::{*};
22780    ///
22781    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
22782    ///         array: jfloatArray, chunk_buffer: &mut [jfloat], chunk_offset: usize) -> bool {
22783    ///     if array.is_null() {
22784    ///         panic!("Java Array is null")
22785    ///     }
22786    ///
22787    ///     env.GetFloatArrayRegion(array, chunk_offset as jsize, chunk_buffer.len() as jsize, chunk_buffer.as_mut_ptr());
22788    ///     if env.ExceptionCheck() {
22789    ///         //ArrayIndexOutOfBoundsException
22790    ///         env.ExceptionClear();
22791    ///         return false;
22792    ///     }
22793    ///     true
22794    /// }
22795    /// ```
22796    ///
22797    pub unsafe fn GetFloatArrayRegion(&self, array: jfloatArray, start: jsize, len: jsize, buf: *mut jfloat) {
22798        unsafe {
22799            #[cfg(feature = "asserts")]
22800            {
22801                self.check_not_critical("GetFloatArrayRegion");
22802                self.check_no_exception("GetFloatArrayRegion");
22803                assert!(!array.is_null(), "GetFloatArrayRegion jarray must not be null");
22804                assert!(!buf.is_null(), "GetFloatArrayRegion buf must not be null");
22805                assert_eq!(0, buf.align_offset(align_of::<jfloat>()), "GetFloatArrayRegion buf pointer is not aligned");
22806            }
22807
22808            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, jsize, jsize, *mut jfloat)>(205)(self.vtable, array, start, len, buf);
22809        }
22810    }
22811
22812    ///
22813    /// Copies data from the jfloatArray `array` starting from the given `start` index into the slice `buf`.
22814    ///
22815    /// # Arguments
22816    /// * `array` - handle to a Java jfloatArray.
22817    /// * `start` - the index of the first element to copy in the Java jfloatArray
22818    /// * `buf` - the slice to copy data into
22819    ///
22820    /// # Throws Java Exception:
22821    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
22822    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
22823    ///
22824    /// It is JVM implementation specific what is stored inside buf if this function throws an exception.
22825    /// * Data partially written
22826    /// * No data written
22827    ///
22828    /// # Panics
22829    /// if asserts feature is enabled and UB was detected
22830    /// if the `buf.len()` is larger than `jsize::MAX`
22831    ///
22832    /// # Safety
22833    /// Current thread must not be detached from JNI.
22834    ///
22835    /// Current thread must not be currently throwing an exception.
22836    ///
22837    /// Current thread does not hold a critical reference.
22838    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22839    ///
22840    /// `array` must be a valid non-null reference to a jfloatArray.
22841    ///
22842    /// # Example
22843    /// ```rust
22844    /// use jni_simple::{*};
22845    ///
22846    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
22847    ///         array: jfloatArray, chunk_buffer: &mut [jfloat], chunk_offset: usize) -> bool {
22848    ///     if array.is_null() {
22849    ///         panic!("Java Array is null")
22850    ///     }
22851    ///
22852    ///     env.GetFloatArrayRegion_into_slice(array, chunk_offset as jsize, chunk_buffer);
22853    ///     if env.ExceptionCheck() {
22854    ///         //ArrayIndexOutOfBoundsException
22855    ///         env.ExceptionClear();
22856    ///         return false;
22857    ///     }
22858    ///     true
22859    /// }
22860    /// ```
22861    ///
22862    pub unsafe fn GetFloatArrayRegion_into_slice(&self, array: jfloatArray, start: jsize, buf: &mut [jfloat]) {
22863        unsafe {
22864            self.GetFloatArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_mut_ptr());
22865        }
22866    }
22867
22868    ///
22869    /// Copies data from the slice `buf` into the jfloatArray `array` starting at the given `start` index.
22870    ///
22871    /// # Arguments
22872    /// * `array` - handle to a Java jfloatArray.
22873    /// * `start` - the index where the first element should be coped into in the Java jfloatArray
22874    /// * `buf` - the slice where data is copied from
22875    ///
22876    /// # Throws Java Exception:
22877    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
22878    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
22879    ///
22880    /// It is JVM implementation specific what is stored inside `array` if this function throws an exception.
22881    /// * Data partially written
22882    /// * No data written
22883    ///
22884    /// # Panics
22885    /// if asserts feature is enabled and UB was detected
22886    ///
22887    /// # Safety
22888    /// Current thread must not be detached from JNI.
22889    ///
22890    /// Current thread must not be currently throwing an exception.
22891    ///
22892    /// Current thread does not hold a critical reference.
22893    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22894    ///
22895    /// `array` must be a valid non-null reference to a jfloatArray.
22896    ///
22897    /// # Example
22898    /// ```rust
22899    /// use jni_simple::{*};
22900    ///
22901    /// unsafe fn copy_chunk_from_rust_to_java(env: JNIEnv,
22902    ///         array: jfloatArray, chunk_buffer: &[jfloat], chunk_offset: usize) -> bool {
22903    ///     if array.is_null() {
22904    ///         panic!("Java Array is null")
22905    ///     }
22906    ///
22907    ///     env.SetFloatArrayRegion_from_slice(array, chunk_offset as jsize, chunk_buffer);
22908    ///     if env.ExceptionCheck() {
22909    ///         //ArrayIndexOutOfBoundsException
22910    ///         env.ExceptionClear();
22911    ///         return false;
22912    ///     }
22913    ///     true
22914    /// }
22915    /// ```
22916    ///
22917    pub unsafe fn SetFloatArrayRegion_from_slice(&self, array: jfloatArray, start: jsize, buf: &[jfloat]) {
22918        unsafe {
22919            self.SetFloatArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_ptr());
22920        }
22921    }
22922
22923    ///
22924    /// Copies data from a Java jfloatArray `array` into a new `Vec<jfloat>`
22925    ///
22926    /// # Arguments
22927    /// * `array` - handle to a Java jfloatArray.
22928    /// * `start` - the index of the first element to copy in the Java jfloatArray
22929    /// * `len` - the amount of data that should be copied. If `None` then all remaining elements in the array are copied.
22930    ///
22931    /// # Returns:
22932    /// a new `Vec<jfloat>` that contains the copied data.
22933    ///
22934    /// # Returns empty Vec:
22935    /// * When the array in fact was empty or len was zero.
22936    /// * When this function throws a Java Exception.
22937    ///
22938    /// # Throws Java Exception:
22939    /// * `ArrayIndexOutOfBoundsException` - if `len` is negative.
22940    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the array.
22941    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative.
22942    /// * `ArrayIndexOutOfBoundsException` - if `start` is larget than `env.GetArrayLength(array)`.
22943    /// * `ArrayIndexOutOfBoundsException` - if `start` equals env.GetArrayLength(array) and `len` is larger than 0.
22944    ///
22945    /// # Panics
22946    /// if asserts feature is enabled and UB was detected
22947    ///
22948    /// # Safety
22949    /// Current thread must not be detached from JNI.
22950    ///
22951    /// Current thread must not be currently throwing an exception.
22952    ///
22953    /// Current thread does not hold a critical reference.
22954    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22955    ///
22956    /// `array` must be a valid non-null reference to a jfloatArray.
22957    ///
22958    /// # Example
22959    /// ```rust
22960    /// use jni_simple::{*};
22961    ///
22962    /// unsafe fn copy_entire_java_array_to_rust(env: JNIEnv, array: jfloatArray) -> Vec<jfloat> {
22963    ///     if array.is_null() {
22964    ///         panic!("Java Array is null")
22965    ///     }
22966    ///     env.GetFloatArrayRegion_as_vec(array, 0, None)
22967    /// }
22968    /// ```
22969    ///
22970    pub unsafe fn GetFloatArrayRegion_as_vec(&self, array: jfloatArray, start: jsize, len: Option<jsize>) -> Vec<jfloat> {
22971        unsafe {
22972            let len = len.unwrap_or_else(|| self.GetArrayLength(array).saturating_sub(start.max(0)).max(0));
22973            if let Ok(len) = usize::try_from(len) {
22974                let mut data = vec![jfloat::default(); len]; //We could un-init this, but better play it safe...
22975                self.GetFloatArrayRegion_into_slice(array, start, data.as_mut_slice());
22976                if self.ExceptionCheck() {
22977                    return Vec::new();
22978                }
22979                return data;
22980            }
22981
22982            //Negative len
22983            let mut sentinel_buffer = [jfloat::default()];
22984            self.GetFloatArrayRegion(array, start, len.min(-1), sentinel_buffer.as_mut_ptr());
22985            Vec::new()
22986        }
22987    }
22988
22989    ///
22990    /// Copies data from the jdoubleArray `array` starting from the given `start` index into the memory pointed to by `buf`.
22991    ///
22992    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_PrimitiveType_ArrayRegion_routines>
22993    ///
22994    /// # Arguments
22995    /// * `array` - handle to a Java jdoubleArray
22996    /// * `start` - the index of the first element to copy in the Java jdoubleArray
22997    /// * `len` - amount of data to be copied
22998    /// * `buf` - pointer to memory where the data should be copied to
22999    ///
23000    /// # Throws Java Exception:
23001    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the `array`.
23002    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
23003    ///
23004    /// It is JVM implementation specific what is written into `buf` if this function throws an exception.
23005    /// * Data partially written
23006    /// * No data written
23007    ///
23008    /// # Panics
23009    /// if asserts feature is enabled and UB was detected
23010    ///
23011    /// # Safety
23012    /// Current thread must not be detached from JNI.
23013    ///
23014    /// Current thread must not be currently throwing an exception.
23015    ///
23016    /// Current thread does not hold a critical reference.
23017    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23018    ///
23019    /// `array` must be a valid non-null reference to a jdoubleArray.
23020    /// `buf` must be valid non-null pointer to memory with enough capacity and proper alignment to store `len` jdouble's.
23021    ///
23022    /// # Example
23023    /// ```rust
23024    /// use jni_simple::{*};
23025    ///
23026    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
23027    ///         array: jdoubleArray, chunk_buffer: &mut [jdouble], chunk_offset: usize) -> bool {
23028    ///     if array.is_null() {
23029    ///         panic!("Java Array is null")
23030    ///     }
23031    ///
23032    ///     env.GetDoubleArrayRegion(array, chunk_offset as jsize, chunk_buffer.len() as jsize, chunk_buffer.as_mut_ptr());
23033    ///     if env.ExceptionCheck() {
23034    ///         //ArrayIndexOutOfBoundsException
23035    ///         env.ExceptionClear();
23036    ///         return false;
23037    ///     }
23038    ///     true
23039    /// }
23040    /// ```
23041    ///
23042    pub unsafe fn GetDoubleArrayRegion(&self, array: jdoubleArray, start: jsize, len: jsize, buf: *mut jdouble) {
23043        unsafe {
23044            #[cfg(feature = "asserts")]
23045            {
23046                self.check_not_critical("GetDoubleArrayRegion");
23047                self.check_no_exception("GetDoubleArrayRegion");
23048                assert!(!array.is_null(), "GetDoubleArrayRegion jarray must not be null");
23049                assert!(!buf.is_null(), "GetDoubleArrayRegion buf must not be null");
23050                assert_eq!(0, buf.align_offset(align_of::<jdouble>()), "GetDoubleArrayRegion buf pointer is not aligned");
23051            }
23052
23053            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, jsize, jsize, *mut jdouble)>(206)(self.vtable, array, start, len, buf);
23054        }
23055    }
23056
23057    ///
23058    /// Copies data from the jdoubleArray `array` starting from the given `start` index into the slice `buf`.
23059    ///
23060    /// # Arguments
23061    /// * `array` - handle to a Java jdoubleArray.
23062    /// * `start` - the index of the first element to copy in the Java jdoubleArray
23063    /// * `buf` - the slice to copy data into
23064    ///
23065    /// # Throws Java Exception:
23066    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
23067    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
23068    ///
23069    /// It is JVM implementation specific what is stored inside buf if this function throws an exception.
23070    /// * Data partially written
23071    /// * No data written
23072    ///
23073    /// # Panics
23074    /// if asserts feature is enabled and UB was detected
23075    /// if the `buf.len()` is larger than `jsize::MAX`
23076    ///
23077    /// # Safety
23078    /// Current thread must not be detached from JNI.
23079    ///
23080    /// Current thread must not be currently throwing an exception.
23081    ///
23082    /// Current thread does not hold a critical reference.
23083    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23084    ///
23085    /// `array` must be a valid non-null reference to a jdoubleArray.
23086    ///
23087    /// # Example
23088    /// ```rust
23089    /// use jni_simple::{*};
23090    ///
23091    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
23092    ///         array: jdoubleArray, chunk_buffer: &mut [jdouble], chunk_offset: usize) -> bool {
23093    ///     if array.is_null() {
23094    ///         panic!("Java Array is null")
23095    ///     }
23096    ///
23097    ///     env.GetDoubleArrayRegion_into_slice(array, chunk_offset as jsize, chunk_buffer);
23098    ///     if env.ExceptionCheck() {
23099    ///         //ArrayIndexOutOfBoundsException
23100    ///         env.ExceptionClear();
23101    ///         return false;
23102    ///     }
23103    ///     true
23104    /// }
23105    /// ```
23106    ///
23107    pub unsafe fn GetDoubleArrayRegion_into_slice(&self, array: jdoubleArray, start: jsize, buf: &mut [jdouble]) {
23108        unsafe {
23109            self.GetDoubleArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_mut_ptr());
23110        }
23111    }
23112
23113    ///
23114    /// Copies data from the slice `buf` into the jfloatArray `array` starting at the given `start` index.
23115    ///
23116    /// # Arguments
23117    /// * `array` - handle to a Java jfloatArray.
23118    /// * `start` - the index where the first element should be coped into in the Java jfloatArray
23119    /// * `buf` - the slice where data is copied from
23120    ///
23121    /// # Throws Java Exception:
23122    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
23123    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
23124    ///
23125    /// It is JVM implementation specific what is stored inside `array` if this function throws an exception.
23126    /// * Data partially written
23127    /// * No data written
23128    ///
23129    /// # Panics
23130    /// if asserts feature is enabled and UB was detected
23131    ///
23132    /// # Safety
23133    /// Current thread must not be detached from JNI.
23134    ///
23135    /// Current thread must not be currently throwing an exception.
23136    ///
23137    /// Current thread does not hold a critical reference.
23138    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23139    ///
23140    /// `array` must be a valid non-null reference to a jfloatArray.
23141    ///
23142    /// # Example
23143    /// ```rust
23144    /// use jni_simple::{*};
23145    ///
23146    /// unsafe fn copy_chunk_from_rust_to_java(env: JNIEnv,
23147    ///         array: jfloatArray, chunk_buffer: &[jdouble], chunk_offset: usize) -> bool {
23148    ///     if array.is_null() {
23149    ///         panic!("Java Array is null")
23150    ///     }
23151    ///
23152    ///     env.SetDoubleArrayRegion_from_slice(array, chunk_offset as jsize, chunk_buffer);
23153    ///     if env.ExceptionCheck() {
23154    ///         //ArrayIndexOutOfBoundsException
23155    ///         env.ExceptionClear();
23156    ///         return false;
23157    ///     }
23158    ///     true
23159    /// }
23160    /// ```
23161    ///
23162    pub unsafe fn SetDoubleArrayRegion_from_slice(&self, array: jdoubleArray, start: jsize, buf: &[jdouble]) {
23163        unsafe {
23164            self.SetDoubleArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_ptr());
23165        }
23166    }
23167
23168    ///
23169    /// Copies data from a Java jdoubleArray `array` into a new `Vec<jdouble>`
23170    ///
23171    /// # Arguments
23172    /// * `array` - handle to a Java jdoubleArray.
23173    /// * `start` - the index of the first element to copy in the Java jdoubleArray
23174    /// * `len` - the amount of data that should be copied. If `None` then all remaining elements in the array are copied.
23175    ///
23176    /// # Returns:
23177    /// a new `Vec<jdouble>` that contains the copied data.
23178    ///
23179    /// # Returns empty Vec:
23180    /// * When the array in fact was empty or len was zero.
23181    /// * When this function throws a Java Exception.
23182    ///
23183    /// # Throws Java Exception:
23184    /// * `ArrayIndexOutOfBoundsException` - if `len` is negative.
23185    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the array.
23186    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative.
23187    /// * `ArrayIndexOutOfBoundsException` - if `start` is larget than `env.GetArrayLength(array)`.
23188    /// * `ArrayIndexOutOfBoundsException` - if `start` equals env.GetArrayLength(array) and `len` is larger than 0.
23189    ///
23190    /// # Panics
23191    /// if asserts feature is enabled and UB was detected
23192    ///
23193    /// # Safety
23194    /// Current thread must not be detached from JNI.
23195    ///
23196    /// Current thread must not be currently throwing an exception.
23197    ///
23198    /// Current thread does not hold a critical reference.
23199    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23200    ///
23201    /// `array` must be a valid non-null reference to a jdoubleArray.
23202    ///
23203    /// # Example
23204    /// ```rust
23205    /// use jni_simple::{*};
23206    ///
23207    /// unsafe fn copy_entire_java_array_to_rust(env: JNIEnv, array: jdoubleArray) -> Vec<jdouble> {
23208    ///     if array.is_null() {
23209    ///         panic!("Java Array is null")
23210    ///     }
23211    ///     env.GetDoubleArrayRegion_as_vec(array, 0, None)
23212    /// }
23213    /// ```
23214    ///
23215    pub unsafe fn GetDoubleArrayRegion_as_vec(&self, array: jdoubleArray, start: jsize, len: Option<jsize>) -> Vec<jdouble> {
23216        unsafe {
23217            let len = len.unwrap_or_else(|| self.GetArrayLength(array).saturating_sub(start.max(0)).max(0));
23218            if let Ok(len) = usize::try_from(len) {
23219                let mut data = vec![jdouble::default(); len]; //We could un-init this, but better play it safe...
23220                self.GetDoubleArrayRegion_into_slice(array, start, data.as_mut_slice());
23221                if self.ExceptionCheck() {
23222                    return Vec::new();
23223                }
23224                return data;
23225            }
23226
23227            //Negative len
23228            let mut sentinel_buffer = [jdouble::default()];
23229            self.GetDoubleArrayRegion(array, start, len.min(-1), sentinel_buffer.as_mut_ptr());
23230            Vec::new()
23231        }
23232    }
23233
23234    ///
23235    /// Sets a boolean array region from a buffer
23236    ///
23237    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_PrimitiveType_ArrayRegion_routines>
23238    ///
23239    /// # Arguments
23240    /// * `array` - handle to a Java array.
23241    ///     * must not be null
23242    /// * `start` - index in the `array` where the fist element should be copied to
23243    /// * `len` - amount of elements to copy
23244    /// * `buf` - buffer where the elements are copied from.
23245    ///     * must not be null
23246    ///
23247    /// # Throws Java Exception:
23248    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
23249    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
23250    ///
23251    /// The state of the array is implementation specific if the fn throws an exception.
23252    /// It may have partially copied some data or copied no data.
23253    ///
23254    /// # Panics
23255    /// if asserts feature is enabled and UB was detected
23256    ///
23257    /// # Safety
23258    /// Current thread must not be detached from JNI.
23259    ///
23260    /// Current thread must not be currently throwing an exception.
23261    ///
23262    /// Current thread does not hold a critical reference.
23263    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23264    ///
23265    /// `array` must be a valid non-null reference to a jbooleanArray.
23266    /// `buf` must be at least `len` elements in size
23267    ///
23268    pub unsafe fn SetBooleanArrayRegion(&self, array: jbooleanArray, start: jsize, len: jsize, buf: *const impl JBooleanInputLayout) {
23269        let ptr: *const jboolean = buf.cast();
23270        unsafe {
23271            #[cfg(feature = "asserts")]
23272            {
23273                self.check_not_critical("SetBooleanArrayRegion");
23274                self.check_no_exception("SetBooleanArrayRegion");
23275                assert!(!array.is_null(), "SetBooleanArrayRegion jarray must not be null");
23276                assert!(!buf.is_null(), "SetBooleanArrayRegion buf must not be null");
23277                Self::check_bool_array_is_narrow("SetBooleanArrayRegion", ptr, len);
23278            }
23279            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, jsize, jsize, *const jboolean)>(207)(self.vtable, array, start, len, ptr);
23280        }
23281    }
23282
23283    ///
23284    /// Sets a byte array region from a buffer
23285    ///
23286    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_PrimitiveType_ArrayRegion_routines>
23287    ///
23288    /// # Arguments
23289    /// * `array` - handle to a Java array.
23290    ///     * must not be null
23291    /// * `start` - index in the `array` where the fist element should be copied to
23292    /// * `len` - amount of elements to copy
23293    /// * `buf` - buffer where the elements are copied from.
23294    ///     * must not be null
23295    ///
23296    /// # Throws Java Exception:
23297    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
23298    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
23299    ///
23300    /// The state of the array is implementation specific if the fn throws an exception.
23301    /// It may have partially copied some data or copied no data.
23302    ///
23303    /// # Panics
23304    /// if asserts feature is enabled and UB was detected
23305    ///
23306    /// # Safety
23307    /// Current thread must not be detached from JNI.
23308    ///
23309    /// Current thread must not be currently throwing an exception.
23310    ///
23311    /// Current thread does not hold a critical reference.
23312    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23313    ///
23314    /// `array` must be a valid non-null reference to a jbyteArray.
23315    /// `buf` must be at least `len` elements in size
23316    ///
23317    pub unsafe fn SetByteArrayRegion(&self, array: jbyteArray, start: jsize, len: jsize, buf: *const jbyte) {
23318        unsafe {
23319            #[cfg(feature = "asserts")]
23320            {
23321                self.check_not_critical("SetByteArrayRegion");
23322                self.check_no_exception("SetByteArrayRegion");
23323                assert!(!array.is_null(), "SetByteArrayRegion jarray must not be null");
23324                assert!(!buf.is_null(), "SetByteArrayRegion buf must not be null");
23325            }
23326
23327            self.jni::<extern "system" fn(JNIEnvVTable, jbyteArray, jsize, jsize, *const jbyte)>(208)(self.vtable, array, start, len, buf);
23328        }
23329    }
23330
23331    ///
23332    /// Sets a char array region from a buffer
23333    ///
23334    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_PrimitiveType_ArrayRegion_routines>
23335    ///
23336    /// # Arguments
23337    /// * `array` - handle to a Java array.
23338    ///     * must not be null
23339    /// * `start` - index in the `array` where the fist element should be copied to
23340    /// * `len` - amount of elements to copy
23341    /// * `buf` - buffer where the elements are copied from.
23342    ///     * must not be null
23343    ///
23344    /// # Throws Java Exception:
23345    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
23346    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
23347    ///
23348    /// The state of the array is implementation specific if the fn throws an exception.
23349    /// It may have partially copied some data or copied no data.
23350    ///
23351    /// # Panics
23352    /// if asserts feature is enabled and UB was detected
23353    ///
23354    /// # Safety
23355    /// Current thread must not be detached from JNI.
23356    ///
23357    /// Current thread must not be currently throwing an exception.
23358    ///
23359    /// Current thread does not hold a critical reference.
23360    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23361    ///
23362    /// `array` must be a valid non-null reference to a jcharArray.
23363    /// `buf` must be at least `len` elements in size
23364    ///
23365    pub unsafe fn SetCharArrayRegion(&self, array: jcharArray, start: jsize, len: jsize, buf: *const jchar) {
23366        unsafe {
23367            #[cfg(feature = "asserts")]
23368            {
23369                self.check_not_critical("SetCharArrayRegion");
23370                self.check_no_exception("SetCharArrayRegion");
23371                assert!(!array.is_null(), "SetCharArrayRegion jarray must not be null");
23372                assert!(!buf.is_null(), "SetCharArrayRegion buf must not be null");
23373                assert_eq!(0, buf.align_offset(align_of::<jchar>()), "SetCharArrayRegion buf pointer is not aligned");
23374            }
23375
23376            self.jni::<extern "system" fn(JNIEnvVTable, jcharArray, jsize, jsize, *const jchar)>(209)(self.vtable, array, start, len, buf);
23377        }
23378    }
23379
23380    ///
23381    /// Sets a short array region from a buffer
23382    ///
23383    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_PrimitiveType_ArrayRegion_routines>
23384    ///
23385    /// # Arguments
23386    /// * `array` - handle to a Java array.
23387    ///     * must not be null
23388    /// * `start` - index in the `array` where the fist element should be copied to
23389    /// * `len` - amount of elements to copy
23390    /// * `buf` - buffer where the elements are copied from.
23391    ///     * must not be null
23392    ///
23393    /// # Throws Java Exception:
23394    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
23395    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
23396    ///
23397    /// The state of the array is implementation specific if the fn throws an exception.
23398    /// It may have partially copied some data or copied no data.
23399    ///
23400    /// # Panics
23401    /// if asserts feature is enabled and UB was detected
23402    ///
23403    /// # Safety
23404    /// Current thread must not be detached from JNI.
23405    ///
23406    /// Current thread must not be currently throwing an exception.
23407    ///
23408    /// Current thread does not hold a critical reference.
23409    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23410    ///
23411    /// `array` must be a valid non-null reference to a jshortArray.
23412    /// `buf` must be at least `len` elements in size
23413    ///
23414    pub unsafe fn SetShortArrayRegion(&self, array: jshortArray, start: jsize, len: jsize, buf: *const jshort) {
23415        unsafe {
23416            #[cfg(feature = "asserts")]
23417            {
23418                self.check_not_critical("SetShortArrayRegion");
23419                self.check_no_exception("SetShortArrayRegion");
23420                assert!(!array.is_null(), "SetShortArrayRegion jarray must not be null");
23421                assert!(!buf.is_null(), "SetShortArrayRegion buf must not be null");
23422                assert_eq!(0, buf.align_offset(align_of::<jshort>()), "SetShortArrayRegion buf pointer is not aligned");
23423            }
23424
23425            self.jni::<extern "system" fn(JNIEnvVTable, jshortArray, jsize, jsize, *const jshort)>(210)(self.vtable, array, start, len, buf);
23426        }
23427    }
23428
23429    ///
23430    /// Sets a int array region from a buffer
23431    ///
23432    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_PrimitiveType_ArrayRegion_routines>
23433    ///
23434    /// # Arguments
23435    /// * `array` - handle to a Java array.
23436    ///     * must not be null
23437    /// * `start` - index in the `array` where the fist element should be copied to
23438    /// * `len` - amount of elements to copy
23439    /// * `buf` - buffer where the elements are copied from.
23440    ///     * must not be null
23441    ///
23442    /// # Throws Java Exception:
23443    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
23444    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
23445    ///
23446    /// The state of the array is implementation specific if the fn throws an exception.
23447    /// It may have partially copied some data or copied no data.
23448    ///
23449    /// # Panics
23450    /// if asserts feature is enabled and UB was detected
23451    ///
23452    /// # Safety
23453    /// Current thread must not be detached from JNI.
23454    ///
23455    /// Current thread must not be currently throwing an exception.
23456    ///
23457    /// Current thread does not hold a critical reference.
23458    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23459    ///
23460    /// `array` must be a valid non-null reference to a jintArray.
23461    /// `buf` must be at least `len` elements in size
23462    ///
23463    pub unsafe fn SetIntArrayRegion(&self, array: jintArray, start: jsize, len: jsize, buf: *const jint) {
23464        unsafe {
23465            #[cfg(feature = "asserts")]
23466            {
23467                self.check_not_critical("SetIntArrayRegion");
23468                self.check_no_exception("SetIntArrayRegion");
23469                assert!(!array.is_null(), "SetIntArrayRegion jarray must not be null");
23470                assert!(!buf.is_null(), "SetIntArrayRegion buf must not be null");
23471                assert_eq!(0, buf.align_offset(align_of::<jint>()), "SetIntArrayRegion buf pointer is not aligned");
23472            }
23473
23474            self.jni::<extern "system" fn(JNIEnvVTable, jintArray, jsize, jsize, *const jint)>(211)(self.vtable, array, start, len, buf);
23475        }
23476    }
23477
23478    ///
23479    /// Sets a long array region from a buffer
23480    ///
23481    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_PrimitiveType_ArrayRegion_routines>
23482    ///
23483    /// # Arguments
23484    /// * `array` - handle to a Java array.
23485    ///     * must not be null
23486    /// * `start` - index in the `array` where the fist element should be copied to
23487    /// * `len` - amount of elements to copy
23488    /// * `buf` - buffer where the elements are copied from.
23489    ///     * must not be null
23490    ///
23491    /// # Throws Java Exception:
23492    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
23493    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
23494    ///
23495    /// The state of the array is implementation specific if the fn throws an exception.
23496    /// It may have partially copied some data or copied no data.
23497    ///
23498    /// # Panics
23499    /// if asserts feature is enabled and UB was detected
23500    ///
23501    /// # Safety
23502    /// Current thread must not be detached from JNI.
23503    ///
23504    /// Current thread must not be currently throwing an exception.
23505    ///
23506    /// Current thread does not hold a critical reference.
23507    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23508    ///
23509    /// `array` must be a valid non-null reference to a jlongArray.
23510    /// `buf` must be at least `len` elements in size
23511    ///
23512    pub unsafe fn SetLongArrayRegion(&self, array: jlongArray, start: jsize, len: jsize, buf: *const jlong) {
23513        unsafe {
23514            #[cfg(feature = "asserts")]
23515            {
23516                self.check_not_critical("SetLongArrayRegion");
23517                self.check_no_exception("SetLongArrayRegion");
23518                assert!(!array.is_null(), "SetLongArrayRegion jarray must not be null");
23519                assert!(!buf.is_null(), "SetLongArrayRegion buf must not be null");
23520                assert_eq!(0, buf.align_offset(align_of::<jlong>()), "SetLongArrayRegion buf pointer is not aligned");
23521            }
23522
23523            self.jni::<extern "system" fn(JNIEnvVTable, jlongArray, jsize, jsize, *const jlong)>(212)(self.vtable, array, start, len, buf);
23524        }
23525    }
23526
23527    ///
23528    /// Sets a float array region from a buffer
23529    ///
23530    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_PrimitiveType_ArrayRegion_routines>
23531    ///
23532    /// # Arguments
23533    /// * `array` - handle to a Java array.
23534    ///     * must not be null
23535    /// * `start` - index in the `array` where the fist element should be copied to
23536    /// * `len` - amount of elements to copy
23537    /// * `buf` - buffer where the elements are copied from.
23538    ///     * must not be null
23539    ///
23540    /// # Throws Java Exception:
23541    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
23542    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
23543    ///
23544    /// The state of the array is implementation specific if the fn throws an exception.
23545    /// It may have partially copied some data or copied no data.
23546    ///
23547    /// # Panics
23548    /// if asserts feature is enabled and UB was detected
23549    ///
23550    /// # Safety
23551    /// Current thread must not be detached from JNI.
23552    ///
23553    /// Current thread must not be currently throwing an exception.
23554    ///
23555    /// Current thread does not hold a critical reference.
23556    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23557    ///
23558    /// `array` must be a valid non-null reference to a jfloatArray.
23559    /// `buf` must be at least `len` elements in size
23560    ///
23561    pub unsafe fn SetFloatArrayRegion(&self, array: jfloatArray, start: jsize, len: jsize, buf: *const jfloat) {
23562        unsafe {
23563            #[cfg(feature = "asserts")]
23564            {
23565                self.check_not_critical("SetFloatArrayRegion");
23566                self.check_no_exception("SetFloatArrayRegion");
23567                assert!(!array.is_null(), "SetFloatArrayRegion jarray must not be null");
23568                assert!(!buf.is_null(), "SetFloatArrayRegion buf must not be null");
23569                assert_eq!(0, buf.align_offset(align_of::<jfloat>()), "SetFloatArrayRegion buf pointer is not aligned");
23570            }
23571
23572            self.jni::<extern "system" fn(JNIEnvVTable, jfloatArray, jsize, jsize, *const jfloat)>(213)(self.vtable, array, start, len, buf);
23573        }
23574    }
23575
23576    ///
23577    /// Sets a double array region from a buffer
23578    ///
23579    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_PrimitiveType_ArrayRegion_routines>
23580    ///
23581    /// # Arguments
23582    /// * `array` - handle to a Java array.
23583    ///     * must not be null
23584    /// * `start` - index in the `array` where the fist element should be copied to
23585    /// * `len` - amount of elements to copy
23586    /// * `buf` - buffer where the elements are copied from.
23587    ///     * must not be null
23588    ///
23589    /// # Throws Java Exception:
23590    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
23591    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
23592    ///
23593    /// The state of the array is implementation specific if the fn throws an exception.
23594    /// It may have partially copied some data or copied no data.
23595    ///
23596    /// # Panics
23597    /// if asserts feature is enabled and UB was detected
23598    ///
23599    /// # Safety
23600    /// Current thread must not be detached from JNI.
23601    ///
23602    /// Current thread must not be currently throwing an exception.
23603    ///
23604    /// Current thread does not hold a critical reference.
23605    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23606    ///
23607    /// `array` must be a valid non-null reference to a jdoubleArray.
23608    /// `buf` must be at least `len` elements in size
23609    ///
23610    pub unsafe fn SetDoubleArrayRegion(&self, array: jdoubleArray, start: jsize, len: jsize, buf: *const jdouble) {
23611        unsafe {
23612            #[cfg(feature = "asserts")]
23613            {
23614                self.check_not_critical("SetDoubleArrayRegion");
23615                self.check_no_exception("SetDoubleArrayRegion");
23616                assert!(!array.is_null(), "SetDoubleArrayRegion jarray must not be null");
23617                assert!(!buf.is_null(), "SetDoubleArrayRegion buf must not be null");
23618                assert_eq!(0, buf.align_offset(align_of::<jdouble>()), "SetDoubleArrayRegion buf pointer is not aligned");
23619            }
23620
23621            self.jni::<extern "system" fn(JNIEnvVTable, jdoubleArray, jsize, jsize, *const jdouble)>(214)(self.vtable, array, start, len, buf);
23622        }
23623    }
23624
23625    #[cfg(all(feature = "asserts", feature = "std"))]
23626    std::thread_local! {
23627        //The "Critical Section" created by GetPrimitiveArrayCritical has a lot of restrictions placed upon it.
23628        //This attempts to track "some" of them on a best effort basis.
23629        static CRITICAL_POINTERS: std::cell::RefCell<std::collections::HashMap<*mut c_void, usize>> = std::cell::RefCell::new(std::collections::HashMap::new());
23630    }
23631
23632    ///
23633    /// Obtains a critical pointer into a primitive java array.
23634    /// This pointer must be released by calling `ReleasePrimitiveArrayCritical`.
23635    /// No other JNI functions can be called in the current thread.
23636    /// The only exception being multiple consecutive calls to `GetPrimitiveArrayCritical` & `GetStringCritical` to obtain multiple critical
23637    /// pointers at the same time.
23638    ///
23639    /// This method will return NULL to indicate error.
23640    /// The JVM will most likely throw an Exception, probably an `OOMError`.
23641    /// If you obtain multiple critical pointers, you MUST release all successfully obtained critical pointers
23642    /// before being able to check for the exception.
23643    ///
23644    /// Special care must be taken to avoid blocking the current thread with a dependency on another JVM thread.
23645    /// I.e. Do not read from a pipe that is filled by another JVM thread for example.
23646    ///
23647    /// It is also ill-advised to hold onto critical pointers for long periods of time even if no dependency on another JVM Thread is made.
23648    /// The JVM may decide among other things to suspend garbage collection while a critical pointer is held.
23649    /// So reading from a Socket with a long timeout while holding a critical pointer is unlikely to be a good idea.
23650    /// As it may cause unintended side effects in the rest of the JVM (like running out of memory because the GC doesn't run)
23651    ///
23652    /// Failure to release critical pointers before returning execution back to Java Code should be treated as UB
23653    /// even tho the JVM spec fails to mention this detail.
23654    ///
23655    /// Releasing critical pointers in another thread other than the thread that created it should be treated as UB
23656    /// even tho the JVM spec only mentions this detail indirectly.
23657    ///
23658    /// I recommend against using this method for almost every use case as using either Set/Get array region or direct NIO buffers
23659    /// is a better choice. One use case I can think of where this method is a valid choice
23660    /// is performing pixel manipulations on the int[]/byte[] inside a large existing `BufferedImage`.
23661    ///
23662    /// # Returns
23663    /// returns null on error otherwise returns a pointer into the data and begins a critical section.
23664    ///
23665    /// # Panics
23666    /// if asserts feature is enabled and UB was detected
23667    ///
23668    /// # Safety
23669    /// `array` must be valid non null reference to a array that is not already garbage collected
23670    ///
23671    pub unsafe fn GetPrimitiveArrayCritical(&self, array: jarray, isCopy: impl JBooleanMutPtr) -> *mut c_void {
23672        unsafe {
23673            #[cfg(all(feature = "asserts", feature = "std"))]
23674            {
23675                Self::CRITICAL_POINTERS.with(|set| {
23676                    if set.borrow().is_empty() {
23677                        Self::CRITICAL_STRINGS.with(|strings| {
23678                            if strings.borrow().is_empty() {
23679                                //We can only do this check if we have not yet obtained a unreleased critical on the current thread.
23680                                //For subsequent calls we cannot do this check.
23681                                self.check_no_exception("GetPrimitiveArrayCritical");
23682                            }
23683                        });
23684                    }
23685                });
23686                assert!(!array.is_null(), "GetPrimitiveArrayCritical jarray must not be null");
23687            }
23688
23689            let crit = isCopy.use_jboolean_mut(|isCopy| self.jni::<extern "system" fn(JNIEnvVTable, jarray, *mut jboolean) -> *mut c_void>(222)(self.vtable, array, isCopy));
23690
23691            #[cfg(all(feature = "asserts", feature = "std"))]
23692            {
23693                if !crit.is_null() {
23694                    Self::CRITICAL_POINTERS.with(|set| {
23695                        let mut rm = set.borrow_mut();
23696                        let n = rm.remove(&crit).unwrap_or(0) + 1;
23697                        rm.insert(crit, n);
23698                    });
23699                }
23700            }
23701
23702            crit
23703        }
23704    }
23705
23706    ///
23707    /// Releases a critical array obtains in `GetPrimitiveArrayCritical`
23708    ///
23709    /// # Panics
23710    /// if asserts feature is enabled and UB was detected
23711    ///
23712    /// # Safety
23713    /// `array` must be valid non null reference to a array that is not already garbage collected
23714    /// `carray` must be the result of a `GetPrimitiveArrayCritical` call with the same `array`
23715    /// `mode` must be one of `JNI_OK`, `JNI_COMMIT` or `JNI_ABORT` constant values.
23716    ///
23717    pub unsafe fn ReleasePrimitiveArrayCritical(&self, array: jarray, carray: *mut c_void, mode: jint) {
23718        unsafe {
23719            #[cfg(feature = "asserts")]
23720            {
23721                assert!(!array.is_null(), "ReleasePrimitiveArrayCritical jarray must not be null");
23722                assert!(!carray.is_null(), "ReleasePrimitiveArrayCritical carray must not be null");
23723                assert!(
23724                    mode == JNI_OK || mode == JNI_COMMIT || mode == JNI_ABORT,
23725                    "ReleasePrimitiveArrayCritical mode is invalid {mode}"
23726                );
23727
23728                #[cfg(feature = "std")]
23729                {
23730                    Self::CRITICAL_POINTERS.with(|set| {
23731                        let mut rm = set.borrow_mut();
23732                        let mut n = rm.remove(&carray).expect("ReleasePrimitiveArrayCritical carray is not valid");
23733                        if n == 0 {
23734                            unreachable!();
23735                        }
23736
23737                        if mode != JNI_COMMIT {
23738                            //JNI_COMMIT does not release the pointer. It's a noop for non-copied pointers.
23739                            n -= 1;
23740                        }
23741
23742                        if n >= 1 {
23743                            rm.insert(carray, n);
23744                        }
23745                    });
23746                }
23747            }
23748
23749            self.jni::<extern "system" fn(JNIEnvVTable, jarray, *mut c_void, jint)>(223)(self.vtable, array, carray, mode);
23750        }
23751    }
23752
23753    ///
23754    /// Registers native methods to a java class with native methods
23755    ///
23756    /// # Arguments
23757    /// * `clazz` - handle to a Java array.
23758    ///     * must not be null
23759    /// * `methods` - the native method function pointers
23760    ///
23761    /// # Panics
23762    /// if more than `jsize::MAX` native methods are supposed to be registered.
23763    /// if asserts feature is enabled and UB was detected
23764    ///
23765    /// # Safety
23766    /// Current thread must not be detached from JNI.
23767    ///
23768    /// Current thread must not be currently throwing an exception.
23769    ///
23770    /// Current thread does not hold a critical reference.
23771    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23772    ///
23773    /// `clazz` must be a valid non-null reference to a class.
23774    /// `methods` all elements and their function pointers must be non null and valid.
23775    ///
23776    pub unsafe fn RegisterNatives_from_slice(&self, clazz: jclass, methods: &[JNINativeMethod]) -> jint {
23777        unsafe { self.RegisterNatives(clazz, methods.as_ptr(), jint::try_from(methods.len()).expect("More than jsize::MAX methods")) }
23778    }
23779
23780    ///
23781    /// Registers native methods to a java class with native methods
23782    ///
23783    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#RegisterNatives>
23784    ///
23785    /// # Arguments
23786    /// * `clazz`
23787    ///     * must not be null
23788    ///     * must not be already garbage collected
23789    /// * `methods` - the native method function pointers
23790    ///     * must not be null
23791    /// * `size` - amount of `JNINativeMethod`'s in `methods`
23792    ///     * must not be negative
23793    ///
23794    /// # Panics
23795    /// if asserts feature is enabled and UB was detected
23796    ///
23797    /// # Safety
23798    /// Current thread must not be detached from JNI.
23799    ///
23800    /// Current thread must not be currently throwing an exception.
23801    ///
23802    /// Current thread does not hold a critical reference.
23803    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23804    ///
23805    /// `clazz` must be a valid non-null reference to a class.
23806    /// `methods` all elements and their function pointers must be non null and valid.
23807    /// `methods` must be at least `size` elements large
23808    ///
23809    pub unsafe fn RegisterNatives(&self, clazz: jclass, methods: *const JNINativeMethod, size: jint) -> jint {
23810        unsafe {
23811            #[cfg(feature = "asserts")]
23812            {
23813                self.check_not_critical("RegisterNatives");
23814                self.check_no_exception("RegisterNatives");
23815                assert!(!clazz.is_null(), "RegisterNatives class must not be null");
23816                assert!(size > 0, "RegisterNatives size must be greater than 0");
23817                if let Ok(size) = usize::try_from(size) {
23818                    for (idx, cur) in core::slice::from_raw_parts(methods, size).iter().enumerate() {
23819                        assert!(!cur.name.is_null(), "RegisterNatives JNINativeMethod[{idx}],name is null");
23820                        assert!(!cur.signature.is_null(), "RegisterNatives JNINativeMethod[{idx}].signature is null");
23821                        assert!(!cur.fnPtr.is_null(), "RegisterNatives JNINativeMethod[{idx}].fnPtr is null");
23822                    }
23823                }
23824            }
23825
23826            self.jni::<extern "system" fn(JNIEnvVTable, jclass, *const JNINativeMethod, jint) -> jint>(215)(self.vtable, clazz, methods, size)
23827        }
23828    }
23829
23830    ///
23831    /// Unregisters all native bindings from a java class.
23832    ///
23833    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#UnregisterNatives>
23834    ///
23835    /// # Arguments
23836    /// * `clazz`
23837    ///     * must not be null
23838    ///     * must not be already garbage collected
23839    ///
23840    /// # Panics
23841    /// if asserts feature is enabled and UB was detected
23842    ///
23843    /// # Safety
23844    /// Current thread must not be detached from JNI.
23845    ///
23846    /// Current thread must not be currently throwing an exception.
23847    ///
23848    /// Current thread does not hold a critical reference.
23849    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23850    ///
23851    /// `clazz` must be a valid non-null reference to a class.
23852    /// `methods` all elements and their function pointers must be non null and valid.
23853    /// `methods` must be at least `size` elements large
23854    ///
23855    pub unsafe fn UnregisterNatives(&self, clazz: jclass) -> jint {
23856        unsafe {
23857            #[cfg(feature = "asserts")]
23858            {
23859                self.check_not_critical("UnregisterNatives");
23860                self.check_no_exception("UnregisterNatives");
23861                assert!(!clazz.is_null(), "UnregisterNatives class must not be null");
23862            }
23863
23864            self.jni::<extern "system" fn(JNIEnvVTable, jclass) -> jint>(216)(self.vtable, clazz)
23865        }
23866    }
23867
23868    ///
23869    /// Enters a monitor on a java object.
23870    /// A will cause all other java threads to block when trying to enter a synchronized block
23871    /// on the object or other native threads to block when trying to enter a monitor.
23872    /// This fn will block until all other threads have either left their synchronized block or monitor sections.
23873    ///
23874    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#MonitorEnter>
23875    ///
23876    /// # Returns
23877    /// `JNI_OK` on success
23878    ///
23879    /// # Arguments
23880    /// * `obj`
23881    ///     * must not be null
23882    ///     * must not be already garbage collected
23883    ///
23884    /// # Panics
23885    /// if asserts feature is enabled and UB was detected
23886    ///
23887    /// # Safety
23888    /// Current thread must not be detached from JNI.
23889    ///
23890    /// Current thread must not be currently throwing an exception.
23891    ///
23892    /// Current thread does not hold a critical reference.
23893    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23894    ///
23895    /// `jobject` must be a valid non-null reference that is not yet garbage collected.
23896    ///
23897    pub unsafe fn MonitorEnter(&self, obj: jobject) -> jint {
23898        unsafe {
23899            #[cfg(feature = "asserts")]
23900            {
23901                self.check_not_critical("MonitorEnter");
23902                self.check_no_exception("MonitorEnter");
23903                assert!(!obj.is_null(), "MonitorEnter object must not be null");
23904            }
23905
23906            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jint>(217)(self.vtable, obj)
23907        }
23908    }
23909
23910    ///
23911    /// Leaves a monitor entered by `MonitorEnter`
23912    /// This fn cannot be used to "leave" synchronized blocks entered into by java code.
23913    ///
23914    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#MonitorExit>
23915    ///
23916    /// # Arguments
23917    /// * `obj`
23918    ///     * must not be null
23919    ///     * must not be already garbage collected
23920    ///
23921    /// # Returns
23922    /// `JNI_OK` on success
23923    ///
23924    /// # Throws Java Exception
23925    /// * `IllegalMonitorStateException` - if the current thread does not own the monitor
23926    ///
23927    /// # Panics
23928    /// if asserts feature is enabled and UB was detected
23929    ///
23930    /// # Safety
23931    /// Current thread must not be detached from JNI.
23932    ///
23933    /// Current thread must not be currently throwing an exception.
23934    ///
23935    /// Current thread does not hold a critical reference.
23936    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23937    ///
23938    /// `jobject` must be a valid non-null reference that is not yet garbage collected.
23939    ///
23940    pub unsafe fn MonitorExit(&self, obj: jobject) -> jint {
23941        unsafe {
23942            #[cfg(feature = "asserts")]
23943            {
23944                self.check_not_critical("MonitorExit");
23945                assert!(!obj.is_null(), "MonitorExit object must not be null");
23946            }
23947
23948            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jint>(218)(self.vtable, obj)
23949        }
23950    }
23951
23952    ///
23953    /// Creates a new nio direct `ByteBuffer` that is backed by some native memory provided to by the pointer.
23954    /// When garbage collection collects that `ByteBuffer` it will not perform any operation on the backed memory.
23955    /// The caller has to ensure that the pointer remains valid for the entire existance of the `ByteBuffer`
23956    ///
23957    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewDirectByteBuffer>
23958    ///
23959    /// # Arguments
23960    /// * `address`
23961    ///     * must not be null
23962    /// * `capacity`
23963    ///     * size of the memory pointed to by address
23964    ///     * must be positive
23965    ///
23966    /// # Returns
23967    /// A local reference to the newly created `ByteBuffer`
23968    ///
23969    /// # Panics
23970    /// if asserts feature is enabled and UB was detected
23971    ///
23972    /// # Safety
23973    /// Current thread must not be detached from JNI.
23974    ///
23975    /// Current thread must not be currently throwing an exception.
23976    ///
23977    /// Current thread does not hold a critical reference.
23978    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23979    ///
23980    /// `address` must be a valid non-null.
23981    /// `capacity` must be positive, the memory pointed to by `address` must have at least this amount of bytes in space.
23982    ///
23983    pub unsafe fn NewDirectByteBuffer(&self, address: *mut c_void, capacity: jlong) -> jobject {
23984        unsafe {
23985            #[cfg(feature = "asserts")]
23986            {
23987                self.check_not_critical("NewDirectByteBuffer");
23988                self.check_no_exception("NewDirectByteBuffer");
23989                assert!(!address.is_null(), "NewDirectByteBuffer address must not be null");
23990                assert!(capacity >= 0, "NewDirectByteBuffer capacity must not be negative {capacity}");
23991                assert!(
23992                    capacity <= jlong::from(jint::MAX),
23993                    "NewDirectByteBuffer capacity is too big, its larger than Integer.MAX_VALUE {capacity}"
23994                );
23995            }
23996
23997            self.jni::<extern "system" fn(JNIEnvVTable, *mut c_void, jlong) -> jobject>(229)(self.vtable, address, capacity)
23998        }
23999    }
24000
24001    ///
24002    /// Gets the memory address that backs a direct nio buffer.
24003    ///
24004    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetDirectBufferAddress>
24005    ///
24006    /// # Arguments
24007    /// * `buf`
24008    ///     * must not be null
24009    ///     * must not be garbage collected
24010    ///
24011    /// If `buf` does not refer to a Buffer object or is not direct then this fn returns -1.
24012    /// If the jvm does not support accessing direct buffers then this fn returns -1.
24013    ///
24014    /// # Returns
24015    /// The backing pointer or -1 on error
24016    ///
24017    /// # Panics
24018    /// if asserts feature is enabled and UB was detected
24019    ///
24020    /// # Safety
24021    /// Current thread must not be detached from JNI.
24022    ///
24023    /// Current thread must not be currently throwing an exception.
24024    ///
24025    /// Current thread does not hold a critical reference.
24026    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
24027    ///
24028    /// `buf` must be a valid non-null reference to a object and not be garbage collected.
24029    ///
24030    pub unsafe fn GetDirectBufferAddress(&self, buf: jobject) -> *mut c_void {
24031        unsafe {
24032            #[cfg(feature = "asserts")]
24033            {
24034                self.check_not_critical("GetDirectBufferAddress");
24035                self.check_no_exception("GetDirectBufferAddress");
24036                assert!(!buf.is_null(), "GetDirectBufferAddress buffer must not be null");
24037            }
24038            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> *mut c_void>(230)(self.vtable, buf)
24039        }
24040    }
24041
24042    ///
24043    /// Gets the capacity of a direct nio buffer.
24044    ///
24045    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetDirectBufferCapacity>
24046    ///
24047    /// # Arguments
24048    /// * `buf`
24049    ///     * must not be null
24050    ///     * must not be garbage collected
24051    ///
24052    /// If `buf` does not refer to a Buffer object or is not direct then this fn returns -1.
24053    /// If the jvm does not support accessing direct buffers then this fn returns -1.
24054    ///
24055    /// # Returns
24056    /// The capacity or -1 on error
24057    ///
24058    /// # Panics
24059    /// if asserts feature is enabled and UB was detected
24060    ///
24061    /// # Safety
24062    /// Current thread must not be detached from JNI.
24063    ///
24064    /// Current thread must not be currently throwing an exception.
24065    ///
24066    /// Current thread does not hold a critical reference.
24067    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
24068    ///
24069    /// `buf` must be a valid non-null reference to a object and not be garbage collected.
24070    ///
24071    pub unsafe fn GetDirectBufferCapacity(&self, buf: jobject) -> jlong {
24072        unsafe {
24073            #[cfg(feature = "asserts")]
24074            {
24075                self.check_not_critical("GetDirectBufferCapacity");
24076                self.check_no_exception("GetDirectBufferCapacity");
24077                assert!(!buf.is_null(), "GetDirectBufferCapacity buffer must not be null");
24078            }
24079            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jlong>(231)(self.vtable, buf)
24080        }
24081    }
24082
24083    ///
24084    /// Converts a reflection Method to a jmethodID
24085    ///
24086    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#FromReflectedMethod>
24087    ///
24088    /// # Arguments
24089    /// * `method`
24090    ///     * must not be null
24091    ///     * must not be garbage collected
24092    ///     * must be instanceof a java.lang.reflect.Method or java.lang.reflect.Constructor
24093    ///
24094    ///
24095    /// # Returns
24096    /// the jmethodID that refers to the same method.
24097    ///
24098    /// # Panics
24099    /// if asserts feature is enabled and UB was detected
24100    ///
24101    /// # Safety
24102    /// Current thread must not be detached from JNI.
24103    ///
24104    /// Current thread must not be currently throwing an exception.
24105    ///
24106    /// Current thread does not hold a critical reference.
24107    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
24108    ///
24109    /// `method` must be a valid non-null reference to a java.lang.reflect.Method or java.lang.reflect.Constructor and not be garbage collected.
24110    ///
24111    pub unsafe fn FromReflectedMethod(&self, method: jobject) -> jmethodID {
24112        unsafe {
24113            #[cfg(feature = "asserts")]
24114            {
24115                self.check_not_critical("FromReflectedMethod");
24116                self.check_no_exception("FromReflectedMethod");
24117                assert!(!method.is_null(), "FromReflectedMethod method must not be null");
24118            }
24119            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jmethodID>(7)(self.vtable, method)
24120        }
24121    }
24122
24123    ///
24124    /// Converts a jmethodID into a reflection Method
24125    ///
24126    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#FromReflectedField>
24127    ///
24128    /// # Arguments
24129    /// * `cls` - the class the method is in
24130    ///     * must not be null
24131    ///     * must not be garbage collected
24132    /// * `jmethodID`
24133    ///     * must not be null
24134    ///     * must refer to a method that is in `cls`
24135    /// * `isStatic` - is the method static or not?
24136    ///
24137    ///
24138    /// # Returns
24139    /// a local reference that refers to the same method as the jmethodID or null on erro
24140    ///
24141    /// # Throws Java Exception
24142    /// * `OutOfMemoryError` - if the jvm runs out of memory.
24143    ///
24144    /// # Panics
24145    /// if asserts feature is enabled and UB was detected
24146    ///
24147    /// # Safety
24148    /// Current thread must not be detached from JNI.
24149    ///
24150    /// Current thread must not be currently throwing an exception.
24151    ///
24152    /// Current thread does not hold a critical reference.
24153    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
24154    ///
24155    /// `cls` must be a valid non-null reference to a Class and not be garbage collected.
24156    /// `jmethodID` must refer to a method in `cls` and must be either static or not static depending on the `isStatic` flag.
24157    ///
24158    pub unsafe fn ToReflectedMethod(&self, cls: jclass, jmethodID: jmethodID, isStatic: impl Into<jboolean>) -> jobject {
24159        let isStatic = isStatic.into();
24160        unsafe {
24161            #[cfg(feature = "asserts")]
24162            {
24163                self.check_not_critical("ToReflectedMethod");
24164                self.check_no_exception("ToReflectedMethod");
24165                assert!(!cls.is_null(), "ToReflectedMethod class must not be null");
24166                assert!(!jmethodID.is_null(), "ToReflectedMethod method must not be null");
24167                assert!(!isStatic.is_wide(), "ToReflectedMethod isStatic is wide value");
24168            }
24169            self.jni::<extern "system" fn(JNIEnvVTable, jclass, jmethodID, jboolean) -> jobject>(9)(self.vtable, cls, jmethodID, isStatic)
24170        }
24171    }
24172
24173    ///
24174    /// Converts a reflection Field to a jfieldID
24175    ///
24176    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#FromReflectedField>
24177    ///
24178    /// # Arguments
24179    /// * `field`
24180    ///     * must not be null
24181    ///     * must not be garbage collected
24182    ///     * must be instanceof a java.lang.reflect.Field
24183    ///
24184    ///
24185    /// # Returns
24186    /// the jfieldID that refers to the same field.
24187    ///
24188    /// # Panics
24189    /// if asserts feature is enabled and UB was detected
24190    ///
24191    /// # Safety
24192    /// Current thread must not be detached from JNI.
24193    ///
24194    /// Current thread must not be currently throwing an exception.
24195    ///
24196    /// Current thread does not hold a critical reference.
24197    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
24198    ///
24199    /// `field` must be a valid non-null reference to a java.lang.reflect.Field and not be garbage collected.
24200    ///
24201    pub unsafe fn FromReflectedField(&self, field: jobject) -> jfieldID {
24202        unsafe {
24203            #[cfg(feature = "asserts")]
24204            {
24205                self.check_not_critical("FromReflectedField");
24206                self.check_no_exception("FromReflectedField");
24207                assert!(!field.is_null(), "FromReflectedField field must not be null");
24208            }
24209            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jfieldID>(8)(self.vtable, field)
24210        }
24211    }
24212
24213    ///
24214    /// Converts a jfieldID into a reflection Field
24215    ///
24216    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#FromReflectedField>
24217    ///
24218    /// # Arguments
24219    /// * `cls` - the class the method is in
24220    ///     * must not be null
24221    ///     * must not be garbage collected
24222    /// * `jfieldID`
24223    ///     * must not be null
24224    ///     * must refer to a field that is in `cls`
24225    /// * `isStatic` - is the method static or not?
24226    ///
24227    ///
24228    /// # Returns
24229    /// a local reference that refers to the same field as the jfieldID or null on erro
24230    ///
24231    /// # Throws Java Exception
24232    /// * `OutOfMemoryError` - if the jvm runs out of memory.
24233    ///
24234    /// # Panics
24235    /// if asserts feature is enabled and UB was detected
24236    ///
24237    /// # Safety
24238    /// Current thread must not be detached from JNI.
24239    ///
24240    /// Current thread must not be currently throwing an exception.
24241    ///
24242    /// Current thread does not hold a critical reference.
24243    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
24244    ///
24245    /// `cls` must be a valid non-null reference to a Class and not be garbage collected.
24246    /// `jfieldID` must refer to a field in `cls` and must be either static or not static depending on the `isStatic` flag.
24247    ///
24248    pub unsafe fn ToReflectedField(&self, cls: jclass, jfieldID: jfieldID, isStatic: impl Into<jboolean>) -> jobject {
24249        let isStatic = isStatic.into();
24250        unsafe {
24251            #[cfg(feature = "asserts")]
24252            {
24253                self.check_not_critical("ToReflectedField");
24254                self.check_no_exception("ToReflectedField");
24255                assert!(!cls.is_null(), "ToReflectedField class must not be null");
24256                assert!(!jfieldID.is_null(), "ToReflectedField field must not be null");
24257                assert!(!isStatic.is_wide(), "ToReflectedMethod isStatic is wide value");
24258            }
24259            self.jni::<extern "system" fn(JNIEnvVTable, jclass, jfieldID, jboolean) -> jobject>(12)(self.vtable, cls, jfieldID, isStatic)
24260        }
24261    }
24262
24263    ///
24264    /// Returns the `JavaVM` assosicated with this `JNIEnv`
24265    ///
24266    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetJavaVM>
24267    ///
24268    /// # Panics
24269    /// if the JVM does not return an error but refuses to set the `JavaVM` pointer.
24270    ///
24271    /// # Returns
24272    /// the `JavaVM` "object" or an error code.
24273    ///
24274    /// # Errors
24275    /// JNI implementation specific error constants like `JNI_EINVAL`
24276    ///
24277    /// # Panics
24278    /// if asserts feature is enabled and UB was detected
24279    ///
24280    /// # Safety
24281    /// Current thread must not be detached from JNI.
24282    ///
24283    /// Current thread must not be currently throwing an exception.
24284    ///
24285    /// Current thread does not hold a critical reference.
24286    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
24287    ///
24288    pub unsafe fn GetJavaVM(&self) -> Result<JavaVM, jint> {
24289        unsafe {
24290            #[cfg(feature = "asserts")]
24291            {
24292                self.check_not_critical("GetJavaVM");
24293                self.check_no_exception("GetJavaVM");
24294            }
24295            let mut r: JNIInvPtr = SyncMutPtr::null();
24296            let res = self.jni::<extern "system" fn(JNIEnvVTable, *mut JNIInvPtr) -> jint>(219)(self.vtable, &raw mut r);
24297            if res != 0 {
24298                return Err(res);
24299            }
24300            assert!(!r.is_null(), "GetJavaVM returned 0 but did not set JVM pointer");
24301            Ok(JavaVM { vtable: r })
24302        }
24303    }
24304
24305    ///
24306    /// Returns the module of the given class.
24307    ///
24308    /// <https://docs.oracle.com/en/java/javase/21/docs/specs/jni/functions.html#getmodule>
24309    ///
24310    /// # Arguments
24311    /// * `cls`
24312    ///     * must not be null
24313    ///     * must not be garbage collected
24314    ///     * must refer to a class
24315    ///
24316    /// # Returns
24317    /// a local reference to the module object.
24318    ///
24319    /// # Panics
24320    /// if asserts feature is enabled and UB was detected
24321    ///
24322    /// # Safety
24323    /// Current thread must not be detached from JNI.
24324    ///
24325    /// Current thread must not be currently throwing an exception.
24326    ///
24327    /// Current thread does not hold a critical reference.
24328    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
24329    ///
24330    /// The JVM must be at least Java 9
24331    ///
24332    /// `cls` must refer to a non-null class that is not yet garbage collected.
24333    ///
24334    pub unsafe fn GetModule(&self, cls: jclass) -> jobject {
24335        unsafe {
24336            #[cfg(feature = "asserts")]
24337            {
24338                self.check_not_critical("GetModule");
24339                self.check_no_exception("GetModule");
24340                assert!(self.GetVersion() >= JNI_VERSION_9);
24341            }
24342
24343            self.jni::<extern "system" fn(JNIEnvVTable, jclass) -> jobject>(233)(self.vtable, cls)
24344        }
24345    }
24346
24347    ///
24348    /// Returns the module of the given class.
24349    ///
24350    /// <https://docs.oracle.com/en/java/javase/21/docs/specs/jni/functions.html#isvirtualthread>
24351    ///
24352    /// # Arguments
24353    /// * `thread`
24354    ///     * must not be null
24355    ///     * must not be garbage collected
24356    ///     * must refer to a java.lang.Thread
24357    ///
24358    /// # Returns
24359    /// true if the thread is virtual, false if not.
24360    ///
24361    /// # Panics
24362    /// if asserts feature is enabled and UB was detected
24363    ///
24364    /// # Safety
24365    /// Current thread must not be detached from JNI.
24366    ///
24367    /// Current thread must not be currently throwing an exception.
24368    ///
24369    /// Current thread does not hold a critical reference.
24370    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
24371    ///
24372    /// The JVM must be at least Java 21
24373    ///
24374    /// `thread` must refer to a non-null java.lang.Thread that is not yet garbage collected.
24375    ///
24376    pub unsafe fn IsVirtualThread(&self, thread: jobject) -> bool {
24377        unsafe {
24378            #[cfg(feature = "asserts")]
24379            {
24380                self.check_not_critical("IsVirtualThread");
24381                self.check_no_exception("IsVirtualThread");
24382                assert!(self.GetVersion() >= JNI_VERSION_21);
24383            }
24384            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jboolean>(234)(self.vtable, thread).as_bool()
24385        }
24386    }
24387
24388    /// Checks that we are not in a critical section currently.
24389    #[cfg(feature = "asserts")]
24390    unsafe fn check_not_critical(self, context: &str) {
24391        #[cfg(feature = "std")]
24392        {
24393            Self::CRITICAL_POINTERS.with(|set| {
24394                let sz = set.borrow_mut().len();
24395                assert_eq!(
24396                    sz, 0,
24397                    "{context} cannot be called now, because there are {sz} critical pointers into primitive arrays that have not been released by the current thread."
24398                );
24399            });
24400            Self::CRITICAL_STRINGS.with(|set| {
24401                let sz = set.borrow_mut().len();
24402                assert_eq!(
24403                    sz, 0,
24404                    "{context} cannot be called now, because there are {sz} critical pointers into strings that have not been released by the current thread."
24405                );
24406            });
24407        }
24408
24409        _ = context;
24410        _ = self;
24411    }
24412
24413    /// Checks that obj is an array of any type
24414    #[cfg(feature = "asserts")]
24415    unsafe fn check_is_array(self, obj: jobject, context: &str) {
24416        unsafe {
24417            assert!(!obj.is_null(), "{context} cannot check if arg is array because arg is null");
24418            let cl = self.GetObjectClass(obj);
24419            assert!(!cl.is_null(), "{context} arg.getClass() is null?");
24420            let clazz = self.GetObjectClass(cl);
24421            assert!(!clazz.is_null(), "{context} Class#getClass() is null?");
24422
24423            let is_array = self.GetMethodID(clazz, "isArray", "()Z");
24424            let r = self.CallBooleanMethod0(cl, is_array);
24425            if self.ExceptionCheck() {
24426                self.ExceptionDescribe();
24427                panic!("{context} Class#isArray() is throws?");
24428            }
24429
24430            assert!(r, "{context} arg is not an array");
24431
24432            self.DeleteLocalRef(cl);
24433            self.DeleteLocalRef(clazz);
24434        }
24435    }
24436
24437    /// Checks that all boolean values in the array determined by len are 0 or 1 in memory (aka not wide booleans)
24438    #[cfg(feature = "asserts")]
24439    unsafe fn check_bool_array_is_narrow(context: &str, ptr: *const jboolean, len: jsize) {
24440        unsafe {
24441            if ptr.is_null() {
24442                return;
24443            }
24444
24445            let Ok(len) = usize::try_from(len) else {
24446                return;
24447            };
24448
24449            let sl = core::slice::from_raw_parts(ptr, len);
24450            for (idx, b) in sl.iter().enumerate() {
24451                assert!(
24452                    !b.is_wide(),
24453                    "{context} boolean array contains a wide value {} in index {idx}. This would likely be UB in the JVM.",
24454                    b.as_wide()
24455                );
24456            }
24457        }
24458    }
24459
24460    /// Checks that no exception is currently thrown
24461    #[cfg(feature = "asserts")]
24462    unsafe fn check_no_exception(self, context: &str) {
24463        unsafe {
24464            if !self.ExceptionCheck() {
24465                return;
24466            }
24467
24468            self.ExceptionDescribe();
24469            panic!("{context} exception is thrown and not handled");
24470        }
24471    }
24472
24473    /// Checks if the object is a valid reference or null
24474    #[cfg(feature = "asserts")]
24475    unsafe fn check_ref_obj_permit_null(self, context: &str, obj: jobject) {
24476        unsafe {
24477            if obj.is_null() {
24478                return;
24479            }
24480
24481            if self.ExceptionCheck() {
24482                //We cannot do this check currently...
24483                return;
24484            }
24485
24486            assert_ne!(self.GetObjectRefType(obj), jobjectRefType::JNIInvalidRefType, "{context} ref is invalid");
24487        }
24488    }
24489
24490    /// Checks if the object is a valid non-null reference
24491    #[cfg(feature = "asserts")]
24492    unsafe fn check_ref_obj(self, context: &str, obj: jobject) {
24493        unsafe {
24494            assert!(!obj.is_null(), "{context} ref is null");
24495
24496            if self.ExceptionCheck() {
24497                //We cannot do this check currently...
24498                return;
24499            }
24500
24501            let cl = self.FindClass("java/lang/System");
24502            assert!(!cl.is_null(), "java/lang/System not found?");
24503
24504            let cname = CString::new("gc").unwrap_unchecked();
24505            let csig = CString::new("()V").unwrap_unchecked();
24506            //GetStaticMethodID
24507            let gc_method = self.jni::<extern "system" fn(JNIEnvVTable, jobject, *const c_char, *const c_char) -> jmethodID>(113)(self.vtable, cl, cname.as_ptr(), csig.as_ptr());
24508
24509            assert!(!gc_method.is_null(), "java/lang/System#gc() not found?");
24510
24511            match self.GetObjectRefType(obj) {
24512                jobjectRefType::JNIInvalidRefType => panic!("{context} ref is invalid"),
24513                jobjectRefType::JNIWeakGlobalRefType => {
24514                    //This bad practice, but sadly sometimes valid.
24515                    //I.e. caller holds a strong reference and "knows" the weak ref cannot be GC'ed during the call.
24516                    //Good practice would be to use the strong ref to make the call but sadly JVM doesn't enforce this.
24517                    //This is just best effort really since we have absolutely NO clue when the GC will run.
24518                    //CallStaticVoidMethod
24519                    self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID)>(141)(self.vtable, obj, gc_method);
24520                    assert!(!self.IsSameObject(obj, null_mut()), "{context} weak reference that has already been garbage collected");
24521                }
24522                _ => {}
24523            }
24524
24525            self.DeleteLocalRef(cl);
24526        }
24527    }
24528
24529    /// Checks if the class is a throwable
24530    #[cfg(feature = "asserts")]
24531    unsafe fn check_is_exception_class(self, context: &str, obj: jclass) {
24532        unsafe {
24533            self.check_is_class(context, obj);
24534            let throwable_cl = self.FindClass("java/lang/Throwable");
24535            assert!(!throwable_cl.is_null(), "{context} java/lang/Throwable not found???");
24536            assert!(self.IsAssignableFrom(obj, throwable_cl), "{context} class is not throwable");
24537            self.DeleteLocalRef(throwable_cl);
24538        }
24539    }
24540
24541    /// Checks if the class is not abstract
24542    #[cfg(feature = "asserts")]
24543    unsafe fn check_is_not_abstract(self, context: &str, obj: jclass) {
24544        unsafe {
24545            self.check_is_class(context, obj);
24546            let class_cl = self.FindClass("java/lang/Class");
24547            assert!(!class_cl.is_null(), "{context} java/lang/Class not found???");
24548            let meth = self.GetMethodID(class_cl, "getModifiers", "()I");
24549            assert!(!meth.is_null(), "{context} java/lang/Class#getModifiers not found???");
24550            let mods = self.CallIntMethod0(obj, meth);
24551            self.DeleteLocalRef(class_cl);
24552            if self.ExceptionCheck() {
24553                self.ExceptionDescribe();
24554                panic!("{context} java/lang/Class#getModifiers throws?");
24555            }
24556
24557            let mod_cl = self.FindClass("java/lang/reflect/Modifier");
24558            assert!(!mod_cl.is_null(), "{context} java/lang/reflect/Modifier not found???");
24559            let mod_field = self.GetStaticFieldID(mod_cl, "ABSTRACT", "I");
24560            assert!(!mod_field.is_null(), "{context} java/lang/reflect/Modifier.ABSTRACT not found???");
24561            let amod = self.GetStaticIntField(mod_cl, mod_field);
24562            self.DeleteLocalRef(mod_cl);
24563
24564            assert_eq!(mods & amod, 0, "{context} class is abstract");
24565        }
24566    }
24567
24568    /// Checks if obj is a class.
24569    #[cfg(feature = "asserts")]
24570    unsafe fn check_is_class(self, context: &str, obj: jclass) {
24571        unsafe {
24572            assert!(!obj.is_null(), "{context} class is null");
24573            self.check_ref_obj(context, obj);
24574
24575            let class_cl = self.FindClass("java/lang/Class");
24576            assert!(!class_cl.is_null(), "{context} java/lang/Class not found???");
24577            //GET OBJECT CLASS
24578            let tcl = self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jobject>(31)(self.vtable, obj);
24579            assert!(self.IsSameObject(tcl, class_cl), "{context} not a class!");
24580            self.DeleteLocalRef(tcl);
24581            self.DeleteLocalRef(class_cl);
24582        }
24583    }
24584
24585    /// Checks if the `obj` is a classloader or null
24586    #[cfg(feature = "asserts")]
24587    unsafe fn check_is_classloader_or_null(self, context: &str, obj: jobject) {
24588        unsafe {
24589            if obj.is_null() {
24590                return;
24591            }
24592            self.check_ref_obj(context, obj);
24593            let classloader_cl = self.FindClass("java/lang/ClassLoader");
24594            assert!(!classloader_cl.is_null(), "{context} java/lang/ClassLoader not found");
24595            assert!(self.IsInstanceOf(obj, classloader_cl), "{context} argument is not a valid instanceof ClassLoader");
24596
24597            self.DeleteLocalRef(classloader_cl);
24598        }
24599    }
24600
24601    /// Checks if the argument refers toa string
24602    #[cfg(feature = "asserts")]
24603    unsafe fn check_if_arg_is_string(self, src: &str, jobject: jobject) {
24604        unsafe {
24605            if jobject.is_null() {
24606                return;
24607            }
24608
24609            let clazz = self.GetObjectClass(jobject);
24610            assert!(!clazz.is_null(), "{src} string.class is null?");
24611            let str_class = self.FindClass("java/lang/String");
24612            assert!(!str_class.is_null(), "{src} java/lang/String not found?");
24613            assert!(self.IsSameObject(clazz, str_class), "{src} Non string passed to GetStringCritical");
24614            self.DeleteLocalRef(clazz);
24615            self.DeleteLocalRef(str_class);
24616        }
24617    }
24618
24619    /// Checks if the field type of a static field matches
24620    #[cfg(feature = "asserts")]
24621    unsafe fn check_field_type_static(self, context: &str, obj: jclass, fieldID: jfieldID, ty: &str) {
24622        unsafe {
24623            self.check_is_class(context, obj);
24624            assert!(!fieldID.is_null(), "{context} fieldID is null");
24625            let f = self.ToReflectedField(obj, fieldID, true);
24626            assert!(!f.is_null(), "{context} -> ToReflectedField returned null");
24627            let field_cl = self.FindClass("java/lang/reflect/Field");
24628            assert!(!f.is_null(), "{context} java/lang/reflect/Method not found???");
24629            let field_rtyp = self.GetMethodID(field_cl, "getType", "()Ljava/lang/Class;");
24630            assert!(!field_rtyp.is_null(), "{context} java/lang/reflect/Field#getType not found???");
24631            //CallObjectMethodA
24632            let rtc = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, f, field_rtyp, null());
24633            assert!(!rtc.is_null(), "{context} java/lang/reflect/Field#getType returned null???");
24634            self.DeleteLocalRef(field_cl);
24635            self.DeleteLocalRef(f);
24636            let class_cl = self.FindClass("java/lang/Class");
24637            assert!(!class_cl.is_null(), "{context} java/lang/Class not found???");
24638            let class_name = self.GetMethodID(class_cl, "getName", "()Ljava/lang/String;");
24639            assert!(!class_name.is_null(), "{context} java/lang/Class#getName not found???");
24640            //CallObjectMethodA
24641            let name_str = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, rtc, class_name, null());
24642            assert!(!name_str.is_null(), "{context} java/lang/Class#getName returned null??? Class has no name???");
24643            self.DeleteLocalRef(rtc);
24644            let the_name = self
24645                .GetStringUTFChars_as_string(name_str)
24646                .unwrap_or_else(|| panic!("{context} failed to get/parse classname???"));
24647            self.DeleteLocalRef(class_cl);
24648            self.DeleteLocalRef(name_str);
24649            if the_name.as_str().eq(ty) {
24650                return;
24651            }
24652
24653            if ty.eq("object") {
24654                match the_name.as_str() {
24655                    "long" | "int" | "short" | "byte" | "char" | "float" | "double" | "boolean" => {
24656                        panic!("{context} type of field is {the_name} but expected object");
24657                    }
24658                    _ => {
24659                        return;
24660                    }
24661                }
24662            }
24663
24664            panic!("{context} type of field is {the_name} but expected {ty}");
24665        }
24666    }
24667
24668    /// Checks if the return type of a static method matches
24669    #[cfg(feature = "asserts")]
24670    unsafe fn check_return_type_static(self, context: &str, obj: jclass, methodID: jmethodID, ty: &str) {
24671        unsafe {
24672            self.check_is_class(context, obj);
24673            assert!(!methodID.is_null(), "{context} methodID is null");
24674            let m = self.ToReflectedMethod(obj, methodID, true);
24675            assert!(!m.is_null(), "{context} -> ToReflectedMethod returned null");
24676            let meth_cl = self.FindClass("java/lang/reflect/Method");
24677            assert!(!m.is_null(), "{context} java/lang/reflect/Method not found???");
24678            let meth_rtyp = self.GetMethodID(meth_cl, "getReturnType", "()Ljava/lang/Class;");
24679            assert!(!meth_rtyp.is_null(), "{context} java/lang/reflect/Method#getReturnType not found???");
24680            //CallObjectMethodA
24681            let rtc = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, m, meth_rtyp, null());
24682            self.DeleteLocalRef(meth_cl);
24683            self.DeleteLocalRef(m);
24684            if rtc.is_null() {
24685                if ty.eq("void") {
24686                    return;
24687                }
24688
24689                panic!("{context} return type of method is void but expected {ty}");
24690            }
24691            let class_cl = self.FindClass("java/lang/Class");
24692            assert!(!class_cl.is_null(), "{context} java/lang/Class not found???");
24693            let class_name = self.GetMethodID(class_cl, "getName", "()Ljava/lang/String;");
24694            assert!(!class_name.is_null(), "{context} java/lang/Class#getName not found???");
24695            //CallObjectMethodA
24696            let name_str = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, rtc, class_name, null());
24697            assert!(!name_str.is_null(), "{context} java/lang/Class#getName returned null??? Class has no name???");
24698            self.DeleteLocalRef(rtc);
24699            let the_name = self
24700                .GetStringUTFChars_as_string(name_str)
24701                .unwrap_or_else(|| panic!("{context} failed to get/parse classname???"));
24702            self.DeleteLocalRef(class_cl);
24703            self.DeleteLocalRef(name_str);
24704            if the_name.as_str().eq(ty) {
24705                return;
24706            }
24707
24708            if ty.eq("object") {
24709                match the_name.as_str() {
24710                    "void" | "long" | "int" | "short" | "byte" | "char" | "float" | "double" | "boolean" => {
24711                        panic!("{context} return type of method is {the_name} but expected object");
24712                    }
24713                    _ => {
24714                        return;
24715                    }
24716                }
24717            }
24718
24719            panic!("{context} return type of method is {the_name} but expected {ty}");
24720        }
24721    }
24722
24723    /// Checks if the parameter types for a static fn match
24724    #[cfg(feature = "asserts")]
24725    unsafe fn check_parameter_types_static<T: JType>(self, context: &str, clazz: jclass, methodID: jmethodID, param1: T, idx: jsize, count: jsize) {
24726        unsafe {
24727            self.check_is_class(context, clazz);
24728            assert!(!methodID.is_null(), "{context} methodID is null");
24729            let java_method = self.ToReflectedMethod(clazz, methodID, true);
24730            assert!(!java_method.is_null(), "{context} -> ToReflectedMethod returned null");
24731            let meth_cl = self.FindClass("java/lang/reflect/Method");
24732            assert!(!java_method.is_null(), "{context} java/lang/reflect/Method not found???");
24733            let meth_params = self.GetMethodID(meth_cl, "getParameterTypes", "()[Ljava/lang/Class;");
24734            assert!(!meth_params.is_null(), "{context} java/lang/reflect/Method#getParameterTypes not found???");
24735
24736            //CallObjectMethodA
24737            let parameter_array = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, java_method, meth_params, null());
24738            self.DeleteLocalRef(meth_cl);
24739            self.DeleteLocalRef(java_method);
24740            assert!(!parameter_array.is_null(), "{context} java/lang/reflect/Method#getParameterTypes return null???");
24741            let parameter_count = self.GetArrayLength(parameter_array);
24742            assert_eq!(parameter_count, count, "{context} wrong number of method parameters");
24743            let param1_class = self.GetObjectArrayElement(parameter_array, idx);
24744            assert!(!param1_class.is_null(), "{context} java/lang/reflect/Method#getParameterTypes[{idx}] is null???");
24745            self.DeleteLocalRef(parameter_array);
24746
24747            let class_cl = self.FindClass("java/lang/Class");
24748            assert!(!class_cl.is_null(), "{context} java/lang/Class not found???");
24749            let class_name = self.GetMethodID(class_cl, "getName", "()Ljava/lang/String;");
24750            assert!(!class_name.is_null(), "{context} java/lang/Class#getName not found???");
24751            let class_is_primitive = self.GetMethodID(class_cl, "isPrimitive", "()Z");
24752            assert!(!class_is_primitive.is_null(), "{context} java/lang/Class#isPrimitive not found???");
24753
24754            //CallObjectMethodA
24755            let name_str = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, param1_class, class_name, null());
24756            assert!(!name_str.is_null(), "{context} java/lang/Class#getName returned null??? Class has no name???");
24757            //CallBooleanMethodA
24758            let param1_is_primitive =
24759                self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jboolean>(39)(self.vtable, param1_class, class_is_primitive, null());
24760
24761            let the_name = self
24762                .GetStringUTFChars_as_string(name_str)
24763                .unwrap_or_else(|| panic!("{context} failed to get/parse classname???"));
24764            self.DeleteLocalRef(class_cl);
24765            self.DeleteLocalRef(name_str);
24766
24767            match T::jtype_id() {
24768                'Z' => assert_eq!("boolean", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed boolean"),
24769                'B' => assert_eq!("byte", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed byte"),
24770                'S' => assert_eq!("short", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed short"),
24771                'C' => assert_eq!("char", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed char"),
24772                'I' => assert_eq!("int", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed int"),
24773                'J' => assert_eq!("long", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed long"),
24774                'F' => assert_eq!("float", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed float"),
24775                'D' => assert_eq!("double", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed double"),
24776                'L' => {
24777                    assert!(!param1_is_primitive, "{context} param{idx} wrong type. Method has {the_name} but passed an object or null");
24778                    let jt: jtype = param1.into();
24779                    let obj = jt.object;
24780                    if !obj.is_null() {
24781                        assert!(
24782                            self.IsInstanceOf(obj, param1_class),
24783                            "{context} param{idx} wrong type. Method has {the_name} but passed an object that is not null and not instanceof"
24784                        );
24785                    }
24786                }
24787                _ => unreachable!("{}", T::jtype_id()),
24788            }
24789
24790            self.DeleteLocalRef(param1_class);
24791        }
24792    }
24793
24794    /// Checks if the parameter type matches the constructor
24795    #[cfg(feature = "asserts")]
24796    unsafe fn check_parameter_types_constructor<T: JType>(self, context: &str, clazz: jclass, methodID: jmethodID, param1: T, idx: jsize, count: jsize) {
24797        unsafe {
24798            self.check_ref_obj(context, clazz);
24799            assert!(!clazz.is_null(), "{context} obj.class is null??");
24800            assert!(!methodID.is_null(), "{context} methodID is null");
24801            let java_method = self.ToReflectedMethod(clazz, methodID, false);
24802            assert!(!java_method.is_null(), "{context} -> ToReflectedMethod returned null");
24803            let meth_cl = self.FindClass("java/lang/reflect/Method");
24804            assert!(!java_method.is_null(), "{context} java/lang/reflect/Method not found???");
24805            let meth_params = self.GetMethodID(meth_cl, "getParameterTypes", "()[Ljava/lang/Class;");
24806            assert!(!meth_params.is_null(), "{context} java/lang/reflect/Method#getParameterTypes not found???");
24807
24808            //CallObjectMethodA
24809            let parameter_array = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, java_method, meth_params, null());
24810            self.DeleteLocalRef(meth_cl);
24811            self.DeleteLocalRef(java_method);
24812            assert!(!parameter_array.is_null(), "{context} java/lang/reflect/Method#getParameterTypes return null???");
24813            let parameter_count = self.GetArrayLength(parameter_array);
24814            assert_eq!(parameter_count, count, "{context} wrong number of method parameters");
24815            let param1_class = self.GetObjectArrayElement(parameter_array, idx);
24816            assert!(!param1_class.is_null(), "{context} java/lang/reflect/Method#getParameterTypes[{idx}] is null???");
24817            self.DeleteLocalRef(parameter_array);
24818
24819            let class_cl = self.FindClass("java/lang/Class");
24820            assert!(!class_cl.is_null(), "{context} java/lang/Class not found???");
24821            let class_name = self.GetMethodID(class_cl, "getName", "()Ljava/lang/String;");
24822            assert!(!class_name.is_null(), "{context} java/lang/Class#getName not found???");
24823            let class_is_primitive = self.GetMethodID(class_cl, "isPrimitive", "()Z");
24824            assert!(!class_is_primitive.is_null(), "{context} java/lang/Class#isPrimitive not found???");
24825
24826            //CallObjectMethodA
24827            let name_str = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, param1_class, class_name, null());
24828            assert!(!name_str.is_null(), "{context} java/lang/Class#getName returned null??? Class has no name???");
24829            //CallBooleanMethodA
24830            let param1_is_primitive =
24831                self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jboolean>(39)(self.vtable, param1_class, class_is_primitive, null());
24832
24833            let the_name = self
24834                .GetStringUTFChars_as_string(name_str)
24835                .unwrap_or_else(|| panic!("{context} failed to get/parse classname???"));
24836            self.DeleteLocalRef(class_cl);
24837            self.DeleteLocalRef(name_str);
24838
24839            match T::jtype_id() {
24840                'Z' => assert_eq!("boolean", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed boolean"),
24841                'B' => assert_eq!("byte", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed byte"),
24842                'S' => assert_eq!("short", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed short"),
24843                'C' => assert_eq!("char", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed char"),
24844                'I' => assert_eq!("int", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed int"),
24845                'J' => assert_eq!("long", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed long"),
24846                'F' => assert_eq!("float", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed float"),
24847                'D' => assert_eq!("double", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed double"),
24848                'L' => {
24849                    assert!(!param1_is_primitive, "{context} param{idx} wrong type. Method has {the_name} but passed an object or null");
24850                    let jt: jtype = param1.into();
24851                    let obj = jt.object;
24852                    if !obj.is_null() {
24853                        assert!(
24854                            self.IsInstanceOf(obj, param1_class),
24855                            "{context} param{idx} wrong type. Method has {the_name} but passed an object that is not null and not instanceof"
24856                        );
24857                    }
24858                }
24859                _ => unreachable!("{}", T::jtype_id()),
24860            }
24861
24862            self.DeleteLocalRef(param1_class);
24863        }
24864    }
24865
24866    /// checks if the method parameter matches the provided argument
24867    #[cfg(feature = "asserts")]
24868    unsafe fn check_parameter_types_object<T: JType>(self, context: &str, obj: jobject, methodID: jmethodID, param1: T, idx: jsize, count: jsize) {
24869        unsafe {
24870            assert!(!obj.is_null(), "{context} obj is null");
24871            self.check_ref_obj(context, obj);
24872            let clazz = self.GetObjectClass(obj);
24873            assert!(!clazz.is_null(), "{context} obj.class is null??");
24874            assert!(!methodID.is_null(), "{context} methodID is null");
24875            let java_method = self.ToReflectedMethod(clazz, methodID, false);
24876            assert!(!java_method.is_null(), "{context} -> ToReflectedMethod returned null");
24877            self.DeleteLocalRef(clazz);
24878            let meth_cl = self.FindClass("java/lang/reflect/Method");
24879            assert!(!java_method.is_null(), "{context} java/lang/reflect/Method not found???");
24880            let meth_params = self.GetMethodID(meth_cl, "getParameterTypes", "()[Ljava/lang/Class;");
24881            assert!(!meth_params.is_null(), "{context} java/lang/reflect/Method#getParameterTypes not found???");
24882
24883            //CallObjectMethodA
24884            let parameter_array = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, java_method, meth_params, null());
24885            self.DeleteLocalRef(meth_cl);
24886            self.DeleteLocalRef(java_method);
24887            assert!(!parameter_array.is_null(), "{context} java/lang/reflect/Method#getParameterTypes return null???");
24888            let parameter_count = self.GetArrayLength(parameter_array);
24889            assert_eq!(parameter_count, count, "{context} wrong number of method parameters");
24890            let param1_class = self.GetObjectArrayElement(parameter_array, idx);
24891            assert!(!param1_class.is_null(), "{context} java/lang/reflect/Method#getParameterTypes[{idx}] is null???");
24892            self.DeleteLocalRef(parameter_array);
24893
24894            let class_cl = self.FindClass("java/lang/Class");
24895            assert!(!class_cl.is_null(), "{context} java/lang/Class not found???");
24896            let class_name = self.GetMethodID(class_cl, "getName", "()Ljava/lang/String;");
24897            assert!(!class_name.is_null(), "{context} java/lang/Class#getName not found???");
24898            let class_is_primitive = self.GetMethodID(class_cl, "isPrimitive", "()Z");
24899            assert!(!class_is_primitive.is_null(), "{context} java/lang/Class#isPrimitive not found???");
24900
24901            //CallObjectMethodA
24902            let name_str = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, param1_class, class_name, null());
24903            assert!(!name_str.is_null(), "{context} java/lang/Class#getName returned null??? Class has no name???");
24904            //CallBooleanMethodA
24905            let param1_is_primitive =
24906                self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jboolean>(39)(self.vtable, param1_class, class_is_primitive, null());
24907
24908            let the_name = self
24909                .GetStringUTFChars_as_string(name_str)
24910                .unwrap_or_else(|| panic!("{context} failed to get/parse classname???"));
24911
24912            self.DeleteLocalRef(class_cl);
24913            self.DeleteLocalRef(name_str);
24914
24915            match T::jtype_id() {
24916                'Z' => assert_eq!("boolean", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed boolean"),
24917                'B' => assert_eq!("byte", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed byte"),
24918                'S' => assert_eq!("short", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed short"),
24919                'C' => assert_eq!("char", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed char"),
24920                'I' => assert_eq!("int", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed int"),
24921                'J' => assert_eq!("long", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed long"),
24922                'F' => assert_eq!("float", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed float"),
24923                'D' => assert_eq!("double", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed double"),
24924                'L' => {
24925                    assert!(!param1_is_primitive, "{context} param{idx} wrong type. Method has {the_name} but passed an object or null");
24926                    let jt: jtype = param1.into();
24927                    let obj = jt.object;
24928                    if !obj.is_null() {
24929                        assert!(
24930                            self.IsInstanceOf(obj, param1_class),
24931                            "{context} param{idx} wrong type. Method has {the_name} but passed an object that is not null and not instanceof"
24932                        );
24933                    }
24934                }
24935                _ => unreachable!("{}", T::jtype_id()),
24936            }
24937
24938            self.DeleteLocalRef(param1_class);
24939        }
24940    }
24941
24942    /// Checks if the function returns an object
24943    #[cfg(feature = "asserts")]
24944    unsafe fn check_return_type_object(self, context: &str, obj: jobject, methodID: jmethodID, ty: &str) {
24945        unsafe {
24946            assert!(!obj.is_null(), "{context} obj is null");
24947            self.check_ref_obj(context, obj);
24948            let clazz = self.GetObjectClass(obj);
24949            assert!(!clazz.is_null(), "{context} obj.class is null??");
24950            assert!(!methodID.is_null(), "{context} methodID is null");
24951            let m = self.ToReflectedMethod(clazz, methodID, false);
24952            self.DeleteLocalRef(clazz);
24953            assert!(!m.is_null(), "{context} -> ToReflectedMethod returned null");
24954            let meth_cl = self.FindClass("java/lang/reflect/Method");
24955            assert!(!m.is_null(), "{context} java/lang/reflect/Method not found???");
24956            let meth_rtyp = self.GetMethodID(meth_cl, "getReturnType", "()Ljava/lang/Class;");
24957            assert!(!meth_rtyp.is_null(), "{context} java/lang/reflect/Method#getReturnType not found???");
24958            //CallObjectMethodA
24959            let rtc = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, m, meth_rtyp, null());
24960            self.DeleteLocalRef(meth_cl);
24961            self.DeleteLocalRef(m);
24962            if rtc.is_null() {
24963                if ty.eq("void") {
24964                    return;
24965                }
24966
24967                panic!("{context} return type of method is void but expected {ty}");
24968            }
24969            let class_cl = self.FindClass("java/lang/Class");
24970            assert!(!class_cl.is_null(), "{context} java/lang/Class not found???");
24971            let class_name = self.GetMethodID(class_cl, "getName", "()Ljava/lang/String;");
24972            assert!(!class_name.is_null(), "{context} java/lang/Class#getName not found???");
24973            //CallObjectMethodA
24974            let name_str = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, rtc, class_name, null());
24975            assert!(!name_str.is_null(), "{context} java/lang/Class#getName returned null??? Class has no name???");
24976            self.DeleteLocalRef(rtc);
24977            let the_name = self
24978                .GetStringUTFChars_as_string(name_str)
24979                .unwrap_or_else(|| panic!("{context} failed to get/parse classname???"));
24980            self.DeleteLocalRef(class_cl);
24981            self.DeleteLocalRef(name_str);
24982            if the_name.as_str().eq(ty) {
24983                return;
24984            }
24985
24986            if ty.eq("object") {
24987                match the_name.as_str() {
24988                    "void" | "long" | "int" | "short" | "byte" | "char" | "float" | "double" | "boolean" => {
24989                        panic!("{context} return type of method is {the_name} but expected object");
24990                    }
24991                    _ => {
24992                        return;
24993                    }
24994                }
24995            }
24996
24997            panic!("{context} return type of method is {the_name} but expected {ty}");
24998        }
24999    }
25000
25001    /// checks if the field type is any object.
25002    #[cfg(feature = "asserts")]
25003    unsafe fn check_field_type_object(self, context: &str, obj: jclass, fieldID: jfieldID, ty: &str) {
25004        unsafe {
25005            assert!(!obj.is_null(), "{context} obj is null");
25006            let clazz = self.GetObjectClass(obj);
25007            assert!(!clazz.is_null(), "{context} obj.class is null??");
25008            assert!(!fieldID.is_null(), "{context} fieldID is null");
25009            let f = self.ToReflectedField(clazz, fieldID, false);
25010            assert!(!f.is_null(), "{context} -> ToReflectedField returned null");
25011            let field_cl = self.FindClass("java/lang/reflect/Field");
25012            assert!(!f.is_null(), "{context} java/lang/reflect/Method not found???");
25013            let field_rtyp = self.GetMethodID(field_cl, "getType", "()Ljava/lang/Class;");
25014            assert!(!field_rtyp.is_null(), "{context} java/lang/reflect/Field#getType not found???");
25015            //CallObjectMethodA
25016            let rtc = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, f, field_rtyp, null());
25017            assert!(!rtc.is_null(), "{context} java/lang/reflect/Field#getType returned null???");
25018            self.DeleteLocalRef(field_cl);
25019            self.DeleteLocalRef(f);
25020            let class_cl = self.FindClass("java/lang/Class");
25021            assert!(!class_cl.is_null(), "{context} java/lang/Class not found???");
25022            let class_name = self.GetMethodID(class_cl, "getName", "()Ljava/lang/String;");
25023            assert!(!class_name.is_null(), "{context} java/lang/Class#getName not found???");
25024            //CallObjectMethodA
25025            let name_str = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, rtc, class_name, null());
25026            assert!(!name_str.is_null(), "{context} java/lang/Class#getName returned null??? Class has no name???");
25027            self.DeleteLocalRef(rtc);
25028            let the_name = self
25029                .GetStringUTFChars_as_string(name_str)
25030                .unwrap_or_else(|| panic!("{context} failed to get/parse classname???"));
25031            self.DeleteLocalRef(class_cl);
25032            self.DeleteLocalRef(name_str);
25033            if the_name.as_str().eq(ty) {
25034                return;
25035            }
25036
25037            if ty.eq("object") {
25038                match the_name.as_str() {
25039                    "long" | "int" | "short" | "byte" | "char" | "float" | "double" | "boolean" => {
25040                        panic!("{context} type of field is {the_name} but expected object");
25041                    }
25042                    _ => {
25043                        return;
25044                    }
25045                }
25046            }
25047
25048            panic!("{context} type of field is {the_name} but expected {ty}");
25049        }
25050    }
25051}
25052
25053impl JavaVM {
25054    /// Helper fn to assist with casting of the internal vtable
25055    /// # Safety
25056    /// This fn is only safe if X matches whats in the vtable of index.
25057    #[inline]
25058    unsafe fn ivk<X>(&self, index: usize) -> X {
25059        unsafe { core::mem::transmute_copy(&(self.vtable.inner().read_volatile().add(index).read_volatile())) }
25060    }
25061
25062    ///
25063    /// Attaches the current thread to the JVM as a normal thread.
25064    /// If a thread name is provided then it will be used as the java name of the current thread.
25065    ///
25066    /// # Errors
25067    /// JNI implementation specific error constants like `JNI_EINVAL`
25068    ///
25069    /// # Safety
25070    /// This fn must not be called on a `JavaVM` object that has been destroyed or is in the process of being destroyed.
25071    ///
25072    pub unsafe fn AttachCurrentThread_str(&self, version: jint, thread_name: impl UseCString, thread_group: jobject) -> Result<JNIEnv, jint> {
25073        unsafe {
25074            thread_name.use_as_const_c_char(|thread_name| {
25075                let mut args = JavaVMAttachArgs::new(version, thread_name, thread_group);
25076                self.AttachCurrentThread(&raw mut args)
25077            })
25078        }
25079    }
25080
25081    ///
25082    /// Attaches the current thread to the JVM as a normal thread.
25083    /// If a thread name is provided then it will be used as the java name of the current thread.
25084    ///
25085    /// # Errors
25086    /// JNI implementation specific error constants like `JNI_EINVAL`
25087    ///
25088    /// # Panics
25089    /// If the JVM does not return an error but also does not set the `JNIEnv` ptr.
25090    ///
25091    /// # Safety
25092    /// This fn must not be called on a `JavaVM` object that has been destroyed or is in the process of being destroyed.
25093    ///
25094    pub unsafe fn AttachCurrentThread(&self, args: *mut JavaVMAttachArgs) -> Result<JNIEnv, jint> {
25095        unsafe {
25096            #[cfg(feature = "asserts")]
25097            {
25098                assert!(!args.is_null(), "AttachCurrentThread args must not be null");
25099            }
25100
25101            let mut envptr: JNIEnvVTable = null_mut();
25102
25103            let result = self.ivk::<extern "system" fn(JNIInvPtr, *mut JNIEnvVTable, *mut JavaVMAttachArgs) -> jint>(4)(self.vtable, &raw mut envptr, args);
25104            if result != JNI_OK {
25105                return Err(result);
25106            }
25107
25108            #[cfg(feature = "asserts")]
25109            {
25110                let jni_version = (*args).version;
25111                assert!(
25112                    jni_version & 0x3000_0000 != 0x3000_0000,
25113                    "AttachCurrentThread called with jni version 0x{jni_version:X} which should cause an error in the JVM but it did not. Using the resulting vtable is likely ub."
25114                );
25115            }
25116
25117            assert!(!envptr.is_null(), "AttachCurrentThread returned JNI_OK but did not set the JNIEnv pointer!");
25118
25119            Ok(JNIEnv { vtable: envptr })
25120        }
25121    }
25122
25123    ///
25124    /// Attaches the current thread to the JVM as a daemon thread.
25125    /// If a thread name is provided then it will be used as the java name of the current thread.
25126    ///
25127    /// # Errors
25128    /// JNI implementation specific error constants like `JNI_EINVAL`
25129    ///
25130    /// # Safety
25131    /// This fn must not be called on a `JavaVM` object that has been destroyed or is in the process of being destroyed.
25132    ///
25133    pub unsafe fn AttachCurrentThreadAsDaemon_str(&self, version: jint, thread_name: impl UseCString, thread_group: jobject) -> Result<JNIEnv, jint> {
25134        unsafe {
25135            thread_name.use_as_const_c_char(|thread_name| {
25136                let mut args = JavaVMAttachArgs::new(version, thread_name, thread_group);
25137                self.AttachCurrentThreadAsDaemon(&raw mut args)
25138            })
25139        }
25140    }
25141
25142    ///
25143    /// Attaches the current thread to the JVM as a daemon thread.
25144    /// If a thread name is provided then it will be used as the java name of the current thread.
25145    ///
25146    /// # Errors
25147    /// JNI implementation specific error constants like `JNI_EINVAL`
25148    ///
25149    /// # Panics
25150    /// If the JVM does not return an error but also does not set the `JNIEnv` ptr.
25151    ///
25152    /// # Safety
25153    /// This fn must not be called on a `JavaVM` object that has been destroyed or is in the process of being destroyed.
25154    ///
25155    pub unsafe fn AttachCurrentThreadAsDaemon(&self, args: *mut JavaVMAttachArgs) -> Result<JNIEnv, jint> {
25156        unsafe {
25157            #[cfg(feature = "asserts")]
25158            {
25159                assert!(!args.is_null(), "AttachCurrentThreadAsDaemon args must not be null");
25160            }
25161            let mut envptr: JNIEnvVTable = null_mut();
25162
25163            let result = self.ivk::<extern "system" fn(JNIInvPtr, *mut JNIEnvVTable, *mut JavaVMAttachArgs) -> jint>(7)(self.vtable, &raw mut envptr, args);
25164
25165            if result != JNI_OK {
25166                return Err(result);
25167            }
25168
25169            assert!(!envptr.is_null(), "AttachCurrentThreadAsDaemon returned JNI_OK but did not set the JNIEnv pointer!");
25170
25171            Ok(JNIEnv { vtable: envptr })
25172        }
25173    }
25174
25175    ///
25176    /// Gets the `JNIEnv` for the current thread.
25177    ///
25178    /// Concerning the generic type `T`. This type must refer to the correct function table for the given `jni_version`:
25179    /// - For ordinary `jni_version` values `T` must be `JNIEnv`.
25180    /// - For jvmti `jni_version` values `T` must be `JVMTIEnv`.
25181    /// - `*mut c_void` is also always a valid type for `T` regardless of the value of `jni_version`!
25182    /// - using `*mut c_void` will return the raw function table.
25183    ///
25184    /// Using the wrong type for `T` is undefined behavior!
25185    /// There is no way to check this as jvmti and jni function tables are completely different!
25186    ///
25187    ///
25188    /// # Safety
25189    /// This fn must not be called on a `JavaVM` object that has been destroyed or is in the process of being destroyed.
25190    /// # Panics
25191    /// If the JVM does not return an error but also does not set the `JNIEnv` ptr.
25192    ///
25193    /// If the asserts feature is enabled and the implementation can detect that `T` is not correct.
25194    /// This is only provided on a best effort basis.
25195    ///
25196    /// # Errors
25197    /// JNI implementation specific error constants like `JNI_EINVAL`
25198    /// # Undefined behavior
25199    /// Using the wrong type `T` for the given `jni_version`. I.e. using `JNIEnv` for `JVMTI` or `JVMTIEnv` for `JNI`.
25200    /// # Example
25201    /// ```rust
25202    /// use std::ffi::c_void;
25203    /// use jni_simple::{JNIEnv, JVMTIEnv, JavaVM, JNI_VERSION_1_8, JVMTI_VERSION_21};
25204    ///
25205    /// unsafe fn some_func(vm: &JavaVM) {
25206    ///     //for 99% use cases this is what you want!
25207    ///     let jni = vm.GetEnv::<JNIEnv>(JNI_VERSION_1_8).expect("Error");
25208    ///
25209    ///     let jni_raw = vm.GetEnv::<*mut c_void>(JNI_VERSION_1_8).expect("Error");
25210    ///     let jvmti = vm.GetEnv::<JVMTIEnv>(JVMTI_VERSION_21).expect("Error");
25211    ///     let jni_raw = vm.GetEnv::<*mut c_void>(JVMTI_VERSION_21).expect("Error");
25212    /// }
25213    /// ```
25214    ///
25215    pub unsafe fn GetEnv<T: SealedEnvVTable>(&self, jni_version: jint) -> Result<T, jint> {
25216        unsafe {
25217            let mut envptr: *mut c_void = null_mut();
25218            #[cfg(feature = "asserts")]
25219            {
25220                assert!(
25221                    jni_version & 0x3000_0000 != 0x3000_0000 || T::can_jvmti(),
25222                    "type parameter T cannot receive a JVMTI function VTable but jni_version 0x{jni_version:X} would likely request one. Using the resulting VTable would be UB."
25223                );
25224
25225                assert!(
25226                    jni_version & 0x3000_0000 != 0x0000_0000 || T::can_jni(),
25227                    "type parameter T cannot receive a JNI function VTable but jni_version 0x{jni_version:X} would likely request one. Using the resulting VTable would be UB."
25228                );
25229            }
25230
25231            let result = self.ivk::<extern "system" fn(JNIInvPtr, *mut *mut c_void, jint) -> jint>(6)(self.vtable, &raw mut envptr, jni_version);
25232
25233            if result != JNI_OK {
25234                return Err(result);
25235            }
25236
25237            assert!(!envptr.is_null(), "GetEnv returned JNI_OK but did not set the JNIEnv pointer!");
25238
25239            Ok(T::from(envptr))
25240        }
25241    }
25242
25243    ///
25244    /// Detaches the current thread from the jvm.
25245    /// This should only be called on functions that were attached with `AttachCurrentThread` or `AttachCurrentThreadAsDaemon`.
25246    ///
25247    /// # Safety
25248    /// Detaches the current thread. The `JNIEnv` of the current thread is no longer valid after this call.
25249    /// Any further calls made using it will result in undefined behavior.
25250    ///
25251    #[must_use]
25252    pub unsafe fn DetachCurrentThread(&self) -> jint {
25253        unsafe { self.ivk::<extern "system" fn(JNIInvPtr) -> jint>(5)(self.vtable) }
25254    }
25255
25256    ///
25257    /// This function will block until all java threads have completed and then destroy the JVM.
25258    /// It should not be called from a method that is called from the JVM.
25259    ///
25260    /// # Safety
25261    /// Careful consideration should be taken when this fn is called. As mentioned calling it from
25262    /// a JVM Thread will probably just block the calling thread forever. However, this fn also
25263    /// does stuff internally with the jvm, after/during its return the JVM can no longer be used in
25264    /// any thread. Any existing `JavaVM` object will become invalid. Attempts to obtain a `JNIEnv` after
25265    /// this fn returns by way of calling `AttachThread` will likely lead to undefined behavior.
25266    /// Shutting down a JVM is a "terminal" operation for any Hotspot implementation of the JVM.
25267    /// The current process will never be able to relaunch a hotspot JVM.
25268    ///
25269    /// This fn should therefore only be used if a rust thread needs to "wait" until the JVM is dead to then perform
25270    /// some operations such a cleanup before eventually calling `exit()`
25271    ///
25272    /// Please note that this fn never returns if the `JavaVM` terminates abnormally (e.g. due to a crash),
25273    /// or someone calling Runtime.getRuntime().halt(...) in Java, because that just terminates the Process instantly.
25274    /// Its usefulness to run shutdown code is therefore limited.
25275    ///
25276    ///
25277    pub unsafe fn DestroyJavaVM(&self) {
25278        unsafe {
25279            self.ivk::<extern "system" fn(JNIInvPtr) -> ()>(3)(self.vtable);
25280        }
25281    }
25282}
25283
25284#[cfg(test)]
25285#[test]
25286const fn test_sync() {
25287    static_assertions::assert_impl_all!(JavaVM: Sync);
25288    static_assertions::assert_impl_all!(JavaVM: Send);
25289
25290    static_assertions::assert_impl_all!(jniNativeInterface: Sync);
25291    static_assertions::assert_impl_all!(jniNativeInterface: Send);
25292
25293    static_assertions::assert_not_impl_all!(JNIEnv: Sync);
25294    static_assertions::assert_not_impl_all!(JNIEnv: Send);
25295
25296    static_assertions::assert_impl_all!(JVMTIEnv: Sync);
25297    static_assertions::assert_impl_all!(JVMTIEnv: Send);
25298}
25299
25300#[cfg(doctest)]
25301#[doc = include_str!("../README.md")]
25302struct ReadmeDocTests;