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
37extern crate alloc;
38#[cfg(feature = "std")]
39extern crate std;
40
41use alloc::borrow::Cow;
42use alloc::ffi::CString;
43use alloc::string::String;
44use alloc::string::ToString;
45use alloc::vec;
46use alloc::vec::Vec;
47
48use crate::private::{SealedAsJNILinkage, SealedEnvVTable};
49use core::cmp::Ordering;
50use core::ffi::{CStr, c_char, c_int, c_uchar, c_void};
51use core::fmt::{Debug, Display, Formatter};
52use core::hash::{Hash, Hasher};
53use core::ptr::null;
54use core::ptr::null_mut;
55#[cfg(feature = "loadjvm")]
56use std::path::PathBuf;
57#[cfg(not(feature = "dynlink"))]
58use sync_ptr::{FromConstPtr, SyncConstPtr};
59use sync_ptr::{FromMutPtr, SyncMutPtr};
60
61pub const JNI_TRUE: jboolean = true;
62pub const JNI_FALSE: jboolean = false;
63
64pub const JNI_OK: jint = 0;
65
66pub const JNI_COMMIT: jint = 1;
67
68pub const JNI_ABORT: jint = 2;
69pub const JNI_ERR: jint = -1;
70pub const JNI_EDETACHED: jint = -2;
71pub const JNI_EVERSION: jint = -3;
72pub const JNI_ENOMEM: jint = -4;
73pub const JNI_EEXIST: jint = -5;
74pub const JNI_EINVAL: jint = -6;
75pub const JVMTI_VERSION_1: jint = 0x3001_0000;
76pub const JVMTI_VERSION_1_0: jint = 0x3001_0000;
77pub const JVMTI_VERSION_1_1: jint = 0x3001_0100;
78pub const JVMTI_VERSION_1_2: jint = 0x3001_0200;
79
80pub const JVMTI_VERSION_9: jint = 0x3009_0000;
81pub const JVMTI_VERSION_11: jint = 0x300B_0000;
82pub const JVMTI_VERSION_19: jint = 0x3013_0000;
83pub const JVMTI_VERSION_21: jint = 0x3015_0000;
84
85pub const JNI_VERSION_1_1: jint = 0x0001_0001;
86pub const JNI_VERSION_1_2: jint = 0x0001_0002;
87pub const JNI_VERSION_1_4: jint = 0x0001_0004;
88pub const JNI_VERSION_1_6: jint = 0x0001_0006;
89pub const JNI_VERSION_1_8: jint = 0x0001_0008;
90pub const JNI_VERSION_9: jint = 0x0009_0000;
91pub const JNI_VERSION_10: jint = 0x000a_0000;
92pub const JNI_VERSION_19: jint = 0x0013_0000;
93pub const JNI_VERSION_20: jint = 0x0014_0000;
94pub const JNI_VERSION_21: jint = 0x0015_0000;
95
96pub const JNI_VERSION_24: jint = 0x0018_0000;
97
98pub type jlong = i64;
99
100pub type jlocation = jlong;
101
102pub type jint = i32;
103pub type jsize = jint;
104pub type jshort = i16;
105pub type jchar = u16;
106pub type jbyte = i8;
107pub type jboolean = bool;
108
109pub type jfloat = core::ffi::c_float;
110
111pub type jdouble = core::ffi::c_double;
112
113pub type jclass = *mut c_void;
114
115pub type jobject = *mut c_void;
116
117pub type jstring = jobject;
118
119pub type jarray = jobject;
120
121pub type jobjectArray = jarray;
122
123pub type jbooleanArray = jarray;
124
125pub type jbyteArray = jarray;
126
127pub type jcharArray = jarray;
128
129pub type jshortArray = jarray;
130
131pub type jintArray = jarray;
132
133pub type jlongArray = jarray;
134
135pub type jfloatArray = jarray;
136
137pub type jdoubleArray = jarray;
138
139#[repr(C)]
140#[derive(Debug, Ord, Eq, PartialOrd, PartialEq, Hash, Clone, Copy)]
141pub enum jobjectRefType {
142    JNIInvalidRefType = 0,
143    JNILocalRefType = 1,
144    JNIGlobalRefType = 2,
145    JNIWeakGlobalRefType = 3,
146}
147
148/// Rust enum that mirrors jvmtiError, however it has a different repr to `c_int` causing it to be incompatible outside of rust code.
149///
150/// It is mainly useful to use in rusts match statements.
151///
152/// This enum can be transformed from the repr(C) jvmtiError or transformed into it via the From/Into traits.
153#[derive(Debug, Eq, Clone, Copy)]
154pub enum JvmtiError {
155    NONE,
156    INVALID_THREAD,
157    INVALID_THREAD_GROUP,
158    INVALID_PRIORITY,
159    THREAD_NOT_SUSPENDED,
160    THREAD_SUSPENDED,
161    THREAD_NOT_ALIVE,
162    INVALID_OBJECT,
163    INVALID_CLASS,
164    CLASS_NOT_PREPARED,
165    INVALID_METHODID,
166    INVALID_LOCATION,
167    INVALID_FIELDID,
168    INVALID_MODULE,
169    NO_MORE_FRAMES,
170    OPAQUE_FRAME,
171    TYPE_MISMATCH,
172    INVALID_SLOT,
173    DUPLICATE,
174    NOT_FOUND,
175    INVALID_MONITOR,
176    NOT_MONITOR_OWNER,
177    INTERRUPT,
178    INVALID_CLASS_FORMAT,
179    CIRCULAR_CLASS_DEFINITION,
180    FAILS_VERIFICATION,
181    UNSUPPORTED_REDEFINITION_METHOD_ADDED,
182    UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED,
183    INVALID_TYPESTATE,
184    UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED,
185    UNSUPPORTED_REDEFINITION_METHOD_DELETED,
186    UNSUPPORTED_VERSION,
187    NAMES_DONT_MATCH,
188    UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED,
189    UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED,
190    UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED,
191    UNSUPPORTED_OPERATION,
192    UNMODIFIABLE_CLASS,
193    UNMODIFIABLE_MODULE,
194    NOT_AVAILABLE,
195    MUST_POSSESS_CAPABILITY,
196    NULL_POINTER,
197    ABSENT_INFORMATION,
198    INVALID_EVENT_TYPE,
199    ILLEGAL_ARGUMENT,
200    NATIVE_METHOD,
201    CLASS_LOADER_UNSUPPORTED,
202    OUT_OF_MEMORY,
203    ACCESS_DENIED,
204    WRONG_PHASE,
205    INTERNAL,
206    UNATTACHED_THREAD,
207    INVALID_ENVIRONMENT,
208    OTHER(c_int),
209}
210
211impl Display for JvmtiError {
212    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
213        //Unwind the other case and fold it into known codes.
214        let me: c_int = (*self).into();
215        let reform = Self::from(me);
216        //Debug fmt it.
217        Debug::fmt(&reform, f)
218    }
219}
220
221//we have to implement this because the OTHER case may shadow an actual error code.
222impl PartialEq for JvmtiError {
223    fn eq(&self, other: &Self) -> bool {
224        let me: c_int = (*self).into();
225        let other: c_int = (*other).into();
226        me == other
227    }
228}
229
230//we have to implement this because the OTHER case may shadow an actual error code.
231impl Ord for JvmtiError {
232    fn cmp(&self, other: &Self) -> Ordering {
233        let me: c_int = (*self).into();
234        let other: c_int = (*other).into();
235        c_int::cmp(&me, &other)
236    }
237}
238
239impl PartialOrd for JvmtiError {
240    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
241        Some(self.cmp(other))
242    }
243}
244
245//we have to implement this because the OTHER case may shadow an actual error code.
246impl Hash for JvmtiError {
247    fn hash<H: Hasher>(&self, state: &mut H) {
248        let me: c_int = (*self).into();
249        state.write_i64(i64::from(me));
250    }
251}
252
253impl From<c_int> for JvmtiError {
254    fn from(value: c_int) -> Self {
255        match value {
256            0 => Self::NONE,
257            10 => Self::INVALID_THREAD,
258            11 => Self::INVALID_THREAD_GROUP,
259            12 => Self::INVALID_PRIORITY,
260            13 => Self::THREAD_NOT_SUSPENDED,
261            14 => Self::THREAD_SUSPENDED,
262            15 => Self::THREAD_NOT_ALIVE,
263            20 => Self::INVALID_OBJECT,
264            21 => Self::INVALID_CLASS,
265            22 => Self::CLASS_NOT_PREPARED,
266            23 => Self::INVALID_METHODID,
267            24 => Self::INVALID_LOCATION,
268            25 => Self::INVALID_FIELDID,
269            26 => Self::INVALID_MODULE,
270            31 => Self::NO_MORE_FRAMES,
271            32 => Self::OPAQUE_FRAME,
272            34 => Self::TYPE_MISMATCH,
273            35 => Self::INVALID_SLOT,
274            40 => Self::DUPLICATE,
275            41 => Self::NOT_FOUND,
276            50 => Self::INVALID_MONITOR,
277            51 => Self::NOT_MONITOR_OWNER,
278            52 => Self::INTERRUPT,
279            60 => Self::INVALID_CLASS_FORMAT,
280            61 => Self::CIRCULAR_CLASS_DEFINITION,
281            62 => Self::FAILS_VERIFICATION,
282            63 => Self::UNSUPPORTED_REDEFINITION_METHOD_ADDED,
283            64 => Self::UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED,
284            65 => Self::INVALID_TYPESTATE,
285            66 => Self::UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED,
286            67 => Self::UNSUPPORTED_REDEFINITION_METHOD_DELETED,
287            68 => Self::UNSUPPORTED_VERSION,
288            69 => Self::NAMES_DONT_MATCH,
289            70 => Self::UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED,
290            71 => Self::UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED,
291            72 => Self::UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED,
292            73 => Self::UNSUPPORTED_OPERATION,
293            79 => Self::UNMODIFIABLE_CLASS,
294            80 => Self::UNMODIFIABLE_MODULE,
295            98 => Self::NOT_AVAILABLE,
296            99 => Self::MUST_POSSESS_CAPABILITY,
297            100 => Self::NULL_POINTER,
298            101 => Self::ABSENT_INFORMATION,
299            102 => Self::INVALID_EVENT_TYPE,
300            103 => Self::ILLEGAL_ARGUMENT,
301            104 => Self::NATIVE_METHOD,
302            106 => Self::CLASS_LOADER_UNSUPPORTED,
303            110 => Self::OUT_OF_MEMORY,
304            111 => Self::ACCESS_DENIED,
305            112 => Self::WRONG_PHASE,
306            113 => Self::INTERNAL,
307            115 => Self::UNATTACHED_THREAD,
308            116 => Self::INVALID_ENVIRONMENT,
309            other => Self::OTHER(other),
310        }
311    }
312}
313
314impl From<JvmtiError> for c_int {
315    fn from(value: JvmtiError) -> Self {
316        match value {
317            JvmtiError::NONE => 0,
318            JvmtiError::INVALID_THREAD => 10,
319            JvmtiError::INVALID_THREAD_GROUP => 11,
320            JvmtiError::INVALID_PRIORITY => 12,
321            JvmtiError::THREAD_NOT_SUSPENDED => 13,
322            JvmtiError::THREAD_SUSPENDED => 14,
323            JvmtiError::THREAD_NOT_ALIVE => 15,
324            JvmtiError::INVALID_OBJECT => 20,
325            JvmtiError::INVALID_CLASS => 21,
326            JvmtiError::CLASS_NOT_PREPARED => 22,
327            JvmtiError::INVALID_METHODID => 23,
328            JvmtiError::INVALID_LOCATION => 24,
329            JvmtiError::INVALID_FIELDID => 25,
330            JvmtiError::INVALID_MODULE => 26,
331            JvmtiError::NO_MORE_FRAMES => 31,
332            JvmtiError::OPAQUE_FRAME => 32,
333            JvmtiError::TYPE_MISMATCH => 34,
334            JvmtiError::INVALID_SLOT => 35,
335            JvmtiError::DUPLICATE => 40,
336            JvmtiError::NOT_FOUND => 41,
337            JvmtiError::INVALID_MONITOR => 50,
338            JvmtiError::NOT_MONITOR_OWNER => 51,
339            JvmtiError::INTERRUPT => 52,
340            JvmtiError::INVALID_CLASS_FORMAT => 60,
341            JvmtiError::CIRCULAR_CLASS_DEFINITION => 61,
342            JvmtiError::FAILS_VERIFICATION => 62,
343            JvmtiError::UNSUPPORTED_REDEFINITION_METHOD_ADDED => 63,
344            JvmtiError::UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED => 64,
345            JvmtiError::INVALID_TYPESTATE => 65,
346            JvmtiError::UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED => 66,
347            JvmtiError::UNSUPPORTED_REDEFINITION_METHOD_DELETED => 67,
348            JvmtiError::UNSUPPORTED_VERSION => 68,
349            JvmtiError::NAMES_DONT_MATCH => 69,
350            JvmtiError::UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED => 70,
351            JvmtiError::UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED => 71,
352            JvmtiError::UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED => 72,
353            JvmtiError::UNSUPPORTED_OPERATION => 73,
354            JvmtiError::UNMODIFIABLE_CLASS => 79,
355            JvmtiError::UNMODIFIABLE_MODULE => 80,
356            JvmtiError::NOT_AVAILABLE => 98,
357            JvmtiError::MUST_POSSESS_CAPABILITY => 99,
358            JvmtiError::NULL_POINTER => 100,
359            JvmtiError::ABSENT_INFORMATION => 101,
360            JvmtiError::INVALID_EVENT_TYPE => 102,
361            JvmtiError::ILLEGAL_ARGUMENT => 103,
362            JvmtiError::NATIVE_METHOD => 104,
363            JvmtiError::CLASS_LOADER_UNSUPPORTED => 106,
364            JvmtiError::OUT_OF_MEMORY => 110,
365            JvmtiError::ACCESS_DENIED => 111,
366            JvmtiError::WRONG_PHASE => 112,
367            JvmtiError::INTERNAL => 113,
368            JvmtiError::UNATTACHED_THREAD => 115,
369            JvmtiError::INVALID_ENVIRONMENT => 116,
370            JvmtiError::OTHER(value) => value,
371        }
372    }
373}
374
375impl JvmtiError {
376    /// Returns true if this `JvmtiError` refers to `JVMTI_ERROR_NONE`
377    #[must_use]
378    pub const fn is_ok(&self) -> bool {
379        matches!(self, Self::NONE)
380    }
381
382    /// Returns true if this `JvmtiError` does not refer to `JVMTI_ERROR_NONE`
383    #[must_use]
384    pub const fn is_err(&self) -> bool {
385        !self.is_ok()
386    }
387}
388
389//We cannot turn this into an enum because the JVM may with a reasonable likelihood decide to add new codes in the future.
390//If we enum this and the VM returned a code we don't know it would instantly be UB.
391#[repr(transparent)]
392#[derive(Debug, Ord, Eq, PartialOrd, PartialEq, Hash, Clone, Copy)]
393#[must_use]
394pub struct jvmtiError(pub c_int);
395
396impl Display for jvmtiError {
397    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
398        Debug::fmt(self, f)
399    }
400}
401
402impl From<c_int> for jvmtiError {
403    fn from(value: c_int) -> Self {
404        Self(value)
405    }
406}
407
408impl From<jvmtiError> for c_int {
409    fn from(value: jvmtiError) -> Self {
410        value.0
411    }
412}
413
414impl From<JvmtiError> for jvmtiError {
415    fn from(value: JvmtiError) -> Self {
416        let me: c_int = value.into();
417        me.into()
418    }
419}
420
421impl From<jvmtiError> for JvmtiError {
422    fn from(value: jvmtiError) -> Self {
423        let me: c_int = value.into();
424        me.into()
425    }
426}
427
428impl jvmtiError {
429    #[must_use]
430    pub fn is_ok(self) -> bool {
431        self == JVMTI_ERROR_NONE
432    }
433
434    #[must_use]
435    pub fn is_err(self) -> bool {
436        self != JVMTI_ERROR_NONE
437    }
438
439    /// This function transforms the jvmtiError into a Result if the jvmtiError is not `JVMTI_ERROR_NONE`.
440    /// Its useful if you want to use the "if let" pattern.
441    ///
442    /// # Errors
443    /// if jvmtiError is not equal to `JVMTI_ERROR_NONE`
444    ///
445    /// # Example
446    /// ```rust
447    /// use jni_simple::{jint, JVMTIEnv, JVMTI_VERSION_21};
448    ///
449    /// fn check_version21(env: JVMTIEnv) {
450    ///     unsafe {
451    ///         let mut version: jint = 0;
452    ///         if let Err(err) = env.GetVersionNumber(&mut version).into_result() {
453    ///             //Handle failed jvmti call
454    ///             //You can also match on err here if you want.
455    ///             panic!("GetVersionNumber call failed with err={err}")
456    ///         }
457    ///
458    ///         //Handle successful jvmti call
459    ///         if version != JVMTI_VERSION_21 {
460    ///             panic!("JVMTI Version is not 21");
461    ///         }
462    ///     }
463    /// }
464    ///
465    /// ```
466    ///
467    pub fn into_result(self) -> Result<(), JvmtiError> {
468        if self == JVMTI_ERROR_NONE {
469            return Ok(());
470        }
471
472        Err(self.into())
473    }
474
475    /// This function transforms the jvmtiError into a rust enum that you can easily match on.
476    ///
477    /// # Example
478    /// ```rust
479    /// use jni_simple::{jint, JVMTIEnv, JvmtiError, JVMTI_VERSION_21};
480    ///
481    /// fn check_version21(env: JVMTIEnv) {
482    ///     unsafe {
483    ///         let mut version: jint = 0;
484    ///         match env.GetVersionNumber(&mut version).into_enum() {
485    ///             JvmtiError::NONE => {
486    ///              //Handle successful jvmti call
487    ///              if version != JVMTI_VERSION_21 {
488    ///                  panic!("JVMTI Version is not 21");
489    ///              }
490    ///             }
491    ///             err => {
492    ///                  panic!("GetVersionNumber call failed with err={err}")
493    ///             }
494    ///         }
495    ///     }
496    /// }
497    ///
498    /// ```
499    ///
500    #[must_use]
501    pub fn into_enum(self) -> JvmtiError {
502        self.into()
503    }
504
505    /// This function transforms the jvmtiError back into its raw magic number from the jvm.
506    /// This is useful if you deal with undocumented errors from customized jvm's.
507    ///
508    /// # Example
509    /// ```rust
510    /// use std::ffi::c_int;
511    /// use jni_simple::{jint, JVMTIEnv, JvmtiError, JVMTI_VERSION_21};
512    ///
513    /// fn check_version21(env: JVMTIEnv) {
514    ///     unsafe {
515    ///         let mut version: jint = 0;
516    ///         let raw_err : c_int = env.GetVersionNumber(&mut version).into_raw();
517    ///         match raw_err {
518    ///             0 => {
519    ///              //Handle successful jvmti call
520    ///              if version != JVMTI_VERSION_21 {
521    ///                  panic!("JVMTI Version is not 21");
522    ///              }
523    ///             }
524    ///             err => {
525    ///                  panic!("GetVersionNumber call failed with magic number err={err}")
526    ///             }
527    ///         }
528    ///     }
529    /// }
530    ///
531    /// ```
532    ///
533    #[must_use]
534    pub const fn into_raw(self) -> c_int {
535        self.0
536    }
537}
538
539pub const JVMTI_ERROR_NONE: jvmtiError = jvmtiError(0);
540pub const JVMTI_ERROR_INVALID_THREAD: jvmtiError = jvmtiError(10);
541pub const JVMTI_ERROR_INVALID_THREAD_GROUP: jvmtiError = jvmtiError(11);
542pub const JVMTI_ERROR_INVALID_PRIORITY: jvmtiError = jvmtiError(12);
543pub const JVMTI_ERROR_THREAD_NOT_SUSPENDED: jvmtiError = jvmtiError(13);
544pub const JVMTI_ERROR_THREAD_SUSPENDED: jvmtiError = jvmtiError(14);
545pub const JVMTI_ERROR_THREAD_NOT_ALIVE: jvmtiError = jvmtiError(15);
546pub const JVMTI_ERROR_INVALID_OBJECT: jvmtiError = jvmtiError(20);
547pub const JVMTI_ERROR_INVALID_CLASS: jvmtiError = jvmtiError(21);
548pub const JVMTI_ERROR_CLASS_NOT_PREPARED: jvmtiError = jvmtiError(22);
549pub const JVMTI_ERROR_INVALID_METHODID: jvmtiError = jvmtiError(23);
550pub const JVMTI_ERROR_INVALID_LOCATION: jvmtiError = jvmtiError(24);
551pub const JVMTI_ERROR_INVALID_FIELDID: jvmtiError = jvmtiError(25);
552pub const JVMTI_ERROR_INVALID_MODULE: jvmtiError = jvmtiError(26);
553pub const JVMTI_ERROR_NO_MORE_FRAMES: jvmtiError = jvmtiError(31);
554pub const JVMTI_ERROR_OPAQUE_FRAME: jvmtiError = jvmtiError(32);
555pub const JVMTI_ERROR_TYPE_MISMATCH: jvmtiError = jvmtiError(34);
556pub const JVMTI_ERROR_INVALID_SLOT: jvmtiError = jvmtiError(35);
557pub const JVMTI_ERROR_DUPLICATE: jvmtiError = jvmtiError(40);
558pub const JVMTI_ERROR_NOT_FOUND: jvmtiError = jvmtiError(41);
559pub const JVMTI_ERROR_INVALID_MONITOR: jvmtiError = jvmtiError(50);
560pub const JVMTI_ERROR_NOT_MONITOR_OWNER: jvmtiError = jvmtiError(51);
561pub const JVMTI_ERROR_INTERRUPT: jvmtiError = jvmtiError(52);
562pub const JVMTI_ERROR_INVALID_CLASS_FORMAT: jvmtiError = jvmtiError(60);
563pub const JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION: jvmtiError = jvmtiError(61);
564pub const JVMTI_ERROR_FAILS_VERIFICATION: jvmtiError = jvmtiError(62);
565pub const JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED: jvmtiError = jvmtiError(63);
566pub const JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED: jvmtiError = jvmtiError(64);
567pub const JVMTI_ERROR_INVALID_TYPESTATE: jvmtiError = jvmtiError(65);
568pub const JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED: jvmtiError = jvmtiError(66);
569pub const JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED: jvmtiError = jvmtiError(67);
570pub const JVMTI_ERROR_UNSUPPORTED_VERSION: jvmtiError = jvmtiError(68);
571pub const JVMTI_ERROR_NAMES_DONT_MATCH: jvmtiError = jvmtiError(69);
572pub const JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED: jvmtiError = jvmtiError(70);
573pub const JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED: jvmtiError = jvmtiError(71);
574pub const JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED: jvmtiError = jvmtiError(72);
575pub const JVMTI_ERROR_UNSUPPORTED_OPERATION: jvmtiError = jvmtiError(73);
576pub const JVMTI_ERROR_UNMODIFIABLE_CLASS: jvmtiError = jvmtiError(79);
577pub const JVMTI_ERROR_UNMODIFIABLE_MODULE: jvmtiError = jvmtiError(80);
578pub const JVMTI_ERROR_NOT_AVAILABLE: jvmtiError = jvmtiError(98);
579pub const JVMTI_ERROR_MUST_POSSESS_CAPABILITY: jvmtiError = jvmtiError(99);
580pub const JVMTI_ERROR_NULL_POINTER: jvmtiError = jvmtiError(100);
581pub const JVMTI_ERROR_ABSENT_INFORMATION: jvmtiError = jvmtiError(101);
582pub const JVMTI_ERROR_INVALID_EVENT_TYPE: jvmtiError = jvmtiError(102);
583pub const JVMTI_ERROR_ILLEGAL_ARGUMENT: jvmtiError = jvmtiError(103);
584pub const JVMTI_ERROR_NATIVE_METHOD: jvmtiError = jvmtiError(104);
585pub const JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED: jvmtiError = jvmtiError(106);
586pub const JVMTI_ERROR_OUT_OF_MEMORY: jvmtiError = jvmtiError(110);
587pub const JVMTI_ERROR_ACCESS_DENIED: jvmtiError = jvmtiError(111);
588pub const JVMTI_ERROR_WRONG_PHASE: jvmtiError = jvmtiError(112);
589pub const JVMTI_ERROR_INTERNAL: jvmtiError = jvmtiError(113);
590pub const JVMTI_ERROR_UNATTACHED_THREAD: jvmtiError = jvmtiError(115);
591pub const JVMTI_ERROR_INVALID_ENVIRONMENT: jvmtiError = jvmtiError(116);
592pub const JVMTI_ERROR_MAX: jvmtiError = jvmtiError(116);
593
594/////////////////////////////////////////////////////////////////////
595///Thread is alive. Zero if thread is new (not started) or terminated.
596pub const JVMTI_THREAD_STATE_ALIVE: jint = 0x0001;
597
598/// Thread has completed execution.
599pub const JVMTI_THREAD_STATE_TERMINATED: jint = 0x0002;
600
601/// Thread is runnable.
602pub const JVMTI_THREAD_STATE_RUNNABLE: jint = 0x0004;
603
604/// Thread is waiting to enter a synchronized block/method or, after an `Object.wait()`, waiting to re-enter a synchronized block/method.
605pub const JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER: jint = 0x0400;
606
607/// Thread is waiting.
608pub const JVMTI_THREAD_STATE_WAITING: jint = 0x0080;
609
610/// Thread is waiting without a timeout. For example, `Object.wait()`.
611pub const JVMTI_THREAD_STATE_WAITING_INDEFINITELY: jint = 0x0010;
612
613/// Thread is waiting with a maximum time to wait specified. For example, Object.wait(long).
614pub const JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT: jint = 0x0020;
615
616/// Thread is sleeping -- Thread.sleep.
617pub const JVMTI_THREAD_STATE_SLEEPING: jint = 0x0040;
618
619/// Thread is waiting on an object monitor -- Object.wait.
620pub const JVMTI_THREAD_STATE_IN_OBJECT_WAIT: jint = 0x0100;
621
622/// 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`.
623pub const JVMTI_THREAD_STATE_PARKED: jint = 0x0200;
624
625/// 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.
626pub const JVMTI_THREAD_STATE_SUSPENDED: jint = 0x0010_0000;
627
628/// Thread has been interrupted.
629pub const JVMTI_THREAD_STATE_INTERRUPTED: jint = 0x0020_0000;
630
631/// 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.
632///
633/// 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.
634///
635/// Native VM interface functions, such as JNI and JVM TI functions, may be implemented as VM code.
636pub const JVMTI_THREAD_STATE_IN_NATIVE: jint = 0x0040_0000;
637
638/// Defined by VM vendor.
639pub const JVMTI_THREAD_STATE_VENDOR_1: jint = 0x1000_0000;
640
641/// Defined by VM vendor.
642pub const JVMTI_THREAD_STATE_VENDOR_2: jint = 0x2000_0000;
643
644/// Defined by VM vendor.
645pub const JVMTI_THREAD_STATE_VENDOR_3: jint = 0x4000_0000;
646
647/// Mod for private trait seals that should be hidden.
648mod private {
649    use core::ffi::{c_char, c_void};
650
651    ///Trait seal for `AsJNILinkage`
652    pub trait SealedAsJNILinkage {
653        /// Returns the jni linkage index.
654        fn linkage(self) -> usize;
655    }
656
657    /// Trait seal for `JType`
658    pub trait SealedJType {}
659
660    /// Trait Seal for `UseCString`
661    pub trait SealedUseCString {
662        /// Transform the string into a zero terminated string if necessary and calls the closure with it.
663        /// The pointer passed into the closure only stays valid until the closure returns.
664        /// The string is guaranteed to be 0 terminated!
665        /// The string is not guaranteed to be valid utf-8, but it can generally be assumed to be utf-8!
666        ///
667        /// # Undefined Behavior
668        /// If called on a raw pointer type that is not in fact 0 terminated.
669        /// Yes I am aware that is should make this fn unsafe because of this.
670        /// I choose not to do so because it doesnt apply for 90% of the implementations of this trait.
671        ///
672        /// # Panics
673        /// panics if asserts feature is enabled and the implementation is capable of detecting that the string is not utf-8.
674        /// This check is only relevant for types that do not do conversion to utf-8 by default (such as `OsString` and friends)
675        ///
676        fn use_as_const_c_char<X>(self, param: impl FnOnce(*const c_char) -> X) -> X;
677    }
678
679    #[test]
680    #[cfg(feature = "std")]
681    pub fn testSealedUseCString() {
682        use std::ffi::{CStr, OsString};
683
684        unsafe {
685            assert!([].use_as_const_c_char(|ptr| CStr::from_ptr(ptr).to_bytes().is_empty()));
686            assert!([0u8].use_as_const_c_char(|ptr| CStr::from_ptr(ptr).to_bytes().is_empty()));
687            assert!("".use_as_const_c_char(|ptr| CStr::from_ptr(ptr).to_bytes().is_empty()));
688            assert!("abc".use_as_const_c_char(|ptr| CStr::from_ptr(ptr).to_bytes() == [b'a', b'b', b'c']));
689            assert!([b'a', b'b', 0, b'c'].use_as_const_c_char(|ptr| CStr::from_ptr(ptr).to_bytes() == [b'a', b'b']));
690            assert!("abc\0".use_as_const_c_char(|ptr| CStr::from_ptr(ptr).to_bytes() == [b'a', b'b', b'c']));
691            assert!(OsString::from("abc").use_as_const_c_char(|ptr| CStr::from_ptr(ptr).to_bytes() == [b'a', b'b', b'c']));
692
693            #[cfg(feature = "asserts")]
694            {
695                let r = std::panic::catch_unwind(|| [0b1011_1111, b'A', b'B'].as_slice().use_as_const_c_char(|_| std::process::abort()));
696                assert!(r.is_err());
697            }
698        }
699    }
700
701    /// Sealed trait for the Env Vtable receiver so we can check if the receiver is correct if asssertions are correct.
702    pub trait SealedEnvVTable: From<*mut c_void> {
703        /// can this receiver get the JNI function table?
704        fn can_jni() -> bool;
705
706        /// can this receiver get the JVMTI function table?
707        fn can_jvmti() -> bool;
708    }
709
710    impl SealedEnvVTable for *mut c_void {
711        fn can_jni() -> bool {
712            true
713        }
714
715        fn can_jvmti() -> bool {
716            true
717        }
718    }
719}
720
721pub type jweak = jobject;
722
723pub type jthrowable = jobject;
724
725pub type jthread = jobject;
726
727pub type jthreadGroup = jobject;
728
729pub type jmethodID = jobject;
730pub type jfieldID = jobject;
731
732///
733/// Marker trait for all types that are valid to use to make variadic JNI Up-calls with.
734///
735pub trait JType: private::SealedJType + Into<jtype> + Clone + Copy {
736    ///
737    /// Returns a single character that equals the type's JNI signature.
738    ///
739    /// Boolean -> Z
740    /// Byte -> B
741    /// Short -> S
742    /// Char -> C
743    /// Int -> I
744    /// Long -> J
745    /// Float -> F
746    /// Double -> D
747    /// any java.lang.Object -> L
748    ///
749    ///
750    fn jtype_id() -> char;
751}
752impl private::SealedJType for jobject {}
753impl JType for jobject {
754    #[inline(always)]
755    fn jtype_id() -> char {
756        'L'
757    }
758}
759impl private::SealedJType for jboolean {}
760impl JType for jboolean {
761    #[inline(always)]
762    fn jtype_id() -> char {
763        'Z'
764    }
765}
766impl private::SealedJType for jbyte {}
767impl JType for jbyte {
768    #[inline(always)]
769    fn jtype_id() -> char {
770        'B'
771    }
772}
773impl private::SealedJType for jshort {}
774impl JType for jshort {
775    #[inline(always)]
776    fn jtype_id() -> char {
777        'S'
778    }
779}
780impl private::SealedJType for jchar {}
781impl JType for jchar {
782    #[inline(always)]
783    fn jtype_id() -> char {
784        'C'
785    }
786}
787impl private::SealedJType for jint {}
788impl JType for jint {
789    #[inline(always)]
790    fn jtype_id() -> char {
791        'I'
792    }
793}
794impl private::SealedJType for jlong {}
795impl JType for jlong {
796    #[inline(always)]
797    fn jtype_id() -> char {
798        'J'
799    }
800}
801impl private::SealedJType for jfloat {}
802impl JType for jfloat {
803    #[inline(always)]
804    fn jtype_id() -> char {
805        'F'
806    }
807}
808impl private::SealedJType for jdouble {}
809impl JType for jdouble {
810    #[inline(always)]
811    fn jtype_id() -> char {
812        'D'
813    }
814}
815
816#[repr(C)]
817#[derive(Clone, Copy)]
818#[allow(clippy::missing_docs_in_private_items)]
819pub union jtype {
820    long: jlong,
821    int: jint,
822    short: jshort,
823    char: jchar,
824    byte: jbyte,
825    boolean: jboolean,
826    float: jfloat,
827    double: jdouble,
828    object: jobject,
829    class: jclass,
830    throwable: jthrowable,
831}
832
833pub type jvalue = jtype;
834
835pub type jrawMonitorID = *mut c_void;
836
837///
838/// This macro is usefull for constructing jtype arrays.
839/// This is often needed when making upcalls into the jvm with many arguments using the 'A' type functions:
840/// * CallStatic(TYPE)MethodA
841///     * `CallStaticVoidMethodA`
842///     * `CallStaticIntMethodA`
843///     * ...
844/// * Call(TYPE)MethodA
845///     * `CallVoidMethodA`
846///     * ...
847/// * `NewObjectA`
848///
849/// # Example
850/// ```rust
851/// use jni_simple::{*};
852///
853/// unsafe fn test(env: JNIEnv, class: jclass) {
854///     //public static void methodWith5Params(int a, int b, long c, long d, boolean e) {}
855///     let meth = env.GetStaticMethodID(class, "methodWith5Params", "(IIJJZ)V");
856///     if meth.is_null() {
857///         unimplemented!("handle method not found");
858///     }
859///     // methodWith5Params(16, 32, 12, 13, false);
860///     env.CallStaticVoidMethodA(class, meth, jtypes!(16i32, 64i32, 12i64, 13i64, false).as_ptr());
861/// }
862/// ```
863///
864#[macro_export]
865macro_rules! jtypes {
866    ( $($x:expr),* ) => {
867        {
868            [ $(jtype::from($x)),* ]
869        }
870    };
871}
872
873impl Debug for jtype {
874    #[inline(never)]
875    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
876        unsafe {
877            let long = core::ptr::read_unaligned(core::ptr::from_ref::<jlong>(&self.long));
878            let int = core::ptr::read_unaligned(core::ptr::from_ref::<jint>(&self.int));
879            let short = core::ptr::read_unaligned(core::ptr::from_ref::<jshort>(&self.short));
880            let byte = core::ptr::read_unaligned(core::ptr::from_ref::<jbyte>(&self.byte));
881            let float = core::ptr::read_unaligned(core::ptr::from_ref::<jfloat>(&self.float));
882            let double = core::ptr::read_unaligned(core::ptr::from_ref::<jdouble>(&self.double));
883
884            f.write_fmt(format_args!(
885                "jtype union[long=0x{long:x} int=0x{int:x} short=0x{short:x} byte=0x{byte:x} float={float:e} double={double:e}]"
886            ))
887        }
888    }
889}
890
891impl jtype {
892    ///
893    /// Helper function to "create" a jtype with a null jobject.
894    ///
895    #[inline(always)]
896    #[must_use]
897    pub const fn null() -> Self {
898        #[cfg(target_pointer_width = "32")]
899        {
900            let mut jt = jtype { long: 0 };
901            jt.object = null_mut();
902            jt
903        }
904        #[cfg(target_pointer_width = "64")]
905        {
906            jtype { object: null_mut() }
907        }
908    }
909
910    /// read this jtype as jlong
911    /// # Safety
912    /// only safe if jtype was a jlong.
913    #[inline(always)]
914    #[must_use]
915    pub const unsafe fn long(&self) -> jlong {
916        unsafe { self.long }
917    }
918
919    /// read this jtype as jint
920    /// # Safety
921    /// only safe if jtype was a jint.
922    #[inline(always)]
923    #[must_use]
924    pub const unsafe fn int(&self) -> jint {
925        unsafe { self.int }
926    }
927
928    /// read this jtype as jshort
929    /// # Safety
930    /// only safe if jtype was a jshort.
931    #[inline(always)]
932    #[must_use]
933    pub const unsafe fn short(&self) -> jshort {
934        unsafe { self.short }
935    }
936
937    /// read this jtype as jchar
938    /// # Safety
939    /// only safe if jtype was a jchar.
940    #[inline(always)]
941    #[must_use]
942    pub const unsafe fn char(&self) -> jchar {
943        unsafe { self.char }
944    }
945
946    /// read this jtype as jbyte
947    /// # Safety
948    /// only safe if jtype was a jbyte.
949    #[inline(always)]
950    #[must_use]
951    pub const unsafe fn byte(&self) -> jbyte {
952        unsafe { self.byte }
953    }
954
955    /// read this jtype as jboolean
956    /// # Safety
957    /// only safe if jtype was a jboolean.
958    #[inline(always)]
959    #[must_use]
960    pub const unsafe fn boolean(&self) -> jboolean {
961        unsafe { self.boolean }
962    }
963
964    /// read this jtype as jfloat
965    /// # Safety
966    /// only safe if jtype was a jfloat.
967    #[inline(always)]
968    #[must_use]
969    pub const unsafe fn float(&self) -> jfloat {
970        unsafe { self.float }
971    }
972
973    /// read this jtype as jdouble
974    /// # Safety
975    /// only safe if jtype was a jdouble.
976    #[inline(always)]
977    #[must_use]
978    pub const unsafe fn double(&self) -> jdouble {
979        unsafe { self.double }
980    }
981
982    /// read this jtype as jobject
983    /// # Safety
984    /// only safe if jtype was a jobject.
985    #[inline(always)]
986    #[must_use]
987    pub const unsafe fn object(&self) -> jobject {
988        unsafe { self.object }
989    }
990
991    /// read this jtype as jclass
992    /// # Safety
993    /// only safe if jtype was a jclass.
994    #[inline(always)]
995    #[must_use]
996    pub const unsafe fn class(&self) -> jclass {
997        unsafe { self.class }
998    }
999
1000    /// read this jtype as jthrowable
1001    /// # Safety
1002    /// only safe if jtype was a jthrowable.
1003    #[inline(always)]
1004    #[must_use]
1005    pub const unsafe fn throwable(&self) -> jthrowable {
1006        unsafe { self.throwable }
1007    }
1008
1009    /// Sets the jtype to a value, this is always safe.
1010    #[inline(always)]
1011    pub fn set<T: Into<Self>>(&mut self, value: T) {
1012        *self = value.into();
1013    }
1014}
1015
1016impl From<jlong> for jtype {
1017    fn from(value: jlong) -> Self {
1018        jtype { long: value }
1019    }
1020}
1021
1022impl From<jobject> for jtype {
1023    #[cfg(target_pointer_width = "64")]
1024    fn from(value: jobject) -> Self {
1025        jtype { object: value }
1026    }
1027
1028    #[cfg(target_pointer_width = "32")]
1029    fn from(value: jobject) -> Self {
1030        let mut jt = jtype { long: 0 };
1031        jt.object = value;
1032        jt
1033    }
1034}
1035impl From<jint> for jtype {
1036    fn from(value: jint) -> Self {
1037        let mut jt = jtype { long: 0 };
1038        jt.int = value;
1039        jt
1040    }
1041}
1042
1043impl From<jshort> for jtype {
1044    fn from(value: jshort) -> Self {
1045        let mut jt = jtype { long: 0 };
1046        jt.short = value;
1047        jt
1048    }
1049}
1050
1051impl From<jbyte> for jtype {
1052    fn from(value: jbyte) -> Self {
1053        let mut jt = jtype { long: 0 };
1054        jt.byte = value;
1055        jt
1056    }
1057}
1058
1059impl From<jchar> for jtype {
1060    fn from(value: jchar) -> Self {
1061        let mut jt = jtype { long: 0 };
1062        jt.char = value;
1063        jt
1064    }
1065}
1066
1067impl From<jfloat> for jtype {
1068    fn from(value: jfloat) -> Self {
1069        let mut jt = jtype { long: 0 };
1070        jt.float = value;
1071        jt
1072    }
1073}
1074
1075impl From<jdouble> for jtype {
1076    fn from(value: jdouble) -> Self {
1077        jtype { double: value }
1078    }
1079}
1080impl From<jboolean> for jtype {
1081    fn from(value: jboolean) -> Self {
1082        let mut jt = jtype { long: 0 };
1083        jt.boolean = value;
1084        jt
1085    }
1086}
1087
1088#[repr(C)]
1089#[derive(Debug, Copy, Clone)]
1090pub struct JNINativeMethod {
1091    /// Name of the native method
1092    name: *const c_char,
1093    /// JNI Signature of the native method
1094    signature: *const c_char,
1095    /// raw Function pointer that should be called when the native method is called.
1096    fnPtr: *const c_void,
1097}
1098
1099type JNIInvPtr = SyncMutPtr<*mut *mut c_void>;
1100
1101#[repr(transparent)]
1102#[derive(Debug, Clone, Copy)]
1103pub struct JavaVM {
1104    /// The vtable of the `JavaVM` object.
1105    vtable: JNIInvPtr,
1106}
1107
1108#[repr(C)]
1109#[derive(Debug, Copy, Clone)]
1110pub struct JavaVMAttachArgs {
1111    /// Jni version
1112    version: jint,
1113    /// Thread name as a C-Linke string
1114    name: *const c_char,
1115    /// `ThreadGroup` reference. This can be null
1116    group: jobject,
1117}
1118
1119#[repr(C)]
1120#[derive(Debug, Clone, Copy)]
1121pub struct JavaVMOption {
1122    /// this field contains the string option as a C-like string.
1123    optionString: *mut c_char,
1124    /// This field is reserved and should be set to null
1125    extraInfo: *mut c_void,
1126}
1127
1128impl JavaVMOption {
1129    pub const fn new(option_string: *mut c_char, extra_info: *mut c_void) -> Self {
1130        Self {
1131            optionString: option_string,
1132            extraInfo: extra_info,
1133        }
1134    }
1135
1136    #[must_use]
1137    pub const fn optionString(&self) -> *mut c_char {
1138        self.optionString
1139    }
1140
1141    #[must_use]
1142    pub const fn extraInfo(&self) -> *mut c_void {
1143        self.extraInfo
1144    }
1145}
1146
1147#[repr(C)]
1148#[derive(Debug, Clone, Copy)]
1149pub struct JavaVMInitArgs {
1150    /// The JNI version
1151    version: i32,
1152    /// amount of options
1153    nOptions: i32,
1154    /// options
1155    options: *mut JavaVMOption,
1156    /// flat to indicate if the jvm should ignore unrecognized options instead of returning an error 1 = yes, 0 = no
1157    ignoreUnrecognized: u8,
1158}
1159
1160impl JavaVMInitArgs {
1161    pub const fn new(version: i32, n_options: i32, options: *mut JavaVMOption, ignore_unrecognized: u8) -> Self {
1162        Self {
1163            version,
1164            nOptions: n_options,
1165            options,
1166            ignoreUnrecognized: ignore_unrecognized,
1167        }
1168    }
1169
1170    #[must_use]
1171    pub const fn version(&self) -> i32 {
1172        self.version
1173    }
1174
1175    #[must_use]
1176    pub const fn nOptions(&self) -> i32 {
1177        self.nOptions
1178    }
1179
1180    #[must_use]
1181    pub const fn options(&self) -> *mut JavaVMOption {
1182        self.options
1183    }
1184
1185    #[must_use]
1186    pub const fn ignoreUnrecognized(&self) -> u8 {
1187        self.ignoreUnrecognized
1188    }
1189}
1190
1191#[derive(Debug, Copy, Clone)]
1192#[repr(C)]
1193pub struct jvmtiThreadInfo {
1194    pub name: *const c_char,
1195    pub priority: jint,
1196    pub is_daemon: jboolean,
1197    pub thread_group: jthreadGroup,
1198    pub context_class_loader: jobject,
1199}
1200
1201impl Default for jvmtiThreadInfo {
1202    fn default() -> Self {
1203        Self {
1204            name: null(),
1205            priority: 0,
1206            is_daemon: false,
1207            thread_group: null_mut(),
1208            context_class_loader: null_mut(),
1209        }
1210    }
1211}
1212
1213#[derive(Debug, Copy, Clone)]
1214#[repr(C)]
1215pub struct jvmtiThreadGroupInfo {
1216    pub parent: jthreadGroup,
1217    pub name: *const c_char,
1218    pub max_priority: jint,
1219    pub is_daemon: jboolean,
1220}
1221
1222#[derive(Debug, Copy, Clone)]
1223#[repr(C)]
1224pub struct jvmtiMonitorStackDepthInfo {
1225    pub monitor: jobject,
1226    pub stack_depth: jint,
1227}
1228
1229pub type jvmtiEventReserved = extern "system" fn();
1230pub type jvmtiEventBreakpoint = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, method: jmethodID, location: jlocation);
1231
1232pub type jvmtiEventClassFileLoadHook = extern "system" fn(
1233    jvmti_env: JVMTIEnv,
1234    jni_env: JNIEnv,
1235    class_being_redefined: jclass,
1236    loader: jobject,
1237    name: *const c_char,
1238    protection_domain: jobject,
1239    class_data_len: jint,
1240    class_data: *const c_uchar,
1241    new_class_data_len: *mut jint,
1242    new_class_data: *mut *mut c_uchar,
1243);
1244
1245pub type jvmtiEventClassLoad = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, klass: jclass);
1246
1247pub type jvmtiEventClassPrepare = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, klass: jclass);
1248
1249#[derive(Debug)]
1250#[repr(C)]
1251pub struct jvmtiAddrLocationMap {
1252    pub start_address: *const c_void,
1253    pub location: jlocation,
1254}
1255pub type jvmtiEventCompiledMethodLoad = extern "system" fn(
1256    jvmti_env: JVMTIEnv,
1257    method: jmethodID,
1258    code_size: jint,
1259    code_addr: *const c_void,
1260    map_length: jint,
1261    map: *const jvmtiAddrLocationMap,
1262    compile_info: *const c_void,
1263);
1264
1265pub type jvmtiEventCompiledMethodUnload = extern "system" fn(jvmti_env: JVMTIEnv, method: jmethodID, code_addr: *const c_void);
1266
1267pub type jvmtiEventDataDumpRequest = extern "system" fn(jvmti_env: JVMTIEnv);
1268
1269pub type jvmtiEventDynamicCodeGenerated = extern "system" fn(jvmti_env: JVMTIEnv, name: *const c_char, address: *const c_void, length: jint);
1270
1271pub type jvmtiEventException = extern "system" fn(
1272    jvmti_env: JVMTIEnv,
1273    jni_env: JNIEnv,
1274    thread: jthread,
1275    method: jmethodID,
1276    location: jlocation,
1277    exception: jobject,
1278    catch_method: jmethodID,
1279    catch_location: jlocation,
1280);
1281
1282pub type jvmtiEventExceptionCatch = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, method: jmethodID, location: jlocation, exception: jobject);
1283
1284pub type jvmtiEventFieldAccess =
1285    extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, method: jmethodID, location: jlocation, field_klass: jclass, object: jobject, field: jfieldID);
1286
1287pub type jvmtiEventFieldModification = extern "system" fn(
1288    jvmti_env: JVMTIEnv,
1289    jni_env: JNIEnv,
1290    thread: jthread,
1291    method: jmethodID,
1292    location: jlocation,
1293    field_klass: jclass,
1294    object: jobject,
1295    field: jfieldID,
1296    signature_type: c_char,
1297    new_value: jvalue,
1298);
1299
1300pub type jvmtiEventFramePop = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, method: jmethodID, was_popped_by_exception: jboolean);
1301
1302pub type jvmtiEventGarbageCollectionFinish = extern "system" fn(jvmti_env: JVMTIEnv);
1303
1304pub type jvmtiEventGarbageCollectionStart = extern "system" fn(jvmti_env: JVMTIEnv);
1305
1306pub type jvmtiEventMethodEntry = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, method: jmethodID);
1307
1308pub type jvmtiEventMethodExit =
1309    extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, method: jmethodID, was_popped_by_exception: jboolean, return_value: jvalue);
1310
1311pub type jvmtiEventMonitorContendedEnter = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, object: jobject);
1312
1313pub type jvmtiEventMonitorContendedEntered = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, object: jobject);
1314
1315pub type jvmtiEventMonitorWait = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, object: jobject, timeout: jlong);
1316
1317pub type jvmtiEventMonitorWaited = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, object: jobject, timed_out: jboolean);
1318
1319pub type jvmtiEventNativeMethodBind =
1320    extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, method: jmethodID, address: *mut c_void, new_address_ptr: *mut *mut c_void);
1321
1322pub type jvmtiEventObjectFree = extern "system" fn(jvmti_env: JVMTIEnv, tag: jlong);
1323
1324pub type jvmtiEventResourceExhausted = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, flags: jint, reserved: *const c_void, description: *const c_char);
1325
1326pub type jvmtiEventSampledObjectAlloc = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, object: jobject, object_klass: jclass, size: jlong);
1327
1328pub type jvmtiEventSingleStep = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, method: jmethodID, location: jlocation);
1329
1330pub type jvmtiEventThreadEnd = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread);
1331
1332pub type jvmtiEventThreadStart = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread);
1333
1334pub type jvmtiEventVirtualThreadEnd = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, virtual_thread: jthread);
1335
1336pub type jvmtiEventVirtualThreadStart = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, virtual_thread: jthread);
1337
1338pub type jvmtiEventVMDeath = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv);
1339
1340pub type jvmtiEventVMInit = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread);
1341
1342pub type jvmtiEventVMObjectAlloc = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv, thread: jthread, object: jobject, object_klass: jclass, size: jlong);
1343
1344pub type jvmtiEventVMStart = extern "system" fn(jvmti_env: JVMTIEnv, jni_env: JNIEnv);
1345
1346#[derive(Debug, Clone, Default)]
1347#[repr(C)]
1348pub struct jvmtiEventCallbacks {
1349    pub VMInit: Option<jvmtiEventVMInit>,
1350    pub VMDeath: Option<jvmtiEventVMDeath>,
1351    pub ThreadStart: Option<jvmtiEventThreadStart>,
1352    pub ThreadEnd: Option<jvmtiEventThreadEnd>,
1353    pub ClassFileLoadHook: Option<jvmtiEventClassFileLoadHook>,
1354    pub ClassLoad: Option<jvmtiEventClassLoad>,
1355    pub ClassPrepare: Option<jvmtiEventClassPrepare>,
1356    pub VMStart: Option<jvmtiEventVMStart>,
1357    pub Exception: Option<jvmtiEventException>,
1358    pub ExceptionCatch: Option<jvmtiEventExceptionCatch>,
1359    pub SingleStep: Option<jvmtiEventSingleStep>,
1360    pub FramePop: Option<jvmtiEventFramePop>,
1361    pub Breakpoint: Option<jvmtiEventBreakpoint>,
1362    pub FieldAccess: Option<jvmtiEventFieldAccess>,
1363    pub FieldModification: Option<jvmtiEventFieldModification>,
1364    pub MethodEntry: Option<jvmtiEventMethodEntry>,
1365    pub MethodExit: Option<jvmtiEventMethodExit>,
1366    pub NativeMethodBind: Option<jvmtiEventNativeMethodBind>,
1367    pub CompiledMethodLoad: Option<jvmtiEventCompiledMethodLoad>,
1368    pub CompiledMethodUnload: Option<jvmtiEventCompiledMethodUnload>,
1369    pub DynamicCodeGenerated: Option<jvmtiEventDynamicCodeGenerated>,
1370    pub DataDumpRequest: Option<jvmtiEventDataDumpRequest>,
1371    pub reserved72: Option<jvmtiEventReserved>,
1372    pub MonitorWait: Option<jvmtiEventMonitorWait>,
1373    pub MonitorWaited: Option<jvmtiEventMonitorWaited>,
1374    pub MonitorContendedEnter: Option<jvmtiEventMonitorContendedEnter>,
1375    pub MonitorContendedEntered: Option<jvmtiEventMonitorContendedEntered>,
1376    pub reserved77: Option<jvmtiEventReserved>,
1377    pub reserved78: Option<jvmtiEventReserved>,
1378    pub reserved79: Option<jvmtiEventReserved>,
1379    pub ResourceExhausted: Option<jvmtiEventResourceExhausted>,
1380    pub GarbageCollectionStart: Option<jvmtiEventGarbageCollectionStart>,
1381    pub GarbageCollectionFinish: Option<jvmtiEventGarbageCollectionFinish>,
1382    pub ObjectFree: Option<jvmtiEventObjectFree>,
1383    pub VMObjectAlloc: Option<jvmtiEventVMObjectAlloc>,
1384    pub reserved85: Option<jvmtiEventReserved>,
1385    pub SampledObjectAlloc: Option<jvmtiEventSampledObjectAlloc>,
1386    pub VirtualThreadStart: Option<jvmtiEventVirtualThreadStart>,
1387    pub VirtualThreadEnd: Option<jvmtiEventVirtualThreadEnd>,
1388}
1389
1390#[repr(C)]
1391#[derive(Debug, Copy, Clone, Default)]
1392pub enum jvmtiEventMode {
1393    #[default]
1394    JVMTI_ENABLE = 1,
1395    JVMTI_DISABLE = 0,
1396}
1397
1398#[repr(C)]
1399#[derive(Debug, Copy, Clone, Default)]
1400pub enum jvmtiEvent {
1401    #[default]
1402    JVMTI_EVENT_VM_DEATH = 51,
1403    JVMTI_EVENT_THREAD_START = 52,
1404    JVMTI_EVENT_THREAD_END = 53,
1405    JVMTI_EVENT_CLASS_FILE_LOAD_HOOK = 54,
1406    JVMTI_EVENT_CLASS_LOAD = 55,
1407    JVMTI_EVENT_CLASS_PREPARE = 56,
1408    JVMTI_EVENT_VM_START = 57,
1409    JVMTI_EVENT_EXCEPTION = 58,
1410    JVMTI_EVENT_EXCEPTION_CATCH = 59,
1411    JVMTI_EVENT_SINGLE_STEP = 60,
1412    JVMTI_EVENT_FRAME_POP = 61,
1413    JVMTI_EVENT_BREAKPOINT = 62,
1414    JVMTI_EVENT_FIELD_ACCESS = 63,
1415    JVMTI_EVENT_FIELD_MODIFICATION = 64,
1416    JVMTI_EVENT_METHOD_ENTRY = 65,
1417    JVMTI_EVENT_METHOD_EXIT = 66,
1418    JVMTI_EVENT_NATIVE_METHOD_BIND = 67,
1419    JVMTI_EVENT_COMPILED_METHOD_LOAD = 68,
1420    JVMTI_EVENT_COMPILED_METHOD_UNLOAD = 69,
1421    JVMTI_EVENT_DYNAMIC_CODE_GENERATED = 70,
1422    JVMTI_EVENT_DATA_DUMP_REQUEST = 71,
1423    JVMTI_EVENT_MONITOR_WAIT = 73,
1424    JVMTI_EVENT_MONITOR_WAITED = 74,
1425    JVMTI_EVENT_MONITOR_CONTENDED_ENTER = 75,
1426    JVMTI_EVENT_MONITOR_CONTENDED_ENTERED = 76,
1427    JVMTI_EVENT_RESOURCE_EXHAUSTED = 80,
1428    JVMTI_EVENT_GARBAGE_COLLECTION_START = 81,
1429    JVMTI_EVENT_GARBAGE_COLLECTION_FINISH = 82,
1430    JVMTI_EVENT_OBJECT_FREE = 83,
1431    JVMTI_EVENT_VM_OBJECT_ALLOC = 84,
1432    JVMTI_EVENT_SAMPLED_OBJECT_ALLOC = 86,
1433    JVMTI_EVENT_VIRTUAL_THREAD_START = 87,
1434    JVMTI_EVENT_VIRTUAL_THREAD_END = 88,
1435}
1436
1437pub type jvmtiExtensionFunction = Option<extern "C" fn(jvmti_env: JVMTIEnv, ...)>;
1438
1439pub type jvmtiExtensionEvent = Option<extern "C" fn(jvmti_env: JVMTIEnv, ...)>;
1440
1441//We cant enum this as the jvm returning an unknown value to us would be ub.
1442pub type jvmtiParamKind = c_int;
1443
1444/// Ingoing argument - foo.
1445pub const JVMTI_KIND_IN: c_int = 91;
1446
1447/// Ingoing pointer argument - const foo*.
1448pub const JVMTI_KIND_IN_PTR: c_int = 92;
1449
1450/// Ingoing array argument - const foo*.
1451pub const JVMTI_KIND_IN_BUF: c_int = 93;
1452
1453/// Outgoing allocated array argument - foo**. Free with Deallocate.
1454pub const JVMTI_KIND_ALLOC_BUF: c_int = 94;
1455
1456/// Outgoing allocated array of allocated arrays argument - foo***. Free with Deallocate.
1457pub const JVMTI_KIND_ALLOC_ALLOC_BUF: c_int = 95;
1458
1459/// Outgoing argument - foo*.
1460pub const JVMTI_KIND_OUT: c_int = 96;
1461
1462/// Outgoing array argument (pre-allocated by agent) - foo*. Do not Deallocate.
1463pub const JVMTI_KIND_OUT_BUF: c_int = 97;
1464
1465//We cant enum this as the jvm returning an unknown value to us would be ub.
1466pub type jvmtiParamTypes = c_int;
1467
1468/// Java programming language primitive type - byte. JNI type jbyte.
1469pub const JVMTI_TYPE_JBYTE: c_int = 101;
1470
1471/// Java programming language primitive type - char. JNI type jchar.
1472pub const JVMTI_TYPE_JCHAR: c_int = 102;
1473
1474/// Java programming language primitive type - short. JNI type jshort.
1475pub const JVMTI_TYPE_JSHORT: c_int = 103;
1476
1477/// Java programming language primitive type - int. JNI type jint.
1478pub const JVMTI_TYPE_JINT: c_int = 104;
1479
1480/// Java programming language primitive type - long. JNI type jlong.
1481pub const JVMTI_TYPE_JLONG: c_int = 105;
1482
1483/// Java programming language primitive type - float. JNI type jfloat.
1484pub const JVMTI_TYPE_JFLOAT: c_int = 106;
1485
1486/// Java programming language primitive type - double. JNI type jdouble.
1487pub const JVMTI_TYPE_JDOUBLE: c_int = 107;
1488
1489/// Java programming language primitive type - boolean. JNI type jboolean.
1490pub const JVMTI_TYPE_JBOOLEAN: c_int = 108;
1491
1492/// Java programming language object type - java.lang.Object. JNI type jobject. Returned values are JNI local references and must be managed.
1493pub const JVMTI_TYPE_JOBJECT: c_int = 109;
1494
1495/// Java programming language object type - java.lang.Thread. JVM TI type jthread. Returned values are JNI local references and must be managed.
1496pub const JVMTI_TYPE_JTHREAD: c_int = 110;
1497
1498/// Java programming language object type - java.lang.Class. JNI type jclass. Returned values are JNI local references and must be managed.
1499pub const JVMTI_TYPE_JCLASS: c_int = 111;
1500
1501/// 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.
1502pub const JVMTI_TYPE_JVALUE: c_int = 112;
1503
1504/// Java programming language field identifier - JNI type jfieldID.
1505pub const JVMTI_TYPE_JFIELDID: c_int = 113;
1506
1507/// Java programming language method identifier - JNI type jmethodID.
1508pub const JVMTI_TYPE_JMETHODID: c_int = 114;
1509
1510/// C programming language type - char.
1511pub const JVMTI_TYPE_CCHAR: c_int = 115;
1512
1513/// C programming language type - void.
1514pub const JVMTI_TYPE_CVOID: c_int = 116;
1515
1516/// JNI environment - `JNIEnv`. Should be used with the correct jvmtiParamKind to make it a pointer type.
1517pub const JVMTI_TYPE_JNIENV: c_int = 117;
1518
1519pub type jvmtiTimerKind = c_int;
1520
1521pub const JVMTI_TIMER_USER_CPU: jvmtiTimerKind = 30;
1522
1523pub const JVMTI_TIMER_TOTAL_CPU: jvmtiTimerKind = 31;
1524
1525pub const JVMTI_TIMER_ELAPSED: jvmtiTimerKind = 32;
1526#[repr(C)]
1527#[derive(Debug, Copy, Clone, Default)]
1528pub struct jvmtiTimerInfo {
1529    pub max_value: jlong,
1530    pub may_skip_forward: jboolean,
1531    pub may_skip_backward: jboolean,
1532    pub kind: jvmtiTimerKind,
1533    pub reserved1: jlong,
1534    pub reserved2: jlong,
1535}
1536
1537#[repr(C)]
1538#[derive(Debug, Copy, Clone)]
1539pub struct jvmtiParamInfo {
1540    pub name: *mut c_char,
1541    pub kind: jvmtiParamKind,
1542    pub base_type: jvmtiParamTypes,
1543    pub null_ok: jboolean,
1544}
1545#[repr(C)]
1546#[derive(Debug, Copy, Clone)]
1547pub struct jvmtiExtensionFunctionInfo {
1548    pub func: jvmtiExtensionFunction,
1549    pub id: *mut c_char,
1550    pub short_description: *mut c_char,
1551    pub param_count: jint,
1552    pub params: *mut jvmtiParamInfo,
1553    pub error_count: jint,
1554    pub errors: *mut jvmtiError,
1555}
1556
1557impl Default for jvmtiExtensionFunctionInfo {
1558    fn default() -> Self {
1559        Self {
1560            func: None,
1561            id: null_mut(),
1562            short_description: null_mut(),
1563            param_count: 0,
1564            params: null_mut(),
1565            error_count: 0,
1566            errors: null_mut(),
1567        }
1568    }
1569}
1570
1571#[repr(C)]
1572#[derive(Debug, Copy, Clone)]
1573pub struct jvmtiExtensionEventInfo {
1574    pub extension_event_index: jint,
1575    pub id: *mut c_char,
1576    pub short_description: *mut c_char,
1577    pub param_count: jint,
1578    pub params: *mut jvmtiParamInfo,
1579}
1580
1581impl Default for jvmtiExtensionEventInfo {
1582    fn default() -> Self {
1583        Self {
1584            extension_event_index: 0,
1585            id: null_mut(),
1586            short_description: null_mut(),
1587            param_count: 0,
1588            params: null_mut(),
1589        }
1590    }
1591}
1592
1593pub type jvmtiPhase = c_int;
1594pub const JVMTI_PHASE_ONLOAD: jvmtiPhase = 1;
1595pub const JVMTI_PHASE_PRIMORDIAL: jvmtiPhase = 2;
1596pub const JVMTI_PHASE_START: jvmtiPhase = 6;
1597pub const JVMTI_PHASE_LIVE: jvmtiPhase = 4;
1598pub const JVMTI_PHASE_DEAD: jvmtiPhase = 8;
1599
1600#[repr(C)]
1601#[derive(Debug, Copy, Clone)]
1602pub enum jvmtiVerboseFlag {
1603    JVMTI_VERBOSE_OTHER = 0,
1604    JVMTI_VERBOSE_GC = 1,
1605    JVMTI_VERBOSE_CLASS = 2,
1606    JVMTI_VERBOSE_JNI = 4,
1607}
1608
1609pub type jvmtiJlocationFormat = c_int;
1610
1611/// jlocation values represent virtual machine bytecode indices--that is, offsets into the virtual machine code for a method.
1612pub const JVMTI_JLOCATION_JVMBCI: jvmtiJlocationFormat = 1;
1613
1614/// jlocation values represent native machine program counter values.
1615pub const JVMTI_JLOCATION_MACHINEPC: jvmtiJlocationFormat = 2;
1616
1617/// jlocation values have some other representation.
1618pub const JVMTI_JLOCATION_OTHER: jvmtiJlocationFormat = 0;
1619
1620#[repr(transparent)]
1621#[derive(Debug, Default, Copy, Clone)]
1622pub struct jvmtiCapabilities(u128);
1623
1624/// Dumped from c program `bitfield_gen` in this repo.
1625#[expect(clippy::missing_docs_in_private_items)]
1626#[cfg(target_endian = "little")]
1627mod jvmti_cap_offsets {
1628    pub const OFFSET_CAN_TAG_OBJECTS: usize = 0x0001;
1629    pub const OFFSET_CAN_GENERATE_FIELD_MODIFICATION_EVENTS: usize = 0x0002;
1630    pub const OFFSET_CAN_GENERATE_FIELD_ACCESS_EVENTS: usize = 0x0004;
1631    pub const OFFSET_CAN_GET_BYTECODES: usize = 0x0008;
1632    pub const OFFSET_CAN_GET_SYNTHETIC_ATTRIBUTE: usize = 0x0010;
1633    pub const OFFSET_CAN_GET_OWNED_MONITOR_INFO: usize = 0x0020;
1634    pub const OFFSET_CAN_GET_CURRENT_CONTENDED_MONITOR: usize = 0x0040;
1635    pub const OFFSET_CAN_GET_MONITOR_INFO: usize = 0x0080;
1636    pub const OFFSET_CAN_POP_FRAME: usize = 0x0101;
1637    pub const OFFSET_CAN_REDEFINE_CLASSES: usize = 0x0102;
1638    pub const OFFSET_CAN_SIGNAL_THREAD: usize = 0x0104;
1639    pub const OFFSET_CAN_GET_SOURCE_FILE_NAME: usize = 0x0108;
1640    pub const OFFSET_CAN_GET_LINE_NUMBERS: usize = 0x0110;
1641    pub const OFFSET_CAN_GET_SOURCE_DEBUG_EXTENSION: usize = 0x0120;
1642    pub const OFFSET_CAN_ACCESS_LOCAL_VARIABLES: usize = 0x0140;
1643    pub const OFFSET_CAN_MAINTAIN_ORIGINAL_METHOD_ORDER: usize = 0x0180;
1644    pub const OFFSET_CAN_GENERATE_SINGLE_STEP_EVENTS: usize = 0x0201;
1645    pub const OFFSET_CAN_GENERATE_EXCEPTION_EVENTS: usize = 0x0202;
1646    pub const OFFSET_CAN_GENERATE_FRAME_POP_EVENTS: usize = 0x0204;
1647    pub const OFFSET_CAN_GENERATE_BREAKPOINT_EVENTS: usize = 0x0208;
1648    pub const OFFSET_CAN_SUSPEND: usize = 0x0210;
1649    pub const OFFSET_CAN_REDEFINE_ANY_CLASS: usize = 0x0220;
1650    pub const OFFSET_CAN_GET_CURRENT_THREAD_CPU_TIME: usize = 0x0240;
1651    pub const OFFSET_CAN_GET_THREAD_CPU_TIME: usize = 0x0280;
1652    pub const OFFSET_CAN_GENERATE_METHOD_ENTRY_EVENTS: usize = 0x0301;
1653    pub const OFFSET_CAN_GENERATE_METHOD_EXIT_EVENTS: usize = 0x0302;
1654    pub const OFFSET_CAN_GENERATE_ALL_CLASS_HOOK_EVENTS: usize = 0x0304;
1655    pub const OFFSET_CAN_GENERATE_COMPILED_METHOD_LOAD_EVENTS: usize = 0x0308;
1656    pub const OFFSET_CAN_GENERATE_MONITOR_EVENTS: usize = 0x0310;
1657    pub const OFFSET_CAN_GENERATE_VM_OBJECT_ALLOC_EVENTS: usize = 0x0320;
1658    pub const OFFSET_CAN_GENERATE_NATIVE_METHOD_BIND_EVENTS: usize = 0x0340;
1659    pub const OFFSET_CAN_GENERATE_GARBAGE_COLLECTION_EVENTS: usize = 0x0380;
1660    pub const OFFSET_CAN_GENERATE_OBJECT_FREE_EVENTS: usize = 0x0401;
1661    pub const OFFSET_CAN_FORCE_EARLY_RETURN: usize = 0x0402;
1662    pub const OFFSET_CAN_GET_OWNED_MONITOR_STACK_DEPTH_INFO: usize = 0x0404;
1663    pub const OFFSET_CAN_GET_CONSTANT_POOL: usize = 0x0408;
1664    pub const OFFSET_CAN_SET_NATIVE_METHOD_PREFIX: usize = 0x0410;
1665    pub const OFFSET_CAN_RETRANSFORM_CLASSES: usize = 0x0420;
1666    pub const OFFSET_CAN_RETRANSFORM_ANY_CLASS: usize = 0x0440;
1667    pub const OFFSET_CAN_GENERATE_RESOURCE_EXHAUSTION_HEAP_EVENTS: usize = 0x0480;
1668    pub const OFFSET_CAN_GENERATE_RESOURCE_EXHAUSTION_THREAD_EVENETS: usize = 0x0501;
1669    pub const OFFSET_CAN_GENERATE_EARLY_VMSTART: usize = 0x0502;
1670    pub const OFFSET_CAN_GENERATE_EARLY_CLASS_HOOK_EVENTS: usize = 0x0504;
1671    pub const OFFSET_CAN_GENERATE_SAMPLED_OBJECT_ALLOC_EVENTS: usize = 0x0508;
1672    pub const OFFSET_CAN_SUPPORT_VIRTUAL_THREADS: usize = 0x0510;
1673}
1674
1675#[expect(clippy::missing_docs_in_private_items)]
1676#[cfg(target_endian = "big")]
1677mod jvmti_cap_offsets {
1678    pub const OFFSET_CAN_TAG_OBJECTS: usize = 0x0080;
1679    pub const OFFSET_CAN_GENERATE_FIELD_MODIFICATION_EVENTS: usize = 0x0040;
1680    pub const OFFSET_CAN_GENERATE_FIELD_ACCESS_EVENTS: usize = 0x0020;
1681    pub const OFFSET_CAN_GET_BYTECODES: usize = 0x0010;
1682    pub const OFFSET_CAN_GET_SYNTHETIC_ATTRIBUTE: usize = 0x0008;
1683    pub const OFFSET_CAN_GET_OWNED_MONITOR_INFO: usize = 0x0004;
1684    pub const OFFSET_CAN_GET_CURRENT_CONTENDED_MONITOR: usize = 0x0002;
1685    pub const OFFSET_CAN_GET_MONITOR_INFO: usize = 0x0001;
1686    pub const OFFSET_CAN_POP_FRAME: usize = 0x0180;
1687    pub const OFFSET_CAN_REDEFINE_CLASSES: usize = 0x0140;
1688    pub const OFFSET_CAN_SIGNAL_THREAD: usize = 0x0120;
1689    pub const OFFSET_CAN_GET_SOURCE_FILE_NAME: usize = 0x0110;
1690    pub const OFFSET_CAN_GET_LINE_NUMBERS: usize = 0x0108;
1691    pub const OFFSET_CAN_GET_SOURCE_DEBUG_EXTENSION: usize = 0x0104;
1692    pub const OFFSET_CAN_ACCESS_LOCAL_VARIABLES: usize = 0x0102;
1693    pub const OFFSET_CAN_MAINTAIN_ORIGINAL_METHOD_ORDER: usize = 0x0101;
1694    pub const OFFSET_CAN_GENERATE_SINGLE_STEP_EVENTS: usize = 0x0280;
1695    pub const OFFSET_CAN_GENERATE_EXCEPTION_EVENTS: usize = 0x0240;
1696    pub const OFFSET_CAN_GENERATE_FRAME_POP_EVENTS: usize = 0x0220;
1697    pub const OFFSET_CAN_GENERATE_BREAKPOINT_EVENTS: usize = 0x0210;
1698    pub const OFFSET_CAN_SUSPEND: usize = 0x0208;
1699    pub const OFFSET_CAN_REDEFINE_ANY_CLASS: usize = 0x0204;
1700    pub const OFFSET_CAN_GET_CURRENT_THREAD_CPU_TIME: usize = 0x0202;
1701    pub const OFFSET_CAN_GET_THREAD_CPU_TIME: usize = 0x0201;
1702    pub const OFFSET_CAN_GENERATE_METHOD_ENTRY_EVENTS: usize = 0x0380;
1703    pub const OFFSET_CAN_GENERATE_METHOD_EXIT_EVENTS: usize = 0x0340;
1704    pub const OFFSET_CAN_GENERATE_ALL_CLASS_HOOK_EVENTS: usize = 0x0320;
1705    pub const OFFSET_CAN_GENERATE_COMPILED_METHOD_LOAD_EVENTS: usize = 0x0310;
1706    pub const OFFSET_CAN_GENERATE_MONITOR_EVENTS: usize = 0x0308;
1707    pub const OFFSET_CAN_GENERATE_VM_OBJECT_ALLOC_EVENTS: usize = 0x0304;
1708    pub const OFFSET_CAN_GENERATE_NATIVE_METHOD_BIND_EVENTS: usize = 0x0302;
1709    pub const OFFSET_CAN_GENERATE_GARBAGE_COLLECTION_EVENTS: usize = 0x0301;
1710    pub const OFFSET_CAN_GENERATE_OBJECT_FREE_EVENTS: usize = 0x0480;
1711    pub const OFFSET_CAN_FORCE_EARLY_RETURN: usize = 0x0440;
1712    pub const OFFSET_CAN_GET_OWNED_MONITOR_STACK_DEPTH_INFO: usize = 0x0420;
1713    pub const OFFSET_CAN_GET_CONSTANT_POOL: usize = 0x0410;
1714    pub const OFFSET_CAN_SET_NATIVE_METHOD_PREFIX: usize = 0x0408;
1715    pub const OFFSET_CAN_RETRANSFORM_CLASSES: usize = 0x0404;
1716    pub const OFFSET_CAN_RETRANSFORM_ANY_CLASS: usize = 0x0402;
1717    pub const OFFSET_CAN_GENERATE_RESOURCE_EXHAUSTION_HEAP_EVENTS: usize = 0x0401;
1718    pub const OFFSET_CAN_GENERATE_RESOURCE_EXHAUSTION_THREAD_EVENETS: usize = 0x0580;
1719    pub const OFFSET_CAN_GENERATE_EARLY_VMSTART: usize = 0x0540;
1720    pub const OFFSET_CAN_GENERATE_EARLY_CLASS_HOOK_EVENTS: usize = 0x0520;
1721    pub const OFFSET_CAN_GENERATE_SAMPLED_OBJECT_ALLOC_EVENTS: usize = 0x0510;
1722    pub const OFFSET_CAN_SUPPORT_VIRTUAL_THREADS: usize = 0x0508;
1723}
1724
1725#[expect(clippy::wildcard_imports)]
1726use crate::jvmti_cap_offsets::*;
1727
1728/// This macro generates an setter and getter for a field that is stored in the C jvmtiCapabilities bitfield struct
1729/// In rust we store the bitfield in a u128.
1730macro_rules! jvmtiCapField {
1731    ($getter:ident, $setter:ident, $constant:expr) => {
1732        #[must_use]
1733        pub const fn $getter(&self) -> bool {
1734            self.get($constant)
1735        }
1736
1737        pub const fn $setter(&mut self, value: bool) {
1738            self.set($constant, value);
1739        }
1740    };
1741}
1742
1743impl jvmtiCapabilities {
1744    /// Copies the raw data into the given slice.
1745    /// # Panics
1746    /// if the target slice does not have the same length as `size()` returns
1747    #[inline(always)]
1748    pub const fn copy_to_slice(&self, target: &mut [u8]) {
1749        target.copy_from_slice(self.0.to_ne_bytes().as_slice());
1750    }
1751
1752    /// Copies the raw data from the given slice into this structure.
1753    /// # Panics
1754    /// if the target slice does not have the same length as `size()` returns
1755    #[inline(always)]
1756    pub const fn copy_from_slice(&mut self, data: &[u8]) {
1757        let mut raw = [0u8; 16];
1758        raw.copy_from_slice(data);
1759        self.0 = u128::from_ne_bytes(raw);
1760    }
1761
1762    ///Returns the amount of bytes needed to access the raw data in this struct.
1763    #[inline(always)]
1764    #[must_use]
1765    pub const fn size(&self) -> usize {
1766        16
1767    }
1768
1769    /// C compatible bitfield setter, translates the offset constant into a slice index and bitmask.
1770    #[expect(clippy::cast_possible_truncation)]
1771    const fn set(&mut self, offset: usize, value: bool) {
1772        let idx = offset >> 8;
1773        let mask = (offset & 0xFF) as u8;
1774        let mut raw = self.0.to_ne_bytes();
1775        if value {
1776            raw[idx] |= mask;
1777        } else {
1778            raw[idx] &= !mask;
1779        }
1780        self.0 = u128::from_ne_bytes(raw);
1781    }
1782
1783    /// C compatible bitfield getter, translates the offset constant into a slice index and bitmask.
1784    #[must_use]
1785    #[expect(clippy::cast_possible_truncation)]
1786    const fn get(&self, offset: usize) -> bool {
1787        let idx = offset >> 8;
1788        let mask = (offset & 0xFF) as u8;
1789        let raw = self.0.to_ne_bytes();
1790        raw[idx] & mask != 0
1791    }
1792
1793    jvmtiCapField!(can_tag_objects, set_can_tag_objects, OFFSET_CAN_TAG_OBJECTS);
1794    jvmtiCapField!(
1795        can_generate_field_modification_events,
1796        set_can_generate_field_modification_events,
1797        OFFSET_CAN_GENERATE_FIELD_MODIFICATION_EVENTS
1798    );
1799    jvmtiCapField!(
1800        can_generate_field_access_events,
1801        set_can_generate_field_access_events,
1802        OFFSET_CAN_GENERATE_FIELD_ACCESS_EVENTS
1803    );
1804    jvmtiCapField!(can_get_bytecodes, set_can_get_bytecodes, OFFSET_CAN_GET_BYTECODES);
1805    jvmtiCapField!(can_get_synthetic_attribute, set_can_get_synthetic_attribute, OFFSET_CAN_GET_SYNTHETIC_ATTRIBUTE);
1806    jvmtiCapField!(can_get_owned_monitor_info, set_can_get_owned_monitor_info, OFFSET_CAN_GET_OWNED_MONITOR_INFO);
1807    jvmtiCapField!(
1808        can_get_current_contended_monitor,
1809        set_can_get_current_contended_monitor,
1810        OFFSET_CAN_GET_CURRENT_CONTENDED_MONITOR
1811    );
1812    jvmtiCapField!(can_get_monitor_info, set_can_get_monitor_info, OFFSET_CAN_GET_MONITOR_INFO);
1813    jvmtiCapField!(can_pop_frame, set_can_pop_frame, OFFSET_CAN_POP_FRAME);
1814    jvmtiCapField!(can_redefine_classes, set_can_redefine_classes, OFFSET_CAN_REDEFINE_CLASSES);
1815    jvmtiCapField!(can_signal_thread, set_can_signal_thread, OFFSET_CAN_SIGNAL_THREAD);
1816    jvmtiCapField!(can_get_source_file_name, set_can_get_source_file_name, OFFSET_CAN_GET_SOURCE_FILE_NAME);
1817    jvmtiCapField!(can_get_line_numbers, set_can_get_line_numbers, OFFSET_CAN_GET_LINE_NUMBERS);
1818    jvmtiCapField!(can_get_source_debug_extension, set_can_get_source_debug_extension, OFFSET_CAN_GET_SOURCE_DEBUG_EXTENSION);
1819    jvmtiCapField!(can_access_local_variables, set_can_access_local_variables, OFFSET_CAN_ACCESS_LOCAL_VARIABLES);
1820    jvmtiCapField!(
1821        can_maintain_original_method_order,
1822        set_can_maintain_original_method_order,
1823        OFFSET_CAN_MAINTAIN_ORIGINAL_METHOD_ORDER
1824    );
1825    jvmtiCapField!(can_generate_single_step_events, set_generate_single_step_events, OFFSET_CAN_GENERATE_SINGLE_STEP_EVENTS);
1826    jvmtiCapField!(can_generate_exception_events, set_can_generate_exception_events, OFFSET_CAN_GENERATE_EXCEPTION_EVENTS);
1827    jvmtiCapField!(can_generate_frame_pop_events, set_can_generate_frame_pop_events, OFFSET_CAN_GENERATE_FRAME_POP_EVENTS);
1828    jvmtiCapField!(can_generate_breakpoint_events, set_can_generate_breakpoint_events, OFFSET_CAN_GENERATE_BREAKPOINT_EVENTS);
1829    jvmtiCapField!(can_suspend, set_can_suspend, OFFSET_CAN_SUSPEND);
1830    jvmtiCapField!(can_redefine_any_class, set_can_redefine_any_class, OFFSET_CAN_REDEFINE_ANY_CLASS);
1831    jvmtiCapField!(can_get_current_thread_cpu_time, set_can_get_current_thread_cpu_time, OFFSET_CAN_GET_CURRENT_THREAD_CPU_TIME);
1832    jvmtiCapField!(can_get_thread_cpu_time, set_can_get_thread_cpu_time, OFFSET_CAN_GET_THREAD_CPU_TIME);
1833    jvmtiCapField!(
1834        can_generate_method_entry_events,
1835        set_can_generate_method_entry_events,
1836        OFFSET_CAN_GENERATE_METHOD_ENTRY_EVENTS
1837    );
1838    jvmtiCapField!(can_generate_method_exit_events, set_can_generate_method_exit_events, OFFSET_CAN_GENERATE_METHOD_EXIT_EVENTS);
1839    jvmtiCapField!(
1840        can_generate_all_class_hook_events,
1841        set_can_generate_all_class_hook_events,
1842        OFFSET_CAN_GENERATE_ALL_CLASS_HOOK_EVENTS
1843    );
1844    jvmtiCapField!(
1845        can_generate_compiled_method_load_events,
1846        set_can_generate_compiled_method_load_events,
1847        OFFSET_CAN_GENERATE_COMPILED_METHOD_LOAD_EVENTS
1848    );
1849    jvmtiCapField!(can_generate_monitor_events, set_can_generate_monitor_events, OFFSET_CAN_GENERATE_MONITOR_EVENTS);
1850    jvmtiCapField!(
1851        can_generate_vm_object_alloc_events,
1852        set_can_generate_vm_object_alloc_events,
1853        OFFSET_CAN_GENERATE_VM_OBJECT_ALLOC_EVENTS
1854    );
1855    jvmtiCapField!(
1856        can_generate_native_method_bind_events,
1857        set_can_generate_native_method_bind_events,
1858        OFFSET_CAN_GENERATE_NATIVE_METHOD_BIND_EVENTS
1859    );
1860    jvmtiCapField!(
1861        can_generate_garbage_collection_events,
1862        set_can_generate_garbage_collection_events,
1863        OFFSET_CAN_GENERATE_GARBAGE_COLLECTION_EVENTS
1864    );
1865    jvmtiCapField!(can_generate_object_free_events, set_can_generate_object_free_events, OFFSET_CAN_GENERATE_OBJECT_FREE_EVENTS);
1866    jvmtiCapField!(can_force_early_return, set_can_force_early_return, OFFSET_CAN_FORCE_EARLY_RETURN);
1867    jvmtiCapField!(
1868        can_get_owned_monitor_stack_depth_info,
1869        set_can_get_owned_monitor_stack_depth_info,
1870        OFFSET_CAN_GET_OWNED_MONITOR_STACK_DEPTH_INFO
1871    );
1872    jvmtiCapField!(can_get_constant_pool, set_can_get_constant_pool, OFFSET_CAN_GET_CONSTANT_POOL);
1873    jvmtiCapField!(can_set_native_method_prefix, set_can_set_native_method_prefix, OFFSET_CAN_SET_NATIVE_METHOD_PREFIX);
1874    jvmtiCapField!(can_retransform_classes, set_can_retransform_classes, OFFSET_CAN_RETRANSFORM_CLASSES);
1875    jvmtiCapField!(can_retransform_any_class, set_can_retransform_any_class, OFFSET_CAN_RETRANSFORM_ANY_CLASS);
1876    jvmtiCapField!(
1877        can_generate_resource_exhaustion_heap_events,
1878        set_can_generate_resource_exhaustion_heap_events,
1879        OFFSET_CAN_GENERATE_RESOURCE_EXHAUSTION_HEAP_EVENTS
1880    );
1881    jvmtiCapField!(
1882        can_generate_resource_exhaustion_threads_events,
1883        set_can_generate_resource_exhaustion_threads_events,
1884        OFFSET_CAN_GENERATE_RESOURCE_EXHAUSTION_THREAD_EVENETS
1885    );
1886    jvmtiCapField!(can_generate_early_vmstart, set_can_generate_early_vmstart, OFFSET_CAN_GENERATE_EARLY_VMSTART);
1887    jvmtiCapField!(
1888        can_generate_early_class_hook_events,
1889        set_can_generate_early_class_hook_events,
1890        OFFSET_CAN_GENERATE_EARLY_CLASS_HOOK_EVENTS
1891    );
1892    jvmtiCapField!(
1893        can_generate_sampled_object_alloc_events,
1894        set_can_generate_sampled_object_alloc_events,
1895        OFFSET_CAN_GENERATE_SAMPLED_OBJECT_ALLOC_EVENTS
1896    );
1897    jvmtiCapField!(can_support_virtual_threads, set_can_support_virtual_threads, OFFSET_CAN_SUPPORT_VIRTUAL_THREADS);
1898}
1899
1900impl Display for jvmtiCapabilities {
1901    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1902        f.write_fmt(format_args!(
1903            "jvmtiCapabilities {{
1904    can_tag_objects: {}
1905    can_generate_field_modification_events: {}
1906    can_generate_field_access_events: {}
1907    can_get_bytecodes: {}
1908    can_get_synthetic_attribute: {}
1909    can_get_owned_monitor_info: {}
1910    can_get_current_contended_monitor: {}
1911    can_get_monitor_info: {}
1912    can_pop_frame: {}
1913    can_redefine_classes: {}
1914    can_signal_thread: {}
1915    can_get_source_file_name: {}
1916    can_get_line_numbers: {}
1917    can_get_source_debug_extension: {}
1918    can_access_local_variables: {}
1919    can_maintain_original_method_order: {}
1920    can_generate_single_step_events: {}
1921    can_generate_exception_events: {}
1922    can_generate_frame_pop_events: {}
1923    can_generate_breakpoint_events: {}
1924    can_suspend: {}
1925    can_redefine_any_class: {}
1926    can_get_current_thread_cpu_time: {}
1927    can_get_thread_cpu_time: {}
1928    can_generate_method_entry_events: {}
1929    can_generate_method_exit_events: {}
1930    can_generate_all_class_hook_events: {}
1931    can_generate_compiled_method_load_events: {}
1932    can_generate_monitor_events: {}
1933    can_generate_vm_object_alloc_events: {}
1934    can_generate_native_method_bind_events: {}
1935    can_generate_garbage_collection_events: {}
1936    can_generate_object_free_events: {}
1937    can_force_early_return: {}
1938    can_get_owned_monitor_stack_depth_info: {}
1939    can_get_constant_pool: {}
1940    can_set_native_method_prefix: {}
1941    can_retransform_classes: {}
1942    can_retransform_any_class: {}
1943    can_generate_resource_exhaustion_heap_events: {}
1944    can_generate_resource_exhaustion_threads_events: {}
1945    can_generate_early_vmstart: {}
1946    can_generate_early_class_hook_events: {}
1947    can_generate_sampled_object_alloc_events: {}
1948    can_support_virtual_threads: {}
1949}}",
1950            self.can_tag_objects(),
1951            self.can_generate_field_modification_events(),
1952            self.can_generate_field_access_events(),
1953            self.can_get_bytecodes(),
1954            self.can_get_synthetic_attribute(),
1955            self.can_get_owned_monitor_info(),
1956            self.can_get_current_contended_monitor(),
1957            self.can_get_monitor_info(),
1958            self.can_pop_frame(),
1959            self.can_redefine_classes(),
1960            self.can_signal_thread(),
1961            self.can_get_source_file_name(),
1962            self.can_get_line_numbers(),
1963            self.can_get_source_debug_extension(),
1964            self.can_access_local_variables(),
1965            self.can_maintain_original_method_order(),
1966            self.can_generate_single_step_events(),
1967            self.can_generate_exception_events(),
1968            self.can_generate_frame_pop_events(),
1969            self.can_generate_breakpoint_events(),
1970            self.can_suspend(),
1971            self.can_redefine_any_class(),
1972            self.can_get_current_thread_cpu_time(),
1973            self.can_get_thread_cpu_time(),
1974            self.can_generate_method_entry_events(),
1975            self.can_generate_method_exit_events(),
1976            self.can_generate_all_class_hook_events(),
1977            self.can_generate_compiled_method_load_events(),
1978            self.can_generate_monitor_events(),
1979            self.can_generate_vm_object_alloc_events(),
1980            self.can_generate_native_method_bind_events(),
1981            self.can_generate_garbage_collection_events(),
1982            self.can_generate_object_free_events(),
1983            self.can_force_early_return(),
1984            self.can_get_owned_monitor_stack_depth_info(),
1985            self.can_get_constant_pool(),
1986            self.can_set_native_method_prefix(),
1987            self.can_retransform_classes(),
1988            self.can_retransform_any_class(),
1989            self.can_generate_resource_exhaustion_heap_events(),
1990            self.can_generate_resource_exhaustion_threads_events(),
1991            self.can_generate_early_vmstart(),
1992            self.can_generate_early_class_hook_events(),
1993            self.can_generate_sampled_object_alloc_events(),
1994            self.can_support_virtual_threads(),
1995        ))
1996    }
1997}
1998
1999#[repr(C)]
2000#[derive(Debug, Default, Clone, Copy)]
2001pub struct jvmtiHeapReferenceInfoReserved {
2002    pub reserved1: jlong,
2003    pub reserved2: jlong,
2004    pub reserved3: jlong,
2005    pub reserved4: jlong,
2006    pub reserved5: jlong,
2007    pub reserved6: jlong,
2008    pub reserved7: jlong,
2009    pub reserved8: jlong,
2010}
2011
2012pub const JVMTI_HEAP_FILTER_TAGGED: jint = 0x4;
2013pub const JVMTI_HEAP_FILTER_UNTAGGED: jint = 0x8;
2014pub const JVMTI_HEAP_FILTER_CLASS_TAGGED: jint = 0x10;
2015pub const JVMTI_HEAP_FILTER_CLASS_UNTAGGED: jint = 0x20;
2016pub const JVMTI_VISIT_OBJECTS: jint = 0x100;
2017pub const JVMTI_VISIT_ABORT: jint = 0x8000;
2018
2019#[repr(C)]
2020#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash, Ord, PartialOrd)]
2021pub enum jvmtiHeapReferenceKind {
2022    CLASS = 0x1,
2023    FIELD = 0x2,
2024    ARRAY_ELEMENT = 0x3,
2025    CLASS_LOADER = 0x4,
2026    SIGNERS = 0x5,
2027    PROTECTION_DOMAIN = 0x6,
2028    INTERFACE = 0x7,
2029    STATIC_FIELD = 0x8,
2030    CONSTANT_POOL = 0x9,
2031    SUPERCLASS = 0x10,
2032    JNI_GLOBAL = 0x21,
2033    SYSTEM_CLASS = 0x22,
2034    MONITOR = 0x23,
2035    STACK_LOCAL = 0x24,
2036    JNI_LOCAL = 0x25,
2037    THREAD = 0x26,
2038    OTHER = 0x27,
2039}
2040pub const JVMTI_HEAP_REFERENCE_CLASS: jint = 0x1;
2041
2042pub const JVMTI_HEAP_REFERENCE_FIELD: jint = 0x2;
2043pub const JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT: jint = 0x3;
2044pub const JVMTI_HEAP_REFERENCE_CLASS_LOADER: jint = 0x4;
2045pub const JVMTI_HEAP_REFERENCE_SIGNERS: jint = 0x5;
2046pub const JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN: jint = 0x6;
2047pub const JVMTI_HEAP_REFERENCE_INTERFACE: jint = 0x7;
2048pub const JVMTI_HEAP_REFERENCE_STATIC_FIELD: jint = 0x8;
2049pub const JVMTI_HEAP_REFERENCE_CONSTANT_POOL: jint = 0x9;
2050pub const JVMTI_HEAP_REFERENCE_SUPERCLASS: jint = 0x10;
2051pub const JVMTI_HEAP_REFERENCE_JNI_GLOBAL: jint = 0x21;
2052pub const JVMTI_HEAP_REFERENCE_SYSTEM_CLASS: jint = 0x22;
2053pub const JVMTI_HEAP_REFERENCE_MONITOR: jint = 0x23;
2054pub const JVMTI_HEAP_REFERENCE_STACK_LOCAL: jint = 0x24;
2055pub const JVMTI_HEAP_REFERENCE_JNI_LOCAL: jint = 0x25;
2056pub const JVMTI_HEAP_REFERENCE_THREAD: jint = 0x26;
2057pub const JVMTI_HEAP_REFERENCE_OTHER: jint = 0x27;
2058
2059#[repr(C)]
2060#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash, Ord, PartialOrd)]
2061pub enum jvmtiPrimitiveType {
2062    JVMTI_PRIMITIVE_TYPE_BOOLEAN = 90,
2063    JVMTI_PRIMITIVE_TYPE_BYTE = 66,
2064    JVMTI_PRIMITIVE_TYPE_CHAR = 67,
2065    JVMTI_PRIMITIVE_TYPE_SHORT = 83,
2066    JVMTI_PRIMITIVE_TYPE_INT = 73,
2067    JVMTI_PRIMITIVE_TYPE_LONG = 74,
2068    JVMTI_PRIMITIVE_TYPE_FLOAT = 70,
2069    JVMTI_PRIMITIVE_TYPE_DOUBLE = 68,
2070}
2071pub const JVMTI_PRIMITIVE_TYPE_BOOLEAN: c_int = 90;
2072pub const JVMTI_PRIMITIVE_TYPE_BYTE: c_int = 66;
2073pub const JVMTI_PRIMITIVE_TYPE_CHAR: c_int = 67;
2074pub const JVMTI_PRIMITIVE_TYPE_SHORT: c_int = 83;
2075pub const JVMTI_PRIMITIVE_TYPE_INT: c_int = 73;
2076pub const JVMTI_PRIMITIVE_TYPE_LONG: c_int = 74;
2077pub const JVMTI_PRIMITIVE_TYPE_FLOAT: c_int = 70;
2078pub const JVMTI_PRIMITIVE_TYPE_DOUBLE: c_int = 68;
2079
2080#[repr(C)]
2081#[derive(Debug, Default, Clone, Copy)]
2082pub struct jvmtiHeapReferenceInfoField {
2083    pub index: jint,
2084}
2085
2086#[repr(C)]
2087#[derive(Debug, Default, Clone, Copy)]
2088pub struct jvmtiHeapReferenceInfoArray {
2089    pub index: jint,
2090}
2091
2092#[repr(C)]
2093#[derive(Debug, Default, Clone, Copy)]
2094pub struct jvmtiHeapReferenceInfoConstantPool {
2095    pub index: jint,
2096}
2097
2098#[repr(C)]
2099#[derive(Debug, Clone, Copy)]
2100pub struct jvmtiHeapReferenceInfoStackLocal {
2101    pub thread_tag: jlong,
2102    pub thread_id: jlong,
2103    pub depth: jint,
2104    pub method: jmethodID,
2105    pub location: jlocation,
2106    pub slot: jint,
2107}
2108
2109impl Default for jvmtiHeapReferenceInfoStackLocal {
2110    fn default() -> Self {
2111        Self {
2112            thread_tag: 0,
2113            thread_id: 0,
2114            depth: 0,
2115            method: null_mut(),
2116            location: 0,
2117            slot: 0,
2118        }
2119    }
2120}
2121
2122#[repr(C)]
2123#[derive(Debug, Clone, Copy)]
2124pub struct jvmtiHeapReferenceInfoJniLocal {
2125    pub thread_tag: jlong,
2126    pub thread_id: jlong,
2127    pub depth: jint,
2128    pub method: jmethodID,
2129}
2130
2131impl Default for jvmtiHeapReferenceInfoJniLocal {
2132    fn default() -> Self {
2133        Self {
2134            thread_tag: 0,
2135            thread_id: 0,
2136            depth: 0,
2137            method: null_mut(),
2138        }
2139    }
2140}
2141
2142#[repr(C)]
2143pub union jvmtiHeapReferenceInfo {
2144    pub field: jvmtiHeapReferenceInfoField,
2145    pub array: jvmtiHeapReferenceInfoArray,
2146    pub constant_pool: jvmtiHeapReferenceInfoConstantPool,
2147    pub stack_local: jvmtiHeapReferenceInfoStackLocal,
2148    pub jni_local: jvmtiHeapReferenceInfoJniLocal,
2149    pub other: jvmtiHeapReferenceInfoReserved,
2150}
2151
2152pub type jvmtiHeapIterationCallback = extern "system" fn(class_tag: jlong, size: jlong, tag_ptr: *mut jlong, length: jint, user_data: *mut c_void) -> jint;
2153pub type jvmtiHeapReferenceCallback = extern "system" fn(
2154    reference_kind: jvmtiHeapReferenceKind,
2155    reference_info: *const jvmtiHeapReferenceInfo,
2156    class_tag: jlong,
2157    referrer_class_tag: jlong,
2158    size: jlong,
2159    tag_ptr: *mut jlong,
2160    referrer_tag_ptr: *mut jlong,
2161    length: jint,
2162    user_data: *mut c_void,
2163) -> jint;
2164
2165pub type jvmtiPrimitiveFieldCallback = extern "system" fn(
2166    kind: jvmtiHeapReferenceKind,
2167    info: *const jvmtiHeapReferenceInfo,
2168    object_class_tag: jlong,
2169    object_tag_ptr: *mut jlong,
2170    value: jvalue,
2171    value_type: jvmtiPrimitiveType,
2172    user_data: *mut c_void,
2173) -> jint;
2174
2175pub type jvmtiArrayPrimitiveValueCallback = extern "system" fn(
2176    class_tag: jlong,
2177    size: jlong,
2178    tag_ptr: *mut jlong,
2179    element_count: jint,
2180    element_type: jvmtiPrimitiveType,
2181    elements: *const c_void,
2182    user_data: *mut c_void,
2183) -> jint;
2184
2185pub type jvmtiStringPrimitiveValueCallback =
2186    extern "system" fn(class_tag: jlong, size: jlong, tag_ptr: *mut jlong, value: *const jchar, value_length: jint, user_data: *mut c_void) -> jint;
2187
2188pub type jvmtiReservedCallback = extern "system" fn() -> jint;
2189
2190#[repr(C)]
2191#[derive(Debug, Clone, Default)]
2192pub struct jvmtiHeapCallbacks {
2193    pub heap_iteration_callback: Option<jvmtiHeapIterationCallback>,
2194    pub heap_reference_callback: Option<jvmtiHeapReferenceCallback>,
2195    pub primitive_field_callback: Option<jvmtiPrimitiveFieldCallback>,
2196    pub array_primitive_value_callback: Option<jvmtiArrayPrimitiveValueCallback>,
2197    pub string_primitive_value_callback: Option<jvmtiStringPrimitiveValueCallback>,
2198    pub reserved5: Option<jvmtiReservedCallback>,
2199    pub reserved6: Option<jvmtiReservedCallback>,
2200    pub reserved7: Option<jvmtiReservedCallback>,
2201    pub reserved8: Option<jvmtiReservedCallback>,
2202    pub reserved9: Option<jvmtiReservedCallback>,
2203    pub reserved10: Option<jvmtiReservedCallback>,
2204    pub reserved11: Option<jvmtiReservedCallback>,
2205    pub reserved12: Option<jvmtiReservedCallback>,
2206    pub reserved13: Option<jvmtiReservedCallback>,
2207    pub reserved14: Option<jvmtiReservedCallback>,
2208    pub reserved15: Option<jvmtiReservedCallback>,
2209}
2210
2211#[derive(Debug, Default, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
2212#[repr(C)]
2213pub enum jvmtiIterationControl {
2214    #[default]
2215    JVMTI_ITERATION_ABORT = 0,
2216    JVMTI_ITERATION_CONTINUE = 1,
2217    JVMTI_ITERATION_IGNORE = 2,
2218}
2219
2220/// jvmtiHeapRootKind cant enum this because we are called with it, making addition in a future version of JVMTI UB in rust.
2221pub type jvmtiHeapRootKind = c_int;
2222pub const JVMTI_HEAP_ROOT_JNI_GLOBAL: jvmtiHeapRootKind = 1;
2223pub const JVMTI_HEAP_ROOT_SYSTEM_CLASS: jvmtiHeapRootKind = 2;
2224pub const JVMTI_HEAP_ROOT_MONITOR: jvmtiHeapRootKind = 3;
2225pub const JVMTI_HEAP_ROOT_STACK_LOCAL: jvmtiHeapRootKind = 4;
2226pub const JVMTI_HEAP_ROOT_JNI_LOCAL: jvmtiHeapRootKind = 5;
2227pub const JVMTI_HEAP_ROOT_THREAD: jvmtiHeapRootKind = 6;
2228pub const JVMTI_HEAP_ROOT_OTHER: jvmtiHeapRootKind = 7;
2229
2230/// jvmtiHeapRootKind cant enum this because we are called with it, making addition in a future version of JVMTI UB in rust.
2231pub type jvmtiObjectReferenceKind = c_int;
2232
2233pub const JVMTI_REFERENCE_CLASS: jvmtiObjectReferenceKind = 1;
2234pub const JVMTI_REFERENCE_FIELD: jvmtiObjectReferenceKind = 2;
2235pub const JVMTI_REFERENCE_ARRAY_ELEMENT: jvmtiObjectReferenceKind = 3;
2236pub const JVMTI_REFERENCE_CLASS_LOADER: jvmtiObjectReferenceKind = 4;
2237pub const JVMTI_REFERENCE_SIGNERS: jvmtiObjectReferenceKind = 5;
2238pub const JVMTI_REFERENCE_PROTECTION_DOMAIN: jvmtiObjectReferenceKind = 6;
2239pub const JVMTI_REFERENCE_INTERFACE: jvmtiObjectReferenceKind = 7;
2240pub const JVMTI_REFERENCE_STATIC_FIELD: jvmtiObjectReferenceKind = 8;
2241pub const JVMTI_REFERENCE_CONSTANT_POOL: jvmtiObjectReferenceKind = 9;
2242
2243// GetClassStatus bitmask values
2244
2245/// Class bytecodes have been verified
2246pub const JVMTI_CLASS_STATUS_VERIFIED: jint = 1;
2247/// Class preparation is complete
2248pub const JVMTI_CLASS_STATUS_PREPARED: jint = 2;
2249/// Class initialization is complete. Static initializer has been run.
2250pub const JVMTI_CLASS_STATUS_INITIALIZED: jint = 4;
2251/// Error during initialization makes class unusable
2252pub const JVMTI_CLASS_STATUS_ERROR: jint = 8;
2253/// Class is an array. If set, all other bits are zero.
2254pub const JVMTI_CLASS_STATUS_ARRAY: jint = 16;
2255/// Class is a primitive class (for example, java.lang.Integer.TYPE). If set, all other bits are zero.
2256pub const JVMTI_CLASS_STATUS_PRIMITIVE: jint = 32;
2257
2258#[derive(Debug, Default, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
2259#[repr(C)]
2260pub enum jvmtiHeapObjectFilter {
2261    JVMTI_HEAP_OBJECT_TAGGED = 1,
2262    JVMTI_HEAP_OBJECT_UNTAGGED = 2,
2263    #[default]
2264    JVMTI_HEAP_OBJECT_EITHER = 3,
2265}
2266
2267pub type jvmtiHeapObjectCallback = extern "system" fn(class_tag: jlong, size: jlong, tag_ptr: *mut jlong, user_data: *mut c_void) -> jvmtiIterationControl;
2268
2269pub type jvmtiHeapRootCallback =
2270    extern "system" fn(root_kind: jvmtiHeapRootKind, class_tag: jlong, size: jlong, tag_ptr: *mut jlong, user_data: *mut c_void) -> jvmtiIterationControl;
2271
2272pub type jvmtiStackReferenceCallback = extern "system" fn(
2273    root_kind: jvmtiHeapRootKind,
2274    class_tag: jlong,
2275    size: jlong,
2276    tag_ptr: *mut jlong,
2277    thread_tag: jlong,
2278    depth: jint,
2279    method: jmethodID,
2280    slot: jint,
2281    user_data: *mut c_void,
2282) -> jvmtiIterationControl;
2283
2284pub type jvmtiObjectReferenceCallback = extern "system" fn(
2285    reference_kind: jvmtiObjectReferenceKind,
2286    class_tag: jlong,
2287    size: jlong,
2288    tag_ptr: *mut jlong,
2289    referrer_tag: jlong,
2290    referrer_index: jint,
2291    user_data: *mut c_void,
2292) -> jvmtiIterationControl;
2293
2294impl From<jvmtiHeapIterationCallback> for jvmtiHeapCallbacks {
2295    fn from(value: jvmtiHeapIterationCallback) -> Self {
2296        Self {
2297            heap_iteration_callback: Some(value),
2298            ..Default::default()
2299        }
2300    }
2301}
2302
2303impl From<jvmtiHeapReferenceCallback> for jvmtiHeapCallbacks {
2304    fn from(value: jvmtiHeapReferenceCallback) -> Self {
2305        Self {
2306            heap_reference_callback: Some(value),
2307            ..Default::default()
2308        }
2309    }
2310}
2311
2312impl From<jvmtiPrimitiveFieldCallback> for jvmtiHeapCallbacks {
2313    fn from(value: jvmtiPrimitiveFieldCallback) -> Self {
2314        Self {
2315            primitive_field_callback: Some(value),
2316            ..Default::default()
2317        }
2318    }
2319}
2320
2321impl From<jvmtiArrayPrimitiveValueCallback> for jvmtiHeapCallbacks {
2322    fn from(value: jvmtiArrayPrimitiveValueCallback) -> Self {
2323        Self {
2324            array_primitive_value_callback: Some(value),
2325            ..Default::default()
2326        }
2327    }
2328}
2329
2330impl From<jvmtiStringPrimitiveValueCallback> for jvmtiHeapCallbacks {
2331    fn from(value: jvmtiStringPrimitiveValueCallback) -> Self {
2332        Self {
2333            string_primitive_value_callback: Some(value),
2334            ..Default::default()
2335        }
2336    }
2337}
2338
2339pub type jvmtiStartFunction = extern "system" fn(JVMTIEnv, JNIEnv, *mut c_void);
2340
2341#[derive(Debug, Clone, Copy)]
2342#[repr(C)]
2343pub struct jvmtiClassDefinition {
2344    pub klass: jclass,
2345    pub class_byte_count: jint,
2346    pub class_bytes: *const c_uchar,
2347}
2348
2349#[derive(Debug, Clone, Copy)]
2350#[repr(C)]
2351pub struct jvmtiMonitorUsage {
2352    pub owner: jthread,
2353    pub entry_count: jint,
2354    pub waiter_count: jint,
2355    pub waiters: *mut jthread,
2356    pub notify_waiter_count: jint,
2357    pub notify_waiters: *mut jthread,
2358}
2359
2360#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
2361#[repr(C)]
2362pub struct jvmtiLineNumberEntry {
2363    pub start_location: jlocation,
2364    pub line_number: jint,
2365}
2366
2367#[derive(Debug, Clone, Copy)]
2368#[repr(C)]
2369pub struct jvmtiLocalVariableEntry {
2370    pub start_location: jlocation,
2371    pub length: jint,
2372    pub name: *mut c_char,
2373    pub signature: *mut c_char,
2374    pub generic_signature: *mut c_char,
2375    pub slot: jint,
2376}
2377
2378/// Vtable of `JVMTIEnv` is passed like this.
2379type JVMTIEnvVTable = SyncMutPtr<*mut *mut c_void>;
2380
2381#[derive(Debug, Clone, Copy)]
2382#[repr(transparent)]
2383pub struct JVMTIEnv {
2384    /// The vtable that contains all the functions
2385    vtable: JVMTIEnvVTable,
2386}
2387
2388impl SealedEnvVTable for JVMTIEnv {
2389    fn can_jni() -> bool {
2390        false
2391    }
2392
2393    fn can_jvmti() -> bool {
2394        true
2395    }
2396}
2397
2398impl From<*mut c_void> for JVMTIEnv {
2399    #[allow(clippy::not_unsafe_ptr_arg_deref)]
2400    fn from(value: *mut c_void) -> Self {
2401        unsafe {
2402            Self {
2403                vtable: value.as_sync_mut().cast(),
2404            }
2405        }
2406    }
2407}
2408
2409impl JVMTIEnv {
2410    ///
2411    /// resolves the function pointer given its linkage index of the jvmt vtable.
2412    /// The indices are documented and guaranteed by the Oracle JVM Spec.
2413    /// NOTE: Oracle has documented them with index starting at 1 so you have to subtract 1!
2414    ///
2415    #[inline(always)]
2416    unsafe fn jvmti<X>(&self, index: usize) -> X {
2417        unsafe { core::mem::transmute_copy(&(self.vtable.read_volatile().add(index).read_volatile())) }
2418    }
2419
2420    /// Returns the raw jvmti vtable.
2421    /// Calling this function is usually not needed.
2422    #[must_use]
2423    pub const fn vtable(&self) -> *mut c_void {
2424        self.vtable.inner().cast()
2425    }
2426
2427    /// Return the JVM TI version via `version_ptr`.
2428    ///
2429    /// The return value is the version identifier.
2430    /// The version identifier includes major, minor and micro version as well as the interface type.
2431    ///
2432    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetVersionNumber>
2433    ///
2434    /// # Safety
2435    /// JVM Implementation dependant
2436    ///
2437    pub unsafe fn GetVersionNumber(&self, version_ptr: *mut jint) -> jvmtiError {
2438        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jint) -> jvmtiError>(87)(self.vtable, version_ptr) }
2439    }
2440
2441    /// Return the current phase of VM execution.
2442    ///
2443    /// The phases proceed in sequence:
2444    /// * `JVMTI_PHASE_ONLOAD` - `OnLoad` phase: while in the `Agent_OnLoad` or, for statically linked agents, the `Agent_OnLoad_<agent-lib-name>` function.
2445    /// * `JVMTI_PHASE_PRIMORDIAL` - `Primordial` phase: between return from `Agent_OnLoad` or `Agent_OnLoad_<agent-lib-name>` and the `VMStart` event.
2446    /// * `JVMTI_PHASE_START` - `Start` phase: when the `VMStart` event is sent and until the `VMInit` event is sent.
2447    /// * `JVMTI_PHASE_LIVE` - `Live` phase: when the `VMInit` event is sent and until the `VMDeath` event returns.
2448    /// * `JVMTI_PHASE_DEAD` - `Dead` phase: after the `VMDeath` event returns or after start-up failure.
2449    ///
2450    /// In the case of start-up failure the VM will proceed directly to the dead phase skipping
2451    /// intermediate phases and neither a `VMInit` nor `VMDeath` event will be sent.
2452    ///
2453    /// JNI functions (except the Invocation API) must only be used in the start or live phases.
2454    /// Most JVM TI events are sent only in the live phase.
2455    ///
2456    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetPhase>
2457    ///
2458    /// # Safety
2459    /// JVM Implementation dependant
2460    ///
2461    pub unsafe fn GetPhase(&self, phase: *mut jvmtiPhase) -> jvmtiError {
2462        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut c_int) -> jvmtiError>(132)(self.vtable, phase) }
2463    }
2464
2465    /// Allocate an area of memory through the JVM TI allocator.
2466    ///
2467    /// The allocated memory should be freed with Deallocate.
2468    ///
2469    ///  See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#Allocate>
2470    ///
2471    /// # Safety
2472    /// The receiver pointer must not be dangling.
2473    ///
2474    pub unsafe fn Allocate(&self, size: jlong, mem_ptr: *mut *mut c_uchar) -> jvmtiError {
2475        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jlong, *mut *mut c_uchar) -> jvmtiError>(45)(self.vtable, size, mem_ptr) }
2476    }
2477
2478    /// Deallocate mem using the JVM TI allocator.
2479    ///
2480    /// This function should be used to deallocate any memory allocated and returned by a JVM TI function (including memory allocated with Allocate).
2481    /// All allocated memory must be deallocated or the memory cannot be reclaimed.
2482    ///
2483    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#Deallocate>
2484    ///
2485    /// # Safety
2486    /// The pointer must have been allocated by the JVMTI allocator using allocate or returned by some JVMTI function.
2487    /// Naturally use after free problems may arise if the memory is used after this function is called.
2488    ///
2489    pub unsafe fn Deallocate<T>(&self, mem: *const T) -> jvmtiError {
2490        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const c_uchar) -> jvmtiError>(46)(self.vtable, mem.cast()) }
2491    }
2492
2493    /// Get the state of a thread.
2494    ///
2495    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetThreadStatee>
2496    ///
2497    /// # Safety
2498    /// The `thread` must be a valid strong reference to a thread.
2499    /// The `thread_state_ptr` must not be a dangling pointer.
2500    ///
2501    pub unsafe fn GetThreadState(&self, thread: jthread, thread_state_ptr: *mut jint) -> jvmtiError {
2502        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, *mut jint) -> jvmtiError>(16)(self.vtable, thread, thread_state_ptr) }
2503    }
2504
2505    /// Get the current thread.
2506    ///
2507    /// The current thread is the Java programming language thread which has called the function.
2508    /// 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.
2509    /// Note that most JVM TI functions that take a thread as an argument will accept null to mean the current thread.
2510    ///
2511    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetCurrentThread>
2512    ///
2513    /// # Safety
2514    /// The thread receiver pointer must not be dangling.
2515    ///
2516    pub unsafe fn GetCurrentThread(&self, thread: *mut jthread) -> jvmtiError {
2517        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jthread) -> jvmtiError>(17)(self.vtable, thread) }
2518    }
2519
2520    /// Get all live platform threads that are attached to the VM.
2521    ///
2522    /// The list of threads includes agent threads.
2523    /// It does not include virtual threads.
2524    /// A thread is live if `java.lang.Thread.isAlive()` would return true, that is, the thread has been started and has not yet terminated.
2525    /// The universe of threads is determined by the context of the JVM TI environment, which typically is all threads attached to the VM.
2526    ///
2527    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetAllThreads>
2528    ///
2529    /// # Safety
2530    /// All pointer parameters must not be dangling.
2531    ///
2532    pub unsafe fn GetAllThreads(&self, threads_count_ptr: *mut jint, threads_ptr: *mut *mut jthread) -> jvmtiError {
2533        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jint, *mut *mut jthread) -> jvmtiError>(3)(self.vtable, threads_count_ptr, threads_ptr) }
2534    }
2535
2536    /// Suspend the specified thread.
2537    ///
2538    /// If the calling thread is specified,
2539    /// this function will not return until some other thread calls `ResumeThread`.
2540    /// If the thread is currently suspended, this function does nothing and returns an error.
2541    ///
2542    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SuspendThread>
2543    ///
2544    /// # Safety
2545    /// The thread must be a valid strong reference to a thread.
2546    ///
2547    pub unsafe fn SuspendThread(&self, thread: jthread) -> jvmtiError {
2548        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread) -> jvmtiError>(4)(self.vtable, thread) }
2549    }
2550
2551    /// Suspend the `request_count` threads specified in the `request_list` array.
2552    ///
2553    /// Threads may be resumed with `ResumeThreadList` or `ResumeThread`.
2554    /// If the calling thread is specified in the `request_list` array, this function will not return until some other thread resumes it.
2555    /// Errors encountered in the suspension of a thread are returned in the results array, not in the return value of this function.
2556    /// Threads that are currently suspended do not change state.
2557    ///
2558    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SuspendThreadList>
2559    ///
2560    /// # Safety
2561    /// All threads must be valid strong references to a thread.
2562    /// the `request_list` parameter must be a valid array.
2563    /// None of the pointer parameters must be dangling.
2564    ///
2565    pub unsafe fn SuspendThreadList(&self, request_count: jint, request_list: *const jthread, results: *mut jvmtiError) -> jvmtiError {
2566        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, *const jthread, *mut jvmtiError) -> jvmtiError>(91)(self.vtable, request_count, request_list, results) }
2567    }
2568
2569    /// Suspend all virtual threads except those in the exception list.
2570    /// Virtual threads that are currently suspended do not change state.
2571    /// Virtual threads may be resumed with `ResumeAllVirtualThreads` or `ResumeThreadList` or `ResumeThread`.
2572    ///
2573    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SuspendAllVirtualThreads>
2574    ///
2575    /// # Safety
2576    /// All threads must be valid strong references to a thread.
2577    /// the `except_list` and `except_count` parameter must be a valid array.
2578    /// `except_list` must not be a dangling pointer.
2579    ///
2580    pub unsafe fn SuspendAllVirtualThreads(&self, except_count: jint, except_list: *const jthread) -> jvmtiError {
2581        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, *const jthread) -> jvmtiError>(117)(self.vtable, except_count, except_list) }
2582    }
2583
2584    /// Resume a suspended thread.
2585    ///
2586    /// Any threads currently suspended through a JVM TI suspend function (eg. `SuspendThread`) will resume execution;
2587    /// all other threads are unaffected.
2588    ///
2589    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ResumeThread>
2590    ///
2591    /// # Safety
2592    /// thread must refer to a valid strong reference to a thread.
2593    ///
2594    pub unsafe fn ResumeThread(&self, thread: jthread) -> jvmtiError {
2595        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread) -> jvmtiError>(5)(self.vtable, thread) }
2596    }
2597
2598    /// Resume the `request_count` threads specified in the `request_list` array.
2599    /// Any thread suspended through a JVM TI suspend function (eg. `SuspendThreadList`) will resume execution.
2600    ///
2601    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ResumeThreadList>
2602    ///
2603    /// # Safety
2604    /// All threads must be valid strong references to a thread.
2605    /// The `request_list` parameter must be a valid array.
2606    /// None of the pointer parameters must be dangling.
2607    ///
2608    pub unsafe fn ResumeThreadList(&self, request_count: jint, request_list: *const jthread, results: *mut jvmtiError) -> jvmtiError {
2609        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, *const jthread, *mut jvmtiError) -> jvmtiError>(92)(self.vtable, request_count, request_list, results) }
2610    }
2611
2612    /// Resume all virtual threads except those in the exception list.
2613    /// Virtual threads that are currently resumed do not change state.
2614    /// Virtual threads may be suspended with `SuspendAllVirtualThreads` or `SuspendThreadList` or `SuspendThread`.
2615    ///
2616    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ResumeAllVirtualThreads>
2617    ///
2618    /// # Safety
2619    /// All threads must be valid strong references to a thread.
2620    /// The `except_list` and `except_count` parameter must be a valid array.
2621    /// `except_list` must not be a dangling pointer.
2622    ///
2623    pub unsafe fn ResumeAllVirtualThreads(&self, except_count: jint, except_list: *const jthread) -> jvmtiError {
2624        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, *const jthread) -> jvmtiError>(118)(self.vtable, except_count, except_list) }
2625    }
2626
2627    /// Send the specified asynchronous exception to the specified thread.
2628    ///
2629    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#StopThread>
2630    ///
2631    /// # Safety
2632    /// thread must refer to a valid strong reference to a thread.
2633    /// exception must refer to a valid strong reference to a object.
2634    ///
2635    pub unsafe fn StopThread(&self, thread: jthread, exception: jobject) -> jvmtiError {
2636        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jobject) -> jvmtiError>(6)(self.vtable, thread, exception) }
2637    }
2638
2639    /// Interrupt the specified thread (similar to java.lang.Thread.interrupt).
2640    ///
2641    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#InterruptThread>
2642    ///
2643    /// # Safety
2644    /// thread must refer to a valid strong reference to a thread.
2645    ///
2646    pub unsafe fn InterruptThread(&self, thread: jthread) -> jvmtiError {
2647        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread) -> jvmtiError>(7)(self.vtable, thread) }
2648    }
2649
2650    /// Get thread information. The fields of the jvmtiThreadInfo structure are filled in with details of the specified thread.
2651    ///
2652    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetThreadInfo>
2653    ///
2654    /// # Safety
2655    /// thread must refer to a valid strong reference to a thread.
2656    /// `info_ptr` must not be dangling.
2657    ///
2658    pub unsafe fn GetThreadInfo(&self, thread: jthread, info_ptr: *mut jvmtiThreadInfo) -> jvmtiError {
2659        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, *mut jvmtiThreadInfo) -> jvmtiError>(8)(self.vtable, thread, info_ptr) }
2660    }
2661
2662    /// Get information about the monitors owned by the specified thread.
2663    ///
2664    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetOwnedMonitorInfo>
2665    ///
2666    /// # Safety
2667    /// thread must refer to a valid strong reference to a thread.
2668    /// pointer parameters must not be dangling.
2669    ///
2670    pub unsafe fn GetOwnedMonitorInfo(&self, thread: jthread, owned_monitor_count_ptr: *mut jint, owned_monitors_ptr: *mut *mut jobject) -> jvmtiError {
2671        unsafe {
2672            self.jvmti::<extern "system" fn(JVMTIEnvVTable, crate::jthread, *mut jint, *mut *mut jobject) -> jvmtiError>(9)(
2673                self.vtable,
2674                thread,
2675                owned_monitor_count_ptr,
2676                owned_monitors_ptr,
2677            )
2678        }
2679    }
2680
2681    /// Get information about the monitors owned by the specified thread and the depth of the stack frame which locked them.
2682    ///
2683    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetOwnedMonitorStackDepthInfo>
2684    ///
2685    /// # Safety
2686    /// thread must refer to a valid strong reference to a thread.
2687    /// pointer parameters must not be dangling.
2688    ///
2689    pub unsafe fn GetOwnedMonitorStackDepthInfo(&self, thread: jthread, monitor_info_count_ptr: *mut jint, monitor_info_ptr: *mut *mut jvmtiMonitorStackDepthInfo) -> jvmtiError {
2690        unsafe {
2691            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, *mut jint, *mut *mut jvmtiMonitorStackDepthInfo) -> jvmtiError>(152)(
2692                self.vtable,
2693                thread,
2694                monitor_info_count_ptr,
2695                monitor_info_ptr,
2696            )
2697        }
2698    }
2699
2700    /// Get the object, if any, whose monitor the specified thread is waiting to enter or waiting to regain through java.lang.Object.wait.
2701    ///
2702    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetCurrentContendedMonitor>
2703    ///
2704    /// # Safety
2705    /// `thread` must refer to a valid strong reference to a thread.
2706    /// `monitor_ptr` parameter must not be dangling.
2707    ///
2708    pub unsafe fn GetCurrentContendedMonitor(&self, thread: jthread, monitor_ptr: *mut jobject) -> jvmtiError {
2709        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, *mut jobject) -> jvmtiError>(10)(self.vtable, thread, monitor_ptr) }
2710    }
2711
2712    /// Starts the execution of an agent thread. with the specified native function.
2713    ///
2714    /// The parameter arg is forwarded on to the start function (specified with proc) as its single argument.
2715    /// 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.
2716    /// 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.
2717    /// The thread object can be created with JNI calls.
2718    ///
2719    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#RunAgentThread>
2720    ///
2721    /// # Safety
2722    /// `thread` must refer to a valid strong reference to a thread.
2723    /// `proc` must refer to a extern system fn with a matching signature.
2724    ///
2725    pub unsafe fn RunAgentThread(&self, thread: jthread, proc: jvmtiStartFunction, arg: *mut c_void, priority: jint) -> jvmtiError {
2726        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jvmtiStartFunction, *mut c_void, jint) -> jvmtiError>(11)(self.vtable, thread, proc, arg, priority) }
2727    }
2728
2729    /// The VM stores a pointer value associated with each environment-thread pair.
2730    ///
2731    /// This pointer value is called thread-local storage.
2732    ///
2733    /// This value is null unless set with this function. Agents can allocate memory in which they store thread specific information.
2734    /// By setting thread-local storage it can then be accessed with `GetThreadLocalStorage`.
2735    /// This function is called by the agent to set the value of the JVM TI thread-local storage.
2736    /// JVM TI supplies to the agent a pointer-size thread-local storage that can be used to record per-thread information.
2737    ///
2738    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetThreadLocalStorage>
2739    ///
2740    /// # Safety
2741    /// `thread` must refer to a valid strong reference to a thread.
2742    ///
2743    pub unsafe fn SetThreadLocalStorage(&self, thread: jthread, data: *mut c_void) -> jvmtiError {
2744        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, *const c_void) -> jvmtiError>(102)(self.vtable, thread, data) }
2745    }
2746
2747    /// Called by the agent to get the value of the JVM TI thread-local storage.
2748    ///
2749    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetThreadLocalStorage>
2750    ///
2751    /// # Safety
2752    /// `thread` must refer to a valid strong reference to a thread.
2753    /// `data_ptr` must not be dangling.
2754    ///
2755    pub unsafe fn GetThreadLocalStorage(&self, thread: jthread, data_ptr: *mut *mut c_void) -> jvmtiError {
2756        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, *mut *mut c_void) -> jvmtiError>(101)(self.vtable, thread, data_ptr) }
2757    }
2758
2759    /// Return all top-level (parentless) thread groups in the VM.
2760    ///
2761    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetTopThreadGroups>
2762    ///
2763    /// # Safety
2764    /// all pointer parameters must not be dangling.
2765    ///
2766    pub unsafe fn GetTopThreadGroups(&self, group_count_ptr: *mut jint, groups_ptr: *mut *mut jthreadGroup) -> jvmtiError {
2767        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jint, *mut *mut jthreadGroup) -> jvmtiError>(12)(self.vtable, group_count_ptr, groups_ptr) }
2768    }
2769
2770    /// Return all top-level (parentless) thread groups in the VM.
2771    ///
2772    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetThreadGroupInfo>
2773    ///
2774    /// # Safety
2775    /// all pointer parameters must not be dangling.
2776    ///
2777    pub unsafe fn GetThreadGroupInfo(&self, group: jthreadGroup, info_ptr: *mut jvmtiThreadGroupInfo) -> jvmtiError {
2778        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthreadGroup, *mut jvmtiThreadGroupInfo) -> jvmtiError>(13)(self.vtable, group, info_ptr) }
2779    }
2780
2781    /// Get the live platform threads and the child thread groups in this thread group. Virtual threads are not returned by this function.
2782    ///
2783    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetThreadGroupChildren>
2784    ///
2785    /// # Safety
2786    /// all pointer parameters must not be dangling.
2787    ///
2788    pub unsafe fn GetThreadGroupChildren(
2789        &self,
2790        group: jthreadGroup,
2791        thread_count_ptr: *mut jint,
2792        threads_ptr: *mut *mut jthread,
2793        group_count_ptr: *mut jint,
2794        groups_ptr: *mut *mut jthreadGroup,
2795    ) -> jvmtiError {
2796        unsafe {
2797            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthreadGroup, *mut jint, *mut *mut jthread, *mut jint, *mut *mut jthreadGroup) -> jvmtiError>(14)(
2798                self.vtable,
2799                group,
2800                thread_count_ptr,
2801                threads_ptr,
2802                group_count_ptr,
2803                groups_ptr,
2804            )
2805        }
2806    }
2807
2808    /// Returns via `capabilities_ptr` the JVM TI features that can potentially be possessed by this environment at this time.
2809    /// The returned capabilities differ from the complete set of capabilities implemented by the VM in two cases:
2810    /// * another environment possesses capabilities that can only be possessed by one environment
2811    /// * the current phase is live, and certain capabilities can only be added during the `OnLoad` phase.
2812    ///
2813    /// The `AddCapabilities` function may be used to set any or all or these capabilities.
2814    /// Currently possessed capabilities are included.
2815    ///
2816    /// Typically this function is used in the `OnLoad` function.
2817    /// Some virtual machines may allow a limited set of capabilities to be added in the live phase.
2818    /// In this case, the set of potentially available capabilities will likely differ from the `OnLoad` phase set.
2819    ///
2820    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetPotentialCapabilities>
2821    ///
2822    /// # Safety
2823    /// `capabilities_ptr` pointer must not be dangling.
2824    ///
2825    pub unsafe fn GetPotentialCapabilities(&self, capabilities_ptr: *mut jvmtiCapabilities) -> jvmtiError {
2826        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jvmtiCapabilities) -> jvmtiError>(139)(self.vtable, capabilities_ptr) }
2827    }
2828
2829    /// Returns via `capabilities_ptr` the optional JVM TI features which this environment currently possesses.
2830    ///
2831    /// Each possessed capability is indicated by a one (1) in the corresponding bitfield of the capabilities structure.
2832    /// An environment does not possess a capability unless it has been successfully added with `AddCapabilities`.
2833    /// An environment only loses possession of a capability if it has been relinquished with `RelinquishCapabilities`.
2834    /// Thus, this function returns the net result of the `AddCapabilities` and `RelinquishCapabilities` calls which have been made.
2835    ///
2836    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetPotentialCapabilities>
2837    ///
2838    /// # Safety
2839    /// `capabilities_ptr` pointer must not be dangling.
2840    ///
2841    pub unsafe fn GetCapabilities(&self, capabilities_ptr: *mut jvmtiCapabilities) -> jvmtiError {
2842        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jvmtiCapabilities) -> jvmtiError>(88)(self.vtable, capabilities_ptr) }
2843    }
2844
2845    /// Set new capabilities by adding the capabilities whose values are set to one in `capabilities_ptr`.
2846    /// All previous capabilities are retained.
2847    /// Typically this function is used in the `OnLoad` function.
2848    /// Some virtual machines may allow a limited set of capabilities to be added in the live phase.
2849    ///
2850    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#AddCapabilities>
2851    ///
2852    /// # Safety
2853    /// `capabilities_ptr` pointer must not be dangling.
2854    ///
2855    pub unsafe fn AddCapabilities(&self, capabilities_ptr: *const jvmtiCapabilities) -> jvmtiError {
2856        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const jvmtiCapabilities) -> jvmtiError>(141)(self.vtable, capabilities_ptr) }
2857    }
2858
2859    /// Relinquish the capabilities whose values are set to one in `capabilities_ptr`.
2860    ///
2861    /// Some implementations may allow only one environment to have a capability.
2862    /// This function releases capabilities so that they may be used by other agents.
2863    /// All other capabilities are retained. The capability will no longer be present in `GetCapabilities`.
2864    /// Attempting to relinquish a capability that the agent does not possess is not an error.
2865    ///
2866    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#AddCapabilities>
2867    ///
2868    /// # Safety
2869    /// `capabilities_ptr` pointer must not be dangling.
2870    pub unsafe fn RelinquishCapabilities(&self, capabilities_ptr: *const jvmtiCapabilities) -> jvmtiError {
2871        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const jvmtiCapabilities) -> jvmtiError>(142)(self.vtable, capabilities_ptr) }
2872    }
2873
2874    /// Get the number of frames currently in the specified thread's call stack.
2875    ///
2876    /// If this function is called for a thread actively executing bytecodes
2877    /// (for example, not the current thread and not suspended),
2878    /// the information returned is transient.
2879    ///
2880    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetFrameCount>
2881    ///
2882    /// # Safety
2883    /// `count_ptr` pointer must not be dangling.
2884    pub unsafe fn GetFrameCount(&self, thread: jthread, count_ptr: *mut jint) -> jvmtiError {
2885        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, *mut jint) -> jvmtiError>(15)(self.vtable, thread, count_ptr) }
2886    }
2887
2888    /// Pop the current frame of thread's stack. Popping a frame takes you to the previous frame.
2889    ///
2890    /// When the thread is resumed, the execution state of the thread is reset to the state immediately before the called method was invoked.
2891    /// * the current frame is discarded as the previous frame becomes the current one
2892    /// * the operand stack is restored--the argument values are added back and if the invoke was not invokestatic, objectref is added back as well
2893    /// * the Java virtual machine PC is restored to the opcode of the invoke instruction
2894    ///
2895    /// 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.
2896    /// 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:
2897    /// * suspend the thread via an event (step, breakpoint, ...)
2898    /// * call `PopFrame`
2899    /// * resume the thread
2900    ///
2901    /// A lock acquired by calling the called method (if it is a synchronized method)
2902    /// and locks acquired by entering synchronized blocks within the called method are released.
2903    /// Note: this does not apply to native locks or java.util.concurrent.locks locks.
2904    ///
2905    /// Finally blocks are not executed.
2906    /// Changes to global state are not addressed and thus remain changed.
2907    /// The specified thread must be suspended or must be the current thread.
2908    /// Both the called method and calling method must be non-native Java programming language methods.
2909    /// No JVM TI events are generated by this function.
2910    ///
2911    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#PopFrame>
2912    ///
2913    /// # Safety
2914    /// `thread` must refer to a valid strong reference to a thread.
2915    pub unsafe fn PopFrame(&self, thread: jthread) -> jvmtiError {
2916        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread) -> jvmtiError>(79)(self.vtable, thread) }
2917    }
2918
2919    /// For a Java programming language frame, return the location of the instruction currently executing.
2920    ///
2921    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetFrameLocation>
2922    ///
2923    /// # Safety
2924    /// `method_ptr` and `location_ptr` pointer must not be dangling.
2925    pub unsafe fn GetFrameLocation(&self, thread: jthread, depth: jint, method_ptr: *mut jmethodID, location_ptr: *mut jlocation) -> jvmtiError {
2926        unsafe {
2927            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, *mut jmethodID, *mut jlocation) -> jvmtiError>(18)(self.vtable, thread, depth, method_ptr, location_ptr)
2928        }
2929    }
2930
2931    /// When the frame that is currently at depth is popped from the stack,
2932    /// generate a `FramePop` event. See the `FramePop` event for details.
2933    /// Only frames corresponding to non-native Java programming language methods can receive notification.
2934    ///
2935    /// The specified thread must be suspended or must be the current thread.
2936    ///
2937    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#NotifyFramePop>
2938    ///
2939    /// # Safety
2940    /// `thread` must refer to a valid strong reference to a thread.
2941    pub unsafe fn NotifyFramePop(&self, thread: jthread, depth: jint) -> jvmtiError {
2942        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint) -> jvmtiError>(19)(self.vtable, thread, depth) }
2943    }
2944
2945    /// This function can be used to return from a method whose result type is Object or a subclass of Object.
2946    ///
2947    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ForceEarlyReturnObject>
2948    ///
2949    /// # Safety
2950    /// `thread` must refer to a valid strong reference to a thread.
2951    /// `value` must be a valid strong reference to a object or null.
2952    pub unsafe fn ForceEarlyReturnObject(&self, thread: jthread, value: jobject) -> jvmtiError {
2953        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jobject) -> jvmtiError>(80)(self.vtable, thread, value) }
2954    }
2955
2956    /// This function can be used to return from a method whose result type is int, short, char, byte, or boolean.
2957    ///
2958    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ForceEarlyReturnInt>
2959    ///
2960    /// # Safety
2961    /// `thread` must refer to a valid strong reference to a thread.
2962    pub unsafe fn ForceEarlyReturnInt(&self, thread: jthread, value: jint) -> jvmtiError {
2963        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint) -> jvmtiError>(81)(self.vtable, thread, value) }
2964    }
2965
2966    /// This function can be used to return from a method whose result type is long.
2967    ///
2968    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ForceEarlyReturnLong>
2969    ///
2970    /// # Safety
2971    /// `thread` must refer to a valid strong reference to a thread.
2972    pub unsafe fn ForceEarlyReturnLong(&self, thread: jthread, value: jlong) -> jvmtiError {
2973        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jlong) -> jvmtiError>(82)(self.vtable, thread, value) }
2974    }
2975
2976    /// This function can be used to return from a method whose result type is float.
2977    ///
2978    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ForceEarlyReturnFloat>
2979    ///
2980    /// # Safety
2981    /// `thread` must refer to a valid strong reference to a thread.
2982    pub unsafe fn ForceEarlyReturnFloat(&self, thread: jthread, value: jfloat) -> jvmtiError {
2983        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jfloat) -> jvmtiError>(83)(self.vtable, thread, value) }
2984    }
2985
2986    /// This function can be used to return from a method whose result type is double.
2987    ///
2988    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ForceEarlyReturnDouble>
2989    ///
2990    /// # Safety
2991    /// `thread` must refer to a valid strong reference to a thread.
2992    pub unsafe fn ForceEarlyReturnDouble(&self, thread: jthread, value: jdouble) -> jvmtiError {
2993        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jdouble) -> jvmtiError>(84)(self.vtable, thread, value) }
2994    }
2995
2996    /// This function can be used to return from a method with no result type. That is, the called method must be declared void.
2997    ///
2998    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ForceEarlyReturnVoid>
2999    ///
3000    /// # Safety
3001    /// `thread` must refer to a valid strong reference to a thread.
3002    pub unsafe fn ForceEarlyReturnVoid(&self, thread: jthread) -> jvmtiError {
3003        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread) -> jvmtiError>(85)(self.vtable, thread) }
3004    }
3005
3006    /// 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.
3007    ///
3008    /// 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.
3009    ///
3010    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#FollowReferences>
3011    ///
3012    /// # Safety
3013    /// `klass` must be a valid strong reference to a class.
3014    /// `inital_object` must be a valid strong reference to a object.
3015    /// `callbacks` must not be a dangling pointer.
3016    pub unsafe fn FollowReferences(&self, heap_filter: jint, klass: jclass, initial_object: jobject, callbacks: *const jvmtiHeapCallbacks, user_data: *const c_void) -> jvmtiError {
3017        unsafe {
3018            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, jclass, jobject, *const jvmtiHeapCallbacks, *const c_void) -> jvmtiError>(114)(
3019                self.vtable,
3020                heap_filter,
3021                klass,
3022                initial_object,
3023                callbacks,
3024                user_data,
3025            )
3026        }
3027    }
3028
3029    /// Initiate an iteration over all objects in the heap. This includes both reachable and unreachable objects.
3030    ///
3031    /// Objects are visited in no particular order.
3032    ///
3033    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IterateThroughHeap>
3034    ///
3035    /// # Safety
3036    /// `klass` must refer to a valid strong reference to a class.
3037    /// `callbacks` must not be a dangling pointer.
3038    pub unsafe fn IterateThroughHeap(&self, heap_filter: jint, klass: jclass, callbacks: *const jvmtiHeapCallbacks, user_data: *const c_void) -> jvmtiError {
3039        unsafe {
3040            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, jclass, *const jvmtiHeapCallbacks, *const c_void) -> jvmtiError>(115)(
3041                self.vtable,
3042                heap_filter,
3043                klass,
3044                callbacks,
3045                user_data,
3046            )
3047        }
3048    }
3049
3050    /// Retrieve the tag associated with an object.
3051    ///
3052    /// The tag is a long value typically used to store a unique identifier or pointer to object information.
3053    /// The tag is set with `SetTag`. Objects for which no tags have been set return a tag value of zero.
3054    ///
3055    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetTag>
3056    ///
3057    /// # Safety
3058    /// `object` must refer to a valid strong reference to a class.
3059    /// `tag_ptr` must not be a dangling pointer.
3060    pub unsafe fn GetTag(&self, object: jobject, tag_ptr: *mut jlong) -> jvmtiError {
3061        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, *mut jlong) -> jvmtiError>(105)(self.vtable, object, tag_ptr) }
3062    }
3063
3064    /// Set the tag associated with an object.
3065    /// The tag is a long value typically used to store a unique identifier or pointer to object information.
3066    /// The tag is visible with `GetTag`.
3067    ///
3068    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetTag>
3069    ///
3070    /// # Safety
3071    /// `object` must refer to a valid strong reference to a class.
3072    pub unsafe fn SetTag(&self, object: jobject, tag: jlong) -> jvmtiError {
3073        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, jlong) -> jvmtiError>(106)(self.vtable, object, tag) }
3074    }
3075
3076    /// Return objects in the heap with the specified tags.
3077    ///
3078    /// The format is parallel arrays of objects and tags.
3079    ///
3080    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetObjectsWithTags>
3081    ///
3082    /// # Safety
3083    /// all pointer arguments must not be dangling.
3084    /// `tags` and `tag_count` must form a valid array.
3085    pub unsafe fn GetObjectsWithTags(
3086        &self,
3087        tag_count: jint,
3088        tags: *const jlong,
3089        count_ptr: *mut jint,
3090        object_result_ptr: *mut *mut jobject,
3091        tag_result_ptr: *mut *mut jlong,
3092    ) -> jvmtiError {
3093        unsafe {
3094            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, *const jlong, *mut jint, *mut *mut jobject, *mut *mut jlong) -> jvmtiError>(113)(
3095                self.vtable,
3096                tag_count,
3097                tags,
3098                count_ptr,
3099                object_result_ptr,
3100                tag_result_ptr,
3101            )
3102        }
3103    }
3104
3105    /// Force the VM to perform a garbage collection.
3106    ///
3107    /// The garbage collection is as complete as possible.
3108    /// This function does not cause finalizers to be run.
3109    /// This function does not return until the garbage collection is finished.
3110    ///
3111    /// Although garbage collection is as complete as possible there is no guarantee
3112    /// that all `ObjectFree` events will have been sent by the time that this function returns.
3113    /// In particular, an object may be prevented from being freed because it is awaiting finalization.
3114    ///
3115    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ForceGarbageCollection>
3116    ///
3117    /// # Safety
3118    /// JVM Implementation dependant
3119    pub unsafe fn ForceGarbageCollection(&self) -> jvmtiError {
3120        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable) -> jvmtiError>(107)(self.vtable) }
3121    }
3122
3123    /// This function iterates over all objects that are directly and indirectly reachable from the specified object.
3124    ///
3125    /// 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.
3126    /// 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.
3127    /// 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`.
3128    /// The callback for an object will always occur after the callback for its referrer.
3129    ///
3130    /// See `FollowReferences` for the object references which are reported.
3131    /// 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.
3132    /// 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.
3133    ///
3134    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IterateOverObjectsReachableFromObject>
3135    ///
3136    /// # Safety
3137    /// `object_reference_callback` must be valid.
3138    /// `object` must be a valid strong reference to a object.
3139    #[deprecated(
3140        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."
3141    )]
3142    pub unsafe fn IterateOverObjectsReachableFromObject(&self, object: jobject, object_reference_callback: jvmtiObjectReferenceCallback, user_data: *const c_void) -> jvmtiError {
3143        unsafe {
3144            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, jvmtiObjectReferenceCallback, *const c_void) -> jvmtiError>(108)(
3145                self.vtable,
3146                object,
3147                object_reference_callback,
3148                user_data,
3149            )
3150        }
3151    }
3152
3153    /// This function iterates over the root objects and all objects that are directly and indirectly reachable from the root objects.
3154    ///
3155    /// The root objects comprise the set of system classes, JNI globals, references from platform thread stacks,
3156    /// and other objects used as roots for the purposes of garbage collection.
3157    ///
3158    /// For each root the `heap_root_callback` or `stack_ref_callback` callback is called.
3159    /// An object can be a root object for more than one reason and in that case the appropriate callback is called for each reason.
3160    ///
3161    /// For each object reference the `object_ref_callback` callback function is called to describe the object reference.
3162    /// The callback is called exactly once for each reference from a referrer.
3163    /// This is true even if there are reference cycles or multiple paths to the referrer.
3164    /// There may be more than one reference between a referrer and a referree,
3165    /// These may be distinguished by the `jvmtiObjectReferenceCallback.reference_kind` and `jvmtiObjectReferenceCallback.referrer_index`.
3166    /// The callback for an object will always occur after the callback for its referrer.
3167    ///
3168    /// See `FollowReferences` for the object references which are reported.
3169    ///
3170    /// Roots are always reported to the profiler before any object references are reported.
3171    /// In other words, the `object_ref_callback` callback will not be called until the appropriate callback has been called for all roots.
3172    /// If the `object_ref_callback` callback is specified as null then this function returns after reporting the root objects to the profiler.
3173    ///
3174    /// During the execution of this function the state of the heap does not change: no objects are allocated,
3175    /// no objects are garbage collected, and the state of objects (including held values) does not change.
3176    /// As a result, threads executing Java programming language code,
3177    /// threads attempting to resume the execution of Java programming language code,
3178    /// and threads attempting to execute JNI functions are typically stalled.
3179    ///
3180    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IterateOverReachableObjects>
3181    ///
3182    /// # Safety
3183    /// the callback functions must be valid.
3184    #[deprecated(
3185        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."
3186    )]
3187    pub unsafe fn IterateOverReachableObjects(
3188        &self,
3189        heap_root_callback: Option<jvmtiHeapRootCallback>,
3190        stack_ref_callback: Option<jvmtiStackReferenceCallback>,
3191        object_ref_callback: Option<jvmtiObjectReferenceCallback>,
3192        user_data: *const c_void,
3193    ) -> jvmtiError {
3194        unsafe {
3195            self.jvmti::<extern "system" fn(
3196                JVMTIEnvVTable,
3197                Option<jvmtiHeapRootCallback>,
3198                Option<jvmtiStackReferenceCallback>,
3199                Option<jvmtiObjectReferenceCallback>,
3200                *const c_void,
3201            ) -> jvmtiError>(109)(self.vtable, heap_root_callback, stack_ref_callback, object_ref_callback, user_data)
3202        }
3203    }
3204
3205    /// Iterate over all objects in the heap. This includes both reachable and unreachable objects.
3206    ///
3207    /// The `object_filter` parameter indicates the objects for which the callback function is called.
3208    ///
3209    /// If this parameter is `JVMTI_HEAP_OBJECT_TAGGED` then the callback will only be called for every object that is tagged.
3210    ///
3211    /// If the parameter is `JVMTI_HEAP_OBJECT_UNTAGGED` then the callback will only be for objects that are not tagged.
3212    ///
3213    /// 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.
3214    /// During the execution of this function the state of the heap does not change: no objects are allocated, no objects are garbage collected,
3215    /// and the state of objects (including held values) does not change.
3216    ///
3217    /// As a result, threads executing Java programming language code, threads attempting to resume the execution of Java programming language code,
3218    /// and threads attempting to execute JNI functions are typically stalled.
3219    ///
3220    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IterateOverHeap>
3221    ///
3222    /// # Safety
3223    /// the callback functions must be valid.
3224    #[deprecated(
3225        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."
3226    )]
3227    pub unsafe fn IterateOverHeap(&self, object_filter: jvmtiHeapObjectFilter, heap_object_callback: jvmtiHeapObjectCallback, user_data: *const c_void) -> jvmtiError {
3228        unsafe {
3229            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jvmtiHeapObjectFilter, jvmtiHeapObjectCallback, *const c_void) -> jvmtiError>(110)(
3230                self.vtable,
3231                object_filter,
3232                heap_object_callback,
3233                user_data,
3234            )
3235        }
3236    }
3237
3238    /// Iterate over all objects in the heap that are instances of the specified class.
3239    ///
3240    /// This includes direct instances of the specified class and instances of all subclasses of the specified class.
3241    /// This includes both reachable and unreachable objects.
3242    ///
3243    /// The `object_filter` parameter indicates the objects for which the callback function is called.
3244    ///
3245    /// If this parameter is `JVMTI_HEAP_OBJECT_TAGGED` then the callback will only be called for every object that is tagged.
3246    ///
3247    /// If the parameter is `JVMTI_HEAP_OBJECT_UNTAGGED` then the callback will only be called for objects that are not tagged.
3248    ///
3249    /// 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.
3250    ///
3251    /// 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.
3252    /// 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.
3253    ///
3254    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IterateOverInstancesOfClass>
3255    ///
3256    /// # Safety
3257    /// the callback functions must be valid.
3258    /// `klaas` parameter must be a valid strong reference.
3259    #[deprecated(
3260        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."
3261    )]
3262    pub unsafe fn IterateOverInstancesOfClass(
3263        &self,
3264        klass: jclass,
3265        object_filter: jvmtiHeapObjectFilter,
3266        heap_object_callback: jvmtiHeapObjectCallback,
3267        user_data: *const c_void,
3268    ) -> jvmtiError {
3269        unsafe {
3270            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, jvmtiHeapObjectFilter, jvmtiHeapObjectCallback, *const c_void) -> jvmtiError>(111)(
3271                self.vtable,
3272                klass,
3273                object_filter,
3274                heap_object_callback,
3275                user_data,
3276            )
3277        }
3278    }
3279
3280    /// This function can be used to retrieve the value of a local variable whose type is Object or a subclass of Object.
3281    ///
3282    /// The specified thread must be suspended or must be the current thread.
3283    ///
3284    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetLocalObject>
3285    ///
3286    /// # Safety
3287    /// `thread` is a valid strong reference to a thread.
3288    /// `value_ptr` is not a dangling pointer.
3289    pub unsafe fn GetLocalObject(&self, thread: jthread, depth: jint, slot: jint, value_ptr: *mut jobject) -> jvmtiError {
3290        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, *mut jobject) -> jvmtiError>(20)(self.vtable, thread, depth, slot, value_ptr) }
3291    }
3292
3293    /// This function can be used to retrieve the value of the local object variable at slot 0 (the "this" object) from non-static frames.
3294    ///
3295    /// This function can retrieve the "this" object from native method frames, whereas `GetLocalObject()` would return `JVMTI_ERROR_OPAQUE_FRAME` in those cases.
3296    /// The specified thread must be suspended or must be the current thread.
3297    ///
3298    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetLocalInstance>
3299    ///
3300    /// # Safety
3301    /// `thread` is a valid strong reference to a thread.
3302    /// `value_ptr` is not a dangling pointer.
3303    pub unsafe fn GetLocalInstance(&self, thread: jthread, depth: jint, value_ptr: *mut jobject) -> jvmtiError {
3304        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, *mut jobject) -> jvmtiError>(154)(self.vtable, thread, depth, value_ptr) }
3305    }
3306
3307    /// This function can be used to retrieve the value of a local variable whose type is int, short, char, byte, or boolean.
3308    ///
3309    /// The specified thread must be suspended or must be the current thread.
3310    ///
3311    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetLocalInt>
3312    ///
3313    /// # Safety
3314    /// `thread` is a valid strong reference to a thread.
3315    /// `value_ptr` is not a dangling pointer.
3316    pub unsafe fn GetLocalInt(&self, thread: jthread, depth: jint, slot: jint, value_ptr: *mut jint) -> jvmtiError {
3317        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, *mut jint) -> jvmtiError>(21)(self.vtable, thread, depth, slot, value_ptr) }
3318    }
3319
3320    /// This function can be used to retrieve the value of a local variable whose type is long.
3321    ///
3322    /// The specified thread must be suspended or must be the current thread.
3323    ///
3324    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetLocalLong>
3325    ///
3326    /// # Safety
3327    /// `thread` is a valid strong reference to a thread.
3328    /// `value_ptr` is not a dangling pointer.
3329    pub unsafe fn GetLocalLong(&self, thread: jthread, depth: jint, slot: jint, value_ptr: *mut jlong) -> jvmtiError {
3330        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, *mut jlong) -> jvmtiError>(22)(self.vtable, thread, depth, slot, value_ptr) }
3331    }
3332
3333    /// This function can be used to retrieve the value of a local variable whose type is float.
3334    ///
3335    /// The specified thread must be suspended or must be the current thread.
3336    ///
3337    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetLocalFloat>
3338    ///
3339    /// # Safety
3340    /// `thread` is a valid strong reference to a thread.
3341    /// `value_ptr` is not a dangling pointer.
3342    pub unsafe fn GetLocalFloat(&self, thread: jthread, depth: jint, slot: jint, value_ptr: *mut jfloat) -> jvmtiError {
3343        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, *mut jfloat) -> jvmtiError>(23)(self.vtable, thread, depth, slot, value_ptr) }
3344    }
3345
3346    /// This function can be used to retrieve the value of a local variable whose type is double.
3347    ///
3348    /// The specified thread must be suspended or must be the current thread.
3349    ///
3350    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetLocalDouble>
3351    ///
3352    /// # Safety
3353    /// `thread` is a valid strong reference to a thread.
3354    /// `value_ptr` is not a dangling pointer.
3355    pub unsafe fn GetLocalDouble(&self, thread: jthread, depth: jint, slot: jint, value_ptr: *mut jdouble) -> jvmtiError {
3356        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, *mut jdouble) -> jvmtiError>(24)(self.vtable, thread, depth, slot, value_ptr) }
3357    }
3358
3359    /// This function can be used to set the value of a local variable whose type is Object or a subclass of Object.
3360    ///
3361    /// The specified thread must be suspended or must be the current thread.
3362    ///
3363    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetLocalObject>
3364    ///
3365    /// # Safety
3366    /// `thread` is a valid strong reference to a thread.
3367    /// `value` is a valid strong reference or null.
3368    pub unsafe fn SetLocalObject(&self, thread: jthread, depth: jint, slot: jint, value: jobject) -> jvmtiError {
3369        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, jobject) -> jvmtiError>(25)(self.vtable, thread, depth, slot, value) }
3370    }
3371
3372    /// This function can be used to set the value of a local variable whose type is int, short, char, byte, or boolean.
3373    ///
3374    /// The specified thread must be suspended or must be the current thread.
3375    ///
3376    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetLocalInt>
3377    ///
3378    /// # Safety
3379    /// `thread` is a valid strong reference to a thread.
3380    pub unsafe fn SetLocalInt(&self, thread: jthread, depth: jint, slot: jint, value: jint) -> jvmtiError {
3381        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, jint) -> jvmtiError>(26)(self.vtable, thread, depth, slot, value) }
3382    }
3383
3384    /// This function can be used to set the value of a local variable whose type is long.
3385    ///
3386    /// The specified thread must be suspended or must be the current thread.
3387    ///
3388    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetLocalLong>
3389    ///
3390    /// # Safety
3391    /// `thread` is a valid strong reference to a thread.
3392    pub unsafe fn SetLocalLong(&self, thread: jthread, depth: jint, slot: jint, value: jlong) -> jvmtiError {
3393        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, jlong) -> jvmtiError>(27)(self.vtable, thread, depth, slot, value) }
3394    }
3395
3396    /// This function can be used to set the value of a local variable whose type is float.
3397    ///
3398    /// The specified thread must be suspended or must be the current thread.
3399    ///
3400    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetLocalFloat>
3401    ///
3402    /// # Safety
3403    /// `thread` is a valid strong reference to a thread.
3404    pub unsafe fn SetLocalFloat(&self, thread: jthread, depth: jint, slot: jint, value: jfloat) -> jvmtiError {
3405        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, jfloat) -> jvmtiError>(28)(self.vtable, thread, depth, slot, value) }
3406    }
3407
3408    /// This function can be used to set the value of a local variable whose type is double.
3409    ///
3410    /// The specified thread must be suspended or must be the current thread.
3411    ///
3412    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetLocalDouble>
3413    ///
3414    /// # Safety
3415    /// `thread` is a valid strong reference to a thread.
3416    pub unsafe fn SetLocalDouble(&self, thread: jthread, depth: jint, slot: jint, value: jdouble) -> jvmtiError {
3417        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, jint, jint, jdouble) -> jvmtiError>(29)(self.vtable, thread, depth, slot, value) }
3418    }
3419
3420    /// Set a breakpoint at the instruction indicated by method and location. An instruction can only have one breakpoint.
3421    /// Whenever the designated instruction is about to be executed, a Breakpoint event is generated.
3422    ///
3423    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetBreakpoint>
3424    ///
3425    /// # Safety
3426    /// `method` must be valid
3427    pub unsafe fn SetBreakpoint(&self, method: jmethodID, location: jlocation) -> jvmtiError {
3428        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, jlocation) -> jvmtiError>(37)(self.vtable, method, location) }
3429    }
3430
3431    /// Clear the breakpoint at the bytecode indicated by method and location.
3432    ///
3433    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ClearBreakpoint>
3434    ///
3435    /// # Safety
3436    /// `method` must be valid
3437    pub unsafe fn ClearBreakpoint(&self, method: jmethodID, location: jlocation) -> jvmtiError {
3438        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, jlocation) -> jvmtiError>(37)(self.vtable, method, location) }
3439    }
3440
3441    /// Generate a `FieldAccess` event when the field specified by klass and field is about to be accessed.
3442    ///
3443    /// An event will be generated for each access of the field until it is canceled with `ClearFieldAccessWatch`.
3444    /// Field accesses from Java programming language code or from JNI code are watched, fields modified by other means are not watched.
3445    /// Note that JVM TI users should be aware that their own field accesses will trigger the watch.
3446    /// A field can only have one field access watch set.
3447    /// Modification of a field is not considered an access--use `SetFieldModificationWatch` to monitor modifications.
3448    ///
3449    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetFieldAccessWatch>
3450    ///
3451    /// # Safety
3452    /// `klass` must be a valid strong reference to a class.
3453    /// `field` must be valid
3454    pub unsafe fn SetFieldAccessWatch(&self, klass: jclass, field: jfieldID) -> jvmtiError {
3455        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, jfieldID) -> jvmtiError>(40)(self.vtable, klass, field) }
3456    }
3457
3458    /// Cancel a field access watch previously set by `SetFieldAccessWatch`, on the field specified by klass and field.
3459    ///
3460    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ClearFieldAccessWatch>
3461    ///
3462    /// # Safety
3463    /// `klass` must be a valid strong reference to a class.
3464    /// `field` must be valid
3465    pub unsafe fn ClearFieldAccessWatch(&self, klass: jclass, field: jfieldID) -> jvmtiError {
3466        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, jfieldID) -> jvmtiError>(41)(self.vtable, klass, field) }
3467    }
3468
3469    /// Cancel a field modification watch previously set by `SetFieldModificationWatch`, on the field specified by klass and field.
3470    ///
3471    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetFieldModificationWatch>
3472    ///
3473    /// # Safety
3474    /// `klass` must be a valid strong reference to a class.
3475    /// `field` must be valid
3476    pub unsafe fn SetFieldModificationWatch(&self, klass: jclass, field: jfieldID) -> jvmtiError {
3477        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, jfieldID) -> jvmtiError>(42)(self.vtable, klass, field) }
3478    }
3479
3480    /// Cancel a field modification watch previously set by `SetFieldModificationWatch`, on the field specified by klass and field.
3481    ///
3482    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#ClearFieldModificationWatch>
3483    ///
3484    /// # Safety
3485    /// `klass` must be a valid strong reference to a class.
3486    /// `field` must be valid
3487    pub unsafe fn ClearFieldModificationWatch(&self, klass: jclass, field: jfieldID) -> jvmtiError {
3488        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, jfieldID) -> jvmtiError>(43)(self.vtable, klass, field) }
3489    }
3490
3491    /// Return an array of all modules loaded in the virtual machine.
3492    /// The array includes the unnamed module for each class loader.
3493    /// The number of modules in the array is returned via `module_count_ptr`, and the array itself via `modules_ptr`.
3494    ///
3495    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetAllModules>
3496    ///
3497    /// # Safety
3498    /// all pointer parameters must not be dangling.
3499    pub unsafe fn GetAllModules(&self, module_count_ptr: *mut jint, modules_ptr: *mut *mut jobject) -> jvmtiError {
3500        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jint, *mut *mut jobject) -> jvmtiError>(2)(self.vtable, module_count_ptr, modules_ptr) }
3501    }
3502
3503    /// Return the java.lang.Module object for a named module defined to a class loader that contains a given package.
3504    ///
3505    /// The module is returned via `module_ptr`.
3506    /// 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.
3507    ///
3508    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetNamedModule>
3509    ///
3510    /// # Safety
3511    /// `class_loader` must be a valid strong reference or null
3512    /// all pointer parameters must not be dangling.
3513    pub unsafe fn GetNamedModule(&self, class_loader: jobject, package_name: impl UseCString, module_ptr: *mut jobject) -> jvmtiError {
3514        unsafe {
3515            package_name.use_as_const_c_char(|package_name| {
3516                self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, *const c_char, *mut jobject) -> jvmtiError>(39)(self.vtable, class_loader, package_name, module_ptr)
3517            })
3518        }
3519    }
3520
3521    /// Update a module to read another module.
3522    ///
3523    /// This function is a no-op when module is an unnamed module.
3524    /// This function facilitates the instrumentation of code in named modules where that instrumentation requires expanding the set of modules that a module reads.
3525    ///
3526    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#AddModuleReads>
3527    ///
3528    /// # Safety
3529    /// `module` must be a valid strong reference or null
3530    /// `to_module` must be a valid strong reference or null
3531    pub unsafe fn AddModuleReads(&self, module: jobject, to_module: jobject) -> jvmtiError {
3532        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, jobject) -> jvmtiError>(93)(self.vtable, module, to_module) }
3533    }
3534
3535    /// Update a module to export a package to another module.
3536    ///
3537    /// This function is a no-op when module is an unnamed module or an open module.
3538    /// This function facilitates the instrumentation of code in named modules where that instrumentation requires expanding the set of packages that a module exports.
3539    ///
3540    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#AddModuleExports>
3541    ///
3542    /// # Safety
3543    /// `module` must be a valid strong reference or null
3544    /// `to_module` must be a valid strong reference or null
3545    /// all pointer parameters must not be dangling.
3546    pub unsafe fn AddModuleExports(&self, module: jobject, pkg_name: impl UseCString, to_module: jobject) -> jvmtiError {
3547        unsafe {
3548            pkg_name.use_as_const_c_char(|pkg_name| {
3549                self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, *const c_char, jobject) -> jvmtiError>(94)(self.vtable, module, pkg_name, to_module)
3550            })
3551        }
3552    }
3553
3554    /// Update a module to open a package to another module.
3555    ///
3556    /// This function is a no-op when module is an unnamed module or an open module.
3557    /// 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.
3558    ///
3559    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#AddModuleOpens>
3560    ///
3561    /// # Safety
3562    /// `module` must be a valid strong reference or null
3563    /// `to_module` must be a valid strong reference or null
3564    /// all pointer parameters must not be dangling.
3565    pub unsafe fn AddModuleOpens(&self, module: jobject, pkg_name: impl UseCString, to_module: jobject) -> jvmtiError {
3566        unsafe {
3567            pkg_name.use_as_const_c_char(|pkg_name| {
3568                self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, *const c_char, jobject) -> jvmtiError>(95)(self.vtable, module, pkg_name, to_module)
3569            })
3570        }
3571    }
3572
3573    /// Updates a module to add a service to the set of services that a module uses.
3574    ///
3575    /// This function is a no-op when the module is an unnamed module.
3576    /// This function facilitates the instrumentation of code in named modules where that instrumentation requires expanding the set of services that a module is using.
3577    ///
3578    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#AddModuleUses>
3579    ///
3580    /// # Safety
3581    /// `module` must be a valid strong reference or null
3582    /// `service` must be a valid strong reference or null
3583    pub unsafe fn AddModuleUses(&self, module: jobject, service: jclass) -> jvmtiError {
3584        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, jclass) -> jvmtiError>(96)(self.vtable, module, service) }
3585    }
3586
3587    /// Updates a module to add a service to the set of services that a module provides.
3588    ///
3589    /// This function is a no-op when the module is an unnamed module.
3590    /// This function facilitates the instrumentation of code in named modules where that instrumentation requires changes to the services that are provided.
3591    ///
3592    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#AddModuleProvides>
3593    ///
3594    /// # Safety
3595    /// `module` must be a valid strong reference or null
3596    /// `service` must be a valid strong reference or null
3597    /// `impl_class` must be a valid strong reference or null
3598    pub unsafe fn AddModuleProvides(&self, module: jobject, service: jclass, impl_class: jclass) -> jvmtiError {
3599        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, jclass, jclass) -> jvmtiError>(97)(self.vtable, module, service, impl_class) }
3600    }
3601
3602    /// Determines whether a module is modifiable.
3603    ///
3604    /// If a module is modifiable then this module can be updated with `AddModuleReads`, `AddModuleExports`, `AddModuleOpens`, `AddModuleUses`, and `AddModuleProvides`.
3605    /// If a module is not modifiable then the module can not be updated with these functions.
3606    /// The result of this function is always `JNI_TRUE` when called to determine if an unnamed module is modifiable.
3607    ///
3608    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IsModifiableModule>
3609    ///
3610    /// # Safety
3611    /// `module` must be a valid strong reference or null
3612    /// `service` must be a valid strong reference or null
3613    /// `impl_class` must be a valid strong reference or null
3614    pub unsafe fn IsModifiableModule(&self, module: jobject, is_modifiable_module_ptr: *mut jboolean) -> jvmtiError {
3615        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, *mut jboolean) -> jvmtiError>(98)(self.vtable, module, is_modifiable_module_ptr) }
3616    }
3617
3618    /// Return an array of all classes loaded in the virtual machine.
3619    ///
3620    /// The number of classes in the array is returned via `class_count_ptr`, and the array itself via `classes_ptr`.
3621    ///
3622    /// A class or interface creation can be triggered by one of the following:
3623    /// * By loading and deriving a class from a class file representation using a class loader (see The Java™ Virtual Machine Specification, Chapter 5.3).
3624    /// * By invoking `Lookup::defineHiddenClass` that creates a hidden class or interface from a class file representation.
3625    /// * By invoking methods in certain Java SE Platform APIs such as reflection.
3626    ///
3627    /// 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.
3628    /// 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.
3629    ///
3630    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetLoadedClasses>
3631    ///
3632    /// # Safety
3633    /// all pointer parameters must not be dangling.
3634    pub unsafe fn GetLoadedClasses(&self, count_ptr: *mut jint, classes_ptr: *mut *mut jclass) -> jvmtiError {
3635        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jint, *mut *mut jclass) -> jvmtiError>(77)(self.vtable, count_ptr, classes_ptr) }
3636    }
3637
3638    /// Returns an array of all classes which this class loader can find by name via `ClassLoader::loadClass`, `Class::forName` and bytecode linkage.
3639    ///
3640    /// That is, all classes for which `initiating_loader` has been recorded as an initiating loader.
3641    /// Each class in the returned array was created by this class loader, either by defining it directly or by delegation to another class loader.
3642    /// See The Java™ Virtual Machine Specification, Chapter 5.3.
3643    /// 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.
3644    /// The number of classes in the array is returned via `class_count_ptr`, and the array itself via `classes_ptr`.
3645    /// See `Lookup::defineHiddenClass`.
3646    ///
3647    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetClassLoaderClasses>
3648    ///
3649    /// # Safety
3650    /// `initiating_loader` must be a valid strong reference or null.
3651    /// all pointer parameters must not be dangling.
3652    pub unsafe fn GetClassLoaderClasses(&self, initiating_loader: jobject, count_ptr: *mut jint, classes_ptr: *mut *mut jclass) -> jvmtiError {
3653        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, *mut jint, *mut *mut jclass) -> jvmtiError>(78)(self.vtable, initiating_loader, count_ptr, classes_ptr) }
3654    }
3655
3656    /// Returns an array of all classes which this class loader can find by name via `ClassLoader::loadClass`, `Class::forName` and bytecode linkage.
3657    ///
3658    /// That is, all classes for which `initiating_loader` has been recorded as an initiating loader.
3659    /// Each class in the returned array was created by this class loader, either by defining it directly or by delegation to another class loader. See The Java™ Virtual Machine Specification, Chapter 5.3.
3660    /// 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.
3661    /// The number of classes in the array is returned via `class_count_ptr`, and the array itself via `classes_ptr`.
3662    /// See `Lookup::defineHiddenClass`.
3663    ///
3664    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetClassSignature>
3665    ///
3666    /// # Safety
3667    /// `klass` must be a valid strong reference or null.
3668    /// all pointer parameters must not be dangling.
3669    pub unsafe fn GetClassSignature(&self, klass: jclass, signature_ptr: *mut *mut c_char, generic_ptr: *mut *mut c_char) -> jvmtiError {
3670        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) }
3671    }
3672
3673    /// Get the status of the class. Zero or more of the following bits can be set.
3674    ///
3675    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetClassStatus>
3676    ///
3677    /// # Safety
3678    /// `klass` must be a valid strong reference or null.
3679    /// `status_ptr` must not be dangling.
3680    pub unsafe fn GetClassStatus(&self, klass: jclass, status_ptr: *mut jint) -> jvmtiError {
3681        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jint) -> jvmtiError>(48)(self.vtable, klass, status_ptr) }
3682    }
3683
3684    /// For the class indicated by klass, return the source file name via `source_name_ptr`.
3685    ///
3686    /// The returned string is a file name only and never contains a directory name.
3687    ///
3688    /// For primitive classes (for example, java.lang.Integer.TYPE) and for arrays this function returns `JVMTI_ERROR_ABSENT_INFORMATION`.
3689    ///
3690    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetSourceFileName>
3691    ///
3692    /// # Safety
3693    /// `klass` must be a valid strong reference or null.
3694    /// `source_name_ptr` must not be dangling.
3695    pub unsafe fn GetSourceFileName(&self, klass: jclass, source_name_ptr: *mut *mut c_char) -> jvmtiError {
3696        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut *mut c_char) -> jvmtiError>(49)(self.vtable, klass, source_name_ptr) }
3697    }
3698
3699    /// For the class indicated by klass, return the access flags via `modifiers_ptr`.
3700    ///
3701    /// Access flags are defined in The Java™ Virtual Machine Specification, Chapter 4.
3702    ///
3703    /// If the class is an array class, then its public, private, and protected modifiers are the same as those of its component type.
3704    /// For arrays of primitives, this component type is represented by one of the primitive classes (for example, java.lang.Integer.TYPE).
3705    /// If the class is a primitive class, its public modifier is always true, and its protected and private modifiers are always false.
3706    /// 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.
3707    /// The values of its other modifiers are not determined by this specification.
3708    ///
3709    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetSourceFileName>
3710    ///
3711    /// # Safety
3712    /// `klass` must be a valid strong reference or null.
3713    /// `modifiers_ptr` must not be dangling.
3714    pub unsafe fn GetClassModifiers(&self, klass: jclass, modifiers_ptr: *mut jint) -> jvmtiError {
3715        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jint) -> jvmtiError>(50)(self.vtable, klass, modifiers_ptr) }
3716    }
3717
3718    /// For the class indicated by klass, return a count of methods via `method_count_ptr` and a list of method IDs via `methods_ptr`.
3719    ///
3720    /// The method list contains constructors and static initializers as well as true methods.
3721    /// Only directly declared methods are returned (not inherited methods).
3722    /// An empty method list is returned for array classes and primitive classes (for example, java.lang.Integer.TYPE).
3723    ///
3724    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetClassMethods>
3725    ///
3726    /// # Safety
3727    /// `klass` must be a valid strong reference or null.
3728    /// `method_count_ptr` and `methods_ptr` must not be dangling.
3729    pub unsafe fn GetClassMethods(&self, klass: jclass, method_count_ptr: *mut jint, methods_ptr: *mut *mut jmethodID) -> jvmtiError {
3730        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jint, *mut *mut jmethodID) -> jvmtiError>(51)(self.vtable, klass, method_count_ptr, methods_ptr) }
3731    }
3732
3733    /// For the class indicated by klass, return a count of fields via `field_count_ptr` and a list of field IDs via `fields_ptr`.
3734    ///
3735    /// Only directly declared fields are returned (not inherited fields).
3736    /// Fields are returned in the order they occur in the class file.
3737    /// An empty field list is returned for array classes and primitive classes (for example, java.lang.Integer.TYPE).
3738    /// Use JNI to determine the length of an array.
3739    ///
3740    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetClassFields>
3741    ///
3742    /// # Safety
3743    /// `klass` must be a valid strong reference or null.
3744    /// `field_count_ptr` and `fields_ptr` must not be dangling.
3745    pub unsafe fn GetClassFields(&self, klass: jclass, field_count_ptr: *mut jint, fields_ptr: *mut *mut jfieldID) -> jvmtiError {
3746        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jint, *mut *mut jfieldID) -> jvmtiError>(52)(self.vtable, klass, field_count_ptr, fields_ptr) }
3747    }
3748
3749    /// Return the direct super-interfaces of this class. For a class, this function returns the interfaces declared in its implements clause.
3750    ///
3751    /// For an interface, this function returns the interfaces declared in its extends clause.
3752    /// An empty interface list is returned for array classes and primitive classes (for example, java.lang.Integer.TYPE).
3753    ///
3754    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetImplementedInterfaces>
3755    ///
3756    /// # Safety
3757    /// `klass` must be a valid strong reference or null.
3758    /// `interface_count_ptr` and `interfaces_ptr` must not be dangling.
3759    pub unsafe fn GetImplementedInterfaces(&self, klass: jclass, interface_count_ptr: *mut jint, interfaces_ptr: *mut *mut jclass) -> jvmtiError {
3760        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jint, *mut *mut jclass) -> jvmtiError>(53)(self.vtable, klass, interface_count_ptr, interfaces_ptr) }
3761    }
3762
3763    /// For the class indicated by klass, return the minor and major version numbers, as defined in The Java™ Virtual Machine Specification, Chapter 4.
3764    ///
3765    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetClassVersionNumbers>
3766    ///
3767    /// # Safety
3768    /// `klass` must be a valid strong reference or null.
3769    /// `minor_version_ptr` and `major_version_ptr` must not be dangling.
3770    pub unsafe fn GetClassVersionNumbers(&self, klass: jclass, minor_version_ptr: *mut jint, major_version_ptr: *mut jint) -> jvmtiError {
3771        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jint, *mut jint) -> jvmtiError>(54)(self.vtable, klass, minor_version_ptr, major_version_ptr) }
3772    }
3773
3774    /// 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.
3775    ///
3776    /// 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.
3777    ///
3778    /// The returned constant pool might not have the same layout or contents as the constant pool in the defining class file.
3779    /// The constant pool returned by `GetConstantPool()` may have more or fewer entries than the defining constant pool.
3780    /// Entries may be in a different order. The constant pool returned by `GetConstantPool()` will match the constant pool used by `GetBytecodes()`.
3781    /// That is, the bytecodes returned by `GetBytecodes()` will have constant pool indices which refer to constant pool entries returned by `GetConstantPool()`.
3782    /// Note that since `RetransformClasses` and `RedefineClasses` can change the constant pool, the constant pool returned by this function can change accordingly.
3783    /// Thus, the correspondence between `GetConstantPool()` and `GetBytecodes()` does not hold if there is an intervening class retransformation or redefinition.
3784    /// 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).
3785    /// 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.
3786    ///
3787    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetConstantPool>
3788    ///
3789    /// # Safety
3790    /// `klass` must be a valid strong reference or null.
3791    /// all pointer parameters must not be dangling.
3792    pub unsafe fn GetConstantPool(
3793        &self,
3794        klass: jclass,
3795        constant_pool_count_ptr: *mut jint,
3796        constant_pool_byte_count_ptr: *mut jint,
3797        constant_pool_bytes_ptr: *mut *mut c_uchar,
3798    ) -> jvmtiError {
3799        unsafe {
3800            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jint, *mut jint, *mut *mut c_uchar) -> jvmtiError>(54)(
3801                self.vtable,
3802                klass,
3803                constant_pool_count_ptr,
3804                constant_pool_byte_count_ptr,
3805                constant_pool_bytes_ptr,
3806            )
3807        }
3808    }
3809
3810    /// Determines whether a class object reference represents an interface.
3811    /// The jboolean result is `JNI_TRUE` if the "class" is actually an interface,
3812    /// `JNI_FALSE` otherwise.
3813    ///
3814    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IsInterface>
3815    ///
3816    /// # Safety
3817    /// `klass` must be a valid strong reference or null.
3818    /// all pointer parameters must not be dangling.
3819    pub unsafe fn IsInterface(&self, klass: jclass, is_interface_ptr: *mut jboolean) -> jvmtiError {
3820        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jboolean) -> jvmtiError>(54)(self.vtable, klass, is_interface_ptr) }
3821    }
3822
3823    /// Determines whether a class object reference represents an array.
3824    /// The jboolean result is true if the class is an array, false otherwise.
3825    ///
3826    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IsArrayClass>
3827    ///
3828    /// # Safety
3829    /// `klass` must be a valid strong reference or null.
3830    /// all pointer parameters must not be dangling.
3831    pub unsafe fn IsArrayClass(&self, klass: jclass, is_array_class_ptr: *mut jboolean) -> jvmtiError {
3832        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jboolean) -> jvmtiError>(55)(self.vtable, klass, is_array_class_ptr) }
3833    }
3834
3835    /// Determines whether a class is modifiable.
3836    ///
3837    /// If a class is modifiable (`is_modifiable_class_ptr` returns `JNI_TRUE`)
3838    /// the class can be redefined with `RedefineClasses` (assuming the agent possesses the `can_redefine_classes` capability)
3839    /// or retransformed with `RetransformClasses` (assuming the agent possesses the `can_retransform_classes` capability).
3840    /// If a class is not modifiable (`is_modifiable_class_ptr` returns `JNI_FALSE`) the class can be neither redefined nor retransformed.
3841    /// Primitive classes (for example, java.lang.Integer.TYPE), array classes, and some implementation defined classes are never modifiable.
3842    ///
3843    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IsModifiableClass>
3844    ///
3845    /// # Safety
3846    /// `klass` must be a valid strong reference or null.
3847    /// all pointer parameters must not be dangling.
3848    pub unsafe fn IsModifiableClass(&self, klass: jclass, is_modifiable_class_ptr: *mut jboolean) -> jvmtiError {
3849        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jboolean) -> jvmtiError>(44)(self.vtable, klass, is_modifiable_class_ptr) }
3850    }
3851
3852    /// For the class indicated by klass, return via `classloader_ptr` a reference to the class loader for the class.
3853    ///
3854    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IsModifiableClass>
3855    ///
3856    /// # Safety
3857    /// `klass` must be a valid strong reference or null.
3858    /// all pointer parameters must not be dangling.
3859    pub unsafe fn GetClassLoader(&self, klass: jclass, classloader_ptr: *mut jobject) -> jvmtiError {
3860        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut jobject) -> jvmtiError>(56)(self.vtable, klass, classloader_ptr) }
3861    }
3862
3863    /// For the class indicated by klass, return the debug extension via `source_debug_extension_ptr`.
3864    /// The returned string contains exactly the debug extension information present in the class file of klass.
3865    ///
3866    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetSourceDebugExtension>
3867    ///
3868    /// # Safety
3869    /// `klass` must be a valid strong reference or null.
3870    /// all pointer parameters must not be dangling.
3871    pub unsafe fn GetSourceDebugExtension(&self, klass: jclass, source_debug_extension_ptr: *mut *mut c_char) -> jvmtiError {
3872        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, *mut *mut c_char) -> jvmtiError>(89)(self.vtable, klass, source_debug_extension_ptr) }
3873    }
3874
3875    /// This function facilitates the bytecode instrumentation of already loaded classes.
3876    ///
3877    /// To replace the class definition without reference to the existing bytecodes,
3878    /// as one might do when recompiling from source for fix-and-continue debugging,
3879    /// `RedefineClasses` function should be used instead.
3880    ///
3881    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#RetransformClasses>
3882    ///
3883    /// # Safety
3884    /// `klass` must be a valid strong reference or null.
3885    /// all pointer parameters must not be dangling.
3886    pub unsafe fn RetransformClasses(&self, class_count: jint, classes: *const jclass) -> jvmtiError {
3887        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, *const jclass) -> jvmtiError>(151)(self.vtable, class_count, classes) }
3888    }
3889
3890    /// All classes given are redefined according to the definitions supplied.
3891    ///
3892    /// This function is used to replace the definition of a class with a new definition, as might be needed in fix-and-continue debugging.
3893    /// Where the existing class file bytes are to be transformed, for example in bytecode instrumentation, `RetransformClasses` should be used.
3894    ///
3895    /// Redefinition can cause new versions of methods to be installed.
3896    /// Old method versions may become obsolete The new method version will be used on new invokes.
3897    /// If a method has active stack frames, those active frames continue to run the bytecodes of the original method version.
3898    /// If resetting of stack frames is desired, use `PopFrame` to pop frames with obsolete method versions.
3899    ///
3900    /// This function does not cause any initialization except that which would occur under the customary JVM semantics.
3901    /// In other words, redefining a class does not cause its initializers to be run.
3902    /// The values of static fields will remain as they were prior to the call.
3903    ///
3904    /// Threads need not be suspended.
3905    /// All breakpoints in the class are cleared.
3906    /// All attributes are updated.
3907    /// Instances of the redefined class are not affected, fields retain their previous values.
3908    /// Tags on the instances are also unaffected.
3909    /// In response to this call, the JVM TI event Class File Load Hook will be sent (if enabled),
3910    /// but no other JVM TI events will be sent.
3911    ///
3912    /// The redefinition may change method bodies, the constant pool and attributes (unless explicitly prohibited).
3913    /// The redefinition must not add, remove or rename fields or methods, change the signatures of methods, change modifiers, or change inheritance.
3914    /// The redefinition must not change the `NestHost`, `NestMembers`, `Record`, or `PermittedSubclasses` attributes.
3915    /// These restrictions may be lifted in future versions.
3916    /// See the error return description for information on error codes returned if an unsupported redefinition is attempted.
3917    /// The class file bytes are not verified or installed until they have passed through the chain of `ClassFileLoadHook` events,
3918    /// thus the returned error code reflects the result of the transformations applied to the bytes passed into `class_definitions`.
3919    ///
3920    /// If any error code is returned other than `JVMTI_ERROR_NONE`,
3921    /// none of the classes to be redefined will have a new definition installed.
3922    ///
3923    /// When this function returns (with the error code of `JVMTI_ERROR_NONE`)
3924    /// all of the classes to be redefined will have their new definitions installed.
3925    ///
3926    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#RedefineClasses>
3927    ///
3928    /// # Safety
3929    /// `class_count` and `class_definitions` must form a valid array.
3930    /// all pointer parameters must not be dangling.
3931    /// `class_definitions` must be internally consistent and valid. (no dangling pointers, size + byte pointer must match)
3932    pub unsafe fn RedefineClasses(&self, class_count: jint, class_definitions: *const jvmtiClassDefinition) -> jvmtiError {
3933        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, *const jvmtiClassDefinition) -> jvmtiError>(86)(self.vtable, class_count, class_definitions) }
3934    }
3935
3936    /// For the object indicated by object, return via `size_ptr` the size of the object.
3937    ///
3938    /// This size is an implementation-specific approximation of the amount of storage consumed by this object.
3939    /// It may include some or all of the object's overhead, and thus is useful for comparison within an implementation but not between implementations.
3940    /// The estimate may change during a single invocation of the JVM.
3941    ///
3942    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetObjectSize>
3943    ///
3944    /// # Safety
3945    /// `object` must be a valid strong reference or null.
3946    /// all pointer parameters must not be dangling.
3947    pub unsafe fn GetObjectSize(&self, object: jobject, size_ptr: *mut jlong) -> jvmtiError {
3948        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, *mut jlong) -> jvmtiError>(153)(self.vtable, object, size_ptr) }
3949    }
3950
3951    /// For the object indicated by object, return via `hash_code_ptr` a hash code.
3952    ///
3953    /// This hash code could be used to maintain a hash table of object references, however, on some implementations this can cause significant performance impacts,
3954    /// in most cases tags will be a more efficient means of associating information with objects.
3955    ///
3956    /// This function guarantees the same hash code value for a particular object throughout its life
3957    ///
3958    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetObjectHashCode>
3959    ///
3960    /// # Safety
3961    /// `object` must be a valid strong reference or null.
3962    /// all pointer parameters must not be dangling.
3963    pub unsafe fn GetObjectHashCode(&self, object: jobject, hash_code_ptr: *mut jint) -> jvmtiError {
3964        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, *mut jint) -> jvmtiError>(57)(self.vtable, object, hash_code_ptr) }
3965    }
3966
3967    /// Get information about the object's monitor. The fields of the jvmtiMonitorUsage structure are filled in with information about usage of the monitor.
3968    ///
3969    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetObjectMonitorUsage>
3970    ///
3971    /// # Safety
3972    /// `object` must be a valid strong reference or null.
3973    /// all pointer parameters must not be dangling.
3974    pub unsafe fn GetObjectMonitorUsage(&self, object: jobject, info_ptr: *mut jvmtiMonitorUsage) -> jvmtiError {
3975        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jobject, *mut jvmtiMonitorUsage) -> jvmtiError>(58)(self.vtable, object, info_ptr) }
3976    }
3977
3978    /// For the field indicated by klass and field, return the field name via `name_ptr` and field signature via `signature_ptr`.
3979    ///
3980    /// 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.
3981    ///
3982    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetFieldName>
3983    ///
3984    /// # Safety
3985    /// `klass` must be a valid strong reference or null.
3986    /// `field` must be a valid field reference in the class referred to by `klass`
3987    /// all pointer parameters must not be dangling.
3988    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 {
3989        unsafe {
3990            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, jfieldID, *mut *mut c_char, *mut *mut c_char, *mut *mut c_char) -> jvmtiError>(59)(
3991                self.vtable,
3992                klass,
3993                field,
3994                name_ptr,
3995                signature_ptr,
3996                generic_ptr,
3997            )
3998        }
3999    }
4000
4001    /// For the field indicated by klass and field return the class that defined it via `declaring_class_ptr`.
4002    /// The declaring class will either be klass, a superclass, or an implemented interface.
4003    ///
4004    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetFieldDeclaringClass>
4005    ///
4006    /// # Safety
4007    /// `klass` must be a valid strong reference or null.
4008    /// `field` must be a valid field reference in the class referred to by `klass`
4009    /// all pointer parameters must not be dangling.
4010    pub unsafe fn GetFieldDeclaringClass(&self, klass: jclass, field: jfieldID, declaring_class_ptr: *mut jclass) -> jvmtiError {
4011        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, jfieldID, *mut jclass) -> jvmtiError>(60)(self.vtable, klass, field, declaring_class_ptr) }
4012    }
4013
4014    /// For the field indicated by klass and field return the access flags via `modifiers_ptr`.
4015    ///
4016    /// Access flags are defined in The Java™ Virtual Machine Specification, Chapter 4.
4017    ///
4018    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetFieldModifiers>
4019    ///
4020    /// # Safety
4021    /// `klass` must be a valid strong reference or null.
4022    /// `field` must be a valid field reference in the class referred to by `klass`
4023    /// all pointer parameters must not be dangling.
4024    pub unsafe fn GetFieldModifiers(&self, klass: jclass, field: jfieldID, modifiers_ptr: *mut jint) -> jvmtiError {
4025        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, jfieldID, *mut jint) -> jvmtiError>(61)(self.vtable, klass, field, modifiers_ptr) }
4026    }
4027
4028    /// For the field indicated by klass and field, return a value indicating whether the field is synthetic via `is_synthetic_ptr`.
4029    ///
4030    /// Synthetic fields are generated by the compiler but not present in the original source code.
4031    ///
4032    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IsFieldSynthetic>
4033    ///
4034    /// # Safety
4035    /// `klass` must be a valid strong reference or null.
4036    /// `field` must be a valid field reference in the class referred to by `klass`
4037    /// all pointer parameters must not be dangling.
4038    pub unsafe fn IsFieldSynthetic(&self, klass: jclass, field: jfieldID, is_synthetic_ptr: *mut jboolean) -> jvmtiError {
4039        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jclass, jfieldID, *mut jboolean) -> jvmtiError>(62)(self.vtable, klass, field, is_synthetic_ptr) }
4040    }
4041
4042    /// For the method indicated by method, return the method name via `name_ptr` and method signature via `signature_ptr`.
4043    ///
4044    /// 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.
4045    /// Note this is different than method signatures as defined in the Java Language Specification.
4046    ///
4047    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetMethodName>
4048    ///
4049    /// # Safety
4050    /// `method` must be a valid methodID or null.
4051    /// all pointer parameters must not be dangling.
4052    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 {
4053        unsafe {
4054            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut *mut c_char, *mut *mut c_char, *mut *mut c_char) -> jvmtiError>(63)(
4055                self.vtable,
4056                method,
4057                name_ptr,
4058                signature_ptr,
4059                generic_ptr,
4060            )
4061        }
4062    }
4063
4064    /// For the method indicated by method, return the class that defined it via `declaring_class_ptr`.
4065    ///
4066    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetMethodDeclaringClass>
4067    ///
4068    /// # Safety
4069    /// `method` must be a valid methodID or null.
4070    /// all pointer parameters must not be dangling.
4071    pub unsafe fn GetMethodDeclaringClass(&self, method: jmethodID, declaring_class_ptr: *mut jclass) -> jvmtiError {
4072        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jclass) -> jvmtiError>(64)(self.vtable, method, declaring_class_ptr) }
4073    }
4074
4075    /// For the method indicated by method, return the access flags via `modifiers_ptr`.
4076    ///
4077    /// Access flags are defined in The Java™ Virtual Machine Specification, Chapter 4.
4078    ///
4079    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetMethodModifiers>
4080    ///
4081    /// # Safety
4082    /// `method` must be a valid methodID or null.
4083    /// all pointer parameters must not be dangling.
4084    pub unsafe fn GetMethodModifiers(&self, method: jmethodID, modifiers_ptr: *mut jint) -> jvmtiError {
4085        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jint) -> jvmtiError>(65)(self.vtable, method, modifiers_ptr) }
4086    }
4087
4088    /// For the method indicated by method, return the number of local variable slots used by the method,
4089    /// including the local variables used to pass parameters to the method on its invocation.
4090    ///
4091    /// See `max_locals` in The Java™ Virtual Machine Specification, Chapter 4.7.3.
4092    ///
4093    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetMaxLocals>
4094    ///
4095    /// # Safety
4096    /// `method` must be a valid methodID or null.
4097    /// all pointer parameters must not be dangling.
4098    pub unsafe fn GetMaxLocals(&self, method: jmethodID, max_ptr: *mut jint) -> jvmtiError {
4099        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jint) -> jvmtiError>(67)(self.vtable, method, max_ptr) }
4100    }
4101
4102    /// For the method indicated by method, return via `max_ptr` the number of local variable slots used by the method's arguments.
4103    ///
4104    /// Note that two-word arguments use two slots.
4105    ///
4106    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetArgumentsSize>
4107    ///
4108    /// # Safety
4109    /// `method` must be a valid methodID or null.
4110    /// all pointer parameters must not be dangling.
4111    pub unsafe fn GetArgumentsSize(&self, method: jmethodID, max_ptr: *mut jint) -> jvmtiError {
4112        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jint) -> jvmtiError>(68)(self.vtable, method, max_ptr) }
4113    }
4114
4115    /// For the method indicated by method, return a table of source line number entries.
4116    /// The size of the table is returned via `entry_count_ptr` and the table itself is returned via `table_ptr`.
4117    ///
4118    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetLineNumberTable>
4119    ///
4120    /// # Safety
4121    /// `method` must be a valid methodID or null.
4122    /// all pointer parameters must not be dangling.
4123    pub unsafe fn GetLineNumberTable(&self, method: jmethodID, entry_count_ptr: *mut jint, table_ptr: *mut *mut jvmtiLineNumberEntry) -> jvmtiError {
4124        unsafe {
4125            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jint, *mut *mut jvmtiLineNumberEntry) -> jvmtiError>(69)(
4126                self.vtable,
4127                method,
4128                entry_count_ptr,
4129                table_ptr,
4130            )
4131        }
4132    }
4133
4134    /// For the method indicated by method, return the beginning and ending addresses through `start_location_ptr` and `end_location_ptr`.
4135    /// 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.
4136    ///
4137    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetMethodLocation>
4138    ///
4139    /// # Safety
4140    /// `method` must be a valid methodID or null.
4141    /// all pointer parameters must not be dangling.
4142    pub unsafe fn GetMethodLocation(&self, method: jmethodID, start_location_ptr: *mut jlocation, end_location_ptr: *mut jlocation) -> jvmtiError {
4143        unsafe {
4144            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jlocation, *mut jlocation) -> jvmtiError>(70)(self.vtable, method, start_location_ptr, end_location_ptr)
4145        }
4146    }
4147
4148    /// Return local variable information.
4149    ///
4150    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetLocalVariableTable>
4151    ///
4152    /// # Safety
4153    /// `method` must be a valid methodID or null.
4154    /// all pointer parameters must not be dangling.
4155    pub unsafe fn GetLocalVariableTable(&self, method: jmethodID, entry_count_ptr: *mut jint, table_ptr: *mut *mut jvmtiLocalVariableEntry) -> jvmtiError {
4156        unsafe {
4157            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jint, *mut *mut jvmtiLocalVariableEntry) -> jvmtiError>(71)(
4158                self.vtable,
4159                method,
4160                entry_count_ptr,
4161                table_ptr,
4162            )
4163        }
4164    }
4165
4166    /// For the method indicated by method, return the bytecodes that implement the method. The number of bytecodes is returned via `bytecode_count_ptr`.
4167    ///
4168    /// The bytecodes themselves are returned via `bytecodes_ptr`.
4169    ///
4170    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetBytecodes>
4171    ///
4172    /// # Safety
4173    /// `method` must be a valid methodID or null.
4174    /// all pointer parameters must not be dangling.
4175    pub unsafe fn GetBytecodes(&self, method: jmethodID, bytecode_count_ptr: *mut jint, bytecodes_ptr: *mut *mut c_uchar) -> jvmtiError {
4176        unsafe {
4177            self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jint, *mut *mut c_uchar) -> jvmtiError>(74)(self.vtable, method, bytecode_count_ptr, bytecodes_ptr)
4178        }
4179    }
4180
4181    /// For the method indicated by method, return a value indicating whether the method is native via `is_native_ptr`.
4182    ///
4183    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IsMethodNative>
4184    ///
4185    /// # Safety
4186    /// `method` must be a valid methodID or null.
4187    /// all pointer parameters must not be dangling.
4188    pub unsafe fn IsMethodNative(&self, method: jmethodID, is_native_ptr: *mut jboolean) -> jvmtiError {
4189        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jboolean) -> jvmtiError>(75)(self.vtable, method, is_native_ptr) }
4190    }
4191
4192    /// For the method indicated by method, return a value indicating whether the method is synthetic via `is_synthetic_ptr`.
4193    ///
4194    /// Synthetic methods are generated by the compiler but not present in the original source code.
4195    ///
4196    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IsMethodSynthetic>
4197    ///
4198    /// # Safety
4199    /// `method` must be a valid methodID or null.
4200    /// all pointer parameters must not be dangling.
4201    pub unsafe fn IsMethodSynthetic(&self, method: jmethodID, is_synthetic_ptr: *mut jboolean) -> jvmtiError {
4202        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jboolean) -> jvmtiError>(76)(self.vtable, method, is_synthetic_ptr) }
4203    }
4204
4205    /// Determine if a method ID refers to an obsolete method version.
4206    ///
4207    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#IsMethodObsolete>
4208    ///
4209    /// # Safety
4210    /// `method` must be a valid methodID or null.
4211    /// all pointer parameters must not be dangling.
4212    pub unsafe fn IsMethodObsolete(&self, method: jmethodID, is_obsolete_ptr: *mut jboolean) -> jvmtiError {
4213        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jmethodID, *mut jboolean) -> jvmtiError>(90)(self.vtable, method, is_obsolete_ptr) }
4214    }
4215
4216    /// This function modifies the failure handling of native method resolution by allowing retry with a prefix applied to the name.
4217    ///
4218    /// When used with the `ClassFileLoadHook` event, it enables native methods to be instrumented.
4219    ///
4220    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetNativeMethodPrefix>
4221    ///
4222    /// # Safety
4223    /// `prefix` must be a rust string type or a valid zero terminated utf-8 string or null.
4224    /// all pointer parameters must not be dangling.
4225    pub unsafe fn SetNativeMethodPrefix(&self, prefix: impl UseCString) -> jvmtiError {
4226        unsafe { prefix.use_as_const_c_char(|prefix| self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const c_char) -> jvmtiError>(72)(self.vtable, prefix)) }
4227    }
4228
4229    /// For a normal agent, `SetNativeMethodPrefix` will provide all needed native method prefixing.
4230    /// 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.
4231    /// 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`.
4232    ///
4233    /// Any previous prefixes are replaced. Thus, calling this function with a `prefix_count` of 0 disables prefixing in this environment.
4234    ///
4235    /// `SetNativeMethodPrefix` and this function are the two ways to set the prefixes.
4236    /// Calling `SetNativeMethodPrefix` with a prefix is the same as calling this function with `prefix_count` of 1.
4237    /// Calling `SetNativeMethodPrefix` with NULL is the same as calling this function with `prefix_count` of 0.
4238    ///
4239    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetNativeMethodPrefix>
4240    ///
4241    /// # Safety
4242    /// `prefixes` must contain valid zero terminated utf-8 strings.
4243    /// `prefix_count` and `prefixes` must form a valid array.
4244    /// all pointer parameters must not be dangling.
4245    pub unsafe fn SetNativeMethodPrefixes(&self, prefix_count: jint, prefixes: *mut *mut c_char) -> jvmtiError {
4246        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, *mut *mut c_char) -> jvmtiError>(73)(self.vtable, prefix_count, prefixes) }
4247    }
4248
4249    /// Create a raw monitor.
4250    ///
4251    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#CreateRawMonitor>
4252    ///
4253    /// # Safety
4254    /// `name` must be a rust string type or a valid zero terminated utf-8 string or null.
4255    /// all pointer parameters must not be dangling.
4256    pub unsafe fn CreateRawMonitor(&self, name: impl UseCString, monitor_ptr: *mut jrawMonitorID) -> jvmtiError {
4257        unsafe {
4258            name.use_as_const_c_char(|name| self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const c_char, *mut jrawMonitorID) -> jvmtiError>(30)(self.vtable, name, monitor_ptr))
4259        }
4260    }
4261
4262    /// Destroy the raw monitor.
4263    ///
4264    /// If the monitor being destroyed has been entered by this thread, it will be exited before it is destroyed.
4265    /// If the monitor being destroyed has been entered by another thread, an error will be returned and the monitor will not be destroyed.
4266    ///
4267    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#DestroyRawMonitor>
4268    ///
4269    /// # Safety
4270    /// `monitor` must be a valid raw monitor
4271    pub unsafe fn DestroyRawMonitor(&self, monitor: jrawMonitorID) -> jvmtiError {
4272        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jrawMonitorID) -> jvmtiError>(31)(self.vtable, monitor) }
4273    }
4274
4275    /// Gain exclusive ownership of a raw monitor.
4276    ///
4277    /// The same thread may enter a monitor more then once.
4278    /// The thread must exit the monitor the same number of times as it is entered.
4279    /// If a monitor is entered during `OnLoad` (before attached threads exist) and has not exited when attached threads come into existence,
4280    /// the enter is considered to have occurred on the main thread.
4281    ///
4282    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#RawMonitorEnter>
4283    ///
4284    /// # Safety
4285    /// `monitor` must be a valid raw monitor
4286    pub unsafe fn RawMonitorEnter(&self, monitor: jrawMonitorID) -> jvmtiError {
4287        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jrawMonitorID) -> jvmtiError>(32)(self.vtable, monitor) }
4288    }
4289
4290    /// Release exclusive ownership of a raw monitor.
4291    ///
4292    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#RawMonitorExit>
4293    ///
4294    /// # Safety
4295    /// `monitor` must be a valid raw monitor
4296    pub unsafe fn RawMonitorExit(&self, monitor: jrawMonitorID) -> jvmtiError {
4297        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jrawMonitorID) -> jvmtiError>(33)(self.vtable, monitor) }
4298    }
4299
4300    /// Wait for notification of the raw monitor.
4301    ///
4302    /// 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.
4303    ///
4304    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#RawMonitorWait>
4305    ///
4306    /// # Safety
4307    /// `monitor` must be a valid raw monitor
4308    pub unsafe fn RawMonitorWait(&self, monitor: jrawMonitorID) -> jvmtiError {
4309        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jrawMonitorID) -> jvmtiError>(34)(self.vtable, monitor) }
4310    }
4311
4312    /// Notify a single thread waiting on the raw monitor.
4313    ///
4314    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#RawMonitorNotify>
4315    ///
4316    /// # Safety
4317    /// `monitor` must be a valid raw monitor
4318    pub unsafe fn RawMonitorNotify(&self, monitor: jrawMonitorID) -> jvmtiError {
4319        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jrawMonitorID) -> jvmtiError>(35)(self.vtable, monitor) }
4320    }
4321
4322    /// Notify all threads waiting on the raw monitor.
4323    ///
4324    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#RawMonitorNotifyAll>
4325    ///
4326    /// # Safety
4327    /// `monitor` must be a valid raw monitor
4328    pub unsafe fn RawMonitorNotifyAll(&self, monitor: jrawMonitorID) -> jvmtiError {
4329        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jrawMonitorID) -> jvmtiError>(36)(self.vtable, monitor) }
4330    }
4331
4332    /// Set the JNI function table in all current and future JNI environments.
4333    ///
4334    /// As a result, all future JNI calls are directed to the specified functions.
4335    /// Use `GetJNIFunctionTable` to get the function table to pass to this function.
4336    /// For this function to take effect the updated table entries must be used by the JNI clients.
4337    /// The table is copied--changes to the local copy of the table have no effect.
4338    /// This function affects only the function table, all other aspects of the environment are unaffected.
4339    ///
4340    /// # Compiler Optimizations
4341    /// Since the table is defined const in the C headers some compilers may optimize away the access to the table,
4342    /// thus preventing this function from taking effect.
4343    /// This is entirely dependant on the compiler and its settings that was used to compile the JNI Client.
4344    /// The rust compiler settings used to compile the JVMTI agent have no effect on this.
4345    ///
4346    /// ## Rust Compiler Optimizations
4347    /// 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
4348    /// regardless of chosen rust compiler settings and flags.
4349    /// It is very unlikely that future versions of the rust compiler will change this behavior.
4350    ///
4351    ///
4352    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetJNIFunctionTable>
4353    ///
4354    /// # Safety
4355    /// `function_table` must be a valid initalized jni function table
4356    pub unsafe fn SetJNIFunctionTable(&self, function_table: jniNativeInterface) -> jvmtiError {
4357        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jniNativeInterface) -> jvmtiError>(119)(self.vtable, function_table) }
4358    }
4359
4360    /// Get the JNI function table. The JNI function table is copied into allocated memory.
4361    ///
4362    /// If `SetJNIFunctionTable` has been called, the modified (not the original) function table is returned.
4363    /// Only the function table is copied, no other aspects of the environment are copied.
4364    ///
4365    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetJNIFunctionTable>
4366    ///
4367    /// # Safety
4368    /// `function_table` must not be dangling
4369    pub unsafe fn GetJNIFunctionTable(&self, function_table: *mut jniNativeInterface) -> jvmtiError {
4370        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jniNativeInterface) -> jvmtiError>(120)(self.vtable, function_table) }
4371    }
4372
4373    /// Set the functions to be called for each event.
4374    ///
4375    /// The callbacks are specified by supplying a replacement function table.
4376    ///
4377    /// The function table is copied, changes to the local copy of the table have no effect.
4378    /// This is an atomic action, all callbacks are set at once.
4379    ///
4380    /// No events are sent before this function is called.
4381    /// When an entry is NULL or when the event is beyond `size_of_callbacks` no event is sent.
4382    /// Details on events are described later in this document.
4383    ///
4384    /// An event must be enabled and have a callback in order to be sent,
4385    /// the order in which this function and `SetEventNotificationMode` are called does not affect the result.
4386    ///
4387    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetEventCallbacks>
4388    ///
4389    /// # Safety
4390    /// `callbacks` must not be dangling
4391    #[expect(clippy::cast_possible_truncation)] // size_of::<jvmtiEventCallbacks>() will never be larger than jint::MAX
4392    #[expect(clippy::cast_possible_wrap)]
4393    pub unsafe fn SetEventCallbacks(&self, callbacks: *const jvmtiEventCallbacks) -> jvmtiError {
4394        unsafe {
4395            self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const jvmtiEventCallbacks, jint) -> jvmtiError>(121)(self.vtable, callbacks, size_of::<jvmtiEventCallbacks>() as jint)
4396        }
4397    }
4398
4399    /// Raw variant of `SetEventCallbacks` which allows for passing an arbitrary payload.
4400    /// This is useful when attempting to use a jvmti version that is newer than what jni-simple supports.
4401    ///
4402    /// # Safety
4403    /// The `callbacks` and `size_of_callbacks` must match what the jvm expects.
4404    pub unsafe fn SetEventCallbacks_raw(&self, callbacks: *const c_void, size_of_callbacks: jint) -> jvmtiError {
4405        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const jvmtiEventCallbacks, jint) -> jvmtiError>(121)(self.vtable, callbacks.cast(), size_of_callbacks) }
4406    }
4407
4408    /// Control the generation of events.
4409    ///
4410    /// Calling this function either enables or disables future generation of specific jvmti events.
4411    /// If `event_thread` is null then this control the behavior of event generation a global level.
4412    /// Otherwise changes are only made for the given thread.
4413    ///
4414    /// The following events cannot be controlled at the thread level through this function:
4415    /// - `VMInit`
4416    /// - `VMStart`
4417    /// - `VMDeath`
4418    /// - `ThreadStart`
4419    /// - `VirtualThreadStart`
4420    /// - `CompiledMethodLoad`
4421    /// - `CompiledMethodUnload`
4422    /// - `DynamicCodeGenerated`
4423    /// - `DataDumpRequest`
4424    ///
4425    /// Initially, no events are enabled at either the thread level or the global level.
4426    /// Any needed capabilities (see Event Enabling Capabilities below) must be possessed before calling this function.
4427    ///
4428    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetEventNotificationMode>
4429    ///
4430    /// # Safety
4431    /// `event_thread` must either be null or a valid strong reference to a jthread.
4432    /// The `callbacks` and `size_of_callbacks` must match what the jvm expects.
4433    pub unsafe fn SetEventNotificationMode(&self, mode: jvmtiEventMode, event_type: jvmtiEvent, event_thread: jthread) -> jvmtiError {
4434        unsafe { self.jvmti::<extern "C" fn(JVMTIEnvVTable, jvmtiEventMode, jvmtiEvent, jthread, ...) -> jvmtiError>(1)(self.vtable, mode, event_type, event_thread) }
4435    }
4436
4437    /// Allows for calling undocumented variadic extensions.
4438    /// The current jvmti specification only provides this function with the disclaimer
4439    /// "for future expansion"
4440    ///
4441    /// Since rust does support c-variadics yet calling this from rust is non trivial.
4442    ///
4443    /// # Safety
4444    /// There are a lot of things that can go wrong when calling this function, see the example.
4445    /// using this function requires deep knowledge of jvm implementation specific details.
4446    /// Use with care and only if necessary.
4447    ///
4448    /// # Example
4449    /// ```rust
4450    /// use std::ffi::{c_int, c_void};
4451    /// use core::ptr::null_mut;
4452    /// use jni_simple::*;
4453    ///
4454    /// fn enable_very_special_custom_event(env: JVMTIEnv) {
4455    ///   unsafe {
4456    ///     //NOTE: jvmtiEvent with a value 5 does not exist, this is just for illustrative purposes!
4457    ///     //This example assumes that the hypothetical global jni event 5 would want a jint extension parameter.
4458    ///     let _err : jvmtiError = env.SetEventNotificationMode_extension::<extern "C" fn(*mut c_void, jvmtiEventMode, c_int, jthread, ...) -> jvmtiError>()
4459    ///         (env.vtable(), jvmtiEventMode::JVMTI_ENABLE, 5, null_mut(), 4i32);
4460    ///   }
4461    /// }
4462    /// ```
4463    #[must_use]
4464    pub unsafe fn SetEventNotificationMode_extension<X>(&self) -> X {
4465        unsafe { self.jvmti::<X>(1) }
4466    }
4467
4468    /// Generate events to represent the current state of the VM.
4469    ///
4470    /// For example, if `event_type` is `JVMTI_EVENT_COMPILED_METHOD_LOAD`, a `CompiledMethodLoad` event will be sent for each currently compiled method.
4471    /// Methods that were loaded and now have been unloaded are not sent.
4472    /// The history of what events have previously been sent does not effect what events are sent by this function,
4473    /// for example, all currently compiled methods will be sent each time this function is called.
4474    ///
4475    /// 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.
4476    ///
4477    /// Attempts to execute Java programming language code or JNI functions may be paused until this function returns,
4478    /// so neither should be called from the thread sending the event.
4479    ///
4480    /// This function returns only after the missed events have been sent, processed and have returned.
4481    ///
4482    /// The event may be sent on a different thread than the thread on which the event occurred.
4483    /// The callback for the event must be set with `SetEventCallbacks` and the event must be enabled with `SetEventNotificationMode` or the events will not occur.
4484    /// 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.
4485    ///
4486    /// Only the following events are supported:
4487    /// - `CompiledMethodLoad`
4488    /// - `DynamicCodeGenerated`
4489    ///
4490    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GenerateEvents>
4491    ///
4492    /// # Safety
4493    /// `function_table` must not be dangling
4494    pub unsafe fn GenerateEvents(&self, event_type: jvmtiEvent) -> jvmtiError {
4495        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jvmtiEvent) -> jvmtiError>(122)(self.vtable, event_type) }
4496    }
4497
4498    /// Returns the set of extension functions.
4499    ///
4500    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetExtensionFunctions>
4501    ///
4502    /// # Safety
4503    /// all pointer parameters must not be dangling
4504    pub unsafe fn GetExtensionFunctions(&self, extension_count_ptr: *mut jint, extensions: *mut *mut jvmtiExtensionFunctionInfo) -> jvmtiError {
4505        unsafe {
4506            self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jint, *mut *mut jvmtiExtensionFunctionInfo) -> jvmtiError>(123)(self.vtable, extension_count_ptr, extensions)
4507        }
4508    }
4509
4510    /// Returns the set of extension events.
4511    ///
4512    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetExtensionEvents>
4513    ///
4514    /// # Safety
4515    /// all pointer parameters must not be dangling
4516    pub unsafe fn GetExtensionEvents(&self, extension_count_ptr: *mut jint, extensions: *mut *mut jvmtiExtensionEventInfo) -> jvmtiError {
4517        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jint, *mut *mut jvmtiExtensionEventInfo) -> jvmtiError>(124)(self.vtable, extension_count_ptr, extensions) }
4518    }
4519
4520    /// Sets the callback function for an extension event and enables the event. Or, if the callback is NULL, disables the event.
4521    ///
4522    /// Note that unlike standard events, setting the callback and enabling the event are a single operation.
4523    ///
4524    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetExtensionEventCallback>
4525    ///
4526    /// # Safety
4527    /// all pointer parameters must not be dangling
4528    /// `callback` must match the function signature that the jvm implementation expects.
4529    pub unsafe fn SetExtensionEventCallback(&self, extension_event_index: jint, callback: jvmtiExtensionEvent) -> jvmtiError {
4530        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint, jvmtiExtensionEvent) -> jvmtiError>(125)(self.vtable, extension_event_index, callback) }
4531    }
4532
4533    /// Get information about the `GetCurrentThreadCpuTime` timer.
4534    ///
4535    /// The fields of the jvmtiTimerInfo structure are filled in with details about the timer.
4536    ///
4537    /// 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.
4538    ///
4539    /// Note that the implementations of `GetCurrentThreadCpuTime` and `GetThreadCpuTime` may differ,
4540    /// and thus the values returned by `GetCurrentThreadCpuTimerInfo` and `GetThreadCpuTimerInfo` may differ,
4541    /// see `GetCurrentThreadCpuTime` for more information.
4542    ///
4543    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetCurrentThreadCpuTimerInfo>
4544    ///
4545    /// # Safety
4546    /// all pointer parameters must not be dangling
4547    pub unsafe fn GetCurrentThreadCpuTimerInfo(&self, info_ptr: *mut jvmtiTimerInfo) -> jvmtiError {
4548        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jvmtiTimerInfo) -> jvmtiError>(133)(self.vtable, info_ptr) }
4549    }
4550
4551    /// Return the CPU time utilized by the current thread.
4552    ///
4553    /// Note that the `GetThreadCpuTime` function provides CPU time for any thread, including the current thread.
4554    /// `GetCurrentThreadCpuTime` exists to support platforms which cannot supply CPU time for threads other than the current thread
4555    /// or which have more accurate information for the current thread (see `GetCurrentThreadCpuTimerInfo` vs `GetThreadCpuTimerInfo`).
4556    ///
4557    /// 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.
4558    /// see `GetCurrentThreadCpuTime` for more information.
4559    ///
4560    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetCurrentThreadCpuTime>
4561    ///
4562    /// # Safety
4563    /// all pointer parameters must not be dangling
4564    pub unsafe fn GetCurrentThreadCpuTime(&self, nanos_ptr: *mut jlong) -> jvmtiError {
4565        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jlong) -> jvmtiError>(134)(self.vtable, nanos_ptr) }
4566    }
4567
4568    /// Get information about the `GetCurrentThreadCpuTime` timer.
4569    ///
4570    /// The fields of the jvmtiTimerInfo structure are filled in with details about the timer.
4571    ///
4572    /// 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.
4573    ///
4574    /// Note that the implementations of `GetCurrentThreadCpuTime` and `GetThreadCpuTime` may differ,
4575    /// and thus the values returned by `GetCurrentThreadCpuTimerInfo` and `GetThreadCpuTimerInfo` may differ,
4576    /// see `GetCurrentThreadCpuTime` for more information.
4577    ///
4578    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetCurrentThreadCpuTimerInfo>
4579    ///
4580    /// # Safety
4581    /// all pointer parameters must not be dangling
4582    pub unsafe fn GetThreadCpuTimerInfo(&self, info_ptr: *mut jvmtiTimerInfo) -> jvmtiError {
4583        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jvmtiTimerInfo) -> jvmtiError>(135)(self.vtable, info_ptr) }
4584    }
4585
4586    /// Return the CPU time utilized by the specified thread.
4587    ///
4588    /// Get information about this timer with `GetThreadCpuTimerInfo`.
4589    ///
4590    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetThreadCpuTime>
4591    ///
4592    /// # Safety
4593    /// all pointer parameters must not be dangling
4594    pub unsafe fn GetThreadCpuTime(&self, thread: jthread, nanos_ptr: *mut jlong) -> jvmtiError {
4595        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jthread, *mut jlong) -> jvmtiError>(136)(self.vtable, thread, nanos_ptr) }
4596    }
4597
4598    /// Get information about the `GetTime` timer.
4599    ///
4600    /// The fields of the jvmtiTimerInfo structure are filled in with details about the timer.
4601    /// This information will not change during a particular invocation of the VM.
4602    ///
4603    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetTimerInfo>
4604    ///
4605    /// # Safety
4606    /// all pointer parameters must not be dangling
4607    pub unsafe fn GetTimerInfo(&self, info_ptr: *mut jvmtiTimerInfo) -> jvmtiError {
4608        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jvmtiTimerInfo) -> jvmtiError>(137)(self.vtable, info_ptr) }
4609    }
4610
4611    /// Return the current value of the system timer, in nanoseconds.
4612    ///
4613    /// The value returned represents nanoseconds since some fixed but arbitrary time (perhaps in the future, so values may be negative).
4614    ///
4615    /// This function provides nanosecond precision, but not necessarily nanosecond accuracy.
4616    ///
4617    /// No guarantees are made about how frequently values change.
4618    /// Get information about this timer with `GetTimerInfo`.
4619    ///
4620    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetTime>
4621    ///
4622    /// # Safety
4623    /// all pointer parameters must not be dangling
4624    pub unsafe fn GetTime(&self, nanos_ptr: *mut jlong) -> jvmtiError {
4625        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jlong) -> jvmtiError>(138)(self.vtable, nanos_ptr) }
4626    }
4627
4628    /// Returns the number of processors available to the Java virtual machine.
4629    ///
4630    /// This value may change during a particular invocation of the virtual machine.
4631    /// Applications that are sensitive to the number of available processors should therefore occasionally poll this property.
4632    ///
4633    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetAvailableProcessors>
4634    ///
4635    /// # Safety
4636    /// all pointer parameters must not be dangling
4637    pub unsafe fn GetAvailableProcessors(&self, processor_count_ptr: *mut jint) -> jvmtiError {
4638        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jint) -> jvmtiError>(143)(self.vtable, processor_count_ptr) }
4639    }
4640
4641    /// This function can be used to cause instrumentation classes to be defined by the bootstrap class loader.
4642    ///
4643    /// See The Java™ Virtual Machine Specification, Chapter 5.3.1. After the bootstrap class loader unsuccessfully searches for a class,
4644    /// the specified platform-dependent search path segment will be searched as well.
4645    ///
4646    /// Only one segment may be specified in the segment.
4647    /// This function may be called multiple times to add multiple segments, the segments will be searched in the order that this function was called.
4648    ///
4649    /// 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.
4650    /// The segment is typically a directory or JAR file.
4651    ///
4652    /// In the live phase the segment may be used to specify any platform-dependent path to a JAR file.
4653    /// 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.
4654    /// The Java™ Virtual Machine Specification specifies that a subsequent attempt to resolve a symbolic reference
4655    /// 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.
4656    /// 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,
4657    /// then subsequent attempts to resolve that reference will fail with the same error as the initial attempt.
4658    ///
4659    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#AddToSystemClassLoaderSearch>
4660    ///
4661    /// # Safety
4662    /// `segment` must be a rust string, or a valid zero terminated utf-8 string or null
4663    pub unsafe fn AddToBootstrapClassLoaderSearch(&self, segment: impl UseCString) -> jvmtiError {
4664        unsafe { segment.use_as_const_c_char(|segment| self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const c_char) -> jvmtiError>(148)(self.vtable, segment)) }
4665    }
4666
4667    /// 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.
4668    ///
4669    /// After the class loader unsuccessfully searches for a class, the specified platform-dependent search path segment will be searched as well.
4670    /// 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.
4671    ///
4672    /// 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.
4673    /// The segment is typically a directory or JAR file.
4674    ///
4675    /// 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.
4676    /// 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.
4677    ///
4678    /// 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
4679    /// which takes a single parameter of type java.lang.String. The method is not required to have public access.
4680    ///
4681    /// 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
4682    /// always fails with the same error that was thrown as a result of the initial resolution attempt.
4683    /// 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,
4684    /// then subsequent attempts to resolve that reference will fail with the same error as the initial attempt.
4685    ///
4686    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#AddToSystemClassLoaderSearch>
4687    ///
4688    /// # Safety
4689    /// `segment` must be a rust string, or a valid zero terminated utf-8 string or null
4690    pub unsafe fn AddToSystemClassLoaderSearch(&self, segment: impl UseCString) -> jvmtiError {
4691        unsafe { segment.use_as_const_c_char(|segment| self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const c_char) -> jvmtiError>(150)(self.vtable, segment)) }
4692    }
4693
4694    /// Provides access to system properties defined by and used by the VM.
4695    ///
4696    /// Properties set on the command-line are included.
4697    /// This allows getting and setting of these properties before the VM even begins executing bytecodes.
4698    /// 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.
4699    /// JNI method invocation may be used to access java.lang.System.getProperties.
4700    /// The set of properties may grow during execution.
4701    ///
4702    /// The list of VM system property keys which may be used with `GetSystemProperty` is returned.
4703    /// It is strongly recommended that virtual machines provide the following property keys:
4704    /// - java.vm.vendor
4705    /// - java.vm.version
4706    /// - java.vm.name
4707    /// - java.vm.info
4708    /// - java.library.path
4709    /// - java.class.path
4710    ///
4711    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetSystemProperties>
4712    ///
4713    /// # Safety
4714    /// all pointer parameters must not be dangling
4715    pub unsafe fn GetSystemProperties(&self, count_ptr: *mut jint, property_ptr: *mut *mut *mut c_char) -> jvmtiError {
4716        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jint, *mut *mut *mut c_char) -> jvmtiError>(129)(self.vtable, count_ptr, property_ptr) }
4717    }
4718
4719    /// Return a VM system property value given the property key.
4720    ///
4721    /// The function `GetSystemProperties` returns the set of property keys which may be used.
4722    /// The properties which can be retrieved may grow during execution.
4723    ///
4724    /// Since this is a VM view of system properties, the values of properties may differ from that returned by java.lang.System.getProperty(String).
4725    /// 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.
4726    /// Thereafter any changes to the VM system properties (with `SetSystemProperty`) or the java.lang.System system properties (with java.lang.System.setProperty(String,String))
4727    /// would cause the values to diverge.
4728    /// JNI method invocation may be used to access java.lang.System.getProperty(String).
4729    ///
4730    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetSystemProperty>
4731    ///
4732    /// # Safety
4733    /// `property` must be a rust string, a valid utf-8 zero terminated string or null.
4734    /// all pointer parameters must not be dangling
4735    pub unsafe fn GetSystemProperty(&self, property: impl UseCString, value_ptr: *mut *mut c_char) -> jvmtiError {
4736        unsafe {
4737            property.use_as_const_c_char(|property| {
4738                self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const c_char, *mut *mut c_char) -> jvmtiError>(130)(self.vtable, property, value_ptr)
4739            })
4740        }
4741    }
4742
4743    /// Set a VM system property value.
4744    ///
4745    /// The function `GetSystemProperties` returns the set of property keys, some of these may be settable. See `GetSystemProperty`.
4746    ///
4747    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetSystemProperty>
4748    ///
4749    /// # Safety
4750    /// `property` must be a rust string, a valid utf-8 zero terminated string or null.
4751    /// all pointer parameters must not be dangling
4752    pub unsafe fn SetSystemProperty(&self, property: impl UseCString, value_ptr: impl UseCString) -> jvmtiError {
4753        unsafe {
4754            property.use_as_const_c_char(|property| {
4755                value_ptr.use_as_const_c_char(|value_ptr| {
4756                    self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const c_char, *const c_char) -> jvmtiError>(131)(self.vtable, property, value_ptr)
4757                })
4758            })
4759        }
4760    }
4761
4762    /// Shutdown a JVM TI connection created with JNI `GetEnv` (see JVM TI Environments).
4763    ///
4764    /// Dispose of any resources held by the environment.
4765    /// Threads suspended by this environment are not resumed by this call, this must be done explicitly by the agent.
4766    /// 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.
4767    /// Raw monitors created by this environment are not destroyed, this can be done explicitly by the agent by calling `DestroyRawMonitor`.
4768    /// The state of threads waiting on raw monitors created by this environment are not affected.
4769    /// Any native method prefixes for this environment will be unset; the agent must remove any prefixed native methods before dispose is called.
4770    /// Any capabilities held by this environment are relinquished.
4771    /// Events enabled by this environment will no longer be sent, however event handlers currently running will continue to run.
4772    ///
4773    /// Caution must be exercised in the design of event handlers whose environment may be disposed and thus become invalid during their execution.
4774    /// This environment may not be used after this call. This call returns to the caller.
4775    ///
4776    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#DisposeEnvironment>
4777    ///
4778    /// # Safety
4779    /// 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.
4780    pub unsafe fn DisposeEnvironment(&self) -> jvmtiError {
4781        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable) -> jvmtiError>(126)(self.vtable) }
4782    }
4783
4784    /// The VM stores a pointer value associated with each environment.
4785    ///
4786    /// This pointer value is called environment-local storage. This value is NULL unless set with this function.
4787    /// Agents can allocate memory in which they store environment specific information.
4788    /// By setting environment-local storage it can then be accessed with `GetEnvironmentLocalStorage`.
4789    /// Called by the agent to set the value of the JVM TI environment-local storage.
4790    /// JVM TI supplies to the agent a pointer-size environment-local storage that can be used to record per-environment information.
4791    ///
4792    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetEnvironmentLocalStorage>
4793    ///
4794    /// # Safety
4795    /// JVM implementation specific
4796    pub unsafe fn SetEnvironmentLocalStorage(&self, data: *const c_void) -> jvmtiError {
4797        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *const c_void) -> jvmtiError>(147)(self.vtable, data) }
4798    }
4799
4800    /// The VM stores a pointer value associated with each environment.
4801    ///
4802    /// This pointer value is called environment-local storage. This value is NULL unless set with this function.
4803    /// Agents can allocate memory in which they store environment specific information.
4804    /// By setting environment-local storage it can then be accessed with `GetEnvironmentLocalStorage`.
4805    /// Called by the agent to set the value of the JVM TI environment-local storage.
4806    /// JVM TI supplies to the agent a pointer-size environment-local storage that can be used to record per-environment information.
4807    ///
4808    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetEnvironmentLocalStorage>
4809    ///
4810    /// # Safety
4811    /// all pointer parameters must not be dangling
4812    pub unsafe fn GetEnvironmentLocalStorage(&self, data: *mut *mut c_void) -> jvmtiError {
4813        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut *mut c_void) -> jvmtiError>(146)(self.vtable, data) }
4814    }
4815
4816    /// Return the symbolic name for an error code.
4817    ///
4818    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetErrorName>
4819    ///
4820    /// # Safety
4821    /// all pointer parameters must not be dangling
4822    pub unsafe fn GetErrorName(&self, error: impl Into<jvmtiError>, name_ptr: *mut *mut c_char) -> jvmtiError {
4823        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jvmtiError, *mut *mut c_char) -> jvmtiError>(127)(self.vtable, error.into(), name_ptr) }
4824    }
4825
4826    /// Control verbose output.
4827    ///
4828    /// This is the output which typically is sent to stderr.
4829    ///
4830    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetVerboseFlag>
4831    ///
4832    /// # Safety
4833    /// jvm implementation specific
4834    pub unsafe fn SetVerboseFlag(&self, flag: jvmtiVerboseFlag, value: jboolean) -> jvmtiError {
4835        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jvmtiVerboseFlag, jboolean) -> jvmtiError>(149)(self.vtable, flag, value) }
4836    }
4837
4838    /// This function describes the representation of jlocation used in this VM.
4839    ///
4840    /// If the returned format is `JVMTI_JLOCATION_JVMBCI`, jlocations can be used as in indices into the array returned by `GetBytecodes`.
4841    ///
4842    /// Although the greatest functionality is achieved with location information referencing the virtual machine bytecode index,
4843    /// the definition of jlocation has intentionally been left unconstrained to allow VM implementations that do not have this information.
4844    ///
4845    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#GetJLocationFormat>
4846    ///
4847    /// # Safety
4848    /// all pointer parameters must not be dangling
4849    pub unsafe fn GetJLocationFormat(&self, format_ptr: *mut jvmtiJlocationFormat) -> jvmtiError {
4850        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, *mut jvmtiJlocationFormat) -> jvmtiError>(128)(self.vtable, format_ptr) }
4851    }
4852
4853    /// Generate a `SampledObjectAlloc` event when objects are allocated.
4854    ///
4855    /// 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.
4856    /// 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.
4857    /// Note that updating the new sampling interval might take various number of allocations to provoke internal data structure updates.
4858    /// Therefore it is important to consider the sampling interval as an average.
4859    /// This includes the interval 0, where events might not be generated straight away for each allocation.
4860    ///
4861    /// See <https://docs.oracle.com/en/java/javase/24/docs/specs/jvmti.html#SetHeapSamplingInterval>
4862    ///
4863    /// # Safety
4864    /// all pointer parameters must not be dangling
4865    pub unsafe fn SetHeapSamplingInterval(&self, sampling_interval: jint) -> jvmtiError {
4866        unsafe { self.jvmti::<extern "system" fn(JVMTIEnvVTable, jint) -> jvmtiError>(155)(self.vtable, sampling_interval) }
4867    }
4868}
4869
4870#[derive(Debug, Copy, Clone)]
4871#[repr(transparent)]
4872pub struct jniNativeInterface(SyncMutPtr<*mut c_void>);
4873
4874impl From<jniNativeInterface> for *mut c_void {
4875    fn from(value: jniNativeInterface) -> Self {
4876        value.0.inner().cast()
4877    }
4878}
4879
4880impl jniNativeInterface {
4881    ///
4882    /// Returns uninitialized jniNativeInterface.
4883    /// The interface must be initialized with a call to `JVMTIEnv::GetJNIFunctionTable`
4884    /// before it can be used in any way.
4885    ///
4886    /// # Undefined behavior of uninitialized `jniNativeInterface`
4887    /// Calling any jvmti fn is ub.
4888    /// Calling any unsafe fn is ub.
4889    #[must_use]
4890    pub const fn new_uninit() -> Self {
4891        Self(SyncMutPtr::null())
4892    }
4893
4894    /// Constructs a new jniNativeInterface from a raw pointer.
4895    ///
4896    /// # Safety
4897    /// Unless the raw pointer was constructed by an invocation on `JVMTIEnv::GetJNIFunctionTable`
4898    /// then the using the resulting `jniNativeInterface` in any way is UB.
4899    #[must_use]
4900    pub const unsafe fn from_raw_ptr(ptr: *mut c_void) -> Self {
4901        unsafe { Self(SyncMutPtr::new(ptr.cast())) }
4902    }
4903
4904    ///
4905    /// Overwrites function in this `jniNativeInterface`
4906    ///
4907    /// # Safety
4908    /// if value is not a function with a matching signature/calling convention
4909    /// then putting the `jniNativeInterface` into use will trigger UB once that linkage is later used.
4910    ///
4911    /// # Example
4912    /// ```rust
4913    /// use jni_simple::*;
4914    ///
4915    /// extern "system" fn hooked_get_version(_env: JNIEnv) -> jint {
4916    ///     println!("JNIEnv GetVersion was called!");
4917    ///     JNI_VERSION_1_8
4918    /// }
4919    ///
4920    /// fn install_hook(env: JVMTIEnv) {
4921    ///     unsafe {
4922    ///         let mut iface = jniNativeInterface::new_uninit();
4923    ///         assert_eq!(env.GetJNIFunctionTable(&mut iface), JVMTI_ERROR_NONE);
4924    ///         iface.set(JNILinkage::GetVersion, hooked_get_version as _);
4925    ///         assert_eq!(env.SetJNIFunctionTable(iface), JVMTI_ERROR_NONE);
4926    ///     }
4927    /// }
4928    /// ```
4929    ///
4930    pub unsafe fn set(&self, linkage: impl AsJNILinkage, value: *mut c_void) {
4931        unsafe {
4932            self.0.add(linkage.linkage()).write_volatile(value);
4933        }
4934    }
4935
4936    ///
4937    /// Returns a function in this `jniNativeInterface`
4938    /// This is usually used to retrieve the unhooked original function from a `jniNativeInterface`
4939    ///
4940    /// # Safety
4941    /// The size of X must be usize (a function pointer).
4942    ///
4943    /// # Example
4944    /// This example illustrates hooking of the `GetVersion` function.
4945    /// The hooked function calls the original function and prints the result to stdout.
4946    /// ```rust
4947    /// use std::ffi::c_void;
4948    /// use std::ops::DerefMut;
4949    /// use std::sync::OnceLock;
4950    /// use jni_simple::*;
4951    ///
4952    /// static ORIGINAL_FUNCTIONS: OnceLock<jniNativeInterface> = OnceLock::new();
4953    ///
4954    /// extern "system" fn hooked_get_version(env: JNIEnv) -> jint {
4955    ///     println!("JNIEnv GetVersion will be called!");
4956    ///     let guard = ORIGINAL_FUNCTIONS.get().unwrap();
4957    ///     let result = unsafe {
4958    ///         guard.get::<extern "system" fn(*mut c_void) -> jint>(JNILinkage::GetVersion)(env.vtable())
4959    ///     };
4960    ///
4961    ///     println!("JNIEnv GetVersion returned {result}!");
4962    ///     result
4963    /// }
4964    ///
4965    /// fn install_hook(env: JVMTIEnv) {
4966    ///     unsafe {
4967    ///         _= ORIGINAL_FUNCTIONS.get_or_init(|| {
4968    ///             let mut iface = jniNativeInterface::new_uninit();
4969    ///             assert_eq!(env.GetJNIFunctionTable(&mut iface), JVMTI_ERROR_NONE);
4970    ///             iface
4971    ///         });
4972    ///
4973    ///         let mut iface = jniNativeInterface::new_uninit();
4974    ///         assert_eq!(env.GetJNIFunctionTable(&mut iface), JVMTI_ERROR_NONE);
4975    ///         iface.set(JNILinkage::GetVersion, hooked_get_version as _);
4976    ///         assert_eq!(env.SetJNIFunctionTable(iface), JVMTI_ERROR_NONE);
4977    ///     }
4978    /// }
4979    /// ```
4980    ///
4981    pub unsafe fn get<X>(&self, linkage: impl AsJNILinkage) -> X {
4982        unsafe { core::mem::transmute_copy(&self.0.add(linkage.linkage()).read_volatile()) }
4983    }
4984}
4985
4986/// Enum of all known jni linkage numbers
4987/// This is mostly useful for use with jvmti when hooking jvm functions.
4988#[derive(Debug, Copy, Clone, Ord, PartialOrd, PartialEq, Eq, Default)]
4989#[repr(usize)]
4990pub enum JNILinkage {
4991    #[default]
4992    GetVersion = 4,
4993
4994    DefineClass = 5,
4995    FindClass = 6,
4996
4997    FromReflectedMethod = 7,
4998    FromReflectedField = 8,
4999    ToReflectedMethod = 9,
5000
5001    GetSuperclass = 10,
5002    IsAssignableFrom = 11,
5003
5004    ToReflectedField = 12,
5005
5006    Throw = 13,
5007    ThrowNew = 14,
5008    ExceptionOccurred = 15,
5009    ExceptionDescribe = 16,
5010    ExceptionClear = 17,
5011    FatalError = 18,
5012
5013    PushLocalFrame = 19,
5014    PopLocalFrame = 20,
5015
5016    NewGlobalRef = 21,
5017    DeleteGlobalRef = 22,
5018    DeleteLocalRef = 23,
5019    IsSameObject = 24,
5020    NewLocalRef = 25,
5021    EnsureLocalCapacity = 26,
5022
5023    AllocObject = 27,
5024    NewObject = 28,
5025    NewObjectV = 29,
5026    NewObjectA = 30,
5027
5028    GetObjectClass = 31,
5029    IsInstanceOf = 32,
5030
5031    GetMethodID = 33,
5032
5033    CallObjectMethod = 34,
5034    CallObjectMethodV = 35,
5035    CallObjectMethodA = 36,
5036    CallBooleanMethod = 37,
5037    CallBooleanMethodV = 38,
5038    CallBooleanMethodA = 39,
5039    CallByteMethod = 40,
5040    CallByteMethodV = 41,
5041    CallByteMethodA = 42,
5042    CallCharMethod = 43,
5043    CallCharMethodV = 44,
5044    CallCharMethodA = 45,
5045    CallShortMethod = 46,
5046    CallShortMethodV = 47,
5047    CallShortMethodA = 48,
5048    CallIntMethod = 49,
5049    CallIntMethodV = 50,
5050    CallIntMethodA = 51,
5051    CallLongMethod = 52,
5052    CallLongMethodV = 53,
5053    CallLongMethodA = 54,
5054    CallFloatMethod = 55,
5055    CallFloatMethodV = 56,
5056    CallFloatMethodA = 57,
5057    CallDoubleMethod = 58,
5058    CallDoubleMethodV = 59,
5059    CallDoubleMethodA = 60,
5060    CallVoidMethod = 61,
5061    CallVoidMethodV = 62,
5062    CallVoidMethodA = 63,
5063
5064    CallNonvirtualObjectMethod = 64,
5065    CallNonvirtualObjectMethodV = 65,
5066    CallNonvirtualObjectMethodA = 66,
5067    CallNonvirtualBooleanMethod = 67,
5068    CallNonvirtualBooleanMethodV = 68,
5069    CallNonvirtualBooleanMethodA = 69,
5070    CallNonvirtualByteMethod = 70,
5071    CallNonvirtualByteMethodV = 71,
5072    CallNonvirtualByteMethodA = 72,
5073    CallNonvirtualCharMethod = 73,
5074    CallNonvirtualCharMethodV = 74,
5075    CallNonvirtualCharMethodA = 75,
5076    CallNonvirtualShortMethod = 76,
5077    CallNonvirtualShortMethodV = 77,
5078    CallNonvirtualShortMethodA = 78,
5079    CallNonvirtualIntMethod = 79,
5080    CallNonvirtualIntMethodV = 80,
5081    CallNonvirtualIntMethodA = 81,
5082    CallNonvirtualLongMethod = 82,
5083    CallNonvirtualLongMethodV = 83,
5084    CallNonvirtualLongMethodA = 84,
5085    CallNonvirtualFloatMethod = 85,
5086    CallNonvirtualFloatMethodV = 86,
5087    CallNonvirtualFloatMethodA = 87,
5088    CallNonvirtualDoubleMethod = 88,
5089    CallNonvirtualDoubleMethodV = 89,
5090    CallNonvirtualDoubleMethodA = 90,
5091    CallNonvirtualVoidMethod = 91,
5092    CallNonvirtualVoidMethodV = 92,
5093    CallNonvirtualVoidMethodA = 93,
5094
5095    GetFieldID = 94,
5096
5097    GetObjectField = 95,
5098    GetBooleanField = 96,
5099    GetByteField = 97,
5100    GetCharField = 98,
5101    GetShortField = 99,
5102    GetIntField = 100,
5103    GetLongField = 101,
5104    GetFloatField = 102,
5105    GetDoubleField = 103,
5106    SetObjectField = 104,
5107    SetBooleanField = 105,
5108    SetByteField = 106,
5109    SetCharField = 107,
5110    SetShortField = 108,
5111    SetIntField = 109,
5112    SetLongField = 110,
5113    SetFloatField = 111,
5114    SetDoubleField = 112,
5115
5116    GetStaticMethodID = 113,
5117
5118    CallStaticObjectMethod = 114,
5119    CallStaticObjectMethodV = 115,
5120    CallStaticObjectMethodA = 116,
5121    CallStaticBooleanMethod = 117,
5122    CallStaticBooleanMethodV = 118,
5123    CallStaticBooleanMethodA = 119,
5124    CallStaticByteMethod = 120,
5125    CallStaticByteMethodV = 121,
5126    CallStaticByteMethodA = 122,
5127    CallStaticCharMethod = 123,
5128    CallStaticCharMethodV = 124,
5129    CallStaticCharMethodA = 125,
5130    CallStaticShortMethod = 126,
5131    CallStaticShortMethodV = 127,
5132    CallStaticShortMethodA = 128,
5133    CallStaticIntMethod = 129,
5134    CallStaticIntMethodV = 130,
5135    CallStaticIntMethodA = 131,
5136    CallStaticLongMethod = 132,
5137    CallStaticLongMethodV = 133,
5138    CallStaticLongMethodA = 134,
5139    CallStaticFloatMethod = 135,
5140    CallStaticFloatMethodV = 136,
5141    CallStaticFloatMethodA = 137,
5142    CallStaticDoubleMethod = 138,
5143    CallStaticDoubleMethodV = 139,
5144    CallStaticDoubleMethodA = 140,
5145    CallStaticVoidMethod = 141,
5146    CallStaticVoidMethodV = 142,
5147    CallStaticVoidMethodA = 143,
5148
5149    GetStaticFieldID = 144,
5150
5151    GetStaticObjectField = 145,
5152    GetStaticBooleanField = 146,
5153    GetStaticByteField = 147,
5154    GetStaticCharField = 148,
5155    GetStaticShortField = 149,
5156    GetStaticIntField = 150,
5157    GetStaticLongField = 151,
5158    GetStaticFloatField = 152,
5159    GetStaticDoubleField = 153,
5160
5161    SetStaticObjectField = 154,
5162    SetStaticBooleanField = 155,
5163    SetStaticByteField = 156,
5164    SetStaticCharField = 157,
5165    SetStaticShortField = 158,
5166    SetStaticIntField = 159,
5167    SetStaticLongField = 160,
5168    SetStaticFloatField = 161,
5169    SetStaticDoubleField = 162,
5170
5171    NewString = 163,
5172
5173    GetStringLength = 164,
5174    GetStringChars = 165,
5175    ReleaseStringChars = 166,
5176
5177    NewStringUTF = 167,
5178    GetStringUTFLength = 168,
5179    GetStringUTFChars = 169,
5180    ReleaseStringUTFChars = 170,
5181
5182    GetArrayLength = 171,
5183
5184    NewObjectArray = 172,
5185    GetObjectArrayElement = 173,
5186    SetObjectArrayElement = 174,
5187
5188    NewBooleanArray = 175,
5189    NewByteArray = 176,
5190    NewCharArray = 177,
5191    NewShortArray = 178,
5192    NewIntArray = 179,
5193    NewLongArray = 180,
5194    NewFloatArray = 181,
5195    NewDoubleArray = 182,
5196
5197    GetBooleanArrayElements = 183,
5198    GetByteArrayElements = 184,
5199    GetCharArrayElements = 185,
5200    GetShortArrayElements = 186,
5201    GetIntArrayElements = 187,
5202    GetLongArrayElements = 188,
5203    GetFloatArrayElements = 189,
5204    GetDoubleArrayElements = 190,
5205
5206    ReleaseBooleanArrayElements = 191,
5207    ReleaseByteArrayElements = 192,
5208    ReleaseCharArrayElements = 193,
5209    ReleaseShortArrayElements = 194,
5210    ReleaseIntArrayElements = 195,
5211    ReleaseLongArrayElements = 196,
5212    ReleaseFloatArrayElements = 197,
5213    ReleaseDoubleArrayElements = 198,
5214
5215    GetBooleanArrayRegion = 199,
5216    GetByteArrayRegion = 200,
5217    GetCharArrayRegion = 201,
5218    GetShortArrayRegion = 202,
5219    GetIntArrayRegion = 203,
5220    GetLongArrayRegion = 204,
5221    GetFloatArrayRegion = 205,
5222    GetDoubleArrayRegion = 206,
5223    SetBooleanArrayRegion = 207,
5224    SetByteArrayRegion = 208,
5225    SetCharArrayRegion = 209,
5226    SetShortArrayRegion = 210,
5227    SetIntArrayRegion = 211,
5228    SetLongArrayRegion = 212,
5229    SetFloatArrayRegion = 213,
5230    SetDoubleArrayRegion = 214,
5231
5232    RegisterNatives = 215,
5233    UnregisterNatives = 216,
5234
5235    MonitorEnter = 217,
5236    MonitorExit = 218,
5237
5238    GetJavaVM = 219,
5239
5240    GetStringRegion = 220,
5241    GetStringUTFRegion = 221,
5242
5243    GetPrimitiveArrayCritical = 222,
5244    ReleasePrimitiveArrayCritical = 223,
5245
5246    GetStringCritical = 224,
5247    ReleaseStringCritical = 225,
5248
5249    NewWeakGlobalRef = 226,
5250    DeleteWeakGlobalRef = 227,
5251
5252    ExceptionCheck = 228,
5253
5254    NewDirectByteBuffer = 229,
5255    GetDirectBufferAddress = 230,
5256    GetDirectBufferCapacity = 231,
5257
5258    GetObjectRefType = 232,
5259
5260    GetModule = 233,
5261
5262    IsVirtualThread = 234,
5263
5264    GetStringUTFLengthAsLong = 235,
5265}
5266
5267impl From<JNILinkage> for usize {
5268    fn from(value: JNILinkage) -> Self {
5269        value as Self
5270    }
5271}
5272
5273pub trait AsJNILinkage: SealedAsJNILinkage {}
5274
5275impl SealedAsJNILinkage for JNILinkage {
5276    fn linkage(self) -> usize {
5277        self as usize
5278    }
5279}
5280
5281impl AsJNILinkage for JNILinkage {}
5282
5283impl SealedAsJNILinkage for usize {
5284    fn linkage(self) -> usize {
5285        self
5286    }
5287}
5288
5289impl AsJNILinkage for usize {}
5290
5291impl SealedAsJNILinkage for i32 {
5292    fn linkage(self) -> usize {
5293        // Negative linkages dont exist, if someone passes a negative linkage
5294        // then its ub anyways and all bets are off.
5295        usize::try_from(self).unwrap_or_default()
5296    }
5297}
5298
5299/// The compiler unless you specify a suffix will assume i32.
5300/// This just makes it a bit easier to not have to write 6usize.
5301impl AsJNILinkage for i32 {}
5302
5303/// Vtable of `JNIEnv` is passed like this.
5304type JNIEnvVTable = *mut jniNativeInterface;
5305
5306#[derive(Debug, Clone, Copy)]
5307#[repr(transparent)]
5308pub struct JNIEnv {
5309    /// The vtable that contains all the functions
5310    vtable: JNIEnvVTable,
5311}
5312
5313impl SealedEnvVTable for JNIEnv {
5314    fn can_jni() -> bool {
5315        true
5316    }
5317
5318    fn can_jvmti() -> bool {
5319        false
5320    }
5321}
5322
5323impl From<*mut c_void> for JNIEnv {
5324    fn from(value: *mut c_void) -> Self {
5325        Self { vtable: value.cast() }
5326    }
5327}
5328
5329impl JNINativeMethod {
5330    #[must_use]
5331    pub const fn new(name: *const c_char, signature: *const c_char, function_pointer: *const c_void) -> Self {
5332        Self {
5333            name,
5334            signature,
5335            fnPtr: function_pointer,
5336        }
5337    }
5338
5339    #[must_use]
5340    pub const fn name(&self) -> *const c_char {
5341        self.name
5342    }
5343
5344    #[must_use]
5345    pub const fn signature(&self) -> *const c_char {
5346        self.signature
5347    }
5348
5349    #[must_use]
5350    pub const fn fnPtr(&self) -> *const c_void {
5351        self.fnPtr
5352    }
5353}
5354
5355impl JavaVMAttachArgs {
5356    pub const fn new(version: jint, name: *const c_char, group: jobject) -> Self {
5357        Self { version, name, group }
5358    }
5359
5360    #[must_use]
5361    pub const fn version(&self) -> jint {
5362        self.version
5363    }
5364    #[must_use]
5365    pub const fn name(&self) -> *const c_char {
5366        self.name
5367    }
5368    #[must_use]
5369    pub const fn group(&self) -> jobject {
5370        self.group
5371    }
5372}
5373
5374/// Helper trait that converts rusts various strings into a zero terminated c string for use with a JNI method.
5375///
5376/// This trait is implemented for:
5377/// &str, String, &String,
5378/// `CString`, `CStr`, *const `c_char`,
5379/// &`OsStr`, `OsString`, &`OsString`,
5380/// &[u8], Vec<u8>,
5381///
5382/// If the String contains the equivalent of a 0 byte then the string stops at the 0 byte ignoring the rest of the string.
5383/// Any non Unicode characters in `OsString` and its derivatives will be replaced with the Unicode replacement character by using to `to_str_lossy` fn.
5384/// 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`!
5385/// - Doing this on with any call to JNI will result in undefined behavior.
5386///
5387pub trait UseCString: private::SealedUseCString {}
5388
5389impl UseCString for &str {}
5390
5391impl private::SealedUseCString for &str {
5392    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
5393        self.as_bytes().use_as_const_c_char(func)
5394    }
5395}
5396
5397impl UseCString for String {}
5398
5399impl private::SealedUseCString for String {
5400    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
5401        self.into_bytes().use_as_const_c_char(func)
5402    }
5403}
5404
5405impl UseCString for &String {}
5406
5407impl private::SealedUseCString for &String {
5408    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
5409        self.as_bytes().use_as_const_c_char(func)
5410    }
5411}
5412
5413impl UseCString for CString {}
5414
5415impl private::SealedUseCString for CString {
5416    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
5417        func(self.as_ptr())
5418    }
5419}
5420
5421impl UseCString for &CString {}
5422
5423impl private::SealedUseCString for &CString {
5424    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
5425        func(self.as_ptr())
5426    }
5427}
5428
5429impl UseCString for &CStr {}
5430
5431impl private::SealedUseCString for &CStr {
5432    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
5433        func(self.as_ptr())
5434    }
5435}
5436
5437impl UseCString for *const i8 {}
5438
5439impl private::SealedUseCString for *const i8 {
5440    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
5441        #[cfg(feature = "asserts")]
5442        {
5443            if self.is_null() {
5444                return func(self.cast());
5445            }
5446
5447            //If we are called on a non 0 terminated pointer then all bets are off anyway.
5448            let mut size = 0usize;
5449            loop {
5450                unsafe {
5451                    if self.add(size).read_volatile() == 0 {
5452                        break;
5453                    }
5454                    size += 1;
5455                }
5456            }
5457
5458            unsafe {
5459                let to_check: &[u8] = std::slice::from_raw_parts(self.cast(), size);
5460                assert!(
5461                    std::str::from_utf8(to_check).is_ok(),
5462                    "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:?}"
5463                );
5464            }
5465        }
5466
5467        func(self.cast())
5468    }
5469}
5470
5471impl UseCString for *const u8 {}
5472
5473impl private::SealedUseCString for *const u8 {
5474    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
5475        #[cfg(feature = "asserts")]
5476        {
5477            if self.is_null() {
5478                return func(self.cast());
5479            }
5480
5481            //If we are called on a non 0 terminated pointer then all bets are off anyway.
5482            let mut size = 0usize;
5483            loop {
5484                unsafe {
5485                    if self.add(size).read_volatile() == 0 {
5486                        break;
5487                    }
5488                    size += 1;
5489                }
5490            }
5491
5492            unsafe {
5493                let to_check = std::slice::from_raw_parts(self, size);
5494                assert!(
5495                    std::str::from_utf8(to_check).is_ok(),
5496                    "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:?}"
5497                );
5498            }
5499        }
5500
5501        func(self.cast())
5502    }
5503}
5504
5505impl UseCString for *mut i8 {}
5506
5507impl private::SealedUseCString for *mut i8 {
5508    fn use_as_const_c_char<X>(self, param: impl FnOnce(*const c_char) -> X) -> X {
5509        self.cast_const().use_as_const_c_char(param)
5510    }
5511}
5512
5513impl UseCString for *mut u8 {}
5514
5515impl private::SealedUseCString for *mut u8 {
5516    fn use_as_const_c_char<X>(self, param: impl FnOnce(*const c_char) -> X) -> X {
5517        self.cast_const().use_as_const_c_char(param)
5518    }
5519}
5520
5521impl UseCString for Cow<'_, str> {}
5522
5523impl private::SealedUseCString for Cow<'_, str> {
5524    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
5525        self.as_ref().use_as_const_c_char(func)
5526    }
5527}
5528
5529impl UseCString for &Cow<'_, str> {}
5530
5531impl private::SealedUseCString for &Cow<'_, str> {
5532    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
5533        self.as_ref().use_as_const_c_char(func)
5534    }
5535}
5536
5537#[cfg(feature = "std")]
5538impl UseCString for std::ffi::OsString {}
5539
5540#[cfg(feature = "std")]
5541impl private::SealedUseCString for std::ffi::OsString {
5542    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
5543        self.to_string_lossy().use_as_const_c_char(func)
5544    }
5545}
5546
5547#[cfg(feature = "std")]
5548impl UseCString for &std::ffi::OsString {}
5549
5550#[cfg(feature = "std")]
5551impl private::SealedUseCString for &std::ffi::OsString {
5552    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
5553        self.to_string_lossy().use_as_const_c_char(func)
5554    }
5555}
5556
5557#[cfg(feature = "std")]
5558impl UseCString for &std::ffi::OsStr {}
5559
5560#[cfg(feature = "std")]
5561impl private::SealedUseCString for &std::ffi::OsStr {
5562    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
5563        self.to_string_lossy().use_as_const_c_char(func)
5564    }
5565}
5566
5567impl UseCString for Vec<u8> {}
5568
5569impl private::SealedUseCString for Vec<u8> {
5570    fn use_as_const_c_char<X>(mut self, func: impl FnOnce(*const c_char) -> X) -> X {
5571        #[cfg(feature = "asserts")]
5572        {
5573            //Check for valid UTF-8
5574            let len = self.iter().position(|r| *r == 0).unwrap_or(self.len());
5575            let to_check = &self[..len];
5576            assert!(
5577                std::str::from_utf8(to_check).is_ok(),
5578                "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:?}"
5579            );
5580        }
5581
5582        let Some(last) = self.last().copied() else {
5583            return func([0i8].as_ptr().cast()); //Edge case empty string.
5584        };
5585
5586        if last == 0 {
5587            return func(self.as_ptr().cast());
5588        }
5589
5590        if self.capacity() > self.len() {
5591            //We own the Vec, faster to push 0 in this case, no need to copy or check for intermittent bytes.
5592            self.push(0);
5593            return func(self.as_ptr().cast());
5594        }
5595
5596        for n in &self {
5597            if *n == 0 {
5598                return func(self.as_ptr().cast());
5599            }
5600        }
5601
5602        self.reserve_exact(1); //We know the Vec will be dropped at the end of the scope.
5603        self.push(0); //Oh well guess we will have to copy the Vec...
5604        func(self.as_ptr().cast())
5605    }
5606}
5607
5608impl UseCString for &Vec<u8> {}
5609
5610impl private::SealedUseCString for &Vec<u8> {
5611    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
5612        self.as_slice().use_as_const_c_char(func)
5613    }
5614}
5615
5616impl UseCString for &[u8] {}
5617
5618impl private::SealedUseCString for &[u8] {
5619    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
5620        #[cfg(feature = "asserts")]
5621        {
5622            //Check for valid UTF-8
5623            let len = self.iter().position(|r| *r == 0).unwrap_or(self.len());
5624            let to_check = &self[..len];
5625            assert!(
5626                std::str::from_utf8(to_check).is_ok(),
5627                "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:?}",
5628            );
5629        }
5630
5631        let Some(last) = self.last().copied() else {
5632            return func([0i8].as_ptr().cast()); //Edge case empty string/slice.
5633        };
5634
5635        // Fast case, last byte in slice is 0
5636        if last == 0 {
5637            //We get here if the caller appends \0 to their rust string literals.
5638            return func(self.as_ptr().cast());
5639        }
5640
5641        // Impl detail: CStr::from_bytes_until_nul
5642        // will iterate the string from beginning to end to look for 0 byte,
5643        // so checking if last byte is 0 byte makes sense, especially for longer strings.
5644        // We do not care if there is a second 0 byte already somewhere in the middle of the string.
5645        if let Ok(c_str) = CStr::from_bytes_until_nul(self) {
5646            return func(c_str.as_ptr());
5647        }
5648
5649        // There no 0 byte in the slice. We have to copy the slice, append a 0 byte and then call downstream.
5650        // This is the slowest path. Unfortunately all ordinary ""
5651        // rust strings get here unless the caller explicitly made sure to add \0 to the end.
5652        let mut vec = self.to_vec();
5653        vec.reserve_exact(1);
5654        vec.push(0);
5655        func(vec.as_ptr().cast())
5656    }
5657}
5658
5659impl UseCString for () {}
5660
5661impl private::SealedUseCString for () {
5662    fn use_as_const_c_char<X>(self, func: impl FnOnce(*const c_char) -> X) -> X {
5663        func(null())
5664    }
5665}
5666
5667impl JNIEnv {
5668    ///
5669    /// Resolves the function pointer given its linkage index of the jni vtable.
5670    /// The indices are documented and guaranteed by the Oracle JVM Spec.
5671    ///
5672    #[inline(always)]
5673    unsafe fn jni<X>(&self, index: usize) -> X {
5674        unsafe {
5675            //We need the read_volatile because a java debugger may at any point in time exchange the jni function table at its convenience.
5676            core::mem::transmute_copy(&(self.vtable.read_volatile().0.add(index).read_volatile()))
5677        }
5678    }
5679
5680    ///
5681    /// Raw indexes the JNI vtable.
5682    /// This can be used to call future JNI methods that jni-simple in the used version is not aware of.
5683    /// It can also be used to call undocumented implementation specific jni functions,
5684    /// or functions defined in a native java debugger.
5685    ///
5686    /// 99% of programs do not need to use this function.
5687    /// Use this function as a last resort.
5688    ///
5689    /// # Generic Type X
5690    /// Almost always a "extern system" function signature.
5691    /// The first parameter is nearly universally a pointer to the raw vtable.
5692    ///
5693    /// # Safety
5694    /// This function is very unsafe. If index is too large, you cause UB due to out of bounds read.
5695    /// The actual size of the vtable cannot be known and is JVM implementation specific.
5696    ///
5697    /// If the generic type X is wrong for the given index then you either cause UB instantly depending
5698    /// on if your supplied X has the same size as `c_void` or not,
5699    /// or once you use the result.
5700    ///
5701    /// # Example
5702    /// This shows how to call the JNI Function `GetVersion` using the raw vtable call.
5703    /// ```rust
5704    /// use std::ffi::c_void;
5705    /// use jni_simple::*;
5706    ///
5707    /// fn some_func(env: JNIEnv) {
5708    ///     unsafe {
5709    ///         // The linkage index for GetVersion is 4. See oracle documentation for a list of linkage indexes as well as their signature.
5710    ///         // The calling convention is the "system" calling convention by default.
5711    ///         // This is the same as "C" on linux but on Windows 32 bit its different. See jni.h and rusts calling convention documentation.
5712    ///         let version: jint = env.index_vtable::<extern "system" fn(*mut c_void) -> jint>(4)(env.vtable());
5713    ///     }
5714    /// }
5715    ///
5716    /// ```
5717    ///
5718    pub unsafe fn index_vtable<X>(&self, index: impl AsJNILinkage) -> X {
5719        unsafe { self.jni::<X>(index.linkage()) }
5720    }
5721
5722    /// Returns the raw jni vtable.
5723    /// This is usefully in some rare situations, especially when used with the `index_vtable` function.
5724    #[must_use]
5725    pub const fn vtable(&self) -> *mut c_void {
5726        self.vtable.cast()
5727    }
5728
5729    ///
5730    /// Returns the version of the JNI interface.
5731    ///
5732    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetVersion>
5733    ///
5734    /// The returned value must be compared against a constant. (They start with `JNI_VERSION`_...)
5735    /// Not every java version has such a constant.
5736    /// Only java versions where a function in the JNI interface was added has one.
5737    ///
5738    ///
5739    /// # Panics
5740    /// if asserts feature is enabled and UB was detected
5741    ///
5742    /// # Safety
5743    ///
5744    /// Current thread must not be detached from JNI.
5745    ///
5746    /// Current thread does not hold a critical reference.
5747    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
5748    ///
5749    /// Current thread is not currently throwing a Java exception.
5750    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
5751    ///
5752    ///
5753    /// # Example
5754    /// ```rust
5755    /// use jni_simple::{*};
5756    ///
5757    /// unsafe fn is_at_least_java10(env: JNIEnv) -> bool {
5758    ///     env.GetVersion() >= JNI_VERSION_10
5759    /// }
5760    /// ```
5761    ///
5762    #[must_use]
5763    pub unsafe fn GetVersion(&self) -> jint {
5764        unsafe {
5765            #[cfg(feature = "asserts")]
5766            {
5767                self.check_not_critical("GetVersion");
5768                self.check_no_exception("GetVersion");
5769            }
5770            self.jni::<extern "system" fn(JNIEnvVTable) -> jint>(4)(self.vtable)
5771        }
5772    }
5773
5774    ///
5775    /// Defines a class in the given classloader.
5776    ///
5777    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#DefineClass>
5778    ///
5779    /// # Arguments
5780    /// * `name` - name of the class
5781    /// * `classloader` - handle to the classloader java object. This can be null if the current JNI classloader should be used.
5782    /// * `data` - the binary content of the compiled java .class file.
5783    /// * `len` - the length of the data in bytes.
5784    ///
5785    /// # Returns
5786    /// A local ref handle to the java.lang.Class (jclass) object that was just defined.
5787    /// On error null is returned.
5788    ///
5789    /// # Throws Java Exception:
5790    /// * `ClassFormatError` - if the class data does not specify a valid class.
5791    /// * `ClassCircularityError` - if a class or interface would be its own superclass or superinterface.
5792    /// * `OutOfMemoryError` - if the system runs out of memory.
5793    /// * `SecurityException` - if the caller attempts to define a class in the "java" package tree.
5794    ///
5795    ///
5796    /// # Panics
5797    /// if asserts feature is enabled and UB was detected
5798    ///
5799    /// # Safety
5800    ///
5801    /// Current thread must not be detached from JNI.
5802    ///
5803    /// Current thread does not hold a critical reference.
5804    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
5805    ///
5806    /// Current thread is not currently throwing a Java exception.
5807    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
5808    ///
5809    /// The `classloader` handle must be a valid handle if it is not null.
5810    /// `name` must be a valid pointer to a 0 terminated utf-8 string. It must not be null.
5811    /// `data` must not be null.
5812    /// `len` must not be larger than the actual length of the data.
5813    /// `len` must not be negative.
5814    ///
5815    /// # Example
5816    /// ```rust
5817    /// use std::ffi::CString;
5818    /// use core::ptr::null_mut;
5819    /// use jni_simple::{*};
5820    ///
5821    /// unsafe fn define_main_class(env: JNIEnv) -> jclass {
5822    ///     let class_blob = &[0u8]; // = include_bytes!("../my_java_project/src/main/java/org/example/Main.class");
5823    ///     let name = CString::new("org/example/Main").unwrap();
5824    ///     let class = env.DefineClass(name.as_ptr(), null_mut(), class_blob.as_ptr().cast(), class_blob.len() as i32);
5825    ///     if env.ExceptionCheck() {
5826    ///         env.ExceptionDescribe();
5827    ///         panic!("Failed to load main class check stderr for an error");
5828    ///     }
5829    ///     if class.is_null() {
5830    ///         panic!("Failed to load main class. JVM did not throw an exception!"); //Unlikely
5831    ///     }
5832    ///     class
5833    /// }
5834    /// ```
5835    ///
5836    pub unsafe fn DefineClass(&self, name: impl UseCString, classloader: jobject, data: *const jbyte, len: jsize) -> jclass {
5837        unsafe {
5838            name.use_as_const_c_char(|name| {
5839                #[cfg(feature = "asserts")]
5840                {
5841                    self.check_not_critical("DefineClass");
5842                    self.check_no_exception("DefineClass");
5843                    assert!(!name.is_null(), "DefineClass name is null");
5844                    self.check_is_classloader_or_null("DefineClass", classloader);
5845                    assert!(!data.is_null(), "DefineClass data is null");
5846                    assert!(len >= 0, "DefineClass len is negative {len}");
5847                }
5848
5849                self.jni::<extern "system" fn(JNIEnvVTable, *const c_char, jobject, *const jbyte, i32) -> jclass>(5)(self.vtable, name, classloader, data, len)
5850            })
5851        }
5852    }
5853
5854    ///
5855    /// Defines a class in the given classloader.
5856    ///
5857    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#DefineClass>
5858    ///
5859    /// # Arguments
5860    /// * `name` - name of the class
5861    /// * `classloader` - handle to the classloader java object. This can be null if the current JNI classloader should be used.
5862    /// * `data` - the binary content of the compiled java .class file.
5863    ///
5864    /// # Returns
5865    /// A local ref handle to the java.lang.Class (jclass) object that was just defined.
5866    /// On error null is returned.
5867    ///
5868    /// # Throws Java Exception:
5869    /// * `ClassFormatError` - if the class data does not specify a valid class.
5870    /// * `ClassCircularityError` - if a class or interface would be its own superclass or superinterface.
5871    /// * `OutOfMemoryError` - if the system runs out of memory.
5872    /// * `SecurityException` - if the caller attempts to define a class in the "java" package tree.
5873    ///
5874    ///
5875    /// # Panics
5876    /// if asserts feature is enabled and UB was detected
5877    ///
5878    /// # Safety
5879    ///
5880    /// Current thread must not be detached from JNI.
5881    ///
5882    /// Current thread does not hold a critical reference.
5883    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
5884    ///
5885    /// Current thread is not currently throwing a Java exception.
5886    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
5887    ///
5888    /// The `classloader` handle must be a valid handle if it is not null.
5889    /// `name` must be a valid pointer to a 0 terminated utf-8 string. It must not be null.
5890    ///
5891    /// # Example
5892    /// ```rust
5893    /// use std::ffi::CString;
5894    /// use core::ptr::null_mut;
5895    /// use jni_simple::{*};
5896    ///
5897    /// unsafe fn define_main_class(env: JNIEnv) -> jclass {
5898    ///     let class_blob = &[0u8]; // = include_bytes!("../my_java_project/src/main/java/org/example/Main.class");
5899    ///     let name = CString::new("org/example/Main").unwrap();
5900    ///     let class = env.DefineClass_from_slice(name.as_ptr(), null_mut(), class_blob);
5901    ///     if env.ExceptionCheck() {
5902    ///         env.ExceptionDescribe();
5903    ///         panic!("Failed to load main class check stderr for an error");
5904    ///     }
5905    ///     if class.is_null() {
5906    ///         panic!("Failed to load main class. JVM did not throw an exception!"); //Unlikely
5907    ///     }
5908    ///     class
5909    /// }
5910    /// ```
5911    ///
5912    pub unsafe fn DefineClass_from_slice(&self, name: impl UseCString, classloader: jobject, data: impl AsRef<[u8]>) -> jclass {
5913        unsafe {
5914            let slice = data.as_ref();
5915            self.DefineClass(
5916                name,
5917                classloader,
5918                slice.as_ptr().cast::<jbyte>(),
5919                jsize::try_from(slice.len()).expect("data.len() > jsize::MAX"),
5920            )
5921        }
5922    }
5923
5924    ///
5925    /// Finds or loads a class.
5926    /// If the class was previously loaded by the current JNI Classloader then it is returned.
5927    /// If the class was not previously loaded then the current JNI Classloader will attempt to
5928    /// load it.
5929    ///
5930    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#FindClass>
5931    ///
5932    /// # Arguments
5933    /// * `name` - name of the class in jni notation (i.e: "java/lang/Object")
5934    ///
5935    /// # Returns
5936    /// A local ref handle to the java.lang.Class (jclass) object.
5937    /// On error null is returned.
5938    ///
5939    /// # Throws Java Exception:
5940    /// * `ClassFormatError` - if the class data does not specify a valid class.
5941    /// * `ClassCircularityError` - if a class or interface would be its own superclass or superinterface.
5942    /// * `OutOfMemoryError` - if the system runs out of memory.
5943    /// * `NoClassDefFoundError` -  if no definition for a requested class or interface can be found.
5944    ///
5945    ///
5946    /// # Panics
5947    /// if asserts feature is enabled and UB was detected
5948    ///
5949    /// # Safety
5950    ///
5951    /// Current thread must not be detached from JNI.
5952    ///
5953    /// Current thread does not hold a critical reference.
5954    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
5955    ///
5956    /// Current thread is not currently throwing a Java exception.
5957    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
5958    ///
5959    /// `name` must be a valid pointer to a 0 terminated utf-8 string. It must not be null.
5960    ///
5961    /// # Example
5962    /// ```rust
5963    /// use std::ffi::CString;
5964    /// use jni_simple::{*};
5965    ///
5966    /// unsafe fn find_main_class(env: JNIEnv) -> jclass {
5967    ///     let name = CString::new("org/example/Main").unwrap();
5968    ///     let class = env.FindClass(name.as_ptr());
5969    ///     if env.ExceptionCheck() {
5970    ///         env.ExceptionDescribe();
5971    ///         panic!("Failed to find main class check stderr for an error");
5972    ///     }
5973    ///     if class.is_null() {
5974    ///         panic!("Failed to find main class. JVM did not throw an exception!"); //Unlikely
5975    ///     }
5976    ///     class
5977    /// }
5978    /// ```
5979    ///
5980    pub unsafe fn FindClass(&self, name: impl UseCString) -> jclass {
5981        unsafe {
5982            name.use_as_const_c_char(|name| {
5983                #[cfg(feature = "asserts")]
5984                {
5985                    self.check_not_critical("FindClass");
5986                    self.check_no_exception("FindClass");
5987                    assert!(!name.is_null(), "FindClass name is null");
5988                }
5989                self.jni::<extern "system" fn(JNIEnvVTable, *const c_char) -> jclass>(6)(self.vtable, name)
5990            })
5991        }
5992    }
5993
5994    ///
5995    /// Gets the superclass of the class `class`.
5996    ///
5997    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetSuperclass>
5998    ///
5999    /// # Arguments
6000    /// * `class` - handle to a class object. must not be null.
6001    ///
6002    /// # Returns
6003    /// A local ref handle to the superclass or null.
6004    /// If `class` refers to java.lang.Object class then null is returned.
6005    /// If `class` refers to any Interface then null is returned.
6006    ///
6007    ///
6008    ///
6009    /// # Panics
6010    /// if asserts feature is enabled and UB was detected
6011    ///
6012    /// # Safety
6013    ///
6014    /// Current thread must not be detached from JNI.
6015    ///
6016    /// Current thread does not hold a critical reference.
6017    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6018    ///
6019    /// Current thread is not currently throwing a Java exception.
6020    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
6021    ///
6022    /// `class` must be a valid non-null handle to a class object.
6023    ///
6024    /// # Example
6025    /// ```rust
6026    /// use jni_simple::{*};
6027    ///
6028    /// unsafe fn has_parent(env: JNIEnv, class: jclass) -> bool {
6029    ///     if class.is_null() {
6030    ///         return false;
6031    ///     }
6032    ///     let local = env.NewLocalRef(class);
6033    ///     let parent_or_null = env.GetSuperclass(local);
6034    ///     env.DeleteLocalRef(local);
6035    ///     if parent_or_null.is_null() {
6036    ///         return false;
6037    ///     }
6038    ///     env.DeleteLocalRef(parent_or_null);
6039    ///     true
6040    /// }
6041    /// ```
6042    ///
6043    pub unsafe fn GetSuperclass(&self, class: jclass) -> jclass {
6044        unsafe {
6045            #[cfg(feature = "asserts")]
6046            {
6047                self.check_not_critical("GetSuperclass");
6048                self.check_no_exception("GetSuperclass");
6049                self.check_is_class("GetSuperclass", class);
6050            }
6051            self.jni::<extern "system" fn(JNIEnvVTable, jclass) -> jclass>(10)(self.vtable, class)
6052        }
6053    }
6054
6055    ///
6056    /// Determines whether an object of clazz1 can be safely cast to clazz2.
6057    ///
6058    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#IsAssignableFrom>
6059    ///
6060    /// # Arguments
6061    /// * `class1` - handle to a class object. must not be null.
6062    /// * `class2` - handle to a class object. must not be null.
6063    ///
6064    /// # Returns
6065    /// true if either:
6066    /// * class1 and class2 refer to the same class.
6067    /// * class1 is a subclass of class2.
6068    /// * class1 has class2 as one of its interfaces.
6069    ///
6070    ///
6071    /// # Panics
6072    /// if asserts feature is enabled and UB was detected
6073    ///
6074    /// # Safety
6075    ///
6076    /// Current thread must not be detached from JNI.
6077    ///
6078    /// Current thread does not hold a critical reference.
6079    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6080    ///
6081    /// Current thread is not currently throwing a Java exception.
6082    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
6083    ///
6084    /// `class1` and `class2` must be valid non-null handles to class objects.
6085    ///
6086    /// # Example
6087    /// ```rust
6088    /// use jni_simple::{*};
6089    ///
6090    /// unsafe fn is_throwable_class(env: JNIEnv, class: jclass) -> bool {
6091    ///     let throwable_class = env.FindClass("java/lang/Throwable");
6092    ///     if throwable_class.is_null() {
6093    ///         env.ExceptionDescribe();
6094    ///         panic!("java/lang/Throwable not found! See stderr!");
6095    ///     }
6096    ///     let local = env.NewLocalRef(class);
6097    ///     if local.is_null() {
6098    ///         env.DeleteLocalRef(throwable_class);
6099    ///         return false;
6100    ///     }
6101    ///     let result = env.IsAssignableFrom(local, throwable_class);
6102    ///     env.DeleteLocalRef(local);
6103    ///     env.DeleteLocalRef(throwable_class);
6104    ///     result
6105    /// }
6106    /// ```
6107    ///
6108    pub unsafe fn IsAssignableFrom(&self, class1: jclass, class2: jclass) -> jboolean {
6109        unsafe {
6110            #[cfg(feature = "asserts")]
6111            {
6112                self.check_not_critical("IsAssignableFrom");
6113                self.check_no_exception("IsAssignableFrom");
6114                self.check_is_class("IsAssignableFrom", class1);
6115                self.check_is_class("IsAssignableFrom", class2);
6116            }
6117            self.jni::<extern "system" fn(JNIEnvVTable, jclass, jclass) -> jboolean>(11)(self.vtable, class1, class2)
6118        }
6119    }
6120
6121    ///
6122    /// Throws a java.lang.Throwable. This is roughly equal to the throw keyword in Java.
6123    ///
6124    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Throw>
6125    ///
6126    /// # Arguments
6127    /// * `throwable` - handle to an object which is instanceof java.lang.Throwable. must not be null.
6128    ///
6129    /// # Returns
6130    /// `JNI_OK` on success. a negative value on failure.
6131    ///
6132    /// ## If `JNI_OK` was returned
6133    /// The JVM will be throwing an exception as a result of this call.
6134    ///
6135    /// When the current thread is throwing an exception you may only call the following JNI functions:
6136    /// * `ExceptionOccurred`
6137    /// * `ExceptionDescribe`
6138    /// * `ExceptionClear`
6139    /// * `ExceptionCheck`
6140    /// * `ReleaseStringChars`
6141    /// * `ReleaseStringUTFChars`
6142    /// * `ReleaseStringCritical`
6143    /// * Release<Type>`ArrayElements`
6144    /// * `ReleasePrimitiveArrayCritical`
6145    /// * `DeleteLocalRef`
6146    /// * `DeleteGlobalRef`
6147    /// * `DeleteWeakGlobalRef`
6148    /// * `MonitorExit`
6149    /// * `PushLocalFrame`
6150    /// * `PopLocalFrame`
6151    ///
6152    /// Calling any other JNI function is UB.
6153    ///
6154    ///
6155    ///
6156    /// # Panics
6157    /// if asserts feature is enabled and UB was detected
6158    ///
6159    /// # Safety
6160    ///
6161    /// Current thread must not be detached from JNI.
6162    ///
6163    /// Current thread does not hold a critical reference.
6164    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6165    ///
6166    /// Current thread is not currently throwing a Java exception.
6167    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
6168    ///
6169    /// `throwable` must be a valid non-null handle to an object which is instanceof java.lang.Throwable.
6170    ///
6171    /// # Example
6172    /// ```rust
6173    /// use jni_simple::{*};
6174    ///
6175    /// unsafe fn throw_null_pointer_exception(env: JNIEnv) {
6176    ///     let npe_class = env.FindClass("java/lang/NullPointerException");
6177    ///     if npe_class.is_null() {
6178    ///         env.ExceptionDescribe();
6179    ///         panic!("java/lang/NullPointerException not found!");
6180    ///     }
6181    ///     let npe_constructor = env.GetMethodID(npe_class, "<init>", "()V");
6182    ///     if npe_constructor.is_null() {
6183    ///         env.ExceptionDescribe();
6184    ///         env.DeleteLocalRef(npe_class);
6185    ///         panic!("java/lang/NullPointerException has no zero arg constructor!");
6186    ///     }
6187    ///
6188    ///     let npe_obj = env.NewObject0(npe_class, npe_constructor);
6189    ///     env.DeleteLocalRef(npe_class);
6190    ///     if npe_obj.is_null() {
6191    ///         env.ExceptionDescribe();
6192    ///         panic!("java/lang/NullPointerException failed to call zero arg constructor!");
6193    ///     }
6194    ///     env.Throw(npe_obj);
6195    ///     env.DeleteLocalRef(npe_obj);
6196    /// }
6197    /// ```
6198    ///
6199    pub unsafe fn Throw(&self, throwable: jthrowable) -> jint {
6200        unsafe {
6201            #[cfg(feature = "asserts")]
6202            {
6203                self.check_not_critical("Throw");
6204                self.check_no_exception("Throw");
6205                assert!(!throwable.is_null(), "Throw throwable is null");
6206            }
6207            self.jni::<extern "system" fn(JNIEnvVTable, jthrowable) -> jint>(13)(self.vtable, throwable)
6208        }
6209    }
6210
6211    ///
6212    /// Throws a new instance `class`. This is roughly equal to `throw new ...` in Java.
6213    ///
6214    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ThrowNew>
6215    ///
6216    /// # Arguments
6217    /// * `class` - handle to a non-abstract class instances of which can be cast to java.lang.Throwable. Must not be null.
6218    /// * `message` - the exception message. Must be null or a pointer to a 0 terminated utf-8 string.
6219    ///
6220    /// # Returns
6221    /// `JNI_OK` on success. a negative value on failure.
6222    ///
6223    /// ## If `JNI_OK` was returned
6224    /// The JVM will be throwing an exception as a result of this call.
6225    ///
6226    /// When the current thread is throwing an exception you may only call the following JNI functions:
6227    /// * `ExceptionOccurred`
6228    /// * `ExceptionDescribe`
6229    /// * `ExceptionClear`
6230    /// * `ExceptionCheck`
6231    /// * `ReleaseStringChars`
6232    /// * `ReleaseStringUTFChars`
6233    /// * `ReleaseStringCritical`
6234    /// * Release<Type>`ArrayElements`
6235    /// * `ReleasePrimitiveArrayCritical`
6236    /// * `DeleteLocalRef`
6237    /// * `DeleteGlobalRef`
6238    /// * `DeleteWeakGlobalRef`
6239    /// * `MonitorExit`
6240    /// * `PushLocalFrame`
6241    /// * `PopLocalFrame`
6242    ///
6243    /// Calling any other JNI function is UB.
6244    ///
6245    /// # Throws Java Exception:
6246    /// * `NoSuchMethodError` if the class has no suitable constructor for the argument supplied. Note: the return value remains `JNI_OK`!
6247    ///   - null `message`: no zero arg or one arg String constructor exists.
6248    ///   - non-null `message`: no one arg String constructor exists.
6249    ///
6250    ///
6251    /// # Panics
6252    /// if asserts feature is enabled and UB was detected
6253    ///
6254    /// # Safety
6255    ///
6256    /// Current thread must not be detached from JNI.
6257    ///
6258    /// Current thread does not hold a critical reference.
6259    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6260    ///
6261    /// Current thread is not currently throwing a Java exception.
6262    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
6263    ///
6264    /// `class` must be a valid non-null handle to a class which is:
6265    /// * Not abstract
6266    /// * Is a descendant of java.lang.Throwable (instances can be cast to Throwable)
6267    ///
6268    /// `message` must be a pointer to a 0 terminated utf-8 string or null.
6269    ///
6270    /// # Example
6271    /// ```rust
6272    /// use std::ffi::CString;
6273    /// use core::ptr::null;
6274    /// use jni_simple::{*};
6275    ///
6276    /// unsafe fn throw_illegal_argument_exception(env: JNIEnv, message: Option<&str>) {
6277    ///     let npe_class = env.FindClass("java/lang/IllegalArgumentException");
6278    ///     if npe_class.is_null() {
6279    ///         env.ExceptionDescribe();
6280    ///         panic!("java/lang/IllegalArgumentException not found!");
6281    ///     }
6282    ///     match message {
6283    ///         None => {
6284    ///             env.ThrowNew(npe_class, ());
6285    ///         }
6286    ///         Some(message) => {
6287    ///             let message = CString::new(message).expect("message contains 0 byte!");
6288    ///             env.ThrowNew(npe_class, message.as_ptr());
6289    ///         }
6290    ///     }
6291    ///     env.DeleteLocalRef(npe_class);
6292    /// }
6293    /// ```
6294    ///
6295    pub unsafe fn ThrowNew(&self, class: jclass, message: impl UseCString) -> jint {
6296        unsafe {
6297            message.use_as_const_c_char(|message| {
6298                #[cfg(feature = "asserts")]
6299                {
6300                    self.check_not_critical("ThrowNew");
6301                    self.check_no_exception("ThrowNew");
6302                    self.check_is_exception_class("ThrowNew", class);
6303                    self.check_is_not_abstract("ThrowNew", class);
6304                }
6305                self.jni::<extern "system" fn(JNIEnvVTable, jclass, *const c_char) -> jint>(14)(self.vtable, class, message)
6306            })
6307        }
6308    }
6309
6310    ///
6311    /// Returns a local reference to the exception currently being thrown.
6312    /// Calling this function does not clear the exception.
6313    /// It stays thrown until for example `ExceptionClear` is called.
6314    ///
6315    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ExceptionOccurred>
6316    ///
6317    /// # Returns
6318    /// A local ref to the throwable that is currently being thrown.
6319    /// null if no throwable is currently thrown.
6320    ///
6321    ///
6322    /// # Panics
6323    /// if asserts feature is enabled and UB was detected
6324    ///
6325    /// # Safety
6326    ///
6327    /// Current thread must not be detached from JNI.
6328    ///
6329    /// Current thread does not hold a critical reference.
6330    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6331    ///
6332    /// # Example
6333    /// ```rust
6334    /// use jni_simple::{*};
6335    ///
6336    ///
6337    /// unsafe fn test(env: JNIEnv) {
6338    ///     let special_exception = env.FindClass("org/example/SuperSpecialException");
6339    ///     if special_exception.is_null() {
6340    ///         unimplemented!("handle class not found")
6341    ///     }
6342    ///     let my_class = env.FindClass("org/example/TestClass");
6343    ///     if my_class.is_null() {
6344    ///         unimplemented!("handle class not found")
6345    ///     }
6346    ///     let my_zero_arg_constructor = env.GetMethodID(my_class, "<init>", "()V");
6347    ///     if my_zero_arg_constructor.is_null() {
6348    ///         unimplemented!("handle no zero arg constructor")
6349    ///     }
6350    ///     let my_object = env.NewObject0(my_class, my_zero_arg_constructor);
6351    ///     if env.ExceptionCheck() {
6352    ///         let exception_object = env.ExceptionOccurred();
6353    ///         env.ExceptionClear();
6354    ///         if env.IsInstanceOf(exception_object, special_exception) {
6355    ///             panic!("zero arg constructor threw SuperSpecialException!")
6356    ///         }
6357    ///
6358    ///         unimplemented!("handle other exceptions");
6359    ///     }
6360    ///     unimplemented!()
6361    /// }
6362    /// ```
6363    ///
6364    #[must_use]
6365    pub unsafe fn ExceptionOccurred(&self) -> jthrowable {
6366        unsafe {
6367            #[cfg(feature = "asserts")]
6368            {
6369                self.check_not_critical("ExceptionOccurred");
6370            }
6371            self.jni::<extern "system" fn(JNIEnvVTable) -> jthrowable>(15)(self.vtable)
6372        }
6373    }
6374
6375    ///
6376    /// Print the stacktrace and message currently thrown to STDOUT.
6377    /// A side effect of this function is that the exception is also cleared.
6378    /// This is roughly equivalent to calling `java.lang.Throwable#printStackTrace()` in java.
6379    ///
6380    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ExceptionDescribe>
6381    ///
6382    /// If no exception is currently thrown then this method is a no-op.
6383    ///
6384    ///
6385    /// # Panics
6386    /// if asserts feature is enabled and UB was detected
6387    ///
6388    /// # Safety
6389    ///
6390    /// Current thread must not be detached from JNI.
6391    ///
6392    /// Current thread does not hold a critical reference.
6393    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6394    ///
6395    /// # Example
6396    /// ```rust
6397    /// use jni_simple::{*};
6398    ///
6399    ///
6400    /// unsafe fn test(env: JNIEnv) {
6401    ///     let my_class = env.FindClass("org/example/TestClass");
6402    ///     if my_class.is_null() {
6403    ///         env.ExceptionDescribe();
6404    ///         panic!("Class not found check stderr");
6405    ///     }
6406    ///     unimplemented!()
6407    /// }
6408    /// ```
6409    ///
6410    pub unsafe fn ExceptionDescribe(&self) {
6411        unsafe {
6412            #[cfg(feature = "asserts")]
6413            {
6414                self.check_not_critical("ExceptionDescribe");
6415            }
6416            self.jni::<extern "system" fn(JNIEnvVTable)>(16)(self.vtable);
6417        }
6418    }
6419
6420    ///
6421    /// Print the stacktrace and message currently thrown to STDOUT.
6422    /// A side effect of this function is that the exception is also cleared.
6423    /// This is roughly equivalent to calling `java.lang.Throwable#printStackTrace()` in java.
6424    ///
6425    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ExceptionDescribe>
6426    ///
6427    /// If no exception is currently thrown then this method is a no-op.
6428    ///
6429    ///
6430    /// # Panics
6431    /// if asserts feature is enabled and UB was detected
6432    ///
6433    /// # Safety
6434    ///
6435    /// Current thread must not be detached from JNI.
6436    ///
6437    /// Current thread does not hold a critical reference.
6438    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6439    ///
6440    /// # Example
6441    /// ```rust
6442    /// use jni_simple::{*};
6443    ///
6444    ///
6445    /// unsafe fn test(env: JNIEnv) {
6446    ///     let mut my_class = env.FindClass("org/example/TestClass");
6447    ///     if my_class.is_null() {
6448    ///         env.ExceptionClear();
6449    ///         my_class = env.FindClass("org/example/FallbackClass");
6450    ///     }
6451    ///     unimplemented!()
6452    /// }
6453    /// ```
6454    ///
6455    pub unsafe fn ExceptionClear(&self) {
6456        unsafe {
6457            #[cfg(feature = "asserts")]
6458            {
6459                self.check_not_critical("ExceptionClear");
6460            }
6461            self.jni::<extern "system" fn(JNIEnvVTable)>(17)(self.vtable);
6462        }
6463    }
6464
6465    ///
6466    /// Raises a fatal error and does not expect the VM to recover. This function does not return.
6467    ///
6468    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#FatalError>
6469    ///
6470    /// # Arguments
6471    /// * `msg` - message that should be present in the error report. 0 terminated utf-8. Must not be null.
6472    ///
6473    ///
6474    /// # Panics
6475    /// if asserts feature is enabled and UB was detected
6476    ///
6477    /// # Safety
6478    ///
6479    /// Current thread must not be detached from JNI.
6480    ///
6481    /// `msg` must be a non-null pointer to a valid 0 terminated utf-8 string.
6482    ///
6483    pub unsafe fn FatalError(&self, msg: impl UseCString) -> ! {
6484        unsafe {
6485            msg.use_as_const_c_char(|msg| {
6486                #[cfg(feature = "asserts")]
6487                {
6488                    assert!(!msg.is_null(), "FatalError msg is null");
6489                }
6490                self.jni::<extern "system" fn(JNIEnvVTable, *const c_char)>(18)(self.vtable, msg);
6491                unreachable!("FatalError");
6492            })
6493        }
6494    }
6495
6496    ///
6497    /// Checks if an exception is thrown on the current thread.
6498    ///
6499    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ExceptionCheck>
6500    ///
6501    /// # Returns
6502    /// true if an exception is thrown on the current thread, false otherwise.
6503    ///
6504    ///
6505    /// # Panics
6506    /// if asserts feature is enabled and UB was detected
6507    ///
6508    /// # Safety
6509    ///
6510    /// Current thread must not be detached from JNI.
6511    ///
6512    /// Current thread does not hold a critical reference.
6513    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6514    ///
6515    /// # Example
6516    /// ```rust
6517    /// use jni_simple::{*};
6518    ///
6519    ///
6520    /// unsafe fn test(env: JNIEnv) {
6521    ///     let my_class = env.FindClass("org/example/TestClass");
6522    ///     if my_class.is_null() {
6523    ///         unimplemented!("handle class not found")
6524    ///     }
6525    ///     let my_zero_arg_constructor = env.GetMethodID(my_class, "<init>", "()V");
6526    ///     if my_zero_arg_constructor.is_null() {
6527    ///         unimplemented!("handle no zero arg constructor")
6528    ///     }
6529    ///     let my_object = env.NewObject0(my_class, my_zero_arg_constructor);
6530    ///     if env.ExceptionCheck() {
6531    ///         panic!("org/example/TestClass zero arg constructor threw an exception!");
6532    ///     }
6533    ///     unimplemented!()
6534    /// }
6535    /// ```
6536    ///
6537    #[must_use]
6538    pub unsafe fn ExceptionCheck(&self) -> jboolean {
6539        unsafe {
6540            #[cfg(feature = "asserts")]
6541            {
6542                self.check_not_critical("ExceptionCheck");
6543            }
6544            self.jni::<extern "system" fn(JNIEnvVTable) -> jboolean>(228)(self.vtable)
6545        }
6546    }
6547
6548    ///
6549    /// Creates a new global reference from an existing reference.
6550    ///
6551    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewGlobalRef>
6552    ///
6553    /// # Arguments
6554    /// * `obj` - a valid reference or null.
6555    ///
6556    /// # Returns
6557    /// the newly created global reference or null.
6558    /// null is returned if:
6559    /// * the argument `obj` is null
6560    /// * the system ran out of memory
6561    /// * `obj` is a weak reference that has already been garbage collected.
6562    ///
6563    ///
6564    /// # Panics
6565    /// if asserts feature is enabled and UB was detected
6566    ///
6567    /// # Safety
6568    ///
6569    /// Current thread must not be detached from JNI.
6570    ///
6571    /// Current thread does not hold a critical reference.
6572    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6573    ///
6574    /// Current thread is not currently throwing a Java exception.
6575    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
6576    ///
6577    /// `obj` must not refer to a reference that has already been deleted by calling `DeleteLocalRef`, `DeleteGlobalRef`, `DeleteWeakGlobalRef`
6578    ///
6579    pub unsafe fn NewGlobalRef(&self, obj: jobject) -> jobject {
6580        unsafe {
6581            #[cfg(feature = "asserts")]
6582            {
6583                self.check_not_critical("NewGlobalRef");
6584                self.check_no_exception("NewGlobalRef");
6585            }
6586            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jobject>(21)(self.vtable, obj)
6587        }
6588    }
6589
6590    ///
6591    /// Deletes a global reference to an object allowing the garbage collector to free it if no more
6592    /// references to it exists.
6593    ///
6594    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#DeleteGlobalRef>
6595    ///
6596    /// # Arguments
6597    /// * `obj` - a valid non-null global reference.
6598    ///
6599    ///
6600    /// # Panics
6601    /// if asserts feature is enabled and UB was detected
6602    ///
6603    /// # Safety
6604    ///
6605    /// Current thread must not be detached from JNI.
6606    ///
6607    /// Current thread does not hold a critical reference.
6608    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6609    ///
6610    /// Current thread is not currently throwing a Java exception.
6611    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
6612    ///
6613    /// `obj` must not be null.
6614    /// `obj` must be a global reference.
6615    /// `obj` must not refer to an already deleted global reference. (Double free)
6616    ///
6617    pub unsafe fn DeleteGlobalRef(&self, obj: jobject) {
6618        unsafe {
6619            #[cfg(feature = "asserts")]
6620            {
6621                self.check_not_critical("DeleteGlobalRef");
6622                assert!(!obj.is_null(), "DeleteGlobalRef obj is null");
6623                match self.GetObjectRefType(obj) {
6624                    jobjectRefType::JNIInvalidRefType => panic!("DeleteGlobalRef invalid non null reference"),
6625                    jobjectRefType::JNILocalRefType => panic!("DeleteGlobalRef local reference passed"),
6626                    jobjectRefType::JNIWeakGlobalRefType => panic!("DeleteGlobalRef weak global reference passed"),
6627                    jobjectRefType::JNIGlobalRefType => {}
6628                }
6629            }
6630            self.jni::<extern "system" fn(JNIEnvVTable, jobject)>(22)(self.vtable, obj);
6631        }
6632    }
6633
6634    ///
6635    /// Deletes a local reference to an object allowing the garbage collector to free it if no more
6636    /// references to it exists.
6637    ///
6638    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#DeleteGlobalRef>
6639    ///
6640    /// # Arguments
6641    /// * `obj` - a valid non-null local reference.
6642    ///
6643    ///
6644    /// # Panics
6645    /// if asserts feature is enabled and UB was detected
6646    ///
6647    /// # Safety
6648    ///
6649    /// Current thread must not be detached from JNI.
6650    ///
6651    /// Current thread does not hold a critical reference.
6652    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6653    ///
6654    /// Current thread is not currently throwing a Java exception.
6655    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
6656    ///
6657    /// `obj` must not be null.
6658    /// `obj` must be a local reference.
6659    /// `obj` must not refer to an already deleted local reference. (Double free)
6660    ///
6661    pub unsafe fn DeleteLocalRef(&self, obj: jobject) {
6662        unsafe {
6663            #[cfg(feature = "asserts")]
6664            {
6665                self.check_not_critical("DeleteLocalRef");
6666                assert!(!obj.is_null(), "DeleteLocalRef obj is null");
6667                if !self.ExceptionCheck() {
6668                    match self.GetObjectRefType(obj) {
6669                        jobjectRefType::JNIInvalidRefType => panic!("DeleteLocalRef invalid non null reference"),
6670                        jobjectRefType::JNILocalRefType => {}
6671                        jobjectRefType::JNIGlobalRefType => panic!("DeleteLocalRef global reference passed"),
6672                        jobjectRefType::JNIWeakGlobalRefType => panic!("DeleteLocalRef weak global reference passed"),
6673                    }
6674                }
6675            }
6676            self.jni::<extern "system" fn(JNIEnvVTable, jobject)>(23)(self.vtable, obj);
6677        }
6678    }
6679
6680    ///
6681    /// The jvm guarantees that a native method can have at least 16 local references.
6682    /// Creating any more than 16 local references without calling this function is effectively UB.
6683    /// This function instructs the JVM to ensure that at least
6684    /// `capacity` amount of local references are available for allocation.
6685    /// This function can be called multiple times to increase the amount of required locals.
6686    ///
6687    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#EnsureLocalCapacity>
6688    ///
6689    ///
6690    /// # Arguments
6691    /// * `capacity` - amount of local references the jvm must provide. Must be larger than 0.
6692    ///
6693    /// # Returns
6694    /// 0 on success, negative value indicating the error.
6695    ///
6696    /// # Throws Java Exception
6697    /// * `OutOfMemoryError` - if the vm runs out of memory ensuring capacity. This is never the case when 0 is returned.
6698    ///
6699    ///
6700    /// # Panics
6701    /// if asserts feature is enabled and UB was detected
6702    ///
6703    /// # Safety
6704    ///
6705    /// Current thread must not be detached from JNI.
6706    ///
6707    /// Current thread does not hold a critical reference.
6708    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6709    ///
6710    /// Current thread is not currently throwing a Java exception.
6711    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
6712    ///
6713    /// `capacity` must not be 0 or negative.
6714    ///
6715    /// ## Observed UB when more locals are allocated than ensured
6716    /// This behavior depends heavily on the jvm used and the arguments used to start it. This list is incomplete
6717    /// * Heap/Stack corruption.
6718    /// * JVM calls `FatalError` and aborts the process.
6719    /// * JVM Functions that would return a local reference return null.
6720    /// * JVM simply allocates more locals than ensured. (starting the jvm with -verbose:jni will log this)
6721    ///
6722    #[must_use]
6723    pub unsafe fn EnsureLocalCapacity(&self, capacity: jint) -> jint {
6724        unsafe {
6725            #[cfg(feature = "asserts")]
6726            {
6727                self.check_not_critical("EnsureLocalCapacity");
6728                self.check_no_exception("EnsureLocalCapacity");
6729                assert!(capacity >= 0, "EnsureLocalCapacity capacity is negative");
6730            }
6731            self.jni::<extern "system" fn(JNIEnvVTable, jint) -> jint>(26)(self.vtable, capacity)
6732        }
6733    }
6734
6735    ///
6736    /// Creates a new local reference frame, in which at least a given number of local references can be created.
6737    /// Note that local references already created in previous local frames are still valid in the current local frame.
6738    /// This method should be called by code that is called from unknown code where it is not known if enough
6739    /// local capacity is available. This method is superior to just increasing the capacity by calling `EnsureLocalCapacity`
6740    /// because that requires at least a rough knowledge of how many locals the caller itself has used and still needs.
6741    ///
6742    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#PushLocalFrame>
6743    ///
6744    ///
6745    /// # Arguments
6746    /// * `capacity` - amount of local references the jvm must provide. Must be larger than 0.
6747    ///
6748    /// # Returns
6749    /// 0 on success, negative value indicating the error.
6750    ///
6751    /// # Throws Java Exception
6752    /// * `OutOfMemoryError` - if the vm runs out of memory ensuring capacity. This is never the case when 0 is returned.
6753    ///
6754    ///
6755    /// # Panics
6756    /// if asserts feature is enabled and UB was detected
6757    ///
6758    /// # Safety
6759    ///
6760    /// Current thread must not be detached from JNI.
6761    ///
6762    /// Current thread does not hold a critical reference.
6763    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6764    ///
6765    /// Current thread is not currently throwing a Java exception.
6766    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#java_exceptions>
6767    ///
6768    /// `capacity` must not be 0 or negative.
6769    ///
6770    /// returning back to java code without cleaning up all created local reference frames by calling `PopLocalFrame` is UB.
6771    ///
6772    /// ## Observed UB when more locals are allocated than ensured
6773    /// This behavior depends heavily on the jvm used and the arguments used to start it. This list is incomplete
6774    /// * Heap/Stack corruption.
6775    /// * JVM calls `FatalError` and aborts the process.
6776    /// * JVM Functions that would return a local reference return null.
6777    /// * JVM simply allocates more locals than ensured. (starting the jvm with -verbose:jni will log this)
6778    ///
6779    #[must_use]
6780    pub unsafe fn PushLocalFrame(&self, capacity: jint) -> jint {
6781        unsafe {
6782            #[cfg(feature = "asserts")]
6783            {
6784                self.check_not_critical("PushLocalFrame");
6785            }
6786            self.jni::<extern "system" fn(JNIEnvVTable, jint) -> jint>(19)(self.vtable, capacity)
6787        }
6788    }
6789
6790    ///
6791    /// Pops a local reference frame created with `PushLocalFrame`
6792    /// All local references created within this reference frame are freed automatically
6793    /// and are no longer valid when this call returns.
6794    ///
6795    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#PopLocalFrame>
6796    ///
6797    /// # Arguments
6798    /// * result - arbitrary jni reference that should be moved to the parent reference frame.
6799    ///   this is similar to a "return" value and may be null if no such result is needed.
6800    ///   the local reference this function returns is valid within the parent local reference frame.
6801    ///
6802    /// # Returns
6803    /// A valid local reference that points to the same object as the reference `result`. Is null if `result` is null.
6804    ///
6805    ///
6806    /// # Panics
6807    /// if asserts feature is enabled and UB was detected
6808    ///
6809    /// # Safety
6810    ///
6811    /// Current thread must not be detached from JNI.
6812    ///
6813    /// Current thread does not hold a critical reference.
6814    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6815    ///
6816    /// result must be a valid reference or null
6817    ///
6818    ///
6819    pub unsafe fn PopLocalFrame(&self, result: jobject) -> jobject {
6820        unsafe {
6821            #[cfg(feature = "asserts")]
6822            {
6823                self.check_not_critical("PopLocalFrame");
6824                self.check_ref_obj_permit_null("PopLocalFrame", result);
6825            }
6826            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jobject>(20)(self.vtable, result)
6827        }
6828    }
6829
6830    ///
6831    /// Creates a new local reference from the given jobject.
6832    ///
6833    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewLocalRef>
6834    ///
6835    /// # Arguments
6836    /// * obj - arbitrary valid jni reference or null
6837    ///
6838    /// # Returns
6839    /// A valid local reference that points to the same object as the reference `obj`. Is null if `obj` is null.
6840    ///
6841    ///
6842    /// # Panics
6843    /// if asserts feature is enabled and UB was detected
6844    ///
6845    /// # Safety
6846    ///
6847    /// Current thread must not be detached from JNI.
6848    ///
6849    /// Current thread must not be throwing an exception.
6850    ///
6851    /// Current thread does not hold a critical reference.
6852    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6853    ///
6854    /// `obj` must be a valid reference or null
6855    ///
6856    pub unsafe fn NewLocalRef(&self, obj: jobject) -> jobject {
6857        unsafe {
6858            #[cfg(feature = "asserts")]
6859            {
6860                self.check_not_critical("NewLocalRef");
6861                self.check_no_exception("NewLocalRef");
6862                self.check_ref_obj_permit_null("NewLocalRef", obj);
6863            }
6864            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jobject>(25)(self.vtable, obj)
6865        }
6866    }
6867
6868    ///
6869    /// Creates a new weak global reference from the given jobject.
6870    ///
6871    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewWeakGlobalRef>
6872    ///
6873    /// # Arguments
6874    /// * obj - arbitrary valid jni reference or null
6875    ///
6876    /// # Returns
6877    /// A valid local weak global reference that points to the same object as the reference `obj`. Is null if `obj` is null.
6878    ///
6879    /// # Throws Java Exception
6880    /// If the JVM runs out of memory, an `OutOfMemoryError` will be thrown.
6881    ///
6882    ///
6883    /// # Panics
6884    /// if asserts feature is enabled and UB was detected
6885    ///
6886    /// # Safety
6887    ///
6888    /// Current thread must not be detached from JNI.
6889    ///
6890    /// Current thread must not be throwing an exception.
6891    ///
6892    /// Current thread does not hold a critical reference.
6893    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6894    ///
6895    /// `obj` must be a valid reference or null
6896    ///
6897    pub unsafe fn NewWeakGlobalRef(&self, obj: jobject) -> jweak {
6898        unsafe {
6899            #[cfg(feature = "asserts")]
6900            {
6901                self.check_not_critical("NewWeakGlobalRef");
6902                self.check_no_exception("NewWeakGlobalRef");
6903            }
6904            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jweak>(226)(self.vtable, obj)
6905        }
6906    }
6907
6908    ///
6909    /// Deletes a weak global reference.
6910    ///
6911    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#DeleteWeakGlobalRef>
6912    ///
6913    /// # Arguments
6914    /// * obj - a weak global reference.
6915    ///     * must not already be deleted.
6916    ///     * must not be null.
6917    ///     * If the referred obj has been garbage collected by the JVM already or not is irrelevant.
6918    ///
6919    /// # Returns
6920    /// A valid local weak global reference that points to the same object as the reference `obj`. Is null if `obj` is null.
6921    ///
6922    ///
6923    /// # Panics
6924    /// if asserts feature is enabled and UB was detected
6925    ///
6926    /// # Safety
6927    ///
6928    /// Current thread must not be detached from JNI.
6929    ///
6930    /// Current thread does not hold a critical reference.
6931    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
6932    ///
6933    /// `obj` must not be null and be a valid weak reference that has not yet been deleted.
6934    ///
6935    pub unsafe fn DeleteWeakGlobalRef(&self, obj: jweak) {
6936        unsafe {
6937            #[cfg(feature = "asserts")]
6938            {
6939                self.check_not_critical("DeleteWeakGlobalRef");
6940                assert!(!obj.is_null(), "DeleteWeakGlobalRef obj is null");
6941                if !self.ExceptionCheck() {
6942                    match self.GetObjectRefType(obj) {
6943                        jobjectRefType::JNIInvalidRefType => panic!("DeleteWeakGlobalRef invalid non null reference"),
6944                        jobjectRefType::JNILocalRefType => panic!("DeleteWeakGlobalRef local reference passed"),
6945                        jobjectRefType::JNIGlobalRefType => panic!("DeleteWeakGlobalRef strong global reference passed"),
6946                        jobjectRefType::JNIWeakGlobalRefType => {}
6947                    }
6948                }
6949            }
6950
6951            self.jni::<extern "system" fn(JNIEnvVTable, jobject)>(227)(self.vtable, obj);
6952        }
6953    }
6954
6955    ///
6956    /// Allocates a new direct instance of the given class without calling any constructor.
6957    ///
6958    /// Every field in the instance will be the JVM default value for the type.
6959    /// * Every numeric is 0,
6960    /// * Every reference/object is null,
6961    /// * Every boolean is false,
6962    /// * Every array is null
6963    ///
6964    /// This will also not perform default initialization of types so a field that is initialized like this in java:
6965    /// ```java
6966    /// private int x = 5;
6967    /// ```
6968    /// This field would not be 5 but be 0 in the instance returned by `AllocObject`.
6969    ///
6970    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#AllocObject>
6971    ///
6972    /// # Note
6973    /// Be aware that the created instance may be initially in a state that is invalid for the given java object.
6974    /// Any object constructed using `AllocObject` should be brought into a valid state by essentially performing duties similar to
6975    /// what the constructor of that object would do. Handling errors during the subsequent initialization process can
6976    /// be especially tricky concerning object finalization. As part of error handling the object will likely be freed which
6977    /// then causes the JVM may run the finalization implementation on the object that is from a java point of view in an invalid state.
6978    /// This might cause undefined behavior in the jvm, depending on what the finalization implementation of the object does.
6979    /// Future Java releases have commited to removing object finalization. This restriction is known to apply to java 21 and lower.
6980    ///
6981    /// Calling any java methods on or with the partially initialized object should be avoided,
6982    /// as the jvm may for example have made assumptions about not yet initialized final fields.
6983    /// How the jvm reacts to this is entirely dependent on which jvm implementation you use and how it was started.
6984    ///
6985    /// # Arguments
6986    /// * `clazz` - reference to a class.
6987    ///     * must not be null
6988    ///     * must be valid
6989    ///     * must not be already garbage collected
6990    ///
6991    /// # Returns
6992    /// A local reference to the newly created object or null if the object could not be created.
6993    ///
6994    /// # Throws Java Exception
6995    /// * `OutOfMemoryError`
6996    ///     * if the jvm runs out of memory.
6997    /// * `InstantiationException`
6998    ///     * if the class is an interface or an abstract class.
6999    ///
7000    ///
7001    ///
7002    /// # Panics
7003    /// if asserts feature is enabled and UB was detected
7004    ///
7005    /// # Safety
7006    ///
7007    /// Current thread must not be detached from JNI.
7008    ///
7009    /// Current thread does not hold a critical reference.
7010    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7011    ///
7012    /// `clazz` must not be null and be a valid reference that has not yet been deleted or garbage collected.
7013    ///
7014    ///
7015    pub unsafe fn AllocObject(&self, clazz: jclass) -> jobject {
7016        unsafe {
7017            #[cfg(feature = "asserts")]
7018            {
7019                assert!(!clazz.is_null(), "AllocObject clazz is null");
7020                self.check_not_critical("AllocObject");
7021                self.check_no_exception("AllocObject");
7022                self.check_is_class("AllocObject", clazz);
7023            }
7024            self.jni::<extern "system" fn(JNIEnvVTable, jclass) -> jobject>(27)(self.vtable, clazz)
7025        }
7026    }
7027
7028    ///
7029    /// Allocates an object by calling a constructor.
7030    ///
7031    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewObject>
7032    ///
7033    ///
7034    /// # Arguments
7035    /// * `clazz` - reference to a class.
7036    ///     * must not be null
7037    ///     * must be valid
7038    ///     * must not be already garbage collected
7039    ///
7040    /// * `constructor` - jmethodID of a constructor
7041    ///     * must be a constructor ('<init>' method name)
7042    ///     * must be a constructor of `clazz`
7043    ///
7044    /// * args - java method parameters
7045    ///     * can be null for 0 arg constructors.
7046    ///     * must be a valid pointer into a jtype array with at least the same length as the java method has parameters.
7047    ///     * the parameters must be valid types.
7048    ///
7049    /// # Returns
7050    /// A local reference to the newly created object or null if the object could not be created.
7051    ///
7052    /// # Throws Java Exception
7053    /// * `OutOfMemoryError`
7054    ///     * if the jvm runs out of memory.
7055    /// * `InstantiationException`
7056    ///     * if the class is an interface or an abstract class.
7057    /// * Any exception thrown by the constructor
7058    ///
7059    ///
7060    /// # Panics
7061    /// if asserts feature is enabled and UB was detected
7062    ///
7063    /// # Safety
7064    ///
7065    /// Current thread must not be detached from JNI.
7066    ///
7067    /// Current thread does not hold a critical reference.
7068    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7069    ///
7070    /// `clazz` must not be null and be a valid reference that has not yet been deleted or garbage collected.
7071    ///
7072    /// `constructor` must be a valid non-static methodID of `clazz` that is a constructor.
7073    ///
7074    /// `args` must be valid, have enough length and contain valid parameters for the method.
7075    /// * for example calling a java constructor that needs a String as parameter, with an 'int' instead is UB.
7076    ///
7077    pub unsafe fn NewObjectA(&self, clazz: jclass, constructor: jmethodID, args: *const jtype) -> jobject {
7078        unsafe {
7079            #[cfg(feature = "asserts")]
7080            {
7081                self.check_not_critical("NewObjectA");
7082                self.check_no_exception("NewObjectA");
7083                assert!(!constructor.is_null(), "NewObjectA constructor is null");
7084                self.check_is_class("NewObjectA", clazz);
7085                //TODO check if constructor is actually constructor or just a normal method.
7086                //TODO check arguments match constructor
7087            }
7088            self.jni::<extern "system" fn(JNIEnvVTable, jclass, jmethodID, *const jtype) -> jobject>(30)(self.vtable, clazz, constructor, args)
7089        }
7090    }
7091
7092    ///
7093    /// Creates a new object instance by calling the zero arg constructor.
7094    ///
7095    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewObject>
7096    ///
7097    ///
7098    /// # Arguments
7099    /// * `clazz` - reference to a class.
7100    ///     * must not be null
7101    ///     * must be valid
7102    ///     * must not be already garbage collected
7103    /// * `constructor` - jmethodID of a constructor
7104    ///     * must be a constructor
7105    ///     * must be a constructor of `clazz`
7106    ///     * must have 0 args
7107    ///
7108    /// # Returns
7109    /// A local reference to the newly created object or null if the object could not be created.
7110    ///
7111    /// # Throws Java Exception
7112    /// * `OutOfMemoryError`
7113    ///     * if the jvm runs out of memory.
7114    /// * `InstantiationException`
7115    ///     * if the class is an interface or an abstract class.
7116    /// * Any exception thrown by the constructor
7117    ///
7118    ///
7119    /// # Panics
7120    /// if asserts feature is enabled and UB was detected
7121    ///
7122    /// # Safety
7123    ///
7124    /// Current thread must not be detached from JNI.
7125    ///
7126    /// Current thread does not hold a critical reference.
7127    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7128    ///
7129    /// `clazz` must not be null and be a valid reference that has not yet been deleted or garbage collected.
7130    ///
7131    /// `constructor` must be a valid non-static methodID of `clazz` that is a constructor.
7132    ///
7133    /// `constructor` must have 0 arguments.
7134    ///
7135    pub unsafe fn NewObject0(&self, clazz: jclass, constructor: jmethodID) -> jobject {
7136        unsafe {
7137            #[cfg(feature = "asserts")]
7138            {
7139                self.check_not_critical("NewObject0");
7140                self.check_no_exception("NewObject0");
7141                assert!(!constructor.is_null(), "NewObject0 constructor is null");
7142                self.check_is_class("NewObject0", clazz);
7143                //TODO check if constructor is actually constructor or just a normal method.
7144                //TODO check zero arg.
7145            }
7146            self.jni::<extern "C" fn(JNIEnvVTable, jclass, jmethodID) -> jobject>(28)(self.vtable, clazz, constructor)
7147        }
7148    }
7149
7150    ///
7151    /// Creates a new object instance by calling the one arg constructor.
7152    ///
7153    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewObject>
7154    ///
7155    ///
7156    /// # Arguments
7157    /// * `clazz` - reference to a class.
7158    ///     * must not be null
7159    ///     * must be valid
7160    ///     * must not be already garbage collected
7161    ///
7162    /// * `constructor` - jmethodID of a constructor
7163    ///     * must be a constructor
7164    ///     * must be a constructor of `clazz`
7165    ///     * must have 1 arg
7166    ///
7167    /// * `arg1` - the argument
7168    ///     * must be of the exact type that the constructor needs to be called with.
7169    ///
7170    /// # Returns
7171    /// A local reference to the newly created object or null if the object could not be created.
7172    ///
7173    /// # Throws Java Exception
7174    /// * `OutOfMemoryError`
7175    ///     * if the jvm runs out of memory.
7176    /// * `InstantiationException`
7177    ///     * if the class is an interface or an abstract class.
7178    /// * Any exception thrown by the constructor
7179    ///
7180    ///
7181    /// # Panics
7182    /// if asserts feature is enabled and UB was detected
7183    ///
7184    /// # Safety
7185    ///
7186    /// Current thread must not be detached from JNI.
7187    ///
7188    /// Current thread does not hold a critical reference.
7189    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7190    ///
7191    /// `clazz` must not be null and be a valid reference that has not yet been deleted or garbage collected.
7192    ///
7193    /// `constructor` must be a valid non-static methodID of `clazz` that is a constructor.
7194    ///
7195    /// `constructor` must have 1 argument.
7196    ///
7197    /// `JType` of `arg1` must match the argument type of the java method exactly.
7198    /// * absolutely no coercion is performed. Not even between trivially coercible types such as for example jint->jlong.
7199    ///     * ex: calling a constructor that expects a jlong with a jint is UB.
7200    ///
7201    pub unsafe fn NewObject1<A: JType>(&self, clazz: jclass, constructor: jmethodID, arg1: A) -> jobject {
7202        unsafe {
7203            #[cfg(feature = "asserts")]
7204            {
7205                self.check_not_critical("NewObject1");
7206                self.check_no_exception("NewObject1");
7207                assert!(!constructor.is_null(), "NewObject1 constructor is null");
7208                self.check_is_class("NewObject1", clazz);
7209                //TODO check if constructor is actually constructor or just a normal method.
7210                self.check_parameter_types_constructor("NewObject1", clazz, constructor, arg1, 0, 1);
7211            }
7212            self.jni::<extern "C" fn(JNIEnvVTable, jclass, jmethodID, ...) -> jobject>(28)(self.vtable, clazz, constructor, arg1)
7213        }
7214    }
7215
7216    ///
7217    /// Creates a new object instance by calling the two arg constructor.
7218    ///
7219    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewObject>
7220    ///
7221    ///
7222    /// # Arguments
7223    /// * `clazz` - reference to a class.
7224    ///     * must not be null
7225    ///     * must be valid
7226    ///     * must not be already garbage collected
7227    ///
7228    /// * `constructor` - jmethodID of a constructor
7229    ///     * must be a constructor
7230    ///     * must be a constructor of `clazz`
7231    ///     * must have 2 args
7232    /// * `arg1` & `arg2` - the arguments
7233    ///     * must be of the exact type that the constructor needs to be called with.
7234    ///
7235    /// # Returns
7236    /// A local reference to the newly created object or null if the object could not be created.
7237    ///
7238    /// # Throws Java Exception
7239    /// * `OutOfMemoryError`
7240    ///     * if the jvm runs out of memory.
7241    /// * `InstantiationException`
7242    ///     * if the class is an interface or an abstract class.
7243    /// * Any exception thrown by the constructor
7244    ///
7245    ///
7246    /// # Panics
7247    /// if asserts feature is enabled and UB was detected
7248    ///
7249    /// # Safety
7250    ///
7251    /// Current thread must not be detached from JNI.
7252    ///
7253    /// Current thread does not hold a critical reference.
7254    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7255    ///
7256    /// `clazz` must not be null and be a valid reference that has not yet been deleted or garbage collected.
7257    ///
7258    /// `constructor` must be a valid non-static methodID of `clazz` that is a constructor.
7259    ///
7260    /// `constructor` must have 2 arguments.
7261    ///
7262    /// `JType` of `arg1` & `arg2` must match the argument type of the java method exactly.
7263    /// * absolutely no coercion is performed. Not even between trivially coercible types such as for example jint->jlong.
7264    ///     * ex: calling a constructor that expects a jlong with a jint is UB.
7265    ///
7266    pub unsafe fn NewObject2<A: JType, B: JType>(&self, clazz: jclass, constructor: jmethodID, arg1: A, arg2: B) -> jobject {
7267        unsafe {
7268            #[cfg(feature = "asserts")]
7269            {
7270                self.check_not_critical("NewObject2");
7271                self.check_no_exception("NewObject2");
7272                assert!(!constructor.is_null(), "NewObject2 constructor is null");
7273                self.check_is_class("NewObject2", clazz);
7274                //TODO check if constructor is actually constructor or just a normal method.
7275                self.check_parameter_types_constructor("NewObject2", clazz, constructor, arg1, 0, 2);
7276                self.check_parameter_types_constructor("NewObject2", clazz, constructor, arg2, 1, 2);
7277            }
7278            self.jni::<extern "C" fn(JNIEnvVTable, jclass, jmethodID, ...) -> jobject>(28)(self.vtable, clazz, constructor, arg1, arg2)
7279        }
7280    }
7281
7282    ///
7283    /// Creates a new object instance by calling the three arg constructor.
7284    ///
7285    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewObject>
7286    ///
7287    ///
7288    /// # Arguments
7289    /// * `clazz` - reference to a class.
7290    ///     * must not be null
7291    ///     * must be valid
7292    ///     * must not be already garbage collected
7293    ///
7294    /// * `constructor` - jmethodID of a constructor
7295    ///     * must be a constructor ('<init>' method name)
7296    ///     * must be a constructor of `clazz`
7297    ///     * must have 3 args
7298    ///
7299    /// * `arg1` & `arg2` & `arg3` - the arguments
7300    ///     * must be of the exact type that the constructor needs to be called with.
7301    ///
7302    /// # Returns
7303    /// A local reference to the newly created object or null if the object could not be created.
7304    ///
7305    /// # Throws Java Exception
7306    /// * `OutOfMemoryError`
7307    ///     * if the jvm runs out of memory.
7308    /// * `InstantiationException`
7309    ///     * if the class is an interface or an abstract class.
7310    /// * Any exception thrown by the constructor
7311    ///
7312    ///
7313    /// # Panics
7314    /// if asserts feature is enabled and UB was detected
7315    ///
7316    /// # Safety
7317    ///
7318    /// Current thread must not be detached from JNI.
7319    ///
7320    /// Current thread does not hold a critical reference.
7321    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7322    ///
7323    /// `clazz` must not be null and be a valid reference that has not yet been deleted or garbage collected.
7324    ///
7325    /// `constructor` must be a valid non-static methodID of `clazz` that is a constructor
7326    ///
7327    /// `constructor` must have 2 arguments.
7328    ///
7329    /// `JType` of `arg1` & `arg2` & `arg3` must match the argument type of the java method exactly.
7330    /// * absolutely no coercion is performed. Not even between trivially coercible types such as for example jint->jlong.
7331    ///     * ex: calling a constructor that expects a jlong with a jint is UB.
7332    ///
7333    pub unsafe fn NewObject3<A: JType, B: JType, C: JType>(&self, clazz: jclass, constructor: jmethodID, arg1: A, arg2: B, arg3: C) -> jobject {
7334        unsafe {
7335            #[cfg(feature = "asserts")]
7336            {
7337                self.check_not_critical("NewObject3");
7338                self.check_no_exception("NewObject3");
7339                assert!(!constructor.is_null(), "NewObject3 constructor is null");
7340                self.check_is_class("NewObject3", clazz);
7341                //TODO check if constructor is actually constructor or just a normal method.
7342                self.check_parameter_types_constructor("NewObject3", clazz, constructor, arg1, 0, 3);
7343                self.check_parameter_types_constructor("NewObject3", clazz, constructor, arg2, 1, 3);
7344                self.check_parameter_types_constructor("NewObject3", clazz, constructor, arg3, 2, 3);
7345            }
7346            self.jni::<extern "C" fn(JNIEnvVTable, jclass, jmethodID, ...) -> jobject>(28)(self.vtable, clazz, constructor, arg1, arg2, arg3)
7347        }
7348    }
7349
7350    ///
7351    /// Gets the class of an object instance.
7352    ///
7353    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetObjectClass>
7354    ///
7355    ///
7356    /// # Arguments
7357    /// * `obj` - reference to a object.
7358    ///     * must not be null
7359    ///     * must be valid
7360    ///     * must not be already garbage collected
7361    ///
7362    /// # Returns
7363    /// A local reference to the class of the object.
7364    ///
7365    ///
7366    /// # Panics
7367    /// if asserts feature is enabled and UB was detected
7368    ///
7369    /// # Safety
7370    ///
7371    /// Current thread must not be detached from JNI.
7372    ///
7373    /// Current thread must not be currently throwing an exception.
7374    ///
7375    /// Current thread does not hold a critical reference.
7376    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7377    ///
7378    /// `obj` must not be null and be a valid reference that has not yet been deleted or garbage collected.
7379    ///
7380    pub unsafe fn GetObjectClass(&self, obj: jobject) -> jclass {
7381        unsafe {
7382            #[cfg(feature = "asserts")]
7383            {
7384                self.check_not_critical("GetObjectClass");
7385                self.check_no_exception("GetObjectClass");
7386                self.check_ref_obj("GetObjectClass", obj);
7387            }
7388            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jobject>(31)(self.vtable, obj)
7389        }
7390    }
7391
7392    ///
7393    /// Gets the type of reference
7394    ///
7395    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetObjectRefType>
7396    ///
7397    ///
7398    /// # Arguments
7399    /// * `obj` - reference to an object.
7400    ///     * must be valid or null
7401    ///
7402    /// # Returns
7403    /// The type of reference
7404    /// `JNIInvalidRefType` is returned for null inputs.
7405    ///
7406    ///
7407    /// # Panics
7408    /// if asserts feature is enabled and UB was detected
7409    ///
7410    /// # Safety
7411    ///
7412    /// Current thread must not be detached from JNI.
7413    ///
7414    /// Current thread must not be currently throwing an exception.
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    /// `obj` must be a valid reference.
7420    ///
7421    /// Calling this fn with an obj that has already been manually deleted using `DeleteLocalRef` for example is UB.
7422    ///
7423    pub unsafe fn GetObjectRefType(&self, obj: jobject) -> jobjectRefType {
7424        unsafe {
7425            #[cfg(feature = "asserts")]
7426            {
7427                self.check_not_critical("GetObjectRefType");
7428                self.check_no_exception("GetObjectRefType");
7429            }
7430            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jobjectRefType>(232)(self.vtable, obj)
7431        }
7432    }
7433
7434    ///
7435    /// Checks if the obj is instanceof the given class
7436    ///
7437    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#IsInstanceOf>
7438    ///
7439    ///
7440    /// # Arguments
7441    /// * `obj` - reference to an object.
7442    ///     * must be valid or null
7443    ///     * must not be already garbage collected
7444    /// * `clazz` - reference to the class.
7445    ///     * must be a valid reference to a class
7446    ///     * must not be null
7447    ///     * must not be already garbage collected
7448    ///
7449    /// # Returns
7450    /// true if `obj` is instanceof `clazz`, false otherwise
7451    /// if `obj` is null then this fn returns false for any `clazz` input
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 must not be currently throwing an exception.
7462    ///
7463    /// Current thread does not hold a critical reference.
7464    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7465    ///
7466    /// `obj` must be null or a valid reference that is not already garbage collected.
7467    /// `clazz` must be a valid non-null reference to a class that is not already garbage collected.
7468    ///
7469    pub unsafe fn IsInstanceOf(&self, obj: jobject, clazz: jclass) -> jboolean {
7470        unsafe {
7471            #[cfg(feature = "asserts")]
7472            {
7473                self.check_not_critical("IsInstanceOf");
7474                self.check_no_exception("IsInstanceOf");
7475                self.check_is_class("IsInstanceOf", clazz);
7476                self.check_ref_obj_permit_null("IsInstanceOf", obj);
7477            }
7478            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass) -> jboolean>(32)(self.vtable, obj, clazz)
7479        }
7480    }
7481
7482    ///
7483    /// this is the java == operator on 2 java objects.
7484    /// The opaque handles of the 2 objects could be different but refer to the same underlying object.
7485    /// This fn exists in order to be able to check this.
7486    ///
7487    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#IsSameObject>
7488    ///
7489    ///
7490    /// # Arguments
7491    /// * `obj1` - reference to an object.
7492    ///     * must be valid or null
7493    ///     * must not be already garbage collected
7494    /// * `obj2` - reference to the class.
7495    ///     * must be valid or null
7496    ///     * must not be already garbage collected
7497    ///
7498    /// # Returns
7499    /// true if `obj1` == `obj2`, false otherwise
7500    ///
7501    ///
7502    ///
7503    /// # Panics
7504    /// if asserts feature is enabled and UB was detected
7505    ///
7506    /// # Safety
7507    ///
7508    /// Current thread must not be detached from JNI.
7509    ///
7510    /// Current thread must not be currently throwing an exception.
7511    ///
7512    /// Current thread does not hold a critical reference.
7513    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7514    ///
7515    /// `obj1` must be null or a valid reference that is not already garbage collected.
7516    /// `obj2` must be null or a valid reference that is not already garbage collected.
7517    ///
7518    pub unsafe fn IsSameObject(&self, obj1: jobject, obj2: jobject) -> jboolean {
7519        unsafe {
7520            #[cfg(feature = "asserts")]
7521            {
7522                self.check_not_critical("IsSameObject");
7523                self.check_no_exception("IsSameObject");
7524                self.check_ref_obj_permit_null("IsSameObject obj1", obj1);
7525                self.check_ref_obj_permit_null("IsSameObject obj2", obj2);
7526            }
7527            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jobject) -> jboolean>(24)(self.vtable, obj1, obj2)
7528        }
7529    }
7530
7531    ///
7532    /// Gets the field id of a non-static field
7533    ///
7534    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetFieldID>
7535    ///
7536    ///
7537    /// # Arguments
7538    /// * `clazz` - reference to the clazz where the field is declared in.
7539    ///     * must be valid
7540    ///     * must not be null
7541    ///     * must not be already garbage collected
7542    /// * `name` - name of the field
7543    ///     * must not be null
7544    ///     * must be zero terminated utf-8
7545    /// * `sig` - jni signature of the field
7546    ///     * must not be null
7547    ///     * must be zero terminated utf-8
7548    ///
7549    /// # Returns
7550    /// A non-null field handle or null on error.
7551    /// The field handle can be assumed to be constant for the given class and must not be freed.
7552    /// It can also be safely shared with any thread or stored in a constant.
7553    ///
7554    /// # Throws Java Exception
7555    /// * `NoSuchFieldError` - field with the given name and sig doesnt exist in the class
7556    /// * `ExceptionInInitializerError` - Exception occurs in initializer of the class
7557    /// * `OutOfMemoryError` - if the jvm runs out of memory
7558    ///
7559    ///
7560    /// # Panics
7561    /// if asserts feature is enabled and UB was detected
7562    ///
7563    /// # Safety
7564    ///
7565    /// Current thread must not be detached from JNI.
7566    ///
7567    /// Current thread must not be currently throwing an exception.
7568    ///
7569    /// Current thread does not hold a critical reference.
7570    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7571    ///
7572    /// `clazz` must a valid reference to a class that is not already garbage collected.
7573    /// `name` must be non-null and zero terminated utf-8.
7574    /// `sig` must be non-null and zero terminated utf-8.
7575    ///
7576    pub unsafe fn GetFieldID(&self, clazz: jclass, name: impl UseCString, sig: impl UseCString) -> jfieldID {
7577        unsafe {
7578            name.use_as_const_c_char(|name| {
7579                sig.use_as_const_c_char(|sig| {
7580                    #[cfg(feature = "asserts")]
7581                    {
7582                        self.check_not_critical("GetFieldID");
7583                        self.check_no_exception("GetFieldID");
7584                        assert!(!name.is_null(), "GetFieldID name is null");
7585                        assert!(!sig.is_null(), "GetFieldID sig is null");
7586                        self.check_is_class("GetFieldID", clazz);
7587                    }
7588                    self.jni::<extern "system" fn(JNIEnvVTable, jclass, *const c_char, *const c_char) -> jfieldID>(94)(self.vtable, clazz, name, sig)
7589                })
7590            })
7591        }
7592    }
7593
7594    ///
7595    /// Returns a local reference from a field in an object.
7596    ///
7597    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines>
7598    ///
7599    ///
7600    /// # Arguments
7601    /// * `obj` - reference to the object the field is in
7602    ///     * must be valid
7603    ///     * must not be null
7604    ///     * must not be already garbage collected
7605    /// * `fieldID` - the field to get
7606    ///     * must be valid
7607    ///     * must be a object field
7608    ///
7609    /// # Returns
7610    /// A local reference to the fields value or null if the field is null
7611    ///
7612    ///
7613    /// # Panics
7614    /// if asserts feature is enabled and UB was detected
7615    ///
7616    /// # Safety
7617    ///
7618    /// Current thread must not be detached from JNI.
7619    ///
7620    /// Current thread must not be currently throwing an exception.
7621    ///
7622    /// Current thread does not hold a critical reference.
7623    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7624    ///
7625    /// `obj` must a valid reference to the object that is not already garbage collected.
7626    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
7627    /// `fieldID` must not be from a static field
7628    /// `fieldID` must refer to a field that is an object and not a primitive.
7629    ///
7630    pub unsafe fn GetObjectField(&self, obj: jobject, fieldID: jfieldID) -> jobject {
7631        unsafe {
7632            #[cfg(feature = "asserts")]
7633            {
7634                self.check_not_critical("GetObjectField");
7635                self.check_no_exception("GetObjectField");
7636                self.check_field_type_object("GetObjectField", obj, fieldID, "object");
7637            }
7638            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jobject>(95)(self.vtable, obj, fieldID)
7639        }
7640    }
7641
7642    ///
7643    /// Returns a boolean field value
7644    ///
7645    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines>
7646    ///
7647    ///
7648    /// # Arguments
7649    /// * `obj` - reference to the object the field is in
7650    ///     * must be valid
7651    ///     * must not be null
7652    ///     * must not be already garbage collected
7653    /// * `fieldID` - the field to get
7654    ///     * must be valid
7655    ///     * must be a boolean field
7656    ///
7657    /// # Returns
7658    /// The boolean field value
7659    ///
7660    ///
7661    /// # Panics
7662    /// if asserts feature is enabled and UB was detected
7663    ///
7664    /// # Safety
7665    ///
7666    /// Current thread must not be detached from JNI.
7667    ///
7668    /// Current thread must not be currently throwing an exception.
7669    ///
7670    /// Current thread does not hold a critical reference.
7671    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7672    ///
7673    /// `obj` must a valid reference to the object that is not already garbage collected.
7674    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
7675    /// `fieldID` must not be from a static field
7676    /// `fieldID` must refer to a field that is a boolean and not something else.
7677    ///
7678    pub unsafe fn GetBooleanField(&self, obj: jobject, fieldID: jfieldID) -> jboolean {
7679        unsafe {
7680            #[cfg(feature = "asserts")]
7681            {
7682                self.check_not_critical("GetBooleanField");
7683                self.check_no_exception("GetBooleanField");
7684                self.check_field_type_object("GetBooleanField", obj, fieldID, "boolean");
7685            }
7686            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jboolean>(96)(self.vtable, obj, fieldID)
7687        }
7688    }
7689
7690    ///
7691    /// Returns a byte field value
7692    ///
7693    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines>
7694    ///
7695    ///
7696    /// # Arguments
7697    /// * `obj` - reference to the object the field is in
7698    ///     * must be valid
7699    ///     * must not be null
7700    ///     * must not be already garbage collected
7701    /// * `fieldID` - the field to get
7702    ///     * must be valid
7703    ///     * must be a byte field
7704    ///
7705    /// # Returns
7706    /// The byte field value
7707    ///
7708    ///
7709    /// # Panics
7710    /// if asserts feature is enabled and UB was detected
7711    ///
7712    /// # Safety
7713    ///
7714    /// Current thread must not be detached from JNI.
7715    ///
7716    /// Current thread must not be currently throwing an exception.
7717    ///
7718    /// Current thread does not hold a critical reference.
7719    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7720    ///
7721    /// `obj` must a valid reference to the object that is not already garbage collected.
7722    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
7723    /// `fieldID` must not be from a static field
7724    /// `fieldID` must refer to a field that is a byte and not something else.
7725    ///
7726    pub unsafe fn GetByteField(&self, obj: jobject, fieldID: jfieldID) -> jbyte {
7727        unsafe {
7728            #[cfg(feature = "asserts")]
7729            {
7730                self.check_not_critical("GetByteField");
7731                self.check_no_exception("GetByteField");
7732                self.check_field_type_object("GetByteField", obj, fieldID, "byte");
7733            }
7734            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jbyte>(97)(self.vtable, obj, fieldID)
7735        }
7736    }
7737
7738    ///
7739    /// Returns a char field value
7740    ///
7741    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines>
7742    ///
7743    ///
7744    /// # Arguments
7745    /// * `obj` - reference to the object the field is in
7746    ///     * must be valid
7747    ///     * must not be null
7748    ///     * must not be already garbage collected
7749    /// * `fieldID` - the field to get
7750    ///     * must be valid
7751    ///     * must be a char field
7752    ///
7753    /// # Returns
7754    /// The char field value
7755    ///
7756    ///
7757    /// # Panics
7758    /// if asserts feature is enabled and UB was detected
7759    ///
7760    /// # Safety
7761    ///
7762    /// Current thread must not be detached from JNI.
7763    ///
7764    /// Current thread must not be currently throwing an exception.
7765    ///
7766    /// Current thread does not hold a critical reference.
7767    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7768    ///
7769    /// `obj` must a valid reference to the object that is not already garbage collected.
7770    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
7771    /// `fieldID` must not be from a static field
7772    /// `fieldID` must refer to a field that is a char and not something else.
7773    ///
7774    pub unsafe fn GetCharField(&self, obj: jobject, fieldID: jfieldID) -> jchar {
7775        unsafe {
7776            #[cfg(feature = "asserts")]
7777            {
7778                self.check_not_critical("GetCharField");
7779                self.check_no_exception("GetCharField");
7780                self.check_field_type_object("GetCharField", obj, fieldID, "char");
7781            }
7782            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jchar>(98)(self.vtable, obj, fieldID)
7783        }
7784    }
7785
7786    ///
7787    /// Returns a short field value
7788    ///
7789    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines>
7790    ///
7791    ///
7792    /// # Arguments
7793    /// * `obj` - reference to the object the field is in
7794    ///     * must be valid
7795    ///     * must not be null
7796    ///     * must not be already garbage collected
7797    /// * `fieldID` - the field to get
7798    ///     * must be valid
7799    ///     * must be a short field
7800    ///
7801    /// # Returns
7802    /// The short field value
7803    ///
7804    ///
7805    /// # Panics
7806    /// if asserts feature is enabled and UB was detected
7807    ///
7808    /// # Safety
7809    ///
7810    /// Current thread must not be detached from JNI.
7811    ///
7812    /// Current thread must not be currently throwing an exception.
7813    ///
7814    /// Current thread does not hold a critical reference.
7815    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7816    ///
7817    /// `obj` must a valid reference to the object that is not already garbage collected.
7818    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
7819    /// `fieldID` must not be from a static field
7820    /// `fieldID` must refer to a field that is a short and not something else.
7821    ///
7822    pub unsafe fn GetShortField(&self, obj: jobject, fieldID: jfieldID) -> jshort {
7823        unsafe {
7824            #[cfg(feature = "asserts")]
7825            {
7826                self.check_not_critical("GetShortField");
7827                self.check_no_exception("GetShortField");
7828                self.check_field_type_object("GetShortField", obj, fieldID, "short");
7829            }
7830            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jshort>(99)(self.vtable, obj, fieldID)
7831        }
7832    }
7833
7834    ///
7835    /// Returns a int field value
7836    ///
7837    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines>
7838    ///
7839    ///
7840    /// # Arguments
7841    /// * `obj` - reference to the object the field is in
7842    ///     * must be valid
7843    ///     * must not be null
7844    ///     * must not be already garbage collected
7845    /// * `fieldID` - the field to get
7846    ///     * must be valid
7847    ///     * must be a int field
7848    ///
7849    /// # Returns
7850    /// The int field value
7851    ///
7852    ///
7853    /// # Panics
7854    /// if asserts feature is enabled and UB was detected
7855    ///
7856    /// # Safety
7857    ///
7858    /// Current thread must not be detached from JNI.
7859    ///
7860    /// Current thread must not be currently throwing an exception.
7861    ///
7862    /// Current thread does not hold a critical reference.
7863    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7864    ///
7865    /// `obj` must a valid reference to the object that is not already garbage collected.
7866    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
7867    /// `fieldID` must not be from a static field
7868    /// `fieldID` must refer to a field that is a int and not something else.
7869    ///
7870    pub unsafe fn GetIntField(&self, obj: jobject, fieldID: jfieldID) -> jint {
7871        unsafe {
7872            #[cfg(feature = "asserts")]
7873            {
7874                self.check_not_critical("GetIntField");
7875                self.check_no_exception("GetIntField");
7876                self.check_field_type_object("GetIntField", obj, fieldID, "int");
7877            }
7878            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jint>(100)(self.vtable, obj, fieldID)
7879        }
7880    }
7881
7882    ///
7883    /// Returns a int field value
7884    ///
7885    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines>
7886    ///
7887    ///
7888    /// # Arguments
7889    /// * `obj` - reference to the object the field is in
7890    ///     * must be valid
7891    ///     * must not be null
7892    ///     * must not be already garbage collected
7893    /// * `fieldID` - the field to get
7894    ///     * must be valid
7895    ///     * must be a long field
7896    ///
7897    /// # Returns
7898    /// The long field value
7899    ///
7900    ///
7901    /// # Panics
7902    /// if asserts feature is enabled and UB was detected
7903    ///
7904    /// # Safety
7905    ///
7906    /// Current thread must not be detached from JNI.
7907    ///
7908    /// Current thread must not be currently throwing an exception.
7909    ///
7910    /// Current thread does not hold a critical reference.
7911    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7912    ///
7913    /// `obj` must a valid reference to the object that is not already garbage collected.
7914    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
7915    /// `fieldID` must not be from a static field
7916    /// `fieldID` must refer to a field that is a long and not something else.
7917    ///
7918    pub unsafe fn GetLongField(&self, obj: jobject, fieldID: jfieldID) -> jlong {
7919        unsafe {
7920            #[cfg(feature = "asserts")]
7921            {
7922                self.check_not_critical("GetLongField");
7923                self.check_no_exception("GetLongField");
7924                self.check_field_type_object("GetLongField", obj, fieldID, "long");
7925            }
7926            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jlong>(101)(self.vtable, obj, fieldID)
7927        }
7928    }
7929
7930    ///
7931    /// Returns a float field value
7932    ///
7933    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines>
7934    ///
7935    ///
7936    /// # Arguments
7937    /// * `obj` - reference to the object the field is in
7938    ///     * must be valid
7939    ///     * must not be null
7940    ///     * must not be already garbage collected
7941    /// * `fieldID` - the field to get
7942    ///     * must be valid
7943    ///     * must be a long field
7944    ///
7945    /// # Returns
7946    /// The float field value
7947    ///
7948    ///
7949    /// # Panics
7950    /// if asserts feature is enabled and UB was detected
7951    ///
7952    /// # Safety
7953    ///
7954    /// Current thread must not be detached from JNI.
7955    ///
7956    /// Current thread must not be currently throwing an exception.
7957    ///
7958    /// Current thread does not hold a critical reference.
7959    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
7960    ///
7961    /// `obj` must a valid reference to the object that is not already garbage collected.
7962    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
7963    /// `fieldID` must not be from a static field
7964    /// `fieldID` must refer to a field that is a float and not something else.
7965    ///
7966    pub unsafe fn GetFloatField(&self, obj: jobject, fieldID: jfieldID) -> jfloat {
7967        unsafe {
7968            #[cfg(feature = "asserts")]
7969            {
7970                self.check_not_critical("GetFloatField");
7971                self.check_no_exception("GetFloatField");
7972                self.check_field_type_object("GetFloatField", obj, fieldID, "float");
7973            }
7974            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jfloat>(102)(self.vtable, obj, fieldID)
7975        }
7976    }
7977
7978    ///
7979    /// Returns a double field value
7980    ///
7981    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines>
7982    ///
7983    ///
7984    /// # Arguments
7985    /// * `obj` - reference to the object the field is in
7986    ///     * must be valid
7987    ///     * must not be null
7988    ///     * must not be already garbage collected
7989    /// * `fieldID` - the field to get
7990    ///     * must be valid
7991    ///     * must be a double field
7992    ///
7993    /// # Returns
7994    /// The double field value
7995    ///
7996    ///
7997    /// # Panics
7998    /// if asserts feature is enabled and UB was detected
7999    ///
8000    /// # Safety
8001    ///
8002    /// Current thread must not be detached from JNI.
8003    ///
8004    /// Current thread must not be currently throwing an exception.
8005    ///
8006    /// Current thread does not hold a critical reference.
8007    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8008    ///
8009    /// `obj` must a valid reference to the object that is not already garbage collected.
8010    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
8011    /// `fieldID` must not be from a static field
8012    /// `fieldID` must refer to a field that is a double and not something else.
8013    ///
8014    pub unsafe fn GetDoubleField(&self, obj: jobject, fieldID: jfieldID) -> jdouble {
8015        unsafe {
8016            #[cfg(feature = "asserts")]
8017            {
8018                self.check_not_critical("GetDoubleField");
8019                self.check_no_exception("GetDoubleField");
8020                self.check_field_type_object("GetDoubleField", obj, fieldID, "double");
8021            }
8022            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jdouble>(103)(self.vtable, obj, fieldID)
8023        }
8024    }
8025
8026    ///
8027    /// Sets a object field to a given value
8028    ///
8029    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_type_Field_routines>
8030    ///
8031    /// # Arguments
8032    /// * `obj` - reference to the object the field is in
8033    ///     * must be valid
8034    ///     * must not be null
8035    ///     * must not be already garbage collected
8036    ///
8037    /// * `fieldID` - the field to set
8038    ///     * must be valid
8039    ///     * must be a object field
8040    ///     * must reside in the object `obj`
8041    ///
8042    /// * `value`
8043    ///     * must be null or valid
8044    ///     * must not be already garbage collected (if non-null)
8045    ///     * must be assignable to the field type (if non-null)
8046    ///
8047    ///
8048    /// # Panics
8049    /// if asserts feature is enabled and UB was detected
8050    ///
8051    /// # Safety
8052    ///
8053    /// Current thread must not be detached from JNI.
8054    ///
8055    /// Current thread must not be currently throwing an exception.
8056    ///
8057    /// Current thread does not hold a critical reference.
8058    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8059    ///
8060    /// `obj` must be a valid reference to the object that is not already garbage collected.
8061    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
8062    /// `fieldID` must not be from a static field
8063    /// `fieldID` must refer to a field that is an object and not a primitive.
8064    /// `value` must be a valid reference to the object that is not already garbage collected or it must be null.
8065    /// `value` must be assignable to the field type (i.e. if it's a String field setting to an `ArrayList` for example is UB)
8066    ///
8067    pub unsafe fn SetObjectField(&self, obj: jobject, fieldID: jfieldID, value: jobject) {
8068        unsafe {
8069            #[cfg(feature = "asserts")]
8070            {
8071                self.check_not_critical("SetObjectField");
8072                self.check_no_exception("SetObjectField");
8073                self.check_field_type_object("SetObjectField", obj, fieldID, "object");
8074                self.check_ref_obj_permit_null("SetObjectField", value);
8075            }
8076            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jobject)>(104)(self.vtable, obj, fieldID, value);
8077        }
8078    }
8079
8080    ///
8081    /// Sets a boolean field to a given value
8082    ///
8083    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_type_Field_routines>
8084    ///
8085    /// # Arguments
8086    /// * `obj` - reference to the object the field is in
8087    ///     * must be valid
8088    ///     * must not be null
8089    ///     * must not be already garbage collected
8090    ///
8091    /// * `fieldID` - the field to set
8092    ///     * must be valid
8093    ///     * must be a object field
8094    ///     * must reside in the object `obj`
8095    ///
8096    /// * `value` - the value to set
8097    ///
8098    ///
8099    /// # Panics
8100    /// if asserts feature is enabled and UB was detected
8101    ///
8102    /// # Safety
8103    ///
8104    /// Current thread must not be detached from JNI.
8105    ///
8106    /// Current thread must not be currently throwing an exception.
8107    ///
8108    /// Current thread does not hold a critical reference.
8109    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8110    ///
8111    /// `obj` must be a valid reference to the object that is not already garbage collected.
8112    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
8113    /// `fieldID` must not be from a static field
8114    /// `fieldID` must refer to a field that is a boolean.
8115    ///
8116    pub unsafe fn SetBooleanField(&self, obj: jobject, fieldID: jfieldID, value: jboolean) {
8117        unsafe {
8118            #[cfg(feature = "asserts")]
8119            {
8120                self.check_not_critical("SetBooleanField");
8121                self.check_no_exception("SetBooleanField");
8122                self.check_field_type_object("SetBooleanField", obj, fieldID, "boolean");
8123            }
8124            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jboolean)>(105)(self.vtable, obj, fieldID, value);
8125        }
8126    }
8127
8128    ///
8129    /// Sets a byte field to a given value
8130    ///
8131    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_type_Field_routines>
8132    ///
8133    /// # Arguments
8134    /// * `obj` - reference to the object the field is in
8135    ///     * must be valid
8136    ///     * must not be null
8137    ///     * must not be already garbage collected
8138    ///
8139    /// * `fieldID` - the field to set
8140    ///     * must be valid
8141    ///     * must be a object field
8142    ///     * must reside in the object `obj`
8143    ///
8144    /// * `value` - the value to set
8145    ///
8146    ///
8147    /// # Panics
8148    /// if asserts feature is enabled and UB was detected
8149    ///
8150    /// # Safety
8151    ///
8152    /// Current thread must not be detached from JNI.
8153    ///
8154    /// Current thread must not be currently throwing an exception.
8155    ///
8156    /// Current thread does not hold a critical reference.
8157    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8158    ///
8159    /// `obj` must be a valid reference to the object that is not already garbage collected.
8160    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
8161    /// `fieldID` must not be from a static field
8162    /// `fieldID` must refer to a field that is a byte.
8163    ///
8164    pub unsafe fn SetByteField(&self, obj: jobject, fieldID: jfieldID, value: jbyte) {
8165        unsafe {
8166            #[cfg(feature = "asserts")]
8167            {
8168                self.check_not_critical("SetByteField");
8169                self.check_no_exception("SetByteField");
8170                self.check_field_type_object("SetByteField", obj, fieldID, "byte");
8171            }
8172            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jbyte)>(106)(self.vtable, obj, fieldID, value);
8173        }
8174    }
8175
8176    ///
8177    /// Sets a char field to a given value
8178    ///
8179    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_type_Field_routines>
8180    ///
8181    /// # Arguments
8182    /// * `obj` - reference to the object the field is in
8183    ///     * must be valid
8184    ///     * must not be null
8185    ///     * must not be already garbage collected
8186    ///
8187    /// * `fieldID` - the field to set
8188    ///     * must be valid
8189    ///     * must be a object field
8190    ///     * must reside in the object `obj`
8191    ///
8192    /// * `value` - the value to set
8193    ///
8194    ///
8195    /// # Panics
8196    /// if asserts feature is enabled and UB was detected
8197    ///
8198    /// # Safety
8199    ///
8200    /// Current thread must not be detached from JNI.
8201    ///
8202    /// Current thread must not be currently throwing an exception.
8203    ///
8204    /// Current thread does not hold a critical reference.
8205    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8206    ///
8207    /// `obj` must be a valid reference to the object that is not already garbage collected.
8208    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
8209    /// `fieldID` must not be from a static field
8210    /// `fieldID` must refer to a field that is a char.
8211    ///
8212    pub unsafe fn SetCharField(&self, obj: jobject, fieldID: jfieldID, value: jchar) {
8213        unsafe {
8214            #[cfg(feature = "asserts")]
8215            {
8216                self.check_not_critical("SetCharField");
8217                self.check_no_exception("SetCharField");
8218                self.check_field_type_object("SetCharField", obj, fieldID, "char");
8219            }
8220            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jchar)>(107)(self.vtable, obj, fieldID, value);
8221        }
8222    }
8223
8224    ///
8225    /// Sets a short field to a given value
8226    ///
8227    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_type_Field_routines>
8228    ///
8229    /// # Arguments
8230    /// * `obj` - reference to the object the field is in
8231    ///     * must be valid
8232    ///     * must not be null
8233    ///     * must not be already garbage collected
8234    ///
8235    /// * `fieldID` - the field to set
8236    ///     * must be valid
8237    ///     * must be a object field
8238    ///     * must reside in the object `obj`
8239    ///
8240    /// * `value` - the value to set
8241    ///
8242    ///
8243    /// # Panics
8244    /// if asserts feature is enabled and UB was detected
8245    ///
8246    /// # Safety
8247    ///
8248    /// Current thread must not be detached from JNI.
8249    ///
8250    /// Current thread must not be currently throwing an exception.
8251    ///
8252    /// Current thread does not hold a critical reference.
8253    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8254    ///
8255    /// `obj` must be a valid reference to the object that is not already garbage collected.
8256    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
8257    /// `fieldID` must not be from a static field
8258    /// `fieldID` must refer to a field that is a short.
8259    ///
8260    pub unsafe fn SetShortField(&self, obj: jobject, fieldID: jfieldID, value: jshort) {
8261        unsafe {
8262            #[cfg(feature = "asserts")]
8263            {
8264                self.check_not_critical("SetShortField");
8265                self.check_no_exception("SetShortField");
8266                self.check_field_type_object("SetShortField", obj, fieldID, "short");
8267            }
8268            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jshort)>(108)(self.vtable, obj, fieldID, value);
8269        }
8270    }
8271
8272    ///
8273    /// Sets a int field to a given value
8274    ///
8275    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_type_Field_routines>
8276    ///
8277    /// # Arguments
8278    /// * `obj` - reference to the object the field is in
8279    ///     * must be valid
8280    ///     * must not be null
8281    ///     * must not be already garbage collected
8282    ///
8283    /// * `fieldID` - the field to set
8284    ///     * must be valid
8285    ///     * must be a object field
8286    ///     * must reside in the object `obj`
8287    ///
8288    /// * `value` - the value to set
8289    ///
8290    ///
8291    /// # Panics
8292    /// if asserts feature is enabled and UB was detected
8293    ///
8294    /// # Safety
8295    ///
8296    /// Current thread must not be detached from JNI.
8297    ///
8298    /// Current thread must not be currently throwing an exception.
8299    ///
8300    /// Current thread does not hold a critical reference.
8301    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8302    ///
8303    /// `obj` must be a valid reference to the object that is not already garbage collected.
8304    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
8305    /// `fieldID` must not be from a static field
8306    /// `fieldID` must refer to a field that is a int.
8307    ///
8308    pub unsafe fn SetIntField(&self, obj: jobject, fieldID: jfieldID, value: jint) {
8309        unsafe {
8310            #[cfg(feature = "asserts")]
8311            {
8312                self.check_not_critical("SetIntField");
8313                self.check_no_exception("SetIntField");
8314                self.check_field_type_object("SetIntField", obj, fieldID, "int");
8315            }
8316            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jint)>(109)(self.vtable, obj, fieldID, value);
8317        }
8318    }
8319
8320    ///
8321    /// Sets a long field to a given value
8322    ///
8323    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_type_Field_routines>
8324    ///
8325    /// # Arguments
8326    /// * `obj` - reference to the object the field is in
8327    ///     * must be valid
8328    ///     * must not be null
8329    ///     * must not be already garbage collected
8330    ///
8331    /// * `fieldID` - the field to set
8332    ///     * must be valid
8333    ///     * must be a object field
8334    ///     * must reside in the object `obj`
8335    ///
8336    /// * `value` - the value to set
8337    ///
8338    ///
8339    /// # Panics
8340    /// if asserts feature is enabled and UB was detected
8341    ///
8342    /// # Safety
8343    ///
8344    /// Current thread must not be detached from JNI.
8345    ///
8346    /// Current thread must not be currently throwing an exception.
8347    ///
8348    /// Current thread does not hold a critical reference.
8349    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8350    ///
8351    /// `obj` must be a valid reference to the object that is not already garbage collected.
8352    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
8353    /// `fieldID` must not be from a static field
8354    /// `fieldID` must refer to a field that is a long.
8355    ///
8356    pub unsafe fn SetLongField(&self, obj: jobject, fieldID: jfieldID, value: jlong) {
8357        unsafe {
8358            #[cfg(feature = "asserts")]
8359            {
8360                self.check_not_critical("SetLongField");
8361                self.check_no_exception("SetLongField");
8362                self.check_field_type_object("SetLongField", obj, fieldID, "long");
8363            }
8364            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jlong)>(110)(self.vtable, obj, fieldID, value);
8365        }
8366    }
8367
8368    ///
8369    /// Sets a float field to a given value
8370    ///
8371    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_type_Field_routines>
8372    ///
8373    /// # Arguments
8374    /// * `obj` - reference to the object the field is in
8375    ///     * must be valid
8376    ///     * must not be null
8377    ///     * must not be already garbage collected
8378    ///
8379    /// * `fieldID` - the field to set
8380    ///     * must be valid
8381    ///     * must be a object field
8382    ///     * must reside in the object `obj`
8383    ///
8384    /// * `value` - the value to set
8385    ///
8386    ///
8387    /// # Panics
8388    /// if asserts feature is enabled and UB was detected
8389    ///
8390    /// # Safety
8391    ///
8392    /// Current thread must not be detached from JNI.
8393    ///
8394    /// Current thread must not be currently throwing an exception.
8395    ///
8396    /// Current thread does not hold a critical reference.
8397    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8398    ///
8399    /// `obj` must be a valid reference to the object that is not already garbage collected.
8400    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
8401    /// `fieldID` must not be from a static field
8402    /// `fieldID` must refer to a field that is a float.
8403    ///
8404    pub unsafe fn SetFloatField(&self, obj: jobject, fieldID: jfieldID, value: jfloat) {
8405        unsafe {
8406            #[cfg(feature = "asserts")]
8407            {
8408                self.check_not_critical("SetFloatField");
8409                self.check_no_exception("SetFloatField");
8410                self.check_field_type_object("SetFloatField", obj, fieldID, "float");
8411            }
8412            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jfloat)>(111)(self.vtable, obj, fieldID, value);
8413        }
8414    }
8415
8416    ///
8417    /// Sets a double field to a given value
8418    ///
8419    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_type_Field_routines>
8420    ///
8421    /// # Arguments
8422    /// * `obj` - reference to the object the field is in
8423    ///     * must be valid
8424    ///     * must not be null
8425    ///     * must not be already garbage collected
8426    ///
8427    /// * `fieldID` - the field to set
8428    ///     * must be valid
8429    ///     * must be a object field
8430    ///     * must reside in the object `obj`
8431    ///
8432    /// * `value` - the value to set
8433    ///
8434    ///
8435    /// # Panics
8436    /// if asserts feature is enabled and UB was detected
8437    ///
8438    /// # Safety
8439    ///
8440    /// Current thread must not be detached from JNI.
8441    ///
8442    /// Current thread must not be currently throwing an exception.
8443    ///
8444    /// Current thread does not hold a critical reference.
8445    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8446    ///
8447    /// `obj` must be a valid reference to the object that is not already garbage collected.
8448    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
8449    /// `fieldID` must not be from a static field
8450    /// `fieldID` must refer to a field that is a double.
8451    ///
8452    pub unsafe fn SetDoubleField(&self, obj: jobject, fieldID: jfieldID, value: jdouble) {
8453        unsafe {
8454            #[cfg(feature = "asserts")]
8455            {
8456                self.check_not_critical("SetDoubleField");
8457                self.check_no_exception("SetDoubleField");
8458                self.check_field_type_object("SetDoubleField", obj, fieldID, "double");
8459            }
8460            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jdouble)>(112)(self.vtable, obj, fieldID, value);
8461        }
8462    }
8463
8464    ///
8465    /// Gets the method id of a non-static method
8466    ///
8467    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetMethodID>
8468    ///
8469    ///
8470    /// # Arguments
8471    /// * `clazz` - reference to the clazz where the field is declared in.
8472    ///     * must be valid
8473    ///     * must not be null
8474    ///     * must not be already garbage collected
8475    /// * `name` - name of the method
8476    ///     * must not be null
8477    ///     * must be zero terminated utf-8
8478    /// * `sig` - jni signature of the method
8479    ///     * must not be null
8480    ///     * must be zero terminated utf-8
8481    ///
8482    /// # Returns
8483    /// A non-null field handle or null on error.
8484    /// The field handle can be assumed to be constant for the given class and must not be freed.
8485    /// It can also be safely shared with any thread or stored in a constant.
8486    ///
8487    /// # Throws Java Exception
8488    /// * `NoSuchMethodError` - method with the given name and sig doesn't exist in the class
8489    /// * `ExceptionInInitializerError` - Exception occurs in initializer of the class
8490    /// * `OutOfMemoryError` - if the jvm runs out of memory
8491    ///
8492    ///
8493    /// # Panics
8494    /// if asserts feature is enabled and UB was detected
8495    ///
8496    /// # Safety
8497    ///
8498    /// Current thread must not be detached from JNI.
8499    ///
8500    /// Current thread must not be currently throwing an exception.
8501    ///
8502    /// Current thread does not hold a critical reference.
8503    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8504    ///
8505    /// `clazz` must a valid reference to a class that is not already garbage collected.
8506    /// `name` must be non-null and zero terminated utf-8.
8507    /// `sig` must be non-null and zero terminated utf-8.
8508    ///
8509    pub unsafe fn GetMethodID(&self, class: jclass, name: impl UseCString, sig: impl UseCString) -> jmethodID {
8510        unsafe {
8511            name.use_as_const_c_char(|name| {
8512                sig.use_as_const_c_char(|sig| {
8513                    #[cfg(feature = "asserts")]
8514                    {
8515                        self.check_not_critical("GetMethodID");
8516                        self.check_no_exception("GetMethodID");
8517                        assert!(!name.is_null(), "GetMethodID name is null");
8518                        assert!(!sig.is_null(), "GetMethodID sig is null");
8519                        self.check_is_class("GetMethodID", class);
8520                    }
8521                    self.jni::<extern "system" fn(JNIEnvVTable, jobject, *const c_char, *const c_char) -> jmethodID>(33)(self.vtable, class, name, sig)
8522                })
8523            })
8524        }
8525    }
8526
8527    ///
8528    /// Calls a non-static java method that returns void
8529    ///
8530    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
8531    ///
8532    ///
8533    /// # Arguments
8534    /// * `obj` - which object the method should be called on
8535    ///     * must be valid
8536    ///     * must not be null
8537    ///     * must not be already garbage collected
8538    ///
8539    /// * `methodID` - method id of the method
8540    ///     * must not be null
8541    ///     * must be valid
8542    ///     * must not be a static
8543    ///     * must actually be a method of `obj`
8544    ///
8545    /// * `args` - argument pointer
8546    ///     * can be null if the method has no arguments
8547    ///     * must not be null otherwise and point to the exact number of arguments the method expects
8548    ///
8549    /// # Throws Java Exception
8550    /// * Whatever the method threw
8551    ///
8552    ///
8553    /// # Panics
8554    /// if asserts feature is enabled and UB was detected
8555    ///
8556    /// # Safety
8557    ///
8558    /// Current thread must not be detached from JNI.
8559    ///
8560    /// Current thread must not be currently throwing an exception.
8561    ///
8562    /// Current thread does not hold a critical reference.
8563    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8564    ///
8565    /// `obj` must a valid and not already garbage collected.
8566    /// `methodID` must be valid, non-static and actually be a method of `obj` and return void
8567    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
8568    /// `args` union must contain types that match the java methods parameters.
8569    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
8570    ///
8571    pub unsafe fn CallVoidMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) {
8572        unsafe {
8573            #[cfg(feature = "asserts")]
8574            {
8575                self.check_not_critical("CallVoidMethodA");
8576                self.check_no_exception("CallVoidMethodA");
8577                self.check_return_type_object("CallVoidMethodA", obj, methodID, "void");
8578            }
8579            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype)>(63)(self.vtable, obj, methodID, args);
8580        }
8581    }
8582
8583    ///
8584    /// Calls a non-static java method that has 0 arguments and returns void
8585    ///
8586    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
8587    ///
8588    ///
8589    /// # Arguments
8590    /// * `obj` - which object the method should be called on
8591    ///     * must be valid
8592    ///     * must not be null
8593    ///     * must not be already garbage collected
8594    ///
8595    /// * `methodID` - method id of the method
8596    ///     * must not be null
8597    ///     * must be valid
8598    ///     * must not be a static
8599    ///     * must actually be a method of `obj`
8600    ///     * must refer to a method with 0 arguments
8601    ///
8602    /// # Throws Java Exception
8603    /// * Whatever the method threw
8604    ///
8605    ///
8606    /// # Panics
8607    /// if asserts feature is enabled and UB was detected
8608    ///
8609    /// # Safety
8610    ///
8611    /// Current thread must not be detached from JNI.
8612    ///
8613    /// Current thread must not be currently throwing an exception.
8614    ///
8615    /// Current thread does not hold a critical reference.
8616    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8617    ///
8618    /// `obj` must a valid and not already garbage collected.
8619    /// `methodID` must be valid, non-static and actually be a method of `obj`, return void and have no parameters
8620    ///
8621    pub unsafe fn CallVoidMethod0(&self, obj: jobject, methodID: jmethodID) {
8622        unsafe {
8623            #[cfg(feature = "asserts")]
8624            {
8625                self.check_not_critical("CallVoidMethod");
8626                self.check_no_exception("CallVoidMethod");
8627                self.check_return_type_object("CallVoidMethod", obj, methodID, "void");
8628            }
8629            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID)>(61)(self.vtable, obj, methodID);
8630        }
8631    }
8632
8633    ///
8634    /// Calls a non-static java method that has 1 arguments and returns void
8635    ///
8636    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
8637    ///
8638    ///
8639    /// # Arguments
8640    /// * `obj` - which object the method should be called on
8641    ///     * must be valid
8642    ///     * must not be null
8643    ///     * must not be already garbage collected
8644    ///
8645    /// * `methodID` - method id of the method
8646    ///     * must not be null
8647    ///     * must be valid
8648    ///     * must not be a static
8649    ///     * must actually be a method of `obj`
8650    ///     * must refer to a method with 1 arguments
8651    ///
8652    /// # Throws Java Exception
8653    /// * Whatever the method threw
8654    ///
8655    ///
8656    /// # Panics
8657    /// if asserts feature is enabled and UB was detected
8658    ///
8659    /// # Safety
8660    ///
8661    /// Current thread must not be detached from JNI.
8662    ///
8663    /// Current thread must not be currently throwing an exception.
8664    ///
8665    /// Current thread does not hold a critical reference.
8666    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8667    ///
8668    /// `obj` must a valid and not already garbage collected.
8669    /// `methodID` must be valid, non-static and actually be a method of `obj`, return void and have 1 arguments
8670    ///
8671    pub unsafe fn CallVoidMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) {
8672        unsafe {
8673            #[cfg(feature = "asserts")]
8674            {
8675                self.check_not_critical("CallVoidMethod");
8676                self.check_no_exception("CallVoidMethod");
8677                self.check_return_type_object("CallVoidMethod", obj, methodID, "void");
8678                self.check_parameter_types_object("CallVoidMethod", obj, methodID, arg1, 0, 1);
8679            }
8680            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...)>(61)(self.vtable, obj, methodID, arg1);
8681        }
8682    }
8683
8684    ///
8685    /// Calls a non-static java method that has 2 arguments and returns void
8686    ///
8687    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
8688    ///
8689    ///
8690    /// # Arguments
8691    /// * `obj` - which object the method should be called on
8692    ///     * must be valid
8693    ///     * must not be null
8694    ///     * must not be already garbage collected
8695    ///
8696    /// * `methodID` - method id of the method
8697    ///     * must not be null
8698    ///     * must be valid
8699    ///     * must not be a static
8700    ///     * must actually be a method of `obj`
8701    ///     * must refer to a method with 2 arguments
8702    ///
8703    /// # Throws Java Exception
8704    /// * Whatever the method threw
8705    ///
8706    ///
8707    /// # Panics
8708    /// if asserts feature is enabled and UB was detected
8709    ///
8710    /// # Safety
8711    ///
8712    /// Current thread must not be detached from JNI.
8713    ///
8714    /// Current thread must not be currently throwing an exception.
8715    ///
8716    /// Current thread does not hold a critical reference.
8717    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8718    ///
8719    /// `obj` must a valid and not already garbage collected.
8720    /// `methodID` must be valid, non-static and actually be a method of `obj`, return void and have 2 arguments
8721    ///
8722    pub unsafe fn CallVoidMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) {
8723        unsafe {
8724            #[cfg(feature = "asserts")]
8725            {
8726                self.check_not_critical("CallVoidMethod");
8727                self.check_no_exception("CallVoidMethod");
8728                self.check_return_type_object("CallVoidMethod", obj, methodID, "void");
8729                self.check_parameter_types_object("CallVoidMethod", obj, methodID, arg1, 0, 2);
8730                self.check_parameter_types_object("CallVoidMethod", obj, methodID, arg2, 1, 2);
8731            }
8732            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...)>(61)(self.vtable, obj, methodID, arg1, arg2);
8733        }
8734    }
8735
8736    ///
8737    /// Calls a non-static java method that has 3 arguments and returns void
8738    ///
8739    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
8740    ///
8741    ///
8742    /// # Arguments
8743    /// * `obj` - which object the method should be called on
8744    ///     * must be valid
8745    ///     * must not be null
8746    ///     * must not be already garbage collected
8747    ///
8748    /// * `methodID` - method id of the method
8749    ///     * must not be null
8750    ///     * must be valid
8751    ///     * must not be a static
8752    ///     * must actually be a method of `obj`
8753    ///     * must refer to a method with 3 arguments
8754    ///
8755    /// # Throws Java Exception
8756    /// * Whatever the method threw
8757    ///
8758    ///
8759    /// # Panics
8760    /// if asserts feature is enabled and UB was detected
8761    ///
8762    /// # Safety
8763    ///
8764    /// Current thread must not be detached from JNI.
8765    ///
8766    /// Current thread must not be currently throwing an exception.
8767    ///
8768    /// Current thread does not hold a critical reference.
8769    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8770    ///
8771    /// `obj` must a valid and not already garbage collected.
8772    /// `methodID` must be valid, non-static and actually be a method of `obj`, return void and have 3 arguments
8773    ///
8774    pub unsafe fn CallVoidMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) {
8775        unsafe {
8776            #[cfg(feature = "asserts")]
8777            {
8778                self.check_not_critical("CallVoidMethod");
8779                self.check_no_exception("CallVoidMethod");
8780                self.check_return_type_object("CallVoidMethod", obj, methodID, "void");
8781                self.check_parameter_types_object("CallVoidMethod", obj, methodID, arg1, 0, 3);
8782                self.check_parameter_types_object("CallVoidMethod", obj, methodID, arg2, 1, 3);
8783                self.check_parameter_types_object("CallVoidMethod", obj, methodID, arg3, 2, 3);
8784            }
8785            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...)>(61)(self.vtable, obj, methodID, arg1, arg2, arg3);
8786        }
8787    }
8788
8789    ///
8790    /// Calls a non-static java method that returns an object
8791    ///
8792    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
8793    ///
8794    ///
8795    /// # Arguments
8796    /// * `obj` - which object the method should be called on
8797    ///     * must be valid
8798    ///     * must not be null
8799    ///     * must not be already garbage collected
8800    ///
8801    /// * `methodID` - method id of the method
8802    ///     * must not be null
8803    ///     * must be valid
8804    ///     * must not be a static
8805    ///     * must actually be a method of `obj`
8806    ///
8807    /// * `args` - argument pointer
8808    ///     * can be null if the method has no arguments
8809    ///     * must not be null otherwise and point to the exact number of arguments the method expects
8810    ///
8811    /// # Returns
8812    /// Whatever the method returned or null if it threw
8813    ///
8814    /// # Throws Java Exception
8815    /// * Whatever the method threw
8816    ///
8817    ///
8818    /// # Panics
8819    /// if asserts feature is enabled and UB was detected
8820    ///
8821    /// # Safety
8822    ///
8823    /// Current thread must not be detached from JNI.
8824    ///
8825    /// Current thread must not be currently throwing an exception.
8826    ///
8827    /// Current thread does not hold a critical reference.
8828    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8829    ///
8830    /// `obj` must a valid and not already garbage collected.
8831    /// `methodID` must be valid, non-static and actually be a method of `obj` and return an object
8832    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
8833    /// `args` union must contain types that match the java methods parameters.
8834    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
8835    ///
8836    pub unsafe fn CallObjectMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) -> jobject {
8837        unsafe {
8838            #[cfg(feature = "asserts")]
8839            {
8840                self.check_not_critical("CallObjectMethodA");
8841                self.check_no_exception("CallObjectMethodA");
8842                self.check_return_type_object("CallObjectMethodA", obj, methodID, "object");
8843            }
8844            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, obj, methodID, args)
8845        }
8846    }
8847
8848    ///
8849    /// Calls a non-static java method that has 0 arguments and returns an object
8850    ///
8851    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
8852    ///
8853    ///
8854    /// # Arguments
8855    /// * `obj` - which object the method should be called on
8856    ///     * must be valid
8857    ///     * must not be null
8858    ///     * must not be already garbage collected
8859    ///
8860    /// * `methodID` - method id of the method
8861    ///     * must not be null
8862    ///     * must be valid
8863    ///     * must not be a static
8864    ///     * must actually be a method of `obj`
8865    ///     * must refer to a method with 0 arguments
8866    ///
8867    /// # Returns
8868    /// Whatever the method returned or null if it threw
8869    ///
8870    /// # Throws Java Exception
8871    /// * Whatever the method threw
8872    ///
8873    ///
8874    /// # Panics
8875    /// if asserts feature is enabled and UB was detected
8876    ///
8877    /// # Safety
8878    ///
8879    /// Current thread must not be detached from JNI.
8880    ///
8881    /// Current thread must not be currently throwing an exception.
8882    ///
8883    /// Current thread does not hold a critical reference.
8884    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8885    ///
8886    /// `obj` must a valid and not already garbage collected.
8887    /// `methodID` must be valid, non-static and actually be a method of `obj`, return an object and have no parameters
8888    ///
8889    pub unsafe fn CallObjectMethod0(&self, obj: jobject, methodID: jmethodID) -> jobject {
8890        unsafe {
8891            #[cfg(feature = "asserts")]
8892            {
8893                self.check_not_critical("CallObjectMethod");
8894                self.check_no_exception("CallObjectMethod");
8895                self.check_return_type_object("CallObjectMethod", obj, methodID, "object");
8896            }
8897            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jobject>(34)(self.vtable, obj, methodID)
8898        }
8899    }
8900
8901    ///
8902    /// Calls a non-static java method that has 1 arguments and returns an object
8903    ///
8904    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
8905    ///
8906    ///
8907    /// # Arguments
8908    /// * `obj` - which object the method should be called on
8909    ///     * must be valid
8910    ///     * must not be null
8911    ///     * must not be already garbage collected
8912    ///
8913    /// * `methodID` - method id of the method
8914    ///     * must not be null
8915    ///     * must be valid
8916    ///     * must not be a static
8917    ///     * must actually be a method of `obj`
8918    ///     * must refer to a method with 1 arguments
8919    ///
8920    /// # Returns
8921    /// Whatever the method returned or null if it threw
8922    ///
8923    /// # Throws Java Exception
8924    /// * Whatever the method threw
8925    ///
8926    ///
8927    /// # Panics
8928    /// if asserts feature is enabled and UB was detected
8929    ///
8930    /// # Safety
8931    ///
8932    /// Current thread must not be detached from JNI.
8933    ///
8934    /// Current thread must not be currently throwing an exception.
8935    ///
8936    /// Current thread does not hold a critical reference.
8937    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8938    ///
8939    /// `obj` must a valid and not already garbage collected.
8940    /// `methodID` must be valid, non-static and actually be a method of `obj`, return an object and have 1 arguments
8941    ///
8942    pub unsafe fn CallObjectMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) -> jobject {
8943        unsafe {
8944            #[cfg(feature = "asserts")]
8945            {
8946                self.check_not_critical("CallObjectMethod");
8947                self.check_no_exception("CallObjectMethod");
8948                self.check_return_type_object("CallObjectMethod", obj, methodID, "object");
8949                self.check_parameter_types_object("CallObjectMethod", obj, methodID, arg1, 0, 1);
8950            }
8951            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jobject>(34)(self.vtable, obj, methodID, arg1)
8952        }
8953    }
8954
8955    ///
8956    /// Calls a non-static java method that has 2 arguments and returns an object
8957    ///
8958    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
8959    ///
8960    ///
8961    /// # Arguments
8962    /// * `obj` - which object the method should be called on
8963    ///     * must be valid
8964    ///     * must not be null
8965    ///     * must not be already garbage collected
8966    ///
8967    /// * `methodID` - method id of the method
8968    ///     * must not be null
8969    ///     * must be valid
8970    ///     * must not be a static
8971    ///     * must actually be a method of `obj`
8972    ///     * must refer to a method with 2 arguments
8973    ///
8974    /// # Returns
8975    /// Whatever the method returned or null if it threw
8976    ///
8977    /// # Throws Java Exception
8978    /// * Whatever the method threw
8979    ///
8980    ///
8981    /// # Panics
8982    /// if asserts feature is enabled and UB was detected
8983    ///
8984    /// # Safety
8985    ///
8986    /// Current thread must not be detached from JNI.
8987    ///
8988    /// Current thread must not be currently throwing an exception.
8989    ///
8990    /// Current thread does not hold a critical reference.
8991    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
8992    ///
8993    /// `obj` must a valid and not already garbage collected.
8994    /// `methodID` must be valid, non-static and actually be a method of `obj`, return an object and have 2 arguments
8995    ///
8996    pub unsafe fn CallObjectMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) -> jobject {
8997        unsafe {
8998            #[cfg(feature = "asserts")]
8999            {
9000                self.check_not_critical("CallObjectMethod");
9001                self.check_no_exception("CallObjectMethod");
9002                self.check_return_type_object("CallObjectMethod", obj, methodID, "object");
9003                self.check_parameter_types_object("CallObjectMethod", obj, methodID, arg1, 0, 2);
9004                self.check_parameter_types_object("CallObjectMethod", obj, methodID, arg2, 1, 2);
9005            }
9006            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jobject>(34)(self.vtable, obj, methodID, arg1, arg2)
9007        }
9008    }
9009
9010    ///
9011    /// Calls a non-static java method that has 3 arguments and returns an object
9012    ///
9013    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9014    ///
9015    ///
9016    /// # Arguments
9017    /// * `obj` - which object the method should be called on
9018    ///     * must be valid
9019    ///     * must not be null
9020    ///     * must not be already garbage collected
9021    ///
9022    /// * `methodID` - method id of the method
9023    ///     * must not be null
9024    ///     * must be valid
9025    ///     * must not be a static
9026    ///     * must actually be a method of `obj`
9027    ///     * must refer to a method with 3 arguments
9028    ///
9029    /// # Returns
9030    /// Whatever the method returned or null if it threw
9031    ///
9032    /// # Throws Java Exception
9033    /// * Whatever the method threw
9034    ///
9035    ///
9036    /// # Panics
9037    /// if asserts feature is enabled and UB was detected
9038    ///
9039    /// # Safety
9040    ///
9041    /// Current thread must not be detached from JNI.
9042    ///
9043    /// Current thread must not be currently throwing an exception.
9044    ///
9045    /// Current thread does not hold a critical reference.
9046    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9047    ///
9048    /// `obj` must a valid and not already garbage collected.
9049    /// `methodID` must be valid, non-static and actually be a method of `obj`, return an object and have 3 arguments
9050    ///
9051    pub unsafe fn CallObjectMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jobject {
9052        unsafe {
9053            #[cfg(feature = "asserts")]
9054            {
9055                self.check_not_critical("CallObjectMethod");
9056                self.check_no_exception("CallObjectMethod");
9057                self.check_return_type_object("CallObjectMethod", obj, methodID, "object");
9058                self.check_parameter_types_object("CallObjectMethod", obj, methodID, arg1, 0, 3);
9059                self.check_parameter_types_object("CallObjectMethod", obj, methodID, arg2, 1, 3);
9060                self.check_parameter_types_object("CallObjectMethod", obj, methodID, arg3, 2, 3);
9061            }
9062            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jobject>(34)(self.vtable, obj, methodID, arg1, arg2, arg3)
9063        }
9064    }
9065
9066    ///
9067    /// Calls a non-static java method that returns a boolean
9068    ///
9069    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9070    ///
9071    ///
9072    /// # Arguments
9073    /// * `obj` - which object the method should be called on
9074    ///     * must be valid
9075    ///     * must not be null
9076    ///     * must not be already garbage collected
9077    ///
9078    /// * `methodID` - method id of the method
9079    ///     * must not be null
9080    ///     * must be valid
9081    ///     * must not be a static
9082    ///     * must actually be a method of `obj`
9083    ///
9084    /// * `args` - argument pointer
9085    ///     * can be null if the method has no arguments
9086    ///     * must not be null otherwise and point to the exact number of arguments the method expects
9087    ///
9088    /// # Returns
9089    /// Whatever the method returned or false if it threw
9090    ///
9091    /// # Throws Java Exception
9092    /// * Whatever the method threw
9093    ///
9094    ///
9095    /// # Panics
9096    /// if asserts feature is enabled and UB was detected
9097    ///
9098    /// # Safety
9099    ///
9100    /// Current thread must not be detached from JNI.
9101    ///
9102    /// Current thread must not be currently throwing an exception.
9103    ///
9104    /// Current thread does not hold a critical reference.
9105    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9106    ///
9107    /// `obj` must a valid and not already garbage collected.
9108    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a boolean
9109    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
9110    /// `args` union must contain types that match the java methods parameters.
9111    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
9112    ///
9113    pub unsafe fn CallBooleanMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) -> jboolean {
9114        unsafe {
9115            #[cfg(feature = "asserts")]
9116            {
9117                self.check_not_critical("CallBooleanMethodA");
9118                self.check_no_exception("CallBooleanMethodA");
9119                self.check_return_type_object("CallBooleanMethodA", obj, methodID, "boolean");
9120            }
9121            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jboolean>(39)(self.vtable, obj, methodID, args)
9122        }
9123    }
9124
9125    ///
9126    /// Calls a non-static java method that has 0 arguments and returns boolean
9127    ///
9128    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9129    ///
9130    ///
9131    /// # Arguments
9132    /// * `obj` - which object the method should be called on
9133    ///     * must be valid
9134    ///     * must not be null
9135    ///     * must not be already garbage collected
9136    ///
9137    /// * `methodID` - method id of the method
9138    ///     * must not be null
9139    ///     * must be valid
9140    ///     * must not be a static
9141    ///     * must actually be a method of `obj`
9142    ///     * must refer to a method with 0 arguments
9143    ///
9144    /// # Returns
9145    /// Whatever the method returned or false if it threw
9146    ///
9147    /// # Throws Java Exception
9148    /// * Whatever the method threw
9149    ///
9150    ///
9151    /// # Panics
9152    /// if asserts feature is enabled and UB was detected
9153    ///
9154    /// # Safety
9155    ///
9156    /// Current thread must not be detached from JNI.
9157    ///
9158    /// Current thread must not be currently throwing an exception.
9159    ///
9160    /// Current thread does not hold a critical reference.
9161    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9162    ///
9163    /// `obj` must a valid and not already garbage collected.
9164    /// `methodID` must be valid, non-static and actually be a method of `obj`, return boolean and have no parameters
9165    ///
9166    pub unsafe fn CallBooleanMethod0(&self, obj: jobject, methodID: jmethodID) -> jboolean {
9167        unsafe {
9168            #[cfg(feature = "asserts")]
9169            {
9170                self.check_not_critical("CallBooleanMethod");
9171                self.check_no_exception("CallBooleanMethod");
9172                self.check_return_type_object("CallBooleanMethod", obj, methodID, "boolean");
9173            }
9174            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jboolean>(37)(self.vtable, obj, methodID)
9175        }
9176    }
9177
9178    ///
9179    /// Calls a non-static java method that has 1 arguments and returns boolean
9180    ///
9181    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9182    ///
9183    ///
9184    /// # Arguments
9185    /// * `obj` - which object the method should be called on
9186    ///     * must be valid
9187    ///     * must not be null
9188    ///     * must not be already garbage collected
9189    ///
9190    /// * `methodID` - method id of the method
9191    ///     * must not be null
9192    ///     * must be valid
9193    ///     * must not be a static
9194    ///     * must actually be a method of `obj`
9195    ///     * must refer to a method with 1 arguments
9196    ///
9197    /// # Returns
9198    /// Whatever the method returned or false if it threw
9199    ///
9200    /// # Throws Java Exception
9201    /// * Whatever the method threw
9202    ///
9203    ///
9204    /// # Panics
9205    /// if asserts feature is enabled and UB was detected
9206    ///
9207    /// # Safety
9208    ///
9209    /// Current thread must not be detached from JNI.
9210    ///
9211    /// Current thread must not be currently throwing an exception.
9212    ///
9213    /// Current thread does not hold a critical reference.
9214    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9215    ///
9216    /// `obj` must a valid and not already garbage collected.
9217    /// `methodID` must be valid, non-static and actually be a method of `obj`, return boolean and have 1 parameter
9218    /// The parameter types must exactly match the java method parameters.
9219    ///
9220    pub unsafe fn CallBooleanMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) -> jboolean {
9221        unsafe {
9222            #[cfg(feature = "asserts")]
9223            {
9224                self.check_not_critical("CallBooleanMethod");
9225                self.check_no_exception("CallBooleanMethod");
9226                self.check_return_type_object("CallBooleanMethod", obj, methodID, "boolean");
9227                self.check_parameter_types_object("CallBooleanMethod", obj, methodID, arg1, 0, 1);
9228            }
9229            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jboolean>(37)(self.vtable, obj, methodID, arg1)
9230        }
9231    }
9232
9233    ///
9234    /// Calls a non-static java method that has 2 arguments and returns boolean
9235    ///
9236    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9237    ///
9238    ///
9239    /// # Arguments
9240    /// * `obj` - which object the method should be called on
9241    ///     * must be valid
9242    ///     * must not be null
9243    ///     * must not be already garbage collected
9244    ///
9245    /// * `methodID` - method id of the method
9246    ///     * must not be null
9247    ///     * must be valid
9248    ///     * must not be a static
9249    ///     * must actually be a method of `obj`
9250    ///     * must refer to a method with 2 arguments
9251    ///
9252    /// # Returns
9253    /// Whatever the method returned or false if it threw
9254    ///
9255    /// # Throws Java Exception
9256    /// * Whatever the method threw
9257    ///
9258    ///
9259    /// # Panics
9260    /// if asserts feature is enabled and UB was detected
9261    ///
9262    /// # Safety
9263    ///
9264    /// Current thread must not be detached from JNI.
9265    ///
9266    /// Current thread must not be currently throwing an exception.
9267    ///
9268    /// Current thread does not hold a critical reference.
9269    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9270    ///
9271    /// `obj` must a valid and not already garbage collected.
9272    /// `methodID` must be valid, non-static and actually be a method of `obj`, return boolean and have 2 parameter
9273    /// The parameter types must exactly match the java method parameters.
9274    ///
9275    pub unsafe fn CallBooleanMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) -> jboolean {
9276        unsafe {
9277            #[cfg(feature = "asserts")]
9278            {
9279                self.check_not_critical("CallBooleanMethod");
9280                self.check_no_exception("CallBooleanMethod");
9281                self.check_return_type_object("CallBooleanMethod", obj, methodID, "boolean");
9282                self.check_parameter_types_object("CallBooleanMethod", obj, methodID, arg1, 0, 2);
9283                self.check_parameter_types_object("CallBooleanMethod", obj, methodID, arg2, 1, 2);
9284            }
9285            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jboolean>(37)(self.vtable, obj, methodID, arg1, arg2)
9286        }
9287    }
9288
9289    ///
9290    /// Calls a non-static java method that has 3 arguments and returns boolean
9291    ///
9292    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9293    ///
9294    ///
9295    /// # Arguments
9296    /// * `obj` - which object the method should be called on
9297    ///     * must be valid
9298    ///     * must not be null
9299    ///     * must not be already garbage collected
9300    ///
9301    /// * `methodID` - method id of the method
9302    ///     * must not be null
9303    ///     * must be valid
9304    ///     * must not be a static
9305    ///     * must actually be a method of `obj`
9306    ///     * must refer to a method with 3 arguments
9307    ///
9308    /// # Returns
9309    /// Whatever the method returned or false if it threw
9310    ///
9311    /// # Throws Java Exception
9312    /// * Whatever the method threw
9313    ///
9314    ///
9315    /// # Panics
9316    /// if asserts feature is enabled and UB was detected
9317    ///
9318    /// # Safety
9319    ///
9320    /// Current thread must not be detached from JNI.
9321    ///
9322    /// Current thread must not be currently throwing an exception.
9323    ///
9324    /// Current thread does not hold a critical reference.
9325    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9326    ///
9327    /// `obj` must a valid and not already garbage collected.
9328    /// `methodID` must be valid, non-static and actually be a method of `obj`, return boolean and have 3 parameter
9329    /// The parameter types must exactly match the java method parameters.
9330    ///
9331    pub unsafe fn CallBooleanMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jboolean {
9332        unsafe {
9333            #[cfg(feature = "asserts")]
9334            {
9335                self.check_not_critical("CallBooleanMethod");
9336                self.check_no_exception("CallBooleanMethod");
9337                self.check_return_type_object("CallBooleanMethod", obj, methodID, "boolean");
9338                self.check_parameter_types_object("CallBooleanMethod", obj, methodID, arg1, 0, 3);
9339                self.check_parameter_types_object("CallBooleanMethod", obj, methodID, arg2, 1, 3);
9340                self.check_parameter_types_object("CallBooleanMethod", obj, methodID, arg3, 2, 3);
9341            }
9342            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jboolean>(37)(self.vtable, obj, methodID, arg1, arg2, arg3)
9343        }
9344    }
9345
9346    ///
9347    /// Calls a non-static java method that returns a byte
9348    ///
9349    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9350    ///
9351    ///
9352    /// # Arguments
9353    /// * `obj` - which object the method should be called on
9354    ///     * must be valid
9355    ///     * must not be null
9356    ///     * must not be already garbage collected
9357    ///
9358    /// * `methodID` - method id of the method
9359    ///     * must not be null
9360    ///     * must be valid
9361    ///     * must not be a static
9362    ///     * must actually be a method of `obj`
9363    ///
9364    /// * `args` - argument pointer
9365    ///     * can be null if the method has no arguments
9366    ///     * must not be null otherwise and point to the exact number of arguments the method expects
9367    ///
9368    /// # Returns
9369    /// Whatever the method returned or 0 if it threw
9370    ///
9371    /// # Throws Java Exception
9372    /// * Whatever the method threw
9373    ///
9374    ///
9375    /// # Panics
9376    /// if asserts feature is enabled and UB was detected
9377    ///
9378    /// # Safety
9379    ///
9380    /// Current thread must not be detached from JNI.
9381    ///
9382    /// Current thread must not be currently throwing an exception.
9383    ///
9384    /// Current thread does not hold a critical reference.
9385    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9386    ///
9387    /// `obj` must a valid and not already garbage collected.
9388    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a byte
9389    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
9390    /// `args` union must contain types that match the java methods parameters.
9391    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
9392    ///
9393    pub unsafe fn CallByteMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) -> jbyte {
9394        unsafe {
9395            #[cfg(feature = "asserts")]
9396            {
9397                self.check_not_critical("CallByteMethodA");
9398                self.check_no_exception("CallByteMethodA");
9399                self.check_return_type_object("CallByteMethodA", obj, methodID, "byte");
9400            }
9401            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jbyte>(42)(self.vtable, obj, methodID, args)
9402        }
9403    }
9404
9405    ///
9406    /// Calls a non-static java method that has 0 arguments and returns byte
9407    ///
9408    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9409    ///
9410    ///
9411    /// # Arguments
9412    /// * `obj` - which object the method should be called on
9413    ///     * must be valid
9414    ///     * must not be null
9415    ///     * must not be already garbage collected
9416    ///
9417    /// * `methodID` - method id of the method
9418    ///     * must not be null
9419    ///     * must be valid
9420    ///     * must not be a static
9421    ///     * must actually be a method of `obj`
9422    ///     * must refer to a method with 0 arguments
9423    ///
9424    /// # Returns
9425    /// Whatever the method returned or 0 if it threw
9426    ///
9427    /// # Throws Java Exception
9428    /// * Whatever the method threw
9429    ///
9430    ///
9431    /// # Panics
9432    /// if asserts feature is enabled and UB was detected
9433    ///
9434    /// # Safety
9435    ///
9436    /// Current thread must not be detached from JNI.
9437    ///
9438    /// Current thread must not be currently throwing an exception.
9439    ///
9440    /// Current thread does not hold a critical reference.
9441    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9442    ///
9443    /// `obj` must a valid and not already garbage collected.
9444    /// `methodID` must be valid, non-static and actually be a method of `obj`, return byte and have no parameters
9445    ///
9446    pub unsafe fn CallByteMethod0(&self, obj: jobject, methodID: jmethodID) -> jbyte {
9447        unsafe {
9448            #[cfg(feature = "asserts")]
9449            {
9450                self.check_not_critical("CallByteMethod0");
9451                self.check_no_exception("CallByteMethod0");
9452                self.check_return_type_object("CallByteMethod0", obj, methodID, "byte");
9453            }
9454            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jbyte>(40)(self.vtable, obj, methodID)
9455        }
9456    }
9457
9458    ///
9459    /// Calls a non-static java method that has 1 arguments and returns byte
9460    ///
9461    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9462    ///
9463    ///
9464    /// # Arguments
9465    /// * `obj` - which object the method should be called on
9466    ///     * must be valid
9467    ///     * must not be null
9468    ///     * must not be already garbage collected
9469    ///
9470    /// * `methodID` - method id of the method
9471    ///     * must not be null
9472    ///     * must be valid
9473    ///     * must not be a static
9474    ///     * must actually be a method of `obj`
9475    ///     * must refer to a method with 1 arguments
9476    ///
9477    /// # Returns
9478    /// Whatever the method returned or 0 if it threw
9479    ///
9480    /// # Throws Java Exception
9481    /// * Whatever the method threw
9482    ///
9483    ///
9484    /// # Panics
9485    /// if asserts feature is enabled and UB was detected
9486    ///
9487    /// # Safety
9488    ///
9489    /// Current thread must not be detached from JNI.
9490    ///
9491    /// Current thread must not be currently throwing an exception.
9492    ///
9493    /// Current thread does not hold a critical reference.
9494    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9495    ///
9496    /// `obj` must a valid and not already garbage collected.
9497    /// `methodID` must be valid, non-static and actually be a method of `obj`, return byte and have 1 parameter
9498    /// The parameter types must exactly match the java method parameters.
9499    ///
9500    pub unsafe fn CallByteMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) -> jbyte {
9501        unsafe {
9502            #[cfg(feature = "asserts")]
9503            {
9504                self.check_not_critical("CallByteMethod1");
9505                self.check_no_exception("CallByteMethod1");
9506                self.check_return_type_object("CallByteMethod1", obj, methodID, "byte");
9507                self.check_parameter_types_object("CallByteMethod1", obj, methodID, arg1, 0, 1);
9508            }
9509            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jbyte>(40)(self.vtable, obj, methodID, arg1)
9510        }
9511    }
9512
9513    ///
9514    /// Calls a non-static java method that has 2 arguments and returns byte
9515    ///
9516    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9517    ///
9518    ///
9519    /// # Arguments
9520    /// * `obj` - which object the method should be called on
9521    ///     * must be valid
9522    ///     * must not be null
9523    ///     * must not be already garbage collected
9524    ///
9525    /// * `methodID` - method id of the method
9526    ///     * must not be null
9527    ///     * must be valid
9528    ///     * must not be a static
9529    ///     * must actually be a method of `obj`
9530    ///     * must refer to a method with 2 arguments
9531    ///
9532    /// # Returns
9533    /// Whatever the method returned or 0 if it threw
9534    ///
9535    /// # Throws Java Exception
9536    /// * Whatever the method threw
9537    ///
9538    ///
9539    /// # Panics
9540    /// if asserts feature is enabled and UB was detected
9541    ///
9542    /// # Safety
9543    ///
9544    /// Current thread must not be detached from JNI.
9545    ///
9546    /// Current thread must not be currently throwing an exception.
9547    ///
9548    /// Current thread does not hold a critical reference.
9549    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9550    ///
9551    /// `obj` must a valid and not already garbage collected.
9552    /// `methodID` must be valid, non-static and actually be a method of `obj`, return byte and have 2 parameter
9553    /// The parameter types must exactly match the java method parameters.
9554    ///
9555    pub unsafe fn CallByteMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) -> jbyte {
9556        unsafe {
9557            #[cfg(feature = "asserts")]
9558            {
9559                self.check_not_critical("CallByteMethod2");
9560                self.check_no_exception("CallByteMethod2");
9561                self.check_return_type_object("CallByteMethod2", obj, methodID, "byte");
9562                self.check_parameter_types_object("CallByteMethod2", obj, methodID, arg1, 0, 2);
9563                self.check_parameter_types_object("CallByteMethod2", obj, methodID, arg2, 1, 2);
9564            }
9565            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jbyte>(40)(self.vtable, obj, methodID, arg1, arg2)
9566        }
9567    }
9568
9569    ///
9570    /// Calls a non-static java method that has 3 arguments and returns byte
9571    ///
9572    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9573    ///
9574    ///
9575    /// # Arguments
9576    /// * `obj` - which object the method should be called on
9577    ///     * must be valid
9578    ///     * must not be null
9579    ///     * must not be already garbage collected
9580    ///
9581    /// * `methodID` - method id of the method
9582    ///     * must not be null
9583    ///     * must be valid
9584    ///     * must not be a static
9585    ///     * must actually be a method of `obj`
9586    ///     * must refer to a method with 3 arguments
9587    ///
9588    /// # Returns
9589    /// Whatever the method returned or 0 if it threw
9590    ///
9591    /// # Throws Java Exception
9592    /// * Whatever the method threw
9593    ///
9594    ///
9595    /// # Panics
9596    /// if asserts feature is enabled and UB was detected
9597    ///
9598    /// # Safety
9599    ///
9600    /// Current thread must not be detached from JNI.
9601    ///
9602    /// Current thread must not be currently throwing an exception.
9603    ///
9604    /// Current thread does not hold a critical reference.
9605    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9606    ///
9607    /// `obj` must a valid and not already garbage collected.
9608    /// `methodID` must be valid, non-static and actually be a method of `obj`, return byte and have 3 parameter
9609    /// The parameter types must exactly match the java method parameters.
9610    ///
9611    pub unsafe fn CallByteMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jbyte {
9612        unsafe {
9613            #[cfg(feature = "asserts")]
9614            {
9615                self.check_not_critical("CallByteMethod3");
9616                self.check_no_exception("CallByteMethod3");
9617                self.check_return_type_object("CallByteMethod3", obj, methodID, "byte");
9618                self.check_parameter_types_object("CallByteMethod3", obj, methodID, arg1, 0, 3);
9619                self.check_parameter_types_object("CallByteMethod3", obj, methodID, arg2, 1, 3);
9620                self.check_parameter_types_object("CallByteMethod3", obj, methodID, arg3, 2, 3);
9621            }
9622            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jbyte>(40)(self.vtable, obj, methodID, arg1, arg2, arg3)
9623        }
9624    }
9625
9626    ///
9627    /// Calls a non-static java method that returns a char
9628    ///
9629    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9630    ///
9631    ///
9632    /// # Arguments
9633    /// * `obj` - which object the method should be called on
9634    ///     * must be valid
9635    ///     * must not be null
9636    ///     * must not be already garbage collected
9637    ///
9638    /// * `methodID` - method id of the method
9639    ///     * must not be null
9640    ///     * must be valid
9641    ///     * must not be a static
9642    ///     * must actually be a method of `obj`
9643    ///
9644    /// * `args` - argument pointer
9645    ///     * can be null if the method has no arguments
9646    ///     * must not be null otherwise and point to the exact number of arguments the method expects
9647    ///
9648    /// # Returns
9649    /// Whatever the method returned or 0 if it threw
9650    ///
9651    /// # Throws Java Exception
9652    /// * Whatever the method threw
9653    ///
9654    ///
9655    /// # Panics
9656    /// if asserts feature is enabled and UB was detected
9657    ///
9658    /// # Safety
9659    ///
9660    /// Current thread must not be detached from JNI.
9661    ///
9662    /// Current thread must not be currently throwing an exception.
9663    ///
9664    /// Current thread does not hold a critical reference.
9665    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9666    ///
9667    /// `obj` must a valid and not already garbage collected.
9668    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a char
9669    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
9670    /// `args` union must contain types that match the java methods parameters.
9671    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
9672    ///
9673    pub unsafe fn CallCharMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) -> jchar {
9674        unsafe {
9675            #[cfg(feature = "asserts")]
9676            {
9677                self.check_not_critical("CallCharMethodA");
9678                self.check_no_exception("CallCharMethodA");
9679                self.check_return_type_object("CallCharMethodA", obj, methodID, "char");
9680            }
9681            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jchar>(45)(self.vtable, obj, methodID, args)
9682        }
9683    }
9684
9685    ///
9686    /// Calls a non-static java method that has 0 arguments and returns char
9687    ///
9688    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9689    ///
9690    ///
9691    /// # Arguments
9692    /// * `obj` - which object the method should be called on
9693    ///     * must be valid
9694    ///     * must not be null
9695    ///     * must not be already garbage collected
9696    ///
9697    /// * `methodID` - method id of the method
9698    ///     * must not be null
9699    ///     * must be valid
9700    ///     * must not be a static
9701    ///     * must actually be a method of `obj`
9702    ///     * must refer to a method with 0 arguments
9703    ///
9704    /// # Returns
9705    /// Whatever the method returned or 0 if it threw
9706    ///
9707    /// # Throws Java Exception
9708    /// * Whatever the method threw
9709    ///
9710    ///
9711    /// # Panics
9712    /// if asserts feature is enabled and UB was detected
9713    ///
9714    /// # Safety
9715    ///
9716    /// Current thread must not be detached from JNI.
9717    ///
9718    /// Current thread must not be currently throwing an exception.
9719    ///
9720    /// Current thread does not hold a critical reference.
9721    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9722    ///
9723    /// `obj` must a valid and not already garbage collected.
9724    /// `methodID` must be valid, non-static and actually be a method of `obj`, return char and have no parameters
9725    ///
9726    pub unsafe fn CallCharMethod0(&self, obj: jobject, methodID: jmethodID) -> jchar {
9727        unsafe {
9728            #[cfg(feature = "asserts")]
9729            {
9730                self.check_not_critical("CallCharMethod");
9731                self.check_no_exception("CallCharMethod");
9732                self.check_return_type_object("CallCharMethod", obj, methodID, "char");
9733            }
9734            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jchar>(43)(self.vtable, obj, methodID)
9735        }
9736    }
9737
9738    ///
9739    /// Calls a non-static java method that has 1 arguments and returns char
9740    ///
9741    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9742    ///
9743    ///
9744    /// # Arguments
9745    /// * `obj` - which object the method should be called on
9746    ///     * must be valid
9747    ///     * must not be null
9748    ///     * must not be already garbage collected
9749    ///
9750    /// * `methodID` - method id of the method
9751    ///     * must not be null
9752    ///     * must be valid
9753    ///     * must not be a static
9754    ///     * must actually be a method of `obj`
9755    ///     * must refer to a method with 1 arguments
9756    ///
9757    /// # Returns
9758    /// Whatever the method returned or 0 if it threw
9759    ///
9760    /// # Throws Java Exception
9761    /// * Whatever the method threw
9762    ///
9763    ///
9764    /// # Panics
9765    /// if asserts feature is enabled and UB was detected
9766    ///
9767    /// # Safety
9768    ///
9769    /// Current thread must not be detached from JNI.
9770    ///
9771    /// Current thread must not be currently throwing an exception.
9772    ///
9773    /// Current thread does not hold a critical reference.
9774    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9775    ///
9776    /// `obj` must a valid and not already garbage collected.
9777    /// `methodID` must be valid, non-static and actually be a method of `obj`, return char and have 1 parameter
9778    /// The parameter types must exactly match the java method parameters.
9779    ///
9780    pub unsafe fn CallCharMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) -> jchar {
9781        unsafe {
9782            #[cfg(feature = "asserts")]
9783            {
9784                self.check_not_critical("CallCharMethod");
9785                self.check_no_exception("CallCharMethod");
9786                self.check_return_type_object("CallCharMethod", obj, methodID, "char");
9787                self.check_parameter_types_object("CallCharMethod", obj, methodID, arg1, 0, 1);
9788            }
9789            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jchar>(43)(self.vtable, obj, methodID, arg1)
9790        }
9791    }
9792
9793    ///
9794    /// Calls a non-static java method that has 2 arguments and returns char
9795    ///
9796    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9797    ///
9798    ///
9799    /// # Arguments
9800    /// * `obj` - which object the method should be called on
9801    ///     * must be valid
9802    ///     * must not be null
9803    ///     * must not be already garbage collected
9804    ///
9805    /// * `methodID` - method id of the method
9806    ///     * must not be null
9807    ///     * must be valid
9808    ///     * must not be a static
9809    ///     * must actually be a method of `obj`
9810    ///     * must refer to a method with 2 arguments
9811    ///
9812    /// # Returns
9813    /// Whatever the method returned or 0 if it threw
9814    ///
9815    /// # Throws Java Exception
9816    /// * Whatever the method threw
9817    ///
9818    ///
9819    /// # Panics
9820    /// if asserts feature is enabled and UB was detected
9821    ///
9822    /// # Safety
9823    ///
9824    /// Current thread must not be detached from JNI.
9825    ///
9826    /// Current thread must not be currently throwing an exception.
9827    ///
9828    /// Current thread does not hold a critical reference.
9829    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9830    ///
9831    /// `obj` must a valid and not already garbage collected.
9832    /// `methodID` must be valid, non-static and actually be a method of `obj`, return char and have 2 parameter
9833    /// The parameter types must exactly match the java method parameters.
9834    ///
9835    pub unsafe fn CallCharMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) -> jchar {
9836        unsafe {
9837            #[cfg(feature = "asserts")]
9838            {
9839                self.check_not_critical("CallCharMethod");
9840                self.check_no_exception("CallCharMethod");
9841                self.check_return_type_object("CallCharMethod", obj, methodID, "char");
9842                self.check_parameter_types_object("CallCharMethod", obj, methodID, arg1, 0, 2);
9843                self.check_parameter_types_object("CallCharMethod", obj, methodID, arg2, 1, 2);
9844            }
9845            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jchar>(43)(self.vtable, obj, methodID, arg1, arg2)
9846        }
9847    }
9848
9849    ///
9850    /// Calls a non-static java method that has 3 arguments and returns char
9851    ///
9852    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9853    ///
9854    ///
9855    /// # Arguments
9856    /// * `obj` - which object the method should be called on
9857    ///     * must be valid
9858    ///     * must not be null
9859    ///     * must not be already garbage collected
9860    ///
9861    /// * `methodID` - method id of the method
9862    ///     * must not be null
9863    ///     * must be valid
9864    ///     * must not be a static
9865    ///     * must actually be a method of `obj`
9866    ///     * must refer to a method with 3 arguments
9867    ///
9868    /// # Returns
9869    /// Whatever the method returned or 0 if it threw
9870    ///
9871    /// # Throws Java Exception
9872    /// * Whatever the method threw
9873    ///
9874    ///
9875    /// # Panics
9876    /// if asserts feature is enabled and UB was detected
9877    ///
9878    /// # Safety
9879    ///
9880    /// Current thread must not be detached from JNI.
9881    ///
9882    /// Current thread must not be currently throwing an exception.
9883    ///
9884    /// Current thread does not hold a critical reference.
9885    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9886    ///
9887    /// `obj` must a valid and not already garbage collected.
9888    /// `methodID` must be valid, non-static and actually be a method of `obj`, return char and have 3 parameter
9889    /// The parameter types must exactly match the java method parameters.
9890    ///
9891    pub unsafe fn CallCharMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jchar {
9892        unsafe {
9893            #[cfg(feature = "asserts")]
9894            {
9895                self.check_not_critical("CallCharMethod");
9896                self.check_no_exception("CallCharMethod");
9897                self.check_return_type_object("CallCharMethod", obj, methodID, "char");
9898                self.check_parameter_types_object("CallCharMethod", obj, methodID, arg1, 0, 3);
9899                self.check_parameter_types_object("CallCharMethod", obj, methodID, arg2, 1, 3);
9900                self.check_parameter_types_object("CallCharMethod", obj, methodID, arg3, 2, 3);
9901            }
9902            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jchar>(43)(self.vtable, obj, methodID, arg1, arg2, arg3)
9903        }
9904    }
9905
9906    ///
9907    /// Calls a non-static java method that returns a short
9908    ///
9909    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9910    ///
9911    ///
9912    /// # Arguments
9913    /// * `obj` - which object the method should be called on
9914    ///     * must be valid
9915    ///     * must not be null
9916    ///     * must not be already garbage collected
9917    ///
9918    /// * `methodID` - method id of the method
9919    ///     * must not be null
9920    ///     * must be valid
9921    ///     * must not be a static
9922    ///     * must actually be a method of `obj`
9923    ///
9924    /// * `args` - argument pointer
9925    ///     * can be null if the method has no arguments
9926    ///     * must not be null otherwise and point to the exact number of arguments the method expects
9927    ///
9928    /// # Returns
9929    /// Whatever the method returned or 0 if it threw
9930    ///
9931    /// # Throws Java Exception
9932    /// * Whatever the method threw
9933    ///
9934    ///
9935    /// # Panics
9936    /// if asserts feature is enabled and UB was detected
9937    ///
9938    /// # Safety
9939    ///
9940    /// Current thread must not be detached from JNI.
9941    ///
9942    /// Current thread must not be currently throwing an exception.
9943    ///
9944    /// Current thread does not hold a critical reference.
9945    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
9946    ///
9947    /// `obj` must a valid and not already garbage collected.
9948    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a short
9949    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
9950    /// `args` union must contain types that match the java methods parameters.
9951    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
9952    ///
9953    pub unsafe fn CallShortMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) -> jshort {
9954        unsafe {
9955            #[cfg(feature = "asserts")]
9956            {
9957                self.check_not_critical("CallShortMethodA");
9958                self.check_no_exception("CallShortMethodA");
9959                self.check_return_type_object("CallShortMethodA", obj, methodID, "short");
9960            }
9961            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jshort>(48)(self.vtable, obj, methodID, args)
9962        }
9963    }
9964
9965    ///
9966    /// Calls a non-static java method that has 0 arguments and returns short
9967    ///
9968    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
9969    ///
9970    ///
9971    /// # Arguments
9972    /// * `obj` - which object the method should be called on
9973    ///     * must be valid
9974    ///     * must not be null
9975    ///     * must not be already garbage collected
9976    ///
9977    /// * `methodID` - method id of the method
9978    ///     * must not be null
9979    ///     * must be valid
9980    ///     * must not be a static
9981    ///     * must actually be a method of `obj`
9982    ///     * must refer to a method with 0 arguments
9983    ///
9984    /// # Returns
9985    /// Whatever the method returned or 0 if it threw
9986    ///
9987    /// # Throws Java Exception
9988    /// * Whatever the method threw
9989    ///
9990    ///
9991    /// # Panics
9992    /// if asserts feature is enabled and UB was detected
9993    ///
9994    /// # Safety
9995    ///
9996    /// Current thread must not be detached from JNI.
9997    ///
9998    /// Current thread must not be currently throwing an exception.
9999    ///
10000    /// Current thread does not hold a critical reference.
10001    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10002    ///
10003    /// `obj` must a valid and not already garbage collected.
10004    /// `methodID` must be valid, non-static and actually be a method of `obj`, return short and have no parameters
10005    ///
10006    pub unsafe fn CallShortMethod0(&self, obj: jobject, methodID: jmethodID) -> jshort {
10007        unsafe {
10008            #[cfg(feature = "asserts")]
10009            {
10010                self.check_not_critical("CallShortMethod");
10011                self.check_no_exception("CallShortMethod");
10012                self.check_return_type_object("CallShortMethod", obj, methodID, "short");
10013            }
10014            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jshort>(46)(self.vtable, obj, methodID)
10015        }
10016    }
10017
10018    ///
10019    /// Calls a non-static java method that has 1 arguments and returns short
10020    ///
10021    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10022    ///
10023    ///
10024    /// # Arguments
10025    /// * `obj` - which object the method should be called on
10026    ///     * must be valid
10027    ///     * must not be null
10028    ///     * must not be already garbage collected
10029    ///
10030    /// * `methodID` - method id of the method
10031    ///     * must not be null
10032    ///     * must be valid
10033    ///     * must not be a static
10034    ///     * must actually be a method of `obj`
10035    ///     * must refer to a method with 1 arguments
10036    ///
10037    /// # Returns
10038    /// Whatever the method returned or 0 if it threw
10039    ///
10040    /// # Throws Java Exception
10041    /// * Whatever the method threw
10042    ///
10043    ///
10044    /// # Panics
10045    /// if asserts feature is enabled and UB was detected
10046    ///
10047    /// # Safety
10048    ///
10049    /// Current thread must not be detached from JNI.
10050    ///
10051    /// Current thread must not be currently throwing an exception.
10052    ///
10053    /// Current thread does not hold a critical reference.
10054    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10055    ///
10056    /// `obj` must a valid and not already garbage collected.
10057    /// `methodID` must be valid, non-static and actually be a method of `obj`, return short and have 1 parameter
10058    /// The parameter types must exactly match the java method parameters.
10059    ///
10060    pub unsafe fn CallShortMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) -> jshort {
10061        unsafe {
10062            #[cfg(feature = "asserts")]
10063            {
10064                self.check_not_critical("CallShortMethod");
10065                self.check_no_exception("CallShortMethod");
10066                self.check_return_type_object("CallShortMethod", obj, methodID, "short");
10067                self.check_parameter_types_object("CallShortMethod", obj, methodID, arg1, 0, 1);
10068            }
10069            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jshort>(46)(self.vtable, obj, methodID, arg1)
10070        }
10071    }
10072
10073    ///
10074    /// Calls a non-static java method that has 2 arguments and returns short
10075    ///
10076    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10077    ///
10078    ///
10079    /// # Arguments
10080    /// * `obj` - which object the method should be called on
10081    ///     * must be valid
10082    ///     * must not be null
10083    ///     * must not be already garbage collected
10084    ///
10085    /// * `methodID` - method id of the method
10086    ///     * must not be null
10087    ///     * must be valid
10088    ///     * must not be a static
10089    ///     * must actually be a method of `obj`
10090    ///     * must refer to a method with 2 arguments
10091    ///
10092    /// # Returns
10093    /// Whatever the method returned or 0 if it threw
10094    ///
10095    /// # Throws Java Exception
10096    /// * Whatever the method threw
10097    ///
10098    ///
10099    /// # Panics
10100    /// if asserts feature is enabled and UB was detected
10101    ///
10102    /// # Safety
10103    ///
10104    /// Current thread must not be detached from JNI.
10105    ///
10106    /// Current thread must not be currently throwing an exception.
10107    ///
10108    /// Current thread does not hold a critical reference.
10109    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10110    ///
10111    /// `obj` must a valid and not already garbage collected.
10112    /// `methodID` must be valid, non-static and actually be a method of `obj`, return short and have 2 parameter
10113    /// The parameter types must exactly match the java method parameters.
10114    ///
10115    pub unsafe fn CallShortMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) -> jshort {
10116        unsafe {
10117            #[cfg(feature = "asserts")]
10118            {
10119                self.check_not_critical("CallShortMethod");
10120                self.check_no_exception("CallShortMethod");
10121                self.check_return_type_object("CallShortMethod", obj, methodID, "short");
10122                self.check_parameter_types_object("CallShortMethod", obj, methodID, arg1, 0, 2);
10123                self.check_parameter_types_object("CallShortMethod", obj, methodID, arg2, 1, 2);
10124            }
10125            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jshort>(46)(self.vtable, obj, methodID, arg1, arg2)
10126        }
10127    }
10128
10129    ///
10130    /// Calls a non-static java method that has 3 arguments and returns short
10131    ///
10132    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10133    ///
10134    ///
10135    /// # Arguments
10136    /// * `obj` - which object the method should be called on
10137    ///     * must be valid
10138    ///     * must not be null
10139    ///     * must not be already garbage collected
10140    ///
10141    /// * `methodID` - method id of the method
10142    ///     * must not be null
10143    ///     * must be valid
10144    ///     * must not be a static
10145    ///     * must actually be a method of `obj`
10146    ///     * must refer to a method with 3 arguments
10147    ///
10148    /// # Returns
10149    /// Whatever the method returned or 0 if it threw
10150    ///
10151    /// # Throws Java Exception
10152    /// * Whatever the method threw
10153    ///
10154    ///
10155    /// # Panics
10156    /// if asserts feature is enabled and UB was detected
10157    ///
10158    /// # Safety
10159    ///
10160    /// Current thread must not be detached from JNI.
10161    ///
10162    /// Current thread must not be currently throwing an exception.
10163    ///
10164    /// Current thread does not hold a critical reference.
10165    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10166    ///
10167    /// `obj` must a valid and not already garbage collected.
10168    /// `methodID` must be valid, non-static and actually be a method of `obj`, return short and have 3 parameter
10169    /// The parameter types must exactly match the java method parameters.
10170    ///
10171    pub unsafe fn CallShortMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jshort {
10172        unsafe {
10173            #[cfg(feature = "asserts")]
10174            {
10175                self.check_not_critical("CallShortMethod");
10176                self.check_no_exception("CallShortMethod");
10177                self.check_return_type_object("CallShortMethod", obj, methodID, "short");
10178                self.check_parameter_types_object("CallShortMethod", obj, methodID, arg1, 0, 3);
10179                self.check_parameter_types_object("CallShortMethod", obj, methodID, arg2, 1, 3);
10180                self.check_parameter_types_object("CallShortMethod", obj, methodID, arg3, 2, 3);
10181            }
10182            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jshort>(46)(self.vtable, obj, methodID, arg1, arg2, arg3)
10183        }
10184    }
10185
10186    ///
10187    /// Calls a non-static java method that returns a int
10188    ///
10189    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10190    ///
10191    ///
10192    /// # Arguments
10193    /// * `obj` - which object the method should be called on
10194    ///     * must be valid
10195    ///     * must not be null
10196    ///     * must not be already garbage collected
10197    ///
10198    /// * `methodID` - method id of the method
10199    ///     * must not be null
10200    ///     * must be valid
10201    ///     * must not be a static
10202    ///     * must actually be a method of `obj`
10203    ///
10204    /// * `args` - argument pointer
10205    ///     * can be null if the method has no arguments
10206    ///     * must not be null otherwise and point to the exact number of arguments the method expects
10207    ///
10208    /// # Returns
10209    /// Whatever the method returned or 0 if it threw
10210    ///
10211    /// # Throws Java Exception
10212    /// * Whatever the method threw
10213    ///
10214    ///
10215    /// # Panics
10216    /// if asserts feature is enabled and UB was detected
10217    ///
10218    /// # Safety
10219    ///
10220    /// Current thread must not be detached from JNI.
10221    ///
10222    /// Current thread must not be currently throwing an exception.
10223    ///
10224    /// Current thread does not hold a critical reference.
10225    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10226    ///
10227    /// `obj` must a valid and not already garbage collected.
10228    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a int
10229    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
10230    /// `args` union must contain types that match the java methods parameters.
10231    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
10232    ///
10233    pub unsafe fn CallIntMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) -> jint {
10234        unsafe {
10235            #[cfg(feature = "asserts")]
10236            {
10237                self.check_not_critical("CallIntMethodA");
10238                self.check_no_exception("CallIntMethodA");
10239                self.check_return_type_object("CallIntMethodA", obj, methodID, "int");
10240            }
10241            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jint>(51)(self.vtable, obj, methodID, args)
10242        }
10243    }
10244
10245    ///
10246    /// Calls a non-static java method that has 0 arguments and returns int
10247    ///
10248    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10249    ///
10250    ///
10251    /// # Arguments
10252    /// * `obj` - which object the method should be called on
10253    ///     * must be valid
10254    ///     * must not be null
10255    ///     * must not be already garbage collected
10256    ///
10257    /// * `methodID` - method id of the method
10258    ///     * must not be null
10259    ///     * must be valid
10260    ///     * must not be a static
10261    ///     * must actually be a method of `obj`
10262    ///     * must refer to a method with 0 arguments
10263    ///
10264    /// # Returns
10265    /// Whatever the method returned or 0 if it threw
10266    ///
10267    /// # Throws Java Exception
10268    /// * Whatever the method threw
10269    ///
10270    ///
10271    /// # Panics
10272    /// if asserts feature is enabled and UB was detected
10273    ///
10274    /// # Safety
10275    ///
10276    /// Current thread must not be detached from JNI.
10277    ///
10278    /// Current thread must not be currently throwing an exception.
10279    ///
10280    /// Current thread does not hold a critical reference.
10281    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10282    ///
10283    /// `obj` must a valid and not already garbage collected.
10284    /// `methodID` must be valid, non-static and actually be a method of `obj`, return int and have no parameters
10285    ///
10286    pub unsafe fn CallIntMethod0(&self, obj: jobject, methodID: jmethodID) -> jint {
10287        unsafe {
10288            #[cfg(feature = "asserts")]
10289            {
10290                self.check_not_critical("CallIntMethod");
10291                self.check_no_exception("CallIntMethod");
10292                self.check_return_type_object("CallIntMethod", obj, methodID, "int");
10293            }
10294            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jint>(49)(self.vtable, obj, methodID)
10295        }
10296    }
10297
10298    ///
10299    /// Calls a non-static java method that has 1 arguments and returns int
10300    ///
10301    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10302    ///
10303    ///
10304    /// # Arguments
10305    /// * `obj` - which object the method should be called on
10306    ///     * must be valid
10307    ///     * must not be null
10308    ///     * must not be already garbage collected
10309    ///
10310    /// * `methodID` - method id of the method
10311    ///     * must not be null
10312    ///     * must be valid
10313    ///     * must not be a static
10314    ///     * must actually be a method of `obj`
10315    ///     * must refer to a method with 1 arguments
10316    ///
10317    /// # Returns
10318    /// Whatever the method returned or 0 if it threw
10319    ///
10320    /// # Throws Java Exception
10321    /// * Whatever the method threw
10322    ///
10323    ///
10324    /// # Panics
10325    /// if asserts feature is enabled and UB was detected
10326    ///
10327    /// # Safety
10328    ///
10329    /// Current thread must not be detached from JNI.
10330    ///
10331    /// Current thread must not be currently throwing an exception.
10332    ///
10333    /// Current thread does not hold a critical reference.
10334    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10335    ///
10336    /// `obj` must a valid and not already garbage collected.
10337    /// `methodID` must be valid, non-static and actually be a method of `obj`, return int and have 1 parameter
10338    /// The parameter types must exactly match the java method parameters.
10339    ///
10340    pub unsafe fn CallIntMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) -> jint {
10341        unsafe {
10342            #[cfg(feature = "asserts")]
10343            {
10344                self.check_not_critical("CallIntMethod");
10345                self.check_no_exception("CallIntMethod");
10346                self.check_return_type_object("CallIntMethod", obj, methodID, "int");
10347                self.check_parameter_types_object("CallIntMethod", obj, methodID, arg1, 0, 1);
10348            }
10349            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jint>(49)(self.vtable, obj, methodID, arg1)
10350        }
10351    }
10352
10353    ///
10354    /// Calls a non-static java method that has 2 arguments and returns int
10355    ///
10356    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10357    ///
10358    ///
10359    /// # Arguments
10360    /// * `obj` - which object the method should be called on
10361    ///     * must be valid
10362    ///     * must not be null
10363    ///     * must not be already garbage collected
10364    ///
10365    /// * `methodID` - method id of the method
10366    ///     * must not be null
10367    ///     * must be valid
10368    ///     * must not be a static
10369    ///     * must actually be a method of `obj`
10370    ///     * must refer to a method with 2 arguments
10371    ///
10372    /// # Returns
10373    /// Whatever the method returned or 0 if it threw
10374    ///
10375    /// # Throws Java Exception
10376    /// * Whatever the method threw
10377    ///
10378    ///
10379    /// # Panics
10380    /// if asserts feature is enabled and UB was detected
10381    ///
10382    /// # Safety
10383    ///
10384    /// Current thread must not be detached from JNI.
10385    ///
10386    /// Current thread must not be currently throwing an exception.
10387    ///
10388    /// Current thread does not hold a critical reference.
10389    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10390    ///
10391    /// `obj` must a valid and not already garbage collected.
10392    /// `methodID` must be valid, non-static and actually be a method of `obj`, return int and have 2 parameter
10393    /// The parameter types must exactly match the java method parameters.
10394    ///
10395    pub unsafe fn CallIntMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) -> jint {
10396        unsafe {
10397            #[cfg(feature = "asserts")]
10398            {
10399                self.check_not_critical("CallIntMethod");
10400                self.check_no_exception("CallIntMethod");
10401                self.check_return_type_object("CallIntMethod", obj, methodID, "int");
10402                self.check_parameter_types_object("CallIntMethod", obj, methodID, arg1, 0, 2);
10403                self.check_parameter_types_object("CallIntMethod", obj, methodID, arg2, 1, 2);
10404            }
10405            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jint>(49)(self.vtable, obj, methodID, arg1, arg2)
10406        }
10407    }
10408
10409    ///
10410    /// Calls a non-static java method that has 3 arguments and returns int
10411    ///
10412    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10413    ///
10414    ///
10415    /// # Arguments
10416    /// * `obj` - which object the method should be called on
10417    ///     * must be valid
10418    ///     * must not be null
10419    ///     * must not be already garbage collected
10420    /// * `methodID` - method id of the method
10421    ///     * must not be null
10422    ///     * must be valid
10423    ///     * must not be a static
10424    ///     * must actually be a method of `obj`
10425    ///     * must refer to a method with 3 arguments
10426    ///
10427    /// # Returns
10428    /// Whatever the method returned or 0 if it threw
10429    ///
10430    /// # Throws Java Exception
10431    /// * Whatever the method threw
10432    ///
10433    ///
10434    /// # Panics
10435    /// if asserts feature is enabled and UB was detected
10436    ///
10437    /// # Safety
10438    ///
10439    /// Current thread must not be detached from JNI.
10440    ///
10441    /// Current thread must not be currently throwing an exception.
10442    ///
10443    /// Current thread does not hold a critical reference.
10444    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10445    ///
10446    /// `obj` must a valid and not already garbage collected.
10447    /// `methodID` must be valid, non-static and actually be a method of `obj`, return int and have 3 parameter
10448    /// The parameter types must exactly match the java method parameters.
10449    ///
10450    pub unsafe fn CallIntMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jint {
10451        unsafe {
10452            #[cfg(feature = "asserts")]
10453            {
10454                self.check_not_critical("CallIntMethod");
10455                self.check_no_exception("CallIntMethod");
10456                self.check_return_type_object("CallIntMethod", obj, methodID, "int");
10457                self.check_parameter_types_object("CallIntMethod", obj, methodID, arg1, 0, 3);
10458                self.check_parameter_types_object("CallIntMethod", obj, methodID, arg2, 1, 3);
10459                self.check_parameter_types_object("CallIntMethod", obj, methodID, arg3, 2, 3);
10460            }
10461            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jint>(49)(self.vtable, obj, methodID, arg1, arg2, arg3)
10462        }
10463    }
10464
10465    ///
10466    /// Calls a non-static java method that returns a long
10467    ///
10468    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10469    ///
10470    ///
10471    /// # Arguments
10472    /// * `obj` - which object the method should be called on
10473    ///     * must be valid
10474    ///     * must not be null
10475    ///     * must not be already garbage collected
10476    /// * `methodID` - method id of the method
10477    ///     * must not be null
10478    ///     * must be valid
10479    ///     * must not be a static
10480    ///     * must actually be a method of `obj`
10481    /// * `args` - argument pointer
10482    ///     * can be null if the method has no arguments
10483    ///     * must not be null otherwise and point to the exact number of arguments the method expects
10484    ///
10485    /// # Returns
10486    /// Whatever the method returned or 0 if it threw
10487    ///
10488    /// # Throws Java Exception
10489    /// * Whatever the method threw
10490    ///
10491    ///
10492    /// # Panics
10493    /// if asserts feature is enabled and UB was detected
10494    ///
10495    /// # Safety
10496    ///
10497    /// Current thread must not be detached from JNI.
10498    ///
10499    /// Current thread must not be currently throwing an exception.
10500    ///
10501    /// Current thread does not hold a critical reference.
10502    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10503    ///
10504    /// `obj` must a valid and not already garbage collected.
10505    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a long
10506    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
10507    /// `args` union must contain types that match the java methods parameters.
10508    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
10509    ///
10510    pub unsafe fn CallLongMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) -> jlong {
10511        unsafe {
10512            #[cfg(feature = "asserts")]
10513            {
10514                self.check_not_critical("CallLongMethodA");
10515                self.check_no_exception("CallLongMethodA");
10516                self.check_return_type_object("CallLongMethodA", obj, methodID, "long");
10517            }
10518            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jlong>(54)(self.vtable, obj, methodID, args)
10519        }
10520    }
10521
10522    ///
10523    /// Calls a non-static java method that has 0 arguments and returns long
10524    ///
10525    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10526    ///
10527    ///
10528    /// # Arguments
10529    /// * `obj` - which object the method should be called on
10530    ///     * must be valid
10531    ///     * must not be null
10532    ///     * must not be already garbage collected
10533    /// * `methodID` - method id of the method
10534    ///     * must not be null
10535    ///     * must be valid
10536    ///     * must not be a static
10537    ///     * must actually be a method of `obj`
10538    ///     * must refer to a method with 0 arguments
10539    ///
10540    /// # Returns
10541    /// Whatever the method returned or 0 if it threw
10542    ///
10543    /// # Throws Java Exception
10544    /// * Whatever the method threw
10545    ///
10546    ///
10547    /// # Panics
10548    /// if asserts feature is enabled and UB was detected
10549    ///
10550    /// # Safety
10551    ///
10552    /// Current thread must not be detached from JNI.
10553    ///
10554    /// Current thread must not be currently throwing an exception.
10555    ///
10556    /// Current thread does not hold a critical reference.
10557    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10558    ///
10559    /// `obj` must a valid and not already garbage collected.
10560    /// `methodID` must be valid, non-static and actually be a method of `obj`, return long and have no parameters
10561    ///
10562    pub unsafe fn CallLongMethod0(&self, obj: jobject, methodID: jmethodID) -> jlong {
10563        unsafe {
10564            #[cfg(feature = "asserts")]
10565            {
10566                self.check_not_critical("CallLongMethod");
10567                self.check_no_exception("CallLongMethod");
10568                self.check_return_type_object("CallLongMethod", obj, methodID, "long");
10569            }
10570            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jlong>(52)(self.vtable, obj, methodID)
10571        }
10572    }
10573
10574    ///
10575    /// Calls a non-static java method that has 1 arguments and returns long
10576    ///
10577    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10578    ///
10579    ///
10580    /// # Arguments
10581    /// * `obj` - which object the method should be called on
10582    ///     * must be valid
10583    ///     * must not be null
10584    ///     * must not be already garbage collected
10585    /// * `methodID` - method id of the method
10586    ///     * must not be null
10587    ///     * must be valid
10588    ///     * must not be a static
10589    ///     * must actually be a method of `obj`
10590    ///     * must refer to a method with 1 arguments
10591    ///
10592    /// # Returns
10593    /// Whatever the method returned or 0 if it threw
10594    ///
10595    /// # Throws Java Exception
10596    /// * Whatever the method threw
10597    ///
10598    ///
10599    /// # Panics
10600    /// if asserts feature is enabled and UB was detected
10601    ///
10602    /// # Safety
10603    ///
10604    /// Current thread must not be detached from JNI.
10605    ///
10606    /// Current thread must not be currently throwing an exception.
10607    ///
10608    /// Current thread does not hold a critical reference.
10609    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10610    ///
10611    /// `obj` must a valid and not already garbage collected.
10612    /// `methodID` must be valid, non-static and actually be a method of `obj`, return long and have 1 parameter
10613    /// The parameter types must exactly match the java method parameters.
10614    ///
10615    pub unsafe fn CallLongMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) -> jlong {
10616        unsafe {
10617            #[cfg(feature = "asserts")]
10618            {
10619                self.check_not_critical("CallLongMethod");
10620                self.check_no_exception("CallLongMethod");
10621                self.check_return_type_object("CallLongMethod", obj, methodID, "long");
10622                self.check_parameter_types_object("CallLongMethod", obj, methodID, arg1, 0, 1);
10623            }
10624            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jlong>(52)(self.vtable, obj, methodID, arg1)
10625        }
10626    }
10627
10628    ///
10629    /// Calls a non-static java method that has 2 arguments and returns long
10630    ///
10631    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10632    ///
10633    ///
10634    /// # Arguments
10635    /// * `obj` - which object the method should be called on
10636    ///     * must be valid
10637    ///     * must not be null
10638    ///     * must not be already garbage collected
10639    /// * `methodID` - method id of the method
10640    ///     * must not be null
10641    ///     * must be valid
10642    ///     * must not be a static
10643    ///     * must actually be a method of `obj`
10644    ///     * must refer to a method with 2 arguments
10645    ///
10646    /// # Returns
10647    /// Whatever the method returned or 0 if it threw
10648    ///
10649    /// # Throws Java Exception
10650    /// * Whatever the method threw
10651    ///
10652    ///
10653    /// # Panics
10654    /// if asserts feature is enabled and UB was detected
10655    ///
10656    /// # Safety
10657    ///
10658    /// Current thread must not be detached from JNI.
10659    ///
10660    /// Current thread must not be currently throwing an exception.
10661    ///
10662    /// Current thread does not hold a critical reference.
10663    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10664    ///
10665    /// `obj` must a valid and not already garbage collected.
10666    /// `methodID` must be valid, non-static and actually be a method of `obj`, return long and have 2 parameter
10667    /// The parameter types must exactly match the java method parameters.
10668    ///
10669    pub unsafe fn CallLongMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) -> jlong {
10670        unsafe {
10671            #[cfg(feature = "asserts")]
10672            {
10673                self.check_not_critical("CallLongMethod");
10674                self.check_no_exception("CallLongMethod");
10675                self.check_return_type_object("CallLongMethod", obj, methodID, "long");
10676                self.check_parameter_types_object("CallLongMethod", obj, methodID, arg1, 0, 2);
10677                self.check_parameter_types_object("CallLongMethod", obj, methodID, arg2, 1, 2);
10678            }
10679            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jlong>(52)(self.vtable, obj, methodID, arg1, arg2)
10680        }
10681    }
10682
10683    ///
10684    /// Calls a non-static java method that has 3 arguments and returns long
10685    ///
10686    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10687    ///
10688    ///
10689    /// # Arguments
10690    /// * `obj` - which object the method should be called on
10691    ///     * must be valid
10692    ///     * must not be null
10693    ///     * must not be already garbage collected
10694    /// * `methodID` - method id of the method
10695    ///     * must not be null
10696    ///     * must be valid
10697    ///     * must not be a static
10698    ///     * must actually be a method of `obj`
10699    ///     * must refer to a method with 3 arguments
10700    ///
10701    /// # Returns
10702    /// Whatever the method returned or 0 if it threw
10703    ///
10704    /// # Throws Java Exception
10705    /// * Whatever the method threw
10706    ///
10707    ///
10708    /// # Panics
10709    /// if asserts feature is enabled and UB was detected
10710    ///
10711    /// # Safety
10712    ///
10713    /// Current thread must not be detached from JNI.
10714    ///
10715    /// Current thread must not be currently throwing an exception.
10716    ///
10717    /// Current thread does not hold a critical reference.
10718    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10719    ///
10720    /// `obj` must a valid and not already garbage collected.
10721    /// `methodID` must be valid, non-static and actually be a method of `obj`, return long and have 3 parameter
10722    /// The parameter types must exactly match the java method parameters.
10723    ///
10724    pub unsafe fn CallLongMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jlong {
10725        unsafe {
10726            #[cfg(feature = "asserts")]
10727            {
10728                self.check_not_critical("CallLongMethod");
10729                self.check_no_exception("CallLongMethod");
10730                self.check_return_type_object("CallLongMethod", obj, methodID, "long");
10731                self.check_parameter_types_object("CallLongMethod", obj, methodID, arg1, 0, 3);
10732                self.check_parameter_types_object("CallLongMethod", obj, methodID, arg2, 1, 3);
10733                self.check_parameter_types_object("CallLongMethod", obj, methodID, arg3, 2, 3);
10734            }
10735            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jlong>(52)(self.vtable, obj, methodID, arg1, arg2, arg3)
10736        }
10737    }
10738
10739    ///
10740    /// Calls a non-static java method that returns a float
10741    ///
10742    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10743    ///
10744    ///
10745    /// # Arguments
10746    /// * `obj` - which object the method should be called on
10747    ///     * must be valid
10748    ///     * must not be null
10749    ///     * must not be already garbage collected
10750    /// * `methodID` - method id of the method
10751    ///     * must not be null
10752    ///     * must be valid
10753    ///     * must not be a static
10754    ///     * must actually be a method of `obj`
10755    /// * `args` - argument pointer
10756    ///     * can be null if the method has no arguments
10757    ///     * must not be null otherwise and point to the exact number of arguments the method expects
10758    ///
10759    /// # Returns
10760    /// Whatever the method returned or 0 if it threw
10761    ///
10762    /// # Throws Java Exception
10763    /// * Whatever the method threw
10764    ///
10765    ///
10766    /// # Panics
10767    /// if asserts feature is enabled and UB was detected
10768    ///
10769    /// # Safety
10770    ///
10771    /// Current thread must not be detached from JNI.
10772    ///
10773    /// Current thread must not be currently throwing an exception.
10774    ///
10775    /// Current thread does not hold a critical reference.
10776    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10777    ///
10778    /// `obj` must a valid and not already garbage collected.
10779    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a float
10780    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
10781    /// `args` union must contain types that match the java methods parameters.
10782    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
10783    ///
10784    pub unsafe fn CallFloatMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) -> jfloat {
10785        unsafe {
10786            #[cfg(feature = "asserts")]
10787            {
10788                self.check_not_critical("CallFloatMethodA");
10789                self.check_no_exception("CallFloatMethodA");
10790                self.check_return_type_object("CallFloatMethodA", obj, methodID, "float");
10791            }
10792            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jfloat>(57)(self.vtable, obj, methodID, args)
10793        }
10794    }
10795
10796    ///
10797    /// Calls a non-static java method that has 0 arguments and returns float
10798    ///
10799    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10800    ///
10801    ///
10802    /// # Arguments
10803    /// * `obj` - which object the method should be called on
10804    ///     * must be valid
10805    ///     * must not be null
10806    ///     * must not be already garbage collected
10807    /// * `methodID` - method id of the method
10808    ///     * must not be null
10809    ///     * must be valid
10810    ///     * must not be a static
10811    ///     * must actually be a method of `obj`
10812    ///     * must refer to a method with 0 arguments
10813    ///
10814    /// # Returns
10815    /// Whatever the method returned or 0 if it threw
10816    ///
10817    /// # Throws Java Exception
10818    /// * Whatever the method threw
10819    ///
10820    ///
10821    /// # Panics
10822    /// if asserts feature is enabled and UB was detected
10823    ///
10824    /// # Safety
10825    ///
10826    /// Current thread must not be detached from JNI.
10827    ///
10828    /// Current thread must not be currently throwing an exception.
10829    ///
10830    /// Current thread does not hold a critical reference.
10831    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10832    ///
10833    /// `obj` must a valid and not already garbage collected.
10834    /// `methodID` must be valid, non-static and actually be a method of `obj`, return float and have no parameters
10835    ///
10836    pub unsafe fn CallFloatMethod0(&self, obj: jobject, methodID: jmethodID) -> jfloat {
10837        unsafe {
10838            #[cfg(feature = "asserts")]
10839            {
10840                self.check_not_critical("CallFloatMethod");
10841                self.check_no_exception("CallFloatMethod");
10842                self.check_return_type_object("CallFloatMethod", obj, methodID, "float");
10843            }
10844            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jfloat>(55)(self.vtable, obj, methodID)
10845        }
10846    }
10847
10848    ///
10849    /// Calls a non-static java method that has 1 arguments and returns float
10850    ///
10851    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10852    ///
10853    ///
10854    /// # Arguments
10855    /// * `obj` - which object the method should be called on
10856    ///     * must be valid
10857    ///     * must not be null
10858    ///     * must not be already garbage collected
10859    /// * `methodID` - method id of the method
10860    ///     * must not be null
10861    ///     * must be valid
10862    ///     * must not be a static
10863    ///     * must actually be a method of `obj`
10864    ///     * must refer to a method with 1 arguments
10865    ///
10866    /// # Returns
10867    /// Whatever the method returned or 0 if it threw
10868    ///
10869    /// # Throws Java Exception
10870    /// * Whatever the method threw
10871    ///
10872    ///
10873    /// # Panics
10874    /// if asserts feature is enabled and UB was detected
10875    ///
10876    /// # Safety
10877    ///
10878    /// Current thread must not be detached from JNI.
10879    ///
10880    /// Current thread must not be currently throwing an exception.
10881    ///
10882    /// Current thread does not hold a critical reference.
10883    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10884    ///
10885    /// `obj` must a valid and not already garbage collected.
10886    /// `methodID` must be valid, non-static and actually be a method of `obj`, return float and have 1 parameter
10887    /// The parameter types must exactly match the java method parameters.
10888    ///
10889    pub unsafe fn CallFloatMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) -> jfloat {
10890        unsafe {
10891            #[cfg(feature = "asserts")]
10892            {
10893                self.check_not_critical("CallFloatMethod");
10894                self.check_no_exception("CallFloatMethod");
10895                self.check_return_type_object("CallFloatMethod", obj, methodID, "float");
10896                self.check_parameter_types_object("CallFloatMethod", obj, methodID, arg1, 0, 1);
10897            }
10898            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jfloat>(55)(self.vtable, obj, methodID, arg1)
10899        }
10900    }
10901
10902    ///
10903    /// Calls a non-static java method that has 2 arguments and returns float
10904    ///
10905    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10906    ///
10907    ///
10908    /// # Arguments
10909    /// * `obj` - which object the method should be called on
10910    ///     * must be valid
10911    ///     * must not be null
10912    ///     * must not be already garbage collected
10913    /// * `methodID` - method id of the method
10914    ///     * must not be null
10915    ///     * must be valid
10916    ///     * must not be a static
10917    ///     * must actually be a method of `obj`
10918    ///     * must refer to a method with 2 arguments
10919    ///
10920    /// # Returns
10921    /// Whatever the method returned or 0 if it threw
10922    ///
10923    /// # Throws Java Exception
10924    /// * Whatever the method threw
10925    ///
10926    ///
10927    /// # Panics
10928    /// if asserts feature is enabled and UB was detected
10929    ///
10930    /// # Safety
10931    ///
10932    /// Current thread must not be detached from JNI.
10933    ///
10934    /// Current thread must not be currently throwing an exception.
10935    ///
10936    /// Current thread does not hold a critical reference.
10937    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10938    ///
10939    /// `obj` must a valid and not already garbage collected.
10940    /// `methodID` must be valid, non-static and actually be a method of `obj`, return float and have 2 parameter
10941    /// The parameter types must exactly match the java method parameters.
10942    ///
10943    pub unsafe fn CallFloatMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) -> jfloat {
10944        unsafe {
10945            #[cfg(feature = "asserts")]
10946            {
10947                self.check_not_critical("CallFloatMethod");
10948                self.check_no_exception("CallFloatMethod");
10949                self.check_return_type_object("CallFloatMethod", obj, methodID, "float");
10950                self.check_parameter_types_object("CallFloatMethod", obj, methodID, arg1, 0, 2);
10951                self.check_parameter_types_object("CallFloatMethod", obj, methodID, arg2, 1, 2);
10952            }
10953            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jfloat>(55)(self.vtable, obj, methodID, arg1, arg2)
10954        }
10955    }
10956
10957    ///
10958    /// Calls a non-static java method that has 3 arguments and returns float
10959    ///
10960    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
10961    ///
10962    ///
10963    /// # Arguments
10964    /// * `obj` - which object the method should be called on
10965    ///     * must be valid
10966    ///     * must not be null
10967    ///     * must not be already garbage collected
10968    /// * `methodID` - method id of the method
10969    ///     * must not be null
10970    ///     * must be valid
10971    ///     * must not be a static
10972    ///     * must actually be a method of `obj`
10973    ///     * must refer to a method with 3 arguments
10974    ///
10975    /// # Returns
10976    /// Whatever the method returned or 0 if it threw
10977    ///
10978    /// # Throws Java Exception
10979    /// * Whatever the method threw
10980    ///
10981    ///
10982    /// # Panics
10983    /// if asserts feature is enabled and UB was detected
10984    ///
10985    /// # Safety
10986    ///
10987    /// Current thread must not be detached from JNI.
10988    ///
10989    /// Current thread must not be currently throwing an exception.
10990    ///
10991    /// Current thread does not hold a critical reference.
10992    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
10993    ///
10994    /// `obj` must a valid and not already garbage collected.
10995    /// `methodID` must be valid, non-static and actually be a method of `obj`, return float and have 3 parameter
10996    /// The parameter types must exactly match the java method parameters.
10997    ///
10998    pub unsafe fn CallFloatMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jfloat {
10999        unsafe {
11000            #[cfg(feature = "asserts")]
11001            {
11002                self.check_not_critical("CallFloatMethod");
11003                self.check_no_exception("CallFloatMethod");
11004                self.check_return_type_object("CallFloatMethod", obj, methodID, "float");
11005                self.check_parameter_types_object("CallFloatMethod", obj, methodID, arg1, 0, 3);
11006                self.check_parameter_types_object("CallFloatMethod", obj, methodID, arg2, 1, 3);
11007                self.check_parameter_types_object("CallFloatMethod", obj, methodID, arg3, 2, 3);
11008            }
11009            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jfloat>(55)(self.vtable, obj, methodID, arg1, arg2, arg3)
11010        }
11011    }
11012
11013    ///
11014    /// Calls a non-static java method that returns a double
11015    ///
11016    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11017    ///
11018    ///
11019    /// # Arguments
11020    /// * `obj` - which object the method should be called on
11021    ///     * must be valid
11022    ///     * must not be null
11023    ///     * must not be already garbage collected
11024    /// * `methodID` - method id of the method
11025    ///     * must not be null
11026    ///     * must be valid
11027    ///     * must not be a static
11028    ///     * must actually be a method of `obj`
11029    /// * `args` - argument pointer
11030    ///     * can be null if the method has no arguments
11031    ///     * must not be null otherwise and point to the exact number of arguments the method expects
11032    ///
11033    /// # Returns
11034    /// Whatever the method returned or 0 if it threw
11035    ///
11036    /// # Throws Java Exception
11037    /// * Whatever the method threw
11038    ///
11039    ///
11040    /// # Panics
11041    /// if asserts feature is enabled and UB was detected
11042    ///
11043    /// # Safety
11044    ///
11045    /// Current thread must not be detached from JNI.
11046    ///
11047    /// Current thread must not be currently throwing an exception.
11048    ///
11049    /// Current thread does not hold a critical reference.
11050    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11051    ///
11052    /// `obj` must a valid and not already garbage collected.
11053    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a double
11054    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
11055    /// `args` union must contain types that match the java methods parameters.
11056    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
11057    ///
11058    pub unsafe fn CallDoubleMethodA(&self, obj: jobject, methodID: jmethodID, args: *const jtype) -> jdouble {
11059        unsafe {
11060            #[cfg(feature = "asserts")]
11061            {
11062                self.check_not_critical("CallDoubleMethodA");
11063                self.check_no_exception("CallDoubleMethodA");
11064                self.check_return_type_object("CallDoubleMethodA", obj, methodID, "double");
11065            }
11066            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jdouble>(60)(self.vtable, obj, methodID, args)
11067        }
11068    }
11069
11070    ///
11071    /// Calls a non-static java method that has 0 arguments and returns double
11072    ///
11073    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11074    ///
11075    ///
11076    /// # Arguments
11077    /// * `obj` - which object the method should be called on
11078    ///     * must be valid
11079    ///     * must not be null
11080    ///     * must not be already garbage collected
11081    /// * `methodID` - method id of the method
11082    ///     * must not be null
11083    ///     * must be valid
11084    ///     * must not be a static
11085    ///     * must actually be a method of `obj`
11086    ///     * must refer to a method with 0 arguments
11087    ///
11088    /// # Returns
11089    /// Whatever the method returned or 0 if it threw
11090    ///
11091    /// # Throws Java Exception
11092    /// * Whatever the method threw
11093    ///
11094    ///
11095    /// # Panics
11096    /// if asserts feature is enabled and UB was detected
11097    ///
11098    /// # Safety
11099    ///
11100    /// Current thread must not be detached from JNI.
11101    ///
11102    /// Current thread must not be currently throwing an exception.
11103    ///
11104    /// Current thread does not hold a critical reference.
11105    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11106    ///
11107    /// `obj` must a valid and not already garbage collected.
11108    /// `methodID` must be valid, non-static and actually be a method of `obj`, return double and have no parameters
11109    ///
11110    pub unsafe fn CallDoubleMethod0(&self, obj: jobject, methodID: jmethodID) -> jdouble {
11111        unsafe {
11112            #[cfg(feature = "asserts")]
11113            {
11114                self.check_not_critical("CallDoubleMethod");
11115                self.check_no_exception("CallDoubleMethod");
11116                self.check_return_type_object("CallDoubleMethod", obj, methodID, "double");
11117            }
11118            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jdouble>(58)(self.vtable, obj, methodID)
11119        }
11120    }
11121
11122    ///
11123    /// Calls a non-static java method that has 1 arguments and returns double
11124    ///
11125    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11126    ///
11127    ///
11128    /// # Arguments
11129    /// * `obj` - which object the method should be called on
11130    ///     * must be valid
11131    ///     * must not be null
11132    ///     * must not be already garbage collected
11133    /// * `methodID` - method id of the method
11134    ///     * must not be null
11135    ///     * must be valid
11136    ///     * must not be a static
11137    ///     * must actually be a method of `obj`
11138    ///     * must refer to a method with 1 arguments
11139    ///
11140    /// # Returns
11141    /// Whatever the method returned or 0 if it threw
11142    ///
11143    /// # Throws Java Exception
11144    /// * Whatever the method threw
11145    ///
11146    ///
11147    /// # Panics
11148    /// if asserts feature is enabled and UB was detected
11149    ///
11150    /// # Safety
11151    ///
11152    /// Current thread must not be detached from JNI.
11153    ///
11154    /// Current thread must not be currently throwing an exception.
11155    ///
11156    /// Current thread does not hold a critical reference.
11157    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11158    ///
11159    /// `obj` must a valid and not already garbage collected.
11160    /// `methodID` must be valid, non-static and actually be a method of `obj`, return double and have 1 parameter
11161    /// The parameter types must exactly match the java method parameters.
11162    ///
11163    pub unsafe fn CallDoubleMethod1<A: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A) -> jdouble {
11164        unsafe {
11165            #[cfg(feature = "asserts")]
11166            {
11167                self.check_not_critical("CallDoubleMethod");
11168                self.check_no_exception("CallDoubleMethod");
11169                self.check_return_type_object("CallDoubleMethod", obj, methodID, "double");
11170                self.check_parameter_types_object("CallDoubleMethod", obj, methodID, arg1, 0, 1);
11171            }
11172            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jdouble>(58)(self.vtable, obj, methodID, arg1)
11173        }
11174    }
11175
11176    ///
11177    /// Calls a non-static java method that has 2 arguments and returns double
11178    ///
11179    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11180    ///
11181    ///
11182    /// # Arguments
11183    /// * `obj` - which object the method should be called on
11184    ///     * must be valid
11185    ///     * must not be null
11186    ///     * must not be already garbage collected
11187    /// * `methodID` - method id of the method
11188    ///     * must not be null
11189    ///     * must be valid
11190    ///     * must not be a static
11191    ///     * must actually be a method of `obj`
11192    ///     * must refer to a method with 2 arguments
11193    ///
11194    /// # Returns
11195    /// Whatever the method returned or 0 if it threw
11196    ///
11197    /// # Throws Java Exception
11198    /// * Whatever the method threw
11199    ///
11200    ///
11201    /// # Panics
11202    /// if asserts feature is enabled and UB was detected
11203    ///
11204    /// # Safety
11205    ///
11206    /// Current thread must not be detached from JNI.
11207    ///
11208    /// Current thread must not be currently throwing an exception.
11209    ///
11210    /// Current thread does not hold a critical reference.
11211    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11212    ///
11213    /// `obj` must a valid and not already garbage collected.
11214    /// `methodID` must be valid, non-static and actually be a method of `obj`, return double and have 2 parameter
11215    /// The parameter types must exactly match the java method parameters.
11216    ///
11217    pub unsafe fn CallDoubleMethod2<A: JType, B: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B) -> jdouble {
11218        unsafe {
11219            #[cfg(feature = "asserts")]
11220            {
11221                self.check_not_critical("CallDoubleMethod");
11222                self.check_no_exception("CallDoubleMethod");
11223                self.check_return_type_object("CallDoubleMethod", obj, methodID, "double");
11224                self.check_parameter_types_object("CallDoubleMethod", obj, methodID, arg1, 0, 2);
11225                self.check_parameter_types_object("CallDoubleMethod", obj, methodID, arg2, 1, 2);
11226            }
11227            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jdouble>(58)(self.vtable, obj, methodID, arg1, arg2)
11228        }
11229    }
11230
11231    ///
11232    /// Calls a non-static java method that has 3 arguments and returns double
11233    ///
11234    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Call_type_Method_routines>
11235    ///
11236    ///
11237    /// # Arguments
11238    /// * `obj` - which object the method should be called on
11239    ///     * must be valid
11240    ///     * must not be null
11241    ///     * must not be already garbage collected
11242    /// * `methodID` - method id of the method
11243    ///     * must not be null
11244    ///     * must be valid
11245    ///     * must not be a static
11246    ///     * must actually be a method of `obj`
11247    ///     * must refer to a method with 3 arguments
11248    ///
11249    /// # Returns
11250    /// Whatever the method returned or 0 if it threw
11251    ///
11252    /// # Throws Java Exception
11253    /// * Whatever the method threw
11254    ///
11255    ///
11256    /// # Panics
11257    /// if asserts feature is enabled and UB was detected
11258    ///
11259    /// # Safety
11260    ///
11261    /// Current thread must not be detached from JNI.
11262    ///
11263    /// Current thread must not be currently throwing an exception.
11264    ///
11265    /// Current thread does not hold a critical reference.
11266    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11267    ///
11268    /// `obj` must a valid and not already garbage collected.
11269    /// `methodID` must be valid, non-static and actually be a method of `obj`, return double and have 3 parameter
11270    /// The parameter types must exactly match the java method parameters.
11271    ///
11272    pub unsafe fn CallDoubleMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jdouble {
11273        unsafe {
11274            #[cfg(feature = "asserts")]
11275            {
11276                self.check_not_critical("CallDoubleMethod");
11277                self.check_no_exception("CallDoubleMethod");
11278                self.check_return_type_object("CallDoubleMethod", obj, methodID, "double");
11279                self.check_parameter_types_object("CallDoubleMethod", obj, methodID, arg1, 0, 3);
11280                self.check_parameter_types_object("CallDoubleMethod", obj, methodID, arg2, 1, 3);
11281                self.check_parameter_types_object("CallDoubleMethod", obj, methodID, arg3, 2, 3);
11282            }
11283            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jdouble>(58)(self.vtable, obj, methodID, arg1, arg2, arg3)
11284        }
11285    }
11286
11287    ///
11288    /// Calls a non-static java method that returns void without using the objects vtable to look up the method.
11289    /// This means that should the object be a subclass of the class that the method is declared in
11290    /// then the base method that the methodID refers to is invoked instead of a potencially overwritten one.
11291    ///
11292    /// This is roughly equivalent to calling "super.someMethod(...)" in java
11293    ///
11294    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
11295    ///
11296    ///
11297    /// # Arguments
11298    /// * `obj` - which object the method should be called on
11299    ///     * must be valid
11300    ///     * must not be null
11301    ///     * must not be already garbage collected
11302    /// * `methodID` - method id of the method
11303    ///     * must not be null
11304    ///     * must be valid
11305    ///     * must not be a static
11306    ///     * must actually be a method of `obj`
11307    /// * `args` - argument pointer
11308    ///     * can be null if the method has no arguments
11309    ///     * must not be null otherwise and point to the exact number of arguments the method expects
11310    ///
11311    /// # Throws Java Exception
11312    /// * Whatever the method threw
11313    ///
11314    ///
11315    /// # Panics
11316    /// if asserts feature is enabled and UB was detected
11317    ///
11318    /// # Safety
11319    ///
11320    /// Current thread must not be detached from JNI.
11321    ///
11322    /// Current thread must not be currently throwing an exception.
11323    ///
11324    /// Current thread does not hold a critical reference.
11325    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11326    ///
11327    /// `obj` must a valid and not already garbage collected.
11328    /// `methodID` must be valid, non-static and actually be a method of `obj` and return void
11329    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
11330    /// `args` union must contain types that match the java methods parameters.
11331    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
11332    ///
11333    pub unsafe fn CallNonvirtualVoidMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) {
11334        unsafe {
11335            #[cfg(feature = "asserts")]
11336            {
11337                self.check_not_critical("CallNonvirtualVoidMethodA");
11338                self.check_no_exception("CallNonvirtualVoidMethodA");
11339                self.check_return_type_object("CallNonvirtualVoidMethodA", obj, methodID, "void");
11340                self.check_is_class("CallNonvirtualVoidMethodA", class);
11341            }
11342            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype)>(93)(self.vtable, obj, class, methodID, args);
11343        }
11344    }
11345
11346    ///
11347    /// Calls a non-static java method with 0 arguments that returns void without using the objects vtable to look up the method.
11348    /// This means that should the object be a subclass of the class that the method is declared in
11349    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
11350    ///
11351    /// This is roughly equivalent to calling "super.someMethod(...)" in java
11352    ///
11353    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
11354    ///
11355    ///
11356    /// # Arguments
11357    /// * `obj` - which object the method should be called on
11358    ///     * must be valid
11359    ///     * must not be null
11360    ///     * must not be already garbage collected
11361    /// * `methodID` - method id of the method
11362    ///     * must not be null
11363    ///     * must be valid
11364    ///     * must not be a static
11365    ///     * must actually be a method of `obj`
11366    ///     * must refer to a method with 0 arguments
11367    ///
11368    /// # Throws Java Exception
11369    /// * Whatever the method threw
11370    ///
11371    ///
11372    /// # Panics
11373    /// if asserts feature is enabled and UB was detected
11374    ///
11375    /// # Safety
11376    ///
11377    /// Current thread must not be detached from JNI.
11378    ///
11379    /// Current thread must not be currently throwing an exception.
11380    ///
11381    /// Current thread does not hold a critical reference.
11382    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11383    ///
11384    /// `obj` must a valid and not already garbage collected.
11385    /// `methodID` must be valid, non-static and actually be a method of `obj`, return void and have no parameters
11386    ///
11387    pub unsafe fn CallNonvirtualVoidMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) {
11388        unsafe {
11389            #[cfg(feature = "asserts")]
11390            {
11391                self.check_not_critical("CallNonvirtualVoidMethod");
11392                self.check_no_exception("CallNonvirtualVoidMethod");
11393                self.check_return_type_object("CallNonvirtualVoidMethod", obj, methodID, "void");
11394                self.check_is_class("CallNonvirtualVoidMethod", class);
11395            }
11396            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID)>(91)(self.vtable, obj, class, methodID);
11397        }
11398    }
11399
11400    ///
11401    /// Calls a non-static java method with 1 arguments that returns void without using the objects vtable to look up the method.
11402    /// This means that should the object be a subclass of the class that the method is declared in
11403    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
11404    ///
11405    /// This is roughly equivalent to calling "super.someMethod(...)" in java
11406    ///
11407    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
11408    ///
11409    ///
11410    /// # Arguments
11411    /// * `obj` - which object the method should be called on
11412    ///     * must be valid
11413    ///     * must not be null
11414    ///     * must not be already garbage collected
11415    /// * `methodID` - method id of the method
11416    ///     * must not be null
11417    ///     * must be valid
11418    ///     * must not be a static
11419    ///     * must actually be a method of `obj`
11420    ///     * must refer to a method with 1 arguments
11421    ///
11422    /// # Throws Java Exception
11423    /// * Whatever the method threw
11424    ///
11425    ///
11426    /// # Panics
11427    /// if asserts feature is enabled and UB was detected
11428    ///
11429    /// # Safety
11430    ///
11431    /// Current thread must not be detached from JNI.
11432    ///
11433    /// Current thread must not be currently throwing an exception.
11434    ///
11435    /// Current thread does not hold a critical reference.
11436    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11437    ///
11438    /// `obj` must a valid and not already garbage collected.
11439    /// `methodID` must be valid, non-static and actually be a method of `obj`, return void and have 1 argument
11440    ///
11441    pub unsafe fn CallNonvirtualVoidMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) {
11442        unsafe {
11443            #[cfg(feature = "asserts")]
11444            {
11445                self.check_not_critical("CallNonvirtualVoidMethod");
11446                self.check_no_exception("CallNonvirtualVoidMethod");
11447                self.check_return_type_object("CallNonvirtualVoidMethod", obj, methodID, "void");
11448                self.check_is_class("CallNonvirtualVoidMethod", class);
11449                self.check_parameter_types_object("CallNonvirtualVoidMethod", obj, methodID, arg1, 0, 1);
11450            }
11451            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...)>(91)(self.vtable, obj, class, methodID, arg1);
11452        }
11453    }
11454
11455    ///
11456    /// Calls a non-static java method with 2 arguments that returns void without using the objects vtable to look up the method.
11457    /// This means that should the object be a subclass of the class that the method is declared in
11458    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
11459    ///
11460    /// This is roughly equivalent to calling "super.someMethod(...)" in java
11461    ///
11462    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
11463    ///
11464    ///
11465    /// # Arguments
11466    /// * `obj` - which object the method should be called on
11467    ///     * must be valid
11468    ///     * must not be null
11469    ///     * must not be already garbage collected
11470    /// * `methodID` - method id of the method
11471    ///     * must not be null
11472    ///     * must be valid
11473    ///     * must not be a static
11474    ///     * must actually be a method of `obj`
11475    ///     * must refer to a method with 2 arguments
11476    ///
11477    /// # Throws Java Exception
11478    /// * Whatever the method threw
11479    ///
11480    ///
11481    /// # Panics
11482    /// if asserts feature is enabled and UB was detected
11483    ///
11484    /// # Safety
11485    ///
11486    /// Current thread must not be detached from JNI.
11487    ///
11488    /// Current thread must not be currently throwing an exception.
11489    ///
11490    /// Current thread does not hold a critical reference.
11491    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11492    ///
11493    /// `obj` must a valid and not already garbage collected.
11494    /// `methodID` must be valid, non-static and actually be a method of `obj`, return void and have 2 arguments
11495    ///
11496    pub unsafe fn CallNonvirtualVoidMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) {
11497        unsafe {
11498            #[cfg(feature = "asserts")]
11499            {
11500                self.check_not_critical("CallNonvirtualVoidMethod");
11501                self.check_no_exception("CallNonvirtualVoidMethod");
11502                self.check_return_type_object("CallNonvirtualVoidMethod", obj, methodID, "void");
11503                self.check_is_class("CallNonvirtualVoidMethod", class);
11504                self.check_parameter_types_object("CallNonvirtualVoidMethod", obj, methodID, arg1, 0, 2);
11505                self.check_parameter_types_object("CallNonvirtualVoidMethod", obj, methodID, arg2, 1, 2);
11506            }
11507            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...)>(91)(self.vtable, obj, class, methodID, arg1, arg2);
11508        }
11509    }
11510
11511    ///
11512    /// Calls a non-static java method with 3 arguments that returns void without using the objects vtable to look up the method.
11513    /// This means that should the object be a subclass of the class that the method is declared in
11514    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
11515    ///
11516    /// This is roughly equivalent to calling "super.someMethod(...)" in java
11517    ///
11518    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
11519    ///
11520    ///
11521    /// # Arguments
11522    /// * `obj` - which object the method should be called on
11523    ///     * must be valid
11524    ///     * must not be null
11525    ///     * must not be already garbage collected
11526    /// * `methodID` - method id of the method
11527    ///     * must not be null
11528    ///     * must be valid
11529    ///     * must not be a static
11530    ///     * must actually be a method of `obj`
11531    ///     * must refer to a method with 3 arguments
11532    ///
11533    /// # Throws Java Exception
11534    /// * Whatever the method threw
11535    ///
11536    ///
11537    /// # Panics
11538    /// if asserts feature is enabled and UB was detected
11539    ///
11540    /// # Safety
11541    ///
11542    /// Current thread must not be detached from JNI.
11543    ///
11544    /// Current thread must not be currently throwing an exception.
11545    ///
11546    /// Current thread does not hold a critical reference.
11547    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11548    ///
11549    /// `obj` must a valid and not already garbage collected.
11550    /// `methodID` must be valid, non-static and actually be a method of `obj`, return void and have 3 arguments
11551    ///
11552    pub unsafe fn CallNonvirtualVoidMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) {
11553        unsafe {
11554            #[cfg(feature = "asserts")]
11555            {
11556                self.check_not_critical("CallNonvirtualVoidMethod");
11557                self.check_no_exception("CallNonvirtualVoidMethod");
11558                self.check_return_type_object("CallNonvirtualVoidMethod", obj, methodID, "void");
11559                self.check_is_class("CallNonvirtualVoidMethod", class);
11560                self.check_parameter_types_object("CallNonvirtualVoidMethod", obj, methodID, arg1, 0, 3);
11561                self.check_parameter_types_object("CallNonvirtualVoidMethod", obj, methodID, arg2, 1, 3);
11562                self.check_parameter_types_object("CallNonvirtualVoidMethod", obj, methodID, arg3, 2, 3);
11563            }
11564            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...)>(91)(self.vtable, obj, class, methodID, arg1, arg2, arg3);
11565        }
11566    }
11567
11568    ///
11569    /// Calls a non-static java method that returns object without using the objects vtable to look up the method.
11570    /// This means that should the object be a subclass of the class that the method is declared in
11571    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
11572    ///
11573    /// This is roughly equivalent to calling "super.someMethod(...)" in java
11574    ///
11575    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
11576    ///
11577    ///
11578    /// # Arguments
11579    /// * `obj` - which object the method should be called on
11580    ///     * must be valid
11581    ///     * must not be null
11582    ///     * must not be already garbage collected
11583    /// * `methodID` - method id of the method
11584    ///     * must not be null
11585    ///     * must be valid
11586    ///     * must not be a static
11587    ///     * must actually be a method of `obj`
11588    /// * `args` - argument pointer
11589    ///     * can be null if the method has no arguments
11590    ///     * must not be null otherwise and point to the exact number of arguments the method expects
11591    ///
11592    /// # Returns
11593    /// Whatever the method returned or null if it threw
11594    ///
11595    /// # Throws Java Exception
11596    /// * Whatever the method threw
11597    ///
11598    ///
11599    /// # Panics
11600    /// if asserts feature is enabled and UB was detected
11601    ///
11602    /// # Safety
11603    ///
11604    /// Current thread must not be detached from JNI.
11605    ///
11606    /// Current thread must not be currently throwing an exception.
11607    ///
11608    /// Current thread does not hold a critical reference.
11609    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11610    ///
11611    /// `obj` must a valid and not already garbage collected.
11612    /// `methodID` must be valid, non-static and actually be a method of `obj` and return an object
11613    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
11614    /// `args` union must contain types that match the java methods parameters.
11615    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
11616    ///
11617    pub unsafe fn CallNonvirtualObjectMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) -> jobject {
11618        unsafe {
11619            #[cfg(feature = "asserts")]
11620            {
11621                self.check_not_critical("CallNonvirtualObjectMethodA");
11622                self.check_no_exception("CallNonvirtualObjectMethodA");
11623                self.check_return_type_object("CallNonvirtualObjectMethodA", obj, methodID, "object");
11624                self.check_is_class("CallNonvirtualObjectMethodA", class);
11625            }
11626            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype) -> jobject>(66)(self.vtable, obj, class, methodID, args)
11627        }
11628    }
11629
11630    ///
11631    /// Calls a non-static java method with 0 arguments that returns object without using the objects vtable to look up the method.
11632    /// This means that should the object be a subclass of the class that the method is declared in
11633    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
11634    ///
11635    /// This is roughly equivalent to calling "super.someMethod(...)" in java
11636    ///
11637    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
11638    ///
11639    ///
11640    /// # Arguments
11641    /// * `obj` - which object the method should be called on
11642    ///     * must be valid
11643    ///     * must not be null
11644    ///     * must not be already garbage collected
11645    /// * `methodID` - method id of the method
11646    ///     * must not be null
11647    ///     * must be valid
11648    ///     * must not be a static
11649    ///     * must actually be a method of `obj`
11650    ///     * must refer to a method with 0 arguments
11651    ///
11652    /// # Returns
11653    /// Whatever the method returned or null if it threw
11654    ///
11655    /// # Throws Java Exception
11656    /// * Whatever the method threw
11657    ///
11658    ///
11659    /// # Panics
11660    /// if asserts feature is enabled and UB was detected
11661    ///
11662    /// # Safety
11663    ///
11664    /// Current thread must not be detached from JNI.
11665    ///
11666    /// Current thread must not be currently throwing an exception.
11667    ///
11668    /// Current thread does not hold a critical reference.
11669    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11670    ///
11671    /// `obj` must a valid and not already garbage collected.
11672    /// `methodID` must be valid, non-static and actually be a method of `obj`, return an object and have no parameters
11673    ///
11674    pub unsafe fn CallNonvirtualObjectMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) -> jobject {
11675        unsafe {
11676            #[cfg(feature = "asserts")]
11677            {
11678                self.check_not_critical("CallNonvirtualObjectMethod");
11679                self.check_no_exception("CallNonvirtualObjectMethod");
11680                self.check_return_type_object("CallNonvirtualObjectMethod", obj, methodID, "object");
11681                self.check_is_class("CallNonvirtualObjectMethod", class);
11682            }
11683            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID) -> jobject>(64)(self.vtable, obj, class, methodID)
11684        }
11685    }
11686
11687    ///
11688    /// Calls a non-static java method with 1 arguments that returns object without using the objects vtable to look up the method.
11689    /// This means that should the object be a subclass of the class that the method is declared in
11690    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
11691    ///
11692    /// This is roughly equivalent to calling "super.someMethod(...)" in java
11693    ///
11694    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
11695    ///
11696    ///
11697    /// # Arguments
11698    /// * `obj` - which object the method should be called on
11699    ///     * must be valid
11700    ///     * must not be null
11701    ///     * must not be already garbage collected
11702    /// * `methodID` - method id of the method
11703    ///     * must not be null
11704    ///     * must be valid
11705    ///     * must not be a static
11706    ///     * must actually be a method of `obj`
11707    ///     * must refer to a method with 1 arguments
11708    ///
11709    /// # Returns
11710    /// Whatever the method returned or null if it threw
11711    ///
11712    /// # Throws Java Exception
11713    /// * Whatever the method threw
11714    ///
11715    ///
11716    /// # Panics
11717    /// if asserts feature is enabled and UB was detected
11718    ///
11719    /// # Safety
11720    ///
11721    /// Current thread must not be detached from JNI.
11722    ///
11723    /// Current thread must not be currently throwing an exception.
11724    ///
11725    /// Current thread does not hold a critical reference.
11726    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11727    ///
11728    /// `obj` must a valid and not already garbage collected.
11729    /// `methodID` must be valid, non-static and actually be a method of `obj`, return an object and have 1 arguments
11730    ///
11731    pub unsafe fn CallNonvirtualObjectMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) -> jobject {
11732        unsafe {
11733            #[cfg(feature = "asserts")]
11734            {
11735                self.check_not_critical("CallNonvirtualObjectMethod");
11736                self.check_no_exception("CallNonvirtualObjectMethod");
11737                self.check_return_type_object("CallNonvirtualObjectMethod", obj, methodID, "object");
11738                self.check_is_class("CallNonvirtualObjectMethod", class);
11739                self.check_parameter_types_object("CallNonvirtualObjectMethod", obj, methodID, arg1, 0, 1);
11740            }
11741            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jobject>(64)(self.vtable, obj, class, methodID, arg1)
11742        }
11743    }
11744
11745    ///
11746    /// Calls a non-static java method with 2 arguments that returns object without using the objects vtable to look up the method.
11747    /// This means that should the object be a subclass of the class that the method is declared in
11748    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
11749    ///
11750    /// This is roughly equivalent to calling "super.someMethod(...)" in java
11751    ///
11752    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
11753    ///
11754    ///
11755    /// # Arguments
11756    /// * `obj` - which object the method should be called on
11757    ///     * must be valid
11758    ///     * must not be null
11759    ///     * must not be already garbage collected
11760    /// * `methodID` - method id of the method
11761    ///     * must not be null
11762    ///     * must be valid
11763    ///     * must not be a static
11764    ///     * must actually be a method of `obj`
11765    ///     * must refer to a method with 2 arguments
11766    ///
11767    /// # Returns
11768    /// Whatever the method returned or null if it threw
11769    ///
11770    /// # Throws Java Exception
11771    /// * Whatever the method threw
11772    ///
11773    ///
11774    /// # Panics
11775    /// if asserts feature is enabled and UB was detected
11776    ///
11777    /// # Safety
11778    ///
11779    /// Current thread must not be detached from JNI.
11780    ///
11781    /// Current thread must not be currently throwing an exception.
11782    ///
11783    /// Current thread does not hold a critical reference.
11784    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11785    ///
11786    /// `obj` must a valid and not already garbage collected.
11787    /// `methodID` must be valid, non-static and actually be a method of `obj`, return an object and have 2 arguments
11788    ///
11789    pub unsafe fn CallNonvirtualObjectMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jobject {
11790        unsafe {
11791            #[cfg(feature = "asserts")]
11792            {
11793                self.check_not_critical("CallNonvirtualObjectMethod");
11794                self.check_no_exception("CallNonvirtualObjectMethod");
11795                self.check_return_type_object("CallNonvirtualObjectMethod", obj, methodID, "object");
11796                self.check_is_class("CallNonvirtualObjectMethod", class);
11797                self.check_parameter_types_object("CallNonvirtualObjectMethod", obj, methodID, arg1, 0, 2);
11798                self.check_parameter_types_object("CallNonvirtualObjectMethod", obj, methodID, arg2, 1, 2);
11799            }
11800            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jobject>(64)(self.vtable, obj, class, methodID, arg1, arg2)
11801        }
11802    }
11803
11804    ///
11805    /// Calls a non-static java method with 3 arguments that returns object without using the objects vtable to look up the method.
11806    /// This means that should the object be a subclass of the class that the method is declared in
11807    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
11808    ///
11809    /// This is roughly equivalent to calling "super.someMethod(...)" in java
11810    ///
11811    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
11812    ///
11813    ///
11814    /// # Arguments
11815    /// * `obj` - which object the method should be called on
11816    ///     * must be valid
11817    ///     * must not be null
11818    ///     * must not be already garbage collected
11819    /// * `methodID` - method id of the method
11820    ///     * must not be null
11821    ///     * must be valid
11822    ///     * must not be a static
11823    ///     * must actually be a method of `obj`
11824    ///     * must refer to a method with 3 arguments
11825    ///
11826    /// # Returns
11827    /// Whatever the method returned or null if it threw
11828    ///
11829    /// # Throws Java Exception
11830    /// * Whatever the method threw
11831    ///
11832    ///
11833    /// # Panics
11834    /// if asserts feature is enabled and UB was detected
11835    ///
11836    /// # Safety
11837    ///
11838    /// Current thread must not be detached from JNI.
11839    ///
11840    /// Current thread must not be currently throwing an exception.
11841    ///
11842    /// Current thread does not hold a critical reference.
11843    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11844    ///
11845    /// `obj` must a valid and not already garbage collected.
11846    /// `methodID` must be valid, non-static and actually be a method of `obj`, return an object and have 3 arguments
11847    ///
11848    pub unsafe fn CallNonvirtualObjectMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jobject {
11849        unsafe {
11850            #[cfg(feature = "asserts")]
11851            {
11852                self.check_not_critical("CallNonvirtualObjectMethod");
11853                self.check_no_exception("CallNonvirtualObjectMethod");
11854                self.check_return_type_object("CallNonvirtualObjectMethod", obj, methodID, "object");
11855                self.check_is_class("CallNonvirtualObjectMethod", class);
11856                self.check_parameter_types_object("CallNonvirtualObjectMethod", obj, methodID, arg1, 0, 3);
11857                self.check_parameter_types_object("CallNonvirtualObjectMethod", obj, methodID, arg2, 1, 3);
11858                self.check_parameter_types_object("CallNonvirtualObjectMethod", obj, methodID, arg3, 2, 3);
11859            }
11860            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jobject>(64)(self.vtable, obj, class, methodID, arg1, arg2, arg3)
11861        }
11862    }
11863
11864    ///
11865    /// Calls a non-static java method that returns boolean without using the objects vtable to look up the method.
11866    /// This means that should the object be a subclass of the class that the method is declared in
11867    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
11868    ///
11869    /// This is roughly equivalent to calling "super.someMethod(...)" in java
11870    ///
11871    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
11872    ///
11873    ///
11874    /// # Arguments
11875    /// * `obj` - which object the method should be called on
11876    ///     * must be valid
11877    ///     * must not be null
11878    ///     * must not be already garbage collected
11879    /// * `methodID` - method id of the method
11880    ///     * must not be null
11881    ///     * must be valid
11882    ///     * must not be a static
11883    ///     * must actually be a method of `obj`
11884    /// * `args` - argument pointer
11885    ///     * can be null if the method has no arguments
11886    ///     * must not be null otherwise and point to the exact number of arguments the method expects
11887    ///
11888    /// # Returns
11889    /// Whatever the method returned or false if it threw
11890    ///
11891    /// # Throws Java Exception
11892    /// * Whatever the method threw
11893    ///
11894    ///
11895    /// # Panics
11896    /// if asserts feature is enabled and UB was detected
11897    ///
11898    /// # Safety
11899    ///
11900    /// Current thread must not be detached from JNI.
11901    ///
11902    /// Current thread must not be currently throwing an exception.
11903    ///
11904    /// Current thread does not hold a critical reference.
11905    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11906    ///
11907    /// `obj` must a valid and not already garbage collected.
11908    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a boolean
11909    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
11910    /// `args` union must contain types that match the java methods parameters.
11911    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
11912    ///
11913    pub unsafe fn CallNonvirtualBooleanMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) -> jboolean {
11914        unsafe {
11915            #[cfg(feature = "asserts")]
11916            {
11917                self.check_not_critical("CallNonvirtualBooleanMethodA");
11918                self.check_no_exception("CallNonvirtualBooleanMethodA");
11919                self.check_return_type_object("CallNonvirtualBooleanMethodA", obj, methodID, "boolean");
11920                self.check_is_class("CallNonvirtualBooleanMethodA", class);
11921            }
11922            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype) -> jboolean>(69)(self.vtable, obj, class, methodID, args)
11923        }
11924    }
11925
11926    ///
11927    /// Calls a non-static java method with 0 arguments that returns boolean without using the objects vtable to look up the method.
11928    /// This means that should the object be a subclass of the class that the method is declared in
11929    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
11930    ///
11931    /// This is roughly equivalent to calling "super.someMethod(...)" in java
11932    ///
11933    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
11934    ///
11935    ///
11936    /// # Arguments
11937    /// * `obj` - which object the method should be called on
11938    ///     * must be valid
11939    ///     * must not be null
11940    ///     * must not be already garbage collected
11941    /// * `methodID` - method id of the method
11942    ///     * must not be null
11943    ///     * must be valid
11944    ///     * must not be a static
11945    ///     * must actually be a method of `obj`
11946    ///     * must refer to a method with 0 arguments
11947    ///
11948    /// # Returns
11949    /// Whatever the method returned or false if it threw
11950    ///
11951    /// # Throws Java Exception
11952    /// * Whatever the method threw
11953    ///
11954    ///
11955    /// # Panics
11956    /// if asserts feature is enabled and UB was detected
11957    ///
11958    /// # Safety
11959    ///
11960    /// Current thread must not be detached from JNI.
11961    ///
11962    /// Current thread must not be currently throwing an exception.
11963    ///
11964    /// Current thread does not hold a critical reference.
11965    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
11966    ///
11967    /// `obj` must a valid and not already garbage collected.
11968    /// `methodID` must be valid, non-static and actually be a method of `obj`, return boolean and have no parameters
11969    ///
11970    pub unsafe fn CallNonvirtualBooleanMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) -> jboolean {
11971        unsafe {
11972            #[cfg(feature = "asserts")]
11973            {
11974                self.check_not_critical("CallNonvirtualBooleanMethod");
11975                self.check_no_exception("CallNonvirtualBooleanMethod");
11976                self.check_return_type_object("CallNonvirtualBooleanMethod", obj, methodID, "boolean");
11977                self.check_is_class("CallNonvirtualBooleanMethod", class);
11978            }
11979            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID) -> jboolean>(67)(self.vtable, obj, class, methodID)
11980        }
11981    }
11982
11983    ///
11984    /// Calls a non-static java method with 1 arguments that returns boolean without using the objects vtable to look up the method.
11985    /// This means that should the object be a subclass of the class that the method is declared in
11986    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
11987    ///
11988    /// This is roughly equivalent to calling "super.someMethod(...)" in java
11989    ///
11990    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
11991    ///
11992    ///
11993    /// # Arguments
11994    /// * `obj` - which object the method should be called on
11995    ///     * must be valid
11996    ///     * must not be null
11997    ///     * must not be already garbage collected
11998    /// * `methodID` - method id of the method
11999    ///     * must not be null
12000    ///     * must be valid
12001    ///     * must not be a static
12002    ///     * must actually be a method of `obj`
12003    ///     * must refer to a method with 1 arguments
12004    ///
12005    /// # Returns
12006    /// Whatever the method returned or false if it threw
12007    ///
12008    /// # Throws Java Exception
12009    /// * Whatever the method threw
12010    ///
12011    ///
12012    /// # Panics
12013    /// if asserts feature is enabled and UB was detected
12014    ///
12015    /// # Safety
12016    ///
12017    /// Current thread must not be detached from JNI.
12018    ///
12019    /// Current thread must not be currently throwing an exception.
12020    ///
12021    /// Current thread does not hold a critical reference.
12022    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12023    ///
12024    /// `obj` must a valid and not already garbage collected.
12025    /// `methodID` must be valid, non-static and actually be a method of `obj`, return boolean and have 1 arguments
12026    ///
12027    pub unsafe fn CallNonvirtualBooleanMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) -> jboolean {
12028        unsafe {
12029            #[cfg(feature = "asserts")]
12030            {
12031                self.check_not_critical("CallNonvirtualBooleanMethod");
12032                self.check_no_exception("CallNonvirtualBooleanMethod");
12033                self.check_return_type_object("CallNonvirtualBooleanMethod", obj, methodID, "boolean");
12034                self.check_is_class("CallNonvirtualBooleanMethod", class);
12035                self.check_parameter_types_object("CallNonvirtualBooleanMethod", obj, methodID, arg1, 0, 1);
12036            }
12037            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jboolean>(67)(self.vtable, obj, class, methodID, arg1)
12038        }
12039    }
12040
12041    ///
12042    /// Calls a non-static java method with 2 arguments that returns boolean without using the objects vtable to look up the method.
12043    /// This means that should the object be a subclass of the class that the method is declared in
12044    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12045    ///
12046    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12047    ///
12048    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12049    ///
12050    ///
12051    /// # Arguments
12052    /// * `obj` - which object the method should be called on
12053    ///     * must be valid
12054    ///     * must not be null
12055    ///     * must not be already garbage collected
12056    /// * `methodID` - method id of the method
12057    ///     * must not be null
12058    ///     * must be valid
12059    ///     * must not be a static
12060    ///     * must actually be a method of `obj`
12061    ///     * must refer to a method with 2 arguments
12062    ///
12063    /// # Returns
12064    /// Whatever the method returned or false if it threw
12065    ///
12066    /// # Throws Java Exception
12067    /// * Whatever the method threw
12068    ///
12069    ///
12070    /// # Panics
12071    /// if asserts feature is enabled and UB was detected
12072    ///
12073    /// # Safety
12074    ///
12075    /// Current thread must not be detached from JNI.
12076    ///
12077    /// Current thread must not be currently throwing an exception.
12078    ///
12079    /// Current thread does not hold a critical reference.
12080    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12081    ///
12082    /// `obj` must a valid and not already garbage collected.
12083    /// `methodID` must be valid, non-static and actually be a method of `obj`, return boolean and have 2 arguments
12084    ///
12085    pub unsafe fn CallNonvirtualBooleanMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jboolean {
12086        unsafe {
12087            #[cfg(feature = "asserts")]
12088            {
12089                self.check_not_critical("CallNonvirtualBooleanMethod");
12090                self.check_no_exception("CallNonvirtualBooleanMethod");
12091                self.check_return_type_object("CallNonvirtualBooleanMethod", obj, methodID, "boolean");
12092                self.check_is_class("CallNonvirtualBooleanMethod", class);
12093                self.check_parameter_types_object("CallNonvirtualBooleanMethod", obj, methodID, arg1, 0, 2);
12094                self.check_parameter_types_object("CallNonvirtualBooleanMethod", obj, methodID, arg2, 1, 2);
12095            }
12096            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jboolean>(67)(self.vtable, obj, class, methodID, arg1, arg2)
12097        }
12098    }
12099
12100    ///
12101    /// Calls a non-static java method with 3 arguments that returns boolean without using the objects vtable to look up the method.
12102    /// This means that should the object be a subclass of the class that the method is declared in
12103    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12104    ///
12105    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12106    ///
12107    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12108    ///
12109    ///
12110    /// # Arguments
12111    /// * `obj` - which object the method should be called on
12112    ///     * must be valid
12113    ///     * must not be null
12114    ///     * must not be already garbage collected
12115    /// * `methodID` - method id of the method
12116    ///     * must not be null
12117    ///     * must be valid
12118    ///     * must not be a static
12119    ///     * must actually be a method of `obj`
12120    ///     * must refer to a method with 3 arguments
12121    ///
12122    /// # Returns
12123    /// Whatever the method returned or false if it threw
12124    ///
12125    /// # Throws Java Exception
12126    /// * Whatever the method threw
12127    ///
12128    ///
12129    /// # Panics
12130    /// if asserts feature is enabled and UB was detected
12131    ///
12132    /// # Safety
12133    ///
12134    /// Current thread must not be detached from JNI.
12135    ///
12136    /// Current thread must not be currently throwing an exception.
12137    ///
12138    /// Current thread does not hold a critical reference.
12139    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12140    ///
12141    /// `obj` must a valid and not already garbage collected.
12142    /// `methodID` must be valid, non-static and actually be a method of `obj`, return boolean and have 3 arguments
12143    ///
12144    pub unsafe fn CallNonvirtualBooleanMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jboolean {
12145        unsafe {
12146            #[cfg(feature = "asserts")]
12147            {
12148                self.check_not_critical("CallNonvirtualBooleanMethod");
12149                self.check_no_exception("CallNonvirtualBooleanMethod");
12150                self.check_return_type_object("CallNonvirtualBooleanMethod", obj, methodID, "boolean");
12151                self.check_is_class("CallNonvirtualBooleanMethod", class);
12152                self.check_parameter_types_object("CallNonvirtualBooleanMethod", obj, methodID, arg1, 0, 3);
12153                self.check_parameter_types_object("CallNonvirtualBooleanMethod", obj, methodID, arg2, 1, 3);
12154                self.check_parameter_types_object("CallNonvirtualBooleanMethod", obj, methodID, arg3, 2, 3);
12155            }
12156            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jboolean>(67)(self.vtable, obj, class, methodID, arg1, arg2, arg3)
12157        }
12158    }
12159
12160    ///
12161    /// Calls a non-static java method that returns byte without using the objects vtable to look up the method.
12162    /// This means that should the object be a subclass of the class that the method is declared in
12163    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12164    ///
12165    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12166    ///
12167    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12168    ///
12169    ///
12170    /// # Arguments
12171    /// * `obj` - which object the method should be called on
12172    ///     * must be valid
12173    ///     * must not be null
12174    ///     * must not be already garbage collected
12175    /// * `methodID` - method id of the method
12176    ///     * must not be null
12177    ///     * must be valid
12178    ///     * must not be a static
12179    ///     * must actually be a method of `obj`
12180    /// * `args` - argument pointer
12181    ///     * can be null if the method has no arguments
12182    ///     * must not be null otherwise and point to the exact number of arguments the method expects
12183    ///
12184    /// # Returns
12185    /// Whatever the method returned or 0 if it threw
12186    ///
12187    /// # Throws Java Exception
12188    /// * Whatever the method threw
12189    ///
12190    ///
12191    /// # Panics
12192    /// if asserts feature is enabled and UB was detected
12193    ///
12194    /// # Safety
12195    ///
12196    /// Current thread must not be detached from JNI.
12197    ///
12198    /// Current thread must not be currently throwing an exception.
12199    ///
12200    /// Current thread does not hold a critical reference.
12201    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12202    ///
12203    /// `obj` must a valid and not already garbage collected.
12204    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a byte
12205    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
12206    /// `args` union must contain types that match the java methods parameters.
12207    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
12208    ///
12209    pub unsafe fn CallNonvirtualByteMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) -> jbyte {
12210        unsafe {
12211            #[cfg(feature = "asserts")]
12212            {
12213                self.check_not_critical("CallNonvirtualByteMethodA");
12214                self.check_no_exception("CallNonvirtualByteMethodA");
12215                self.check_return_type_object("CallNonvirtualByteMethodA", obj, methodID, "byte");
12216                self.check_is_class("CallNonvirtualByteMethodA", class);
12217            }
12218            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype) -> jbyte>(72)(self.vtable, obj, class, methodID, args)
12219        }
12220    }
12221
12222    ///
12223    /// Calls a non-static java method with 0 arguments that returns byte without using the objects vtable to look up the method.
12224    /// This means that should the object be a subclass of the class that the method is declared in
12225    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12226    ///
12227    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12228    ///
12229    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12230    ///
12231    ///
12232    /// # Arguments
12233    /// * `obj` - which object the method should be called on
12234    ///     * must be valid
12235    ///     * must not be null
12236    ///     * must not be already garbage collected
12237    /// * `methodID` - method id of the method
12238    ///     * must not be null
12239    ///     * must be valid
12240    ///     * must not be a static
12241    ///     * must actually be a method of `obj`
12242    ///     * must refer to a method with 0 arguments
12243    ///
12244    /// # Returns
12245    /// Whatever the method returned or 0 if it threw
12246    ///
12247    /// # Throws Java Exception
12248    /// * Whatever the method threw
12249    ///
12250    ///
12251    /// # Panics
12252    /// if asserts feature is enabled and UB was detected
12253    ///
12254    /// # Safety
12255    ///
12256    /// Current thread must not be detached from JNI.
12257    ///
12258    /// Current thread must not be currently throwing an exception.
12259    ///
12260    /// Current thread does not hold a critical reference.
12261    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12262    ///
12263    /// `obj` must a valid and not already garbage collected.
12264    /// `methodID` must be valid, non-static and actually be a method of `obj`, return byte and have 0 arguments
12265    ///
12266    pub unsafe fn CallNonvirtualByteMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) -> jbyte {
12267        unsafe {
12268            #[cfg(feature = "asserts")]
12269            {
12270                self.check_not_critical("CallNonvirtualByteMethod");
12271                self.check_no_exception("CallNonvirtualByteMethod");
12272                self.check_return_type_object("CallNonvirtualByteMethod", obj, methodID, "byte");
12273                self.check_is_class("CallNonvirtualByteMethod", class);
12274            }
12275            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID) -> jbyte>(70)(self.vtable, obj, class, methodID)
12276        }
12277    }
12278
12279    ///
12280    /// Calls a non-static java method with 1 arguments that returns byte without using the objects vtable to look up the method.
12281    /// This means that should the object be a subclass of the class that the method is declared in
12282    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12283    ///
12284    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12285    ///
12286    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12287    ///
12288    ///
12289    /// # Arguments
12290    /// * `obj` - which object the method should be called on
12291    ///     * must be valid
12292    ///     * must not be null
12293    ///     * must not be already garbage collected
12294    /// * `methodID` - method id of the method
12295    ///     * must not be null
12296    ///     * must be valid
12297    ///     * must not be a static
12298    ///     * must actually be a method of `obj`
12299    ///     * must refer to a method with 1 arguments
12300    ///
12301    /// # Returns
12302    /// Whatever the method returned or 0 if it threw
12303    ///
12304    /// # Throws Java Exception
12305    /// * Whatever the method threw
12306    ///
12307    ///
12308    /// # Panics
12309    /// if asserts feature is enabled and UB was detected
12310    ///
12311    /// # Safety
12312    ///
12313    /// Current thread must not be detached from JNI.
12314    ///
12315    /// Current thread must not be currently throwing an exception.
12316    ///
12317    /// Current thread does not hold a critical reference.
12318    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12319    ///
12320    /// `obj` must a valid and not already garbage collected.
12321    /// `methodID` must be valid, non-static and actually be a method of `obj`, return byte and have 1 arguments
12322    ///
12323    pub unsafe fn CallNonvirtualByteMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) -> jbyte {
12324        unsafe {
12325            #[cfg(feature = "asserts")]
12326            {
12327                self.check_not_critical("CallNonvirtualByteMethod");
12328                self.check_no_exception("CallNonvirtualByteMethod");
12329                self.check_return_type_object("CallNonvirtualByteMethod", obj, methodID, "byte");
12330                self.check_is_class("CallNonvirtualByteMethod", class);
12331                self.check_parameter_types_object("CallNonvirtualByteMethod", obj, methodID, arg1, 0, 1);
12332            }
12333            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jbyte>(70)(self.vtable, obj, class, methodID, arg1)
12334        }
12335    }
12336
12337    ///
12338    /// Calls a non-static java method with 2 arguments that returns byte without using the objects vtable to look up the method.
12339    /// This means that should the object be a subclass of the class that the method is declared in
12340    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12341    ///
12342    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12343    ///
12344    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12345    ///
12346    ///
12347    /// # Arguments
12348    /// * `obj` - which object the method should be called on
12349    ///     * must be valid
12350    ///     * must not be null
12351    ///     * must not be already garbage collected
12352    /// * `methodID` - method id of the method
12353    ///     * must not be null
12354    ///     * must be valid
12355    ///     * must not be a static
12356    ///     * must actually be a method of `obj`
12357    ///     * must refer to a method with 0 arguments
12358    ///
12359    /// # Returns
12360    /// Whatever the method returned or 2 if it threw
12361    ///
12362    /// # Throws Java Exception
12363    /// * Whatever the method threw
12364    ///
12365    ///
12366    /// # Panics
12367    /// if asserts feature is enabled and UB was detected
12368    ///
12369    /// # Safety
12370    ///
12371    /// Current thread must not be detached from JNI.
12372    ///
12373    /// Current thread must not be currently throwing an exception.
12374    ///
12375    /// Current thread does not hold a critical reference.
12376    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12377    ///
12378    /// `obj` must a valid and not already garbage collected.
12379    /// `methodID` must be valid, non-static and actually be a method of `obj`, return byte and have 2 arguments
12380    ///
12381    pub unsafe fn CallNonvirtualByteMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jbyte {
12382        unsafe {
12383            #[cfg(feature = "asserts")]
12384            {
12385                self.check_not_critical("CallNonvirtualByteMethod");
12386                self.check_no_exception("CallNonvirtualByteMethod");
12387                self.check_return_type_object("CallNonvirtualByteMethod", obj, methodID, "byte");
12388                self.check_is_class("CallNonvirtualByteMethod", class);
12389                self.check_parameter_types_object("CallNonvirtualByteMethod", obj, methodID, arg1, 0, 2);
12390                self.check_parameter_types_object("CallNonvirtualByteMethod", obj, methodID, arg2, 1, 2);
12391            }
12392            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jbyte>(70)(self.vtable, obj, class, methodID, arg1, arg2)
12393        }
12394    }
12395
12396    ///
12397    /// Calls a non-static java method with 3 arguments that returns byte without using the objects vtable to look up the method.
12398    /// This means that should the object be a subclass of the class that the method is declared in
12399    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12400    ///
12401    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12402    ///
12403    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12404    ///
12405    ///
12406    /// # Arguments
12407    /// * `obj` - which object the method should be called on
12408    ///     * must be valid
12409    ///     * must not be null
12410    ///     * must not be already garbage collected
12411    /// * `methodID` - method id of the method
12412    ///     * must not be null
12413    ///     * must be valid
12414    ///     * must not be a static
12415    ///     * must actually be a method of `obj`
12416    ///     * must refer to a method with 0 arguments
12417    ///
12418    /// # Returns
12419    /// Whatever the method returned or 3 if it threw
12420    ///
12421    /// # Throws Java Exception
12422    /// * Whatever the method threw
12423    ///
12424    ///
12425    /// # Panics
12426    /// if asserts feature is enabled and UB was detected
12427    ///
12428    /// # Safety
12429    ///
12430    /// Current thread must not be detached from JNI.
12431    ///
12432    /// Current thread must not be currently throwing an exception.
12433    ///
12434    /// Current thread does not hold a critical reference.
12435    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12436    ///
12437    /// `obj` must a valid and not already garbage collected.
12438    /// `methodID` must be valid, non-static and actually be a method of `obj`, return byte and have 3 arguments
12439    ///
12440    pub unsafe fn CallNonvirtualByteMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jbyte {
12441        unsafe {
12442            #[cfg(feature = "asserts")]
12443            {
12444                self.check_not_critical("CallNonvirtualByteMethod");
12445                self.check_no_exception("CallNonvirtualByteMethod");
12446                self.check_return_type_object("CallNonvirtualByteMethod", obj, methodID, "byte");
12447                self.check_is_class("CallNonvirtualByteMethod", class);
12448                self.check_parameter_types_object("CallNonvirtualByteMethod", obj, methodID, arg1, 0, 3);
12449                self.check_parameter_types_object("CallNonvirtualByteMethod", obj, methodID, arg2, 1, 3);
12450                self.check_parameter_types_object("CallNonvirtualByteMethod", obj, methodID, arg3, 2, 3);
12451            }
12452            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jbyte>(70)(self.vtable, obj, class, methodID, arg1, arg2, arg3)
12453        }
12454    }
12455
12456    ///
12457    /// Calls a non-static java method with 3 arguments that returns char without using the objects vtable to look up the method.
12458    /// This means that should the object be a subclass of the class that the method is declared in
12459    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12460    ///
12461    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12462    ///
12463    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12464    ///
12465    ///
12466    /// # Arguments
12467    /// * `obj` - which object the method should be called on
12468    ///     * must be valid
12469    ///     * must not be null
12470    ///     * must not be already garbage collected
12471    /// * `methodID` - method id of the method
12472    ///     * must not be null
12473    ///     * must be valid
12474    ///     * must not be a static
12475    ///     * must actually be a method of `obj`
12476    /// * `args` - argument pointer
12477    ///     * can be null if the method has no arguments
12478    ///     * must not be null otherwise and point to the exact number of arguments the method expects
12479    ///
12480    /// # Returns
12481    /// Whatever the method returned or 0 if it threw
12482    ///
12483    /// # Throws Java Exception
12484    /// * Whatever the method threw
12485    ///
12486    ///
12487    /// # Panics
12488    /// if asserts feature is enabled and UB was detected
12489    ///
12490    /// # Safety
12491    ///
12492    /// Current thread must not be detached from JNI.
12493    ///
12494    /// Current thread must not be currently throwing an exception.
12495    ///
12496    /// Current thread does not hold a critical reference.
12497    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12498    ///
12499    /// `obj` must a valid and not already garbage collected.
12500    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a char
12501    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
12502    /// `args` union must contain types that match the java methods parameters.
12503    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
12504    ///
12505    pub unsafe fn CallNonvirtualCharMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) -> jchar {
12506        unsafe {
12507            #[cfg(feature = "asserts")]
12508            {
12509                self.check_not_critical("CallNonvirtualCharMethodA");
12510                self.check_no_exception("CallNonvirtualCharMethodA");
12511                self.check_return_type_object("CallNonvirtualCharMethodA", obj, methodID, "char");
12512                self.check_is_class("CallNonvirtualCharMethodA", class);
12513            }
12514            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype) -> jchar>(75)(self.vtable, obj, class, methodID, args)
12515        }
12516    }
12517
12518    ///
12519    /// Calls a non-static java method with 0 arguments that returns char without using the objects vtable to look up the method.
12520    /// This means that should the object be a subclass of the class that the method is declared in
12521    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12522    ///
12523    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12524    ///
12525    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12526    ///
12527    ///
12528    /// # Arguments
12529    /// * `obj` - which object the method should be called on
12530    ///     * must be valid
12531    ///     * must not be null
12532    ///     * must not be already garbage collected
12533    /// * `methodID` - method id of the method
12534    ///     * must not be null
12535    ///     * must be valid
12536    ///     * must not be a static
12537    ///     * must actually be a method of `obj`
12538    ///     * must refer to a method with 0 arguments
12539    ///
12540    /// # Returns
12541    /// Whatever the method returned or 0 if it threw
12542    ///
12543    /// # Throws Java Exception
12544    /// * Whatever the method threw
12545    ///
12546    ///
12547    /// # Panics
12548    /// if asserts feature is enabled and UB was detected
12549    ///
12550    /// # Safety
12551    ///
12552    /// Current thread must not be detached from JNI.
12553    ///
12554    /// Current thread must not be currently throwing an exception.
12555    ///
12556    /// Current thread does not hold a critical reference.
12557    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12558    ///
12559    /// `obj` must a valid and not already garbage collected.
12560    /// `methodID` must be valid, non-static and actually be a method of `obj`, return char and have 0 arguments
12561    ///
12562    pub unsafe fn CallNonvirtualCharMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) -> jchar {
12563        unsafe {
12564            #[cfg(feature = "asserts")]
12565            {
12566                self.check_not_critical("CallNonvirtualCharMethod");
12567                self.check_no_exception("CallNonvirtualCharMethod");
12568                self.check_return_type_object("CallNonvirtualCharMethod", obj, methodID, "char");
12569                self.check_is_class("CallNonvirtualCharMethod", class);
12570            }
12571            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID) -> jchar>(73)(self.vtable, obj, class, methodID)
12572        }
12573    }
12574
12575    ///
12576    /// Calls a non-static java method with 1 arguments that returns char without using the objects vtable to look up the method.
12577    /// This means that should the object be a subclass of the class that the method is declared in
12578    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12579    ///
12580    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12581    ///
12582    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12583    ///
12584    ///
12585    /// # Arguments
12586    /// * `obj` - which object the method should be called on
12587    ///     * must be valid
12588    ///     * must not be null
12589    ///     * must not be already garbage collected
12590    /// * `methodID` - method id of the method
12591    ///     * must not be null
12592    ///     * must be valid
12593    ///     * must not be a static
12594    ///     * must actually be a method of `obj`
12595    ///     * must refer to a method with 1 arguments
12596    ///
12597    /// # Returns
12598    /// Whatever the method returned or 0 if it threw
12599    ///
12600    /// # Throws Java Exception
12601    /// * Whatever the method threw
12602    ///
12603    ///
12604    /// # Panics
12605    /// if asserts feature is enabled and UB was detected
12606    ///
12607    /// # Safety
12608    ///
12609    /// Current thread must not be detached from JNI.
12610    ///
12611    /// Current thread must not be currently throwing an exception.
12612    ///
12613    /// Current thread does not hold a critical reference.
12614    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12615    ///
12616    /// `obj` must a valid and not already garbage collected.
12617    /// `methodID` must be valid, non-static and actually be a method of `obj`, return char and have 1 arguments
12618    ///
12619    pub unsafe fn CallNonvirtualCharMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) -> jchar {
12620        unsafe {
12621            #[cfg(feature = "asserts")]
12622            {
12623                self.check_not_critical("CallNonvirtualCharMethod");
12624                self.check_no_exception("CallNonvirtualCharMethod");
12625                self.check_return_type_object("CallNonvirtualCharMethod", obj, methodID, "char");
12626                self.check_is_class("CallNonvirtualCharMethod", class);
12627                self.check_parameter_types_object("CallNonvirtualCharMethod", obj, methodID, arg1, 0, 1);
12628            }
12629            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jchar>(73)(self.vtable, obj, class, methodID, arg1)
12630        }
12631    }
12632
12633    ///
12634    /// Calls a non-static java method with 2 arguments that returns char without using the objects vtable to look up the method.
12635    /// This means that should the object be a subclass of the class that the method is declared in
12636    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12637    ///
12638    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12639    ///
12640    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12641    ///
12642    ///
12643    /// # Arguments
12644    /// * `obj` - which object the method should be called on
12645    ///     * must be valid
12646    ///     * must not be null
12647    ///     * must not be already garbage collected
12648    /// * `methodID` - method id of the method
12649    ///     * must not be null
12650    ///     * must be valid
12651    ///     * must not be a static
12652    ///     * must actually be a method of `obj`
12653    ///     * must refer to a method with 2 arguments
12654    ///
12655    /// # Returns
12656    /// Whatever the method returned or 0 if it threw
12657    ///
12658    /// # Throws Java Exception
12659    /// * Whatever the method threw
12660    ///
12661    ///
12662    /// # Panics
12663    /// if asserts feature is enabled and UB was detected
12664    ///
12665    /// # Safety
12666    ///
12667    /// Current thread must not be detached from JNI.
12668    ///
12669    /// Current thread must not be currently throwing an exception.
12670    ///
12671    /// Current thread does not hold a critical reference.
12672    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12673    ///
12674    /// `obj` must a valid and not already garbage collected.
12675    /// `methodID` must be valid, non-static and actually be a method of `obj`, return char and have 2 arguments
12676    ///
12677    pub unsafe fn CallNonvirtualCharMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jchar {
12678        unsafe {
12679            #[cfg(feature = "asserts")]
12680            {
12681                self.check_not_critical("CallNonvirtualCharMethod");
12682                self.check_no_exception("CallNonvirtualCharMethod");
12683                self.check_return_type_object("CallNonvirtualCharMethod", obj, methodID, "char");
12684                self.check_is_class("CallNonvirtualCharMethod", class);
12685                self.check_parameter_types_object("CallNonvirtualCharMethod", obj, methodID, arg1, 0, 2);
12686                self.check_parameter_types_object("CallNonvirtualCharMethod", obj, methodID, arg2, 1, 2);
12687            }
12688            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jchar>(73)(self.vtable, obj, class, methodID, arg1, arg2)
12689        }
12690    }
12691
12692    ///
12693    /// Calls a non-static java method with 3 arguments that returns char without using the objects vtable to look up the method.
12694    /// This means that should the object be a subclass of the class that the method is declared in
12695    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12696    ///
12697    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12698    ///
12699    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12700    ///
12701    ///
12702    /// # Arguments
12703    /// * `obj` - which object the method should be called on
12704    ///     * must be valid
12705    ///     * must not be null
12706    ///     * must not be already garbage collected
12707    /// * `methodID` - method id of the method
12708    ///     * must not be null
12709    ///     * must be valid
12710    ///     * must not be a static
12711    ///     * must actually be a method of `obj`
12712    ///     * must refer to a method with 3 arguments
12713    ///
12714    /// # Returns
12715    /// Whatever the method returned or 0 if it threw
12716    ///
12717    /// # Throws Java Exception
12718    /// * Whatever the method threw
12719    ///
12720    ///
12721    /// # Panics
12722    /// if asserts feature is enabled and UB was detected
12723    ///
12724    /// # Safety
12725    ///
12726    /// Current thread must not be detached from JNI.
12727    ///
12728    /// Current thread must not be currently throwing an exception.
12729    ///
12730    /// Current thread does not hold a critical reference.
12731    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12732    ///
12733    /// `obj` must a valid and not already garbage collected.
12734    /// `methodID` must be valid, non-static and actually be a method of `obj`, return char and have 3 arguments
12735    ///
12736    pub unsafe fn CallNonvirtualCharMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jchar {
12737        unsafe {
12738            #[cfg(feature = "asserts")]
12739            {
12740                self.check_not_critical("CallNonvirtualCharMethod");
12741                self.check_no_exception("CallNonvirtualCharMethod");
12742                self.check_return_type_object("CallNonvirtualCharMethod", obj, methodID, "char");
12743                self.check_is_class("CallNonvirtualCharMethod", class);
12744                self.check_parameter_types_object("CallNonvirtualCharMethod", obj, methodID, arg1, 0, 3);
12745                self.check_parameter_types_object("CallNonvirtualCharMethod", obj, methodID, arg2, 1, 3);
12746                self.check_parameter_types_object("CallNonvirtualCharMethod", obj, methodID, arg3, 2, 3);
12747            }
12748            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jchar>(73)(self.vtable, obj, class, methodID, arg1, arg2, arg3)
12749        }
12750    }
12751
12752    ///
12753    /// Calls a non-static java method with 3 arguments that returns short without using the objects vtable to look up the method.
12754    /// This means that should the object be a subclass of the class that the method is declared in
12755    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12756    ///
12757    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12758    ///
12759    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12760    ///
12761    ///
12762    /// # Arguments
12763    /// * `obj` - which object the method should be called on
12764    ///     * must be valid
12765    ///     * must not be null
12766    ///     * must not be already garbage collected
12767    /// * `methodID` - method id of the method
12768    ///     * must not be null
12769    ///     * must be valid
12770    ///     * must not be a static
12771    ///     * must actually be a method of `obj`
12772    /// * `args` - argument pointer
12773    ///     * can be null if the method has no arguments
12774    ///     * must not be null otherwise and point to the exact number of arguments the method expects
12775    ///
12776    /// # Returns
12777    /// Whatever the method returned or 0 if it threw
12778    ///
12779    /// # Throws Java Exception
12780    /// * Whatever the method threw
12781    ///
12782    ///
12783    /// # Panics
12784    /// if asserts feature is enabled and UB was detected
12785    ///
12786    /// # Safety
12787    ///
12788    /// Current thread must not be detached from JNI.
12789    ///
12790    /// Current thread must not be currently throwing an exception.
12791    ///
12792    /// Current thread does not hold a critical reference.
12793    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12794    ///
12795    /// `obj` must a valid and not already garbage collected.
12796    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a short
12797    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
12798    /// `args` union must contain types that match the java methods parameters.
12799    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
12800    ///
12801    pub unsafe fn CallNonvirtualShortMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) -> jshort {
12802        unsafe {
12803            #[cfg(feature = "asserts")]
12804            {
12805                self.check_not_critical("CallNonvirtualShortMethodA");
12806                self.check_no_exception("CallNonvirtualShortMethodA");
12807                self.check_return_type_object("CallNonvirtualShortMethodA", obj, methodID, "short");
12808                self.check_is_class("CallNonvirtualShortMethodA", class);
12809            }
12810            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype) -> jshort>(78)(self.vtable, obj, class, methodID, args)
12811        }
12812    }
12813
12814    ///
12815    /// Calls a non-static java method with 0 arguments that returns short without using the objects vtable to look up the method.
12816    /// This means that should the object be a subclass of the class that the method is declared in
12817    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12818    ///
12819    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12820    ///
12821    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12822    ///
12823    ///
12824    /// # Arguments
12825    /// * `obj` - which object the method should be called on
12826    ///     * must be valid
12827    ///     * must not be null
12828    ///     * must not be already garbage collected
12829    /// * `methodID` - method id of the method
12830    ///     * must not be null
12831    ///     * must be valid
12832    ///     * must not be a static
12833    ///     * must actually be a method of `obj`
12834    ///     * must refer to a method with 0 arguments
12835    ///
12836    /// # Returns
12837    /// Whatever the method returned or 0 if it threw
12838    ///
12839    /// # Throws Java Exception
12840    /// * Whatever the method threw
12841    ///
12842    ///
12843    /// # Panics
12844    /// if asserts feature is enabled and UB was detected
12845    ///
12846    /// # Safety
12847    ///
12848    /// Current thread must not be detached from JNI.
12849    ///
12850    /// Current thread must not be currently throwing an exception.
12851    ///
12852    /// Current thread does not hold a critical reference.
12853    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12854    ///
12855    /// `obj` must a valid and not already garbage collected.
12856    /// `methodID` must be valid, non-static and actually be a method of `obj`, return short and have 0 arguments
12857    ///
12858    pub unsafe fn CallNonvirtualShortMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) -> jshort {
12859        unsafe {
12860            #[cfg(feature = "asserts")]
12861            {
12862                self.check_not_critical("CallNonvirtualShortMethod");
12863                self.check_no_exception("CallNonvirtualShortMethod");
12864                self.check_return_type_object("CallNonvirtualShortMethod", obj, methodID, "short");
12865                self.check_is_class("CallNonvirtualShortMethod", class);
12866            }
12867            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID) -> jshort>(76)(self.vtable, obj, class, methodID)
12868        }
12869    }
12870
12871    ///
12872    /// Calls a non-static java method with 1 arguments that returns short without using the objects vtable to look up the method.
12873    /// This means that should the object be a subclass of the class that the method is declared in
12874    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12875    ///
12876    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12877    ///
12878    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12879    ///
12880    ///
12881    /// # Arguments
12882    /// * `obj` - which object the method should be called on
12883    ///     * must be valid
12884    ///     * must not be null
12885    ///     * must not be already garbage collected
12886    /// * `methodID` - method id of the method
12887    ///     * must not be null
12888    ///     * must be valid
12889    ///     * must not be a static
12890    ///     * must actually be a method of `obj`
12891    ///     * must refer to a method with 1 arguments
12892    ///
12893    /// # Returns
12894    /// Whatever the method returned or 0 if it threw
12895    ///
12896    /// # Throws Java Exception
12897    /// * Whatever the method threw
12898    ///
12899    ///
12900    /// # Panics
12901    /// if asserts feature is enabled and UB was detected
12902    ///
12903    /// # Safety
12904    ///
12905    /// Current thread must not be detached from JNI.
12906    ///
12907    /// Current thread must not be currently throwing an exception.
12908    ///
12909    /// Current thread does not hold a critical reference.
12910    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12911    ///
12912    /// `obj` must a valid and not already garbage collected.
12913    /// `methodID` must be valid, non-static and actually be a method of `obj`, return short and have 1 arguments
12914    ///
12915    pub unsafe fn CallNonvirtualShortMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) -> jshort {
12916        unsafe {
12917            #[cfg(feature = "asserts")]
12918            {
12919                self.check_not_critical("CallNonvirtualShortMethod");
12920                self.check_no_exception("CallNonvirtualShortMethod");
12921                self.check_return_type_object("CallNonvirtualShortMethod", obj, methodID, "short");
12922                self.check_is_class("CallNonvirtualShortMethod", class);
12923                self.check_parameter_types_object("CallNonvirtualShortMethod", obj, methodID, arg1, 0, 1);
12924            }
12925            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jshort>(76)(self.vtable, obj, class, methodID, arg1)
12926        }
12927    }
12928
12929    ///
12930    /// Calls a non-static java method with 2 arguments that returns short without using the objects vtable to look up the method.
12931    /// This means that should the object be a subclass of the class that the method is declared in
12932    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12933    ///
12934    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12935    ///
12936    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12937    ///
12938    ///
12939    /// # Arguments
12940    /// * `obj` - which object the method should be called on
12941    ///     * must be valid
12942    ///     * must not be null
12943    ///     * must not be already garbage collected
12944    /// * `methodID` - method id of the method
12945    ///     * must not be null
12946    ///     * must be valid
12947    ///     * must not be a static
12948    ///     * must actually be a method of `obj`
12949    ///     * must refer to a method with 2 arguments
12950    ///
12951    /// # Returns
12952    /// Whatever the method returned or 0 if it threw
12953    ///
12954    /// # Throws Java Exception
12955    /// * Whatever the method threw
12956    ///
12957    ///
12958    /// # Panics
12959    /// if asserts feature is enabled and UB was detected
12960    ///
12961    /// # Safety
12962    ///
12963    /// Current thread must not be detached from JNI.
12964    ///
12965    /// Current thread must not be currently throwing an exception.
12966    ///
12967    /// Current thread does not hold a critical reference.
12968    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
12969    ///
12970    /// `obj` must a valid and not already garbage collected.
12971    /// `methodID` must be valid, non-static and actually be a method of `obj`, return short and have 2 arguments
12972    ///
12973    pub unsafe fn CallNonvirtualShortMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jshort {
12974        unsafe {
12975            #[cfg(feature = "asserts")]
12976            {
12977                self.check_not_critical("CallNonvirtualShortMethod");
12978                self.check_no_exception("CallNonvirtualShortMethod");
12979                self.check_return_type_object("CallNonvirtualShortMethod", obj, methodID, "short");
12980                self.check_is_class("CallNonvirtualShortMethod", class);
12981                self.check_parameter_types_object("CallNonvirtualShortMethod", obj, methodID, arg1, 0, 2);
12982                self.check_parameter_types_object("CallNonvirtualShortMethod", obj, methodID, arg2, 1, 2);
12983            }
12984            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jshort>(76)(self.vtable, obj, class, methodID, arg1, arg2)
12985        }
12986    }
12987
12988    ///
12989    /// Calls a non-static java method with 3 arguments that returns short without using the objects vtable to look up the method.
12990    /// This means that should the object be a subclass of the class that the method is declared in
12991    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
12992    ///
12993    /// This is roughly equivalent to calling "super.someMethod(...)" in java
12994    ///
12995    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
12996    ///
12997    ///
12998    /// # Arguments
12999    /// * `obj` - which object the method should be called on
13000    ///     * must be valid
13001    ///     * must not be null
13002    ///     * must not be already garbage collected
13003    /// * `methodID` - method id of the method
13004    ///     * must not be null
13005    ///     * must be valid
13006    ///     * must not be a static
13007    ///     * must actually be a method of `obj`
13008    ///     * must refer to a method with 3 arguments
13009    ///
13010    /// # Returns
13011    /// Whatever the method returned or 0 if it threw
13012    ///
13013    /// # Throws Java Exception
13014    /// * Whatever the method threw
13015    ///
13016    ///
13017    /// # Panics
13018    /// if asserts feature is enabled and UB was detected
13019    ///
13020    /// # Safety
13021    ///
13022    /// Current thread must not be detached from JNI.
13023    ///
13024    /// Current thread must not be currently throwing an exception.
13025    ///
13026    /// Current thread does not hold a critical reference.
13027    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13028    ///
13029    /// `obj` must a valid and not already garbage collected.
13030    /// `methodID` must be valid, non-static and actually be a method of `obj`, return short and have 3 arguments
13031    ///
13032    pub unsafe fn CallNonvirtualShortMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jshort {
13033        unsafe {
13034            #[cfg(feature = "asserts")]
13035            {
13036                self.check_not_critical("CallNonvirtualShortMethod");
13037                self.check_no_exception("CallNonvirtualShortMethod");
13038                self.check_return_type_object("CallNonvirtualShortMethod", obj, methodID, "short");
13039                self.check_is_class("CallNonvirtualShortMethod", class);
13040                self.check_parameter_types_object("CallNonvirtualShortMethod", obj, methodID, arg1, 0, 3);
13041                self.check_parameter_types_object("CallNonvirtualShortMethod", obj, methodID, arg2, 1, 3);
13042                self.check_parameter_types_object("CallNonvirtualShortMethod", obj, methodID, arg3, 2, 3);
13043            }
13044            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jshort>(76)(self.vtable, obj, class, methodID, arg1, arg2, arg3)
13045        }
13046    }
13047
13048    ///
13049    /// Calls a non-static java method with 3 arguments that returns int without using the objects vtable to look up the method.
13050    /// This means that should the object be a subclass of the class that the method is declared in
13051    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13052    ///
13053    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13054    ///
13055    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13056    ///
13057    ///
13058    /// # Arguments
13059    /// * `obj` - which object the method should be called on
13060    ///     * must be valid
13061    ///     * must not be null
13062    ///     * must not be already garbage collected
13063    /// * `methodID` - method id of the method
13064    ///     * must not be null
13065    ///     * must be valid
13066    ///     * must not be a static
13067    ///     * must actually be a method of `obj`
13068    /// * `args` - argument pointer
13069    ///     * can be null if the method has no arguments
13070    ///     * must not be null otherwise and point to the exact number of arguments the method expects
13071    ///
13072    /// # Returns
13073    /// Whatever the method returned or 0 if it threw
13074    ///
13075    /// # Throws Java Exception
13076    /// * Whatever the method threw
13077    ///
13078    ///
13079    /// # Panics
13080    /// if asserts feature is enabled and UB was detected
13081    ///
13082    /// # Safety
13083    ///
13084    /// Current thread must not be detached from JNI.
13085    ///
13086    /// Current thread must not be currently throwing an exception.
13087    ///
13088    /// Current thread does not hold a critical reference.
13089    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13090    ///
13091    /// `obj` must a valid and not already garbage collected.
13092    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a int
13093    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
13094    /// `args` union must contain types that match the java methods parameters.
13095    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
13096    ///
13097    pub unsafe fn CallNonvirtualIntMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) -> jint {
13098        unsafe {
13099            #[cfg(feature = "asserts")]
13100            {
13101                self.check_not_critical("CallNonvirtualIntMethodA");
13102                self.check_no_exception("CallNonvirtualIntMethodA");
13103                self.check_return_type_object("CallNonvirtualIntMethodA", obj, methodID, "int");
13104                self.check_is_class("CallNonvirtualIntMethodA", class);
13105            }
13106            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype) -> jint>(81)(self.vtable, obj, class, methodID, args)
13107        }
13108    }
13109
13110    ///
13111    /// Calls a non-static java method with 0 arguments that returns short without using the objects vtable to look up the method.
13112    /// This means that should the object be a subclass of the class that the method is declared in
13113    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13114    ///
13115    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13116    ///
13117    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13118    ///
13119    ///
13120    /// # Arguments
13121    /// * `obj` - which object the method should be called on
13122    ///     * must be valid
13123    ///     * must not be null
13124    ///     * must not be already garbage collected
13125    /// * `methodID` - method id of the method
13126    ///     * must not be null
13127    ///     * must be valid
13128    ///     * must not be a static
13129    ///     * must actually be a method of `obj`
13130    ///     * must refer to a method with 0 arguments
13131    ///
13132    /// # Returns
13133    /// Whatever the method returned or 0 if it threw
13134    ///
13135    /// # Throws Java Exception
13136    /// * Whatever the method threw
13137    ///
13138    ///
13139    /// # Panics
13140    /// if asserts feature is enabled and UB was detected
13141    ///
13142    /// # Safety
13143    ///
13144    /// Current thread must not be detached from JNI.
13145    ///
13146    /// Current thread must not be currently throwing an exception.
13147    ///
13148    /// Current thread does not hold a critical reference.
13149    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13150    ///
13151    /// `obj` must a valid and not already garbage collected.
13152    /// `methodID` must be valid, non-static and actually be a method of `obj`, return int and have 0 arguments
13153    ///
13154    pub unsafe fn CallNonvirtualIntMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) -> jint {
13155        unsafe {
13156            #[cfg(feature = "asserts")]
13157            {
13158                self.check_not_critical("CallNonvirtualIntMethod");
13159                self.check_no_exception("CallNonvirtualIntMethod");
13160                self.check_return_type_object("CallNonvirtualIntMethod", obj, methodID, "int");
13161                self.check_is_class("CallNonvirtualIntMethod", class);
13162            }
13163            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID) -> jint>(79)(self.vtable, obj, class, methodID)
13164        }
13165    }
13166
13167    ///
13168    /// Calls a non-static java method with 1 arguments that returns int without using the objects vtable to look up the method.
13169    /// This means that should the object be a subclass of the class that the method is declared in
13170    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13171    ///
13172    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13173    ///
13174    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13175    ///
13176    ///
13177    /// # Arguments
13178    /// * `obj` - which object the method should be called on
13179    ///     * must be valid
13180    ///     * must not be null
13181    ///     * must not be already garbage collected
13182    /// * `methodID` - method id of the method
13183    ///     * must not be null
13184    ///     * must be valid
13185    ///     * must not be a static
13186    ///     * must actually be a method of `obj`
13187    ///     * must refer to a method with 1 arguments
13188    ///
13189    /// # Returns
13190    /// Whatever the method returned or 0 if it threw
13191    ///
13192    /// # Throws Java Exception
13193    /// * Whatever the method threw
13194    ///
13195    ///
13196    /// # Panics
13197    /// if asserts feature is enabled and UB was detected
13198    ///
13199    /// # Safety
13200    ///
13201    /// Current thread must not be detached from JNI.
13202    ///
13203    /// Current thread must not be currently throwing an exception.
13204    ///
13205    /// Current thread does not hold a critical reference.
13206    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13207    ///
13208    /// `obj` must a valid and not already garbage collected.
13209    /// `methodID` must be valid, non-static and actually be a method of `obj`, return int and have 1 arguments
13210    ///
13211    pub unsafe fn CallNonvirtualIntMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) -> jint {
13212        unsafe {
13213            #[cfg(feature = "asserts")]
13214            {
13215                self.check_not_critical("CallNonvirtualIntMethod");
13216                self.check_no_exception("CallNonvirtualIntMethod");
13217                self.check_return_type_object("CallNonvirtualIntMethod", obj, methodID, "int");
13218                self.check_is_class("CallNonvirtualIntMethod", class);
13219                self.check_parameter_types_object("CallNonvirtualIntMethod", obj, methodID, arg1, 0, 1);
13220            }
13221            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jint>(79)(self.vtable, obj, class, methodID, arg1)
13222        }
13223    }
13224
13225    ///
13226    /// Calls a non-static java method with 2 arguments that returns int without using the objects vtable to look up the method.
13227    /// This means that should the object be a subclass of the class that the method is declared in
13228    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13229    ///
13230    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13231    ///
13232    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13233    ///
13234    ///
13235    /// # Arguments
13236    /// * `obj` - which object the method should be called on
13237    ///     * must be valid
13238    ///     * must not be null
13239    ///     * must not be already garbage collected
13240    /// * `methodID` - method id of the method
13241    ///     * must not be null
13242    ///     * must be valid
13243    ///     * must not be a static
13244    ///     * must actually be a method of `obj`
13245    ///     * must refer to a method with 2 arguments
13246    ///
13247    /// # Returns
13248    /// Whatever the method returned or 0 if it threw
13249    ///
13250    /// # Throws Java Exception
13251    /// * Whatever the method threw
13252    ///
13253    ///
13254    /// # Panics
13255    /// if asserts feature is enabled and UB was detected
13256    ///
13257    /// # Safety
13258    ///
13259    /// Current thread must not be detached from JNI.
13260    ///
13261    /// Current thread must not be currently throwing an exception.
13262    ///
13263    /// Current thread does not hold a critical reference.
13264    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13265    ///
13266    /// `obj` must a valid and not already garbage collected.
13267    /// `methodID` must be valid, non-static and actually be a method of `obj`, return int and have 2 arguments
13268    ///
13269    pub unsafe fn CallNonvirtualIntMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jint {
13270        unsafe {
13271            #[cfg(feature = "asserts")]
13272            {
13273                self.check_not_critical("CallNonvirtualIntMethod");
13274                self.check_no_exception("CallNonvirtualIntMethod");
13275                self.check_return_type_object("CallNonvirtualIntMethod", obj, methodID, "int");
13276                self.check_is_class("CallNonvirtualIntMethod", class);
13277                self.check_parameter_types_object("CallNonvirtualIntMethod", obj, methodID, arg1, 0, 2);
13278                self.check_parameter_types_object("CallNonvirtualIntMethod", obj, methodID, arg2, 1, 2);
13279            }
13280            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jint>(79)(self.vtable, obj, class, methodID, arg1, arg2)
13281        }
13282    }
13283
13284    ///
13285    /// Calls a non-static java method with 3 arguments that returns int without using the objects vtable to look up the method.
13286    /// This means that should the object be a subclass of the class that the method is declared in
13287    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13288    ///
13289    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13290    ///
13291    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13292    ///
13293    ///
13294    /// # Arguments
13295    /// * `obj` - which object the method should be called on
13296    ///     * must be valid
13297    ///     * must not be null
13298    ///     * must not be already garbage collected
13299    /// * `methodID` - method id of the method
13300    ///     * must not be null
13301    ///     * must be valid
13302    ///     * must not be a static
13303    ///     * must actually be a method of `obj`
13304    ///     * must refer to a method with 3 arguments
13305    ///
13306    /// # Returns
13307    /// Whatever the method returned or 0 if it threw
13308    ///
13309    /// # Throws Java Exception
13310    /// * Whatever the method threw
13311    ///
13312    ///
13313    /// # Panics
13314    /// if asserts feature is enabled and UB was detected
13315    ///
13316    /// # Safety
13317    ///
13318    /// Current thread must not be detached from JNI.
13319    ///
13320    /// Current thread must not be currently throwing an exception.
13321    ///
13322    /// Current thread does not hold a critical reference.
13323    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13324    ///
13325    /// `obj` must a valid and not already garbage collected.
13326    /// `methodID` must be valid, non-static and actually be a method of `obj`, return int and have 3 arguments
13327    ///
13328    pub unsafe fn CallNonvirtualIntMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jint {
13329        unsafe {
13330            #[cfg(feature = "asserts")]
13331            {
13332                self.check_not_critical("CallNonvirtualIntMethod");
13333                self.check_no_exception("CallNonvirtualIntMethod");
13334                self.check_return_type_object("CallNonvirtualIntMethod", obj, methodID, "int");
13335                self.check_is_class("CallNonvirtualIntMethod", class);
13336                self.check_parameter_types_object("CallNonvirtualIntMethod", obj, methodID, arg1, 0, 3);
13337                self.check_parameter_types_object("CallNonvirtualIntMethod", obj, methodID, arg2, 1, 3);
13338                self.check_parameter_types_object("CallNonvirtualIntMethod", obj, methodID, arg3, 2, 3);
13339            }
13340            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jint>(79)(self.vtable, obj, class, methodID, arg1, arg2, arg3)
13341        }
13342    }
13343
13344    ///
13345    /// Calls a non-static java method with 3 arguments that returns long without using the objects vtable to look up the method.
13346    /// This means that should the object be a subclass of the class that the method is declared in
13347    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13348    ///
13349    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13350    ///
13351    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13352    ///
13353    ///
13354    /// # Arguments
13355    /// * `obj` - which object the method should be called on
13356    ///     * must be valid
13357    ///     * must not be null
13358    ///     * must not be already garbage collected
13359    /// * `methodID` - method id of the method
13360    ///     * must not be null
13361    ///     * must be valid
13362    ///     * must not be a static
13363    ///     * must actually be a method of `obj`
13364    /// * `args` - argument pointer
13365    ///     * can be null if the method has no arguments
13366    ///     * must not be null otherwise and point to the exact number of arguments the method expects
13367    ///
13368    /// # Returns
13369    /// Whatever the method returned or 0 if it threw
13370    ///
13371    /// # Throws Java Exception
13372    /// * Whatever the method threw
13373    ///
13374    ///
13375    /// # Panics
13376    /// if asserts feature is enabled and UB was detected
13377    ///
13378    /// # Safety
13379    ///
13380    /// Current thread must not be detached from JNI.
13381    ///
13382    /// Current thread must not be currently throwing an exception.
13383    ///
13384    /// Current thread does not hold a critical reference.
13385    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13386    ///
13387    /// `obj` must a valid and not already garbage collected.
13388    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a long
13389    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
13390    /// `args` union must contain types that match the java methods parameters.
13391    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
13392    ///
13393    pub unsafe fn CallNonvirtualLongMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) -> jlong {
13394        unsafe {
13395            #[cfg(feature = "asserts")]
13396            {
13397                self.check_not_critical("CallNonvirtualLongMethodA");
13398                self.check_no_exception("CallNonvirtualLongMethodA");
13399                self.check_return_type_object("CallNonvirtualLongMethodA", obj, methodID, "long");
13400                self.check_is_class("CallNonvirtualLongMethodA", class);
13401            }
13402            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype) -> jlong>(84)(self.vtable, obj, class, methodID, args)
13403        }
13404    }
13405
13406    ///
13407    /// Calls a non-static java method with 0 arguments that returns long without using the objects vtable to look up the method.
13408    /// This means that should the object be a subclass of the class that the method is declared in
13409    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13410    ///
13411    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13412    ///
13413    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13414    ///
13415    ///
13416    /// # Arguments
13417    /// * `obj` - which object the method should be called on
13418    ///     * must be valid
13419    ///     * must not be null
13420    ///     * must not be already garbage collected
13421    /// * `methodID` - method id of the method
13422    ///     * must not be null
13423    ///     * must be valid
13424    ///     * must not be a static
13425    ///     * must actually be a method of `obj`
13426    ///     * must refer to a method with 0 arguments
13427    ///
13428    /// # Returns
13429    /// Whatever the method returned or 0 if it threw
13430    ///
13431    /// # Throws Java Exception
13432    /// * Whatever the method threw
13433    ///
13434    ///
13435    /// # Panics
13436    /// if asserts feature is enabled and UB was detected
13437    ///
13438    /// # Safety
13439    ///
13440    /// Current thread must not be detached from JNI.
13441    ///
13442    /// Current thread must not be currently throwing an exception.
13443    ///
13444    /// Current thread does not hold a critical reference.
13445    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13446    ///
13447    /// `obj` must a valid and not already garbage collected.
13448    /// `methodID` must be valid, non-static and actually be a method of `obj`, return long and have 0 arguments
13449    ///
13450    pub unsafe fn CallNonvirtualLongMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) -> jlong {
13451        unsafe {
13452            #[cfg(feature = "asserts")]
13453            {
13454                self.check_not_critical("CallNonvirtualLongMethod");
13455                self.check_no_exception("CallNonvirtualLongMethod");
13456                self.check_return_type_object("CallNonvirtualLongMethod", obj, methodID, "long");
13457                self.check_is_class("CallNonvirtualLongMethod", class);
13458            }
13459            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID) -> jlong>(82)(self.vtable, obj, class, methodID)
13460        }
13461    }
13462
13463    ///
13464    /// Calls a non-static java method with 1 arguments that returns long without using the objects vtable to look up the method.
13465    /// This means that should the object be a subclass of the class that the method is declared in
13466    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13467    ///
13468    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13469    ///
13470    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13471    ///
13472    ///
13473    /// # Arguments
13474    /// * `obj` - which object the method should be called on
13475    ///     * must be valid
13476    ///     * must not be null
13477    ///     * must not be already garbage collected
13478    /// * `methodID` - method id of the method
13479    ///     * must not be null
13480    ///     * must be valid
13481    ///     * must not be a static
13482    ///     * must actually be a method of `obj`
13483    ///     * must refer to a method with 1 arguments
13484    ///
13485    /// # Returns
13486    /// Whatever the method returned or 0 if it threw
13487    ///
13488    /// # Throws Java Exception
13489    /// * Whatever the method threw
13490    ///
13491    ///
13492    /// # Panics
13493    /// if asserts feature is enabled and UB was detected
13494    ///
13495    /// # Safety
13496    ///
13497    /// Current thread must not be detached from JNI.
13498    ///
13499    /// Current thread must not be currently throwing an exception.
13500    ///
13501    /// Current thread does not hold a critical reference.
13502    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13503    ///
13504    /// `obj` must a valid and not already garbage collected.
13505    /// `methodID` must be valid, non-static and actually be a method of `obj`, return long and have 1 arguments
13506    ///
13507    pub unsafe fn CallNonvirtualLongMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) -> jlong {
13508        unsafe {
13509            #[cfg(feature = "asserts")]
13510            {
13511                self.check_not_critical("CallNonvirtualLongMethod");
13512                self.check_no_exception("CallNonvirtualLongMethod");
13513                self.check_return_type_object("CallNonvirtualLongMethod", obj, methodID, "long");
13514                self.check_is_class("CallNonvirtualLongMethod", class);
13515                self.check_parameter_types_object("CallNonvirtualLongMethod", obj, methodID, arg1, 0, 1);
13516            }
13517            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jlong>(82)(self.vtable, obj, class, methodID, arg1)
13518        }
13519    }
13520
13521    ///
13522    /// Calls a non-static java method with 2 arguments that returns long without using the objects vtable to look up the method.
13523    /// This means that should the object be a subclass of the class that the method is declared in
13524    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13525    ///
13526    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13527    ///
13528    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13529    ///
13530    ///
13531    /// # Arguments
13532    /// * `obj` - which object the method should be called on
13533    ///     * must be valid
13534    ///     * must not be null
13535    ///     * must not be already garbage collected
13536    /// * `methodID` - method id of the method
13537    ///     * must not be null
13538    ///     * must be valid
13539    ///     * must not be a static
13540    ///     * must actually be a method of `obj`
13541    ///     * must refer to a method with 2 arguments
13542    ///
13543    /// # Returns
13544    /// Whatever the method returned or 0 if it threw
13545    ///
13546    /// # Throws Java Exception
13547    /// * Whatever the method threw
13548    ///
13549    ///
13550    /// # Panics
13551    /// if asserts feature is enabled and UB was detected
13552    ///
13553    /// # Safety
13554    ///
13555    /// Current thread must not be detached from JNI.
13556    ///
13557    /// Current thread must not be currently throwing an exception.
13558    ///
13559    /// Current thread does not hold a critical reference.
13560    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13561    ///
13562    /// `obj` must a valid and not already garbage collected.
13563    /// `methodID` must be valid, non-static and actually be a method of `obj`, return long and have 2 arguments
13564    ///
13565    pub unsafe fn CallNonvirtualLongMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jlong {
13566        unsafe {
13567            #[cfg(feature = "asserts")]
13568            {
13569                self.check_not_critical("CallNonvirtualLongMethod");
13570                self.check_no_exception("CallNonvirtualLongMethod");
13571                self.check_return_type_object("CallNonvirtualLongMethod", obj, methodID, "long");
13572                self.check_is_class("CallNonvirtualLongMethod", class);
13573                self.check_parameter_types_object("CallNonvirtualLongMethod", obj, methodID, arg1, 0, 2);
13574                self.check_parameter_types_object("CallNonvirtualLongMethod", obj, methodID, arg2, 1, 2);
13575            }
13576            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jlong>(82)(self.vtable, obj, class, methodID, arg1, arg2)
13577        }
13578    }
13579
13580    ///
13581    /// Calls a non-static java method with 3 arguments that returns long without using the objects vtable to look up the method.
13582    /// This means that should the object be a subclass of the class that the method is declared in
13583    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13584    ///
13585    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13586    ///
13587    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13588    ///
13589    ///
13590    /// # Arguments
13591    /// * `obj` - which object the method should be called on
13592    ///     * must be valid
13593    ///     * must not be null
13594    ///     * must not be already garbage collected
13595    /// * `methodID` - method id of the method
13596    ///     * must not be null
13597    ///     * must be valid
13598    ///     * must not be a static
13599    ///     * must actually be a method of `obj`
13600    ///     * must refer to a method with 3 arguments
13601    ///
13602    /// # Returns
13603    /// Whatever the method returned or 0 if it threw
13604    ///
13605    /// # Throws Java Exception
13606    /// * Whatever the method threw
13607    ///
13608    ///
13609    /// # Panics
13610    /// if asserts feature is enabled and UB was detected
13611    ///
13612    /// # Safety
13613    ///
13614    /// Current thread must not be detached from JNI.
13615    ///
13616    /// Current thread must not be currently throwing an exception.
13617    ///
13618    /// Current thread does not hold a critical reference.
13619    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13620    ///
13621    /// `obj` must a valid and not already garbage collected.
13622    /// `methodID` must be valid, non-static and actually be a method of `obj`, return long and have 3 arguments
13623    ///
13624    pub unsafe fn CallNonvirtualLongMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jlong {
13625        unsafe {
13626            #[cfg(feature = "asserts")]
13627            {
13628                self.check_not_critical("CallNonvirtualLongMethod");
13629                self.check_no_exception("CallNonvirtualLongMethod");
13630                self.check_return_type_object("CallNonvirtualLongMethod", obj, methodID, "long");
13631                self.check_is_class("CallNonvirtualLongMethod", class);
13632                self.check_parameter_types_object("CallNonvirtualLongMethod", obj, methodID, arg1, 0, 3);
13633                self.check_parameter_types_object("CallNonvirtualLongMethod", obj, methodID, arg2, 1, 3);
13634                self.check_parameter_types_object("CallNonvirtualLongMethod", obj, methodID, arg3, 2, 3);
13635            }
13636            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jlong>(82)(self.vtable, obj, class, methodID, arg1, arg2, arg3)
13637        }
13638    }
13639
13640    ///
13641    /// Calls a non-static java method with 3 arguments that returns float without using the objects vtable to look up the method.
13642    /// This means that should the object be a subclass of the class that the method is declared in
13643    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13644    ///
13645    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13646    ///
13647    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13648    ///
13649    ///
13650    /// # Arguments
13651    /// * `obj` - which object the method should be called on
13652    ///     * must be valid
13653    ///     * must not be null
13654    ///     * must not be already garbage collected
13655    /// * `methodID` - method id of the method
13656    ///     * must not be null
13657    ///     * must be valid
13658    ///     * must not be a static
13659    ///     * must actually be a method of `obj`
13660    /// * `args` - argument pointer
13661    ///     * can be null if the method has no arguments
13662    ///     * must not be null otherwise and point to the exact number of arguments the method expects
13663    ///
13664    /// # Returns
13665    /// Whatever the method returned or 0 if it threw
13666    ///
13667    /// # Throws Java Exception
13668    /// * Whatever the method threw
13669    ///
13670    ///
13671    /// # Panics
13672    /// if asserts feature is enabled and UB was detected
13673    ///
13674    /// # Safety
13675    ///
13676    /// Current thread must not be detached from JNI.
13677    ///
13678    /// Current thread must not be currently throwing an exception.
13679    ///
13680    /// Current thread does not hold a critical reference.
13681    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13682    ///
13683    /// `obj` must a valid and not already garbage collected.
13684    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a float
13685    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
13686    /// `args` union must contain types that match the java methods parameters.
13687    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
13688    ///
13689    pub unsafe fn CallNonvirtualFloatMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) -> jfloat {
13690        unsafe {
13691            #[cfg(feature = "asserts")]
13692            {
13693                self.check_not_critical("CallNonvirtualFloatMethodA");
13694                self.check_no_exception("CallNonvirtualFloatMethodA");
13695                self.check_return_type_object("CallNonvirtualFloatMethodA", obj, methodID, "float");
13696                self.check_is_class("CallNonvirtualFloatMethodA", class);
13697            }
13698            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype) -> jfloat>(87)(self.vtable, obj, class, methodID, args)
13699        }
13700    }
13701
13702    ///
13703    /// Calls a non-static java method with 0 arguments that returns float without using the objects vtable to look up the method.
13704    /// This means that should the object be a subclass of the class that the method is declared in
13705    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13706    ///
13707    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13708    ///
13709    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13710    ///
13711    ///
13712    /// # Arguments
13713    /// * `obj` - which object the method should be called on
13714    ///     * must be valid
13715    ///     * must not be null
13716    ///     * must not be already garbage collected
13717    /// * `methodID` - method id of the method
13718    ///     * must not be null
13719    ///     * must be valid
13720    ///     * must not be a static
13721    ///     * must actually be a method of `obj`
13722    ///     * must refer to a method with 0 arguments
13723    ///
13724    /// # Returns
13725    /// Whatever the method returned or 0 if it threw
13726    ///
13727    /// # Throws Java Exception
13728    /// * Whatever the method threw
13729    ///
13730    ///
13731    /// # Panics
13732    /// if asserts feature is enabled and UB was detected
13733    ///
13734    /// # Safety
13735    ///
13736    /// Current thread must not be detached from JNI.
13737    ///
13738    /// Current thread must not be currently throwing an exception.
13739    ///
13740    /// Current thread does not hold a critical reference.
13741    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13742    ///
13743    /// `obj` must a valid and not already garbage collected.
13744    /// `methodID` must be valid, non-static and actually be a method of `obj`, return float and have 0 arguments
13745    ///
13746    pub unsafe fn CallNonvirtualFloatMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) -> jfloat {
13747        unsafe {
13748            #[cfg(feature = "asserts")]
13749            {
13750                self.check_not_critical("CallNonvirtualFloatMethod");
13751                self.check_no_exception("CallNonvirtualFloatMethod");
13752                self.check_return_type_object("CallNonvirtualFloatMethod", obj, methodID, "float");
13753                self.check_is_class("CallNonvirtualFloatMethod", class);
13754            }
13755            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID) -> jfloat>(85)(self.vtable, obj, class, methodID)
13756        }
13757    }
13758
13759    ///
13760    /// Calls a non-static java method with 1 arguments that returns float without using the objects vtable to look up the method.
13761    /// This means that should the object be a subclass of the class that the method is declared in
13762    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13763    ///
13764    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13765    ///
13766    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13767    ///
13768    ///
13769    /// # Arguments
13770    /// * `obj` - which object the method should be called on
13771    ///     * must be valid
13772    ///     * must not be null
13773    ///     * must not be already garbage collected
13774    /// * `methodID` - method id of the method
13775    ///     * must not be null
13776    ///     * must be valid
13777    ///     * must not be a static
13778    ///     * must actually be a method of `obj`
13779    ///     * must refer to a method with 1 arguments
13780    ///
13781    /// # Returns
13782    /// Whatever the method returned or 0 if it threw
13783    ///
13784    /// # Throws Java Exception
13785    /// * Whatever the method threw
13786    ///
13787    ///
13788    /// # Panics
13789    /// if asserts feature is enabled and UB was detected
13790    ///
13791    /// # Safety
13792    ///
13793    /// Current thread must not be detached from JNI.
13794    ///
13795    /// Current thread must not be currently throwing an exception.
13796    ///
13797    /// Current thread does not hold a critical reference.
13798    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13799    ///
13800    /// `obj` must a valid and not already garbage collected.
13801    /// `methodID` must be valid, non-static and actually be a method of `obj`, return float and have 1 arguments
13802    ///
13803    pub unsafe fn CallNonvirtualFloatMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) -> jfloat {
13804        unsafe {
13805            #[cfg(feature = "asserts")]
13806            {
13807                self.check_not_critical("CallNonvirtualFloatMethod");
13808                self.check_no_exception("CallNonvirtualFloatMethod");
13809                self.check_return_type_object("CallNonvirtualFloatMethod", obj, methodID, "float");
13810                self.check_is_class("CallNonvirtualFloatMethod", class);
13811                self.check_parameter_types_object("CallNonvirtualFloatMethod", obj, methodID, arg1, 0, 1);
13812            }
13813            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jfloat>(85)(self.vtable, obj, class, methodID, arg1)
13814        }
13815    }
13816
13817    ///
13818    /// Calls a non-static java method with 2 arguments that returns float without using the objects vtable to look up the method.
13819    /// This means that should the object be a subclass of the class that the method is declared in
13820    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13821    ///
13822    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13823    ///
13824    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13825    ///
13826    ///
13827    /// # Arguments
13828    /// * `obj` - which object the method should be called on
13829    ///     * must be valid
13830    ///     * must not be null
13831    ///     * must not be already garbage collected
13832    /// * `methodID` - method id of the method
13833    ///     * must not be null
13834    ///     * must be valid
13835    ///     * must not be a static
13836    ///     * must actually be a method of `obj`
13837    ///     * must refer to a method with 2 arguments
13838    ///
13839    /// # Returns
13840    /// Whatever the method returned or 0 if it threw
13841    ///
13842    /// # Throws Java Exception
13843    /// * Whatever the method threw
13844    ///
13845    ///
13846    /// # Panics
13847    /// if asserts feature is enabled and UB was detected
13848    ///
13849    /// # Safety
13850    ///
13851    /// Current thread must not be detached from JNI.
13852    ///
13853    /// Current thread must not be currently throwing an exception.
13854    ///
13855    /// Current thread does not hold a critical reference.
13856    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13857    ///
13858    /// `obj` must a valid and not already garbage collected.
13859    /// `methodID` must be valid, non-static and actually be a method of `obj`, return float and have 2 arguments
13860    ///
13861    pub unsafe fn CallNonvirtualFloatMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jfloat {
13862        unsafe {
13863            #[cfg(feature = "asserts")]
13864            {
13865                self.check_not_critical("CallNonvirtualFloatMethod");
13866                self.check_no_exception("CallNonvirtualFloatMethod");
13867                self.check_return_type_object("CallNonvirtualFloatMethod", obj, methodID, "float");
13868                self.check_is_class("CallNonvirtualFloatMethod", class);
13869                self.check_parameter_types_object("CallNonvirtualFloatMethod", obj, methodID, arg1, 0, 2);
13870                self.check_parameter_types_object("CallNonvirtualFloatMethod", obj, methodID, arg2, 1, 2);
13871            }
13872            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jfloat>(85)(self.vtable, obj, class, methodID, arg1, arg2)
13873        }
13874    }
13875
13876    ///
13877    /// Calls a non-static java method with 3 arguments that returns float without using the objects vtable to look up the method.
13878    /// This means that should the object be a subclass of the class that the method is declared in
13879    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13880    ///
13881    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13882    ///
13883    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13884    ///
13885    ///
13886    /// # Arguments
13887    /// * `obj` - which object the method should be called on
13888    ///     * must be valid
13889    ///     * must not be null
13890    ///     * must not be already garbage collected
13891    /// * `methodID` - method id of the method
13892    ///     * must not be null
13893    ///     * must be valid
13894    ///     * must not be a static
13895    ///     * must actually be a method of `obj`
13896    ///     * must refer to a method with 3 arguments
13897    ///
13898    /// # Returns
13899    /// Whatever the method returned or 0 if it threw
13900    ///
13901    /// # Throws Java Exception
13902    /// * Whatever the method threw
13903    ///
13904    ///
13905    /// # Panics
13906    /// if asserts feature is enabled and UB was detected
13907    ///
13908    /// # Safety
13909    ///
13910    /// Current thread must not be detached from JNI.
13911    ///
13912    /// Current thread must not be currently throwing an exception.
13913    ///
13914    /// Current thread does not hold a critical reference.
13915    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13916    ///
13917    /// `obj` must a valid and not already garbage collected.
13918    /// `methodID` must be valid, non-static and actually be a method of `obj`, return float and have 3 arguments
13919    ///
13920    pub unsafe fn CallNonvirtualFloatMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jfloat {
13921        unsafe {
13922            #[cfg(feature = "asserts")]
13923            {
13924                self.check_not_critical("CallNonvirtualFloatMethod");
13925                self.check_no_exception("CallNonvirtualFloatMethod");
13926                self.check_return_type_object("CallNonvirtualFloatMethod", obj, methodID, "float");
13927                self.check_is_class("CallNonvirtualFloatMethod", class);
13928                self.check_parameter_types_object("CallNonvirtualFloatMethod", obj, methodID, arg1, 0, 3);
13929                self.check_parameter_types_object("CallNonvirtualFloatMethod", obj, methodID, arg2, 1, 3);
13930                self.check_parameter_types_object("CallNonvirtualFloatMethod", obj, methodID, arg3, 2, 3);
13931            }
13932            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jfloat>(85)(self.vtable, obj, class, methodID, arg1, arg2, arg3)
13933        }
13934    }
13935
13936    ///
13937    /// Calls a non-static java method with 3 arguments that returns double without using the objects vtable to look up the method.
13938    /// This means that should the object be a subclass of the class that the method is declared in
13939    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
13940    ///
13941    /// This is roughly equivalent to calling "super.someMethod(...)" in java
13942    ///
13943    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
13944    ///
13945    ///
13946    /// # Arguments
13947    /// * `obj` - which object the method should be called on
13948    ///     * must be valid
13949    ///     * must not be null
13950    ///     * must not be already garbage collected
13951    /// * `methodID` - method id of the method
13952    ///     * must not be null
13953    ///     * must be valid
13954    ///     * must not be a static
13955    ///     * must actually be a method of `obj`
13956    /// * `args` - argument pointer
13957    ///     * can be null if the method has no arguments
13958    ///     * must not be null otherwise and point to the exact number of arguments the method expects
13959    ///
13960    /// # Returns
13961    /// Whatever the method returned or 0 if it threw
13962    ///
13963    /// # Throws Java Exception
13964    /// * Whatever the method threw
13965    ///
13966    ///
13967    /// # Panics
13968    /// if asserts feature is enabled and UB was detected
13969    ///
13970    /// # Safety
13971    ///
13972    /// Current thread must not be detached from JNI.
13973    ///
13974    /// Current thread must not be currently throwing an exception.
13975    ///
13976    /// Current thread does not hold a critical reference.
13977    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
13978    ///
13979    /// `obj` must a valid and not already garbage collected.
13980    /// `methodID` must be valid, non-static and actually be a method of `obj` and return a double
13981    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
13982    /// `args` union must contain types that match the java methods parameters.
13983    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
13984    ///
13985    pub unsafe fn CallNonvirtualDoubleMethodA(&self, obj: jobject, class: jclass, methodID: jmethodID, args: *const jtype) -> jdouble {
13986        unsafe {
13987            #[cfg(feature = "asserts")]
13988            {
13989                self.check_not_critical("CallNonvirtualDoubleMethodA");
13990                self.check_no_exception("CallNonvirtualDoubleMethodA");
13991                self.check_return_type_object("CallNonvirtualDoubleMethodA", obj, methodID, "double");
13992                self.check_is_class("CallNonvirtualDoubleMethodA", class);
13993            }
13994            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jclass, jmethodID, *const jtype) -> jdouble>(90)(self.vtable, obj, class, methodID, args)
13995        }
13996    }
13997
13998    ///
13999    /// Calls a non-static java method with 0 arguments that returns double without using the objects vtable to look up the method.
14000    /// This means that should the object be a subclass of the class that the method is declared in
14001    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14002    ///
14003    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14004    ///
14005    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14006    ///
14007    ///
14008    /// # Arguments
14009    /// * `obj` - which object the method should be called on
14010    ///     * must be valid
14011    ///     * must not be null
14012    ///     * must not be already garbage collected
14013    /// * `methodID` - method id of the method
14014    ///     * must not be null
14015    ///     * must be valid
14016    ///     * must not be a static
14017    ///     * must actually be a method of `obj`
14018    ///     * must refer to a method with 0 arguments
14019    ///
14020    /// # Returns
14021    /// Whatever the method returned or 0 if it threw
14022    ///
14023    /// # Throws Java Exception
14024    /// * Whatever the method threw
14025    ///
14026    ///
14027    /// # Panics
14028    /// if asserts feature is enabled and UB was detected
14029    ///
14030    /// # Safety
14031    ///
14032    /// Current thread must not be detached from JNI.
14033    ///
14034    /// Current thread must not be currently throwing an exception.
14035    ///
14036    /// Current thread does not hold a critical reference.
14037    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14038    ///
14039    /// `obj` must a valid and not already garbage collected.
14040    /// `methodID` must be valid, non-static and actually be a method of `obj`, return double and have 0 arguments
14041    ///
14042    pub unsafe fn CallNonvirtualDoubleMethod0(&self, obj: jobject, class: jclass, methodID: jmethodID) -> jdouble {
14043        unsafe {
14044            #[cfg(feature = "asserts")]
14045            {
14046                self.check_not_critical("CallNonvirtualDoubleMethod");
14047                self.check_no_exception("CallNonvirtualDoubleMethod");
14048                self.check_return_type_object("CallNonvirtualDoubleMethod", obj, methodID, "double");
14049                self.check_is_class("CallNonvirtualDoubleMethod", class);
14050            }
14051            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID) -> jdouble>(88)(self.vtable, obj, class, methodID)
14052        }
14053    }
14054
14055    ///
14056    /// Calls a non-static java method with 1 arguments that returns double without using the objects vtable to look up the method.
14057    /// This means that should the object be a subclass of the class that the method is declared in
14058    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14059    ///
14060    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14061    ///
14062    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14063    ///
14064    ///
14065    /// # Arguments
14066    /// * `obj` - which object the method should be called on
14067    ///     * must be valid
14068    ///     * must not be null
14069    ///     * must not be already garbage collected
14070    /// * `methodID` - method id of the method
14071    ///     * must not be null
14072    ///     * must be valid
14073    ///     * must not be a static
14074    ///     * must actually be a method of `obj`
14075    ///     * must refer to a method with 1 arguments
14076    ///
14077    /// # Returns
14078    /// Whatever the method returned or 0 if it threw
14079    ///
14080    /// # Throws Java Exception
14081    /// * Whatever the method threw
14082    ///
14083    ///
14084    /// # Panics
14085    /// if asserts feature is enabled and UB was detected
14086    ///
14087    /// # Safety
14088    ///
14089    /// Current thread must not be detached from JNI.
14090    ///
14091    /// Current thread must not be currently throwing an exception.
14092    ///
14093    /// Current thread does not hold a critical reference.
14094    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14095    ///
14096    /// `obj` must a valid and not already garbage collected.
14097    /// `methodID` must be valid, non-static and actually be a method of `obj`, return double and have 1 arguments
14098    ///
14099    pub unsafe fn CallNonvirtualDoubleMethod1<A: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A) -> jdouble {
14100        unsafe {
14101            #[cfg(feature = "asserts")]
14102            {
14103                self.check_not_critical("CallNonvirtualDoubleMethod");
14104                self.check_no_exception("CallNonvirtualDoubleMethod");
14105                self.check_return_type_object("CallNonvirtualDoubleMethod", obj, methodID, "double");
14106                self.check_is_class("CallNonvirtualDoubleMethod", class);
14107                self.check_parameter_types_object("CallNonvirtualDoubleMethod", obj, methodID, arg1, 0, 1);
14108            }
14109            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jdouble>(88)(self.vtable, obj, class, methodID, arg1)
14110        }
14111    }
14112
14113    ///
14114    /// Calls a non-static java method with 2 arguments that returns double without using the objects vtable to look up the method.
14115    /// This means that should the object be a subclass of the class that the method is declared in
14116    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14117    ///
14118    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14119    ///
14120    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14121    ///
14122    ///
14123    /// # Arguments
14124    /// * `obj` - which object the method should be called on
14125    ///     * must be valid
14126    ///     * must not be null
14127    ///     * must not be already garbage collected
14128    /// * `methodID` - method id of the method
14129    ///     * must not be null
14130    ///     * must be valid
14131    ///     * must not be a static
14132    ///     * must actually be a method of `obj`
14133    ///     * must refer to a method with 2 arguments
14134    ///
14135    /// # Returns
14136    /// Whatever the method returned or 0 if it threw
14137    ///
14138    /// # Throws Java Exception
14139    /// * Whatever the method threw
14140    ///
14141    ///
14142    /// # Panics
14143    /// if asserts feature is enabled and UB was detected
14144    ///
14145    /// # Safety
14146    ///
14147    /// Current thread must not be detached from JNI.
14148    ///
14149    /// Current thread must not be currently throwing an exception.
14150    ///
14151    /// Current thread does not hold a critical reference.
14152    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14153    ///
14154    /// `obj` must a valid and not already garbage collected.
14155    /// `methodID` must be valid, non-static and actually be a method of `obj`, return double and have 2 arguments
14156    ///
14157    pub unsafe fn CallNonvirtualDoubleMethod2<A: JType, B: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jdouble {
14158        unsafe {
14159            #[cfg(feature = "asserts")]
14160            {
14161                self.check_not_critical("CallNonvirtualDoubleMethod");
14162                self.check_no_exception("CallNonvirtualDoubleMethod");
14163                self.check_return_type_object("CallNonvirtualDoubleMethod", obj, methodID, "double");
14164                self.check_is_class("CallNonvirtualDoubleMethod", class);
14165                self.check_parameter_types_object("CallNonvirtualDoubleMethod", obj, methodID, arg1, 0, 2);
14166                self.check_parameter_types_object("CallNonvirtualDoubleMethod", obj, methodID, arg2, 1, 2);
14167            }
14168            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jdouble>(88)(self.vtable, obj, class, methodID, arg1, arg2)
14169        }
14170    }
14171
14172    ///
14173    /// Calls a non-static java method with 3 arguments that returns double without using the objects vtable to look up the method.
14174    /// This means that should the object be a subclass of the class that the method is declared in
14175    /// then the base method that the methodID refers to is invoked instead of a potentially overwritten one.
14176    ///
14177    /// This is roughly equivalent to calling "super.someMethod(...)" in java
14178    ///
14179    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallNonvirtual_type_Method_routines>
14180    ///
14181    ///
14182    /// # Arguments
14183    /// * `obj` - which object the method should be called on
14184    ///     * must be valid
14185    ///     * must not be null
14186    ///     * must not be already garbage collected
14187    /// * `methodID` - method id of the method
14188    ///     * must not be null
14189    ///     * must be valid
14190    ///     * must not be a static
14191    ///     * must actually be a method of `obj`
14192    ///     * must refer to a method with 3 arguments
14193    ///
14194    /// # Returns
14195    /// Whatever the method returned or 0 if it threw
14196    ///
14197    /// # Throws Java Exception
14198    /// * Whatever the method threw
14199    ///
14200    ///
14201    /// # Panics
14202    /// if asserts feature is enabled and UB was detected
14203    ///
14204    /// # Safety
14205    ///
14206    /// Current thread must not be detached from JNI.
14207    ///
14208    /// Current thread must not be currently throwing an exception.
14209    ///
14210    /// Current thread does not hold a critical reference.
14211    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14212    ///
14213    /// `obj` must a valid and not already garbage collected.
14214    /// `methodID` must be valid, non-static and actually be a method of `obj`, return double and have 3 arguments
14215    ///
14216    pub unsafe fn CallNonvirtualDoubleMethod3<A: JType, B: JType, C: JType>(&self, obj: jobject, class: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jdouble {
14217        unsafe {
14218            #[cfg(feature = "asserts")]
14219            {
14220                self.check_not_critical("CallNonvirtualDoubleMethod");
14221                self.check_no_exception("CallNonvirtualDoubleMethod");
14222                self.check_return_type_object("CallNonvirtualDoubleMethod", obj, methodID, "double");
14223                self.check_is_class("CallNonvirtualDoubleMethod", class);
14224                self.check_parameter_types_object("CallNonvirtualDoubleMethod", obj, methodID, arg1, 0, 3);
14225                self.check_parameter_types_object("CallNonvirtualDoubleMethod", obj, methodID, arg2, 1, 3);
14226                self.check_parameter_types_object("CallNonvirtualDoubleMethod", obj, methodID, arg3, 2, 3);
14227            }
14228            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jclass, jmethodID, ...) -> jdouble>(88)(self.vtable, obj, class, methodID, arg1, arg2, arg3)
14229        }
14230    }
14231
14232    ///
14233    /// Gets the field id of a static field
14234    ///
14235    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStaticFieldID>
14236    ///
14237    ///
14238    /// # Arguments
14239    /// * `clazz` - reference to the clazz where the field is declared in.
14240    ///     * must be valid
14241    ///     * must not be null
14242    ///     * must not be already garbage collected
14243    /// * `name` - name of the field
14244    ///     * must not be null
14245    ///     * must be zero terminated utf-8
14246    /// * `sig` - jni signature of the field
14247    ///     * must not be null
14248    ///     * must be zero terminated utf-8
14249    ///
14250    /// # Returns
14251    /// A non-null field handle or null on error.
14252    /// The field handle can be assumed to be constant for the given class and must not be freed.
14253    /// It can also be safely shared with any thread or stored in a constant.
14254    ///
14255    /// # Throws Java Exception
14256    /// * `NoSuchFieldError` - field with the given name and sig doesn't exist in the class
14257    /// * `ExceptionInInitializerError` - Exception occurs in initializer of the class
14258    /// * `OutOfMemoryError` - if the jvm runs out of memory
14259    ///
14260    ///
14261    /// # Panics
14262    /// if asserts feature is enabled and UB was detected
14263    ///
14264    /// # Safety
14265    ///
14266    /// Current thread must not be detached from JNI.
14267    ///
14268    /// Current thread must not be currently throwing an exception.
14269    ///
14270    /// Current thread does not hold a critical reference.
14271    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14272    ///
14273    /// `clazz` must a valid reference to a class that is not already garbage collected.
14274    /// `name` must be non-null and zero terminated utf-8.
14275    /// `sig` must be non-null and zero terminated utf-8.
14276    ///
14277    pub unsafe fn GetStaticFieldID(&self, clazz: jclass, name: impl UseCString, sig: impl UseCString) -> jfieldID {
14278        unsafe {
14279            name.use_as_const_c_char(|name| {
14280                sig.use_as_const_c_char(|sig| {
14281                    #[cfg(feature = "asserts")]
14282                    {
14283                        self.check_not_critical("GetStaticFieldID");
14284                        self.check_no_exception("GetStaticFieldID");
14285                        assert!(!name.is_null(), "GetStaticFieldID name is null");
14286                        assert!(!sig.is_null(), "GetStaticFieldID sig is null");
14287                        self.check_is_class("GetStaticFieldID", clazz);
14288                    }
14289                    self.jni::<extern "system" fn(JNIEnvVTable, jclass, *const c_char, *const c_char) -> jfieldID>(144)(self.vtable, clazz, name, sig)
14290                })
14291            })
14292        }
14293    }
14294
14295    ///
14296    /// Returns a local reference from a static field.
14297    ///
14298    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStatic_type_Field_routines>
14299    ///
14300    ///
14301    /// # Arguments
14302    /// * `obj` - reference to the class the field is in
14303    ///     * must be valid
14304    ///     * must not be null
14305    ///     * must not be already garbage collected
14306    /// * `fieldID` - the field to get
14307    ///     * must be valid
14308    ///     * must be an object field
14309    ///
14310    /// # Returns
14311    /// A local reference to the fields value or null if the field is null
14312    ///
14313    ///
14314    /// # Panics
14315    /// if asserts feature is enabled and UB was detected
14316    ///
14317    /// # Safety
14318    ///
14319    /// Current thread must not be detached from JNI.
14320    ///
14321    /// Current thread must not be currently throwing an exception.
14322    ///
14323    /// Current thread does not hold a critical reference.
14324    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14325    ///
14326    /// `obj` must a valid reference to a class that is not already garbage collected.
14327    /// `fieldID` must be a fieldID of a field located in `obj` class and not some other unrelated class
14328    /// `fieldID` must be from a static field
14329    /// `fieldID` must refer to a field that is an object and not a primitive.
14330    ///
14331    pub unsafe fn GetStaticObjectField(&self, obj: jclass, fieldID: jfieldID) -> jobject {
14332        unsafe {
14333            #[cfg(feature = "asserts")]
14334            {
14335                self.check_not_critical("GetStaticObjectField");
14336                self.check_no_exception("GetStaticObjectField");
14337                self.check_field_type_static("GetStaticObjectField", obj, fieldID, "object");
14338            }
14339            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jobject>(145)(self.vtable, obj, fieldID)
14340        }
14341    }
14342
14343    ///
14344    /// Returns a boolean from a static field.
14345    ///
14346    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStatic_type_Field_routines>
14347    ///
14348    ///
14349    /// # Arguments
14350    /// * `obj` - reference to the class the field is in
14351    ///     * must be valid
14352    ///     * must not be null
14353    ///     * must not be already garbage collected
14354    /// * `fieldID` - the field to get
14355    ///     * must be valid
14356    ///     * must be a boolean field
14357    ///
14358    /// # Returns
14359    /// The value of the field
14360    ///
14361    ///
14362    /// # Panics
14363    /// if asserts feature is enabled and UB was detected
14364    ///
14365    /// # Safety
14366    ///
14367    /// Current thread must not be detached from JNI.
14368    ///
14369    /// Current thread must not be currently throwing an exception.
14370    ///
14371    /// Current thread does not hold a critical reference.
14372    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14373    ///
14374    /// `obj` must a valid reference to a class that is not already garbage collected.
14375    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
14376    /// `fieldID` must be from a static field
14377    /// `fieldID` must refer to a field that is a boolean.
14378    ///
14379    pub unsafe fn GetStaticBooleanField(&self, obj: jclass, fieldID: jfieldID) -> jboolean {
14380        unsafe {
14381            #[cfg(feature = "asserts")]
14382            {
14383                self.check_not_critical("GetStaticBooleanField");
14384                self.check_no_exception("GetStaticBooleanField");
14385                self.check_field_type_static("GetStaticBooleanField", obj, fieldID, "boolean");
14386            }
14387            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jboolean>(146)(self.vtable, obj, fieldID)
14388        }
14389    }
14390
14391    ///
14392    /// Returns a byte from a static field.
14393    ///
14394    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStatic_type_Field_routines>
14395    ///
14396    ///
14397    /// # Arguments
14398    /// * `obj` - reference to the class the field is in
14399    ///     * must be valid
14400    ///     * must not be null
14401    ///     * must not be already garbage collected
14402    /// * `fieldID` - the field to get
14403    ///     * must be valid
14404    ///     * must be a byte field
14405    ///
14406    /// # Returns
14407    /// The value of the field
14408    ///
14409    ///
14410    /// # Panics
14411    /// if asserts feature is enabled and UB was detected
14412    ///
14413    /// # Safety
14414    ///
14415    /// Current thread must not be detached from JNI.
14416    ///
14417    /// Current thread must not be currently throwing an exception.
14418    ///
14419    /// Current thread does not hold a critical reference.
14420    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14421    ///
14422    /// `obj` must a valid reference to a class that is not already garbage collected.
14423    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
14424    /// `fieldID` must be from a static field
14425    /// `fieldID` must refer to a field that is a byte.
14426    ///
14427    pub unsafe fn GetStaticByteField(&self, obj: jclass, fieldID: jfieldID) -> jbyte {
14428        unsafe {
14429            #[cfg(feature = "asserts")]
14430            {
14431                self.check_not_critical("GetStaticByteField");
14432                self.check_no_exception("GetStaticByteField");
14433                self.check_field_type_static("GetStaticByteField", obj, fieldID, "byte");
14434            }
14435            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jbyte>(147)(self.vtable, obj, fieldID)
14436        }
14437    }
14438
14439    ///
14440    /// Returns a char from a static field.
14441    ///
14442    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStatic_type_Field_routines>
14443    ///
14444    ///
14445    /// # Arguments
14446    /// * `obj` - reference to the class the field is in
14447    ///     * must be valid
14448    ///     * must not be null
14449    ///     * must not be already garbage collected
14450    /// * `fieldID` - the field to get
14451    ///     * must be valid
14452    ///     * must be a char field
14453    ///
14454    /// # Returns
14455    /// The value of the field
14456    ///
14457    ///
14458    /// # Panics
14459    /// if asserts feature is enabled and UB was detected
14460    ///
14461    /// # Safety
14462    ///
14463    /// Current thread must not be detached from JNI.
14464    ///
14465    /// Current thread must not be currently throwing an exception.
14466    ///
14467    /// Current thread does not hold a critical reference.
14468    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14469    ///
14470    /// `obj` must a valid reference to a class that is not already garbage collected.
14471    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
14472    /// `fieldID` must be from a static field
14473    /// `fieldID` must refer to a field that is a char.
14474    ///
14475    pub unsafe fn GetStaticCharField(&self, obj: jclass, fieldID: jfieldID) -> jchar {
14476        unsafe {
14477            #[cfg(feature = "asserts")]
14478            {
14479                self.check_not_critical("GetStaticCharField");
14480                self.check_no_exception("GetStaticCharField");
14481                self.check_field_type_static("GetStaticCharField", obj, fieldID, "char");
14482            }
14483            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jchar>(148)(self.vtable, obj, fieldID)
14484        }
14485    }
14486
14487    ///
14488    /// Returns a short from a static field.
14489    ///
14490    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStatic_type_Field_routines>
14491    ///
14492    ///
14493    /// # Arguments
14494    /// * `obj` - reference to the class the field is in
14495    ///     * must be valid
14496    ///     * must not be null
14497    ///     * must not be already garbage collected
14498    /// * `fieldID` - the field to get
14499    ///     * must be valid
14500    ///     * must be a short field
14501    ///
14502    /// # Returns
14503    /// The value of the field
14504    ///
14505    ///
14506    /// # Panics
14507    /// if asserts feature is enabled and UB was detected
14508    ///
14509    /// # Safety
14510    ///
14511    /// Current thread must not be detached from JNI.
14512    ///
14513    /// Current thread must not be currently throwing an exception.
14514    ///
14515    /// Current thread does not hold a critical reference.
14516    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14517    ///
14518    /// `obj` must a valid reference to a class that is not already garbage collected.
14519    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
14520    /// `fieldID` must be from a static field
14521    /// `fieldID` must refer to a field that is a short.
14522    ///
14523    pub unsafe fn GetStaticShortField(&self, obj: jclass, fieldID: jfieldID) -> jshort {
14524        unsafe {
14525            #[cfg(feature = "asserts")]
14526            {
14527                self.check_not_critical("GetStaticShortField");
14528                self.check_no_exception("GetStaticShortField");
14529                self.check_field_type_static("GetStaticShortField", obj, fieldID, "short");
14530            }
14531            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jshort>(149)(self.vtable, obj, fieldID)
14532        }
14533    }
14534
14535    ///
14536    /// Returns a int from a static field.
14537    ///
14538    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStatic_type_Field_routines>
14539    ///
14540    ///
14541    /// # Arguments
14542    /// * `obj` - reference to the class the field is in
14543    ///     * must be valid
14544    ///     * must not be null
14545    ///     * must not be already garbage collected
14546    /// * `fieldID` - the field to get
14547    ///     * must be valid
14548    ///     * must be a int field
14549    ///
14550    /// # Returns
14551    /// The value of the field
14552    ///
14553    ///
14554    /// # Panics
14555    /// if asserts feature is enabled and UB was detected
14556    ///
14557    /// # Safety
14558    ///
14559    /// Current thread must not be detached from JNI.
14560    ///
14561    /// Current thread must not be currently throwing an exception.
14562    ///
14563    /// Current thread does not hold a critical reference.
14564    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14565    ///
14566    /// `obj` must a valid reference to a class that is not already garbage collected.
14567    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
14568    /// `fieldID` must be from a static field
14569    /// `fieldID` must refer to a field that is a int.
14570    ///
14571    pub unsafe fn GetStaticIntField(&self, obj: jclass, fieldID: jfieldID) -> jint {
14572        unsafe {
14573            #[cfg(feature = "asserts")]
14574            {
14575                self.check_not_critical("GetStaticIntField");
14576                self.check_no_exception("GetStaticIntField");
14577                self.check_field_type_static("GetStaticIntField", obj, fieldID, "int");
14578            }
14579            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jint>(150)(self.vtable, obj, fieldID)
14580        }
14581    }
14582
14583    ///
14584    /// Returns a long from a static field.
14585    ///
14586    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStatic_type_Field_routines>
14587    ///
14588    ///
14589    /// # Arguments
14590    /// * `obj` - reference to the class the field is in
14591    ///     * must be valid
14592    ///     * must not be null
14593    ///     * must not be already garbage collected
14594    ///
14595    /// * `fieldID` - the field to get
14596    ///     * must be valid
14597    ///     * must be a long field
14598    ///
14599    /// # Returns
14600    /// The value of the field
14601    ///
14602    ///
14603    /// # Panics
14604    /// if asserts feature is enabled and UB was detected
14605    ///
14606    /// # Safety
14607    ///
14608    /// Current thread must not be detached from JNI.
14609    ///
14610    /// Current thread must not be currently throwing an exception.
14611    ///
14612    /// Current thread does not hold a critical reference.
14613    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14614    ///
14615    /// `obj` must a valid reference to a class that is not already garbage collected.
14616    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
14617    /// `fieldID` must be from a static field
14618    /// `fieldID` must refer to a field that is a long.
14619    ///
14620    pub unsafe fn GetStaticLongField(&self, obj: jclass, fieldID: jfieldID) -> jlong {
14621        unsafe {
14622            #[cfg(feature = "asserts")]
14623            {
14624                self.check_not_critical("GetStaticLongField");
14625                self.check_no_exception("GetStaticLongField");
14626                self.check_field_type_static("GetStaticLongField", obj, fieldID, "long");
14627            }
14628            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jlong>(151)(self.vtable, obj, fieldID)
14629        }
14630    }
14631
14632    ///
14633    /// Returns a float from a static field.
14634    ///
14635    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStatic_type_Field_routines>
14636    ///
14637    ///
14638    /// # Arguments
14639    /// * `obj` - reference to the class the field is in
14640    ///     * must be valid
14641    ///     * must not be null
14642    ///     * must not be already garbage collected
14643    ///
14644    /// * `fieldID` - the field to get
14645    ///     * must be valid
14646    ///     * must be a float field
14647    ///
14648    /// # Returns
14649    /// The value of the field
14650    ///
14651    ///
14652    /// # Panics
14653    /// if asserts feature is enabled and UB was detected
14654    ///
14655    /// # Safety
14656    ///
14657    /// Current thread must not be detached from JNI.
14658    ///
14659    /// Current thread must not be currently throwing an exception.
14660    ///
14661    /// Current thread does not hold a critical reference.
14662    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14663    ///
14664    /// `obj` must a valid reference to a class that is not already garbage collected.
14665    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
14666    /// `fieldID` must be from a static field
14667    /// `fieldID` must refer to a field that is a float.
14668    ///
14669    pub unsafe fn GetStaticFloatField(&self, obj: jclass, fieldID: jfieldID) -> jfloat {
14670        unsafe {
14671            #[cfg(feature = "asserts")]
14672            {
14673                self.check_not_critical("GetStaticFloatField");
14674                self.check_no_exception("GetStaticFloatField");
14675                self.check_field_type_static("GetStaticFloatField", obj, fieldID, "float");
14676            }
14677            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jfloat>(152)(self.vtable, obj, fieldID)
14678        }
14679    }
14680
14681    ///
14682    /// Returns a double from a static field.
14683    ///
14684    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStatic_type_Field_routines>
14685    ///
14686    ///
14687    /// # Arguments
14688    /// * `obj` - reference to the class the field is in
14689    ///     * must be valid
14690    ///     * must not be null
14691    ///     * must not be already garbage collected
14692    ///
14693    /// * `fieldID` - the field to get
14694    ///     * must be valid
14695    ///     * must be a double field
14696    ///
14697    /// # Returns
14698    /// The value of the field
14699    ///
14700    ///
14701    /// # Panics
14702    /// if asserts feature is enabled and UB was detected
14703    ///
14704    /// # Safety
14705    ///
14706    /// Current thread must not be detached from JNI.
14707    ///
14708    /// Current thread must not be currently throwing an exception.
14709    ///
14710    /// Current thread does not hold a critical reference.
14711    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14712    ///
14713    /// `obj` must a valid reference to a class that is not already garbage collected.
14714    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
14715    /// `fieldID` must be from a static field
14716    /// `fieldID` must refer to a field that is a double.
14717    ///
14718    pub unsafe fn GetStaticDoubleField(&self, obj: jclass, fieldID: jfieldID) -> jdouble {
14719        unsafe {
14720            #[cfg(feature = "asserts")]
14721            {
14722                self.check_not_critical("GetStaticDoubleField");
14723                self.check_no_exception("GetStaticDoubleField");
14724                self.check_field_type_static("GetStaticDoubleField", obj, fieldID, "double");
14725            }
14726            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID) -> jdouble>(153)(self.vtable, obj, fieldID)
14727        }
14728    }
14729
14730    ///
14731    /// Sets a static object field to a given value
14732    ///
14733    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#SetStatic_type_Field_routines>
14734    ///
14735    /// # Arguments
14736    /// * `obj` - reference to the object the field is in
14737    ///     * must be valid
14738    ///     * must not be null
14739    ///     * must not be already garbage collected
14740    ///
14741    /// * `fieldID` - the field to set
14742    ///     * must be valid
14743    ///     * must be a object field
14744    ///     * must reside in the object `obj`
14745    ///
14746    /// * `value`
14747    ///     * must be null or valid
14748    ///     * must not be already garbage collected (if non-null)
14749    ///     * must be assignable to the field type (if non-null)
14750    ///
14751    ///
14752    /// # Panics
14753    /// if asserts feature is enabled and UB was detected
14754    ///
14755    /// # Safety
14756    ///
14757    /// Current thread must not be detached from JNI.
14758    ///
14759    /// Current thread must not be currently throwing an exception.
14760    ///
14761    /// Current thread does not hold a critical reference.
14762    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14763    ///
14764    /// `obj` must be a valid reference to the class the field is in that is not already garbage collected.
14765    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
14766    /// `fieldID` must be from a static field
14767    /// `fieldID` must refer to a field that is an object and not a primitive.
14768    /// `value` must be a valid reference to the object that is not already garbage collected or it must be null.
14769    /// `value` must be assignable to the field type (i.e. if it's a String field setting to an `ArrayList` for example is UB)
14770    ///
14771    pub unsafe fn SetStaticObjectField(&self, obj: jclass, fieldID: jfieldID, value: jobject) {
14772        unsafe {
14773            #[cfg(feature = "asserts")]
14774            {
14775                self.check_not_critical("SetStaticObjectField");
14776                self.check_no_exception("SetStaticObjectField");
14777                self.check_field_type_static("SetStaticObjectField", obj, fieldID, "object");
14778            }
14779            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jobject)>(154)(self.vtable, obj, fieldID, value);
14780        }
14781    }
14782
14783    ///
14784    /// Sets a static boolean field to a given value
14785    ///
14786    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#SetStatic_type_Field_routines>
14787    ///
14788    /// # Arguments
14789    /// * `obj` - reference to the object the field is in
14790    ///     * must be valid
14791    ///     * must not be null
14792    ///     * must not be already garbage collected
14793    ///
14794    /// * `fieldID` - the field to set
14795    ///     * must be valid
14796    ///     * must be a object field
14797    ///     * must reside in the object `obj`
14798    ///
14799    /// * `value` - that value to set
14800    ///
14801    ///
14802    /// # Panics
14803    /// if asserts feature is enabled and UB was detected
14804    ///
14805    /// # Safety
14806    ///
14807    /// Current thread must not be detached from JNI.
14808    ///
14809    /// Current thread must not be currently throwing an exception.
14810    ///
14811    /// Current thread does not hold a critical reference.
14812    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14813    ///
14814    /// `obj` must be a valid reference to the class the field is in that is not already garbage collected.
14815    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
14816    /// `fieldID` must be from a static field
14817    /// `fieldID` must refer to a field that is a boolean.
14818    ///
14819    pub unsafe fn SetStaticBooleanField(&self, obj: jclass, fieldID: jfieldID, value: jboolean) {
14820        unsafe {
14821            #[cfg(feature = "asserts")]
14822            {
14823                self.check_not_critical("SetStaticBooleanField");
14824                self.check_no_exception("SetStaticBooleanField");
14825                self.check_field_type_static("SetStaticBooleanField", obj, fieldID, "boolean");
14826            }
14827            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jboolean)>(155)(self.vtable, obj, fieldID, value);
14828        }
14829    }
14830
14831    ///
14832    /// Sets a static byte field to a given value
14833    ///
14834    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#SetStatic_type_Field_routines>
14835    ///
14836    /// # Arguments
14837    /// * `obj` - reference to the object the field is in
14838    ///     * must be valid
14839    ///     * must not be null
14840    ///     * must not be already garbage collected
14841    ///
14842    /// * `fieldID` - the field to set
14843    ///     * must be valid
14844    ///     * must be a object field
14845    ///     * must reside in the object `obj`
14846    ///
14847    /// * `value` - that value to set
14848    ///
14849    ///
14850    /// # Panics
14851    /// if asserts feature is enabled and UB was detected
14852    ///
14853    /// # Safety
14854    ///
14855    /// Current thread must not be detached from JNI.
14856    ///
14857    /// Current thread must not be currently throwing an exception.
14858    ///
14859    /// Current thread does not hold a critical reference.
14860    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14861    ///
14862    /// `obj` must be a valid reference to the class the field is in that is not already garbage collected.
14863    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
14864    /// `fieldID` must be from a static field
14865    /// `fieldID` must refer to a field that is a byte.
14866    ///
14867    pub unsafe fn SetStaticByteField(&self, obj: jclass, fieldID: jfieldID, value: jbyte) {
14868        unsafe {
14869            #[cfg(feature = "asserts")]
14870            {
14871                self.check_not_critical("SetStaticByteField");
14872                self.check_no_exception("SetStaticByteField");
14873                self.check_field_type_static("SetStaticByteField", obj, fieldID, "byte");
14874            }
14875            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jbyte)>(156)(self.vtable, obj, fieldID, value);
14876        }
14877    }
14878
14879    ///
14880    /// Sets a static char field to a given value
14881    ///
14882    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#SetStatic_type_Field_routines>
14883    ///
14884    /// # Arguments
14885    /// * `obj` - reference to the object the field is in
14886    ///     * must be valid
14887    ///     * must not be null
14888    ///     * must not be already garbage collected
14889    ///
14890    /// * `fieldID` - the field to set
14891    ///     * must be valid
14892    ///     * must be a object field
14893    ///     * must reside in the object `obj`
14894    ///
14895    /// * `value` - that value to set
14896    ///
14897    ///
14898    /// # Panics
14899    /// if asserts feature is enabled and UB was detected
14900    ///
14901    /// # Safety
14902    ///
14903    /// Current thread must not be detached from JNI.
14904    ///
14905    /// Current thread must not be currently throwing an exception.
14906    ///
14907    /// Current thread does not hold a critical reference.
14908    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14909    ///
14910    /// `obj` must be a valid reference to the class the field is in that is not already garbage collected.
14911    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
14912    /// `fieldID` must be from a static field
14913    /// `fieldID` must refer to a field that is a char.
14914    ///
14915    pub unsafe fn SetStaticCharField(&self, obj: jclass, fieldID: jfieldID, value: jchar) {
14916        unsafe {
14917            #[cfg(feature = "asserts")]
14918            {
14919                self.check_not_critical("SetStaticCharField");
14920                self.check_no_exception("SetStaticCharField");
14921                self.check_field_type_static("SetStaticCharField", obj, fieldID, "char");
14922            }
14923            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jchar)>(157)(self.vtable, obj, fieldID, value);
14924        }
14925    }
14926
14927    ///
14928    /// Sets a static short field to a given value
14929    ///
14930    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#SetStatic_type_Field_routines>
14931    ///
14932    /// # Arguments
14933    /// * `obj` - reference to the object the field is in
14934    ///     * must be valid
14935    ///     * must not be null
14936    ///     * must not be already garbage collected
14937    ///
14938    /// * `fieldID` - the field to set
14939    ///     * must be valid
14940    ///     * must be a object field
14941    ///     * must reside in the object `obj`
14942    ///
14943    /// * `value` - that value to set
14944    ///
14945    ///
14946    /// # Panics
14947    /// if asserts feature is enabled and UB was detected
14948    ///
14949    /// # Safety
14950    ///
14951    /// Current thread must not be detached from JNI.
14952    ///
14953    /// Current thread must not be currently throwing an exception.
14954    ///
14955    /// Current thread does not hold a critical reference.
14956    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
14957    ///
14958    /// `obj` must be a valid reference to the class the field is in that is not already garbage collected.
14959    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
14960    /// `fieldID` must be from a static field
14961    /// `fieldID` must refer to a field that is a short.
14962    ///
14963    pub unsafe fn SetStaticShortField(&self, obj: jclass, fieldID: jfieldID, value: jshort) {
14964        unsafe {
14965            #[cfg(feature = "asserts")]
14966            {
14967                self.check_not_critical("SetStaticShortField");
14968                self.check_no_exception("SetStaticShortField");
14969                self.check_field_type_static("SetStaticShortField", obj, fieldID, "short");
14970            }
14971            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jshort)>(158)(self.vtable, obj, fieldID, value);
14972        }
14973    }
14974
14975    ///
14976    /// Sets a static int field to a given value
14977    ///
14978    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#SetStatic_type_Field_routines>
14979    ///
14980    /// # Arguments
14981    /// * `obj` - reference to the object the field is in
14982    ///     * must be valid
14983    ///     * must not be null
14984    ///     * must not be already garbage collected
14985    ///
14986    /// * `fieldID` - the field to set
14987    ///     * must be valid
14988    ///     * must be a object field
14989    ///     * must reside in the object `obj`
14990    ///
14991    /// * `value` - that value to set
14992    ///
14993    ///
14994    /// # Panics
14995    /// if asserts feature is enabled and UB was detected
14996    ///
14997    /// # Safety
14998    ///
14999    /// Current thread must not be detached from JNI.
15000    ///
15001    /// Current thread must not be currently throwing an exception.
15002    ///
15003    /// Current thread does not hold a critical reference.
15004    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15005    ///
15006    /// `obj` must be a valid reference to the class the field is in that is not already garbage collected.
15007    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
15008    /// `fieldID` must be from a static field
15009    /// `fieldID` must refer to a field that is a int.
15010    ///
15011    pub unsafe fn SetStaticIntField(&self, obj: jclass, fieldID: jfieldID, value: jint) {
15012        unsafe {
15013            #[cfg(feature = "asserts")]
15014            {
15015                self.check_not_critical("SetStaticIntField");
15016                self.check_no_exception("SetStaticIntField");
15017                self.check_field_type_static("SetStaticIntField", obj, fieldID, "int");
15018            }
15019            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jint)>(159)(self.vtable, obj, fieldID, value);
15020        }
15021    }
15022
15023    ///
15024    /// Sets a static long field to a given value
15025    ///
15026    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#SetStatic_type_Field_routines>
15027    ///
15028    /// # Arguments
15029    /// * `obj` - reference to the object the field is in
15030    ///     * must be valid
15031    ///     * must not be null
15032    ///     * must not be already garbage collected
15033    ///
15034    /// * `fieldID` - the field to set
15035    ///     * must be valid
15036    ///     * must be a object field
15037    ///     * must reside in the object `obj`
15038    ///
15039    /// * `value` - that value to set
15040    ///
15041    ///
15042    /// # Panics
15043    /// if asserts feature is enabled and UB was detected
15044    ///
15045    /// # Safety
15046    ///
15047    /// Current thread must not be detached from JNI.
15048    ///
15049    /// Current thread must not be currently throwing an exception.
15050    ///
15051    /// Current thread does not hold a critical reference.
15052    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15053    ///
15054    /// `obj` must be a valid reference to the class the field is in that is not already garbage collected.
15055    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
15056    /// `fieldID` must be from a static field
15057    /// `fieldID` must refer to a field that is a long.
15058    ///
15059    pub unsafe fn SetStaticLongField(&self, obj: jclass, fieldID: jfieldID, value: jlong) {
15060        unsafe {
15061            #[cfg(feature = "asserts")]
15062            {
15063                self.check_not_critical("SetStaticLongField");
15064                self.check_no_exception("SetStaticLongField");
15065                self.check_field_type_static("SetStaticLongField", obj, fieldID, "long");
15066            }
15067            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jlong)>(160)(self.vtable, obj, fieldID, value);
15068        }
15069    }
15070
15071    ///
15072    /// Sets a static float field to a given value
15073    ///
15074    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#SetStatic_type_Field_routines>
15075    ///
15076    /// # Arguments
15077    /// * `obj` - reference to the object the field is in
15078    ///     * must be valid
15079    ///     * must not be null
15080    ///     * must not be already garbage collected
15081    ///
15082    /// * `fieldID` - the field to set
15083    ///     * must be valid
15084    ///     * must be a object field
15085    ///     * must reside in the object `obj`
15086    ///
15087    /// * `value` - that value to set
15088    ///
15089    ///
15090    /// # Panics
15091    /// if asserts feature is enabled and UB was detected
15092    ///
15093    /// # Safety
15094    ///
15095    /// Current thread must not be detached from JNI.
15096    ///
15097    /// Current thread must not be currently throwing an exception.
15098    ///
15099    /// Current thread does not hold a critical reference.
15100    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15101    ///
15102    /// `obj` must be a valid reference to the class the field is in that is not already garbage collected.
15103    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
15104    /// `fieldID` must be from a static field
15105    /// `fieldID` must refer to a field that is a float.
15106    ///
15107    pub unsafe fn SetStaticFloatField(&self, obj: jclass, fieldID: jfieldID, value: jfloat) {
15108        unsafe {
15109            #[cfg(feature = "asserts")]
15110            {
15111                self.check_not_critical("SetStaticFloatField");
15112                self.check_no_exception("SetStaticFloatField");
15113                self.check_field_type_static("SetStaticFloatField", obj, fieldID, "float");
15114            }
15115            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jfloat)>(161)(self.vtable, obj, fieldID, value);
15116        }
15117    }
15118
15119    ///
15120    /// Sets a static double field to a given value
15121    ///
15122    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#SetStatic_type_Field_routines>
15123    ///
15124    /// # Arguments
15125    /// * `obj` - reference to the object the field is in
15126    ///     * must be valid
15127    ///     * must not be null
15128    ///     * must not be already garbage collected
15129    ///
15130    /// * `fieldID` - the field to set
15131    ///     * must be valid
15132    ///     * must be a object field
15133    ///     * must reside in the object `obj`
15134    ///
15135    /// * `value` - that value to set
15136    ///
15137    ///
15138    /// # Panics
15139    /// if asserts feature is enabled and UB was detected
15140    ///
15141    /// # Safety
15142    ///
15143    /// Current thread must not be detached from JNI.
15144    ///
15145    /// Current thread must not be currently throwing an exception.
15146    ///
15147    /// Current thread does not hold a critical reference.
15148    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15149    ///
15150    /// `obj` must be a valid reference to the class the field is in that is not already garbage collected.
15151    /// `fieldID` must be a fieldID of a field in `obj` and not some other unrelated class
15152    /// `fieldID` must be from a static field
15153    /// `fieldID` must refer to a field that is a double.
15154    ///
15155    pub unsafe fn SetStaticDoubleField(&self, obj: jclass, fieldID: jfieldID, value: jdouble) {
15156        unsafe {
15157            #[cfg(feature = "asserts")]
15158            {
15159                self.check_not_critical("SetStaticDoubleField");
15160                self.check_no_exception("SetStaticDoubleField");
15161                self.check_field_type_static("SetStaticDoubleField", obj, fieldID, "double");
15162            }
15163            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jfieldID, jdouble)>(162)(self.vtable, obj, fieldID, value);
15164        }
15165    }
15166
15167    ///
15168    /// Gets the method id of a static method
15169    ///
15170    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetMethodID>
15171    ///
15172    ///
15173    /// # Arguments
15174    /// * `clazz` - reference to the clazz where the field is declared in.
15175    ///     * must be valid
15176    ///     * must not be null
15177    ///     * must not be already garbage collected
15178    /// * `name` - name of the method
15179    ///     * must not be null
15180    ///     * must be zero terminated utf-8
15181    /// * `sig` - jni signature of the method
15182    ///     * must not be null
15183    ///     * must be zero terminated utf-8
15184    ///
15185    /// # Returns
15186    /// A non-null field handle or null on error.
15187    /// The field handle can be assumed to be constant for the given class and must not be freed.
15188    /// It can also be safely shared with any thread or stored in a constant.
15189    ///
15190    /// # Throws Java Exception
15191    /// * `NoSuchMethodError` - method with the given name and sig doesn't exist in the class
15192    /// * `ExceptionInInitializerError` - Exception occurs in initializer of the class
15193    /// * `OutOfMemoryError` - if the jvm runs out of memory
15194    ///
15195    ///
15196    /// # Panics
15197    /// if asserts feature is enabled and UB was detected
15198    ///
15199    /// # Safety
15200    ///
15201    /// Current thread must not be detached from JNI.
15202    ///
15203    /// Current thread must not be currently throwing an exception.
15204    ///
15205    /// Current thread does not hold a critical reference.
15206    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15207    ///
15208    /// `clazz` must a valid reference to a class that is not already garbage collected.
15209    /// `name` must be non-null and zero terminated utf-8.
15210    /// `sig` must be non-null and zero terminated utf-8.
15211    ///
15212    pub unsafe fn GetStaticMethodID(&self, class: jclass, name: impl UseCString, sig: impl UseCString) -> jmethodID {
15213        unsafe {
15214            name.use_as_const_c_char(|name| {
15215                sig.use_as_const_c_char(|sig| {
15216                    #[cfg(feature = "asserts")]
15217                    {
15218                        self.check_not_critical("GetStaticMethodID");
15219                        self.check_no_exception("GetStaticMethodID");
15220                        self.check_is_class("GetStaticMethodID", class);
15221                        assert!(!name.is_null(), "GetStaticMethodID name is null");
15222                        assert!(!sig.is_null(), "GetStaticMethodID sig is null");
15223                    }
15224
15225                    self.jni::<extern "system" fn(JNIEnvVTable, jobject, *const c_char, *const c_char) -> jmethodID>(113)(self.vtable, class, name, sig)
15226                })
15227            })
15228        }
15229    }
15230
15231    ///
15232    /// Calls a static java method that returns void
15233    ///
15234    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
15235    ///
15236    ///
15237    /// # Arguments
15238    /// * `obj` - which object the method should be called on
15239    ///     * must be valid
15240    ///     * must not be null
15241    ///     * must not be already garbage collected
15242    ///
15243    /// * `methodID` - method id of the method
15244    ///     * must not be null
15245    ///     * must be valid
15246    ///     * must not be a static
15247    ///     * must actually be a method of `obj`
15248    ///
15249    /// * `args` - argument pointer
15250    ///     * can be null if the method has no arguments
15251    ///     * must not be null otherwise and point to the exact number of arguments the method expects
15252    ///
15253    /// # Throws Java Exception
15254    /// * Whatever the method threw
15255    ///
15256    ///
15257    /// # Panics
15258    /// if asserts feature is enabled and UB was detected
15259    ///
15260    /// # Safety
15261    ///
15262    /// Current thread must not be detached from JNI.
15263    ///
15264    /// Current thread must not be currently throwing an exception.
15265    ///
15266    /// Current thread does not hold a critical reference.
15267    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15268    ///
15269    /// `obj` must a valid and not already garbage collected.
15270    /// `methodID` must be valid, static and actually be a method of `obj` class and return void
15271    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
15272    /// `args` union must contain types that match the java methods parameters.
15273    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
15274    ///
15275    pub unsafe fn CallStaticVoidMethodA(&self, clazz: jclass, methodID: jmethodID, args: *const jtype) {
15276        unsafe {
15277            #[cfg(feature = "asserts")]
15278            {
15279                self.check_not_critical("CallStaticVoidMethodA");
15280                self.check_no_exception("CallStaticVoidMethodA");
15281                self.check_return_type_static("CallStaticVoidMethodA", clazz, methodID, "void");
15282            }
15283            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype)>(143)(self.vtable, clazz, methodID, args);
15284        }
15285    }
15286
15287    ///
15288    /// Calls a static java method that has 0 arguments and returns void
15289    ///
15290    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
15291    ///
15292    ///
15293    /// # Arguments
15294    /// * `obj` - which object the method should be called on
15295    ///     * must be valid
15296    ///     * must not be null
15297    ///     * must not be already garbage collected
15298    ///
15299    /// * `methodID` - method id of the method
15300    ///     * must not be null
15301    ///     * must be valid
15302    ///     * must be a static
15303    ///     * must actually be a method of `obj`
15304    ///     * must refer to a method with 0 arguments
15305    ///
15306    /// # Throws Java Exception
15307    /// * Whatever the method threw
15308    ///
15309    ///
15310    /// # Panics
15311    /// if asserts feature is enabled and UB was detected
15312    ///
15313    /// # Safety
15314    ///
15315    /// Current thread must not be detached from JNI.
15316    ///
15317    /// Current thread must not be currently throwing an exception.
15318    ///
15319    /// Current thread does not hold a critical reference.
15320    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15321    ///
15322    /// `clazz` must a valid and not already garbage collected.
15323    /// `methodID` must be valid, static and actually be a method of `obj`, return void and have 0 arguments
15324    ///
15325    pub unsafe fn CallStaticVoidMethod0(&self, clazz: jclass, methodID: jmethodID) {
15326        unsafe {
15327            #[cfg(feature = "asserts")]
15328            {
15329                self.check_not_critical("CallStaticVoidMethod");
15330                self.check_no_exception("CallStaticVoidMethod");
15331                self.check_return_type_static("CallStaticVoidMethod", clazz, methodID, "void");
15332            }
15333            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID)>(141)(self.vtable, clazz, methodID);
15334        }
15335    }
15336
15337    ///
15338    /// Calls a static java method that has 1 arguments and returns void
15339    ///
15340    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
15341    ///
15342    ///
15343    /// # Arguments
15344    /// * `obj` - which object the method should be called on
15345    ///     * must be valid
15346    ///     * must not be null
15347    ///     * must not be already garbage collected
15348    ///
15349    /// * `methodID` - method id of the method
15350    ///     * must not be null
15351    ///     * must be valid
15352    ///     * must be a static
15353    ///     * must actually be a method of `obj`
15354    ///     * must refer to a method with 1 arguments
15355    ///
15356    /// # Throws Java Exception
15357    /// * Whatever the method threw
15358    ///
15359    ///
15360    /// # Panics
15361    /// if asserts feature is enabled and UB was detected
15362    ///
15363    /// # Safety
15364    ///
15365    /// Current thread must not be detached from JNI.
15366    ///
15367    /// Current thread must not be currently throwing an exception.
15368    ///
15369    /// Current thread does not hold a critical reference.
15370    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15371    ///
15372    /// `clazz` must a valid and not already garbage collected.
15373    /// `methodID` must be valid, static and actually be a method of `obj`, return void and have 1 arguments
15374    ///
15375    pub unsafe fn CallStaticVoidMethod1<A: JType>(&self, clazz: jclass, methodID: jmethodID, arg1: A) {
15376        unsafe {
15377            #[cfg(feature = "asserts")]
15378            {
15379                self.check_not_critical("CallStaticVoidMethod");
15380                self.check_no_exception("CallStaticVoidMethod");
15381                self.check_return_type_static("CallStaticVoidMethod", clazz, methodID, "void");
15382                self.check_parameter_types_static("CallStaticVoidMethod", clazz, methodID, arg1, 0, 1);
15383            }
15384            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...)>(141)(self.vtable, clazz, methodID, arg1);
15385        }
15386    }
15387
15388    ///
15389    /// Calls a static java method that has 2 arguments and returns void
15390    ///
15391    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
15392    ///
15393    ///
15394    /// # Arguments
15395    /// * `obj` - which object the method should be called on
15396    ///     * must be valid
15397    ///     * must not be null
15398    ///     * must not be already garbage collected
15399    ///
15400    /// * `methodID` - method id of the method
15401    ///     * must not be null
15402    ///     * must be valid
15403    ///     * must be a static
15404    ///     * must actually be a method of `obj`
15405    ///     * must refer to a method with 2 arguments
15406    ///
15407    /// # Throws Java Exception
15408    /// * Whatever the method threw
15409    ///
15410    ///
15411    /// # Panics
15412    /// if asserts feature is enabled and UB was detected
15413    ///
15414    /// # Safety
15415    ///
15416    /// Current thread must not be detached from JNI.
15417    ///
15418    /// Current thread must not be currently throwing an exception.
15419    ///
15420    /// Current thread does not hold a critical reference.
15421    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15422    ///
15423    /// `obj` must a valid and not already garbage collected.
15424    /// `methodID` must be valid, static and actually be a method of `obj`, return void and have 2 arguments
15425    ///
15426    pub unsafe fn CallStaticVoidMethod2<A: JType, B: JType>(&self, clazz: jclass, methodID: jmethodID, arg1: A, arg2: B) {
15427        unsafe {
15428            #[cfg(feature = "asserts")]
15429            {
15430                self.check_not_critical("CallStaticVoidMethod");
15431                self.check_no_exception("CallStaticVoidMethod");
15432                self.check_return_type_static("CallStaticVoidMethod", clazz, methodID, "void");
15433                self.check_parameter_types_static("CallStaticVoidMethod", clazz, methodID, arg1, 0, 2);
15434                self.check_parameter_types_static("CallStaticVoidMethod", clazz, methodID, arg2, 1, 2);
15435            }
15436            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...)>(141)(self.vtable, clazz, methodID, arg1, arg2);
15437        }
15438    }
15439
15440    ///
15441    /// Calls a static java method that has 3 arguments and returns void
15442    ///
15443    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
15444    ///
15445    ///
15446    /// # Arguments
15447    /// * `obj` - which object the method should be called on
15448    ///     * must be valid
15449    ///     * must not be null
15450    ///     * must not be already garbage collected
15451    ///
15452    /// * `methodID` - method id of the method
15453    ///     * must not be null
15454    ///     * must be valid
15455    ///     * must be a static
15456    ///     * must actually be a method of `obj`
15457    ///     * must refer to a method with 3 arguments
15458    ///
15459    /// # Throws Java Exception
15460    /// * Whatever the method threw
15461    ///
15462    ///
15463    /// # Panics
15464    /// if asserts feature is enabled and UB was detected
15465    ///
15466    /// # Safety
15467    ///
15468    /// Current thread must not be detached from JNI.
15469    ///
15470    /// Current thread must not be currently throwing an exception.
15471    ///
15472    /// Current thread does not hold a critical reference.
15473    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15474    ///
15475    /// `obj` must a valid and not already garbage collected.
15476    /// `methodID` must be valid, static and actually be a method of `obj`, return void and have 3 arguments
15477    ///
15478    pub unsafe fn CallStaticVoidMethod3<A: JType, B: JType, C: JType>(&self, clazz: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) {
15479        unsafe {
15480            #[cfg(feature = "asserts")]
15481            {
15482                self.check_not_critical("CallStaticVoidMethod");
15483                self.check_no_exception("CallStaticVoidMethod");
15484                self.check_return_type_static("CallStaticVoidMethod", clazz, methodID, "void");
15485                self.check_parameter_types_static("CallStaticVoidMethod", clazz, methodID, arg1, 0, 3);
15486                self.check_parameter_types_static("CallStaticVoidMethod", clazz, methodID, arg2, 1, 3);
15487                self.check_parameter_types_static("CallStaticVoidMethod", clazz, methodID, arg3, 2, 3);
15488            }
15489            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...)>(141)(self.vtable, clazz, methodID, arg1, arg2, arg3);
15490        }
15491    }
15492
15493    ///
15494    /// Calls a static java method that returns an object
15495    ///
15496    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
15497    ///
15498    ///
15499    /// # Arguments
15500    /// * `obj` - which object the method should be called on
15501    ///     * must be valid
15502    ///     * must not be null
15503    ///     * must not be already garbage collected
15504    ///
15505    /// * `methodID` - method id of the method
15506    ///     * must not be null
15507    ///     * must be valid
15508    ///     * must not be a static
15509    ///     * must actually be a method of `obj`
15510    ///
15511    /// * `args` - argument pointer
15512    ///     * can be null if the method has no arguments
15513    ///     * must not be null otherwise and point to the exact number of arguments the method expects
15514    ///
15515    /// # Returns
15516    /// Whatever the method returned or null if it threw
15517    ///
15518    /// # Throws Java Exception
15519    /// * Whatever the method threw
15520    ///
15521    ///
15522    /// # Panics
15523    /// if asserts feature is enabled and UB was detected
15524    ///
15525    /// # Safety
15526    ///
15527    /// Current thread must not be detached from JNI.
15528    ///
15529    /// Current thread must not be currently throwing an exception.
15530    ///
15531    /// Current thread does not hold a critical reference.
15532    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15533    ///
15534    /// `obj` must a valid and not already garbage collected.
15535    /// `methodID` must be valid, static and actually be a method of `obj` class and return an object
15536    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
15537    /// `args` union must contain types that match the java methods parameters.
15538    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
15539    ///
15540    pub unsafe fn CallStaticObjectMethodA(&self, obj: jclass, methodID: jmethodID, args: *const jtype) -> jobject {
15541        unsafe {
15542            #[cfg(feature = "asserts")]
15543            {
15544                self.check_not_critical("CallStaticObjectMethodA");
15545                self.check_no_exception("CallStaticObjectMethodA");
15546                self.check_return_type_static("CallStaticBooleanMethodA", obj, methodID, "object");
15547            }
15548            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(116)(self.vtable, obj, methodID, args)
15549        }
15550    }
15551
15552    ///
15553    /// Calls a static java method that has 0 arguments and returns an object
15554    ///
15555    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
15556    ///
15557    ///
15558    /// # Arguments
15559    /// * `obj` - which object the method should be called on
15560    ///     * must be valid
15561    ///     * must not be null
15562    ///     * must not be already garbage collected
15563    ///
15564    /// * `methodID` - method id of the method
15565    ///     * must not be null
15566    ///     * must be valid
15567    ///     * must be a static
15568    ///     * must actually be a method of `obj`
15569    ///     * must refer to a method with 0 arguments
15570    ///
15571    /// # Returns
15572    /// Whatever the method returned or null if it threw
15573    ///
15574    /// # Throws Java Exception
15575    /// * Whatever the method threw
15576    ///
15577    ///
15578    /// # Panics
15579    /// if asserts feature is enabled and UB was detected
15580    ///
15581    /// # Safety
15582    ///
15583    /// Current thread must not be detached from JNI.
15584    ///
15585    /// Current thread must not be currently throwing an exception.
15586    ///
15587    /// Current thread does not hold a critical reference.
15588    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15589    ///
15590    /// `obj` must a valid and not already garbage collected.
15591    /// `methodID` must be valid, static and actually be a method of `obj`, return an object and have 0 arguments
15592    ///
15593    pub unsafe fn CallStaticObjectMethod0(&self, obj: jclass, methodID: jmethodID) -> jobject {
15594        unsafe {
15595            #[cfg(feature = "asserts")]
15596            {
15597                self.check_not_critical("CallStaticObjectMethod");
15598                self.check_no_exception("CallStaticObjectMethod");
15599                self.check_return_type_static("CallStaticObjectMethod", obj, methodID, "object");
15600            }
15601            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jobject>(114)(self.vtable, obj, methodID)
15602        }
15603    }
15604
15605    ///
15606    /// Calls a static java method that has 1 arguments and returns an object
15607    ///
15608    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
15609    ///
15610    ///
15611    /// # Arguments
15612    /// * `obj` - which object the method should be called on
15613    ///     * must be valid
15614    ///     * must not be null
15615    ///     * must not be already garbage collected
15616    ///
15617    /// * `methodID` - method id of the method
15618    ///     * must not be null
15619    ///     * must be valid
15620    ///     * must be a static
15621    ///     * must actually be a method of `obj`
15622    ///     * must refer to a method with 1 arguments
15623    ///
15624    /// # Returns
15625    /// Whatever the method returned or null if it threw
15626    ///
15627    /// # Throws Java Exception
15628    /// * Whatever the method threw
15629    ///
15630    ///
15631    /// # Panics
15632    /// if asserts feature is enabled and UB was detected
15633    ///
15634    /// # Safety
15635    ///
15636    /// Current thread must not be detached from JNI.
15637    ///
15638    /// Current thread must not be currently throwing an exception.
15639    ///
15640    /// Current thread does not hold a critical reference.
15641    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15642    ///
15643    /// `obj` must a valid and not already garbage collected.
15644    /// `methodID` must be valid, static and actually be a method of `obj`, return an object and have 1 arguments
15645    ///
15646    pub unsafe fn CallStaticObjectMethod1<A: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A) -> jobject {
15647        unsafe {
15648            #[cfg(feature = "asserts")]
15649            {
15650                self.check_not_critical("CallStaticObjectMethod");
15651                self.check_no_exception("CallStaticObjectMethod");
15652                self.check_return_type_static("CallStaticObjectMethod", obj, methodID, "object");
15653                self.check_parameter_types_static("CallStaticObjectMethod", obj, methodID, arg1, 0, 1);
15654            }
15655            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jobject>(114)(self.vtable, obj, methodID, arg1)
15656        }
15657    }
15658
15659    ///
15660    /// Calls a static java method that has 2 arguments and returns an object
15661    ///
15662    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
15663    ///
15664    ///
15665    /// # Arguments
15666    /// * `obj` - which object the method should be called on
15667    ///     * must be valid
15668    ///     * must not be null
15669    ///     * must not be already garbage collected
15670    ///
15671    /// * `methodID` - method id of the method
15672    ///     * must not be null
15673    ///     * must be valid
15674    ///     * must be a static
15675    ///     * must actually be a method of `obj`
15676    ///     * must refer to a method with 2 arguments
15677    ///
15678    /// # Returns
15679    /// Whatever the method returned or null if it threw
15680    ///
15681    /// # Throws Java Exception
15682    /// * Whatever the method threw
15683    ///
15684    ///
15685    /// # Panics
15686    /// if asserts feature is enabled and UB was detected
15687    ///
15688    /// # Safety
15689    ///
15690    /// Current thread must not be detached from JNI.
15691    ///
15692    /// Current thread must not be currently throwing an exception.
15693    ///
15694    /// Current thread does not hold a critical reference.
15695    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15696    ///
15697    /// `obj` must a valid and not already garbage collected.
15698    /// `methodID` must be valid, static and actually be a method of `obj`, return an object and have 2 arguments
15699    ///
15700    pub unsafe fn CallStaticObjectMethod2<A: JType, B: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jobject {
15701        unsafe {
15702            #[cfg(feature = "asserts")]
15703            {
15704                self.check_not_critical("CallStaticObjectMethod");
15705                self.check_no_exception("CallStaticObjectMethod");
15706                self.check_return_type_static("CallStaticObjectMethod", obj, methodID, "object");
15707                self.check_parameter_types_static("CallStaticObjectMethod", obj, methodID, arg1, 0, 2);
15708                self.check_parameter_types_static("CallStaticObjectMethod", obj, methodID, arg2, 1, 2);
15709            }
15710            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jobject>(114)(self.vtable, obj, methodID, arg1, arg2)
15711        }
15712    }
15713
15714    ///
15715    /// Calls a static java method that has 3 arguments and returns an object
15716    ///
15717    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
15718    ///
15719    ///
15720    /// # Arguments
15721    /// * `obj` - which object the method should be called on
15722    ///     * must be valid
15723    ///     * must not be null
15724    ///     * must not be already garbage collected
15725    ///
15726    /// * `methodID` - method id of the method
15727    ///     * must not be null
15728    ///     * must be valid
15729    ///     * must be a static
15730    ///     * must actually be a method of `obj`
15731    ///     * must refer to a method with 3 arguments
15732    ///
15733    /// # Returns
15734    /// Whatever the method returned or null if it threw
15735    ///
15736    /// # Throws Java Exception
15737    /// * Whatever the method threw
15738    ///
15739    ///
15740    /// # Panics
15741    /// if asserts feature is enabled and UB was detected
15742    ///
15743    /// # Safety
15744    ///
15745    /// Current thread must not be detached from JNI.
15746    ///
15747    /// Current thread must not be currently throwing an exception.
15748    ///
15749    /// Current thread does not hold a critical reference.
15750    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15751    ///
15752    /// `obj` must a valid and not already garbage collected.
15753    /// `methodID` must be valid, static and actually be a method of `obj`, return an object and have 3 arguments
15754    ///
15755    pub unsafe fn CallStaticObjectMethod3<A: JType, B: JType, C: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jobject {
15756        unsafe {
15757            #[cfg(feature = "asserts")]
15758            {
15759                self.check_not_critical("CallStaticObjectMethod");
15760                self.check_no_exception("CallStaticObjectMethod");
15761                self.check_return_type_static("CallStaticObjectMethod", obj, methodID, "object");
15762                self.check_parameter_types_static("CallStaticObjectMethod", obj, methodID, arg1, 0, 3);
15763                self.check_parameter_types_static("CallStaticObjectMethod", obj, methodID, arg2, 1, 3);
15764                self.check_parameter_types_static("CallStaticObjectMethod", obj, methodID, arg3, 2, 3);
15765            }
15766            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jobject>(114)(self.vtable, obj, methodID, arg1, arg2, arg3)
15767        }
15768    }
15769
15770    ///
15771    /// Calls a static java method that returns a boolean
15772    ///
15773    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
15774    ///
15775    ///
15776    /// # Arguments
15777    /// * `obj` - which object the method should be called on
15778    ///     * must be valid
15779    ///     * must not be null
15780    ///     * must not be already garbage collected
15781    ///
15782    /// * `methodID` - method id of the method
15783    ///     * must not be null
15784    ///     * must be valid
15785    ///     * must not be a static
15786    ///     * must actually be a method of `obj`
15787    ///
15788    /// * `args` - argument pointer
15789    ///     * can be null if the method has no arguments
15790    ///     * must not be null otherwise and point to the exact number of arguments the method expects
15791    ///
15792    /// # Returns
15793    /// Whatever the method returned or null if it threw
15794    ///
15795    /// # Throws Java Exception
15796    /// * Whatever the method threw
15797    ///
15798    ///
15799    /// # Panics
15800    /// if asserts feature is enabled and UB was detected
15801    ///
15802    /// # Safety
15803    ///
15804    /// Current thread must not be detached from JNI.
15805    ///
15806    /// Current thread must not be currently throwing an exception.
15807    ///
15808    /// Current thread does not hold a critical reference.
15809    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15810    ///
15811    /// `obj` must a valid and not already garbage collected.
15812    /// `methodID` must be valid, static and actually be a method of `obj` class and return a boolean
15813    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
15814    /// `args` union must contain types that match the java methods parameters.
15815    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
15816    ///
15817    pub unsafe fn CallStaticBooleanMethodA(&self, obj: jclass, methodID: jmethodID, args: *const jtype) -> jboolean {
15818        unsafe {
15819            #[cfg(feature = "asserts")]
15820            {
15821                self.check_not_critical("CallStaticBooleanMethodA");
15822                self.check_no_exception("CallStaticBooleanMethodA");
15823                self.check_return_type_static("CallStaticBooleanMethodA", obj, methodID, "boolean");
15824            }
15825            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jboolean>(119)(self.vtable, obj, methodID, args)
15826        }
15827    }
15828
15829    ///
15830    /// Calls a static java method that has 0 arguments and returns boolean
15831    ///
15832    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
15833    ///
15834    ///
15835    /// # Arguments
15836    /// * `obj` - which object the method should be called on
15837    ///     * must be valid
15838    ///     * must not be null
15839    ///     * must not be already garbage collected
15840    ///
15841    /// * `methodID` - method id of the method
15842    ///     * must not be null
15843    ///     * must be valid
15844    ///     * must be a static
15845    ///     * must actually be a method of `obj`
15846    ///     * must refer to a method with 0 arguments
15847    ///
15848    /// # Returns
15849    /// Whatever the method returned or false if it threw
15850    ///
15851    /// # Throws Java Exception
15852    /// * Whatever the method threw
15853    ///
15854    ///
15855    /// # Panics
15856    /// if asserts feature is enabled and UB was detected
15857    ///
15858    /// # Safety
15859    ///
15860    /// Current thread must not be detached from JNI.
15861    ///
15862    /// Current thread must not be currently throwing an exception.
15863    ///
15864    /// Current thread does not hold a critical reference.
15865    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15866    ///
15867    /// `obj` must a valid and not already garbage collected.
15868    /// `methodID` must be valid, static and actually be a method of `obj`, return boolean and have 0 arguments
15869    ///
15870    pub unsafe fn CallStaticBooleanMethod0(&self, obj: jclass, methodID: jmethodID) -> jboolean {
15871        unsafe {
15872            #[cfg(feature = "asserts")]
15873            {
15874                self.check_not_critical("CallStaticBooleanMethod");
15875                self.check_no_exception("CallStaticBooleanMethod");
15876                self.check_return_type_static("CallStaticBooleanMethod", obj, methodID, "boolean");
15877            }
15878            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jboolean>(117)(self.vtable, obj, methodID)
15879        }
15880    }
15881
15882    ///
15883    /// Calls a static java method that has 1 arguments and returns boolean
15884    ///
15885    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
15886    ///
15887    ///
15888    /// # Arguments
15889    /// * `obj` - which object the method should be called on
15890    ///     * must be valid
15891    ///     * must not be null
15892    ///     * must not be already garbage collected
15893    ///
15894    /// * `methodID` - method id of the method
15895    ///     * must not be null
15896    ///     * must be valid
15897    ///     * must be a static
15898    ///     * must actually be a method of `obj`
15899    ///     * must refer to a method with 1 arguments
15900    ///
15901    /// # Returns
15902    /// Whatever the method returned or false if it threw
15903    ///
15904    /// # Throws Java Exception
15905    /// * Whatever the method threw
15906    ///
15907    ///
15908    /// # Panics
15909    /// if asserts feature is enabled and UB was detected
15910    ///
15911    /// # Safety
15912    ///
15913    /// Current thread must not be detached from JNI.
15914    ///
15915    /// Current thread must not be currently throwing an exception.
15916    ///
15917    /// Current thread does not hold a critical reference.
15918    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15919    ///
15920    /// `obj` must a valid and not already garbage collected.
15921    /// `methodID` must be valid, static and actually be a method of `obj`, return boolean and have 1 arguments
15922    ///
15923    pub unsafe fn CallStaticBooleanMethod1<A: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A) -> jboolean {
15924        unsafe {
15925            #[cfg(feature = "asserts")]
15926            {
15927                self.check_not_critical("CallStaticBooleanMethod");
15928                self.check_no_exception("CallStaticBooleanMethod");
15929                self.check_return_type_static("CallStaticBooleanMethod", obj, methodID, "boolean");
15930                self.check_parameter_types_static("CallStaticBooleanMethod", obj, methodID, arg1, 0, 1);
15931            }
15932            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jboolean>(117)(self.vtable, obj, methodID, arg1)
15933        }
15934    }
15935
15936    ///
15937    /// Calls a static java method that has 2 arguments and returns boolean
15938    ///
15939    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
15940    ///
15941    ///
15942    /// # Arguments
15943    /// * `obj` - which object the method should be called on
15944    ///     * must be valid
15945    ///     * must not be null
15946    ///     * must not be already garbage collected
15947    ///
15948    /// * `methodID` - method id of the method
15949    ///     * must not be null
15950    ///     * must be valid
15951    ///     * must be a static
15952    ///     * must actually be a method of `obj`
15953    ///     * must refer to a method with 2 arguments
15954    ///
15955    /// # Returns
15956    /// Whatever the method returned or false if it threw
15957    ///
15958    /// # Throws Java Exception
15959    /// * Whatever the method threw
15960    ///
15961    ///
15962    /// # Panics
15963    /// if asserts feature is enabled and UB was detected
15964    ///
15965    /// # Safety
15966    ///
15967    /// Current thread must not be detached from JNI.
15968    ///
15969    /// Current thread must not be currently throwing an exception.
15970    ///
15971    /// Current thread does not hold a critical reference.
15972    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
15973    ///
15974    /// `obj` must a valid and not already garbage collected.
15975    /// `methodID` must be valid, static and actually be a method of `obj`, return boolean and have 2 arguments
15976    ///
15977    pub unsafe fn CallStaticBooleanMethod2<A: JType, B: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jboolean {
15978        unsafe {
15979            #[cfg(feature = "asserts")]
15980            {
15981                self.check_not_critical("CallStaticBooleanMethod");
15982                self.check_no_exception("CallStaticBooleanMethod");
15983                self.check_return_type_static("CallStaticBooleanMethod", obj, methodID, "boolean");
15984                self.check_parameter_types_static("CallStaticBooleanMethod", obj, methodID, arg1, 0, 2);
15985                self.check_parameter_types_static("CallStaticBooleanMethod", obj, methodID, arg2, 1, 2);
15986            }
15987            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jboolean>(117)(self.vtable, obj, methodID, arg1, arg2)
15988        }
15989    }
15990
15991    ///
15992    /// Calls a static java method that has 3 arguments and returns boolean
15993    ///
15994    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
15995    ///
15996    ///
15997    /// # Arguments
15998    /// * `obj` - which object the method should be called on
15999    ///     * must be valid
16000    ///     * must not be null
16001    ///     * must not be already garbage collected
16002    ///
16003    /// * `methodID` - method id of the method
16004    ///     * must not be null
16005    ///     * must be valid
16006    ///     * must be a static
16007    ///     * must actually be a method of `obj`
16008    ///     * must refer to a method with 3 arguments
16009    ///
16010    /// # Returns
16011    /// Whatever the method returned or false if it threw
16012    ///
16013    /// # Throws Java Exception
16014    /// * Whatever the method threw
16015    ///
16016    ///
16017    /// # Panics
16018    /// if asserts feature is enabled and UB was detected
16019    ///
16020    /// # Safety
16021    ///
16022    /// Current thread must not be detached from JNI.
16023    ///
16024    /// Current thread must not be currently throwing an exception.
16025    ///
16026    /// Current thread does not hold a critical reference.
16027    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16028    ///
16029    /// `obj` must a valid and not already garbage collected.
16030    /// `methodID` must be valid, static and actually be a method of `obj`, return boolean and have 3 arguments
16031    ///
16032    pub unsafe fn CallStaticBooleanMethod3<A: JType, B: JType, C: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jboolean {
16033        unsafe {
16034            #[cfg(feature = "asserts")]
16035            {
16036                self.check_not_critical("CallStaticBooleanMethod");
16037                self.check_no_exception("CallStaticBooleanMethod");
16038                self.check_return_type_static("CallStaticBooleanMethod", obj, methodID, "boolean");
16039                self.check_parameter_types_static("CallStaticBooleanMethod", obj, methodID, arg1, 0, 3);
16040                self.check_parameter_types_static("CallStaticBooleanMethod", obj, methodID, arg2, 1, 3);
16041                self.check_parameter_types_static("CallStaticBooleanMethod", obj, methodID, arg3, 2, 3);
16042            }
16043            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jboolean>(117)(self.vtable, obj, methodID, arg1, arg2, arg3)
16044        }
16045    }
16046
16047    ///
16048    /// Calls a static java method that returns a byte
16049    ///
16050    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16051    ///
16052    ///
16053    /// # Arguments
16054    /// * `obj` - which object the method should be called on
16055    ///     * must be valid
16056    ///     * must not be null
16057    ///     * must not be already garbage collected
16058    ///
16059    /// * `methodID` - method id of the method
16060    ///     * must not be null
16061    ///     * must be valid
16062    ///     * must not be a static
16063    ///     * must actually be a method of `obj`
16064    ///
16065    /// * `args` - argument pointer
16066    ///     * can be null if the method has no arguments
16067    ///     * must not be null otherwise and point to the exact number of arguments the method expects
16068    ///
16069    /// # Returns
16070    /// Whatever the method returned or 0 if it threw
16071    ///
16072    /// # Throws Java Exception
16073    /// * Whatever the method threw
16074    ///
16075    ///
16076    /// # Panics
16077    /// if asserts feature is enabled and UB was detected
16078    ///
16079    /// # Safety
16080    ///
16081    /// Current thread must not be detached from JNI.
16082    ///
16083    /// Current thread must not be currently throwing an exception.
16084    ///
16085    /// Current thread does not hold a critical reference.
16086    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16087    ///
16088    /// `obj` must a valid and not already garbage collected.
16089    /// `methodID` must be valid, static and actually be a method of `obj` class and return a byte
16090    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
16091    /// `args` union must contain types that match the java methods parameters.
16092    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
16093    ///
16094    pub unsafe fn CallStaticByteMethodA(&self, obj: jclass, methodID: jmethodID, args: *const jtype) -> jbyte {
16095        unsafe {
16096            #[cfg(feature = "asserts")]
16097            {
16098                self.check_not_critical("CallStaticByteMethodA");
16099                self.check_no_exception("CallStaticByteMethodA");
16100                self.check_return_type_static("CallStaticByteMethodA", obj, methodID, "byte");
16101            }
16102            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jbyte>(122)(self.vtable, obj, methodID, args)
16103        }
16104    }
16105
16106    ///
16107    /// Calls a static java method that has 0 arguments and returns byte
16108    ///
16109    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16110    ///
16111    ///
16112    /// # Arguments
16113    /// * `obj` - which object the method should be called on
16114    ///     * must be valid
16115    ///     * must not be null
16116    ///     * must not be already garbage collected
16117    ///
16118    /// * `methodID` - method id of the method
16119    ///     * must not be null
16120    ///     * must be valid
16121    ///     * must be a static
16122    ///     * must actually be a method of `obj`
16123    ///     * must refer to a method with 0 arguments
16124    ///
16125    /// # Returns
16126    /// Whatever the method returned or 0 if it threw
16127    ///
16128    /// # Throws Java Exception
16129    /// * Whatever the method threw
16130    ///
16131    ///
16132    /// # Panics
16133    /// if asserts feature is enabled and UB was detected
16134    ///
16135    /// # Safety
16136    ///
16137    /// Current thread must not be detached from JNI.
16138    ///
16139    /// Current thread must not be currently throwing an exception.
16140    ///
16141    /// Current thread does not hold a critical reference.
16142    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16143    ///
16144    /// `obj` must a valid and not already garbage collected.
16145    /// `methodID` must be valid, static and actually be a method of `obj`, return byte and have 0 arguments
16146    ///
16147    pub unsafe fn CallStaticByteMethod0(&self, obj: jclass, methodID: jmethodID) -> jbyte {
16148        unsafe {
16149            #[cfg(feature = "asserts")]
16150            {
16151                self.check_not_critical("CallStaticByteMethod");
16152                self.check_no_exception("CallStaticByteMethod");
16153                self.check_return_type_static("CallStaticByteMethod", obj, methodID, "byte");
16154            }
16155            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jbyte>(120)(self.vtable, obj, methodID)
16156        }
16157    }
16158
16159    ///
16160    /// Calls a static java method that has 1 arguments and returns byte
16161    ///
16162    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16163    ///
16164    ///
16165    /// # Arguments
16166    /// * `obj` - which object the method should be called on
16167    ///     * must be valid
16168    ///     * must not be null
16169    ///     * must not be already garbage collected
16170    ///
16171    /// * `methodID` - method id of the method
16172    ///     * must not be null
16173    ///     * must be valid
16174    ///     * must be a static
16175    ///     * must actually be a method of `obj`
16176    ///     * must refer to a method with 1 arguments
16177    ///
16178    /// # Returns
16179    /// Whatever the method returned or 0 if it threw
16180    ///
16181    /// # Throws Java Exception
16182    /// * Whatever the method threw
16183    ///
16184    ///
16185    /// # Panics
16186    /// if asserts feature is enabled and UB was detected
16187    ///
16188    /// # Safety
16189    ///
16190    /// Current thread must not be detached from JNI.
16191    ///
16192    /// Current thread must not be currently throwing an exception.
16193    ///
16194    /// Current thread does not hold a critical reference.
16195    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16196    ///
16197    /// `obj` must a valid and not already garbage collected.
16198    /// `methodID` must be valid, static and actually be a method of `obj`, return byte and have 1 arguments
16199    ///
16200    pub unsafe fn CallStaticByteMethod1<A: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A) -> jbyte {
16201        unsafe {
16202            #[cfg(feature = "asserts")]
16203            {
16204                self.check_not_critical("CallStaticByteMethod");
16205                self.check_no_exception("CallStaticByteMethod");
16206                self.check_return_type_static("CallStaticByteMethod", obj, methodID, "byte");
16207                self.check_parameter_types_static("CallStaticByteMethod", obj, methodID, arg1, 0, 1);
16208            }
16209            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jbyte>(120)(self.vtable, obj, methodID, arg1)
16210        }
16211    }
16212
16213    ///
16214    /// Calls a static java method that has 2 arguments and returns byte
16215    ///
16216    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16217    ///
16218    ///
16219    /// # Arguments
16220    /// * `obj` - which object the method should be called on
16221    ///     * must be valid
16222    ///     * must not be null
16223    ///     * must not be already garbage collected
16224    ///
16225    /// * `methodID` - method id of the method
16226    ///     * must not be null
16227    ///     * must be valid
16228    ///     * must be a static
16229    ///     * must actually be a method of `obj`
16230    ///     * must refer to a method with 2 arguments
16231    ///
16232    /// # Returns
16233    /// Whatever the method returned or 0 if it threw
16234    ///
16235    /// # Throws Java Exception
16236    /// * Whatever the method threw
16237    ///
16238    ///
16239    /// # Panics
16240    /// if asserts feature is enabled and UB was detected
16241    ///
16242    /// # Safety
16243    ///
16244    /// Current thread must not be detached from JNI.
16245    ///
16246    /// Current thread must not be currently throwing an exception.
16247    ///
16248    /// Current thread does not hold a critical reference.
16249    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16250    ///
16251    /// `obj` must a valid and not already garbage collected.
16252    /// `methodID` must be valid, static and actually be a method of `obj`, return byte and have 2 arguments
16253    ///
16254    pub unsafe fn CallStaticByteMethod2<A: JType, B: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jbyte {
16255        unsafe {
16256            #[cfg(feature = "asserts")]
16257            {
16258                self.check_not_critical("CallStaticByteMethod");
16259                self.check_no_exception("CallStaticByteMethod");
16260                self.check_return_type_static("CallStaticByteMethod", obj, methodID, "byte");
16261                self.check_parameter_types_static("CallStaticByteMethod", obj, methodID, arg1, 0, 2);
16262                self.check_parameter_types_static("CallStaticByteMethod", obj, methodID, arg2, 1, 2);
16263            }
16264            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jbyte>(120)(self.vtable, obj, methodID, arg1, arg2)
16265        }
16266    }
16267
16268    ///
16269    /// Calls a static java method that has 3 arguments and returns byte
16270    ///
16271    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16272    ///
16273    ///
16274    /// # Arguments
16275    /// * `obj` - which object the method should be called on
16276    ///     * must be valid
16277    ///     * must not be null
16278    ///     * must not be already garbage collected
16279    ///
16280    /// * `methodID` - method id of the method
16281    ///     * must not be null
16282    ///     * must be valid
16283    ///     * must be a static
16284    ///     * must actually be a method of `obj`
16285    ///     * must refer to a method with 3 arguments
16286    ///
16287    /// # Returns
16288    /// Whatever the method returned or 0 if it threw
16289    ///
16290    /// # Throws Java Exception
16291    /// * Whatever the method threw
16292    ///
16293    ///
16294    /// # Panics
16295    /// if asserts feature is enabled and UB was detected
16296    ///
16297    /// # Safety
16298    ///
16299    /// Current thread must not be detached from JNI.
16300    ///
16301    /// Current thread must not be currently throwing an exception.
16302    ///
16303    /// Current thread does not hold a critical reference.
16304    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16305    ///
16306    /// `obj` must a valid and not already garbage collected.
16307    /// `methodID` must be valid, static and actually be a method of `obj`, return byte and have 3 arguments
16308    ///
16309    pub unsafe fn CallStaticByteMethod3<A: JType, B: JType, C: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jbyte {
16310        unsafe {
16311            #[cfg(feature = "asserts")]
16312            {
16313                self.check_not_critical("CallStaticByteMethod");
16314                self.check_no_exception("CallStaticByteMethod");
16315                self.check_return_type_static("CallStaticByteMethod", obj, methodID, "byte");
16316                self.check_parameter_types_static("CallStaticByteMethod", obj, methodID, arg1, 0, 3);
16317                self.check_parameter_types_static("CallStaticByteMethod", obj, methodID, arg2, 1, 3);
16318                self.check_parameter_types_static("CallStaticByteMethod", obj, methodID, arg3, 2, 3);
16319            }
16320            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jbyte>(120)(self.vtable, obj, methodID, arg1, arg2, arg3)
16321        }
16322    }
16323
16324    ///
16325    /// Calls a static java method that returns a char
16326    ///
16327    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16328    ///
16329    ///
16330    /// # Arguments
16331    /// * `obj` - which object the method should be called on
16332    ///     * must be valid
16333    ///     * must not be null
16334    ///     * must not be already garbage collected
16335    ///
16336    /// * `methodID` - method id of the method
16337    ///     * must not be null
16338    ///     * must be valid
16339    ///     * must not be a static
16340    ///     * must actually be a method of `obj`
16341    ///
16342    /// * `args` - argument pointer
16343    ///     * can be null if the method has no arguments
16344    ///     * must not be null otherwise and point to the exact number of arguments the method expects
16345    ///
16346    /// # Returns
16347    /// Whatever the method returned or 0 if it threw
16348    ///
16349    /// # Throws Java Exception
16350    /// * Whatever the method threw
16351    ///
16352    ///
16353    /// # Panics
16354    /// if asserts feature is enabled and UB was detected
16355    ///
16356    /// # Safety
16357    ///
16358    /// Current thread must not be detached from JNI.
16359    ///
16360    /// Current thread must not be currently throwing an exception.
16361    ///
16362    /// Current thread does not hold a critical reference.
16363    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16364    ///
16365    /// `obj` must a valid and not already garbage collected.
16366    /// `methodID` must be valid, static and actually be a method of `obj` class and return a char
16367    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
16368    /// `args` union must contain types that match the java methods parameters.
16369    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
16370    ///
16371    pub unsafe fn CallStaticCharMethodA(&self, obj: jclass, methodID: jmethodID, args: *const jtype) -> jchar {
16372        unsafe {
16373            #[cfg(feature = "asserts")]
16374            {
16375                self.check_not_critical("CallStaticCharMethodA");
16376                self.check_no_exception("CallStaticCharMethodA");
16377                self.check_return_type_static("CallStaticCharMethodA", obj, methodID, "char");
16378            }
16379            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jchar>(125)(self.vtable, obj, methodID, args)
16380        }
16381    }
16382
16383    ///
16384    /// Calls a static java method that has 0 arguments and returns char
16385    ///
16386    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16387    ///
16388    ///
16389    /// # Arguments
16390    /// * `obj` - which object the method should be called on
16391    ///     * must be valid
16392    ///     * must not be null
16393    ///     * must not be already garbage collected
16394    ///
16395    /// * `methodID` - method id of the method
16396    ///     * must not be null
16397    ///     * must be valid
16398    ///     * must be a static
16399    ///     * must actually be a method of `obj`
16400    ///     * must refer to a method with 0 arguments
16401    ///
16402    /// # Returns
16403    /// Whatever the method returned or 0 if it threw
16404    ///
16405    /// # Throws Java Exception
16406    /// * Whatever the method threw
16407    ///
16408    ///
16409    /// # Panics
16410    /// if asserts feature is enabled and UB was detected
16411    ///
16412    /// # Safety
16413    ///
16414    /// Current thread must not be detached from JNI.
16415    ///
16416    /// Current thread must not be currently throwing an exception.
16417    ///
16418    /// Current thread does not hold a critical reference.
16419    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16420    ///
16421    /// `obj` must a valid and not already garbage collected.
16422    /// `methodID` must be valid, static and actually be a method of `obj`, return char and have 0 arguments
16423    ///
16424    pub unsafe fn CallStaticCharMethod0(&self, obj: jclass, methodID: jmethodID) -> jchar {
16425        unsafe {
16426            #[cfg(feature = "asserts")]
16427            {
16428                self.check_not_critical("CallStaticCharMethod");
16429                self.check_no_exception("CallStaticCharMethod");
16430                self.check_return_type_static("CallStaticCharMethod", obj, methodID, "char");
16431            }
16432            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jchar>(123)(self.vtable, obj, methodID)
16433        }
16434    }
16435
16436    ///
16437    /// Calls a static java method that has 1 arguments and returns char
16438    ///
16439    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16440    ///
16441    ///
16442    /// # Arguments
16443    /// * `obj` - which object the method should be called on
16444    ///     * must be valid
16445    ///     * must not be null
16446    ///     * must not be already garbage collected
16447    ///
16448    /// * `methodID` - method id of the method
16449    ///     * must not be null
16450    ///     * must be valid
16451    ///     * must be a static
16452    ///     * must actually be a method of `obj`
16453    ///     * must refer to a method with 1 arguments
16454    ///
16455    /// # Returns
16456    /// Whatever the method returned or 0 if it threw
16457    ///
16458    /// # Throws Java Exception
16459    /// * Whatever the method threw
16460    ///
16461    ///
16462    /// # Panics
16463    /// if asserts feature is enabled and UB was detected
16464    ///
16465    /// # Safety
16466    ///
16467    /// Current thread must not be detached from JNI.
16468    ///
16469    /// Current thread must not be currently throwing an exception.
16470    ///
16471    /// Current thread does not hold a critical reference.
16472    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16473    ///
16474    /// `obj` must a valid and not already garbage collected.
16475    /// `methodID` must be valid, static and actually be a method of `obj`, return char and have 1 arguments
16476    ///
16477    pub unsafe fn CallStaticCharMethod1<A: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A) -> jchar {
16478        unsafe {
16479            #[cfg(feature = "asserts")]
16480            {
16481                self.check_not_critical("CallStaticCharMethod");
16482                self.check_no_exception("CallStaticCharMethod");
16483                self.check_return_type_static("CallStaticCharMethod", obj, methodID, "char");
16484                self.check_parameter_types_static("CallStaticCharMethod", obj, methodID, arg1, 0, 1);
16485            }
16486            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jchar>(123)(self.vtable, obj, methodID, arg1)
16487        }
16488    }
16489
16490    ///
16491    /// Calls a static java method that has 2 arguments and returns char
16492    ///
16493    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16494    ///
16495    ///
16496    /// # Arguments
16497    /// * `obj` - which object the method should be called on
16498    ///     * must be valid
16499    ///     * must not be null
16500    ///     * must not be already garbage collected
16501    ///
16502    /// * `methodID` - method id of the method
16503    ///     * must not be null
16504    ///     * must be valid
16505    ///     * must be a static
16506    ///     * must actually be a method of `obj`
16507    ///     * must refer to a method with 2 arguments
16508    ///
16509    /// # Returns
16510    /// Whatever the method returned or 0 if it threw
16511    ///
16512    /// # Throws Java Exception
16513    /// * Whatever the method threw
16514    ///
16515    ///
16516    /// # Panics
16517    /// if asserts feature is enabled and UB was detected
16518    ///
16519    /// # Safety
16520    ///
16521    /// Current thread must not be detached from JNI.
16522    ///
16523    /// Current thread must not be currently throwing an exception.
16524    ///
16525    /// Current thread does not hold a critical reference.
16526    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16527    ///
16528    /// `obj` must a valid and not already garbage collected.
16529    /// `methodID` must be valid, static and actually be a method of `obj`, return char and have 2 arguments
16530    ///
16531    pub unsafe fn CallStaticCharMethod2<A: JType, B: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jchar {
16532        unsafe {
16533            #[cfg(feature = "asserts")]
16534            {
16535                self.check_not_critical("CallStaticCharMethod");
16536                self.check_no_exception("CallStaticCharMethod");
16537                self.check_return_type_static("CallStaticCharMethod", obj, methodID, "char");
16538                self.check_parameter_types_static("CallStaticCharMethod", obj, methodID, arg1, 0, 2);
16539                self.check_parameter_types_static("CallStaticCharMethod", obj, methodID, arg2, 1, 2);
16540            }
16541            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jchar>(123)(self.vtable, obj, methodID, arg1, arg2)
16542        }
16543    }
16544
16545    ///
16546    /// Calls a static java method that has 3 arguments and returns char
16547    ///
16548    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16549    ///
16550    ///
16551    /// # Arguments
16552    /// * `obj` - which object the method should be called on
16553    ///     * must be valid
16554    ///     * must not be null
16555    ///     * must not be already garbage collected
16556    ///
16557    /// * `methodID` - method id of the method
16558    ///     * must not be null
16559    ///     * must be valid
16560    ///     * must be a static
16561    ///     * must actually be a method of `obj`
16562    ///     * must refer to a method with 3 arguments
16563    ///
16564    /// # Returns
16565    /// Whatever the method returned or 0 if it threw
16566    ///
16567    /// # Throws Java Exception
16568    /// * Whatever the method threw
16569    ///
16570    ///
16571    /// # Panics
16572    /// if asserts feature is enabled and UB was detected
16573    ///
16574    /// # Safety
16575    ///
16576    /// Current thread must not be detached from JNI.
16577    ///
16578    /// Current thread must not be currently throwing an exception.
16579    ///
16580    /// Current thread does not hold a critical reference.
16581    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16582    ///
16583    /// `obj` must a valid and not already garbage collected.
16584    /// `methodID` must be valid, static and actually be a method of `obj`, return char and have 3 arguments
16585    ///
16586    pub unsafe fn CallStaticCharMethod3<A: JType, B: JType, C: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jchar {
16587        unsafe {
16588            #[cfg(feature = "asserts")]
16589            {
16590                self.check_not_critical("CallStaticCharMethod");
16591                self.check_no_exception("CallStaticCharMethod");
16592                self.check_return_type_static("CallStaticCharMethod", obj, methodID, "char");
16593                self.check_parameter_types_static("CallStaticCharMethod", obj, methodID, arg1, 0, 3);
16594                self.check_parameter_types_static("CallStaticCharMethod", obj, methodID, arg2, 1, 3);
16595                self.check_parameter_types_static("CallStaticCharMethod", obj, methodID, arg3, 2, 3);
16596            }
16597            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jchar>(123)(self.vtable, obj, methodID, arg1, arg2, arg3)
16598        }
16599    }
16600
16601    ///
16602    /// Calls a static java method that returns a short
16603    ///
16604    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16605    ///
16606    ///
16607    /// # Arguments
16608    /// * `obj` - which object the method should be called on
16609    ///     * must be valid
16610    ///     * must not be null
16611    ///     * must not be already garbage collected
16612    ///
16613    /// * `methodID` - method id of the method
16614    ///     * must not be null
16615    ///     * must be valid
16616    ///     * must not be a static
16617    ///     * must actually be a method of `obj`
16618    ///
16619    /// * `args` - argument pointer
16620    ///     * can be null if the method has no arguments
16621    ///     * must not be null otherwise and point to the exact number of arguments the method expects
16622    ///
16623    /// # Returns
16624    /// Whatever the method returned or 0 if it threw
16625    ///
16626    /// # Throws Java Exception
16627    /// * Whatever the method threw
16628    ///
16629    ///
16630    /// # Panics
16631    /// if asserts feature is enabled and UB was detected
16632    ///
16633    /// # Safety
16634    ///
16635    /// Current thread must not be detached from JNI.
16636    ///
16637    /// Current thread must not be currently throwing an exception.
16638    ///
16639    /// Current thread does not hold a critical reference.
16640    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16641    ///
16642    /// `obj` must a valid and not already garbage collected.
16643    /// `methodID` must be valid, static and actually be a method of `obj` class and return a short
16644    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
16645    /// `args` union must contain types that match the java methods parameters.
16646    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
16647    ///
16648    pub unsafe fn CallStaticShortMethodA(&self, obj: jclass, methodID: jmethodID, args: *const jtype) -> jshort {
16649        unsafe {
16650            #[cfg(feature = "asserts")]
16651            {
16652                self.check_not_critical("CallStaticShortMethodA");
16653                self.check_no_exception("CallStaticShortMethodA");
16654                self.check_return_type_static("CallStaticShortMethodA", obj, methodID, "short");
16655            }
16656            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jshort>(128)(self.vtable, obj, methodID, args)
16657        }
16658    }
16659
16660    ///
16661    /// Calls a static java method that has 0 arguments and returns short
16662    ///
16663    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16664    ///
16665    ///
16666    /// # Arguments
16667    /// * `obj` - which object the method should be called on
16668    ///     * must be valid
16669    ///     * must not be null
16670    ///     * must not be already garbage collected
16671    ///
16672    /// * `methodID` - method id of the method
16673    ///     * must not be null
16674    ///     * must be valid
16675    ///     * must be a static
16676    ///     * must actually be a method of `obj`
16677    ///     * must refer to a method with 0 arguments
16678    ///
16679    /// # Returns
16680    /// Whatever the method returned or 0 if it threw
16681    ///
16682    /// # Throws Java Exception
16683    /// * Whatever the method threw
16684    ///
16685    ///
16686    /// # Panics
16687    /// if asserts feature is enabled and UB was detected
16688    ///
16689    /// # Safety
16690    ///
16691    /// Current thread must not be detached from JNI.
16692    ///
16693    /// Current thread must not be currently throwing an exception.
16694    ///
16695    /// Current thread does not hold a critical reference.
16696    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16697    ///
16698    /// `obj` must a valid and not already garbage collected.
16699    /// `methodID` must be valid, static and actually be a method of `obj`, return short and have 0 arguments
16700    ///
16701    pub unsafe fn CallStaticShortMethod0(&self, obj: jclass, methodID: jmethodID) -> jshort {
16702        unsafe {
16703            #[cfg(feature = "asserts")]
16704            {
16705                self.check_not_critical("CallStaticShortMethod");
16706                self.check_no_exception("CallStaticShortMethod");
16707                self.check_return_type_static("CallStaticShortMethod", obj, methodID, "short");
16708            }
16709            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jshort>(126)(self.vtable, obj, methodID)
16710        }
16711    }
16712
16713    ///
16714    /// Calls a static java method that has 1 arguments and returns short
16715    ///
16716    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16717    ///
16718    ///
16719    /// # Arguments
16720    /// * `obj` - which object the method should be called on
16721    ///     * must be valid
16722    ///     * must not be null
16723    ///     * must not be already garbage collected
16724    ///
16725    /// * `methodID` - method id of the method
16726    ///     * must not be null
16727    ///     * must be valid
16728    ///     * must be a static
16729    ///     * must actually be a method of `obj`
16730    ///     * must refer to a method with 1 arguments
16731    ///
16732    /// # Returns
16733    /// Whatever the method returned or 0 if it threw
16734    ///
16735    /// # Throws Java Exception
16736    /// * Whatever the method threw
16737    ///
16738    ///
16739    /// # Panics
16740    /// if asserts feature is enabled and UB was detected
16741    ///
16742    /// # Safety
16743    ///
16744    /// Current thread must not be detached from JNI.
16745    ///
16746    /// Current thread must not be currently throwing an exception.
16747    ///
16748    /// Current thread does not hold a critical reference.
16749    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16750    ///
16751    /// `obj` must a valid and not already garbage collected.
16752    /// `methodID` must be valid, static and actually be a method of `obj`, return short and have 1 arguments
16753    ///
16754    pub unsafe fn CallStaticShortMethod1<A: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A) -> jshort {
16755        unsafe {
16756            #[cfg(feature = "asserts")]
16757            {
16758                self.check_not_critical("CallStaticShortMethod");
16759                self.check_no_exception("CallStaticShortMethod");
16760                self.check_return_type_static("CallStaticShortMethod", obj, methodID, "short");
16761                self.check_parameter_types_static("CallStaticShortMethod", obj, methodID, arg1, 0, 1);
16762            }
16763            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jshort>(126)(self.vtable, obj, methodID, arg1)
16764        }
16765    }
16766
16767    ///
16768    /// Calls a static java method that has 2 arguments and returns short
16769    ///
16770    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16771    ///
16772    ///
16773    /// # Arguments
16774    /// * `obj` - which object the method should be called on
16775    ///     * must be valid
16776    ///     * must not be null
16777    ///     * must not be already garbage collected
16778    ///
16779    /// * `methodID` - method id of the method
16780    ///     * must not be null
16781    ///     * must be valid
16782    ///     * must be a static
16783    ///     * must actually be a method of `obj`
16784    ///     * must refer to a method with 2 arguments
16785    ///
16786    /// # Returns
16787    /// Whatever the method returned or 0 if it threw
16788    ///
16789    /// # Throws Java Exception
16790    /// * Whatever the method threw
16791    ///
16792    ///
16793    /// # Panics
16794    /// if asserts feature is enabled and UB was detected
16795    ///
16796    /// # Safety
16797    ///
16798    /// Current thread must not be detached from JNI.
16799    ///
16800    /// Current thread must not be currently throwing an exception.
16801    ///
16802    /// Current thread does not hold a critical reference.
16803    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16804    ///
16805    /// `obj` must a valid and not already garbage collected.
16806    /// `methodID` must be valid, static and actually be a method of `obj`, return short and have 2 arguments
16807    ///
16808    pub unsafe fn CallStaticShortMethod2<A: JType, B: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jshort {
16809        unsafe {
16810            #[cfg(feature = "asserts")]
16811            {
16812                self.check_not_critical("CallStaticShortMethod");
16813                self.check_no_exception("CallStaticShortMethod");
16814                self.check_return_type_static("CallStaticShortMethod", obj, methodID, "short");
16815                self.check_parameter_types_static("CallStaticShortMethod", obj, methodID, arg1, 0, 2);
16816                self.check_parameter_types_static("CallStaticShortMethod", obj, methodID, arg2, 1, 2);
16817            }
16818            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jshort>(126)(self.vtable, obj, methodID, arg1, arg2)
16819        }
16820    }
16821
16822    ///
16823    /// Calls a static java method that has 3 arguments and returns short
16824    ///
16825    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16826    ///
16827    ///
16828    /// # Arguments
16829    /// * `obj` - which object the method should be called on
16830    ///     * must be valid
16831    ///     * must not be null
16832    ///     * must not be already garbage collected
16833    ///
16834    /// * `methodID` - method id of the method
16835    ///     * must not be null
16836    ///     * must be valid
16837    ///     * must be a static
16838    ///     * must actually be a method of `obj`
16839    ///     * must refer to a method with 3 arguments
16840    ///
16841    /// # Returns
16842    /// Whatever the method returned or 0 if it threw
16843    ///
16844    /// # Throws Java Exception
16845    /// * Whatever the method threw
16846    ///
16847    ///
16848    /// # Panics
16849    /// if asserts feature is enabled and UB was detected
16850    ///
16851    /// # Safety
16852    ///
16853    /// Current thread must not be detached from JNI.
16854    ///
16855    /// Current thread must not be currently throwing an exception.
16856    ///
16857    /// Current thread does not hold a critical reference.
16858    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16859    ///
16860    /// `obj` must a valid and not already garbage collected.
16861    /// `methodID` must be valid, static and actually be a method of `obj`, return short and have 3 arguments
16862    ///
16863    pub unsafe fn CallStaticShortMethod3<A: JType, B: JType, C: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jshort {
16864        unsafe {
16865            #[cfg(feature = "asserts")]
16866            {
16867                self.check_not_critical("CallStaticShortMethod");
16868                self.check_no_exception("CallStaticShortMethod");
16869                self.check_return_type_static("CallStaticShortMethod", obj, methodID, "short");
16870                self.check_parameter_types_static("CallStaticShortMethod", obj, methodID, arg1, 0, 3);
16871                self.check_parameter_types_static("CallStaticShortMethod", obj, methodID, arg2, 1, 3);
16872                self.check_parameter_types_static("CallStaticShortMethod", obj, methodID, arg3, 2, 3);
16873            }
16874            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jshort>(126)(self.vtable, obj, methodID, arg1, arg2, arg3)
16875        }
16876    }
16877
16878    ///
16879    /// Calls a static java method that returns a int
16880    ///
16881    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16882    ///
16883    ///
16884    /// # Arguments
16885    /// * `obj` - which object the method should be called on
16886    ///     * must be valid
16887    ///     * must not be null
16888    ///     * must not be already garbage collected
16889    ///
16890    /// * `methodID` - method id of the method
16891    ///     * must not be null
16892    ///     * must be valid
16893    ///     * must not be a static
16894    ///     * must actually be a method of `obj`
16895    ///
16896    /// * `args` - argument pointer
16897    ///     * can be null if the method has no arguments
16898    ///     * must not be null otherwise and point to the exact number of arguments the method expects
16899    ///
16900    /// # Returns
16901    /// Whatever the method returned or 0 if it threw
16902    ///
16903    /// # Throws Java Exception
16904    /// * Whatever the method threw
16905    ///
16906    ///
16907    /// # Panics
16908    /// if asserts feature is enabled and UB was detected
16909    ///
16910    /// # Safety
16911    ///
16912    /// Current thread must not be detached from JNI.
16913    ///
16914    /// Current thread must not be currently throwing an exception.
16915    ///
16916    /// Current thread does not hold a critical reference.
16917    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16918    ///
16919    /// `obj` must a valid and not already garbage collected.
16920    /// `methodID` must be valid, static and actually be a method of `obj` class and return a int
16921    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
16922    /// `args` union must contain types that match the java methods parameters.
16923    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
16924    ///
16925    pub unsafe fn CallStaticIntMethodA(&self, obj: jclass, methodID: jmethodID, args: *const jtype) -> jint {
16926        unsafe {
16927            #[cfg(feature = "asserts")]
16928            {
16929                self.check_not_critical("CallStaticIntMethodA");
16930                self.check_no_exception("CallStaticIntMethodA");
16931                self.check_return_type_static("CallStaticIntMethodA", obj, methodID, "int");
16932            }
16933            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jint>(131)(self.vtable, obj, methodID, args)
16934        }
16935    }
16936
16937    ///
16938    /// Calls a static java method that has 0 arguments and returns int
16939    ///
16940    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16941    ///
16942    ///
16943    /// # Arguments
16944    /// * `obj` - which object the method should be called on
16945    ///     * must be valid
16946    ///     * must not be null
16947    ///     * must not be already garbage collected
16948    ///
16949    /// * `methodID` - method id of the method
16950    ///     * must not be null
16951    ///     * must be valid
16952    ///     * must be a static
16953    ///     * must actually be a method of `obj`
16954    ///     * must refer to a method with 0 arguments
16955    ///
16956    /// # Returns
16957    /// Whatever the method returned or 0 if it threw
16958    ///
16959    /// # Throws Java Exception
16960    /// * Whatever the method threw
16961    ///
16962    ///
16963    /// # Panics
16964    /// if asserts feature is enabled and UB was detected
16965    ///
16966    /// # Safety
16967    ///
16968    /// Current thread must not be detached from JNI.
16969    ///
16970    /// Current thread must not be currently throwing an exception.
16971    ///
16972    /// Current thread does not hold a critical reference.
16973    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
16974    ///
16975    /// `obj` must a valid and not already garbage collected.
16976    /// `methodID` must be valid, static and actually be a method of `obj`, return int and have 0 arguments
16977    ///
16978    pub unsafe fn CallStaticIntMethod0(&self, obj: jclass, methodID: jmethodID) -> jint {
16979        unsafe {
16980            #[cfg(feature = "asserts")]
16981            {
16982                self.check_not_critical("CallStaticIntMethod");
16983                self.check_no_exception("CallStaticIntMethod");
16984                self.check_return_type_static("CallStaticIntMethod", obj, methodID, "int");
16985            }
16986            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jint>(129)(self.vtable, obj, methodID)
16987        }
16988    }
16989
16990    ///
16991    /// Calls a static java method that has 1 arguments and returns int
16992    ///
16993    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
16994    ///
16995    ///
16996    /// # Arguments
16997    /// * `obj` - which object the method should be called on
16998    ///     * must be valid
16999    ///     * must not be null
17000    ///     * must not be already garbage collected
17001    ///
17002    /// * `methodID` - method id of the method
17003    ///     * must not be null
17004    ///     * must be valid
17005    ///     * must be a static
17006    ///     * must actually be a method of `obj`
17007    ///     * must refer to a method with 1 arguments
17008    ///
17009    /// # Returns
17010    /// Whatever the method returned or 0 if it threw
17011    ///
17012    /// # Throws Java Exception
17013    /// * Whatever the method threw
17014    ///
17015    ///
17016    /// # Panics
17017    /// if asserts feature is enabled and UB was detected
17018    ///
17019    /// # Safety
17020    ///
17021    /// Current thread must not be detached from JNI.
17022    ///
17023    /// Current thread must not be currently throwing an exception.
17024    ///
17025    /// Current thread does not hold a critical reference.
17026    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17027    ///
17028    /// `obj` must a valid and not already garbage collected.
17029    /// `methodID` must be valid, static and actually be a method of `obj`, return int and have 1 arguments
17030    ///
17031    pub unsafe fn CallStaticIntMethod1<A: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A) -> jint {
17032        unsafe {
17033            #[cfg(feature = "asserts")]
17034            {
17035                self.check_not_critical("CallStaticIntMethod");
17036                self.check_no_exception("CallStaticIntMethod");
17037                self.check_return_type_static("CallStaticIntMethod", obj, methodID, "int");
17038                self.check_parameter_types_static("CallStaticIntMethod", obj, methodID, arg1, 0, 1);
17039            }
17040            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jint>(129)(self.vtable, obj, methodID, arg1)
17041        }
17042    }
17043
17044    ///
17045    /// Calls a static java method that has 2 arguments and returns int
17046    ///
17047    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17048    ///
17049    ///
17050    /// # Arguments
17051    /// * `obj` - which object the method should be called on
17052    ///     * must be valid
17053    ///     * must not be null
17054    ///     * must not be already garbage collected
17055    ///
17056    /// * `methodID` - method id of the method
17057    ///     * must not be null
17058    ///     * must be valid
17059    ///     * must be a static
17060    ///     * must actually be a method of `obj`
17061    ///     * must refer to a method with 2 arguments
17062    ///
17063    /// # Returns
17064    /// Whatever the method returned or 0 if it threw
17065    ///
17066    /// # Throws Java Exception
17067    /// * Whatever the method threw
17068    ///
17069    ///
17070    /// # Panics
17071    /// if asserts feature is enabled and UB was detected
17072    ///
17073    /// # Safety
17074    ///
17075    /// Current thread must not be detached from JNI.
17076    ///
17077    /// Current thread must not be currently throwing an exception.
17078    ///
17079    /// Current thread does not hold a critical reference.
17080    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17081    ///
17082    /// `obj` must a valid and not already garbage collected.
17083    /// `methodID` must be valid, static and actually be a method of `obj`, return int and have 2 arguments
17084    ///
17085    pub unsafe fn CallStaticIntMethod2<A: JType, B: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jint {
17086        unsafe {
17087            #[cfg(feature = "asserts")]
17088            {
17089                self.check_not_critical("CallStaticIntMethod");
17090                self.check_no_exception("CallStaticIntMethod");
17091                self.check_return_type_static("CallStaticIntMethod", obj, methodID, "int");
17092                self.check_parameter_types_static("CallStaticIntMethod", obj, methodID, arg1, 0, 2);
17093                self.check_parameter_types_static("CallStaticIntMethod", obj, methodID, arg2, 1, 2);
17094            }
17095            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jint>(129)(self.vtable, obj, methodID, arg1, arg2)
17096        }
17097    }
17098
17099    ///
17100    /// Calls a static java method that has 3 arguments and returns int
17101    ///
17102    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17103    ///
17104    ///
17105    /// # Arguments
17106    /// * `obj` - which object the method should be called on
17107    ///     * must be valid
17108    ///     * must not be null
17109    ///     * must not be already garbage collected
17110    ///
17111    /// * `methodID` - method id of the method
17112    ///     * must not be null
17113    ///     * must be valid
17114    ///     * must be a static
17115    ///     * must actually be a method of `obj`
17116    ///     * must refer to a method with 3 arguments
17117    ///
17118    /// # Returns
17119    /// Whatever the method returned or 0 if it threw
17120    ///
17121    /// # Throws Java Exception
17122    /// * Whatever the method threw
17123    ///
17124    ///
17125    /// # Panics
17126    /// if asserts feature is enabled and UB was detected
17127    ///
17128    /// # Safety
17129    ///
17130    /// Current thread must not be detached from JNI.
17131    ///
17132    /// Current thread must not be currently throwing an exception.
17133    ///
17134    /// Current thread does not hold a critical reference.
17135    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17136    ///
17137    /// `obj` must a valid and not already garbage collected.
17138    /// `methodID` must be valid, static and actually be a method of `obj`, return int and have 3 arguments
17139    ///
17140    pub unsafe fn CallStaticIntMethod3<A: JType, B: JType, C: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jint {
17141        unsafe {
17142            #[cfg(feature = "asserts")]
17143            {
17144                self.check_not_critical("CallStaticIntMethod");
17145                self.check_no_exception("CallStaticIntMethod");
17146                self.check_return_type_static("CallStaticIntMethod", obj, methodID, "int");
17147                self.check_parameter_types_static("CallStaticIntMethod", obj, methodID, arg1, 0, 3);
17148                self.check_parameter_types_static("CallStaticIntMethod", obj, methodID, arg2, 1, 3);
17149                self.check_parameter_types_static("CallStaticIntMethod", obj, methodID, arg3, 2, 3);
17150            }
17151            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jint>(129)(self.vtable, obj, methodID, arg1, arg2, arg3)
17152        }
17153    }
17154
17155    ///
17156    /// Calls a static java method that returns a long
17157    ///
17158    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17159    ///
17160    ///
17161    /// # Arguments
17162    /// * `obj` - which object the method should be called on
17163    ///     * must be valid
17164    ///     * must not be null
17165    ///     * must not be already garbage collected
17166    ///
17167    /// * `methodID` - method id of the method
17168    ///     * must not be null
17169    ///     * must be valid
17170    ///     * must not be a static
17171    ///     * must actually be a method of `obj`
17172    ///
17173    /// * `args` - argument pointer
17174    ///     * can be null if the method has no arguments
17175    ///     * must not be null otherwise and point to the exact number of arguments the method expects
17176    ///
17177    /// # Returns
17178    /// Whatever the method returned or 0 if it threw
17179    ///
17180    /// # Throws Java Exception
17181    /// * Whatever the method threw
17182    ///
17183    ///
17184    /// # Panics
17185    /// if asserts feature is enabled and UB was detected
17186    ///
17187    /// # Safety
17188    ///
17189    /// Current thread must not be detached from JNI.
17190    ///
17191    /// Current thread must not be currently throwing an exception.
17192    ///
17193    /// Current thread does not hold a critical reference.
17194    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17195    ///
17196    /// `obj` must a valid and not already garbage collected.
17197    /// `methodID` must be valid, static and actually be a method of `obj` class and return a long
17198    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
17199    /// `args` union must contain types that match the java methods parameters.
17200    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
17201    ///
17202    pub unsafe fn CallStaticLongMethodA(&self, obj: jclass, methodID: jmethodID, args: *const jtype) -> jlong {
17203        unsafe {
17204            #[cfg(feature = "asserts")]
17205            {
17206                self.check_not_critical("CallStaticLongMethodA");
17207                self.check_no_exception("CallStaticLongMethodA");
17208                self.check_return_type_static("CallStaticLongMethodA", obj, methodID, "long");
17209            }
17210            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jlong>(134)(self.vtable, obj, methodID, args)
17211        }
17212    }
17213
17214    ///
17215    /// Calls a static java method that has 0 arguments and returns long
17216    ///
17217    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17218    ///
17219    ///
17220    /// # Arguments
17221    /// * `obj` - which object the method should be called on
17222    ///     * must be valid
17223    ///     * must not be null
17224    ///     * must not be already garbage collected
17225    ///
17226    /// * `methodID` - method id of the method
17227    ///     * must not be null
17228    ///     * must be valid
17229    ///     * must be a static
17230    ///     * must actually be a method of `obj`
17231    ///     * must refer to a method with 0 arguments
17232    ///
17233    /// # Returns
17234    /// Whatever the method returned or 0 if it threw
17235    ///
17236    /// # Throws Java Exception
17237    /// * Whatever the method threw
17238    ///
17239    ///
17240    /// # Panics
17241    /// if asserts feature is enabled and UB was detected
17242    ///
17243    /// # Safety
17244    ///
17245    /// Current thread must not be detached from JNI.
17246    ///
17247    /// Current thread must not be currently throwing an exception.
17248    ///
17249    /// Current thread does not hold a critical reference.
17250    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17251    ///
17252    /// `obj` must a valid and not already garbage collected.
17253    /// `methodID` must be valid, static and actually be a method of `obj`, return long and have 0 arguments
17254    ///
17255    pub unsafe fn CallStaticLongMethod0(&self, obj: jclass, methodID: jmethodID) -> jlong {
17256        unsafe {
17257            #[cfg(feature = "asserts")]
17258            {
17259                self.check_not_critical("CallStaticLongMethod");
17260                self.check_no_exception("CallStaticLongMethod");
17261                self.check_return_type_static("CallStaticLongMethod", obj, methodID, "long");
17262            }
17263            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jlong>(132)(self.vtable, obj, methodID)
17264        }
17265    }
17266
17267    ///
17268    /// Calls a static java method that has 1 arguments and returns long
17269    ///
17270    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17271    ///
17272    ///
17273    /// # Arguments
17274    /// * `obj` - which object the method should be called on
17275    ///     * must be valid
17276    ///     * must not be null
17277    ///     * must not be already garbage collected
17278    ///
17279    /// * `methodID` - method id of the method
17280    ///     * must not be null
17281    ///     * must be valid
17282    ///     * must be a static
17283    ///     * must actually be a method of `obj`
17284    ///     * must refer to a method with 1 arguments
17285    ///
17286    /// # Returns
17287    /// Whatever the method returned or 0 if it threw
17288    ///
17289    /// # Throws Java Exception
17290    /// * Whatever the method threw
17291    ///
17292    ///
17293    /// # Panics
17294    /// if asserts feature is enabled and UB was detected
17295    ///
17296    /// # Safety
17297    ///
17298    /// Current thread must not be detached from JNI.
17299    ///
17300    /// Current thread must not be currently throwing an exception.
17301    ///
17302    /// Current thread does not hold a critical reference.
17303    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17304    ///
17305    /// `obj` must a valid and not already garbage collected.
17306    /// `methodID` must be valid, static and actually be a method of `obj`, return long and have 1 arguments
17307    ///
17308    pub unsafe fn CallStaticLongMethod1<A: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A) -> jlong {
17309        unsafe {
17310            #[cfg(feature = "asserts")]
17311            {
17312                self.check_not_critical("CallStaticLongMethod");
17313                self.check_no_exception("CallStaticLongMethod");
17314                self.check_return_type_static("CallStaticLongMethod", obj, methodID, "long");
17315                self.check_parameter_types_static("CallStaticLongMethod", obj, methodID, arg1, 0, 1);
17316            }
17317            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jlong>(132)(self.vtable, obj, methodID, arg1)
17318        }
17319    }
17320
17321    ///
17322    /// Calls a static java method that has 2 arguments and returns long
17323    ///
17324    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17325    ///
17326    ///
17327    /// # Arguments
17328    /// * `obj` - which object the method should be called on
17329    ///     * must be valid
17330    ///     * must not be null
17331    ///     * must not be already garbage collected
17332    ///
17333    /// * `methodID` - method id of the method
17334    ///     * must not be null
17335    ///     * must be valid
17336    ///     * must be a static
17337    ///     * must actually be a method of `obj`
17338    ///     * must refer to a method with 2 arguments
17339    ///
17340    /// # Returns
17341    /// Whatever the method returned or 0 if it threw
17342    ///
17343    /// # Throws Java Exception
17344    /// * Whatever the method threw
17345    ///
17346    ///
17347    /// # Panics
17348    /// if asserts feature is enabled and UB was detected
17349    ///
17350    /// # Safety
17351    ///
17352    /// Current thread must not be detached from JNI.
17353    ///
17354    /// Current thread must not be currently throwing an exception.
17355    ///
17356    /// Current thread does not hold a critical reference.
17357    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17358    ///
17359    /// `obj` must a valid and not already garbage collected.
17360    /// `methodID` must be valid, static and actually be a method of `obj`, return long and have 2 arguments
17361    ///
17362    pub unsafe fn CallStaticLongMethod2<A: JType, B: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jlong {
17363        unsafe {
17364            #[cfg(feature = "asserts")]
17365            {
17366                self.check_not_critical("CallStaticLongMethod");
17367                self.check_no_exception("CallStaticLongMethod");
17368                self.check_return_type_static("CallStaticLongMethod", obj, methodID, "long");
17369                self.check_parameter_types_static("CallStaticLongMethod", obj, methodID, arg1, 0, 2);
17370                self.check_parameter_types_static("CallStaticLongMethod", obj, methodID, arg2, 1, 2);
17371            }
17372            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jlong>(132)(self.vtable, obj, methodID, arg1, arg2)
17373        }
17374    }
17375
17376    ///
17377    /// Calls a static java method that has 3 arguments and returns long
17378    ///
17379    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17380    ///
17381    ///
17382    /// # Arguments
17383    /// * `obj` - which object the method should be called on
17384    ///     * must be valid
17385    ///     * must not be null
17386    ///     * must not be already garbage collected
17387    ///
17388    /// * `methodID` - method id of the method
17389    ///     * must not be null
17390    ///     * must be valid
17391    ///     * must be a static
17392    ///     * must actually be a method of `obj`
17393    ///     * must refer to a method with 3 arguments
17394    ///
17395    /// # Returns
17396    /// Whatever the method returned or 0 if it threw
17397    ///
17398    /// # Throws Java Exception
17399    /// * Whatever the method threw
17400    ///
17401    ///
17402    /// # Panics
17403    /// if asserts feature is enabled and UB was detected
17404    ///
17405    /// # Safety
17406    ///
17407    /// Current thread must not be detached from JNI.
17408    ///
17409    /// Current thread must not be currently throwing an exception.
17410    ///
17411    /// Current thread does not hold a critical reference.
17412    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17413    ///
17414    /// `obj` must a valid and not already garbage collected.
17415    /// `methodID` must be valid, static and actually be a method of `obj`, return long and have 3 arguments
17416    ///
17417    pub unsafe fn CallStaticLongMethod3<A: JType, B: JType, C: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jlong {
17418        unsafe {
17419            #[cfg(feature = "asserts")]
17420            {
17421                self.check_not_critical("CallStaticLongMethod");
17422                self.check_no_exception("CallStaticLongMethod");
17423                self.check_return_type_static("CallStaticLongMethod", obj, methodID, "long");
17424                self.check_parameter_types_static("CallStaticLongMethod", obj, methodID, arg1, 0, 3);
17425                self.check_parameter_types_static("CallStaticLongMethod", obj, methodID, arg2, 1, 3);
17426                self.check_parameter_types_static("CallStaticLongMethod", obj, methodID, arg3, 2, 3);
17427            }
17428            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jlong>(132)(self.vtable, obj, methodID, arg1, arg2, arg3)
17429        }
17430    }
17431
17432    ///
17433    /// Calls a static java method that returns a float
17434    ///
17435    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17436    ///
17437    ///
17438    /// # Arguments
17439    /// * `obj` - which object the method should be called on
17440    ///     * must be valid
17441    ///     * must not be null
17442    ///     * must not be already garbage collected
17443    ///
17444    /// * `methodID` - method id of the method
17445    ///     * must not be null
17446    ///     * must be valid
17447    ///     * must not be a static
17448    ///     * must actually be a method of `obj`
17449    ///
17450    /// * `args` - argument pointer
17451    ///     * can be null if the method has no arguments
17452    ///     * must not be null otherwise and point to the exact number of arguments the method expects
17453    ///
17454    /// # Returns
17455    /// Whatever the method returned or 0 if it threw
17456    ///
17457    /// # Throws Java Exception
17458    /// * Whatever the method threw
17459    ///
17460    ///
17461    /// # Panics
17462    /// if asserts feature is enabled and UB was detected
17463    ///
17464    /// # Safety
17465    ///
17466    /// Current thread must not be detached from JNI.
17467    ///
17468    /// Current thread must not be currently throwing an exception.
17469    ///
17470    /// Current thread does not hold a critical reference.
17471    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17472    ///
17473    /// `obj` must a valid and not already garbage collected.
17474    /// `methodID` must be valid, static and actually be a method of `obj` class and return a float
17475    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
17476    /// `args` union must contain types that match the java methods parameters.
17477    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
17478    ///
17479    pub unsafe fn CallStaticFloatMethodA(&self, obj: jclass, methodID: jmethodID, args: *const jtype) -> jfloat {
17480        unsafe {
17481            #[cfg(feature = "asserts")]
17482            {
17483                self.check_not_critical("CallStaticFloatMethodA");
17484                self.check_no_exception("CallStaticFloatMethodA");
17485                self.check_return_type_static("CallStaticFloatMethodA", obj, methodID, "float");
17486            }
17487            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jfloat>(137)(self.vtable, obj, methodID, args)
17488        }
17489    }
17490
17491    ///
17492    /// Calls a static java method that has 0 arguments and returns double
17493    ///
17494    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17495    ///
17496    ///
17497    /// # Arguments
17498    /// * `obj` - which object the method should be called on
17499    ///     * must be valid
17500    ///     * must not be null
17501    ///     * must not be already garbage collected
17502    ///
17503    /// * `methodID` - method id of the method
17504    ///     * must not be null
17505    ///     * must be valid
17506    ///     * must be a static
17507    ///     * must actually be a method of `obj`
17508    ///     * must refer to a method with 0 arguments
17509    ///
17510    /// # Returns
17511    /// Whatever the method returned or 0 if it threw
17512    ///
17513    /// # Throws Java Exception
17514    /// * Whatever the method threw
17515    ///
17516    ///
17517    /// # Panics
17518    /// if asserts feature is enabled and UB was detected
17519    ///
17520    /// # Safety
17521    ///
17522    /// Current thread must not be detached from JNI.
17523    ///
17524    /// Current thread must not be currently throwing an exception.
17525    ///
17526    /// Current thread does not hold a critical reference.
17527    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17528    ///
17529    /// `obj` must a valid and not already garbage collected.
17530    /// `methodID` must be valid, static and actually be a method of `obj`, return float and have 0 arguments
17531    ///
17532    pub unsafe fn CallStaticFloatMethod0(&self, obj: jclass, methodID: jmethodID) -> jfloat {
17533        unsafe {
17534            #[cfg(feature = "asserts")]
17535            {
17536                self.check_not_critical("CallStaticFloatMethod");
17537                self.check_no_exception("CallStaticFloatMethod");
17538                self.check_return_type_static("CallStaticFloatMethod", obj, methodID, "float");
17539            }
17540            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jfloat>(135)(self.vtable, obj, methodID)
17541        }
17542    }
17543
17544    ///
17545    /// Calls a static java method that has 1 arguments and returns double
17546    ///
17547    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17548    ///
17549    ///
17550    /// # Arguments
17551    /// * `obj` - which object the method should be called on
17552    ///     * must be valid
17553    ///     * must not be null
17554    ///     * must not be already garbage collected
17555    ///
17556    /// * `methodID` - method id of the method
17557    ///     * must not be null
17558    ///     * must be valid
17559    ///     * must be a static
17560    ///     * must actually be a method of `obj`
17561    ///     * must refer to a method with 1 arguments
17562    ///
17563    /// # Returns
17564    /// Whatever the method returned or 0 if it threw
17565    ///
17566    /// # Throws Java Exception
17567    /// * Whatever the method threw
17568    ///
17569    ///
17570    /// # Panics
17571    /// if asserts feature is enabled and UB was detected
17572    ///
17573    /// # Safety
17574    ///
17575    /// Current thread must not be detached from JNI.
17576    ///
17577    /// Current thread must not be currently throwing an exception.
17578    ///
17579    /// Current thread does not hold a critical reference.
17580    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17581    ///
17582    /// `obj` must a valid and not already garbage collected.
17583    /// `methodID` must be valid, static and actually be a method of `obj`, return float and have 1 arguments
17584    ///
17585    pub unsafe fn CallStaticFloatMethod1<A: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A) -> jfloat {
17586        unsafe {
17587            #[cfg(feature = "asserts")]
17588            {
17589                self.check_not_critical("CallStaticFloatMethod");
17590                self.check_no_exception("CallStaticFloatMethod");
17591                self.check_return_type_static("CallStaticFloatMethod", obj, methodID, "float");
17592                self.check_parameter_types_static("CallStaticFloatMethod", obj, methodID, arg1, 0, 1);
17593            }
17594            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jfloat>(135)(self.vtable, obj, methodID, arg1)
17595        }
17596    }
17597
17598    ///
17599    /// Calls a static java method that has 2 arguments and returns double
17600    ///
17601    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17602    ///
17603    ///
17604    /// # Arguments
17605    /// * `obj` - which object the method should be called on
17606    ///     * must be valid
17607    ///     * must not be null
17608    ///     * must not be already garbage collected
17609    ///
17610    /// * `methodID` - method id of the method
17611    ///     * must not be null
17612    ///     * must be valid
17613    ///     * must be a static
17614    ///     * must actually be a method of `obj`
17615    ///     * must refer to a method with 2 arguments
17616    ///
17617    /// # Returns
17618    /// Whatever the method returned or 0 if it threw
17619    ///
17620    /// # Throws Java Exception
17621    /// * Whatever the method threw
17622    ///
17623    ///
17624    /// # Panics
17625    /// if asserts feature is enabled and UB was detected
17626    ///
17627    /// # Safety
17628    ///
17629    /// Current thread must not be detached from JNI.
17630    ///
17631    /// Current thread must not be currently throwing an exception.
17632    ///
17633    /// Current thread does not hold a critical reference.
17634    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17635    ///
17636    /// `obj` must a valid and not already garbage collected.
17637    /// `methodID` must be valid, static and actually be a method of `obj`, return float and have 2 arguments
17638    ///
17639    pub unsafe fn CallStaticFloatMethod2<A: JType, B: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jfloat {
17640        unsafe {
17641            #[cfg(feature = "asserts")]
17642            {
17643                self.check_not_critical("CallStaticFloatMethod");
17644                self.check_no_exception("CallStaticFloatMethod");
17645                self.check_return_type_static("CallStaticFloatMethod", obj, methodID, "float");
17646                self.check_parameter_types_static("CallStaticFloatMethod", obj, methodID, arg1, 0, 2);
17647                self.check_parameter_types_static("CallStaticFloatMethod", obj, methodID, arg2, 1, 2);
17648            }
17649            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jfloat>(135)(self.vtable, obj, methodID, arg1, arg2)
17650        }
17651    }
17652
17653    ///
17654    /// Calls a static java method that has 3 arguments and returns double
17655    ///
17656    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17657    ///
17658    ///
17659    /// # Arguments
17660    /// * `obj` - which object the method should be called on
17661    ///     * must be valid
17662    ///     * must not be null
17663    ///     * must not be already garbage collected
17664    ///
17665    /// * `methodID` - method id of the method
17666    ///     * must not be null
17667    ///     * must be valid
17668    ///     * must be a static
17669    ///     * must actually be a method of `obj`
17670    ///     * must refer to a method with 3 arguments
17671    ///
17672    /// # Returns
17673    /// Whatever the method returned or 0 if it threw
17674    ///
17675    /// # Throws Java Exception
17676    /// * Whatever the method threw
17677    ///
17678    ///
17679    /// # Panics
17680    /// if asserts feature is enabled and UB was detected
17681    ///
17682    /// # Safety
17683    ///
17684    /// Current thread must not be detached from JNI.
17685    ///
17686    /// Current thread must not be currently throwing an exception.
17687    ///
17688    /// Current thread does not hold a critical reference.
17689    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17690    ///
17691    /// `obj` must a valid and not already garbage collected.
17692    /// `methodID` must be valid, static and actually be a method of `obj`, return float and have 3 arguments
17693    ///
17694    pub unsafe fn CallStaticFloatMethod3<A: JType, B: JType, C: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jfloat {
17695        unsafe {
17696            #[cfg(feature = "asserts")]
17697            {
17698                self.check_not_critical("CallStaticFloatMethod");
17699                self.check_no_exception("CallStaticFloatMethod");
17700                self.check_return_type_static("CallStaticFloatMethod", obj, methodID, "float");
17701                self.check_parameter_types_static("CallStaticFloatMethod", obj, methodID, arg1, 0, 3);
17702                self.check_parameter_types_static("CallStaticFloatMethod", obj, methodID, arg2, 1, 3);
17703                self.check_parameter_types_static("CallStaticFloatMethod", obj, methodID, arg3, 2, 3);
17704            }
17705            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jfloat>(135)(self.vtable, obj, methodID, arg1, arg2, arg3)
17706        }
17707    }
17708
17709    ///
17710    /// Calls a static java method that returns a double
17711    ///
17712    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17713    ///
17714    ///
17715    /// # Arguments
17716    /// * `obj` - which object the method should be called on
17717    ///     * must be valid
17718    ///     * must not be null
17719    ///     * must not be already garbage collected
17720    ///
17721    /// * `methodID` - method id of the method
17722    ///     * must not be null
17723    ///     * must be valid
17724    ///     * must not be a static
17725    ///     * must actually be a method of `obj`
17726    ///
17727    /// * `args` - argument pointer
17728    ///     * can be null if the method has no arguments
17729    ///     * must not be null otherwise and point to the exact number of arguments the method expects
17730    ///
17731    /// # Returns
17732    /// Whatever the method returned or 0 if it threw
17733    ///
17734    /// # Throws Java Exception
17735    /// * Whatever the method threw
17736    ///
17737    ///
17738    /// # Panics
17739    /// if asserts feature is enabled and UB was detected
17740    ///
17741    /// # Safety
17742    ///
17743    /// Current thread must not be detached from JNI.
17744    ///
17745    /// Current thread must not be currently throwing an exception.
17746    ///
17747    /// Current thread does not hold a critical reference.
17748    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17749    ///
17750    /// `obj` must a valid and not already garbage collected.
17751    /// `methodID` must be valid, static and actually be a method of `obj` class and return a double
17752    /// `args` must have sufficient length to contain the amount of parameter required by the java method.
17753    /// `args` union must contain types that match the java methods parameters.
17754    /// (i.e. do not use a float instead of an object as parameter, beware of java boxed types)
17755    ///
17756    pub unsafe fn CallStaticDoubleMethodA(&self, obj: jclass, methodID: jmethodID, args: *const jtype) -> jdouble {
17757        unsafe {
17758            #[cfg(feature = "asserts")]
17759            {
17760                self.check_not_critical("CallStaticDoubleMethodA");
17761                self.check_no_exception("CallStaticDoubleMethodA");
17762                self.check_return_type_static("CallStaticDoubleMethodA", obj, methodID, "double");
17763            }
17764            self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jdouble>(140)(self.vtable, obj, methodID, args)
17765        }
17766    }
17767
17768    ///
17769    /// Calls a static java method that has 0 arguments and returns double
17770    ///
17771    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17772    ///
17773    ///
17774    /// # Arguments
17775    /// * `obj` - which object the method should be called on
17776    ///     * must be valid
17777    ///     * must not be null
17778    ///     * must not be already garbage collected
17779    ///
17780    /// * `methodID` - method id of the method
17781    ///     * must not be null
17782    ///     * must be valid
17783    ///     * must be a static
17784    ///     * must actually be a method of `obj`
17785    ///     * must refer to a method with 0 arguments
17786    ///
17787    /// # Returns
17788    /// Whatever the method returned or 0 if it threw
17789    ///
17790    /// # Throws Java Exception
17791    /// * Whatever the method threw
17792    ///
17793    ///
17794    /// # Panics
17795    /// if asserts feature is enabled and UB was detected
17796    ///
17797    /// # Safety
17798    ///
17799    /// Current thread must not be detached from JNI.
17800    ///
17801    /// Current thread must not be currently throwing an exception.
17802    ///
17803    /// Current thread does not hold a critical reference.
17804    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17805    ///
17806    /// `obj` must a valid and not already garbage collected.
17807    /// `methodID` must be valid, static and actually be a method of `obj`, return double and have 0 arguments
17808    ///
17809    pub unsafe fn CallStaticDoubleMethod0(&self, obj: jclass, methodID: jmethodID) -> jdouble {
17810        unsafe {
17811            #[cfg(feature = "asserts")]
17812            {
17813                self.check_not_critical("CallStaticDoubleMethod");
17814                self.check_no_exception("CallStaticDoubleMethod");
17815                self.check_return_type_static("CallStaticDoubleMethod", obj, methodID, "double");
17816            }
17817            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID) -> jdouble>(138)(self.vtable, obj, methodID)
17818        }
17819    }
17820
17821    ///
17822    /// Calls a static java method that has 1 arguments and returns double
17823    ///
17824    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17825    ///
17826    ///
17827    /// # Arguments
17828    /// * `obj` - which object the method should be called on
17829    ///     * must be valid
17830    ///     * must not be null
17831    ///     * must not be already garbage collected
17832    ///
17833    /// * `methodID` - method id of the method
17834    ///     * must not be null
17835    ///     * must be valid
17836    ///     * must be a static
17837    ///     * must actually be a method of `obj`
17838    ///     * must refer to a method with 1 arguments
17839    ///
17840    /// # Returns
17841    /// Whatever the method returned or 0 if it threw
17842    ///
17843    /// # Throws Java Exception
17844    /// * Whatever the method threw
17845    ///
17846    ///
17847    /// # Panics
17848    /// if asserts feature is enabled and UB was detected
17849    ///
17850    /// # Safety
17851    ///
17852    /// Current thread must not be detached from JNI.
17853    ///
17854    /// Current thread must not be currently throwing an exception.
17855    ///
17856    /// Current thread does not hold a critical reference.
17857    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17858    ///
17859    /// `obj` must a valid and not already garbage collected.
17860    /// `methodID` must be valid, static and actually be a method of `obj`, return double and have 1 arguments
17861    ///
17862    pub unsafe fn CallStaticDoubleMethod1<A: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A) -> jdouble {
17863        unsafe {
17864            #[cfg(feature = "asserts")]
17865            {
17866                self.check_not_critical("CallStaticDoubleMethod");
17867                self.check_no_exception("CallStaticDoubleMethod");
17868                self.check_return_type_static("CallStaticDoubleMethod", obj, methodID, "double");
17869                self.check_parameter_types_static("CallStaticDoubleMethod", obj, methodID, arg1, 0, 1);
17870            }
17871            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jdouble>(138)(self.vtable, obj, methodID, arg1)
17872        }
17873    }
17874
17875    ///
17876    /// Calls a static java method that has 2 arguments and returns double
17877    ///
17878    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17879    ///
17880    ///
17881    /// # Arguments
17882    /// * `obj` - which object the method should be called on
17883    ///     * must be valid
17884    ///     * must not be null
17885    ///     * must not be already garbage collected
17886    ///
17887    /// * `methodID` - method id of the method
17888    ///     * must not be null
17889    ///     * must be valid
17890    ///     * must be a static
17891    ///     * must actually be a method of `obj`
17892    ///     * must refer to a method with 2 arguments
17893    ///
17894    /// # Returns
17895    /// Whatever the method returned or 0 if it threw
17896    ///
17897    /// # Throws Java Exception
17898    /// * Whatever the method threw
17899    ///
17900    ///
17901    /// # Panics
17902    /// if asserts feature is enabled and UB was detected
17903    ///
17904    /// # Safety
17905    ///
17906    /// Current thread must not be detached from JNI.
17907    ///
17908    /// Current thread must not be currently throwing an exception.
17909    ///
17910    /// Current thread does not hold a critical reference.
17911    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17912    ///
17913    /// `obj` must a valid and not already garbage collected.
17914    /// `methodID` must be valid, static and actually be a method of `obj`, return double and have 2 arguments
17915    ///
17916    pub unsafe fn CallStaticDoubleMethod2<A: JType, B: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B) -> jdouble {
17917        unsafe {
17918            #[cfg(feature = "asserts")]
17919            {
17920                self.check_not_critical("CallStaticDoubleMethod");
17921                self.check_no_exception("CallStaticDoubleMethod");
17922                self.check_return_type_static("CallStaticDoubleMethod", obj, methodID, "double");
17923                self.check_parameter_types_static("CallStaticDoubleMethod", obj, methodID, arg1, 0, 2);
17924                self.check_parameter_types_static("CallStaticDoubleMethod", obj, methodID, arg2, 1, 2);
17925            }
17926            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jdouble>(138)(self.vtable, obj, methodID, arg1, arg2)
17927        }
17928    }
17929
17930    ///
17931    /// Calls a static java method that has 3 arguments and returns double
17932    ///
17933    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#CallStatic_type_Method_routines>
17934    ///
17935    ///
17936    /// # Arguments
17937    /// * `obj` - which object the method should be called on
17938    ///     * must be valid
17939    ///     * must not be null
17940    ///     * must not be already garbage collected
17941    ///
17942    /// * `methodID` - method id of the method
17943    ///     * must not be null
17944    ///     * must be valid
17945    ///     * must be a static
17946    ///     * must actually be a method of `obj`
17947    ///     * must refer to a method with 3 arguments
17948    ///
17949    /// # Returns
17950    /// Whatever the method returned or 0 if it threw
17951    ///
17952    /// # Throws Java Exception
17953    /// * Whatever the method threw
17954    ///
17955    ///
17956    /// # Panics
17957    /// if asserts feature is enabled and UB was detected
17958    ///
17959    /// # Safety
17960    ///
17961    /// Current thread must not be detached from JNI.
17962    ///
17963    /// Current thread must not be currently throwing an exception.
17964    ///
17965    /// Current thread does not hold a critical reference.
17966    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
17967    ///
17968    /// `obj` must a valid and not already garbage collected.
17969    /// `methodID` must be valid, static and actually be a method of `obj`, return double and have 3 arguments
17970    ///
17971    pub unsafe fn CallStaticDoubleMethod3<A: JType, B: JType, C: JType>(&self, obj: jclass, methodID: jmethodID, arg1: A, arg2: B, arg3: C) -> jdouble {
17972        unsafe {
17973            #[cfg(feature = "asserts")]
17974            {
17975                self.check_not_critical("CallStaticDoubleMethod");
17976                self.check_no_exception("CallStaticDoubleMethod");
17977                self.check_return_type_static("CallStaticDoubleMethod", obj, methodID, "double");
17978                self.check_parameter_types_static("CallStaticDoubleMethod", obj, methodID, arg1, 0, 3);
17979                self.check_parameter_types_static("CallStaticDoubleMethod", obj, methodID, arg2, 1, 3);
17980                self.check_parameter_types_static("CallStaticDoubleMethod", obj, methodID, arg3, 2, 3);
17981            }
17982            self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID, ...) -> jdouble>(138)(self.vtable, obj, methodID, arg1, arg2, arg3)
17983        }
17984    }
17985
17986    ///
17987    /// Create a new String form a jchar array.
17988    ///
17989    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewString>
17990    ///
17991    ///
17992    /// # Arguments
17993    /// * `unicodeChars` - pointer to the jchar array
17994    ///     * must not be null
17995    /// * `len` - amount of elements in the jchar array
17996    ///
17997    /// # Returns
17998    /// A local reference to the newly created String or null on error
17999    ///
18000    /// # Throws Java Exception
18001    /// * `OutOfMemoryError` - if the jvm ran out of memory allocating the String
18002    ///
18003    ///
18004    /// # Panics
18005    /// if asserts feature is enabled and UB was detected
18006    ///
18007    /// # Safety
18008    ///
18009    /// Current thread must not be detached from JNI.
18010    ///
18011    /// Current thread must not be currently throwing an exception.
18012    ///
18013    /// Current thread does not hold a critical reference.
18014    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18015    ///
18016    /// `unicodeChars` must not be 0.
18017    /// `unicodeChars` must be equal or larger than `len` suggests.
18018    ///
18019    #[must_use]
18020    pub unsafe fn NewString(&self, unicodeChars: *const jchar, len: jsize) -> jstring {
18021        unsafe {
18022            #[cfg(feature = "asserts")]
18023            {
18024                self.check_not_critical("NewString");
18025                self.check_no_exception("NewString");
18026                assert!(!unicodeChars.is_null(), "NewString string must not be null");
18027                assert!(len >= 0, "NewString len must not be negative");
18028            }
18029            self.jni::<extern "system" fn(JNIEnvVTable, *const jchar, jsize) -> jstring>(163)(self.vtable, unicodeChars, len)
18030        }
18031    }
18032
18033    /// Convenience function to create a `jstring` from any rust string.
18034    ///
18035    /// This function will, after performing some transformations, call `NewString`.
18036    /// This function is quite slow compared to all other alternatives but unlike for example `NewStringUTF`,
18037    /// it works with strings that contain 0 characters or supplementary characters.
18038    ///
18039    /// This function will always be slower than `NewStringUTF`.
18040    ///
18041    /// # Returns
18042    /// return value of `NewString`
18043    ///
18044    /// # Safety
18045    /// Same as the `NewString` fn
18046    ///
18047    /// # Panics
18048    /// If the string is too long to be represented in Java:
18049    /// * This always the case if the `string.chars().count()` is more than `i32::MAX`.
18050    /// * This might be the case if `string.chars().count()` is between `i32::MAX` and `i32::MAX / 2`
18051    ///   if the string contains enough characters that would require 32 bit encoding in utf-16.
18052    /// * This is never the case if `string.chars().count()` is less than `i32::MAX / 2`.
18053    ///
18054    /// Sidenote: This function does not call `string.chars().count()`.
18055    ///
18056    /// # Example
18057    /// ```rust
18058    /// use jni_simple::{jstring, JNIEnv};
18059    ///
18060    /// fn example(env: JNIEnv) {
18061    ///     unsafe {
18062    ///         let my_string = "𝕊"; //U+1D54A MATHEMATICAL DOUBLE-STRUCK CAPITAL S
18063    ///         let java_string: jstring = env.NewString_from_str(my_string);
18064    ///         let and_back_again: String = env.GetStringChars_as_string(java_string).unwrap();
18065    ///         assert_eq!(my_string, and_back_again.as_str());
18066    ///     }
18067    /// }
18068    /// ```
18069    ///
18070    pub unsafe fn NewString_from_str(&self, string: impl AsRef<str>) -> jstring {
18071        let mut utf16 = Vec::new();
18072        let str = string.as_ref();
18073
18074        //This over allocates up to 4 times capacity depending on how many 2,3,4 byte utf-8 charactes the string contains.
18075        //We cap the allocation at 64k (128k bytes) just in case.
18076        utf16.reserve(str.len().min(0x1_00_00));
18077
18078        for utf in string.as_ref().encode_utf16() {
18079            utf16.push(utf);
18080        }
18081
18082        let len = utf16.len();
18083        let Ok(len) = jsize::try_from(len) else {
18084            panic!(
18085                "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.",
18086                jsize::MAX
18087            );
18088        };
18089
18090        unsafe { self.NewString(utf16.as_ptr(), len) }
18091    }
18092
18093    ///
18094    /// Returns the string length in jchar's. This is neither the amount of bytes in utf-8 encoding nor the amount of characters.
18095    /// 3 and 4 byte utf-8 characters take 2 jchars to encode. This is equivalent to calling `String.length()` in java.
18096    ///
18097    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStringLength>
18098    ///
18099    /// # Arguments
18100    /// * `string`
18101    ///     * must not be null
18102    ///     * must refer to a string
18103    ///     * must not be already garbage collected
18104    ///
18105    /// # Returns
18106    /// the amount of jchar's in the String
18107    ///
18108    ///
18109    /// # Panics
18110    /// if asserts feature is enabled and UB was detected
18111    ///
18112    /// # Safety
18113    ///
18114    /// Current thread must not be detached from JNI.
18115    ///
18116    /// Current thread must not be currently throwing an exception.
18117    ///
18118    /// Current thread does not hold a critical reference.
18119    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18120    ///
18121    /// `string` must be a valid reference that is not yet garbage collected and refer to a String.
18122    ///
18123    pub unsafe fn GetStringLength(&self, string: jstring) -> jsize {
18124        unsafe {
18125            #[cfg(feature = "asserts")]
18126            {
18127                self.check_not_critical("GetStringLength");
18128                self.check_no_exception("GetStringLength");
18129                assert!(!string.is_null(), "GetStringLength string must not be null");
18130                self.check_if_arg_is_string("GetStringLength", string);
18131            }
18132            self.jni::<extern "system" fn(JNIEnvVTable, jstring) -> jsize>(164)(self.vtable, string)
18133        }
18134    }
18135
18136    ///
18137    /// Returns the string's jchar arrays representation.
18138    ///
18139    /// Note: This fn will almost always to return a copy of the data for newer JVM's.
18140    ///
18141    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStringChars>
18142    ///
18143    /// # Arguments
18144    /// * `string`
18145    ///     * must not be null
18146    ///     * must refer to a string
18147    ///     * must not be already garbage collected
18148    /// * `isCopy` - optional pointer to a boolean flag for the vm to indicate if it copied the data or not.
18149    ///     * may be null
18150    ///
18151    /// # Returns
18152    /// a pointer to index 0 of a jchar array.
18153    ///
18154    ///
18155    /// # Panics
18156    /// if asserts feature is enabled and UB was detected
18157    ///
18158    /// # Safety
18159    ///
18160    /// Current thread must not be detached from JNI.
18161    ///
18162    /// Current thread must not be currently throwing an exception.
18163    ///
18164    /// Current thread does not hold a critical reference.
18165    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18166    ///
18167    /// `string` must be a valid reference that is not yet garbage collected and refer to a String.
18168    /// `isCopy` must be null or valid.
18169    ///
18170    pub unsafe fn GetStringChars(&self, string: jstring, isCopy: *mut jboolean) -> *const jchar {
18171        unsafe {
18172            #[cfg(feature = "asserts")]
18173            {
18174                self.check_not_critical("GetStringChars");
18175                self.check_no_exception("GetStringChars");
18176                assert!(!string.is_null(), "GetStringChars string must not be null");
18177                self.check_if_arg_is_string("GetStringChars", string);
18178            }
18179            self.jni::<extern "system" fn(JNIEnvVTable, jstring, *mut jboolean) -> *const jchar>(165)(self.vtable, string, isCopy)
18180        }
18181    }
18182
18183    /// Convenience method that calls `GetStringChars` & `GetStringLength`, copies the result
18184    /// into a rust String and then calls `ReleaseStringChars`.
18185    ///
18186    /// This function calls `ReleaseStringChars` in all error cases where it has to be called!
18187    ///
18188    /// # Returns
18189    /// On failure this method return None.
18190    /// There are 3 different causes for returning None:
18191    /// 1. `GetStringLength` returns a negative number.
18192    ///     * This is unlikely unless something has gone horribly wrong.
18193    /// 2. `GetStringChars` fails, in this case more information should be gathered from `ExceptionCheck`.
18194    /// 3. The characters returned by the JVM are not valid utf-16. In this case `ExceptionCheck` should yield None.
18195    ///
18196    /// # Panics
18197    /// if asserts feature is enabled and UB was detected
18198    ///
18199    /// # Safety
18200    /// Current thread must not be detached from JNI.
18201    ///
18202    /// Current thread must not be currently throwing an exception.
18203    ///
18204    /// Current thread does not hold a critical reference.
18205    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18206    ///
18207    /// `string` must not be null, must refer to a string and not already be garbage collected.
18208    ///
18209    pub unsafe fn GetStringChars_as_string(&self, string: jstring) -> Option<String> {
18210        unsafe {
18211            #[cfg(feature = "asserts")]
18212            {
18213                self.check_not_critical("GetStringChars_as_string");
18214                self.check_no_exception("GetStringChars_as_string");
18215                assert!(!string.is_null(), "GetStringChars_as_string string must not be null");
18216                self.check_if_arg_is_string("GetStringChars_as_string", string);
18217            }
18218
18219            let Ok(len) = usize::try_from(self.GetStringLength(string)) else {
18220                //Unlikely
18221                return None;
18222            };
18223
18224            if len == 0 {
18225                //Empty string, we are done.
18226                return Some(String::new());
18227            }
18228
18229            let str = self.GetStringChars(string, null_mut());
18230            if str.is_null() {
18231                return None;
18232            }
18233
18234            let parsed = String::from_utf16(core::slice::from_raw_parts(str, len));
18235            self.ReleaseStringChars(string, str);
18236            parsed.ok()
18237        }
18238    }
18239
18240    ///
18241    /// Frees a char array returned by `GetStringChars`.
18242    ///
18243    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ReleaseStringChars>
18244    ///
18245    /// # Arguments
18246    /// * `string`
18247    ///     * must not be null
18248    ///     * must refer to a string
18249    ///     * must not be already garbage collected
18250    /// * `chars` - the pointer returned by `GetStringChars`
18251    ///     * must not be null
18252    ///
18253    ///
18254    /// # Panics
18255    /// if asserts feature is enabled and UB was detected
18256    ///
18257    /// # Safety
18258    ///
18259    /// Current thread must not be detached from JNI.
18260    ///
18261    /// Current thread does not hold a critical reference.
18262    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18263    ///
18264    /// `string` must be a valid reference that is not yet garbage collected and refer to a String.
18265    /// `chars` must not be null.
18266    /// `chars` must be the result of a call to `GetStringChars` of the String `string`
18267    ///
18268    pub unsafe fn ReleaseStringChars(&self, string: jstring, chars: *const jchar) {
18269        unsafe {
18270            #[cfg(feature = "asserts")]
18271            {
18272                self.check_not_critical("ReleaseStringChars");
18273                assert!(!string.is_null(), "ReleaseStringChars string must not be null");
18274                assert!(!chars.is_null(), "ReleaseStringChars chars must not be null");
18275                self.check_if_arg_is_string("ReleaseStringChars", string);
18276            }
18277            self.jni::<extern "system" fn(JNIEnvVTable, jstring, *const jchar)>(166)(self.vtable, string, chars);
18278        }
18279    }
18280
18281    ///
18282    /// Create a new String form a utf-8 zero terminated c string.
18283    ///
18284    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewString>
18285    ///
18286    /// # IMPORTANT
18287    /// Java uses a modified utf-8 encoding for strings. If your rust string contains any
18288    /// supplementary characters then the resulting java string will not contain the same characters.
18289    /// If this is a concern for you use the much slower method `NewString_from_str` which
18290    /// will properly handle all characters. Using this method despite it containing
18291    /// supplementary does NOT cause UB, it just creates a java string that contains 'random'
18292    /// characters.
18293    ///
18294    /// # Arguments
18295    /// * `bytes` - pointer to the c like zero terminated utf-8 string
18296    ///     * must not be null
18297    ///
18298    /// # Returns
18299    /// A local reference to the newly created String or null on error
18300    ///
18301    /// # Throws Java Exception
18302    /// * `OutOfMemoryError` - if the jvm ran out of memory allocating the String
18303    ///
18304    ///
18305    /// # Panics
18306    /// if asserts feature is enabled and UB was detected
18307    ///
18308    /// # Safety
18309    ///
18310    /// Current thread must not be detached from JNI.
18311    ///
18312    /// Current thread must not be currently throwing an exception.
18313    ///
18314    /// Current thread does not hold a critical reference.
18315    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18316    ///
18317    /// `bytes` must not be null.
18318    /// `bytes` must be zero terminated.
18319    ///
18320    pub unsafe fn NewStringUTF(&self, bytes: impl UseCString) -> jstring {
18321        unsafe {
18322            bytes.use_as_const_c_char(|bytes| {
18323                #[cfg(feature = "asserts")]
18324                {
18325                    self.check_not_critical("NewStringUTF");
18326                    self.check_no_exception("NewStringUTF");
18327                    assert!(!bytes.is_null(), "NewStringUTF string must not be null");
18328                }
18329                self.jni::<extern "system" fn(JNIEnvVTable, *const c_char) -> jstring>(167)(self.vtable, bytes)
18330            })
18331        }
18332    }
18333
18334    ///
18335    /// Returns the length of a String in bytes if it were to be used with `GetStringUTFChars`.
18336    ///
18337    /// Note: For Java 24 or newer this function is deprecated. use `GetStringUTFLengthAsLong` instead.
18338    ///
18339    /// Note: Usage of this function should be carefully evaluated. For most jvms (especially for JVMS older than Java 17)
18340    /// it is faster to just call `GetStringUTFChars` and use a function equivalent to the c function `strlen()` on its return value.
18341    /// Some newer jvm's may, depending on how the vm was started, know this value for most strings,
18342    /// and therefore it is faster to call this fn than to do
18343    /// the approach above if you do not also need the `UTFChars` themselves.
18344    ///
18345    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStringUTFLength>
18346    ///
18347    ///
18348    /// # Arguments
18349    /// * `string`
18350    ///     * must not be null
18351    ///     * must refer to a string
18352    ///     * must not be already garbage collected
18353    ///
18354    /// # Returns
18355    /// The amount of bytes the array returned by `GetStringUTFChars` would have for this string.
18356    ///
18357    ///
18358    /// # Panics
18359    /// if asserts feature is enabled and UB was detected
18360    ///
18361    /// # Safety
18362    ///
18363    /// Current thread must not be detached from JNI.
18364    ///
18365    /// Current thread must not be currently throwing an exception.
18366    ///
18367    /// Current thread does not hold a critical reference.
18368    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18369    ///
18370    /// `string` must not be null, must refer to a string and not already be garbage collected.
18371    ///
18372    pub unsafe fn GetStringUTFLength(&self, string: jstring) -> jsize {
18373        unsafe {
18374            #[cfg(feature = "asserts")]
18375            {
18376                self.check_not_critical("GetStringUTFLength");
18377                self.check_no_exception("GetStringUTFLength");
18378                assert!(!string.is_null(), "GetStringUTFLength string must not be null");
18379                self.check_if_arg_is_string("GetStringUTFLength", string);
18380            }
18381
18382            self.jni::<extern "system" fn(JNIEnvVTable, jstring) -> jsize>(168)(self.vtable, string)
18383        }
18384    }
18385
18386    ///
18387    /// Returns the length of a String in bytes if it were to be used with `GetStringUTFChars`.
18388    /// Beware that this function is only available on Java 24 or newer!
18389    ///
18390    /// <https://docs.oracle.com/en/java/javase/24/docs/specs/jni/functions.html#getstringutflengthaslong>
18391    ///
18392    ///
18393    /// # Arguments
18394    /// * `string`
18395    ///     * must not be null
18396    ///     * must refer to a string
18397    ///     * must not be already garbage collected
18398    ///
18399    /// # Returns
18400    /// The amount of bytes the array returned by `GetStringUTFChars` would have for this string.
18401    ///
18402    /// # Panics
18403    /// if asserts feature is enabled and UB was detected
18404    ///
18405    /// # Safety
18406    ///
18407    /// Current thread must not be detached from JNI.
18408    ///
18409    /// Current thread must not be currently throwing an exception.
18410    ///
18411    /// Current thread does not hold a critical reference.
18412    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18413    ///
18414    /// `string` must not be null, must refer to a string and not already be garbage collected.
18415    ///
18416    /// The JVM must be a Java 24 VM or newer
18417    ///
18418    pub unsafe fn GetStringUTFLengthAsLong(&self, string: jstring) -> jsize {
18419        unsafe {
18420            #[cfg(feature = "asserts")]
18421            {
18422                self.check_not_critical("GetStringUTFLengthAsLong");
18423                self.check_no_exception("GetStringUTFLengthAsLong");
18424                assert!(!string.is_null(), "GetStringUTFLengthAsLong string must not be null");
18425                self.check_if_arg_is_string("GetStringUTFLengthAsLong", string);
18426                assert!(self.GetVersion() >= JNI_VERSION_24);
18427            }
18428
18429            self.jni::<extern "system" fn(JNIEnvVTable, jstring) -> jsize>(235)(self.vtable, string)
18430        }
18431    }
18432
18433    ///
18434    /// Returns the 0 terminated utf-8 representation of the String.
18435    /// The returned string can be used with the "rust" `CStr` struct from the `std::ffi` module.
18436    ///
18437    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStringUTFChars>
18438    ///
18439    ///
18440    /// # Arguments
18441    /// * `string`
18442    ///     * must not be null
18443    ///     * must refer to a string
18444    ///     * must not be already garbage collected
18445    /// * `isCopy` - optional flag for the jvm to indicate if the string is a copy of the data or not.
18446    ///     * can be null
18447    ///
18448    /// # Returns
18449    /// A pointer to the zero terminated utf-8 string or null on error.
18450    ///
18451    /// # Throws Java Exception
18452    /// * `OutOfMemoryError` - if the jvm ran out of memory allocating the utf-8 string
18453    ///
18454    ///
18455    /// # Panics
18456    /// if asserts feature is enabled and UB was detected
18457    ///
18458    /// # Safety
18459    ///
18460    /// Current thread must not be detached from JNI.
18461    ///
18462    /// Current thread must not be currently throwing an exception.
18463    ///
18464    /// Current thread does not hold a critical reference.
18465    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18466    ///
18467    /// `string` must not be null, must refer to a string and not already be garbage collected.
18468    ///
18469    pub unsafe fn GetStringUTFChars(&self, string: jstring, isCopy: *mut jboolean) -> *const c_char {
18470        unsafe {
18471            #[cfg(feature = "asserts")]
18472            {
18473                self.check_not_critical("GetStringUTFChars");
18474                assert!(!string.is_null(), "GetStringUTFChars string must not be null");
18475                self.check_if_arg_is_string("GetStringUTFChars", string);
18476            }
18477
18478            self.jni::<extern "system" fn(JNIEnvVTable, jstring, *mut jboolean) -> *const c_char>(169)(self.vtable, string, isCopy)
18479        }
18480    }
18481
18482    /// Convenience method that calls `GetStringUTFChars`, copies the result
18483    /// into a rust String and then calls `ReleaseStringUTFChars`.
18484    ///
18485    /// This function calls `ReleaseStringUTFChars` in all error cases where it has to be called!
18486    ///
18487    /// # IMPORTANT
18488    /// This function parses the bytes using `CStr::from_ptr(...).to_str()`
18489    ///
18490    /// This function may return None or rust strings that contain
18491    /// unexpected characters which are not actually present in the Java String. <br>
18492    /// This happens when the utf-8 and the modified-utf-8 encoding differ.<br>
18493    /// See <https://docs.oracle.com/en/java/javase/23/docs/api/java.base/java/io/DataInput.html#modified-utf-8> <br>
18494    /// This is the case when the string contains one of the following characters:
18495    /// * \0, null character 0 byte.
18496    /// * any supplementary character. (Any character that would require 4 bytes in normal utf-8 encoding)
18497    ///
18498    /// While this may cause an unexpected return value, it will still never cause UB regardless
18499    /// of what characters the java string contains. Only use this function if you have understood this caveat.
18500    ///
18501    /// An alternative, but slower version of this function is called `GetStringChars_as_string` which does not have this problem
18502    /// because instead of using the utf-8 representation of the string it uses the utf-16 representation,
18503    /// but it is much slower than this function with java 17 or newer. If your application is expected to process Strings containing
18504    /// the problematic characters then accepting the performance penalty is probably worth it.
18505    ///
18506    /// # Returns
18507    /// On failure this method return None.
18508    /// There are 2 different causes for returning None:
18509    /// 1. `GetStringUTFChars` fails, in this case more information should be gathered from `ExceptionCheck`.
18510    /// 2. The String returned by the JVM is not valid utf-8. In this case `ExceptionCheck` should yield None.
18511    ///     * see the IMPORTANT section for when this happens.
18512    ///
18513    /// # Panics
18514    /// if asserts feature is enabled and UB was detected
18515    ///
18516    /// # Safety
18517    /// Current thread must not be detached from JNI.
18518    ///
18519    /// Current thread must not be currently throwing an exception.
18520    ///
18521    /// Current thread does not hold a critical reference.
18522    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18523    ///
18524    /// `string` must not be null, must refer to a string and not already be garbage collected.
18525    ///
18526    pub unsafe fn GetStringUTFChars_as_string(&self, string: jstring) -> Option<String> {
18527        unsafe {
18528            #[cfg(feature = "asserts")]
18529            {
18530                self.check_not_critical("GetStringUTFChars_as_string");
18531                self.check_no_exception("GetStringUTFChars_as_string");
18532                assert!(!string.is_null(), "GetStringUTFChars_as_string string must not be null");
18533                self.check_if_arg_is_string("GetStringUTFChars_as_string", string);
18534            }
18535
18536            let str = self.GetStringUTFChars(string, null_mut());
18537            if str.is_null() {
18538                return None;
18539            }
18540
18541            let parsed = CStr::from_ptr(str).to_str();
18542            if let Ok(parsed) = parsed {
18543                let copy = parsed.to_string();
18544                self.ReleaseStringUTFChars(string, str);
18545                return Some(copy);
18546            }
18547
18548            self.ReleaseStringUTFChars(string, str);
18549            None
18550        }
18551    }
18552
18553    ///
18554    /// Frees the utf-8 string returned by `GetStringUTFChars`.
18555    /// After this method is called the pointer returned by `GetStringUTFChars` becomes invalid
18556    ///
18557    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStringUTFChars>
18558    ///
18559    ///
18560    /// # Arguments
18561    /// * `string` - the string refercence used in `GetStringUTFChars`
18562    ///     * must not be null
18563    ///     * must refer to a string
18564    ///     * must not be already garbage collected
18565    /// * `utf` - the raw utf8 data returned by `GetStringUTFChars`
18566    ///     * must not be null
18567    ///     * must be the exact return value of `GetStringUTFChars`
18568    ///
18569    ///
18570    /// # Panics
18571    /// if asserts feature is enabled and UB was detected
18572    ///
18573    /// # Safety
18574    ///
18575    /// Current thread must not be detached from JNI.
18576    ///
18577    /// Current thread does not hold a critical reference.
18578    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18579    ///
18580    /// `string` must not be null, must refer to a string and not already be garbage collected.
18581    ///
18582    pub unsafe fn ReleaseStringUTFChars(&self, string: jstring, utf: *const c_char) {
18583        unsafe {
18584            #[cfg(feature = "asserts")]
18585            {
18586                self.check_not_critical("ReleaseStringUTFChars");
18587                assert!(!string.is_null(), "ReleaseStringUTFChars string must not be null");
18588                assert!(!utf.is_null(), "ReleaseStringUTFChars utf must not be null");
18589                self.check_if_arg_is_string("ReleaseStringUTFChars", string);
18590            }
18591
18592            self.jni::<extern "system" fn(JNIEnvVTable, jstring, *const c_char)>(170)(self.vtable, string, utf);
18593        }
18594    }
18595
18596    ///
18597    /// Copies a part of the string into a provided jchar buffer
18598    ///
18599    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStringRegion>
18600    ///
18601    ///
18602    /// # Arguments
18603    /// * `string` - the string reference used in `GetStringUTFChars`
18604    ///     * must not be null
18605    ///     * must refer to a string
18606    ///     * must not be already garbage collected
18607    /// * `start` - the index of the first jchar to copy
18608    /// * `len` - the amount of jchar's to copy
18609    /// * `buffer` - the target buffer where the jchar's should be copied to
18610    ///     * must not be null
18611    ///
18612    /// # Throws Java Exception
18613    /// * `StringIndexOutOfBoundsException` - if start or start + len is out of bounds
18614    ///     * The state of the output buffer is undefined if this exception is thrown.
18615    ///
18616    ///
18617    /// # Panics
18618    /// if asserts feature is enabled and UB was detected
18619    ///
18620    /// # Safety
18621    ///
18622    /// Current thread must not be detached from JNI.
18623    ///
18624    /// Current thread must not be currently throwing an exception.
18625    ///
18626    /// Current thread does not hold a critical reference.
18627    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18628    ///
18629    /// `string` must not be null, must refer to a string and not already be garbage collected.
18630    /// `buffer` must be valid
18631    /// `buffer` must be aligned to jchar
18632    /// `buffer` must be large enough to hold the requested amount of jchar's
18633    ///
18634    pub unsafe fn GetStringRegion(&self, string: jstring, start: jsize, len: jsize, buffer: *mut jchar) {
18635        unsafe {
18636            #[cfg(feature = "asserts")]
18637            {
18638                self.check_not_critical("GetStringRegion");
18639                self.check_no_exception("GetStringRegion");
18640                assert!(!string.is_null(), "GetStringRegion string must not be null");
18641                assert!(!buffer.is_null(), "GetStringRegion buffer must not be null");
18642                assert!(buffer.is_aligned(), "GetStringRegion buffer is not aligned properly!");
18643                self.check_if_arg_is_string("GetStringRegion", string);
18644            }
18645
18646            self.jni::<extern "system" fn(JNIEnvVTable, jstring, jsize, jsize, *mut jchar)>(220)(self.vtable, string, start, len, buffer);
18647        }
18648    }
18649
18650    ///
18651    /// Copies a part of the string into a provided jchar buffer
18652    ///
18653    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStringRegion>
18654    ///
18655    ///
18656    /// # Arguments
18657    /// * `string` - the string reference used in `GetStringUTFChars`
18658    ///     * must not be null
18659    ///     * must refer to a string
18660    ///     * must not be already garbage collected
18661    /// * `start` - the index of the first jchar to copy
18662    /// * `buffer` - the target buffer where the jchar's should be copied to
18663    ///
18664    /// # Throws Java Exception
18665    /// * `StringIndexOutOfBoundsException` - if start or start + `buffer.len()` is out of bounds
18666    ///     * The state of the output buffer is undefined if this exception is thrown.
18667    ///
18668    ///
18669    /// # Panics
18670    /// if asserts feature is enabled and UB was detected
18671    ///
18672    /// # Safety
18673    ///
18674    /// Current thread must not be detached from JNI.
18675    ///
18676    /// Current thread must not be currently throwing an exception.
18677    ///
18678    /// Current thread does not hold a critical reference.
18679    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18680    ///
18681    /// `string` must not be null, must refer to a string and not already be garbage collected.
18682    ///
18683    pub unsafe fn GetStringRegion_into_slice(&self, string: jstring, start: jsize, buffer: &mut [jchar]) {
18684        unsafe {
18685            self.GetStringRegion(string, start, jsize::try_from(buffer.len()).expect("buf.len() > jsize::MAX"), buffer.as_mut_ptr());
18686        }
18687    }
18688
18689    ///
18690    /// Copies a part of the string into a provided `c_char` buffer
18691    /// This fn always appends a '0' byte to the output `c_char` buffer!
18692    ///
18693    /// This fn is not recommended for use. It is prone for out of bounds problems because
18694    /// the size of the buffer cannot be predicted easily because the `len` parameter is the amount of jchar's
18695    /// to copy and each jchar may turn into 1-4 bytes of output.
18696    /// The only "safe" way to call this fn is to ensure buffer is len*4+1 bytes large. +1 for the trailing 0 byte.
18697    ///
18698    /// The speed of this fn is also questionable on newer jvm's (at least since java17)
18699    /// as their internal represetation of String makes perform this operation very expensive.
18700    ///
18701    /// 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,
18702    /// and you can predict the buffer sizes with certaining because you know the requrested characters are only ascii for example.
18703    ///
18704    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStringUTFRegion>
18705    ///
18706    ///
18707    /// # Arguments
18708    /// * `string` - the string reference used in `GetStringUTFChars`
18709    ///     * must not be null
18710    ///     * must refer to a string
18711    ///     * must not be already garbage collected
18712    /// * `start` - the index of the first jchar to copy
18713    /// * `len` - the amount of java chars to copy. This has no relation to the output buffer size.
18714    /// * `buffer` - the target buffer where the jchar's should be copied to as utf-8
18715    ///
18716    /// # Throws Java Exception
18717    /// * `StringIndexOutOfBoundsException` - if start or start + len is out of bounds
18718    ///     * The state of the output buffer is undefined if this exception is thrown.
18719    ///
18720    ///
18721    /// # Panics
18722    /// if asserts feature is enabled and UB was detected
18723    ///
18724    /// # Safety
18725    ///
18726    /// Current thread must not be detached from JNI.
18727    ///
18728    /// Current thread must not be currently throwing an exception.
18729    ///
18730    /// Current thread does not hold a critical reference.
18731    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18732    ///
18733    /// `string` must not be null, must refer to a string and not already be garbage collected.
18734    /// `buffer` must be valid
18735    /// `buffer` must be large enough to hold the requested amount of jchar's
18736    ///
18737    pub unsafe fn GetStringUTFRegion(&self, string: jstring, start: jsize, len: jsize, buffer: *mut c_char) {
18738        unsafe {
18739            #[cfg(feature = "asserts")]
18740            {
18741                self.check_not_critical("GetStringUTFRegion");
18742                self.check_no_exception("GetStringUTFRegion");
18743                assert!(!string.is_null(), "GetStringUTFRegion string must not be null");
18744                self.check_if_arg_is_string("GetStringUTFRegion", string);
18745            }
18746
18747            self.jni::<extern "system" fn(JNIEnvVTable, jstring, jsize, jsize, *mut c_char)>(221)(self.vtable, string, start, len, buffer);
18748        }
18749    }
18750
18751    #[cfg(feature = "asserts")]
18752    std::thread_local! {
18753        //The "Critical Section" created by GetStringCritical has a lot of restrictions placed upon it.
18754        //This attempts to track "some" of them on a best effort basis.
18755        static CRITICAL_STRINGS: core::cell::RefCell<std::collections::HashMap<*const jchar, usize>> = core::cell::RefCell::new(std::collections::HashMap::new());
18756    }
18757
18758    ///
18759    /// Obtains a critical pointer into a primitive java String.
18760    /// This pointer must be released by calling `ReleaseStringCritical`.
18761    /// No other JNI functions can be called in the current thread.
18762    /// The only exception being multiple consecutive calls to `GetStringCritical` & `GetPrimitiveArrayCritical` to obtain multiple critical
18763    /// pointers at the same time.
18764    ///
18765    /// This method will return NULL to indicate error.
18766    /// The JVM will most likely throw an Exception, probably an `OOMError`.
18767    /// If you obtain multiple critical pointers, you MUST release all successfully obtained critical pointers
18768    /// before being able to check for the exception.
18769    ///
18770    /// Special care must be taken to avoid blocking the current thread with a dependency on another JVM thread.
18771    /// I.e. Do not read from a pipe that is filled by another JVM thread for example.
18772    ///
18773    /// 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.
18774    /// The JVM may decide among other things to suspend garbage collection while a critical pointer is held.
18775    /// So reading from a Socket with a long timeout while holding a critical pointer is unlikely to be a good idea.
18776    /// As it may cause unintended side effects in the rest of the JVM (like running out of memory because the GC doesn't run)
18777    ///
18778    /// Failure to release critical pointers before returning execution back to Java Code should be treated as UB
18779    /// even tho the JVM spec fails to mention this detail.
18780    ///
18781    /// Releasing critical pointers in another thread other than the thread that created it should be treated as UB
18782    /// even tho the JVM spec only mentions this detail indirectly.
18783    ///
18784    /// I recommend against using this method for almost every use case.
18785    /// Due to newer JVM's using UTF-8 internal representation this method is likely slower than
18786    /// just copying out the UTF-8 string directly for newer JVMs.
18787    ///
18788    /// # Returns
18789    /// A pointer to the jchar array of the string.
18790    ///
18791    ///
18792    /// # Panics
18793    /// if asserts feature is enabled and UB was detected
18794    ///
18795    /// # Safety
18796    /// Writing to the returned `*const jchar` in any way is UB.
18797    /// `string` must be non-null, valid, actually refer to a string and not yet be garbage collected.
18798    ///
18799    pub unsafe fn GetStringCritical(&self, string: jstring, isCopy: *mut jboolean) -> *const jchar {
18800        unsafe {
18801            #[cfg(feature = "asserts")]
18802            {
18803                assert!(!string.is_null(), "GetStringCritical string must not be null");
18804                Self::CRITICAL_POINTERS.with(|set| {
18805                    if set.borrow().is_empty() {
18806                        Self::CRITICAL_STRINGS.with(|strings| {
18807                            if strings.borrow().is_empty() {
18808                                //We can only do this check if we have not yet obtained a unreleased critical on the current thread.
18809                                //For subsequent calls we cannot do this check.
18810                                self.check_no_exception("GetStringCritical");
18811                                self.check_if_arg_is_string("GetStringCritical", string);
18812                            }
18813                        });
18814                    }
18815                });
18816            }
18817
18818            let crit = self.jni::<extern "system" fn(JNIEnvVTable, jstring, *mut jboolean) -> *const jchar>(224)(self.vtable, string, isCopy);
18819
18820            #[cfg(feature = "asserts")]
18821            {
18822                if !crit.is_null() {
18823                    Self::CRITICAL_STRINGS.with(|set| {
18824                        let mut rm = set.borrow_mut();
18825                        let n = rm.remove(&crit).unwrap_or(0) + 1;
18826                        rm.insert(crit, n);
18827                    });
18828                }
18829            }
18830
18831            crit
18832        }
18833    }
18834
18835    ///
18836    /// This fn ends a critical string section.
18837    /// After the call ends the underlying jchar array may be freed, moved by the jvm or garbage collected.
18838    ///
18839    ///
18840    /// # Panics
18841    /// if asserts feature is enabled and UB was detected
18842    ///
18843    /// # Safety
18844    /// `string` must be non-null and valid
18845    /// `cstring` must be non-null and the result of a `GetStringCritical` call
18846    ///
18847    pub unsafe fn ReleaseStringCritical(&self, string: jstring, cstring: *const jchar) {
18848        unsafe {
18849            #[cfg(feature = "asserts")]
18850            {
18851                assert!(!string.is_null(), "ReleaseStringCritical string must not be null");
18852                assert!(!cstring.is_null(), "ReleaseStringCritical cstring must not be null");
18853                Self::CRITICAL_STRINGS.with(|set| {
18854                    let mut rm = set.borrow_mut();
18855                    let mut n = rm.remove(&cstring).expect("ReleaseStringCritical cstring is not valid");
18856                    if n == 0 {
18857                        unreachable!();
18858                    }
18859
18860                    n -= 1;
18861
18862                    if n >= 1 {
18863                        rm.insert(cstring, n);
18864                    }
18865                });
18866            }
18867
18868            self.jni::<extern "system" fn(JNIEnvVTable, jstring, *const jchar)>(225)(self.vtable, string, cstring);
18869        }
18870    }
18871
18872    ///
18873    /// Returns the size of an array
18874    ///
18875    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetArrayLength>
18876    ///
18877    ///
18878    /// # Arguments
18879    /// * `array`
18880    ///     * must not be null
18881    ///     * must refer to an array of any primitve type or Object[]
18882    ///     * must not be already garbage collected
18883    /// # Returns
18884    /// the size of the array in elements
18885    ///
18886    ///
18887    /// # Panics
18888    /// if asserts feature is enabled and UB was detected
18889    ///
18890    /// # Safety
18891    ///
18892    /// Current thread must not be detached from JNI.
18893    ///
18894    /// Current thread must not be currently throwing an exception.
18895    ///
18896    /// Current thread does not hold a critical reference.
18897    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18898    ///
18899    /// `array` must not be null, must refer to a array and not already be garbage collected.
18900    ///
18901    pub unsafe fn GetArrayLength(&self, array: jarray) -> jsize {
18902        unsafe {
18903            #[cfg(feature = "asserts")]
18904            {
18905                self.check_not_critical("GetArrayLength");
18906                self.check_no_exception("GetArrayLength");
18907                assert!(!array.is_null(), "GetArrayLength array must not be null");
18908                self.check_is_array(array, "GetArrayLength");
18909            }
18910
18911            self.jni::<extern "system" fn(JNIEnvVTable, jarray) -> jsize>(171)(self.vtable, array)
18912        }
18913    }
18914
18915    ///
18916    /// Creates a new array of Objects
18917    ///
18918    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewObjectArray>
18919    ///
18920    /// # Arguments
18921    /// * `len` - capcity of the new array
18922    ///     * must not be negative
18923    /// * `elementClass` - the class of the elements in the array
18924    ///     * must not be null
18925    ///     * must refer to a class
18926    ///     * must not be already garbage collected
18927    /// * `initialElement` - the initial value of all elements in the array
18928    ///     * may be null
18929    ///     * must be an instance of the class referred to by `elementClass`
18930    ///     * must not be already garbage collected
18931    ///
18932    ///
18933    /// # Returns
18934    /// A reference to the new array or null on failure
18935    ///
18936    /// # Throws Java Exception
18937    /// `OutOfMemoryError` - if the jvm runs out of memory allocating the array.
18938    ///
18939    /// # Panics
18940    /// if asserts feature is enabled and UB was detected
18941    ///
18942    /// # Safety
18943    ///
18944    /// Current thread must not be detached from JNI.
18945    ///
18946    /// Current thread must not be currently throwing an exception.
18947    ///
18948    /// Current thread does not hold a critical reference.
18949    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18950    ///
18951    /// `elementClass` must not be null, must refer to a class and not already be garbage collected.
18952    /// `len` must not be negative
18953    /// `initialElement` must be null or an instance of the class referred to by `elementClass` and not already be garbage collected.
18954    ///
18955    pub unsafe fn NewObjectArray(&self, len: jsize, elementClass: jclass, initialElement: jobject) -> jobjectArray {
18956        unsafe {
18957            #[cfg(feature = "asserts")]
18958            {
18959                self.check_not_critical("NewObjectArray");
18960                self.check_no_exception("NewObjectArray");
18961                assert!(!elementClass.is_null(), "NewObjectArray elementClass must not be null");
18962                assert!(len >= 0, "NewObjectArray len mot not be negative {len}");
18963            }
18964
18965            self.jni::<extern "system" fn(JNIEnvVTable, jsize, jclass, jobject) -> jobjectArray>(172)(self.vtable, len, elementClass, initialElement)
18966        }
18967    }
18968
18969    ///
18970    /// Returns a local reference to a single element in the given object array.
18971    ///
18972    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetObjectArrayElement>
18973    ///
18974    /// # Arguments
18975    /// * `array` - the object array
18976    ///     * must not be null
18977    ///     * must be an array
18978    ///     * must not already be garbage collected
18979    /// * `index` - the index of the element to get
18980    ///
18981    /// # Returns
18982    /// A local reference to the element at the index in the array or null if the element was null or an error occured.
18983    ///
18984    /// # Throws Java Exception
18985    /// * `ArrayIndexOutOfBoundsException` - if the index is out of bounds
18986    ///
18987    /// # Panics
18988    /// if asserts feature is enabled and UB was detected
18989    ///
18990    /// # Safety
18991    ///
18992    /// Current thread must not be detached from JNI.
18993    ///
18994    /// Current thread must not be currently throwing an exception.
18995    ///
18996    /// Current thread does not hold a critical reference.
18997    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
18998    ///
18999    /// `array` must not be null, must refer to a array and not already be garbage collected.
19000    ///
19001    pub unsafe fn GetObjectArrayElement(&self, array: jobjectArray, index: jsize) -> jobject {
19002        unsafe {
19003            #[cfg(feature = "asserts")]
19004            {
19005                self.check_not_critical("GetObjectArrayElement");
19006                self.check_no_exception("GetObjectArrayElement");
19007                assert!(!array.is_null(), "GetObjectArrayElement array must not be null");
19008            }
19009
19010            self.jni::<extern "system" fn(JNIEnvVTable, jobjectArray, jsize) -> jobject>(173)(self.vtable, array, index)
19011        }
19012    }
19013
19014    ///
19015    /// Set a single element in a object array
19016    ///
19017    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetObjectArrayElement>
19018    ///
19019    /// # Arguments
19020    /// * `array` - the object array
19021    ///     * must not be null
19022    ///     * must be an array
19023    ///     * must not already be garbage collected
19024    /// * `index` - the index of the element to get
19025    /// * `value` - the new value of the element
19026    ///     * may be null
19027    ///     * must match the type of the array
19028    ///     * must not be already garbage collected
19029    ///
19030    /// # Throws Java Exception
19031    /// * `ArrayIndexOutOfBoundsException` - if the index is out of bounds
19032    ///
19033    /// # Panics
19034    /// if asserts feature is enabled and UB was detected
19035    ///
19036    /// # Safety
19037    ///
19038    /// Current thread must not be detached from JNI.
19039    ///
19040    /// Current thread must not be currently throwing an exception.
19041    ///
19042    /// Current thread does not hold a critical reference.
19043    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19044    ///
19045    /// `array` must not be null, must refer to a array and not already be garbage collected.
19046    /// `value` must be null or an instance of the type contained inside the array and not already be garbage collected.
19047    ///
19048    pub unsafe fn SetObjectArrayElement(&self, array: jobjectArray, index: jsize, value: jobject) {
19049        unsafe {
19050            #[cfg(feature = "asserts")]
19051            {
19052                self.check_not_critical("SetObjectArrayElement");
19053                self.check_no_exception("SetObjectArrayElement");
19054                assert!(!array.is_null(), "SetObjectArrayElement array must not be null");
19055                //TODO check array component type matches value
19056            }
19057
19058            self.jni::<extern "system" fn(JNIEnvVTable, jobjectArray, jsize, jobject)>(174)(self.vtable, array, index, value);
19059        }
19060    }
19061
19062    ///
19063    /// Creates a new boolean array
19064    ///
19065    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewBooleanArray>
19066    ///
19067    /// # Arguments
19068    /// * `size` - capacity of the new array
19069    ///     * must not be negative
19070    ///
19071    ///
19072    /// # Returns
19073    /// A reference to the new array or null on failure
19074    ///
19075    /// # Throws Java Exception
19076    /// `OutOfMemoryError` - if the jvm runs out of memory allocating the array.
19077    ///
19078    /// # Panics
19079    /// if asserts feature is enabled and UB was detected
19080    ///
19081    /// # Safety
19082    ///
19083    /// Current thread must not be detached from JNI.
19084    ///
19085    /// Current thread must not be currently throwing an exception.
19086    ///
19087    /// Current thread does not hold a critical reference.
19088    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19089    ///
19090    /// `size` must not be negative
19091    ///
19092    #[must_use]
19093    pub unsafe fn NewBooleanArray(&self, size: jsize) -> jbooleanArray {
19094        unsafe {
19095            #[cfg(feature = "asserts")]
19096            {
19097                self.check_not_critical("NewBooleanArray");
19098                self.check_no_exception("NewBooleanArray");
19099                assert!(size >= 0, "NewBooleanArray size must not be negative {size}");
19100            }
19101
19102            self.jni::<extern "system" fn(JNIEnvVTable, jsize) -> jobject>(175)(self.vtable, size)
19103        }
19104    }
19105
19106    ///
19107    /// Creates a new byte array
19108    ///
19109    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewByteArray>
19110    ///
19111    /// # Arguments
19112    /// * `size` - capacity of the new array
19113    ///     * must not be negative
19114    ///
19115    ///
19116    /// # Returns
19117    /// A reference to the new array or null on failure
19118    ///
19119    /// # Throws Java Exception
19120    /// `OutOfMemoryError` - if the jvm runs out of memory allocating the array.
19121    ///
19122    /// # Panics
19123    /// if asserts feature is enabled and UB was detected
19124    ///
19125    /// # Safety
19126    ///
19127    /// Current thread must not be detached from JNI.
19128    ///
19129    /// Current thread must not be currently throwing an exception.
19130    ///
19131    /// Current thread does not hold a critical reference.
19132    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19133    ///
19134    /// `size` must not be negative
19135    ///
19136    #[must_use]
19137    pub unsafe fn NewByteArray(&self, size: jsize) -> jbyteArray {
19138        unsafe {
19139            #[cfg(feature = "asserts")]
19140            {
19141                self.check_not_critical("NewByteArray");
19142                self.check_no_exception("NewByteArray");
19143                assert!(size >= 0, "NewByteArray size must not be negative {size}");
19144            }
19145
19146            self.jni::<extern "system" fn(JNIEnvVTable, jsize) -> jbyteArray>(176)(self.vtable, size)
19147        }
19148    }
19149
19150    ///
19151    /// Creates a new char array
19152    ///
19153    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewCharArray>
19154    ///
19155    /// # Arguments
19156    /// * `size` - capacity of the new array
19157    ///     * must not be negative
19158    ///
19159    ///
19160    /// # Returns
19161    /// A reference to the new array or null on failure
19162    ///
19163    /// # Throws Java Exception
19164    /// `OutOfMemoryError` - if the jvm runs out of memory allocating the array.
19165    ///
19166    /// # Panics
19167    /// if asserts feature is enabled and UB was detected
19168    ///
19169    /// # Safety
19170    ///
19171    /// Current thread must not be detached from JNI.
19172    ///
19173    /// Current thread must not be currently throwing an exception.
19174    ///
19175    /// Current thread does not hold a critical reference.
19176    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19177    ///
19178    /// `size` must not be negative
19179    ///
19180    #[must_use]
19181    pub unsafe fn NewCharArray(&self, size: jsize) -> jcharArray {
19182        unsafe {
19183            #[cfg(feature = "asserts")]
19184            {
19185                self.check_not_critical("NewCharArray");
19186                self.check_no_exception("NewCharArray");
19187                assert!(size >= 0, "NewCharArray size must not be negative {size}");
19188            }
19189
19190            self.jni::<extern "system" fn(JNIEnvVTable, jsize) -> jcharArray>(177)(self.vtable, size)
19191        }
19192    }
19193
19194    ///
19195    /// Creates a new short array
19196    ///
19197    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewShortArray>
19198    ///
19199    /// # Arguments
19200    /// * `size` - capacity of the new array
19201    ///     * must not be negative
19202    ///
19203    ///
19204    /// # Returns
19205    /// A reference to the new array or null on failure
19206    ///
19207    /// # Throws Java Exception
19208    /// `OutOfMemoryError` - if the jvm runs out of memory allocating the array.
19209    ///
19210    /// # Panics
19211    /// if asserts feature is enabled and UB was detected
19212    ///
19213    /// # Safety
19214    ///
19215    /// Current thread must not be detached from JNI.
19216    ///
19217    /// Current thread must not be currently throwing an exception.
19218    ///
19219    /// Current thread does not hold a critical reference.
19220    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19221    ///
19222    /// `size` must not be negative
19223    ///
19224    #[must_use]
19225    pub unsafe fn NewShortArray(&self, size: jsize) -> jshortArray {
19226        unsafe {
19227            #[cfg(feature = "asserts")]
19228            {
19229                self.check_not_critical("NewShortArray");
19230                self.check_no_exception("NewShortArray");
19231                assert!(size >= 0, "NewShortArray size must not be negative {size}");
19232            }
19233
19234            self.jni::<extern "system" fn(JNIEnvVTable, jsize) -> jshortArray>(178)(self.vtable, size)
19235        }
19236    }
19237
19238    ///
19239    /// Creates a new int array
19240    ///
19241    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewIntArray>
19242    ///
19243    /// # Arguments
19244    /// * `size` - capacity of the new array
19245    ///     * must not be negative
19246    ///
19247    ///
19248    /// # Returns
19249    /// A reference to the new array or null on failure
19250    ///
19251    /// # Throws Java Exception
19252    /// `OutOfMemoryError` - if the jvm runs out of memory allocating the array.
19253    ///
19254    /// # Panics
19255    /// if asserts feature is enabled and UB was detected
19256    ///
19257    /// # Safety
19258    ///
19259    /// Current thread must not be detached from JNI.
19260    ///
19261    /// Current thread must not be currently throwing an exception.
19262    ///
19263    /// Current thread does not hold a critical reference.
19264    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19265    ///
19266    /// `size` must not be negative
19267    ///
19268    #[must_use]
19269    pub unsafe fn NewIntArray(&self, size: jsize) -> jintArray {
19270        unsafe {
19271            #[cfg(feature = "asserts")]
19272            {
19273                self.check_not_critical("NewIntArray");
19274                self.check_no_exception("NewIntArray");
19275                assert!(size >= 0, "NewIntArray size must not be negative {size}");
19276            }
19277
19278            self.jni::<extern "system" fn(JNIEnvVTable, jsize) -> jintArray>(179)(self.vtable, size)
19279        }
19280    }
19281
19282    ///
19283    /// Creates a new long array
19284    ///
19285    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewLongArray>
19286    ///
19287    /// # Arguments
19288    /// * `size` - capacity of the new array
19289    ///     * must not be negative
19290    ///
19291    ///
19292    /// # Returns
19293    /// A reference to the new array or null on failure
19294    ///
19295    /// # Throws Java Exception
19296    /// `OutOfMemoryError` - if the jvm runs out of memory allocating the array.
19297    ///
19298    /// # Panics
19299    /// if asserts feature is enabled and UB was detected
19300    ///
19301    /// # Safety
19302    ///
19303    /// Current thread must not be detached from JNI.
19304    ///
19305    /// Current thread must not be currently throwing an exception.
19306    ///
19307    /// Current thread does not hold a critical reference.
19308    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19309    ///
19310    /// `size` must not be negative
19311    ///
19312    #[must_use]
19313    pub unsafe fn NewLongArray(&self, size: jsize) -> jlongArray {
19314        unsafe {
19315            #[cfg(feature = "asserts")]
19316            {
19317                self.check_not_critical("NewLongArray");
19318                self.check_no_exception("NewLongArray");
19319                assert!(size >= 0, "NewLongArray size must not be negative {size}");
19320            }
19321
19322            self.jni::<extern "system" fn(JNIEnvVTable, jsize) -> jlongArray>(180)(self.vtable, size)
19323        }
19324    }
19325
19326    ///
19327    /// Creates a new float array
19328    ///
19329    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewFloatArray>
19330    ///
19331    /// # Arguments
19332    /// * `size` - capacity of the new array
19333    ///     * must not be negative
19334    ///
19335    ///
19336    /// # Returns
19337    /// A reference to the new array or null on failure
19338    ///
19339    /// # Throws Java Exception
19340    /// `OutOfMemoryError` - if the jvm runs out of memory allocating the array.
19341    ///
19342    /// # Panics
19343    /// if asserts feature is enabled and UB was detected
19344    ///
19345    /// # Safety
19346    ///
19347    /// Current thread must not be detached from JNI.
19348    ///
19349    /// Current thread must not be currently throwing an exception.
19350    ///
19351    /// Current thread does not hold a critical reference.
19352    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19353    ///
19354    /// `size` must not be negative
19355    ///
19356    #[must_use]
19357    pub unsafe fn NewFloatArray(&self, size: jsize) -> jfloatArray {
19358        unsafe {
19359            #[cfg(feature = "asserts")]
19360            {
19361                self.check_not_critical("NewFloatArray");
19362                self.check_no_exception("NewFloatArray");
19363                assert!(size >= 0, "NewFloatArray size must not be negative {size}");
19364            }
19365
19366            self.jni::<extern "system" fn(JNIEnvVTable, jsize) -> jfloatArray>(181)(self.vtable, size)
19367        }
19368    }
19369
19370    ///
19371    /// Creates a new double array
19372    ///
19373    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewDoubleArray>
19374    ///
19375    /// # Arguments
19376    /// * `size` - capacity of the new array
19377    ///     * must not be negative
19378    ///
19379    ///
19380    /// # Returns
19381    /// A reference to the new array or null on failure
19382    ///
19383    /// # Throws Java Exception
19384    /// `OutOfMemoryError` - if the jvm runs out of memory allocating the array.
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    /// `size` must not be negative
19399    ///
19400    #[must_use]
19401    pub unsafe fn NewDoubleArray(&self, size: jsize) -> jdoubleArray {
19402        unsafe {
19403            #[cfg(feature = "asserts")]
19404            {
19405                self.check_not_critical("NewDoubleArray");
19406                self.check_no_exception("NewDoubleArray");
19407                assert!(size >= 0, "NewDoubleArray size must not be negative {size}");
19408            }
19409
19410            self.jni::<extern "system" fn(JNIEnvVTable, jsize) -> jdoubleArray>(182)(self.vtable, size)
19411        }
19412    }
19413
19414    ///
19415    /// Get the boolean content inside the array
19416    ///
19417    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetBooleanArrayElements>
19418    ///
19419    /// # Arguments
19420    /// * `array` - the array
19421    ///     * must not be null
19422    ///     * must be an array
19423    ///     * must not already be garbage collected
19424    /// * `isCopy` - optional flag for the jvm to indicate if the data is a copy or not.
19425    ///     * can be null
19426    ///
19427    /// # Returns
19428    /// A pointer to the elements or null if an error occured.
19429    ///
19430    /// # Throws Java Exception
19431    /// * `OutOfMemoryError` - if the jvm ran out of memory.
19432    ///
19433    /// # Panics
19434    /// if asserts feature is enabled and UB was detected
19435    ///
19436    /// # Safety
19437    ///
19438    /// Current thread must not be detached from JNI.
19439    ///
19440    /// Current thread must not be currently throwing an exception.
19441    ///
19442    /// Current thread does not hold a critical reference.
19443    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19444    ///
19445    /// `array` must not be null, must refer to a array and not already be garbage collected.
19446    ///
19447    pub unsafe fn GetBooleanArrayElements(&self, array: jbooleanArray, is_copy: *mut jboolean) -> *mut jboolean {
19448        unsafe {
19449            #[cfg(feature = "asserts")]
19450            {
19451                self.check_not_critical("GetBooleanArrayElements");
19452                self.check_no_exception("GetBooleanArrayElements");
19453                assert!(!array.is_null(), "GetBooleanArrayElements jarray must not be null");
19454            }
19455
19456            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, *mut jboolean) -> *mut jboolean>(183)(self.vtable, array, is_copy)
19457        }
19458    }
19459
19460    ///
19461    /// Get the byte content inside the array
19462    ///
19463    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetByteArrayElements>
19464    ///
19465    /// # Arguments
19466    /// * `array` - the array
19467    ///     * must not be null
19468    ///     * must be an array
19469    ///     * must not already be garbage collected
19470    /// * `isCopy` - optional flag for the jvm to indicate if the data is a copy or not.
19471    ///     * can be null
19472    ///
19473    /// # Returns
19474    /// A pointer to the elements or null if an error occured.
19475    ///
19476    /// # Throws Java Exception
19477    /// * `OutOfMemoryError` - if the jvm ran out of memory.
19478    ///
19479    /// # Panics
19480    /// if asserts feature is enabled and UB was detected
19481    ///
19482    /// # Safety
19483    ///
19484    /// Current thread must not be detached from JNI.
19485    ///
19486    /// Current thread must not be currently throwing an exception.
19487    ///
19488    /// Current thread does not hold a critical reference.
19489    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19490    ///
19491    /// `array` must not be null, must refer to a array and not already be garbage collected.
19492    ///
19493    pub unsafe fn GetByteArrayElements(&self, array: jbyteArray, is_copy: *mut jboolean) -> *mut jbyte {
19494        unsafe {
19495            #[cfg(feature = "asserts")]
19496            {
19497                self.check_not_critical("GetByteArrayElements");
19498                self.check_no_exception("GetByteArrayElements");
19499                assert!(!array.is_null(), "GetByteArrayElements jarray must not be null");
19500            }
19501
19502            self.jni::<extern "system" fn(JNIEnvVTable, jbyteArray, *mut jboolean) -> *mut jbyte>(184)(self.vtable, array, is_copy)
19503        }
19504    }
19505
19506    ///
19507    /// Get the char content inside the array
19508    ///
19509    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetCharArrayElements>
19510    ///
19511    /// # Arguments
19512    /// * `array` - the array
19513    ///     * must not be null
19514    ///     * must be an array
19515    ///     * must not already be garbage collected
19516    /// * `isCopy` - optional flag for the jvm to indicate if the data is a copy or not.
19517    ///     * can be null
19518    ///
19519    /// # Returns
19520    /// A pointer to the elements or null if an error occured.
19521    ///
19522    /// # Throws Java Exception
19523    /// * `OutOfMemoryError` - if the jvm ran out of memory.
19524    ///
19525    /// # Panics
19526    /// if asserts feature is enabled and UB was detected
19527    ///
19528    /// # Safety
19529    ///
19530    /// Current thread must not be detached from JNI.
19531    ///
19532    /// Current thread must not be currently throwing an exception.
19533    ///
19534    /// Current thread does not hold a critical reference.
19535    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19536    ///
19537    /// `array` must not be null, must refer to a array and not already be garbage collected.
19538    ///
19539    pub unsafe fn GetCharArrayElements(&self, array: jcharArray, is_copy: *mut jboolean) -> *mut jchar {
19540        unsafe {
19541            #[cfg(feature = "asserts")]
19542            {
19543                self.check_not_critical("GetCharArrayElements");
19544                self.check_no_exception("GetCharArrayElements");
19545                assert!(!array.is_null(), "GetCharArrayElements jarray must not be null");
19546            }
19547
19548            self.jni::<extern "system" fn(JNIEnvVTable, jcharArray, *mut jboolean) -> *mut jchar>(185)(self.vtable, array, is_copy)
19549        }
19550    }
19551
19552    ///
19553    /// Get the short content inside the array
19554    ///
19555    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetShortArrayElements>
19556    ///
19557    /// # Arguments
19558    /// * `array` - the array
19559    ///     * must not be null
19560    ///     * must be an array
19561    ///     * must not already be garbage collected
19562    /// * `isCopy` - optional flag for the jvm to indicate if the data is a copy or not.
19563    ///     * can be null
19564    ///
19565    /// # Returns
19566    /// A pointer to the elements or null if an error occured.
19567    ///
19568    /// # Throws Java Exception
19569    /// * `OutOfMemoryError` - if the jvm ran out of memory.
19570    ///
19571    /// # Panics
19572    /// if asserts feature is enabled and UB was detected
19573    ///
19574    /// # Safety
19575    ///
19576    /// Current thread must not be detached from JNI.
19577    ///
19578    /// Current thread must not be currently throwing an exception.
19579    ///
19580    /// Current thread does not hold a critical reference.
19581    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19582    ///
19583    /// `array` must not be null, must refer to a array and not already be garbage collected.
19584    ///
19585    pub unsafe fn GetShortArrayElements(&self, array: jshortArray, is_copy: *mut jboolean) -> *mut jshort {
19586        unsafe {
19587            #[cfg(feature = "asserts")]
19588            {
19589                self.check_not_critical("GetShortArrayElements");
19590                self.check_no_exception("GetShortArrayElements");
19591                assert!(!array.is_null(), "GetShortArrayElements jarray must not be null");
19592            }
19593
19594            self.jni::<extern "system" fn(JNIEnvVTable, jshortArray, *mut jboolean) -> *mut jshort>(186)(self.vtable, array, is_copy)
19595        }
19596    }
19597
19598    ///
19599    /// Get the int content inside the array
19600    ///
19601    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetIntArrayElements>
19602    ///
19603    /// # Arguments
19604    /// * `array` - the array
19605    ///     * must not be null
19606    ///     * must be an array
19607    ///     * must not already be garbage collected
19608    /// * `isCopy` - optional flag for the jvm to indicate if the data is a copy or not.
19609    ///     * can be null
19610    ///
19611    /// # Returns
19612    /// A pointer to the elements or null if an error occured.
19613    ///
19614    /// # Throws Java Exception
19615    /// * `OutOfMemoryError` - if the jvm ran out of memory.
19616    ///
19617    /// # Panics
19618    /// if asserts feature is enabled and UB was detected
19619    ///
19620    /// # Safety
19621    ///
19622    /// Current thread must not be detached from JNI.
19623    ///
19624    /// Current thread must not be currently throwing an exception.
19625    ///
19626    /// Current thread does not hold a critical reference.
19627    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19628    ///
19629    /// `array` must not be null, must refer to a array and not already be garbage collected.
19630    ///
19631    pub unsafe fn GetIntArrayElements(&self, array: jintArray, is_copy: *mut jboolean) -> *mut jint {
19632        unsafe {
19633            #[cfg(feature = "asserts")]
19634            {
19635                self.check_not_critical("GetIntArrayElements");
19636                self.check_no_exception("GetIntArrayElements");
19637                assert!(!array.is_null(), "GetIntArrayElements jarray must not be null");
19638            }
19639
19640            self.jni::<extern "system" fn(JNIEnvVTable, jintArray, *mut jboolean) -> *mut jint>(187)(self.vtable, array, is_copy)
19641        }
19642    }
19643
19644    ///
19645    /// Get the long content inside the array
19646    ///
19647    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetLongArrayElements>
19648    ///
19649    /// # Arguments
19650    /// * `array` - the array
19651    ///     * must not be null
19652    ///     * must be an array
19653    ///     * must not already be garbage collected
19654    /// * `isCopy` - optional flag for the jvm to indicate if the data is a copy or not.
19655    ///     * can be null
19656    ///
19657    /// # Returns
19658    /// A pointer to the elements or null if an error occured.
19659    ///
19660    /// # Throws Java Exception
19661    /// * `OutOfMemoryError` - if the jvm ran out of memory.
19662    ///
19663    /// # Panics
19664    /// if asserts feature is enabled and UB was detected
19665    ///
19666    /// # Safety
19667    ///
19668    /// Current thread must not be detached from JNI.
19669    ///
19670    /// Current thread must not be currently throwing an exception.
19671    ///
19672    /// Current thread does not hold a critical reference.
19673    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19674    ///
19675    /// `array` must not be null, must refer to a array and not already be garbage collected.
19676    ///
19677    pub unsafe fn GetLongArrayElements(&self, array: jlongArray, is_copy: *mut jboolean) -> *mut jlong {
19678        unsafe {
19679            #[cfg(feature = "asserts")]
19680            {
19681                self.check_not_critical("GetLongArrayElements");
19682                self.check_no_exception("GetLongArrayElements");
19683                assert!(!array.is_null(), "GetLongArrayElements jarray must not be null");
19684            }
19685
19686            self.jni::<extern "system" fn(JNIEnvVTable, jlongArray, *mut jboolean) -> *mut jlong>(188)(self.vtable, array, is_copy)
19687        }
19688    }
19689
19690    ///
19691    /// Get the float content inside the array
19692    ///
19693    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetFloatArrayElements>
19694    ///
19695    /// # Arguments
19696    /// * `array` - the array
19697    ///     * must not be null
19698    ///     * must be an array
19699    ///     * must not already be garbage collected
19700    /// * `isCopy` - optional flag for the jvm to indicate if the data is a copy or not.
19701    ///     * can be null
19702    ///
19703    /// # Returns
19704    /// A pointer to the elements or null if an error occured.
19705    ///
19706    /// # Throws Java Exception
19707    /// * `OutOfMemoryError` - if the jvm ran out of memory.
19708    ///
19709    /// # Panics
19710    /// if asserts feature is enabled and UB was detected
19711    ///
19712    /// # Safety
19713    ///
19714    /// Current thread must not be detached from JNI.
19715    ///
19716    /// Current thread must not be currently throwing an exception.
19717    ///
19718    /// Current thread does not hold a critical reference.
19719    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19720    ///
19721    /// `array` must not be null, must refer to a array and not already be garbage collected.
19722    ///
19723    pub unsafe fn GetFloatArrayElements(&self, array: jfloatArray, is_copy: *mut jboolean) -> *mut jfloat {
19724        unsafe {
19725            #[cfg(feature = "asserts")]
19726            {
19727                self.check_not_critical("GetFloatArrayElements");
19728                self.check_no_exception("GetFloatArrayElements");
19729                assert!(!array.is_null(), "GetFloatArrayElements jarray must not be null");
19730            }
19731
19732            self.jni::<extern "system" fn(JNIEnvVTable, jfloatArray, *mut jboolean) -> *mut jfloat>(189)(self.vtable, array, is_copy)
19733        }
19734    }
19735
19736    ///
19737    /// Get the double content inside the array
19738    ///
19739    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetDoubleArrayElements>
19740    ///
19741    /// # Arguments
19742    /// * `array` - the array
19743    ///     * must not be null
19744    ///     * must be an array
19745    ///     * must not already be garbage collected
19746    /// * `isCopy` - optional flag for the jvm to indicate if the data is a copy or not.
19747    ///     * can be null
19748    ///
19749    /// # Returns
19750    /// A pointer to the elements or null if an error occured.
19751    ///
19752    /// # Throws Java Exception
19753    /// * `OutOfMemoryError` - if the jvm ran out of memory.
19754    ///
19755    /// # Panics
19756    /// if asserts feature is enabled and UB was detected
19757    ///
19758    /// # Safety
19759    ///
19760    /// Current thread must not be detached from JNI.
19761    ///
19762    /// Current thread must not be currently throwing an exception.
19763    ///
19764    /// Current thread does not hold a critical reference.
19765    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19766    ///
19767    /// `array` must not be null, must refer to a array and not already be garbage collected.
19768    ///
19769    pub unsafe fn GetDoubleArrayElements(&self, array: jdoubleArray, is_copy: *mut jboolean) -> *mut jdouble {
19770        unsafe {
19771            #[cfg(feature = "asserts")]
19772            {
19773                self.check_not_critical("GetDoubleArrayElements");
19774                self.check_no_exception("GetDoubleArrayElements");
19775                assert!(!array.is_null(), "GetDoubleArrayElements jarray must not be null");
19776            }
19777
19778            self.jni::<extern "system" fn(JNIEnvVTable, jdoubleArray, *mut jboolean) -> *mut jdouble>(190)(self.vtable, array, is_copy)
19779        }
19780    }
19781
19782    ///
19783    /// Releases the boolean array elements back to the jvm
19784    ///
19785    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ReleaseBooleanArrayElements>
19786    ///
19787    /// # Arguments
19788    /// * `array` - the array
19789    ///     * must not be null
19790    ///     * must be an array
19791    ///     * must not already be garbage collected
19792    /// * `elems`
19793    ///     * must not be null
19794    /// * `mode`
19795    ///     * must be one of the following constants:
19796    ///         * `JNI_OK` - release the array, copy back the contents into the internal buffer if it was a copy
19797    ///         * `JNI_COMMIT` - do not release the array, copy back the contents into the internal buffer if it was a copy
19798    ///         * `JNI_ABORT` - release the array, do not copy back the contents into the internal buffer if it was a copy
19799    ///         * Note: if data was not a copy then `JNI_OK` and `JNI_ABORT` do the same.
19800    ///
19801    /// # Panics
19802    /// if asserts feature is enabled and UB was detected
19803    ///
19804    /// # Safety
19805    ///
19806    /// Current thread must not be detached from JNI.
19807    ///
19808    /// Current thread does not hold a critical reference.
19809    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19810    ///
19811    /// `array` must not be null, must refer to a array and not already be garbage collected.
19812    /// `elems` must be the buffer of the same `array` reference
19813    /// `mode` must be one of the constants
19814    ///
19815    pub unsafe fn ReleaseBooleanArrayElements(&self, array: jbooleanArray, elems: *mut jboolean, mode: jint) {
19816        unsafe {
19817            #[cfg(feature = "asserts")]
19818            {
19819                self.check_not_critical("ReleaseBooleanArrayElements");
19820                assert!(!array.is_null(), "ReleaseBooleanArrayElements jarray must not be null");
19821                assert!(!elems.is_null(), "ReleaseBooleanArrayElements elems must not be null");
19822                assert!(
19823                    mode == JNI_OK || mode == JNI_COMMIT || mode == JNI_ABORT,
19824                    "ReleaseBooleanArrayElements mode is invalid {mode}"
19825                );
19826            }
19827
19828            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, *mut jboolean, jint)>(191)(self.vtable, array, elems, mode);
19829        }
19830    }
19831
19832    ///
19833    /// Releases the byte array elements back to the jvm
19834    ///
19835    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ReleaseByteArrayElements>
19836    ///
19837    /// # Arguments
19838    /// * `array` - the array
19839    ///     * must not be null
19840    ///     * must be an array
19841    ///     * must not already be garbage collected
19842    /// * `elems`
19843    ///     * must not be null
19844    /// * `mode`
19845    ///     * must be one of the following constants:
19846    ///         * `JNI_OK` - release the array, copy back the contents into the internal buffer if it was a copy
19847    ///         * `JNI_COMMIT` - do not release the array, copy back the contents into the internal buffer if it was a copy
19848    ///         * `JNI_ABORT` - release the array, do not copy back the contents into the internal buffer if it was a copy
19849    ///         * Note: if data was not a copy then `JNI_OK` and `JNI_ABORT` do the same.
19850    ///
19851    /// # Panics
19852    /// if asserts feature is enabled and UB was detected
19853    ///
19854    /// # Safety
19855    ///
19856    /// Current thread must not be detached from JNI.
19857    ///
19858    /// Current thread does not hold a critical reference.
19859    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19860    ///
19861    /// `array` must not be null, must refer to a array and not already be garbage collected.
19862    /// `elems` must be the buffer of the same `array` reference
19863    /// `mode` must be one of the constants
19864    ///
19865    pub unsafe fn ReleaseByteArrayElements(&self, array: jbyteArray, elems: *mut jbyte, mode: jint) {
19866        unsafe {
19867            #[cfg(feature = "asserts")]
19868            {
19869                self.check_not_critical("ReleaseByteArrayElements");
19870                assert!(!array.is_null(), "ReleaseByteArrayElements jarray must not be null");
19871                assert!(!elems.is_null(), "ReleaseByteArrayElements elems must not be null");
19872                assert!(mode == JNI_OK || mode == JNI_COMMIT || mode == JNI_ABORT, "ReleaseByteArrayElements mode is invalid {mode}");
19873            }
19874
19875            self.jni::<extern "system" fn(JNIEnvVTable, jbyteArray, *mut jbyte, jint)>(192)(self.vtable, array, elems, mode);
19876        }
19877    }
19878
19879    ///
19880    /// Releases the char array elements back to the jvm
19881    ///
19882    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ReleaseCharArrayElements>
19883    ///
19884    /// # Arguments
19885    /// * `array` - the array
19886    ///     * must not be null
19887    ///     * must be an array
19888    ///     * must not already be garbage collected
19889    /// * `elems`
19890    ///     * must not be null
19891    /// * `mode`
19892    ///     * must be one of the following constants:
19893    ///         * `JNI_OK` - release the array, copy back the contents into the internal buffer if it was a copy
19894    ///         * `JNI_COMMIT` - do not release the array, copy back the contents into the internal buffer if it was a copy
19895    ///         * `JNI_ABORT` - release the array, do not copy back the contents into the internal buffer if it was a copy
19896    ///         * Note: if data was not a copy then `JNI_OK` and `JNI_ABORT` do the same.
19897    ///
19898    ///
19899    /// # Panics
19900    /// if asserts feature is enabled and UB was detected
19901    ///
19902    /// # Safety
19903    ///
19904    /// Current thread must not be detached from JNI.
19905    ///
19906    /// Current thread does not hold a critical reference.
19907    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19908    ///
19909    /// `array` must not be null, must refer to a array and not already be garbage collected.
19910    /// `elems` must be the buffer of the same `array` reference
19911    /// `mode` must be one of the constants
19912    ///
19913    pub unsafe fn ReleaseCharArrayElements(&self, array: jcharArray, elems: *mut jchar, mode: jint) {
19914        unsafe {
19915            #[cfg(feature = "asserts")]
19916            {
19917                self.check_not_critical("ReleaseCharArrayElements");
19918                assert!(!array.is_null(), "ReleaseCharArrayElements jarray must not be null");
19919                assert!(!elems.is_null(), "ReleaseCharArrayElements elems must not be null");
19920                assert!(mode == JNI_OK || mode == JNI_COMMIT || mode == JNI_ABORT, "ReleaseCharArrayElements mode is invalid {mode}");
19921            }
19922
19923            self.jni::<extern "system" fn(JNIEnvVTable, jcharArray, *mut jchar, jint)>(193)(self.vtable, array, elems, mode);
19924        }
19925    }
19926
19927    ///
19928    /// Releases the short array elements back to the jvm
19929    ///
19930    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ReleaseShortArrayElements>
19931    ///
19932    /// # Arguments
19933    /// * `array` - the array
19934    ///     * must not be null
19935    ///     * must be an array
19936    ///     * must not already be garbage collected
19937    /// * `elems`
19938    ///     * must not be null
19939    /// * `mode`
19940    ///     * must be one of the following constants:
19941    ///         * `JNI_OK` - release the array, copy back the contents into the internal buffer if it was a copy
19942    ///         * `JNI_COMMIT` - do not release the array, copy back the contents into the internal buffer if it was a copy
19943    ///         * `JNI_ABORT` - release the array, do not copy back the contents into the internal buffer if it was a copy
19944    ///         * Note: if data was not a copy then `JNI_OK` and `JNI_ABORT` do the same.
19945    ///
19946    ///
19947    /// # Panics
19948    /// if asserts feature is enabled and UB was detected
19949    ///
19950    /// # Safety
19951    ///
19952    /// Current thread must not be detached from JNI.
19953    ///
19954    /// Current thread does not hold a critical reference.
19955    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
19956    ///
19957    /// `array` must not be null, must refer to a array and not already be garbage collected.
19958    /// `elems` must be the buffer of the same `array` reference
19959    /// `mode` must be one of the constants
19960    ///
19961    pub unsafe fn ReleaseShortArrayElements(&self, array: jshortArray, elems: *mut jshort, mode: jint) {
19962        unsafe {
19963            #[cfg(feature = "asserts")]
19964            {
19965                self.check_not_critical("ReleaseShortArrayElements");
19966                assert!(!array.is_null(), "ReleaseShortArrayElements jarray must not be null");
19967                assert!(!elems.is_null(), "ReleaseShortArrayElements elems must not be null");
19968                assert!(
19969                    mode == JNI_OK || mode == JNI_COMMIT || mode == JNI_ABORT,
19970                    "ReleaseShortArrayElements mode is invalid {mode}"
19971                );
19972            }
19973
19974            self.jni::<extern "system" fn(JNIEnvVTable, jshortArray, *mut jshort, jint)>(194)(self.vtable, array, elems, mode);
19975        }
19976    }
19977
19978    ///
19979    /// Releases the int array elements back to the jvm
19980    ///
19981    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ReleaseIntArrayElements>
19982    ///
19983    /// # Arguments
19984    /// * `array` - the array
19985    ///     * must not be null
19986    ///     * must be an array
19987    ///     * must not already be garbage collected
19988    /// * `elems`
19989    ///     * must not be null
19990    /// * `mode`
19991    ///     * must be one of the following constants:
19992    ///         * `JNI_OK` - release the array, copy back the contents into the internal buffer if it was a copy
19993    ///         * `JNI_COMMIT` - do not release the array, copy back the contents into the internal buffer if it was a copy
19994    ///         * `JNI_ABORT` - release the array, do not copy back the contents into the internal buffer if it was a copy
19995    ///         * Note: if data was not a copy then `JNI_OK` and `JNI_ABORT` do the same.
19996    ///
19997    ///
19998    /// # Panics
19999    /// if asserts feature is enabled and UB was detected
20000    ///
20001    /// # Safety
20002    ///
20003    /// Current thread must not be detached from JNI.
20004    ///
20005    /// Current thread does not hold a critical reference.
20006    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20007    ///
20008    /// `array` must not be null, must refer to a array and not already be garbage collected.
20009    /// `elems` must be the buffer of the same `array` reference
20010    /// `mode` must be one of the constants
20011    ///
20012    pub unsafe fn ReleaseIntArrayElements(&self, array: jintArray, elems: *mut jint, mode: jint) {
20013        unsafe {
20014            #[cfg(feature = "asserts")]
20015            {
20016                self.check_not_critical("ReleaseIntArrayElements");
20017                assert!(!array.is_null(), "ReleaseIntArrayElements jarray must not be null");
20018                assert!(!elems.is_null(), "ReleaseIntArrayElements elems must not be null");
20019                assert!(mode == JNI_OK || mode == JNI_COMMIT || mode == JNI_ABORT, "ReleaseIntArrayElements mode is invalid {mode}");
20020            }
20021
20022            self.jni::<extern "system" fn(JNIEnvVTable, jintArray, *mut jint, jint)>(195)(self.vtable, array, elems, mode);
20023        }
20024    }
20025
20026    ///
20027    /// Releases the long array elements back to the jvm
20028    ///
20029    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ReleaseLongArrayElements>
20030    ///
20031    /// # Arguments
20032    /// * `array` - the array
20033    ///     * must not be null
20034    ///     * must be an array
20035    ///     * must not already be garbage collected
20036    /// * `elems`
20037    ///     * must not be null
20038    /// * `mode`
20039    ///     * must be one of the following constants:
20040    ///         * `JNI_OK` - release the array, copy back the contents into the internal buffer if it was a copy
20041    ///         * `JNI_COMMIT` - do not release the array, copy back the contents into the internal buffer if it was a copy
20042    ///         * `JNI_ABORT` - release the array, do not copy back the contents into the internal buffer if it was a copy
20043    ///         * Note: if data was not a copy then `JNI_OK` and `JNI_ABORT` do the same.
20044    ///
20045    ///
20046    /// # Panics
20047    /// if asserts feature is enabled and UB was detected
20048    ///
20049    /// # Safety
20050    ///
20051    /// Current thread must not be detached from JNI.
20052    ///
20053    /// Current thread does not hold a critical reference.
20054    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20055    ///
20056    /// `array` must not be null, must refer to a array and not already be garbage collected.
20057    /// `elems` must be the buffer of the same `array` reference
20058    /// `mode` must be one of the constants
20059    ///
20060    pub unsafe fn ReleaseLongArrayElements(&self, array: jlongArray, elems: *mut jlong, mode: jint) {
20061        unsafe {
20062            #[cfg(feature = "asserts")]
20063            {
20064                self.check_not_critical("ReleaseLongArrayElements");
20065                assert!(!array.is_null(), "ReleaseLongArrayElements jarray must not be null");
20066                assert!(!elems.is_null(), "ReleaseLongArrayElements elems must not be null");
20067                assert!(mode == JNI_OK || mode == JNI_COMMIT || mode == JNI_ABORT, "ReleaseLongArrayElements mode is invalid {mode}");
20068            }
20069
20070            self.jni::<extern "system" fn(JNIEnvVTable, jlongArray, *mut jlong, jint)>(196)(self.vtable, array, elems, mode);
20071        }
20072    }
20073
20074    ///
20075    /// Releases the float array elements back to the jvm
20076    ///
20077    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ReleaseFloatArrayElements>
20078    ///
20079    /// # Arguments
20080    /// * `array` - the array
20081    ///     * must not be null
20082    ///     * must be an array
20083    ///     * must not already be garbage collected
20084    /// * `elems`
20085    ///     * must not be null
20086    /// * `mode`
20087    ///     * must be one of the following constants:
20088    ///         * `JNI_OK` - release the array, copy back the contents into the internal buffer if it was a copy
20089    ///         * `JNI_COMMIT` - do not release the array, copy back the contents into the internal buffer if it was a copy
20090    ///         * `JNI_ABORT` - release the array, do not copy back the contents into the internal buffer if it was a copy
20091    ///         * Note: if data was not a copy then `JNI_OK` and `JNI_ABORT` do the same.
20092    ///
20093    ///
20094    /// # Panics
20095    /// if asserts feature is enabled and UB was detected
20096    ///
20097    /// # Safety
20098    ///
20099    /// Current thread must not be detached from JNI.
20100    ///
20101    /// Current thread does not hold a critical reference.
20102    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20103    ///
20104    /// `array` must not be null, must refer to a array and not already be garbage collected.
20105    /// `elems` must be the buffer of the same `array` reference
20106    /// `mode` must be one of the constants
20107    ///
20108    pub unsafe fn ReleaseFloatArrayElements(&self, array: jfloatArray, elems: *mut jfloat, mode: jint) {
20109        unsafe {
20110            #[cfg(feature = "asserts")]
20111            {
20112                self.check_not_critical("ReleaseFloatArrayElements");
20113                assert!(!array.is_null(), "ReleaseFloatArrayElements jarray must not be null");
20114                assert!(!elems.is_null(), "ReleaseFloatArrayElements elems must not be null");
20115                assert!(
20116                    mode == JNI_OK || mode == JNI_COMMIT || mode == JNI_ABORT,
20117                    "ReleaseFloatArrayElements mode is invalid {mode}"
20118                );
20119            }
20120
20121            self.jni::<extern "system" fn(JNIEnvVTable, jfloatArray, *mut jfloat, jint)>(197)(self.vtable, array, elems, mode);
20122        }
20123    }
20124
20125    ///
20126    /// Releases the double array elements back to the jvm
20127    ///
20128    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#ReleaseDoubleArrayElements>
20129    ///
20130    /// # Arguments
20131    /// * `array` - the array
20132    ///     * must not be null
20133    ///     * must be an array
20134    ///     * must not already be garbage collected
20135    /// * `elems`
20136    ///     * must not be null
20137    /// * `mode`
20138    ///     * must be one of the following constants:
20139    ///         * `JNI_OK` - release the array, copy back the contents into the internal buffer if it was a copy
20140    ///         * `JNI_COMMIT` - do not release the array, copy back the contents into the internal buffer if it was a copy
20141    ///         * `JNI_ABORT` - release the array, do not copy back the contents into the internal buffer if it was a copy
20142    ///         * Note: if data was not a copy then `JNI_OK` and `JNI_ABORT` do the same.
20143    ///
20144    ///
20145    /// # Panics
20146    /// if asserts feature is enabled and UB was detected
20147    ///
20148    /// # Safety
20149    ///
20150    /// Current thread must not be detached from JNI.
20151    ///
20152    /// Current thread does not hold a critical reference.
20153    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20154    ///
20155    /// `array` must not be null, must refer to a array and not already be garbage collected.
20156    /// `elems` must be the buffer of the same `array` reference
20157    /// `mode` must be one of the constants
20158    ///
20159    pub unsafe fn ReleaseDoubleArrayElements(&self, array: jdoubleArray, elems: *mut jdouble, mode: jint) {
20160        unsafe {
20161            #[cfg(feature = "asserts")]
20162            {
20163                self.check_not_critical("ReleaseDoubleArrayElements");
20164                assert!(!array.is_null(), "ReleaseDoubleArrayElements jarray must not be null");
20165                assert!(!elems.is_null(), "ReleaseDoubleArrayElements elems must not be null");
20166                assert!(
20167                    mode == JNI_OK || mode == JNI_COMMIT || mode == JNI_ABORT,
20168                    "ReleaseDoubleArrayElements mode is invalid {mode}"
20169                );
20170            }
20171
20172            self.jni::<extern "system" fn(JNIEnvVTable, jdoubleArray, *mut jdouble, jint)>(198)(self.vtable, array, elems, mode);
20173        }
20174    }
20175
20176    ///
20177    /// Copies data from the jbooleanArray `array` starting from the given `start` index into the memory pointed to by `buf`.
20178    ///
20179    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_PrimitiveType_ArrayRegion_routines>
20180    ///
20181    /// # Arguments
20182    /// * `array` - handle to a Java jbooleanArray
20183    /// * `start` - the index of the first element to copy in the Java jbooleanArray
20184    /// * `len` - amount of data to be copied
20185    /// * `buf` - pointer to memory where the data should be copied to
20186    ///
20187    /// # Throws Java Exception:
20188    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the `array`.
20189    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
20190    ///
20191    /// It is JVM implementation specific what is written into `buf` if this function throws an exception.
20192    /// * Data partially written
20193    /// * No data written
20194    ///
20195    /// # Panics
20196    /// if asserts feature is enabled and UB was detected
20197    ///
20198    /// # Safety
20199    /// Current thread must not be detached from JNI.
20200    ///
20201    /// Current thread must not be currently throwing an exception.
20202    ///
20203    /// Current thread does not hold a critical reference.
20204    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20205    ///
20206    /// `array` must be a valid non-null reference to a jbooleanArray.
20207    /// `buf` must be valid non-null pointer to memory with enough capacity to store `len` bytes.
20208    ///
20209    /// # Example
20210    /// ```rust
20211    /// use jni_simple::{*};
20212    ///
20213    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
20214    ///         array: jbooleanArray, chunk_buffer: &mut [bool], chunk_offset: usize) -> bool {
20215    ///     if array.is_null() {
20216    ///         panic!("Java Array is null")
20217    ///     }
20218    ///     env.GetBooleanArrayRegion(array, chunk_offset as jsize, chunk_buffer.len() as jsize, chunk_buffer.as_mut_ptr());
20219    ///     if env.ExceptionCheck() {
20220    ///         //ArrayIndexOutOfBoundsException
20221    ///         env.ExceptionClear();
20222    ///         return false;
20223    ///     }
20224    ///     true
20225    /// }
20226    /// ```
20227    ///
20228    pub unsafe fn GetBooleanArrayRegion(&self, array: jbooleanArray, start: jsize, len: jsize, buf: *mut jboolean) {
20229        unsafe {
20230            #[cfg(feature = "asserts")]
20231            {
20232                self.check_not_critical("GetBooleanArrayRegion");
20233                self.check_no_exception("GetBooleanArrayRegion");
20234                assert!(!array.is_null(), "GetBooleanArrayRegion jarray must not be null");
20235                assert!(!buf.is_null(), "GetBooleanArrayRegion buf must not be null");
20236            }
20237            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, jsize, jsize, *mut jboolean)>(199)(self.vtable, array, start, len, buf);
20238        }
20239    }
20240
20241    ///
20242    /// Copies data from the jbyteArray `array` starting from the given `start` index into the memory pointed to by `buf`.
20243    ///
20244    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_PrimitiveType_ArrayRegion_routines>
20245    ///
20246    /// # Arguments
20247    /// * `array` - handle to a Java jbyteArray
20248    /// * `start` - the index of the first element to copy in the Java jbyteArray
20249    /// * `len` - amount of data to be copied
20250    /// * `buf` - pointer to memory where the data should be copied to
20251    ///
20252    /// # Throws Java Exception:
20253    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the `array`.
20254    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
20255    ///
20256    /// It is JVM implementation specific what is written into `buf` if this function throws an exception.
20257    /// * Data partially written
20258    /// * No data written
20259    ///
20260    /// # Panics
20261    /// if asserts feature is enabled and UB was detected
20262    ///
20263    /// # Safety
20264    /// Current thread must not be detached from JNI.
20265    ///
20266    /// Current thread must not be currently throwing an exception.
20267    ///
20268    /// Current thread does not hold a critical reference.
20269    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20270    ///
20271    /// `array` must be a valid non-null reference to a jbyteArray.
20272    /// `buf` must be valid non-null pointer to memory with enough capacity to store `len` bytes.
20273    ///
20274    /// # Example
20275    /// ```rust
20276    /// use jni_simple::{*};
20277    ///
20278    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
20279    ///         array: jbyteArray, chunk_buffer: &mut [i8], chunk_offset: usize) -> bool {
20280    ///     if array.is_null() {
20281    ///         panic!("Java Array is null")
20282    ///     }
20283    ///
20284    ///     env.GetByteArrayRegion(array, chunk_offset as jsize, chunk_buffer.len() as jsize, chunk_buffer.as_mut_ptr());
20285    ///     if env.ExceptionCheck() {
20286    ///         //ArrayIndexOutOfBoundsException
20287    ///         env.ExceptionClear();
20288    ///         return false;
20289    ///     }
20290    ///     true
20291    /// }
20292    /// ```
20293    ///
20294    pub unsafe fn GetByteArrayRegion(&self, array: jbyteArray, start: jsize, len: jsize, buf: *mut jbyte) {
20295        unsafe {
20296            #[cfg(feature = "asserts")]
20297            {
20298                self.check_not_critical("GetByteArrayRegion");
20299                self.check_no_exception("GetByteArrayRegion");
20300                assert!(!array.is_null(), "GetByteArrayRegion jarray must not be null");
20301                assert!(!buf.is_null(), "GetByteArrayRegion buf must not be null");
20302            }
20303
20304            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, jsize, jsize, *mut jbyte)>(200)(self.vtable, array, start, len, buf);
20305        }
20306    }
20307
20308    ///
20309    /// Copies data from the jbyteArray `array` starting from the given `start` index into the slice `buf`.
20310    ///
20311    /// # Arguments
20312    /// * `array` - handle to a Java jbyteArray.
20313    /// * `start` - the index of the first element to copy in the Java jbyteArray
20314    /// * `buf` - the slice to copy data into
20315    ///
20316    /// # Throws Java Exception:
20317    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
20318    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
20319    ///
20320    /// It is JVM implementation specific what is stored inside buf if this function throws an exception.
20321    /// * Data partially written
20322    /// * No data written
20323    ///
20324    /// # Panics
20325    /// if asserts feature is enabled and UB was detected
20326    ///
20327    /// # Safety
20328    /// Current thread must not be detached from JNI.
20329    ///
20330    /// Current thread must not be currently throwing an exception.
20331    ///
20332    /// Current thread does not hold a critical reference.
20333    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20334    ///
20335    /// `array` must be a valid non-null reference to a jbyteArray.
20336    ///
20337    /// # Example
20338    /// ```rust
20339    /// use jni_simple::{*};
20340    ///
20341    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
20342    ///         array: jbyteArray, chunk_buffer: &mut [jbyte], chunk_offset: usize) -> bool {
20343    ///     if array.is_null() {
20344    ///         panic!("Java Array is null")
20345    ///     }
20346    ///
20347    ///     env.GetByteArrayRegion_into_slice(array, chunk_offset as jsize, chunk_buffer);
20348    ///     if env.ExceptionCheck() {
20349    ///         //ArrayIndexOutOfBoundsException
20350    ///         env.ExceptionClear();
20351    ///         return false;
20352    ///     }
20353    ///     true
20354    /// }
20355    /// ```
20356    ///
20357    pub unsafe fn GetByteArrayRegion_into_slice(&self, array: jbyteArray, start: jsize, buf: &mut [jbyte]) {
20358        unsafe {
20359            self.GetByteArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_mut_ptr());
20360        }
20361    }
20362
20363    ///
20364    /// Copies data from the slice `buf` into the jbyteArray `array` starting at the given `start` index.
20365    ///
20366    /// # Arguments
20367    /// * `array` - handle to a Java jbyteArray.
20368    /// * `start` - the index where the first element should be coped into in the Java jybteArray
20369    /// * `buf` - the slice where data is copied from
20370    ///
20371    /// # Throws Java Exception:
20372    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
20373    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
20374    ///
20375    /// It is JVM implementation specific what is stored inside `array` if this function throws an exception.
20376    /// * Data partially written
20377    /// * No data written
20378    ///
20379    /// # Panics
20380    /// if asserts feature is enabled and UB was detected
20381    ///
20382    /// # Safety
20383    /// Current thread must not be detached from JNI.
20384    ///
20385    /// Current thread must not be currently throwing an exception.
20386    ///
20387    /// Current thread does not hold a critical reference.
20388    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20389    ///
20390    /// `array` must be a valid non-null reference to a jbyteArray.
20391    ///
20392    /// # Example
20393    /// ```rust
20394    /// use jni_simple::{*};
20395    ///
20396    /// unsafe fn copy_chunk_from_rust_to_java(env: JNIEnv,
20397    ///         array: jbyteArray, chunk_buffer: &[jbyte], chunk_offset: usize) -> bool {
20398    ///     if array.is_null() {
20399    ///         panic!("Java Array is null")
20400    ///     }
20401    ///
20402    ///     env.SetByteArrayRegion_from_slice(array, chunk_offset as jsize, chunk_buffer);
20403    ///     if env.ExceptionCheck() {
20404    ///         //ArrayIndexOutOfBoundsException
20405    ///         env.ExceptionClear();
20406    ///         return false;
20407    ///     }
20408    ///     true
20409    /// }
20410    /// ```
20411    ///
20412    pub unsafe fn SetByteArrayRegion_from_slice(&self, array: jbyteArray, start: jsize, buf: &[jbyte]) {
20413        unsafe {
20414            self.SetByteArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_ptr());
20415        }
20416    }
20417
20418    ///
20419    /// Copies data from the slice `buf` into the jbyteArray `array` starting at the given `start` index.
20420    ///
20421    /// # Arguments
20422    /// * `array` - handle to a Java jbyteArray.
20423    /// * `start` - the index where the first element should be coped into in the Java jybteArray
20424    /// * `buf` - the slice where data is copied from
20425    ///
20426    /// # Throws Java Exception:
20427    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
20428    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
20429    ///
20430    /// It is JVM implementation specific what is stored inside `array` if this function throws an exception.
20431    /// * Data partially written
20432    /// * No data written
20433    ///
20434    /// # Panics
20435    /// if asserts feature is enabled and UB was detected
20436    ///
20437    /// # Safety
20438    /// Current thread must not be detached from JNI.
20439    ///
20440    /// Current thread must not be currently throwing an exception.
20441    ///
20442    /// Current thread does not hold a critical reference.
20443    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20444    ///
20445    /// `array` must be a valid non-null reference to a jbyteArray.
20446    ///
20447    /// # Example
20448    /// ```rust
20449    /// use jni_simple::{*};
20450    ///
20451    /// unsafe fn copy_chunk_from_rust_to_java(env: JNIEnv,
20452    ///         array: jbyteArray, chunk_buffer: &[i8], chunk_offset: usize) -> bool {
20453    ///     if array.is_null() {
20454    ///         panic!("Java Array is null")
20455    ///     }
20456    ///
20457    ///     env.SetByteArrayRegion_from_slice(array, chunk_offset as jsize, chunk_buffer);
20458    ///     if env.ExceptionCheck() {
20459    ///         //ArrayIndexOutOfBoundsException
20460    ///         env.ExceptionClear();
20461    ///         return false;
20462    ///     }
20463    ///     true
20464    /// }
20465    /// ```
20466    ///
20467    pub unsafe fn SetBooleanArrayRegion_from_slice(&self, array: jbyteArray, start: jsize, buf: &[jboolean]) {
20468        unsafe {
20469            self.SetBooleanArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_ptr());
20470        }
20471    }
20472
20473    ///
20474    /// Copies data from a Java jbyteArray `array` into a new Vec<i8>
20475    ///
20476    /// # Arguments
20477    /// * `array` - handle to a Java jbyteArray.
20478    /// * `start` - the index of the first element to copy in the Java jbyteArray
20479    /// * `len` - the amount of data that should be copied. If `None` then all remaining elements in the array are copied.
20480    ///
20481    /// If `len` is `Some` and negative or 0 then an empty Vec<i8> is returned.
20482    ///
20483    /// # Returns:
20484    /// a new Vec<i8> that contains the copied data.
20485    ///
20486    ///
20487    /// # Throws Java Exception:
20488    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
20489    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
20490    ///
20491    /// It is JVM implementation specific what is stored inside the returned Vec<i8> if this function throws an exception
20492    /// * Data partially written
20493    /// * No data written
20494    ///
20495    /// It is only guaranteed that this function never returns uninitialized memory.
20496    ///
20497    /// # Panics
20498    /// if asserts feature is enabled and UB was detected
20499    ///
20500    /// # Safety
20501    /// Current thread must not be detached from JNI.
20502    ///
20503    /// Current thread must not be currently throwing an exception.
20504    ///
20505    /// Current thread does not hold a critical reference.
20506    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20507    ///
20508    /// `array` must be a valid non-null reference to a jbyteArray.
20509    ///
20510    /// # Example
20511    /// ```rust
20512    /// use jni_simple::{*};
20513    ///
20514    /// unsafe fn copy_entire_java_array_to_rust(env: JNIEnv, array: jbyteArray) -> Vec<jbyte> {
20515    ///     if array.is_null() {
20516    ///         panic!("Java Array is null")
20517    ///     }
20518    ///     env.GetByteArrayRegion_as_vec(array, 0, None)
20519    /// }
20520    /// ```
20521    ///
20522    pub unsafe fn GetByteArrayRegion_as_vec(&self, array: jbyteArray, start: jsize, len: Option<jsize>) -> Vec<jbyte> {
20523        unsafe {
20524            let len = len.unwrap_or_else(|| self.GetArrayLength(array) - start);
20525            if let Ok(len) = usize::try_from(len) {
20526                let mut data = vec![0i8; len];
20527                self.GetByteArrayRegion_into_slice(array, start, data.as_mut_slice());
20528                return data;
20529            }
20530            Vec::new()
20531        }
20532    }
20533
20534    ///
20535    /// Copies data from the jcharArray `array` starting from the given `start` index into the memory pointed to by `buf`.
20536    ///
20537    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_PrimitiveType_ArrayRegion_routines>
20538    ///
20539    /// # Arguments
20540    /// * `array` - handle to a Java jcharArray
20541    /// * `start` - the index of the first element to copy in the Java jcharArray
20542    /// * `len` - amount of data to be copied
20543    /// * `buf` - pointer to memory where the data should be copied to
20544    ///
20545    /// # Throws Java Exception:
20546    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the `array`.
20547    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
20548    ///
20549    /// It is JVM implementation specific what is written into `buf` if this function throws an exception.
20550    /// * Data partially written
20551    /// * No data written
20552    ///
20553    /// # Panics
20554    /// if asserts feature is enabled and UB was detected
20555    ///
20556    /// # Safety
20557    /// Current thread must not be detached from JNI.
20558    ///
20559    /// Current thread must not be currently throwing an exception.
20560    ///
20561    /// Current thread does not hold a critical reference.
20562    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20563    ///
20564    /// `array` must be a valid non-null reference to a jcharArray.
20565    /// `buf` must be valid non-null pointer to memory with enough capacity and proper alignment to store `len` jchar's.
20566    ///
20567    /// # Example
20568    /// ```rust
20569    /// use jni_simple::{*};
20570    ///
20571    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
20572    ///         array: jcharArray, chunk_buffer: &mut [jchar], chunk_offset: usize) -> bool {
20573    ///     if array.is_null() {
20574    ///         panic!("Java Array is null")
20575    ///     }
20576    ///
20577    ///     env.GetCharArrayRegion(array, chunk_offset as jsize, chunk_buffer.len() as jsize, chunk_buffer.as_mut_ptr());
20578    ///     if env.ExceptionCheck() {
20579    ///         //ArrayIndexOutOfBoundsException
20580    ///         env.ExceptionClear();
20581    ///         return false;
20582    ///     }
20583    ///     true
20584    /// }
20585    /// ```
20586    ///
20587    pub unsafe fn GetCharArrayRegion(&self, array: jcharArray, start: jsize, len: jsize, buf: *mut jchar) {
20588        unsafe {
20589            #[cfg(feature = "asserts")]
20590            {
20591                self.check_not_critical("GetCharArrayRegion");
20592                self.check_no_exception("GetCharArrayRegion");
20593                assert!(!array.is_null(), "GetCharArrayRegion jarray must not be null");
20594                assert!(!buf.is_null(), "GetCharArrayRegion buf must not be null");
20595                assert_eq!(0, buf.align_offset(align_of::<jchar>()), "GetCharArrayRegion buf pointer is not aligned");
20596            }
20597
20598            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, jsize, jsize, *mut jchar)>(201)(self.vtable, array, start, len, buf);
20599        }
20600    }
20601
20602    ///
20603    /// Copies data from the jcharArray `array` starting from the given `start` index into the slice `buf`.
20604    ///
20605    /// # Arguments
20606    /// * `array` - handle to a Java jcharArray.
20607    /// * `start` - the index of the first element to copy in the Java jcharArray
20608    /// * `buf` - the slice to copy data into
20609    ///
20610    /// # Throws Java Exception:
20611    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
20612    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
20613    ///
20614    /// It is JVM implementation specific what is stored inside buf if this function throws an exception.
20615    /// * Data partially written
20616    /// * No data written
20617    ///
20618    /// # Panics
20619    /// if asserts feature is enabled and UB was detected
20620    ///
20621    /// # Safety
20622    /// Current thread must not be detached from JNI.
20623    ///
20624    /// Current thread must not be currently throwing an exception.
20625    ///
20626    /// Current thread does not hold a critical reference.
20627    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20628    ///
20629    /// `array` must be a valid non-null reference to a jcharArray.
20630    ///
20631    /// # Example
20632    /// ```rust
20633    /// use jni_simple::{*};
20634    ///
20635    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
20636    ///         array: jcharArray, chunk_buffer: &mut [jchar], chunk_offset: usize) -> bool {
20637    ///     if array.is_null() {
20638    ///         panic!("Java Array is null")
20639    ///     }
20640    ///
20641    ///     env.GetCharArrayRegion_into_slice(array, chunk_offset as jsize, chunk_buffer);
20642    ///     if env.ExceptionCheck() {
20643    ///         //ArrayIndexOutOfBoundsException
20644    ///         env.ExceptionClear();
20645    ///         return false;
20646    ///     }
20647    ///     true
20648    /// }
20649    /// ```
20650    ///
20651    pub unsafe fn GetCharArrayRegion_into_slice(&self, array: jcharArray, start: jsize, buf: &mut [jchar]) {
20652        unsafe {
20653            self.GetCharArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_mut_ptr());
20654        }
20655    }
20656
20657    ///
20658    /// Copies data from the slice `buf` into the jcharArray `array` starting at the given `start` index.
20659    ///
20660    /// # Arguments
20661    /// * `array` - handle to a Java jcharArray.
20662    /// * `start` - the index where the first element should be coped into in the Java jcharArray
20663    /// * `buf` - the slice where data is copied from
20664    ///
20665    /// # Throws Java Exception:
20666    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
20667    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
20668    ///
20669    /// It is JVM implementation specific what is stored inside `array` if this function throws an exception.
20670    /// * Data partially written
20671    /// * No data written
20672    ///
20673    /// # Panics
20674    /// if asserts feature is enabled and UB was detected
20675    ///
20676    /// # Safety
20677    /// Current thread must not be detached from JNI.
20678    ///
20679    /// Current thread must not be currently throwing an exception.
20680    ///
20681    /// Current thread does not hold a critical reference.
20682    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20683    ///
20684    /// `array` must be a valid non-null reference to a jcharArray.
20685    ///
20686    /// # Example
20687    /// ```rust
20688    /// use jni_simple::{*};
20689    ///
20690    /// unsafe fn copy_chunk_from_rust_to_java(env: JNIEnv,
20691    ///         array: jcharArray, chunk_buffer: &[u16], chunk_offset: usize) -> bool {
20692    ///     if array.is_null() {
20693    ///         panic!("Java Array is null")
20694    ///     }
20695    ///
20696    ///     env.SetCharArrayRegion_from_slice(array, chunk_offset as jsize, chunk_buffer);
20697    ///     if env.ExceptionCheck() {
20698    ///         //ArrayIndexOutOfBoundsException
20699    ///         env.ExceptionClear();
20700    ///         return false;
20701    ///     }
20702    ///     true
20703    /// }
20704    /// ```
20705    ///
20706    pub unsafe fn SetCharArrayRegion_from_slice(&self, array: jcharArray, start: jsize, buf: &[jchar]) {
20707        unsafe {
20708            self.SetCharArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_ptr());
20709        }
20710    }
20711
20712    ///
20713    /// Copies data from a Java jcharArray `array` into a new Vec<u16>
20714    ///
20715    /// # Arguments
20716    /// * `array` - handle to a Java jcharArray.
20717    /// * `start` - the index of the first element to copy in the Java jcharArray
20718    /// * `len` - the amount of data that should be copied. If `None` then all remaining elements in the array are copied.
20719    ///
20720    /// If `len` is `Some` and negative or 0 then an empty Vec<u16> is returned.
20721    ///
20722    /// # Returns:
20723    /// a new Vec<u16> that contains the copied data.
20724    ///
20725    ///
20726    /// # Throws Java Exception:
20727    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
20728    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
20729    ///
20730    /// It is JVM implementation specific what is stored inside the returned Vec<u16> if this function throws an exception
20731    /// * Data partially written
20732    /// * No data written
20733    ///
20734    /// It is only guaranteed that this function never returns uninitialized memory.
20735    ///
20736    /// # Panics
20737    /// if asserts feature is enabled and UB was detected
20738    ///
20739    /// # Safety
20740    /// Current thread must not be detached from JNI.
20741    ///
20742    /// Current thread must not be currently throwing an exception.
20743    ///
20744    /// Current thread does not hold a critical reference.
20745    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20746    ///
20747    /// `array` must be a valid non-null reference to a jbyteArray.
20748    ///
20749    /// # Example
20750    /// ```rust
20751    /// use jni_simple::{*};
20752    ///
20753    /// unsafe fn copy_entire_java_array_to_rust(env: JNIEnv, array: jcharArray) -> Vec<jchar> {
20754    ///     if array.is_null() {
20755    ///         panic!("Java Array is null")
20756    ///     }
20757    ///     env.GetCharArrayRegion_as_vec(array, 0, None)
20758    /// }
20759    /// ```
20760    ///
20761    pub unsafe fn GetCharArrayRegion_as_vec(&self, array: jcharArray, start: jsize, len: Option<jsize>) -> Vec<jchar> {
20762        unsafe {
20763            let len = len.unwrap_or_else(|| self.GetArrayLength(array) - start);
20764            if let Ok(len) = usize::try_from(len) {
20765                let mut data = vec![0u16; len];
20766                self.GetCharArrayRegion_into_slice(array, start, data.as_mut_slice());
20767                return data;
20768            }
20769            Vec::new()
20770        }
20771    }
20772
20773    ///
20774    /// Copies data from the jshortArray `array` starting from the given `start` index into the memory pointed to by `buf`.
20775    ///
20776    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_PrimitiveType_ArrayRegion_routines>
20777    ///
20778    /// # Arguments
20779    /// * `array` - handle to a Java jshortArray
20780    /// * `start` - the index of the first element to copy in the Java jshortArray
20781    /// * `len` - amount of data to be copied
20782    /// * `buf` - pointer to memory where the data should be copied to
20783    ///
20784    /// # Throws Java Exception:
20785    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the `array`.
20786    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
20787    ///
20788    /// It is JVM implementation specific what is written into `buf` if this function throws an exception.
20789    /// * Data partially written
20790    /// * No data written
20791    ///
20792    /// # Panics
20793    /// if asserts feature is enabled and UB was detected
20794    ///
20795    /// # Safety
20796    /// Current thread must not be detached from JNI.
20797    ///
20798    /// Current thread must not be currently throwing an exception.
20799    ///
20800    /// Current thread does not hold a critical reference.
20801    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20802    ///
20803    /// `array` must be a valid non-null reference to a jshortArray.
20804    /// `buf` must be valid non-null pointer to memory with enough capacity and proper alignment to store `len` jshort's.
20805    ///
20806    /// # Example
20807    /// ```rust
20808    /// use jni_simple::{*};
20809    ///
20810    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
20811    ///         array: jshortArray, chunk_buffer: &mut [jshort], chunk_offset: usize) -> bool {
20812    ///     if array.is_null() {
20813    ///         panic!("Java Array is null")
20814    ///     }
20815    ///
20816    ///     env.GetShortArrayRegion(array, chunk_offset as jsize, chunk_buffer.len() as jsize, chunk_buffer.as_mut_ptr());
20817    ///     if env.ExceptionCheck() {
20818    ///         //ArrayIndexOutOfBoundsException
20819    ///         env.ExceptionClear();
20820    ///         return false;
20821    ///     }
20822    ///     true
20823    /// }
20824    /// ```
20825    ///
20826    pub unsafe fn GetShortArrayRegion(&self, array: jshortArray, start: jsize, len: jsize, buf: *mut jshort) {
20827        unsafe {
20828            #[cfg(feature = "asserts")]
20829            {
20830                self.check_not_critical("GetShortArrayRegion");
20831                self.check_no_exception("GetShortArrayRegion");
20832                assert!(!array.is_null(), "GetShortArrayRegion jarray must not be null");
20833                assert!(!buf.is_null(), "GetShortArrayRegion buf must not be null");
20834                assert_eq!(0, buf.align_offset(align_of::<jshort>()), "GetShortArrayRegion buf pointer is not aligned");
20835            }
20836
20837            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, jsize, jsize, *mut jshort)>(202)(self.vtable, array, start, len, buf);
20838        }
20839    }
20840
20841    ///
20842    /// Copies data from the jshortArray `array` starting from the given `start` index into the slice `buf`.
20843    ///
20844    /// # Arguments
20845    /// * `array` - handle to a Java jshortArray.
20846    /// * `start` - the index of the first element to copy in the Java jshortArray
20847    /// * `buf` - the slice to copy data into
20848    ///
20849    /// # Throws Java Exception:
20850    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
20851    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
20852    ///
20853    /// It is JVM implementation specific what is stored inside buf if this function throws an exception.
20854    /// * Data partially written
20855    /// * No data written
20856    ///
20857    /// # Panics
20858    /// if asserts feature is enabled and UB was detected
20859    ///
20860    /// # Safety
20861    /// Current thread must not be detached from JNI.
20862    ///
20863    /// Current thread must not be currently throwing an exception.
20864    ///
20865    /// Current thread does not hold a critical reference.
20866    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20867    ///
20868    /// `array` must be a valid non-null reference to a jshortArray.
20869    ///
20870    /// # Example
20871    /// ```rust
20872    /// use jni_simple::{*};
20873    ///
20874    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
20875    ///         array: jshortArray, chunk_buffer: &mut [jshort], chunk_offset: usize) -> bool {
20876    ///     if array.is_null() {
20877    ///         panic!("Java Array is null")
20878    ///     }
20879    ///
20880    ///     env.GetShortArrayRegion_into_slice(array, chunk_offset as jsize, chunk_buffer);
20881    ///     if env.ExceptionCheck() {
20882    ///         //ArrayIndexOutOfBoundsException
20883    ///         env.ExceptionClear();
20884    ///         return false;
20885    ///     }
20886    ///     true
20887    /// }
20888    /// ```
20889    ///
20890    pub unsafe fn GetShortArrayRegion_into_slice(&self, array: jshortArray, start: jsize, buf: &mut [jshort]) {
20891        unsafe {
20892            self.GetShortArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_mut_ptr());
20893        }
20894    }
20895
20896    ///
20897    /// Copies data from the slice `buf` into the jshortArray `array` starting at the given `start` index.
20898    ///
20899    /// # Arguments
20900    /// * `array` - handle to a Java jshortArray.
20901    /// * `start` - the index where the first element should be coped into in the Java jshortArray
20902    /// * `buf` - the slice where data is copied from
20903    ///
20904    /// # Throws Java Exception:
20905    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
20906    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
20907    ///
20908    /// It is JVM implementation specific what is stored inside `array` if this function throws an exception.
20909    /// * Data partially written
20910    /// * No data written
20911    ///
20912    /// # Panics
20913    /// if asserts feature is enabled and UB was detected
20914    ///
20915    /// # Safety
20916    /// Current thread must not be detached from JNI.
20917    ///
20918    /// Current thread must not be currently throwing an exception.
20919    ///
20920    /// Current thread does not hold a critical reference.
20921    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20922    ///
20923    /// `array` must be a valid non-null reference to a jshortArray.
20924    ///
20925    /// # Example
20926    /// ```rust
20927    /// use jni_simple::{*};
20928    ///
20929    /// unsafe fn copy_chunk_from_rust_to_java(env: JNIEnv,
20930    ///         array: jshortArray, chunk_buffer: &[jshort], chunk_offset: usize) -> bool {
20931    ///     if array.is_null() {
20932    ///         panic!("Java Array is null")
20933    ///     }
20934    ///
20935    ///     env.SetShortArrayRegion_from_slice(array, chunk_offset as jsize, chunk_buffer);
20936    ///     if env.ExceptionCheck() {
20937    ///         //ArrayIndexOutOfBoundsException
20938    ///         env.ExceptionClear();
20939    ///         return false;
20940    ///     }
20941    ///     true
20942    /// }
20943    /// ```
20944    ///
20945    pub unsafe fn SetShortArrayRegion_from_slice(&self, array: jshortArray, start: jsize, buf: &[jshort]) {
20946        unsafe {
20947            self.SetShortArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_ptr());
20948        }
20949    }
20950
20951    ///
20952    /// Copies data from a Java jshortArray `array` into a new Vec<i16>
20953    ///
20954    /// # Arguments
20955    /// * `array` - handle to a Java jshortArray.
20956    /// * `start` - the index of the first element to copy in the Java jshortArray
20957    /// * `len` - the amount of data that should be copied. If `None` then all remaining elements in the array are copied.
20958    ///
20959    /// If `len` is `Some` and negative or 0 then an empty Vec<i16> is returned.
20960    ///
20961    /// # Returns:
20962    /// a new Vec<i16> that contains the copied data.
20963    ///
20964    ///
20965    /// # Throws Java Exception:
20966    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
20967    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
20968    ///
20969    /// It is JVM implementation specific what is stored inside the returned Vec<i16> if this function throws an exception
20970    /// * Data partially written
20971    /// * No data written
20972    ///
20973    /// It is only guaranteed that this function never returns uninitialized memory.
20974    ///
20975    /// # Panics
20976    /// if asserts feature is enabled and UB was detected
20977    ///
20978    /// # Safety
20979    /// Current thread must not be detached from JNI.
20980    ///
20981    /// Current thread must not be currently throwing an exception.
20982    ///
20983    /// Current thread does not hold a critical reference.
20984    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
20985    ///
20986    /// `array` must be a valid non-null reference to a jshortArray.
20987    ///
20988    /// # Example
20989    /// ```rust
20990    /// use jni_simple::{*};
20991    ///
20992    /// unsafe fn copy_entire_java_array_to_rust(env: JNIEnv, array: jshortArray) -> Vec<jshort> {
20993    ///     if array.is_null() {
20994    ///         panic!("Java Array is null")
20995    ///     }
20996    ///     env.GetShortArrayRegion_as_vec(array, 0, None)
20997    /// }
20998    /// ```
20999    ///
21000    pub unsafe fn GetShortArrayRegion_as_vec(&self, array: jshortArray, start: jsize, len: Option<jsize>) -> Vec<jshort> {
21001        unsafe {
21002            let len = len.unwrap_or_else(|| self.GetArrayLength(array) - start);
21003            if let Ok(len) = usize::try_from(len) {
21004                let mut data = vec![0i16; len];
21005                self.GetShortArrayRegion_into_slice(array, start, data.as_mut_slice());
21006                return data;
21007            }
21008            Vec::new()
21009        }
21010    }
21011
21012    ///
21013    /// Copies data from the jintArray `array` starting from the given `start` index into the memory pointed to by `buf`.
21014    ///
21015    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_PrimitiveType_ArrayRegion_routines>
21016    ///
21017    /// # Arguments
21018    /// * `array` - handle to a Java jintArray
21019    /// * `start` - the index of the first element to copy in the Java jintArray
21020    /// * `len` - amount of data to be copied
21021    /// * `buf` - pointer to memory where the data should be copied to
21022    ///
21023    /// # Throws Java Exception:
21024    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the `array`.
21025    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21026    ///
21027    /// It is JVM implementation specific what is written into `buf` if this function throws an exception.
21028    /// * Data partially written
21029    /// * No data written
21030    ///
21031    /// # Panics
21032    /// if asserts feature is enabled and UB was detected
21033    ///
21034    /// # Safety
21035    /// Current thread must not be detached from JNI.
21036    ///
21037    /// Current thread must not be currently throwing an exception.
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 be a valid non-null reference to a jintArray.
21043    /// `buf` must be valid non-null pointer to memory with enough capacity and proper alignment to store `len` jint's.
21044    ///
21045    /// # Example
21046    /// ```rust
21047    /// use jni_simple::{*};
21048    ///
21049    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
21050    ///         array: jintArray, chunk_buffer: &mut [jint], chunk_offset: usize) -> bool {
21051    ///     if array.is_null() {
21052    ///         panic!("Java Array is null")
21053    ///     }
21054    ///
21055    ///     env.GetIntArrayRegion(array, chunk_offset as jsize, chunk_buffer.len() as jsize, chunk_buffer.as_mut_ptr());
21056    ///     if env.ExceptionCheck() {
21057    ///         //ArrayIndexOutOfBoundsException
21058    ///         env.ExceptionClear();
21059    ///         return false;
21060    ///     }
21061    ///     true
21062    /// }
21063    /// ```
21064    ///
21065    pub unsafe fn GetIntArrayRegion(&self, array: jintArray, start: jsize, len: jsize, buf: *mut jint) {
21066        unsafe {
21067            #[cfg(feature = "asserts")]
21068            {
21069                self.check_not_critical("GetIntArrayRegion");
21070                self.check_no_exception("GetIntArrayRegion");
21071                assert!(!array.is_null(), "GetIntArrayRegion jarray must not be null");
21072                assert!(!buf.is_null(), "GetIntArrayRegion buf must not be null");
21073                assert_eq!(0, buf.align_offset(align_of::<jint>()), "GetIntArrayRegion buf pointer is not aligned");
21074            }
21075
21076            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, jsize, jsize, *mut jint)>(203)(self.vtable, array, start, len, buf);
21077        }
21078    }
21079
21080    ///
21081    /// Copies data from the jintArray `array` starting from the given `start` index into the slice `buf`.
21082    ///
21083    /// # Arguments
21084    /// * `array` - handle to a Java jintArray.
21085    /// * `start` - the index of the first element to copy in the Java jintArray
21086    /// * `buf` - the slice to copy data into
21087    ///
21088    /// # Throws Java Exception:
21089    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
21090    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21091    ///
21092    /// It is JVM implementation specific what is stored inside buf if this function throws an exception.
21093    /// * Data partially written
21094    /// * No data written
21095    ///
21096    /// # Panics
21097    /// if asserts feature is enabled and UB was detected
21098    ///
21099    /// # Safety
21100    /// Current thread must not be detached from JNI.
21101    ///
21102    /// Current thread must not be currently throwing an exception.
21103    ///
21104    /// Current thread does not hold a critical reference.
21105    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21106    ///
21107    /// `array` must be a valid non-null reference to a jintArray.
21108    ///
21109    /// # Example
21110    /// ```rust
21111    /// use jni_simple::{*};
21112    ///
21113    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
21114    ///         array: jintArray, chunk_buffer: &mut [jint], chunk_offset: usize) -> bool {
21115    ///     if array.is_null() {
21116    ///         panic!("Java Array is null")
21117    ///     }
21118    ///
21119    ///     env.GetIntArrayRegion_into_slice(array, chunk_offset as jsize, chunk_buffer);
21120    ///     if env.ExceptionCheck() {
21121    ///         //ArrayIndexOutOfBoundsException
21122    ///         env.ExceptionClear();
21123    ///         return false;
21124    ///     }
21125    ///     true
21126    /// }
21127    /// ```
21128    ///
21129    pub unsafe fn GetIntArrayRegion_into_slice(&self, array: jshortArray, start: jsize, buf: &mut [jint]) {
21130        unsafe {
21131            self.GetIntArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_mut_ptr());
21132        }
21133    }
21134
21135    ///
21136    /// Copies data from the slice `buf` into the jintArray `array` starting at the given `start` index.
21137    ///
21138    /// # Arguments
21139    /// * `array` - handle to a Java jintArray.
21140    /// * `start` - the index where the first element should be coped into in the Java jintArray
21141    /// * `buf` - the slice where data is copied from
21142    ///
21143    /// # Throws Java Exception:
21144    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
21145    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21146    ///
21147    /// It is JVM implementation specific what is stored inside `array` if this function throws an exception.
21148    /// * Data partially written
21149    /// * No data written
21150    ///
21151    /// # Panics
21152    /// if asserts feature is enabled and UB was detected
21153    ///
21154    /// # Safety
21155    /// Current thread must not be detached from JNI.
21156    ///
21157    /// Current thread must not be currently throwing an exception.
21158    ///
21159    /// Current thread does not hold a critical reference.
21160    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21161    ///
21162    /// `array` must be a valid non-null reference to a jintArray.
21163    ///
21164    /// # Example
21165    /// ```rust
21166    /// use jni_simple::{*};
21167    ///
21168    /// unsafe fn copy_chunk_from_rust_to_java(env: JNIEnv,
21169    ///         array: jintArray, chunk_buffer: &[jint], chunk_offset: usize) -> bool {
21170    ///     if array.is_null() {
21171    ///         panic!("Java Array is null")
21172    ///     }
21173    ///
21174    ///     env.SetIntArrayRegion_from_slice(array, chunk_offset as jsize, chunk_buffer);
21175    ///     if env.ExceptionCheck() {
21176    ///         //ArrayIndexOutOfBoundsException
21177    ///         env.ExceptionClear();
21178    ///         return false;
21179    ///     }
21180    ///     true
21181    /// }
21182    /// ```
21183    ///
21184    pub unsafe fn SetIntArrayRegion_from_slice(&self, array: jintArray, start: jsize, buf: &[jint]) {
21185        unsafe {
21186            self.SetIntArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_ptr());
21187        }
21188    }
21189
21190    ///
21191    /// Copies data from a Java jintArray `array` into a new Vec<i32>
21192    ///
21193    /// # Arguments
21194    /// * `array` - handle to a Java jintArray.
21195    /// * `start` - the index of the first element to copy in the Java jintArray
21196    /// * `len` - the amount of data that should be copied. If `None` then all remaining elements in the array are copied.
21197    ///
21198    /// If `len` is `Some` and negative or 0 then an empty Vec<i16> is returned.
21199    ///
21200    /// # Returns:
21201    /// a new Vec<i32> that contains the copied data.
21202    ///
21203    ///
21204    /// # Throws Java Exception:
21205    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
21206    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
21207    ///
21208    /// It is JVM implementation specific what is stored inside the returned Vec<i32> if this function throws an exception
21209    /// * Data partially written
21210    /// * No data written
21211    ///
21212    /// It is only guaranteed that this function never returns uninitialized memory.
21213    ///
21214    /// # Panics
21215    /// if asserts feature is enabled and UB was detected
21216    ///
21217    /// # Safety
21218    /// Current thread must not be detached from JNI.
21219    ///
21220    /// Current thread must not be currently throwing an exception.
21221    ///
21222    /// Current thread does not hold a critical reference.
21223    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21224    ///
21225    /// `array` must be a valid non-null reference to a jintArray.
21226    ///
21227    /// # Example
21228    /// ```rust
21229    /// use jni_simple::{*};
21230    ///
21231    /// unsafe fn copy_entire_java_array_to_rust(env: JNIEnv, array: jintArray) -> Vec<jint> {
21232    ///     if array.is_null() {
21233    ///         panic!("Java Array is null")
21234    ///     }
21235    ///     env.GetIntArrayRegion_as_vec(array, 0, None)
21236    /// }
21237    /// ```
21238    ///
21239    pub unsafe fn GetIntArrayRegion_as_vec(&self, array: jintArray, start: jsize, len: Option<jsize>) -> Vec<jint> {
21240        unsafe {
21241            let len = len.unwrap_or_else(|| self.GetArrayLength(array) - start);
21242            if let Ok(len) = usize::try_from(len) {
21243                let mut data = vec![0i32; len];
21244                self.GetIntArrayRegion_into_slice(array, start, data.as_mut_slice());
21245                return data;
21246            }
21247            Vec::new()
21248        }
21249    }
21250
21251    ///
21252    /// Copies data from the jlongArray `array` starting from the given `start` index into the memory pointed to by `buf`.
21253    ///
21254    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_PrimitiveType_ArrayRegion_routines>
21255    ///
21256    /// # Arguments
21257    /// * `array` - handle to a Java jlongArray
21258    /// * `start` - the index of the first element to copy in the Java jlongArray
21259    /// * `len` - amount of data to be copied
21260    /// * `buf` - pointer to memory where the data should be copied to
21261    ///
21262    /// # Throws Java Exception:
21263    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the `array`.
21264    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21265    ///
21266    /// It is JVM implementation specific what is written into `buf` if this function throws an exception.
21267    /// * Data partially written
21268    /// * No data written
21269    ///
21270    /// # Panics
21271    /// if asserts feature is enabled and UB was detected
21272    ///
21273    /// # Safety
21274    /// Current thread must not be detached from JNI.
21275    ///
21276    /// Current thread must not be currently throwing an exception.
21277    ///
21278    /// Current thread does not hold a critical reference.
21279    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21280    ///
21281    /// `array` must be a valid non-null reference to a jlongArray.
21282    /// `buf` must be valid non-null pointer to memory with enough capacity and proper alignment to store `len` jlong's.
21283    ///
21284    /// # Example
21285    /// ```rust
21286    /// use jni_simple::{*};
21287    ///
21288    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
21289    ///         array: jlongArray, chunk_buffer: &mut [jlong], chunk_offset: usize) -> bool {
21290    ///     if array.is_null() {
21291    ///         panic!("Java Array is null")
21292    ///     }
21293    ///
21294    ///     env.GetLongArrayRegion(array, chunk_offset as jsize, chunk_buffer.len() as jsize, chunk_buffer.as_mut_ptr());
21295    ///     if env.ExceptionCheck() {
21296    ///         //ArrayIndexOutOfBoundsException
21297    ///         env.ExceptionClear();
21298    ///         return false;
21299    ///     }
21300    ///     true
21301    /// }
21302    /// ```
21303    ///
21304    pub unsafe fn GetLongArrayRegion(&self, array: jlongArray, start: jsize, len: jsize, buf: *mut jlong) {
21305        unsafe {
21306            #[cfg(feature = "asserts")]
21307            {
21308                self.check_not_critical("GetLongArrayRegion");
21309                self.check_no_exception("GetLongArrayRegion");
21310                assert!(!array.is_null(), "GetLongArrayRegion jarray must not be null");
21311                assert!(!buf.is_null(), "GetLongArrayRegion buf must not be null");
21312                assert_eq!(0, buf.align_offset(align_of::<jlong>()), "GetLongArrayRegion buf pointer is not aligned");
21313            }
21314
21315            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, jsize, jsize, *mut jlong)>(204)(self.vtable, array, start, len, buf);
21316        }
21317    }
21318
21319    ///
21320    /// Copies data from the jlongArray `array` starting from the given `start` index into the slice `buf`.
21321    ///
21322    /// # Arguments
21323    /// * `array` - handle to a Java jlongArray.
21324    /// * `start` - the index of the first element to copy in the Java jlongArray
21325    /// * `buf` - the slice to copy data into
21326    ///
21327    /// # Throws Java Exception:
21328    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
21329    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21330    ///
21331    /// It is JVM implementation specific what is stored inside buf if this function throws an exception.
21332    /// * Data partially written
21333    /// * No data written
21334    ///
21335    /// # Panics
21336    /// if asserts feature is enabled and UB was detected
21337    ///
21338    /// # Safety
21339    /// Current thread must not be detached from JNI.
21340    ///
21341    /// Current thread must not be currently throwing an exception.
21342    ///
21343    /// Current thread does not hold a critical reference.
21344    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21345    ///
21346    /// `array` must be a valid non-null reference to a jlongArray.
21347    ///
21348    /// # Example
21349    /// ```rust
21350    /// use jni_simple::{*};
21351    ///
21352    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
21353    ///         array: jlongArray, chunk_buffer: &mut [jlong], chunk_offset: usize) -> bool {
21354    ///     if array.is_null() {
21355    ///         panic!("Java Array is null")
21356    ///     }
21357    ///
21358    ///     env.GetLongArrayRegion_into_slice(array, chunk_offset as jsize, chunk_buffer);
21359    ///     if env.ExceptionCheck() {
21360    ///         //ArrayIndexOutOfBoundsException
21361    ///         env.ExceptionClear();
21362    ///         return false;
21363    ///     }
21364    ///     true
21365    /// }
21366    /// ```
21367    ///
21368    pub unsafe fn GetLongArrayRegion_into_slice(&self, array: jlongArray, start: jsize, buf: &mut [i64]) {
21369        unsafe {
21370            self.GetLongArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_mut_ptr());
21371        }
21372    }
21373
21374    ///
21375    /// Copies data from the slice `buf` into the jlongArray `array` starting at the given `start` index.
21376    ///
21377    /// # Arguments
21378    /// * `array` - handle to a Java jlongArray.
21379    /// * `start` - the index where the first element should be coped into in the Java jlongArray
21380    /// * `buf` - the slice where data is copied from
21381    ///
21382    /// # Throws Java Exception:
21383    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
21384    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21385    ///
21386    /// It is JVM implementation specific what is stored inside `array` if this function throws an exception.
21387    /// * Data partially written
21388    /// * No data written
21389    ///
21390    /// # Panics
21391    /// if asserts feature is enabled and UB was detected
21392    ///
21393    /// # Safety
21394    /// Current thread must not be detached from JNI.
21395    ///
21396    /// Current thread must not be currently throwing an exception.
21397    ///
21398    /// Current thread does not hold a critical reference.
21399    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21400    ///
21401    /// `array` must be a valid non-null reference to a jlongArray.
21402    ///
21403    /// # Example
21404    /// ```rust
21405    /// use jni_simple::{*};
21406    ///
21407    /// unsafe fn copy_chunk_from_rust_to_java(env: JNIEnv,
21408    ///         array: jlongArray, chunk_buffer: &[jlong], chunk_offset: usize) -> bool {
21409    ///     if array.is_null() {
21410    ///         panic!("Java Array is null")
21411    ///     }
21412    ///
21413    ///     env.SetLongArrayRegion_from_slice(array, chunk_offset as jsize, chunk_buffer);
21414    ///     if env.ExceptionCheck() {
21415    ///         //ArrayIndexOutOfBoundsException
21416    ///         env.ExceptionClear();
21417    ///         return false;
21418    ///     }
21419    ///     true
21420    /// }
21421    /// ```
21422    ///
21423    pub unsafe fn SetLongArrayRegion_from_slice(&self, array: jlongArray, start: jsize, buf: &[jlong]) {
21424        unsafe {
21425            self.SetLongArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_ptr());
21426        }
21427    }
21428
21429    ///
21430    /// Copies data from a Java jlongArray `array` into a new Vec<jlong>
21431    ///
21432    /// # Arguments
21433    /// * `array` - handle to a Java jlongArray.
21434    /// * `start` - the index of the first element to copy in the Java jlongArray
21435    /// * `len` - the amount of data that should be copied. If `None` then all remaining elements in the array are copied.
21436    ///
21437    /// If `len` is `Some` and negative or 0 then an empty Vec<i64> is returned.
21438    ///
21439    /// # Returns:
21440    /// a new Vec<i64> that contains the copied data.
21441    ///
21442    ///
21443    /// # Throws Java Exception:
21444    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
21445    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
21446    ///
21447    /// It is JVM implementation specific what is stored inside the returned Vec<i64> if this function throws an exception
21448    /// * Data partially written
21449    /// * No data written
21450    ///
21451    /// It is only guaranteed that this function never returns uninitialized memory.
21452    ///
21453    /// # Panics
21454    /// if asserts feature is enabled and UB was detected
21455    ///
21456    /// # Safety
21457    /// Current thread must not be detached from JNI.
21458    ///
21459    /// Current thread must not be currently throwing an exception.
21460    ///
21461    /// Current thread does not hold a critical reference.
21462    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21463    ///
21464    /// `array` must be a valid non-null reference to a jlongArray.
21465    ///
21466    /// # Example
21467    /// ```rust
21468    /// use jni_simple::{*};
21469    ///
21470    /// unsafe fn copy_entire_java_array_to_rust(env: JNIEnv, array: jlongArray) -> Vec<jlong> {
21471    ///     if array.is_null() {
21472    ///         panic!("Java Array is null")
21473    ///     }
21474    ///     env.GetLongArrayRegion_as_vec(array, 0, None)
21475    /// }
21476    /// ```
21477    ///
21478    pub unsafe fn GetLongArrayRegion_as_vec(&self, array: jlongArray, start: jsize, len: Option<jsize>) -> Vec<jlong> {
21479        unsafe {
21480            let len = len.unwrap_or_else(|| self.GetArrayLength(array) - start);
21481            if let Ok(len) = usize::try_from(len) {
21482                let mut data = vec![0i64; len];
21483                self.GetLongArrayRegion_into_slice(array, start, data.as_mut_slice());
21484                return data;
21485            }
21486            Vec::new()
21487        }
21488    }
21489
21490    ///
21491    /// Copies data from the jfloatArray `array` starting from the given `start` index into the memory pointed to by `buf`.
21492    ///
21493    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_PrimitiveType_ArrayRegion_routines>
21494    ///
21495    /// # Arguments
21496    /// * `array` - handle to a Java jfloatArray
21497    /// * `start` - the index of the first element to copy in the Java jfloatArray
21498    /// * `len` - amount of data to be copied
21499    /// * `buf` - pointer to memory where the data should be copied to
21500    ///
21501    /// # Throws Java Exception:
21502    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the `array`.
21503    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21504    ///
21505    /// It is JVM implementation specific what is written into `buf` if this function throws an exception.
21506    /// * Data partially written
21507    /// * No data written
21508    ///
21509    /// # Panics
21510    /// if asserts feature is enabled and UB was detected
21511    ///
21512    /// # Safety
21513    /// Current thread must not be detached from JNI.
21514    ///
21515    /// Current thread must not be currently throwing an exception.
21516    ///
21517    /// Current thread does not hold a critical reference.
21518    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21519    ///
21520    /// `array` must be a valid non-null reference to a jfloatArray.
21521    /// `buf` must be valid non-null pointer to memory with enough capacity and proper alignment to store `len` jfloat's.
21522    ///
21523    /// # Example
21524    /// ```rust
21525    /// use jni_simple::{*};
21526    ///
21527    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
21528    ///         array: jfloatArray, chunk_buffer: &mut [jfloat], chunk_offset: usize) -> bool {
21529    ///     if array.is_null() {
21530    ///         panic!("Java Array is null")
21531    ///     }
21532    ///
21533    ///     env.GetFloatArrayRegion(array, chunk_offset as jsize, chunk_buffer.len() as jsize, chunk_buffer.as_mut_ptr());
21534    ///     if env.ExceptionCheck() {
21535    ///         //ArrayIndexOutOfBoundsException
21536    ///         env.ExceptionClear();
21537    ///         return false;
21538    ///     }
21539    ///     true
21540    /// }
21541    /// ```
21542    ///
21543    pub unsafe fn GetFloatArrayRegion(&self, array: jfloatArray, start: jsize, len: jsize, buf: *mut jfloat) {
21544        unsafe {
21545            #[cfg(feature = "asserts")]
21546            {
21547                self.check_not_critical("GetFloatArrayRegion");
21548                self.check_no_exception("GetFloatArrayRegion");
21549                assert!(!array.is_null(), "GetFloatArrayRegion jarray must not be null");
21550                assert!(!buf.is_null(), "GetFloatArrayRegion buf must not be null");
21551                assert_eq!(0, buf.align_offset(align_of::<jfloat>()), "GetFloatArrayRegion buf pointer is not aligned");
21552            }
21553
21554            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, jsize, jsize, *mut jfloat)>(205)(self.vtable, array, start, len, buf);
21555        }
21556    }
21557
21558    ///
21559    /// Copies data from the jfloatArray `array` starting from the given `start` index into the slice `buf`.
21560    ///
21561    /// # Arguments
21562    /// * `array` - handle to a Java jfloatArray.
21563    /// * `start` - the index of the first element to copy in the Java jfloatArray
21564    /// * `buf` - the slice to copy data into
21565    ///
21566    /// # Throws Java Exception:
21567    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
21568    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21569    ///
21570    /// It is JVM implementation specific what is stored inside buf if this function throws an exception.
21571    /// * Data partially written
21572    /// * No data written
21573    ///
21574    /// # Panics
21575    /// if asserts feature is enabled and UB was detected
21576    ///
21577    /// # Safety
21578    /// Current thread must not be detached from JNI.
21579    ///
21580    /// Current thread must not be currently throwing an exception.
21581    ///
21582    /// Current thread does not hold a critical reference.
21583    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21584    ///
21585    /// `array` must be a valid non-null reference to a jfloatArray.
21586    ///
21587    /// # Example
21588    /// ```rust
21589    /// use jni_simple::{*};
21590    ///
21591    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
21592    ///         array: jfloatArray, chunk_buffer: &mut [jfloat], chunk_offset: usize) -> bool {
21593    ///     if array.is_null() {
21594    ///         panic!("Java Array is null")
21595    ///     }
21596    ///
21597    ///     env.GetFloatArrayRegion_into_slice(array, chunk_offset as jsize, chunk_buffer);
21598    ///     if env.ExceptionCheck() {
21599    ///         //ArrayIndexOutOfBoundsException
21600    ///         env.ExceptionClear();
21601    ///         return false;
21602    ///     }
21603    ///     true
21604    /// }
21605    /// ```
21606    ///
21607    pub unsafe fn GetFloatArrayRegion_into_slice(&self, array: jfloatArray, start: jsize, buf: &mut [jfloat]) {
21608        unsafe {
21609            self.GetFloatArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_mut_ptr());
21610        }
21611    }
21612
21613    ///
21614    /// Copies data from the slice `buf` into the jfloatArray `array` starting at the given `start` index.
21615    ///
21616    /// # Arguments
21617    /// * `array` - handle to a Java jfloatArray.
21618    /// * `start` - the index where the first element should be coped into in the Java jfloatArray
21619    /// * `buf` - the slice where data is copied from
21620    ///
21621    /// # Throws Java Exception:
21622    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
21623    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21624    ///
21625    /// It is JVM implementation specific what is stored inside `array` if this function throws an exception.
21626    /// * Data partially written
21627    /// * No data written
21628    ///
21629    /// # Panics
21630    /// if asserts feature is enabled and UB was detected
21631    ///
21632    /// # Safety
21633    /// Current thread must not be detached from JNI.
21634    ///
21635    /// Current thread must not be currently throwing an exception.
21636    ///
21637    /// Current thread does not hold a critical reference.
21638    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21639    ///
21640    /// `array` must be a valid non-null reference to a jfloatArray.
21641    ///
21642    /// # Example
21643    /// ```rust
21644    /// use jni_simple::{*};
21645    ///
21646    /// unsafe fn copy_chunk_from_rust_to_java(env: JNIEnv,
21647    ///         array: jfloatArray, chunk_buffer: &[jfloat], chunk_offset: usize) -> bool {
21648    ///     if array.is_null() {
21649    ///         panic!("Java Array is null")
21650    ///     }
21651    ///
21652    ///     env.SetFloatArrayRegion_from_slice(array, chunk_offset as jsize, chunk_buffer);
21653    ///     if env.ExceptionCheck() {
21654    ///         //ArrayIndexOutOfBoundsException
21655    ///         env.ExceptionClear();
21656    ///         return false;
21657    ///     }
21658    ///     true
21659    /// }
21660    /// ```
21661    ///
21662    pub unsafe fn SetFloatArrayRegion_from_slice(&self, array: jfloatArray, start: jsize, buf: &[jfloat]) {
21663        unsafe {
21664            self.SetFloatArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_ptr());
21665        }
21666    }
21667
21668    ///
21669    /// Copies data from a Java jfloatArray `array` into a new Vec<f32>
21670    ///
21671    /// # Arguments
21672    /// * `array` - handle to a Java jfloatArray.
21673    /// * `start` - the index of the first element to copy in the Java jfloatArray
21674    /// * `len` - the amount of data that should be copied. If `None` then all remaining elements in the array are copied.
21675    ///
21676    /// If `len` is `Some` and negative or 0 then an empty Vec<f32> is returned.
21677    ///
21678    /// # Returns:
21679    /// a new Vec<f32> that contains the copied data.
21680    ///
21681    ///
21682    /// # Throws Java Exception:
21683    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
21684    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
21685    ///
21686    /// It is JVM implementation specific what is stored inside the returned Vec<f32> if this function throws an exception
21687    /// * Data partially written
21688    /// * No data written
21689    ///
21690    /// It is only guaranteed that this function never returns uninitialized memory.
21691    ///
21692    /// # Panics
21693    /// if asserts feature is enabled and UB was detected
21694    ///
21695    /// # Safety
21696    /// Current thread must not be detached from JNI.
21697    ///
21698    /// Current thread must not be currently throwing an exception.
21699    ///
21700    /// Current thread does not hold a critical reference.
21701    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21702    ///
21703    /// `array` must be a valid non-null reference to a jfloatArray.
21704    ///
21705    /// # Example
21706    /// ```rust
21707    /// use jni_simple::{*};
21708    ///
21709    /// unsafe fn copy_entire_java_array_to_rust(env: JNIEnv, array: jfloatArray) -> Vec<f32> {
21710    ///     if array.is_null() {
21711    ///         panic!("Java Array is null")
21712    ///     }
21713    ///     env.GetFloatArrayRegion_as_vec(array, 0, None)
21714    /// }
21715    /// ```
21716    ///
21717    pub unsafe fn GetFloatArrayRegion_as_vec(&self, array: jfloatArray, start: jsize, len: Option<jsize>) -> Vec<jfloat> {
21718        unsafe {
21719            let len = len.unwrap_or_else(|| self.GetArrayLength(array) - start);
21720            if let Ok(len) = usize::try_from(len) {
21721                let mut data = vec![0f32; len];
21722                self.GetFloatArrayRegion_into_slice(array, start, data.as_mut_slice());
21723                return data;
21724            }
21725            Vec::new()
21726        }
21727    }
21728
21729    ///
21730    /// Copies data from the jdoubleArray `array` starting from the given `start` index into the memory pointed to by `buf`.
21731    ///
21732    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_PrimitiveType_ArrayRegion_routines>
21733    ///
21734    /// # Arguments
21735    /// * `array` - handle to a Java jdoubleArray
21736    /// * `start` - the index of the first element to copy in the Java jdoubleArray
21737    /// * `len` - amount of data to be copied
21738    /// * `buf` - pointer to memory where the data should be copied to
21739    ///
21740    /// # Throws Java Exception:
21741    /// * `ArrayIndexOutOfBoundsException` - if `len` is larger than the amount of remaining elements in the `array`.
21742    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21743    ///
21744    /// It is JVM implementation specific what is written into `buf` if this function throws an exception.
21745    /// * Data partially written
21746    /// * No data written
21747    ///
21748    /// # Panics
21749    /// if asserts feature is enabled and UB was detected
21750    ///
21751    /// # Safety
21752    /// Current thread must not be detached from JNI.
21753    ///
21754    /// Current thread must not be currently throwing an exception.
21755    ///
21756    /// Current thread does not hold a critical reference.
21757    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21758    ///
21759    /// `array` must be a valid non-null reference to a jdoubleArray.
21760    /// `buf` must be valid non-null pointer to memory with enough capacity and proper alignment to store `len` jdouble's.
21761    ///
21762    /// # Example
21763    /// ```rust
21764    /// use jni_simple::{*};
21765    ///
21766    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
21767    ///         array: jdoubleArray, chunk_buffer: &mut [jdouble], chunk_offset: usize) -> bool {
21768    ///     if array.is_null() {
21769    ///         panic!("Java Array is null")
21770    ///     }
21771    ///
21772    ///     env.GetDoubleArrayRegion(array, chunk_offset as jsize, chunk_buffer.len() as jsize, chunk_buffer.as_mut_ptr());
21773    ///     if env.ExceptionCheck() {
21774    ///         //ArrayIndexOutOfBoundsException
21775    ///         env.ExceptionClear();
21776    ///         return false;
21777    ///     }
21778    ///     true
21779    /// }
21780    /// ```
21781    ///
21782    pub unsafe fn GetDoubleArrayRegion(&self, array: jdoubleArray, start: jsize, len: jsize, buf: *mut jdouble) {
21783        unsafe {
21784            #[cfg(feature = "asserts")]
21785            {
21786                self.check_not_critical("GetDoubleArrayRegion");
21787                self.check_no_exception("GetDoubleArrayRegion");
21788                assert!(!array.is_null(), "GetDoubleArrayRegion jarray must not be null");
21789                assert!(!buf.is_null(), "GetDoubleArrayRegion buf must not be null");
21790                assert_eq!(0, buf.align_offset(align_of::<jdouble>()), "GetDoubleArrayRegion buf pointer is not aligned");
21791            }
21792
21793            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, jsize, jsize, *mut jdouble)>(206)(self.vtable, array, start, len, buf);
21794        }
21795    }
21796
21797    ///
21798    /// Copies data from the jdoubleArray `array` starting from the given `start` index into the slice `buf`.
21799    ///
21800    /// # Arguments
21801    /// * `array` - handle to a Java jdoubleArray.
21802    /// * `start` - the index of the first element to copy in the Java jdoubleArray
21803    /// * `buf` - the slice to copy data into
21804    ///
21805    /// # Throws Java Exception:
21806    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
21807    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21808    ///
21809    /// It is JVM implementation specific what is stored inside buf if this function throws an exception.
21810    /// * Data partially written
21811    /// * No data written
21812    ///
21813    /// # Panics
21814    /// if asserts feature is enabled and UB was detected
21815    ///
21816    /// # Safety
21817    /// Current thread must not be detached from JNI.
21818    ///
21819    /// Current thread must not be currently throwing an exception.
21820    ///
21821    /// Current thread does not hold a critical reference.
21822    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21823    ///
21824    /// `array` must be a valid non-null reference to a jdoubleArray.
21825    ///
21826    /// # Example
21827    /// ```rust
21828    /// use jni_simple::{*};
21829    ///
21830    /// unsafe fn copy_chunk_from_java_to_rust(env: JNIEnv,
21831    ///         array: jdoubleArray, chunk_buffer: &mut [jdouble], chunk_offset: usize) -> bool {
21832    ///     if array.is_null() {
21833    ///         panic!("Java Array is null")
21834    ///     }
21835    ///
21836    ///     env.GetDoubleArrayRegion_into_slice(array, chunk_offset as jsize, chunk_buffer);
21837    ///     if env.ExceptionCheck() {
21838    ///         //ArrayIndexOutOfBoundsException
21839    ///         env.ExceptionClear();
21840    ///         return false;
21841    ///     }
21842    ///     true
21843    /// }
21844    /// ```
21845    ///
21846    pub unsafe fn GetDoubleArrayRegion_into_slice(&self, array: jdoubleArray, start: jsize, buf: &mut [jdouble]) {
21847        unsafe {
21848            self.GetDoubleArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_mut_ptr());
21849        }
21850    }
21851
21852    ///
21853    /// Copies data from the slice `buf` into the jfloatArray `array` starting at the given `start` index.
21854    ///
21855    /// # Arguments
21856    /// * `array` - handle to a Java jfloatArray.
21857    /// * `start` - the index where the first element should be coped into in the Java jfloatArray
21858    /// * `buf` - the slice where data is copied from
21859    ///
21860    /// # Throws Java Exception:
21861    /// * `ArrayIndexOutOfBoundsException` - if the slice `buf` is larger than the amount of remaining elements in the `array`.
21862    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or >= env.GetArrayLength(array)
21863    ///
21864    /// It is JVM implementation specific what is stored inside `array` if this function throws an exception.
21865    /// * Data partially written
21866    /// * No data written
21867    ///
21868    /// # Panics
21869    /// if asserts feature is enabled and UB was detected
21870    ///
21871    /// # Safety
21872    /// Current thread must not be detached from JNI.
21873    ///
21874    /// Current thread must not be currently throwing an exception.
21875    ///
21876    /// Current thread does not hold a critical reference.
21877    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21878    ///
21879    /// `array` must be a valid non-null reference to a jfloatArray.
21880    ///
21881    /// # Example
21882    /// ```rust
21883    /// use jni_simple::{*};
21884    ///
21885    /// unsafe fn copy_chunk_from_rust_to_java(env: JNIEnv,
21886    ///         array: jfloatArray, chunk_buffer: &[jdouble], chunk_offset: usize) -> bool {
21887    ///     if array.is_null() {
21888    ///         panic!("Java Array is null")
21889    ///     }
21890    ///
21891    ///     env.SetDoubleArrayRegion_from_slice(array, chunk_offset as jsize, chunk_buffer);
21892    ///     if env.ExceptionCheck() {
21893    ///         //ArrayIndexOutOfBoundsException
21894    ///         env.ExceptionClear();
21895    ///         return false;
21896    ///     }
21897    ///     true
21898    /// }
21899    /// ```
21900    ///
21901    pub unsafe fn SetDoubleArrayRegion_from_slice(&self, array: jdoubleArray, start: jsize, buf: &[jdouble]) {
21902        unsafe {
21903            self.SetDoubleArrayRegion(array, start, jsize::try_from(buf.len()).expect("buf.len() > jsize::MAX"), buf.as_ptr());
21904        }
21905    }
21906
21907    ///
21908    /// Copies data from a Java jdoubleArray `array` into a new Vec<f64>
21909    ///
21910    /// # Arguments
21911    /// * `array` - handle to a Java jdoubleArray.
21912    /// * `start` - the index of the first element to copy in the Java jdoubleArray
21913    /// * `len` - the amount of data that should be copied. If `None` then all remaining elements in the array are copied.
21914    ///
21915    /// If `len` is `Some` and negative or 0 then an empty Vec<f64> is returned.
21916    ///
21917    /// # Returns:
21918    /// a new Vec<f64> that contains the copied data.
21919    ///
21920    ///
21921    /// # Throws Java Exception:
21922    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
21923    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
21924    ///
21925    /// It is JVM implementation specific what is stored inside the returned Vec<f64> if this function throws an exception
21926    /// * Data partially written
21927    /// * No data written
21928    ///
21929    /// It is only guaranteed that this function never returns uninitialized memory.
21930    ///
21931    /// # Panics
21932    /// if asserts feature is enabled and UB was detected
21933    ///
21934    /// # Safety
21935    /// Current thread must not be detached from JNI.
21936    ///
21937    /// Current thread must not be currently throwing an exception.
21938    ///
21939    /// Current thread does not hold a critical reference.
21940    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21941    ///
21942    /// `array` must be a valid non-null reference to a jdoubleArray.
21943    ///
21944    /// # Example
21945    /// ```rust
21946    /// use jni_simple::{*};
21947    ///
21948    /// unsafe fn copy_entire_java_array_to_rust(env: JNIEnv, array: jdoubleArray) -> Vec<jdouble> {
21949    ///     if array.is_null() {
21950    ///         panic!("Java Array is null")
21951    ///     }
21952    ///     env.GetDoubleArrayRegion_as_vec(array, 0, None)
21953    /// }
21954    /// ```
21955    ///
21956    pub unsafe fn GetDoubleArrayRegion_as_vec(&self, array: jdoubleArray, start: jsize, len: Option<jsize>) -> Vec<jdouble> {
21957        unsafe {
21958            let len = len.unwrap_or_else(|| self.GetArrayLength(array) - start);
21959            if let Ok(len) = usize::try_from(len) {
21960                let mut data = vec![0f64; len];
21961                self.GetDoubleArrayRegion_into_slice(array, start, data.as_mut_slice());
21962                return data;
21963            }
21964            Vec::new()
21965        }
21966    }
21967
21968    ///
21969    /// Sets a boolean array region from a buffer
21970    ///
21971    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_PrimitiveType_ArrayRegion_routines>
21972    ///
21973    /// # Arguments
21974    /// * `array` - handle to a Java array.
21975    ///     * must not be null
21976    /// * `start` - index in the `array` where the fist element should be copied to
21977    /// * `len` - amount of elements to copy
21978    /// * `buf` - buffer where the elements are copied from.
21979    ///     * must not be null
21980    ///
21981    /// # Throws Java Exception:
21982    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
21983    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
21984    ///
21985    /// The state of the array is implementation specific if the fn throws an exception.
21986    /// It may have partially copied some data or copied no data.
21987    ///
21988    /// # Panics
21989    /// if asserts feature is enabled and UB was detected
21990    ///
21991    /// # Safety
21992    /// Current thread must not be detached from JNI.
21993    ///
21994    /// Current thread must not be currently throwing an exception.
21995    ///
21996    /// Current thread does not hold a critical reference.
21997    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
21998    ///
21999    /// `array` must be a valid non-null reference to a jbooleanArray.
22000    /// `buf` must be at least `len` elements in size
22001    ///
22002    pub unsafe fn SetBooleanArrayRegion(&self, array: jbooleanArray, start: jsize, len: jsize, buf: *const jboolean) {
22003        unsafe {
22004            #[cfg(feature = "asserts")]
22005            {
22006                self.check_not_critical("SetBooleanArrayRegion");
22007                self.check_no_exception("SetBooleanArrayRegion");
22008                assert!(!array.is_null(), "SetBooleanArrayRegion jarray must not be null");
22009                assert!(!buf.is_null(), "SetBooleanArrayRegion buf must not be null");
22010            }
22011
22012            self.jni::<extern "system" fn(JNIEnvVTable, jbooleanArray, jsize, jsize, *const jboolean)>(207)(self.vtable, array, start, len, buf);
22013        }
22014    }
22015
22016    ///
22017    /// Sets a byte array region from a buffer
22018    ///
22019    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_PrimitiveType_ArrayRegion_routines>
22020    ///
22021    /// # Arguments
22022    /// * `array` - handle to a Java array.
22023    ///     * must not be null
22024    /// * `start` - index in the `array` where the fist element should be copied to
22025    /// * `len` - amount of elements to copy
22026    /// * `buf` - buffer where the elements are copied from.
22027    ///     * must not be null
22028    ///
22029    /// # Throws Java Exception:
22030    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
22031    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
22032    ///
22033    /// The state of the array is implementation specific if the fn throws an exception.
22034    /// It may have partially copied some data or copied no data.
22035    ///
22036    /// # Panics
22037    /// if asserts feature is enabled and UB was detected
22038    ///
22039    /// # Safety
22040    /// Current thread must not be detached from JNI.
22041    ///
22042    /// Current thread must not be currently throwing an exception.
22043    ///
22044    /// Current thread does not hold a critical reference.
22045    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22046    ///
22047    /// `array` must be a valid non-null reference to a jbyteArray.
22048    /// `buf` must be at least `len` elements in size
22049    ///
22050    pub unsafe fn SetByteArrayRegion(&self, array: jbyteArray, start: jsize, len: jsize, buf: *const jbyte) {
22051        unsafe {
22052            #[cfg(feature = "asserts")]
22053            {
22054                self.check_not_critical("SetByteArrayRegion");
22055                self.check_no_exception("SetByteArrayRegion");
22056                assert!(!array.is_null(), "SetByteArrayRegion jarray must not be null");
22057                assert!(!buf.is_null(), "SetByteArrayRegion buf must not be null");
22058            }
22059
22060            self.jni::<extern "system" fn(JNIEnvVTable, jbyteArray, jsize, jsize, *const jbyte)>(208)(self.vtable, array, start, len, buf);
22061        }
22062    }
22063
22064    ///
22065    /// Sets a char array region from a buffer
22066    ///
22067    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_PrimitiveType_ArrayRegion_routines>
22068    ///
22069    /// # Arguments
22070    /// * `array` - handle to a Java array.
22071    ///     * must not be null
22072    /// * `start` - index in the `array` where the fist element should be copied to
22073    /// * `len` - amount of elements to copy
22074    /// * `buf` - buffer where the elements are copied from.
22075    ///     * must not be null
22076    ///
22077    /// # Throws Java Exception:
22078    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
22079    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
22080    ///
22081    /// The state of the array is implementation specific if the fn throws an exception.
22082    /// It may have partially copied some data or copied no data.
22083    ///
22084    /// # Panics
22085    /// if asserts feature is enabled and UB was detected
22086    ///
22087    /// # Safety
22088    /// Current thread must not be detached from JNI.
22089    ///
22090    /// Current thread must not be currently throwing an exception.
22091    ///
22092    /// Current thread does not hold a critical reference.
22093    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22094    ///
22095    /// `array` must be a valid non-null reference to a jcharArray.
22096    /// `buf` must be at least `len` elements in size
22097    ///
22098    pub unsafe fn SetCharArrayRegion(&self, array: jcharArray, start: jsize, len: jsize, buf: *const jchar) {
22099        unsafe {
22100            #[cfg(feature = "asserts")]
22101            {
22102                self.check_not_critical("SetCharArrayRegion");
22103                self.check_no_exception("SetCharArrayRegion");
22104                assert!(!array.is_null(), "SetCharArrayRegion jarray must not be null");
22105                assert!(!buf.is_null(), "SetCharArrayRegion buf must not be null");
22106                assert_eq!(0, buf.align_offset(align_of::<jchar>()), "SetCharArrayRegion buf pointer is not aligned");
22107            }
22108
22109            self.jni::<extern "system" fn(JNIEnvVTable, jcharArray, jsize, jsize, *const jchar)>(209)(self.vtable, array, start, len, buf);
22110        }
22111    }
22112
22113    ///
22114    /// Sets a short array region from a buffer
22115    ///
22116    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_PrimitiveType_ArrayRegion_routines>
22117    ///
22118    /// # Arguments
22119    /// * `array` - handle to a Java array.
22120    ///     * must not be null
22121    /// * `start` - index in the `array` where the fist element should be copied to
22122    /// * `len` - amount of elements to copy
22123    /// * `buf` - buffer where the elements are copied from.
22124    ///     * must not be null
22125    ///
22126    /// # Throws Java Exception:
22127    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
22128    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
22129    ///
22130    /// The state of the array is implementation specific if the fn throws an exception.
22131    /// It may have partially copied some data or copied no data.
22132    ///
22133    /// # Panics
22134    /// if asserts feature is enabled and UB was detected
22135    ///
22136    /// # Safety
22137    /// Current thread must not be detached from JNI.
22138    ///
22139    /// Current thread must not be currently throwing an exception.
22140    ///
22141    /// Current thread does not hold a critical reference.
22142    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22143    ///
22144    /// `array` must be a valid non-null reference to a jshortArray.
22145    /// `buf` must be at least `len` elements in size
22146    ///
22147    pub unsafe fn SetShortArrayRegion(&self, array: jshortArray, start: jsize, len: jsize, buf: *const jshort) {
22148        unsafe {
22149            #[cfg(feature = "asserts")]
22150            {
22151                self.check_not_critical("SetShortArrayRegion");
22152                self.check_no_exception("SetShortArrayRegion");
22153                assert!(!array.is_null(), "SetShortArrayRegion jarray must not be null");
22154                assert!(!buf.is_null(), "SetShortArrayRegion buf must not be null");
22155                assert_eq!(0, buf.align_offset(align_of::<jshort>()), "SetShortArrayRegion buf pointer is not aligned");
22156            }
22157
22158            self.jni::<extern "system" fn(JNIEnvVTable, jshortArray, jsize, jsize, *const jshort)>(210)(self.vtable, array, start, len, buf);
22159        }
22160    }
22161
22162    ///
22163    /// Sets a int array region from a buffer
22164    ///
22165    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_PrimitiveType_ArrayRegion_routines>
22166    ///
22167    /// # Arguments
22168    /// * `array` - handle to a Java array.
22169    ///     * must not be null
22170    /// * `start` - index in the `array` where the fist element should be copied to
22171    /// * `len` - amount of elements to copy
22172    /// * `buf` - buffer where the elements are copied from.
22173    ///     * must not be null
22174    ///
22175    /// # Throws Java Exception:
22176    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
22177    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
22178    ///
22179    /// The state of the array is implementation specific if the fn throws an exception.
22180    /// It may have partially copied some data or copied no data.
22181    ///
22182    /// # Panics
22183    /// if asserts feature is enabled and UB was detected
22184    ///
22185    /// # Safety
22186    /// Current thread must not be detached from JNI.
22187    ///
22188    /// Current thread must not be currently throwing an exception.
22189    ///
22190    /// Current thread does not hold a critical reference.
22191    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22192    ///
22193    /// `array` must be a valid non-null reference to a jintArray.
22194    /// `buf` must be at least `len` elements in size
22195    ///
22196    pub unsafe fn SetIntArrayRegion(&self, array: jintArray, start: jsize, len: jsize, buf: *const jint) {
22197        unsafe {
22198            #[cfg(feature = "asserts")]
22199            {
22200                self.check_not_critical("SetIntArrayRegion");
22201                self.check_no_exception("SetIntArrayRegion");
22202                assert!(!array.is_null(), "SetIntArrayRegion jarray must not be null");
22203                assert!(!buf.is_null(), "SetIntArrayRegion buf must not be null");
22204                assert_eq!(0, buf.align_offset(align_of::<jint>()), "SetIntArrayRegion buf pointer is not aligned");
22205            }
22206
22207            self.jni::<extern "system" fn(JNIEnvVTable, jintArray, jsize, jsize, *const jint)>(211)(self.vtable, array, start, len, buf);
22208        }
22209    }
22210
22211    ///
22212    /// Sets a long array region from a buffer
22213    ///
22214    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_PrimitiveType_ArrayRegion_routines>
22215    ///
22216    /// # Arguments
22217    /// * `array` - handle to a Java array.
22218    ///     * must not be null
22219    /// * `start` - index in the `array` where the fist element should be copied to
22220    /// * `len` - amount of elements to copy
22221    /// * `buf` - buffer where the elements are copied from.
22222    ///     * must not be null
22223    ///
22224    /// # Throws Java Exception:
22225    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
22226    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
22227    ///
22228    /// The state of the array is implementation specific if the fn throws an exception.
22229    /// It may have partially copied some data or copied no data.
22230    ///
22231    /// # Panics
22232    /// if asserts feature is enabled and UB was detected
22233    ///
22234    /// # Safety
22235    /// Current thread must not be detached from JNI.
22236    ///
22237    /// Current thread must not be currently throwing an exception.
22238    ///
22239    /// Current thread does not hold a critical reference.
22240    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22241    ///
22242    /// `array` must be a valid non-null reference to a jlongArray.
22243    /// `buf` must be at least `len` elements in size
22244    ///
22245    pub unsafe fn SetLongArrayRegion(&self, array: jlongArray, start: jsize, len: jsize, buf: *const jlong) {
22246        unsafe {
22247            #[cfg(feature = "asserts")]
22248            {
22249                self.check_not_critical("SetLongArrayRegion");
22250                self.check_no_exception("SetLongArrayRegion");
22251                assert!(!array.is_null(), "SetLongArrayRegion jarray must not be null");
22252                assert!(!buf.is_null(), "SetLongArrayRegion buf must not be null");
22253                assert_eq!(0, buf.align_offset(align_of::<jlong>()), "SetLongArrayRegion buf pointer is not aligned");
22254            }
22255
22256            self.jni::<extern "system" fn(JNIEnvVTable, jlongArray, jsize, jsize, *const jlong)>(212)(self.vtable, array, start, len, buf);
22257        }
22258    }
22259
22260    ///
22261    /// Sets a float array region from a buffer
22262    ///
22263    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_PrimitiveType_ArrayRegion_routines>
22264    ///
22265    /// # Arguments
22266    /// * `array` - handle to a Java array.
22267    ///     * must not be null
22268    /// * `start` - index in the `array` where the fist element should be copied to
22269    /// * `len` - amount of elements to copy
22270    /// * `buf` - buffer where the elements are copied from.
22271    ///     * must not be null
22272    ///
22273    /// # Throws Java Exception:
22274    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
22275    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
22276    ///
22277    /// The state of the array is implementation specific if the fn throws an exception.
22278    /// It may have partially copied some data or copied no data.
22279    ///
22280    /// # Panics
22281    /// if asserts feature is enabled and UB was detected
22282    ///
22283    /// # Safety
22284    /// Current thread must not be detached from JNI.
22285    ///
22286    /// Current thread must not be currently throwing an exception.
22287    ///
22288    /// Current thread does not hold a critical reference.
22289    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22290    ///
22291    /// `array` must be a valid non-null reference to a jfloatArray.
22292    /// `buf` must be at least `len` elements in size
22293    ///
22294    pub unsafe fn SetFloatArrayRegion(&self, array: jfloatArray, start: jsize, len: jsize, buf: *const jfloat) {
22295        unsafe {
22296            #[cfg(feature = "asserts")]
22297            {
22298                self.check_not_critical("SetFloatArrayRegion");
22299                self.check_no_exception("SetFloatArrayRegion");
22300                assert!(!array.is_null(), "SetFloatArrayRegion jarray must not be null");
22301                assert!(!buf.is_null(), "SetFloatArrayRegion buf must not be null");
22302                assert_eq!(0, buf.align_offset(align_of::<jfloat>()), "SetFloatArrayRegion buf pointer is not aligned");
22303            }
22304
22305            self.jni::<extern "system" fn(JNIEnvVTable, jfloatArray, jsize, jsize, *const jfloat)>(213)(self.vtable, array, start, len, buf);
22306        }
22307    }
22308
22309    ///
22310    /// Sets a double array region from a buffer
22311    ///
22312    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Set_PrimitiveType_ArrayRegion_routines>
22313    ///
22314    /// # Arguments
22315    /// * `array` - handle to a Java array.
22316    ///     * must not be null
22317    /// * `start` - index in the `array` where the fist element should be copied to
22318    /// * `len` - amount of elements to copy
22319    /// * `buf` - buffer where the elements are copied from.
22320    ///     * must not be null
22321    ///
22322    /// # Throws Java Exception:
22323    /// * `ArrayIndexOutOfBoundsException` - if `len` was Some and is larger than the amount of remaining elements in the array.
22324    /// * `ArrayIndexOutOfBoundsException` - if `start` is negative or `start` is >= env.GetArrayLength(array)
22325    ///
22326    /// The state of the array is implementation specific if the fn throws an exception.
22327    /// It may have partially copied some data or copied no data.
22328    ///
22329    /// # Panics
22330    /// if asserts feature is enabled and UB was detected
22331    ///
22332    /// # Safety
22333    /// Current thread must not be detached from JNI.
22334    ///
22335    /// Current thread must not be currently throwing an exception.
22336    ///
22337    /// Current thread does not hold a critical reference.
22338    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22339    ///
22340    /// `array` must be a valid non-null reference to a jdoubleArray.
22341    /// `buf` must be at least `len` elements in size
22342    ///
22343    pub unsafe fn SetDoubleArrayRegion(&self, array: jdoubleArray, start: jsize, len: jsize, buf: *const jdouble) {
22344        unsafe {
22345            #[cfg(feature = "asserts")]
22346            {
22347                self.check_not_critical("SetDoubleArrayRegion");
22348                self.check_no_exception("SetDoubleArrayRegion");
22349                assert!(!array.is_null(), "SetDoubleArrayRegion jarray must not be null");
22350                assert!(!buf.is_null(), "SetDoubleArrayRegion buf must not be null");
22351                assert_eq!(0, buf.align_offset(align_of::<jdouble>()), "SetDoubleArrayRegion buf pointer is not aligned");
22352            }
22353
22354            self.jni::<extern "system" fn(JNIEnvVTable, jdoubleArray, jsize, jsize, *const jdouble)>(214)(self.vtable, array, start, len, buf);
22355        }
22356    }
22357
22358    #[cfg(feature = "asserts")]
22359    std::thread_local! {
22360        //The "Critical Section" created by GetPrimitiveArrayCritical has a lot of restrictions placed upon it.
22361        //This attempts to track "some" of them on a best effort basis.
22362        static CRITICAL_POINTERS: std::cell::RefCell<std::collections::HashMap<*mut c_void, usize>> = std::cell::RefCell::new(std::collections::HashMap::new());
22363    }
22364
22365    ///
22366    /// Obtains a critical pointer into a primitive java array.
22367    /// This pointer must be released by calling `ReleasePrimitiveArrayCritical`.
22368    /// No other JNI functions can be called in the current thread.
22369    /// The only exception being multiple consecutive calls to `GetPrimitiveArrayCritical` & `GetStringCritical` to obtain multiple critical
22370    /// pointers at the same time.
22371    ///
22372    /// This method will return NULL to indicate error.
22373    /// The JVM will most likely throw an Exception, probably an `OOMError`.
22374    /// If you obtain multiple critical pointers, you MUST release all successfully obtained critical pointers
22375    /// before being able to check for the exception.
22376    ///
22377    /// Special care must be taken to avoid blocking the current thread with a dependency on another JVM thread.
22378    /// I.e. Do not read from a pipe that is filled by another JVM thread for example.
22379    ///
22380    /// 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.
22381    /// The JVM may decide among other things to suspend garbage collection while a critical pointer is held.
22382    /// So reading from a Socket with a long timeout while holding a critical pointer is unlikely to be a good idea.
22383    /// As it may cause unintended side effects in the rest of the JVM (like running out of memory because the GC doesn't run)
22384    ///
22385    /// Failure to release critical pointers before returning execution back to Java Code should be treated as UB
22386    /// even tho the JVM spec fails to mention this detail.
22387    ///
22388    /// Releasing critical pointers in another thread other than the thread that created it should be treated as UB
22389    /// even tho the JVM spec only mentions this detail indirectly.
22390    ///
22391    /// I recommend against using this method for almost every use case as using either Set/Get array region or direct NIO buffers
22392    /// is a better choice. One use case I can think of where this method is a valid choice
22393    /// is performing pixel manipulations on the int[]/byte[] inside a large existing `BufferedImage`.
22394    ///
22395    /// # Returns
22396    /// returns null on error otherwise returns a pointer into the data and begins a critical section.
22397    ///
22398    /// # Panics
22399    /// if asserts feature is enabled and UB was detected
22400    ///
22401    /// # Safety
22402    /// `array` must be valid non null reference to a array that is not already garbage collected
22403    ///
22404    pub unsafe fn GetPrimitiveArrayCritical(&self, array: jarray, isCopy: *mut jboolean) -> *mut c_void {
22405        unsafe {
22406            #[cfg(feature = "asserts")]
22407            {
22408                Self::CRITICAL_POINTERS.with(|set| {
22409                    if set.borrow().is_empty() {
22410                        Self::CRITICAL_STRINGS.with(|strings| {
22411                            if strings.borrow().is_empty() {
22412                                //We can only do this check if we have not yet obtained a unreleased critical on the current thread.
22413                                //For subsequent calls we cannot do this check.
22414                                self.check_no_exception("GetPrimitiveArrayCritical");
22415                            }
22416                        });
22417                    }
22418                });
22419                assert!(!array.is_null(), "GetPrimitiveArrayCritical jarray must not be null");
22420            }
22421
22422            let crit = self.jni::<extern "system" fn(JNIEnvVTable, jarray, *mut jboolean) -> *mut c_void>(222)(self.vtable, array, isCopy);
22423
22424            #[cfg(feature = "asserts")]
22425            {
22426                if !crit.is_null() {
22427                    Self::CRITICAL_POINTERS.with(|set| {
22428                        let mut rm = set.borrow_mut();
22429                        let n = rm.remove(&crit).unwrap_or(0) + 1;
22430                        rm.insert(crit, n);
22431                    });
22432                }
22433            }
22434
22435            crit
22436        }
22437    }
22438
22439    ///
22440    /// Releases a critical array obtains in `GetPrimitiveArrayCritical`
22441    ///
22442    /// # Panics
22443    /// if asserts feature is enabled and UB was detected
22444    ///
22445    /// # Safety
22446    /// `array` must be valid non null reference to a array that is not already garbage collected
22447    /// `carray` must be the result of a `GetPrimitiveArrayCritical` call with the same `array`
22448    /// `mode` must be one of `JNI_OK`, `JNI_COMMIT` or `JNI_ABORT` constant values.
22449    ///
22450    pub unsafe fn ReleasePrimitiveArrayCritical(&self, array: jarray, carray: *mut c_void, mode: jint) {
22451        unsafe {
22452            #[cfg(feature = "asserts")]
22453            {
22454                assert!(!array.is_null(), "ReleasePrimitiveArrayCritical jarray must not be null");
22455                assert!(!carray.is_null(), "ReleasePrimitiveArrayCritical carray must not be null");
22456                assert!(
22457                    mode == JNI_OK || mode == JNI_COMMIT || mode == JNI_ABORT,
22458                    "ReleasePrimitiveArrayCritical mode is invalid {mode}"
22459                );
22460                Self::CRITICAL_POINTERS.with(|set| {
22461                    let mut rm = set.borrow_mut();
22462                    let mut n = rm.remove(&carray).expect("ReleasePrimitiveArrayCritical carray is not valid");
22463                    if n == 0 {
22464                        unreachable!();
22465                    }
22466
22467                    if mode != JNI_COMMIT {
22468                        //JNI_COMMIT does not release the pointer. It's a noop for non-copied pointers.
22469                        n -= 1;
22470                    }
22471
22472                    if n >= 1 {
22473                        rm.insert(carray, n);
22474                    }
22475                });
22476            }
22477
22478            self.jni::<extern "system" fn(JNIEnvVTable, jarray, *mut c_void, jint)>(223)(self.vtable, array, carray, mode);
22479        }
22480    }
22481
22482    ///
22483    /// Registers native methods to a java class with native methods
22484    ///
22485    /// # Arguments
22486    /// * `clazz` - handle to a Java array.
22487    ///     * must not be null
22488    /// * `methods` - the native method function pointers
22489    ///
22490    /// # Panics
22491    /// if more than `jsize::MAX` native methods are supposed to be registered.
22492    /// if asserts feature is enabled and UB was detected
22493    ///
22494    /// # Safety
22495    /// Current thread must not be detached from JNI.
22496    ///
22497    /// Current thread must not be currently throwing an exception.
22498    ///
22499    /// Current thread does not hold a critical reference.
22500    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22501    ///
22502    /// `clazz` must be a valid non-null reference to a class.
22503    /// `methods` all elements and their function pointers must be non null and valid.
22504    ///
22505    pub unsafe fn RegisterNatives_from_slice(&self, clazz: jclass, methods: &[JNINativeMethod]) -> jint {
22506        unsafe { self.RegisterNatives(clazz, methods.as_ptr(), jint::try_from(methods.len()).expect("More than jsize::MAX methods")) }
22507    }
22508
22509    ///
22510    /// Registers native methods to a java class with native methods
22511    ///
22512    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#RegisterNatives>
22513    ///
22514    /// # Arguments
22515    /// * `clazz`
22516    ///     * must not be null
22517    ///     * must not be already garbage collected
22518    /// * `methods` - the native method function pointers
22519    ///     * must not be null
22520    /// * `size` - amount of `JNINativeMethod`'s in `methods`
22521    ///     * must not be negative
22522    ///
22523    /// # Panics
22524    /// if asserts feature is enabled and UB was detected
22525    ///
22526    /// # Safety
22527    /// Current thread must not be detached from JNI.
22528    ///
22529    /// Current thread must not be currently throwing an exception.
22530    ///
22531    /// Current thread does not hold a critical reference.
22532    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22533    ///
22534    /// `clazz` must be a valid non-null reference to a class.
22535    /// `methods` all elements and their function pointers must be non null and valid.
22536    /// `methods` must be at least `size` elements large
22537    ///
22538    pub unsafe fn RegisterNatives(&self, clazz: jclass, methods: *const JNINativeMethod, size: jint) -> jint {
22539        unsafe {
22540            #[cfg(feature = "asserts")]
22541            {
22542                self.check_not_critical("RegisterNatives");
22543                self.check_no_exception("RegisterNatives");
22544                assert!(!clazz.is_null(), "RegisterNatives class must not be null");
22545                assert!(size > 0, "RegisterNatives size must be greater than 0");
22546                if let Ok(size) = usize::try_from(size) {
22547                    for (idx, cur) in std::slice::from_raw_parts(methods, size).iter().enumerate() {
22548                        assert!(!cur.name.is_null(), "RegisterNatives JNINativeMethod[{idx}],name is null");
22549                        assert!(!cur.signature.is_null(), "RegisterNatives JNINativeMethod[{idx}].signature is null");
22550                        assert!(!cur.fnPtr.is_null(), "RegisterNatives JNINativeMethod[{idx}].fnPtr is null");
22551                    }
22552                }
22553            }
22554
22555            self.jni::<extern "system" fn(JNIEnvVTable, jclass, *const JNINativeMethod, jint) -> jint>(215)(self.vtable, clazz, methods, size)
22556        }
22557    }
22558
22559    ///
22560    /// Unregisters all native bindings from a java class.
22561    ///
22562    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#UnregisterNatives>
22563    ///
22564    /// # Arguments
22565    /// * `clazz`
22566    ///     * must not be null
22567    ///     * must not be already garbage collected
22568    ///
22569    /// # Panics
22570    /// if asserts feature is enabled and UB was detected
22571    ///
22572    /// # Safety
22573    /// Current thread must not be detached from JNI.
22574    ///
22575    /// Current thread must not be currently throwing an exception.
22576    ///
22577    /// Current thread does not hold a critical reference.
22578    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22579    ///
22580    /// `clazz` must be a valid non-null reference to a class.
22581    /// `methods` all elements and their function pointers must be non null and valid.
22582    /// `methods` must be at least `size` elements large
22583    ///
22584    pub unsafe fn UnregisterNatives(&self, clazz: jclass) -> jint {
22585        unsafe {
22586            #[cfg(feature = "asserts")]
22587            {
22588                self.check_not_critical("UnregisterNatives");
22589                self.check_no_exception("UnregisterNatives");
22590                assert!(!clazz.is_null(), "UnregisterNatives class must not be null");
22591            }
22592
22593            self.jni::<extern "system" fn(JNIEnvVTable, jclass) -> jint>(216)(self.vtable, clazz)
22594        }
22595    }
22596
22597    ///
22598    /// Enters a monitor on a java object.
22599    /// A will cause all other java threads to block when trying to enter a synchronized block
22600    /// on the object or other native threads to block when trying to enter a monitor.
22601    /// This fn will block until all other threads have either left their synchronized block or monitor sections.
22602    ///
22603    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#MonitorEnter>
22604    ///
22605    /// # Returns
22606    /// `JNI_OK` on success
22607    ///
22608    /// # Arguments
22609    /// * `obj`
22610    ///     * must not be null
22611    ///     * must not be already garbage collected
22612    ///
22613    /// # Panics
22614    /// if asserts feature is enabled and UB was detected
22615    ///
22616    /// # Safety
22617    /// Current thread must not be detached from JNI.
22618    ///
22619    /// Current thread must not be currently throwing an exception.
22620    ///
22621    /// Current thread does not hold a critical reference.
22622    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22623    ///
22624    /// `jobject` must be a valid non-null reference that is not yet garbage collected.
22625    ///
22626    pub unsafe fn MonitorEnter(&self, obj: jobject) -> jint {
22627        unsafe {
22628            #[cfg(feature = "asserts")]
22629            {
22630                self.check_not_critical("MonitorEnter");
22631                self.check_no_exception("MonitorEnter");
22632                assert!(!obj.is_null(), "MonitorEnter object must not be null");
22633            }
22634
22635            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jint>(217)(self.vtable, obj)
22636        }
22637    }
22638
22639    ///
22640    /// Leaves a monitor entered by `MonitorEnter`
22641    /// This fn cannot be used to "leave" synchronized blocks entered into by java code.
22642    ///
22643    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#MonitorExit>
22644    ///
22645    /// # Arguments
22646    /// * `obj`
22647    ///     * must not be null
22648    ///     * must not be already garbage collected
22649    ///
22650    /// # Returns
22651    /// `JNI_OK` on success
22652    ///
22653    /// # Throws Java Exception
22654    /// * `IllegalMonitorStateException` - if the current thread does not own the monitor
22655    ///
22656    /// # Panics
22657    /// if asserts feature is enabled and UB was detected
22658    ///
22659    /// # Safety
22660    /// Current thread must not be detached from JNI.
22661    ///
22662    /// Current thread must not be currently throwing an exception.
22663    ///
22664    /// Current thread does not hold a critical reference.
22665    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22666    ///
22667    /// `jobject` must be a valid non-null reference that is not yet garbage collected.
22668    ///
22669    pub unsafe fn MonitorExit(&self, obj: jobject) -> jint {
22670        unsafe {
22671            #[cfg(feature = "asserts")]
22672            {
22673                self.check_not_critical("MonitorExit");
22674                assert!(!obj.is_null(), "MonitorExit object must not be null");
22675            }
22676
22677            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jint>(218)(self.vtable, obj)
22678        }
22679    }
22680
22681    ///
22682    /// Creates a new nio direct `ByteBuffer` that is backed by some native memory provided to by the pointer.
22683    /// When garbage collection collects that `ByteBuffer` it will not perform any operation on the backed memory.
22684    /// The caller has to ensure that the pointer remains valid for the entire existance of the `ByteBuffer`
22685    ///
22686    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewDirectByteBuffer>
22687    ///
22688    /// # Arguments
22689    /// * `address`
22690    ///     * must not be null
22691    /// * `capacity`
22692    ///     * size of the memory pointed to by address
22693    ///     * must be positive
22694    ///
22695    /// # Returns
22696    /// A local reference to the newly created `ByteBuffer`
22697    ///
22698    /// # Panics
22699    /// if asserts feature is enabled and UB was detected
22700    ///
22701    /// # Safety
22702    /// Current thread must not be detached from JNI.
22703    ///
22704    /// Current thread must not be currently throwing an exception.
22705    ///
22706    /// Current thread does not hold a critical reference.
22707    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22708    ///
22709    /// `address` must be a valid non-null.
22710    /// `capacity` must be positive, the memory pointed to by `address` must have at least this amount of bytes in space.
22711    ///
22712    pub unsafe fn NewDirectByteBuffer(&self, address: *mut c_void, capacity: jlong) -> jobject {
22713        unsafe {
22714            #[cfg(feature = "asserts")]
22715            {
22716                self.check_not_critical("NewDirectByteBuffer");
22717                self.check_no_exception("NewDirectByteBuffer");
22718                assert!(!address.is_null(), "NewDirectByteBuffer address must not be null");
22719                assert!(capacity >= 0, "NewDirectByteBuffer capacity must not be negative {capacity}");
22720                assert!(
22721                    capacity <= jlong::from(jint::MAX),
22722                    "NewDirectByteBuffer capacity is too big, its larger than Integer.MAX_VALUE {capacity}"
22723                );
22724            }
22725
22726            self.jni::<extern "system" fn(JNIEnvVTable, *mut c_void, jlong) -> jobject>(229)(self.vtable, address, capacity)
22727        }
22728    }
22729
22730    ///
22731    /// Gets the memory address that backs a direct nio buffer.
22732    ///
22733    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetDirectBufferAddress>
22734    ///
22735    /// # Arguments
22736    /// * `buf`
22737    ///     * must not be null
22738    ///     * must not be garbage collected
22739    ///
22740    /// If `buf` does not refer to a Buffer object or is not direct then this fn returns -1.
22741    /// If the jvm does not support accessing direct buffers then this fn returns -1.
22742    ///
22743    /// # Returns
22744    /// The backing pointer or -1 on error
22745    ///
22746    /// # Panics
22747    /// if asserts feature is enabled and UB was detected
22748    ///
22749    /// # Safety
22750    /// Current thread must not be detached from JNI.
22751    ///
22752    /// Current thread must not be currently throwing an exception.
22753    ///
22754    /// Current thread does not hold a critical reference.
22755    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22756    ///
22757    /// `buf` must be a valid non-null reference to a object and not be garbage collected.
22758    ///
22759    pub unsafe fn GetDirectBufferAddress(&self, buf: jobject) -> *mut c_void {
22760        unsafe {
22761            #[cfg(feature = "asserts")]
22762            {
22763                self.check_not_critical("GetDirectBufferAddress");
22764                self.check_no_exception("GetDirectBufferAddress");
22765                assert!(!buf.is_null(), "GetDirectBufferAddress buffer must not be null");
22766            }
22767            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> *mut c_void>(230)(self.vtable, buf)
22768        }
22769    }
22770
22771    ///
22772    /// Gets the capacity of a direct nio buffer.
22773    ///
22774    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetDirectBufferCapacity>
22775    ///
22776    /// # Arguments
22777    /// * `buf`
22778    ///     * must not be null
22779    ///     * must not be garbage collected
22780    ///
22781    /// If `buf` does not refer to a Buffer object or is not direct then this fn returns -1.
22782    /// If the jvm does not support accessing direct buffers then this fn returns -1.
22783    ///
22784    /// # Returns
22785    /// The capacity or -1 on error
22786    ///
22787    /// # Panics
22788    /// if asserts feature is enabled and UB was detected
22789    ///
22790    /// # Safety
22791    /// Current thread must not be detached from JNI.
22792    ///
22793    /// Current thread must not be currently throwing an exception.
22794    ///
22795    /// Current thread does not hold a critical reference.
22796    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22797    ///
22798    /// `buf` must be a valid non-null reference to a object and not be garbage collected.
22799    ///
22800    pub unsafe fn GetDirectBufferCapacity(&self, buf: jobject) -> jlong {
22801        unsafe {
22802            #[cfg(feature = "asserts")]
22803            {
22804                self.check_not_critical("GetDirectBufferCapacity");
22805                self.check_no_exception("GetDirectBufferCapacity");
22806                assert!(!buf.is_null(), "GetDirectBufferCapacity buffer must not be null");
22807            }
22808            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jlong>(231)(self.vtable, buf)
22809        }
22810    }
22811
22812    ///
22813    /// Converts a reflection Method to a jmethodID
22814    ///
22815    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#FromReflectedMethod>
22816    ///
22817    /// # Arguments
22818    /// * `method`
22819    ///     * must not be null
22820    ///     * must not be garbage collected
22821    ///     * must be instanceof a java.lang.reflect.Method or java.lang.reflect.Constructor
22822    ///
22823    ///
22824    /// # Returns
22825    /// the jmethodID that refers to the same method.
22826    ///
22827    /// # Panics
22828    /// if asserts feature is enabled and UB was detected
22829    ///
22830    /// # Safety
22831    /// Current thread must not be detached from JNI.
22832    ///
22833    /// Current thread must not be currently throwing an exception.
22834    ///
22835    /// Current thread does not hold a critical reference.
22836    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22837    ///
22838    /// `method` must be a valid non-null reference to a java.lang.reflect.Method or java.lang.reflect.Constructor and not be garbage collected.
22839    ///
22840    pub unsafe fn FromReflectedMethod(&self, method: jobject) -> jmethodID {
22841        unsafe {
22842            #[cfg(feature = "asserts")]
22843            {
22844                self.check_not_critical("FromReflectedMethod");
22845                self.check_no_exception("FromReflectedMethod");
22846                assert!(!method.is_null(), "FromReflectedMethod method must not be null");
22847            }
22848            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jmethodID>(7)(self.vtable, method)
22849        }
22850    }
22851
22852    ///
22853    /// Converts a jmethodID into a reflection Method
22854    ///
22855    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#FromReflectedField>
22856    ///
22857    /// # Arguments
22858    /// * `cls` - the class the method is in
22859    ///     * must not be null
22860    ///     * must not be garbage collected
22861    /// * `jmethodID`
22862    ///     * must not be null
22863    ///     * must refer to a method that is in `cls`
22864    /// * `isStatic` - is the method static or not?
22865    ///
22866    ///
22867    /// # Returns
22868    /// a local reference that refers to the same method as the jmethodID or null on erro
22869    ///
22870    /// # Throws Java Exception
22871    /// * `OutOfMemoryError` - if the jvm runs out of memory.
22872    ///
22873    /// # Panics
22874    /// if asserts feature is enabled and UB was detected
22875    ///
22876    /// # Safety
22877    /// Current thread must not be detached from JNI.
22878    ///
22879    /// Current thread must not be currently throwing an exception.
22880    ///
22881    /// Current thread does not hold a critical reference.
22882    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22883    ///
22884    /// `cls` must be a valid non-null reference to a Class and not be garbage collected.
22885    /// `jmethodID` must refer to a method in `cls` and must be either static or not static depending on the `isStatic` flag.
22886    ///
22887    pub unsafe fn ToReflectedMethod(&self, cls: jclass, jmethodID: jmethodID, isStatic: jboolean) -> jobject {
22888        unsafe {
22889            #[cfg(feature = "asserts")]
22890            {
22891                self.check_not_critical("ToReflectedMethod");
22892                self.check_no_exception("ToReflectedMethod");
22893                assert!(!cls.is_null(), "ToReflectedMethod class must not be null");
22894                assert!(!jmethodID.is_null(), "ToReflectedMethod method must not be null");
22895            }
22896            self.jni::<extern "system" fn(JNIEnvVTable, jclass, jmethodID, jboolean) -> jobject>(9)(self.vtable, cls, jmethodID, isStatic)
22897        }
22898    }
22899
22900    ///
22901    /// Converts a reflection Field to a jfieldID
22902    ///
22903    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#FromReflectedField>
22904    ///
22905    /// # Arguments
22906    /// * `field`
22907    ///     * must not be null
22908    ///     * must not be garbage collected
22909    ///     * must be instanceof a java.lang.reflect.Field
22910    ///
22911    ///
22912    /// # Returns
22913    /// the jfieldID that refers to the same field.
22914    ///
22915    /// # Panics
22916    /// if asserts feature is enabled and UB was detected
22917    ///
22918    /// # Safety
22919    /// Current thread must not be detached from JNI.
22920    ///
22921    /// Current thread must not be currently throwing an exception.
22922    ///
22923    /// Current thread does not hold a critical reference.
22924    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22925    ///
22926    /// `field` must be a valid non-null reference to a java.lang.reflect.Field and not be garbage collected.
22927    ///
22928    pub unsafe fn FromReflectedField(&self, field: jobject) -> jfieldID {
22929        unsafe {
22930            #[cfg(feature = "asserts")]
22931            {
22932                self.check_not_critical("FromReflectedField");
22933                self.check_no_exception("FromReflectedField");
22934                assert!(!field.is_null(), "FromReflectedField field must not be null");
22935            }
22936            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jfieldID>(8)(self.vtable, field)
22937        }
22938    }
22939
22940    ///
22941    /// Converts a jfieldID into a reflection Field
22942    ///
22943    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#FromReflectedField>
22944    ///
22945    /// # Arguments
22946    /// * `cls` - the class the method is in
22947    ///     * must not be null
22948    ///     * must not be garbage collected
22949    /// * `jfieldID`
22950    ///     * must not be null
22951    ///     * must refer to a field that is in `cls`
22952    /// * `isStatic` - is the method static or not?
22953    ///
22954    ///
22955    /// # Returns
22956    /// a local reference that refers to the same field as the jfieldID or null on erro
22957    ///
22958    /// # Throws Java Exception
22959    /// * `OutOfMemoryError` - if the jvm runs out of memory.
22960    ///
22961    /// # Panics
22962    /// if asserts feature is enabled and UB was detected
22963    ///
22964    /// # Safety
22965    /// Current thread must not be detached from JNI.
22966    ///
22967    /// Current thread must not be currently throwing an exception.
22968    ///
22969    /// Current thread does not hold a critical reference.
22970    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
22971    ///
22972    /// `cls` must be a valid non-null reference to a Class and not be garbage collected.
22973    /// `jfieldID` must refer to a field in `cls` and must be either static or not static depending on the `isStatic` flag.
22974    ///
22975    pub unsafe fn ToReflectedField(&self, cls: jclass, jfieldID: jfieldID, isStatic: jboolean) -> jobject {
22976        unsafe {
22977            #[cfg(feature = "asserts")]
22978            {
22979                self.check_not_critical("ToReflectedField");
22980                self.check_no_exception("ToReflectedField");
22981                assert!(!cls.is_null(), "ToReflectedField class must not be null");
22982                assert!(!jfieldID.is_null(), "ToReflectedField field must not be null");
22983            }
22984            self.jni::<extern "system" fn(JNIEnvVTable, jclass, jfieldID, jboolean) -> jobject>(12)(self.vtable, cls, jfieldID, isStatic)
22985        }
22986    }
22987
22988    ///
22989    /// Returns the `JavaVM` assosicated with this `JNIEnv`
22990    ///
22991    /// <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetJavaVM>
22992    ///
22993    /// # Panics
22994    /// if the JVM does not return an error but refuses to set the `JavaVM` pointer.
22995    ///
22996    /// # Returns
22997    /// the `JavaVM` "object" or an error code.
22998    ///
22999    /// # Errors
23000    /// JNI implementation specific error constants like `JNI_EINVAL`
23001    ///
23002    /// # Panics
23003    /// if asserts feature is enabled and UB was detected
23004    ///
23005    /// # Safety
23006    /// Current thread must not be detached from JNI.
23007    ///
23008    /// Current thread must not be currently throwing an exception.
23009    ///
23010    /// Current thread does not hold a critical reference.
23011    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23012    ///
23013    pub unsafe fn GetJavaVM(&self) -> Result<JavaVM, jint> {
23014        unsafe {
23015            #[cfg(feature = "asserts")]
23016            {
23017                self.check_not_critical("GetJavaVM");
23018                self.check_no_exception("GetJavaVM");
23019            }
23020            let mut r: JNIInvPtr = SyncMutPtr::null();
23021            let res = self.jni::<extern "system" fn(JNIEnvVTable, *mut JNIInvPtr) -> jint>(219)(self.vtable, &raw mut r);
23022            if res != 0 {
23023                return Err(res);
23024            }
23025            assert!(!r.is_null(), "GetJavaVM returned 0 but did not set JVM pointer");
23026            Ok(JavaVM { vtable: r })
23027        }
23028    }
23029
23030    ///
23031    /// Returns the module of the given class.
23032    ///
23033    /// <https://docs.oracle.com/en/java/javase/21/docs/specs/jni/functions.html#getmodule>
23034    ///
23035    /// # Arguments
23036    /// * `cls`
23037    ///     * must not be null
23038    ///     * must not be garbage collected
23039    ///     * must refer to a class
23040    ///
23041    /// # Returns
23042    /// a local reference to the module object.
23043    ///
23044    /// # Panics
23045    /// if asserts feature is enabled and UB was detected
23046    ///
23047    /// # Safety
23048    /// Current thread must not be detached from JNI.
23049    ///
23050    /// Current thread must not be currently throwing an exception.
23051    ///
23052    /// Current thread does not hold a critical reference.
23053    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23054    ///
23055    /// The JVM must be at least Java 9
23056    ///
23057    /// `cls` must refer to a non-null class that is not yet garbage collected.
23058    ///
23059    pub unsafe fn GetModule(&self, cls: jclass) -> jobject {
23060        unsafe {
23061            #[cfg(feature = "asserts")]
23062            {
23063                self.check_not_critical("GetModule");
23064                self.check_no_exception("GetModule");
23065                assert!(self.GetVersion() >= JNI_VERSION_9);
23066            }
23067
23068            self.jni::<extern "system" fn(JNIEnvVTable, jclass) -> jobject>(233)(self.vtable, cls)
23069        }
23070    }
23071
23072    ///
23073    /// Returns the module of the given class.
23074    ///
23075    /// <https://docs.oracle.com/en/java/javase/21/docs/specs/jni/functions.html#isvirtualthread>
23076    ///
23077    /// # Arguments
23078    /// * `thread`
23079    ///     * must not be null
23080    ///     * must not be garbage collected
23081    ///     * must refer to a java.lang.Thread
23082    ///
23083    /// # Returns
23084    /// true if the thread is virtual, false if not.
23085    ///
23086    /// # Panics
23087    /// if asserts feature is enabled and UB was detected
23088    ///
23089    /// # Safety
23090    /// Current thread must not be detached from JNI.
23091    ///
23092    /// Current thread must not be currently throwing an exception.
23093    ///
23094    /// Current thread does not hold a critical reference.
23095    /// * <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical>
23096    ///
23097    /// The JVM must be at least Java 21
23098    ///
23099    /// `thread` must refer to a non-null java.lang.Thread that is not yet garbage collected.
23100    ///
23101    pub unsafe fn IsVirtualThread(&self, thread: jobject) -> jboolean {
23102        unsafe {
23103            #[cfg(feature = "asserts")]
23104            {
23105                self.check_not_critical("IsVirtualThread");
23106                self.check_no_exception("IsVirtualThread");
23107                assert!(self.GetVersion() >= JNI_VERSION_21);
23108            }
23109            self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jboolean>(234)(self.vtable, thread)
23110        }
23111    }
23112
23113    /// Checks that we are not in a critical section currently.
23114    #[cfg(feature = "asserts")]
23115    unsafe fn check_not_critical(self, context: &str) {
23116        Self::CRITICAL_POINTERS.with(|set| {
23117            let sz = set.borrow_mut().len();
23118            assert_eq!(
23119                sz, 0,
23120                "{context} cannot be called now, because there are {sz} critical pointers into primitive arrays that have not been released by the current thread."
23121            );
23122        });
23123        Self::CRITICAL_STRINGS.with(|set| {
23124            let sz = set.borrow_mut().len();
23125            assert_eq!(
23126                sz, 0,
23127                "{context} cannot be called now, because there are {sz} critical pointers into strings that have not been released by the current thread."
23128            );
23129        });
23130
23131        _ = self;
23132    }
23133
23134    /// Checks that obj is an array of any type
23135    #[cfg(feature = "asserts")]
23136    unsafe fn check_is_array(self, obj: jobject, context: &str) {
23137        unsafe {
23138            assert!(!obj.is_null(), "{context} cannot check if arg is array because arg is null");
23139            let cl = self.GetObjectClass(obj);
23140            assert!(!cl.is_null(), "{context} arg.getClass() is null?");
23141            let clazz = self.GetObjectClass(cl);
23142            assert!(!clazz.is_null(), "{context} Class#getClass() is null?");
23143
23144            let is_array = self.GetMethodID(clazz, "isArray", "()Z");
23145            let r = self.CallBooleanMethod0(cl, is_array);
23146            if self.ExceptionCheck() {
23147                self.ExceptionDescribe();
23148                panic!("{context} Class#isArray() is throws?");
23149            }
23150
23151            assert!(r, "{context} arg is not an array");
23152
23153            self.DeleteLocalRef(cl);
23154            self.DeleteLocalRef(clazz);
23155        }
23156    }
23157
23158    /// Checks that no exception is currently thrown
23159    #[cfg(feature = "asserts")]
23160    unsafe fn check_no_exception(self, context: &str) {
23161        unsafe {
23162            if !self.ExceptionCheck() {
23163                return;
23164            }
23165
23166            self.ExceptionDescribe();
23167            panic!("{context} exception is thrown and not handled");
23168        }
23169    }
23170
23171    /// Checks if the object is a valid reference or null
23172    #[cfg(feature = "asserts")]
23173    unsafe fn check_ref_obj_permit_null(self, context: &str, obj: jobject) {
23174        unsafe {
23175            if obj.is_null() {
23176                return;
23177            }
23178
23179            if self.ExceptionCheck() {
23180                //We cannot do this check currently...
23181                return;
23182            }
23183
23184            assert_ne!(self.GetObjectRefType(obj), jobjectRefType::JNIInvalidRefType, "{context} ref is invalid");
23185        }
23186    }
23187
23188    /// Checks if the object is a valid non-null reference
23189    #[cfg(feature = "asserts")]
23190    unsafe fn check_ref_obj(self, context: &str, obj: jobject) {
23191        unsafe {
23192            assert!(!obj.is_null(), "{context} ref is null");
23193
23194            if self.ExceptionCheck() {
23195                //We cannot do this check currently...
23196                return;
23197            }
23198
23199            let cl = self.FindClass("java/lang/System");
23200            assert!(!cl.is_null(), "java/lang/System not found?");
23201
23202            let cname = CString::new("gc").unwrap_unchecked();
23203            let csig = CString::new("()V").unwrap_unchecked();
23204            //GetStaticMethodID
23205            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());
23206
23207            assert!(!gc_method.is_null(), "java/lang/System#gc() not found?");
23208
23209            match self.GetObjectRefType(obj) {
23210                jobjectRefType::JNIInvalidRefType => panic!("{context} ref is invalid"),
23211                jobjectRefType::JNIWeakGlobalRefType => {
23212                    //This bad practice, but sadly sometimes valid.
23213                    //I.e. caller holds a strong reference and "knows" the weak ref cannot be GC'ed during the call.
23214                    //Good practice would be to use the strong ref to make the call but sadly JVM doesn't enforce this.
23215                    //This is just best effort really since we have absolutely NO clue when the GC will run.
23216                    //CallStaticVoidMethod
23217                    self.jni::<extern "C" fn(JNIEnvVTable, jobject, jmethodID)>(141)(self.vtable, obj, gc_method);
23218                    assert!(!self.IsSameObject(obj, null_mut()), "{context} weak reference that has already been garbage collected");
23219                }
23220                _ => {}
23221            }
23222
23223            self.DeleteLocalRef(cl);
23224        }
23225    }
23226
23227    /// Checks if the class is a throwable
23228    #[cfg(feature = "asserts")]
23229    unsafe fn check_is_exception_class(self, context: &str, obj: jclass) {
23230        unsafe {
23231            self.check_is_class(context, obj);
23232            let throwable_cl = self.FindClass("java/lang/Throwable");
23233            assert!(!throwable_cl.is_null(), "{context} java/lang/Throwable not found???");
23234            assert!(self.IsAssignableFrom(obj, throwable_cl), "{context} class is not throwable");
23235            self.DeleteLocalRef(throwable_cl);
23236        }
23237    }
23238
23239    /// Checks if the class is not abstract
23240    #[cfg(feature = "asserts")]
23241    unsafe fn check_is_not_abstract(self, context: &str, obj: jclass) {
23242        unsafe {
23243            self.check_is_class(context, obj);
23244            let class_cl = self.FindClass("java/lang/Class");
23245            assert!(!class_cl.is_null(), "{context} java/lang/Class not found???");
23246            let meth = self.GetMethodID(class_cl, "getModifiers", "()I");
23247            assert!(!meth.is_null(), "{context} java/lang/Class#getModifiers not found???");
23248            let mods = self.CallIntMethod0(obj, meth);
23249            self.DeleteLocalRef(class_cl);
23250            if self.ExceptionCheck() {
23251                self.ExceptionDescribe();
23252                panic!("{context} java/lang/Class#getModifiers throws?");
23253            }
23254
23255            let mod_cl = self.FindClass("java/lang/reflect/Modifier");
23256            assert!(!mod_cl.is_null(), "{context} java/lang/reflect/Modifier not found???");
23257            let mod_field = self.GetStaticFieldID(mod_cl, "ABSTRACT", "I");
23258            assert!(!mod_field.is_null(), "{context} java/lang/reflect/Modifier.ABSTRACT not found???");
23259            let amod = self.GetStaticIntField(mod_cl, mod_field);
23260            self.DeleteLocalRef(mod_cl);
23261
23262            assert_eq!(mods & amod, 0, "{context} class is abstract");
23263        }
23264    }
23265
23266    /// Checks if obj is a class.
23267    #[cfg(feature = "asserts")]
23268    unsafe fn check_is_class(self, context: &str, obj: jclass) {
23269        unsafe {
23270            assert!(!obj.is_null(), "{context} class is null");
23271            self.check_ref_obj(context, obj);
23272
23273            let class_cl = self.FindClass("java/lang/Class");
23274            assert!(!class_cl.is_null(), "{context} java/lang/Class not found???");
23275            //GET OBJECT CLASS
23276            let tcl = self.jni::<extern "system" fn(JNIEnvVTable, jobject) -> jobject>(31)(self.vtable, obj);
23277            assert!(self.IsSameObject(tcl, class_cl), "{context} not a class!");
23278            self.DeleteLocalRef(tcl);
23279            self.DeleteLocalRef(class_cl);
23280        }
23281    }
23282
23283    /// Checks if the `obj` is a classloader or null
23284    #[cfg(feature = "asserts")]
23285    unsafe fn check_is_classloader_or_null(self, context: &str, obj: jobject) {
23286        unsafe {
23287            if obj.is_null() {
23288                return;
23289            }
23290            self.check_ref_obj(context, obj);
23291            let classloader_cl = self.FindClass("java/lang/ClassLoader");
23292            assert!(!classloader_cl.is_null(), "{context} java/lang/ClassLoader not found");
23293            assert!(self.IsInstanceOf(obj, classloader_cl), "{context} argument is not a valid instanceof ClassLoader");
23294
23295            self.DeleteLocalRef(classloader_cl);
23296        }
23297    }
23298
23299    /// Checks if the argument refers toa string
23300    #[cfg(feature = "asserts")]
23301    unsafe fn check_if_arg_is_string(self, src: &str, jobject: jobject) {
23302        unsafe {
23303            if jobject.is_null() {
23304                return;
23305            }
23306
23307            let clazz = self.GetObjectClass(jobject);
23308            assert!(!clazz.is_null(), "{src} string.class is null?");
23309            let str_class = self.FindClass("java/lang/String");
23310            assert!(!str_class.is_null(), "{src} java/lang/String not found?");
23311            assert!(self.IsSameObject(clazz, str_class), "{src} Non string passed to GetStringCritical");
23312            self.DeleteLocalRef(clazz);
23313            self.DeleteLocalRef(str_class);
23314        }
23315    }
23316
23317    /// Checks if the field type of a static field matches
23318    #[cfg(feature = "asserts")]
23319    unsafe fn check_field_type_static(self, context: &str, obj: jclass, fieldID: jfieldID, ty: &str) {
23320        unsafe {
23321            self.check_is_class(context, obj);
23322            assert!(!fieldID.is_null(), "{context} fieldID is null");
23323            let f = self.ToReflectedField(obj, fieldID, true);
23324            assert!(!f.is_null(), "{context} -> ToReflectedField returned null");
23325            let field_cl = self.FindClass("java/lang/reflect/Field");
23326            assert!(!f.is_null(), "{context} java/lang/reflect/Method not found???");
23327            let field_rtyp = self.GetMethodID(field_cl, "getType", "()Ljava/lang/Class;");
23328            assert!(!field_rtyp.is_null(), "{context} java/lang/reflect/Field#getType not found???");
23329            //CallObjectMethodA
23330            let rtc = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, f, field_rtyp, null());
23331            assert!(!rtc.is_null(), "{context} java/lang/reflect/Field#getType returned null???");
23332            self.DeleteLocalRef(field_cl);
23333            self.DeleteLocalRef(f);
23334            let class_cl = self.FindClass("java/lang/Class");
23335            assert!(!class_cl.is_null(), "{context} java/lang/Class not found???");
23336            let class_name = self.GetMethodID(class_cl, "getName", "()Ljava/lang/String;");
23337            assert!(!class_name.is_null(), "{context} java/lang/Class#getName not found???");
23338            //CallObjectMethodA
23339            let name_str = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, rtc, class_name, null());
23340            assert!(!name_str.is_null(), "{context} java/lang/Class#getName returned null??? Class has no name???");
23341            self.DeleteLocalRef(rtc);
23342            let the_name = self
23343                .GetStringUTFChars_as_string(name_str)
23344                .unwrap_or_else(|| panic!("{context} failed to get/parse classname???"));
23345            self.DeleteLocalRef(class_cl);
23346            self.DeleteLocalRef(name_str);
23347            if the_name.as_str().eq(ty) {
23348                return;
23349            }
23350
23351            if ty.eq("object") {
23352                match the_name.as_str() {
23353                    "long" | "int" | "short" | "byte" | "char" | "float" | "double" | "boolean" => {
23354                        panic!("{context} type of field is {the_name} but expected object");
23355                    }
23356                    _ => {
23357                        return;
23358                    }
23359                }
23360            }
23361
23362            panic!("{context} type of field is {the_name} but expected {ty}");
23363        }
23364    }
23365
23366    /// Checks if the return type of a static method matches
23367    #[cfg(feature = "asserts")]
23368    unsafe fn check_return_type_static(self, context: &str, obj: jclass, methodID: jmethodID, ty: &str) {
23369        unsafe {
23370            self.check_is_class(context, obj);
23371            assert!(!methodID.is_null(), "{context} methodID is null");
23372            let m = self.ToReflectedMethod(obj, methodID, true);
23373            assert!(!m.is_null(), "{context} -> ToReflectedMethod returned null");
23374            let meth_cl = self.FindClass("java/lang/reflect/Method");
23375            assert!(!m.is_null(), "{context} java/lang/reflect/Method not found???");
23376            let meth_rtyp = self.GetMethodID(meth_cl, "getReturnType", "()Ljava/lang/Class;");
23377            assert!(!meth_rtyp.is_null(), "{context} java/lang/reflect/Method#getReturnType not found???");
23378            //CallObjectMethodA
23379            let rtc = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, m, meth_rtyp, null());
23380            self.DeleteLocalRef(meth_cl);
23381            self.DeleteLocalRef(m);
23382            if rtc.is_null() {
23383                if ty.eq("void") {
23384                    return;
23385                }
23386
23387                panic!("{context} return type of method is void but expected {ty}");
23388            }
23389            let class_cl = self.FindClass("java/lang/Class");
23390            assert!(!class_cl.is_null(), "{context} java/lang/Class not found???");
23391            let class_name = self.GetMethodID(class_cl, "getName", "()Ljava/lang/String;");
23392            assert!(!class_name.is_null(), "{context} java/lang/Class#getName not found???");
23393            //CallObjectMethodA
23394            let name_str = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, rtc, class_name, null());
23395            assert!(!name_str.is_null(), "{context} java/lang/Class#getName returned null??? Class has no name???");
23396            self.DeleteLocalRef(rtc);
23397            let the_name = self
23398                .GetStringUTFChars_as_string(name_str)
23399                .unwrap_or_else(|| panic!("{context} failed to get/parse classname???"));
23400            self.DeleteLocalRef(class_cl);
23401            self.DeleteLocalRef(name_str);
23402            if the_name.as_str().eq(ty) {
23403                return;
23404            }
23405
23406            if ty.eq("object") {
23407                match the_name.as_str() {
23408                    "void" | "long" | "int" | "short" | "byte" | "char" | "float" | "double" | "boolean" => {
23409                        panic!("{context} return type of method is {the_name} but expected object");
23410                    }
23411                    _ => {
23412                        return;
23413                    }
23414                }
23415            }
23416
23417            panic!("{context} return type of method is {the_name} but expected {ty}");
23418        }
23419    }
23420
23421    /// Checks if the parameter types for a static fn match
23422    #[cfg(feature = "asserts")]
23423    unsafe fn check_parameter_types_static<T: JType>(self, context: &str, clazz: jclass, methodID: jmethodID, param1: T, idx: jsize, count: jsize) {
23424        unsafe {
23425            self.check_is_class(context, clazz);
23426            assert!(!methodID.is_null(), "{context} methodID is null");
23427            let java_method = self.ToReflectedMethod(clazz, methodID, true);
23428            assert!(!java_method.is_null(), "{context} -> ToReflectedMethod returned null");
23429            let meth_cl = self.FindClass("java/lang/reflect/Method");
23430            assert!(!java_method.is_null(), "{context} java/lang/reflect/Method not found???");
23431            let meth_params = self.GetMethodID(meth_cl, "getParameterTypes", "()[Ljava/lang/Class;");
23432            assert!(!meth_params.is_null(), "{context} java/lang/reflect/Method#getParameterTypes not found???");
23433
23434            //CallObjectMethodA
23435            let parameter_array = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, java_method, meth_params, null());
23436            self.DeleteLocalRef(meth_cl);
23437            self.DeleteLocalRef(java_method);
23438            assert!(!parameter_array.is_null(), "{context} java/lang/reflect/Method#getParameterTypes return null???");
23439            let parameter_count = self.GetArrayLength(parameter_array);
23440            assert_eq!(parameter_count, count, "{context} wrong number of method parameters");
23441            let param1_class = self.GetObjectArrayElement(parameter_array, idx);
23442            assert!(!param1_class.is_null(), "{context} java/lang/reflect/Method#getParameterTypes[{idx}] is null???");
23443            self.DeleteLocalRef(parameter_array);
23444
23445            let class_cl = self.FindClass("java/lang/Class");
23446            assert!(!class_cl.is_null(), "{context} java/lang/Class not found???");
23447            let class_name = self.GetMethodID(class_cl, "getName", "()Ljava/lang/String;");
23448            assert!(!class_name.is_null(), "{context} java/lang/Class#getName not found???");
23449            let class_is_primitive = self.GetMethodID(class_cl, "isPrimitive", "()Z");
23450            assert!(!class_is_primitive.is_null(), "{context} java/lang/Class#isPrimitive not found???");
23451
23452            //CallObjectMethodA
23453            let name_str = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, param1_class, class_name, null());
23454            assert!(!name_str.is_null(), "{context} java/lang/Class#getName returned null??? Class has no name???");
23455            //CallBooleanMethodA
23456            let param1_is_primitive =
23457                self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jboolean>(39)(self.vtable, param1_class, class_is_primitive, null());
23458
23459            let the_name = self
23460                .GetStringUTFChars_as_string(name_str)
23461                .unwrap_or_else(|| panic!("{context} failed to get/parse classname???"));
23462            self.DeleteLocalRef(class_cl);
23463            self.DeleteLocalRef(name_str);
23464
23465            match T::jtype_id() {
23466                'Z' => assert_eq!("boolean", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed boolean"),
23467                'B' => assert_eq!("byte", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed byte"),
23468                'S' => assert_eq!("short", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed short"),
23469                'C' => assert_eq!("char", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed char"),
23470                'I' => assert_eq!("int", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed int"),
23471                'J' => assert_eq!("long", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed long"),
23472                'F' => assert_eq!("float", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed float"),
23473                'D' => assert_eq!("double", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed double"),
23474                'L' => {
23475                    assert!(!param1_is_primitive, "{context} param{idx} wrong type. Method has {the_name} but passed an object or null");
23476                    let jt: jtype = param1.into();
23477                    let obj = jt.object;
23478                    if !obj.is_null() {
23479                        assert!(
23480                            self.IsInstanceOf(obj, param1_class),
23481                            "{context} param{idx} wrong type. Method has {the_name} but passed an object that is not null and not instanceof"
23482                        );
23483                    }
23484                }
23485                _ => unreachable!("{}", T::jtype_id()),
23486            }
23487
23488            self.DeleteLocalRef(param1_class);
23489        }
23490    }
23491
23492    /// Checks if the parameter type matches the constructor
23493    #[cfg(feature = "asserts")]
23494    unsafe fn check_parameter_types_constructor<T: JType>(self, context: &str, clazz: jclass, methodID: jmethodID, param1: T, idx: jsize, count: jsize) {
23495        unsafe {
23496            self.check_ref_obj(context, clazz);
23497            assert!(!clazz.is_null(), "{context} obj.class is null??");
23498            assert!(!methodID.is_null(), "{context} methodID is null");
23499            let java_method = self.ToReflectedMethod(clazz, methodID, false);
23500            assert!(!java_method.is_null(), "{context} -> ToReflectedMethod returned null");
23501            let meth_cl = self.FindClass("java/lang/reflect/Method");
23502            assert!(!java_method.is_null(), "{context} java/lang/reflect/Method not found???");
23503            let meth_params = self.GetMethodID(meth_cl, "getParameterTypes", "()[Ljava/lang/Class;");
23504            assert!(!meth_params.is_null(), "{context} java/lang/reflect/Method#getParameterTypes not found???");
23505
23506            //CallObjectMethodA
23507            let parameter_array = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, java_method, meth_params, null());
23508            self.DeleteLocalRef(meth_cl);
23509            self.DeleteLocalRef(java_method);
23510            assert!(!parameter_array.is_null(), "{context} java/lang/reflect/Method#getParameterTypes return null???");
23511            let parameter_count = self.GetArrayLength(parameter_array);
23512            assert_eq!(parameter_count, count, "{context} wrong number of method parameters");
23513            let param1_class = self.GetObjectArrayElement(parameter_array, idx);
23514            assert!(!param1_class.is_null(), "{context} java/lang/reflect/Method#getParameterTypes[{idx}] is null???");
23515            self.DeleteLocalRef(parameter_array);
23516
23517            let class_cl = self.FindClass("java/lang/Class");
23518            assert!(!class_cl.is_null(), "{context} java/lang/Class not found???");
23519            let class_name = self.GetMethodID(class_cl, "getName", "()Ljava/lang/String;");
23520            assert!(!class_name.is_null(), "{context} java/lang/Class#getName not found???");
23521            let class_is_primitive = self.GetMethodID(class_cl, "isPrimitive", "()Z");
23522            assert!(!class_is_primitive.is_null(), "{context} java/lang/Class#isPrimitive not found???");
23523
23524            //CallObjectMethodA
23525            let name_str = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, param1_class, class_name, null());
23526            assert!(!name_str.is_null(), "{context} java/lang/Class#getName returned null??? Class has no name???");
23527            //CallBooleanMethodA
23528            let param1_is_primitive =
23529                self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jboolean>(39)(self.vtable, param1_class, class_is_primitive, null());
23530
23531            let the_name = self
23532                .GetStringUTFChars_as_string(name_str)
23533                .unwrap_or_else(|| panic!("{context} failed to get/parse classname???"));
23534            self.DeleteLocalRef(class_cl);
23535            self.DeleteLocalRef(name_str);
23536
23537            match T::jtype_id() {
23538                'Z' => assert_eq!("boolean", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed boolean"),
23539                'B' => assert_eq!("byte", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed byte"),
23540                'S' => assert_eq!("short", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed short"),
23541                'C' => assert_eq!("char", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed char"),
23542                'I' => assert_eq!("int", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed int"),
23543                'J' => assert_eq!("long", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed long"),
23544                'F' => assert_eq!("float", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed float"),
23545                'D' => assert_eq!("double", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed double"),
23546                'L' => {
23547                    assert!(!param1_is_primitive, "{context} param{idx} wrong type. Method has {the_name} but passed an object or null");
23548                    let jt: jtype = param1.into();
23549                    let obj = jt.object;
23550                    if !obj.is_null() {
23551                        assert!(
23552                            self.IsInstanceOf(obj, param1_class),
23553                            "{context} param{idx} wrong type. Method has {the_name} but passed an object that is not null and not instanceof"
23554                        );
23555                    }
23556                }
23557                _ => unreachable!("{}", T::jtype_id()),
23558            }
23559
23560            self.DeleteLocalRef(param1_class);
23561        }
23562    }
23563
23564    /// checks if the method parameter matches the provided argument
23565    #[cfg(feature = "asserts")]
23566    unsafe fn check_parameter_types_object<T: JType>(self, context: &str, obj: jobject, methodID: jmethodID, param1: T, idx: jsize, count: jsize) {
23567        unsafe {
23568            assert!(!obj.is_null(), "{context} obj is null");
23569            self.check_ref_obj(context, obj);
23570            let clazz = self.GetObjectClass(obj);
23571            assert!(!clazz.is_null(), "{context} obj.class is null??");
23572            assert!(!methodID.is_null(), "{context} methodID is null");
23573            let java_method = self.ToReflectedMethod(clazz, methodID, false);
23574            assert!(!java_method.is_null(), "{context} -> ToReflectedMethod returned null");
23575            self.DeleteLocalRef(clazz);
23576            let meth_cl = self.FindClass("java/lang/reflect/Method");
23577            assert!(!java_method.is_null(), "{context} java/lang/reflect/Method not found???");
23578            let meth_params = self.GetMethodID(meth_cl, "getParameterTypes", "()[Ljava/lang/Class;");
23579            assert!(!meth_params.is_null(), "{context} java/lang/reflect/Method#getParameterTypes not found???");
23580
23581            //CallObjectMethodA
23582            let parameter_array = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, java_method, meth_params, null());
23583            self.DeleteLocalRef(meth_cl);
23584            self.DeleteLocalRef(java_method);
23585            assert!(!parameter_array.is_null(), "{context} java/lang/reflect/Method#getParameterTypes return null???");
23586            let parameter_count = self.GetArrayLength(parameter_array);
23587            assert_eq!(parameter_count, count, "{context} wrong number of method parameters");
23588            let param1_class = self.GetObjectArrayElement(parameter_array, idx);
23589            assert!(!param1_class.is_null(), "{context} java/lang/reflect/Method#getParameterTypes[{idx}] is null???");
23590            self.DeleteLocalRef(parameter_array);
23591
23592            let class_cl = self.FindClass("java/lang/Class");
23593            assert!(!class_cl.is_null(), "{context} java/lang/Class not found???");
23594            let class_name = self.GetMethodID(class_cl, "getName", "()Ljava/lang/String;");
23595            assert!(!class_name.is_null(), "{context} java/lang/Class#getName not found???");
23596            let class_is_primitive = self.GetMethodID(class_cl, "isPrimitive", "()Z");
23597            assert!(!class_is_primitive.is_null(), "{context} java/lang/Class#isPrimitive not found???");
23598
23599            //CallObjectMethodA
23600            let name_str = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, param1_class, class_name, null());
23601            assert!(!name_str.is_null(), "{context} java/lang/Class#getName returned null??? Class has no name???");
23602            //CallBooleanMethodA
23603            let param1_is_primitive =
23604                self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jboolean>(39)(self.vtable, param1_class, class_is_primitive, null());
23605
23606            let the_name = self
23607                .GetStringUTFChars_as_string(name_str)
23608                .unwrap_or_else(|| panic!("{context} failed to get/parse classname???"));
23609
23610            self.DeleteLocalRef(class_cl);
23611            self.DeleteLocalRef(name_str);
23612
23613            match T::jtype_id() {
23614                'Z' => assert_eq!("boolean", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed boolean"),
23615                'B' => assert_eq!("byte", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed byte"),
23616                'S' => assert_eq!("short", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed short"),
23617                'C' => assert_eq!("char", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed char"),
23618                'I' => assert_eq!("int", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed int"),
23619                'J' => assert_eq!("long", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed long"),
23620                'F' => assert_eq!("float", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed float"),
23621                'D' => assert_eq!("double", the_name, "{context} param{idx} wrong type. Method has {the_name} but passed double"),
23622                'L' => {
23623                    assert!(!param1_is_primitive, "{context} param{idx} wrong type. Method has {the_name} but passed an object or null");
23624                    let jt: jtype = param1.into();
23625                    let obj = jt.object;
23626                    if !obj.is_null() {
23627                        assert!(
23628                            self.IsInstanceOf(obj, param1_class),
23629                            "{context} param{idx} wrong type. Method has {the_name} but passed an object that is not null and not instanceof"
23630                        );
23631                    }
23632                }
23633                _ => unreachable!("{}", T::jtype_id()),
23634            }
23635
23636            self.DeleteLocalRef(param1_class);
23637        }
23638    }
23639
23640    /// Checks if the function returns an object
23641    #[cfg(feature = "asserts")]
23642    unsafe fn check_return_type_object(self, context: &str, obj: jobject, methodID: jmethodID, ty: &str) {
23643        unsafe {
23644            assert!(!obj.is_null(), "{context} obj is null");
23645            self.check_ref_obj(context, obj);
23646            let clazz = self.GetObjectClass(obj);
23647            assert!(!clazz.is_null(), "{context} obj.class is null??");
23648            assert!(!methodID.is_null(), "{context} methodID is null");
23649            let m = self.ToReflectedMethod(clazz, methodID, false);
23650            self.DeleteLocalRef(clazz);
23651            assert!(!m.is_null(), "{context} -> ToReflectedMethod returned null");
23652            let meth_cl = self.FindClass("java/lang/reflect/Method");
23653            assert!(!m.is_null(), "{context} java/lang/reflect/Method not found???");
23654            let meth_rtyp = self.GetMethodID(meth_cl, "getReturnType", "()Ljava/lang/Class;");
23655            assert!(!meth_rtyp.is_null(), "{context} java/lang/reflect/Method#getReturnType not found???");
23656            //CallObjectMethodA
23657            let rtc = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, m, meth_rtyp, null());
23658            self.DeleteLocalRef(meth_cl);
23659            self.DeleteLocalRef(m);
23660            if rtc.is_null() {
23661                if ty.eq("void") {
23662                    return;
23663                }
23664
23665                panic!("{context} return type of method is void but expected {ty}");
23666            }
23667            let class_cl = self.FindClass("java/lang/Class");
23668            assert!(!class_cl.is_null(), "{context} java/lang/Class not found???");
23669            let class_name = self.GetMethodID(class_cl, "getName", "()Ljava/lang/String;");
23670            assert!(!class_name.is_null(), "{context} java/lang/Class#getName not found???");
23671            //CallObjectMethodA
23672            let name_str = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, rtc, class_name, null());
23673            assert!(!name_str.is_null(), "{context} java/lang/Class#getName returned null??? Class has no name???");
23674            self.DeleteLocalRef(rtc);
23675            let the_name = self
23676                .GetStringUTFChars_as_string(name_str)
23677                .unwrap_or_else(|| panic!("{context} failed to get/parse classname???"));
23678            self.DeleteLocalRef(class_cl);
23679            self.DeleteLocalRef(name_str);
23680            if the_name.as_str().eq(ty) {
23681                return;
23682            }
23683
23684            if ty.eq("object") {
23685                match the_name.as_str() {
23686                    "void" | "long" | "int" | "short" | "byte" | "char" | "float" | "double" | "boolean" => {
23687                        panic!("{context} return type of method is {the_name} but expected object");
23688                    }
23689                    _ => {
23690                        return;
23691                    }
23692                }
23693            }
23694
23695            panic!("{context} return type of method is {the_name} but expected {ty}");
23696        }
23697    }
23698
23699    /// checks if the field type is any object.
23700    #[cfg(feature = "asserts")]
23701    unsafe fn check_field_type_object(self, context: &str, obj: jclass, fieldID: jfieldID, ty: &str) {
23702        unsafe {
23703            assert!(!obj.is_null(), "{context} obj is null");
23704            let clazz = self.GetObjectClass(obj);
23705            assert!(!clazz.is_null(), "{context} obj.class is null??");
23706            assert!(!fieldID.is_null(), "{context} fieldID is null");
23707            let f = self.ToReflectedField(clazz, fieldID, false);
23708            assert!(!f.is_null(), "{context} -> ToReflectedField returned null");
23709            let field_cl = self.FindClass("java/lang/reflect/Field");
23710            assert!(!f.is_null(), "{context} java/lang/reflect/Method not found???");
23711            let field_rtyp = self.GetMethodID(field_cl, "getType", "()Ljava/lang/Class;");
23712            assert!(!field_rtyp.is_null(), "{context} java/lang/reflect/Field#getType not found???");
23713            //CallObjectMethodA
23714            let rtc = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, f, field_rtyp, null());
23715            assert!(!rtc.is_null(), "{context} java/lang/reflect/Field#getType returned null???");
23716            self.DeleteLocalRef(field_cl);
23717            self.DeleteLocalRef(f);
23718            let class_cl = self.FindClass("java/lang/Class");
23719            assert!(!class_cl.is_null(), "{context} java/lang/Class not found???");
23720            let class_name = self.GetMethodID(class_cl, "getName", "()Ljava/lang/String;");
23721            assert!(!class_name.is_null(), "{context} java/lang/Class#getName not found???");
23722            //CallObjectMethodA
23723            let name_str = self.jni::<extern "system" fn(JNIEnvVTable, jobject, jmethodID, *const jtype) -> jobject>(36)(self.vtable, rtc, class_name, null());
23724            assert!(!name_str.is_null(), "{context} java/lang/Class#getName returned null??? Class has no name???");
23725            self.DeleteLocalRef(rtc);
23726            let the_name = self
23727                .GetStringUTFChars_as_string(name_str)
23728                .unwrap_or_else(|| panic!("{context} failed to get/parse classname???"));
23729            self.DeleteLocalRef(class_cl);
23730            self.DeleteLocalRef(name_str);
23731            if the_name.as_str().eq(ty) {
23732                return;
23733            }
23734
23735            if ty.eq("object") {
23736                match the_name.as_str() {
23737                    "long" | "int" | "short" | "byte" | "char" | "float" | "double" | "boolean" => {
23738                        panic!("{context} type of field is {the_name} but expected object");
23739                    }
23740                    _ => {
23741                        return;
23742                    }
23743                }
23744            }
23745
23746            panic!("{context} type of field is {the_name} but expected {ty}");
23747        }
23748    }
23749}
23750
23751/// Module that contains the dll/so imports from the JVM.
23752/// This module should only be used when writing a library that is loaded by the JVM
23753/// using `System.load` or `System.loadLibrary`
23754#[cfg(feature = "dynlink")]
23755mod dynlink {
23756    use crate::{JNIEnv, JNIInvPtr, JavaVMInitArgs, jint, jsize};
23757
23758    unsafe extern "system" {
23759        pub fn JNI_CreateJavaVM(invoker: *mut JNIInvPtr, env: *mut JNIEnv, initargs: *mut JavaVMInitArgs) -> jint;
23760        pub fn JNI_GetCreatedJavaVMs(array: *mut JNIInvPtr, len: jsize, out: *mut jsize) -> jint;
23761    }
23762}
23763
23764/// type signature for the extern fn in the jvm
23765#[cfg(not(feature = "dynlink"))]
23766type JNI_CreateJavaVM = unsafe extern "C" fn(*mut JNIInvPtr, *mut JNIEnv, *mut JavaVMInitArgs) -> jint;
23767
23768/// type signature for the extern fn in the jvm
23769#[cfg(not(feature = "dynlink"))]
23770type JNI_GetCreatedJavaVMs = unsafe extern "C" fn(*mut JNIInvPtr, jsize, *mut jsize) -> jint;
23771
23772/// Data holder for the raw JVM function pointers.
23773#[cfg(not(feature = "dynlink"))]
23774#[derive(Debug, Copy, Clone)]
23775struct JNIDynamicLink {
23776    /// raw function ptr to `JNI_CreateJavaVM`
23777    JNI_CreateJavaVM: SyncConstPtr<c_void>,
23778    /// raw function ptr to `JNI_GetCreatedJavaVMs`
23779    JNI_GetCreatedJavaVMs: SyncConstPtr<c_void>,
23780}
23781
23782#[cfg(not(feature = "dynlink"))]
23783impl JNIDynamicLink {
23784    /// Constructor with the two pointers
23785    pub fn new(JNI_CreateJavaVM: *const c_void, JNI_GetCreatedJavaVMs: *const c_void) -> Self {
23786        assert!(!JNI_GetCreatedJavaVMs.is_null(), "JNI_GetCreatedJavaVMs is null");
23787
23788        assert!(!JNI_CreateJavaVM.is_null(), "JNI_CreateJavaVM is null");
23789
23790        unsafe {
23791            Self {
23792                JNI_CreateJavaVM: JNI_CreateJavaVM.as_sync_const(),
23793                JNI_GetCreatedJavaVMs: JNI_GetCreatedJavaVMs.as_sync_const(),
23794            }
23795        }
23796    }
23797
23798    /// Get the `JNI_GetCreatedJavaVMs` function pointer
23799    pub fn JNI_CreateJavaVM(&self) -> JNI_CreateJavaVM {
23800        unsafe { core::mem::transmute(self.JNI_CreateJavaVM.inner()) }
23801    }
23802
23803    /// Get the `JNI_GetCreatedJavaVMs` function pointer
23804    pub fn JNI_GetCreatedJavaVMs(&self) -> JNI_GetCreatedJavaVMs {
23805        unsafe { core::mem::transmute(self.JNI_GetCreatedJavaVMs.inner()) }
23806    }
23807}
23808
23809/// State that contains the function pointers to the jvm.
23810#[cfg(not(feature = "dynlink"))]
23811static LINK: once_cell::sync::OnceCell<JNIDynamicLink> = once_cell::sync::OnceCell::new();
23812
23813///
23814/// Call this function to initialize the dynamic linking to the jvm to use the provided function pointers to
23815/// create the jvm.
23816///
23817/// If this function is called more than once then it is a noop, since it is not possible to create
23818/// more than one jvm per process.
23819///
23820#[cfg(not(feature = "dynlink"))]
23821pub fn init_dynamic_link(JNI_CreateJavaVM: *const c_void, JNI_GetCreatedJavaVMs: *const c_void) {
23822    _ = LINK.set(JNIDynamicLink::new(JNI_CreateJavaVM, JNI_GetCreatedJavaVMs));
23823}
23824
23825///
23826/// Call this function to initialize the dynamic linking to the jvm to use the provided function pointers to
23827/// create the jvm.
23828///
23829/// If this function is called more than once then it is a noop, since it is not possible to create
23830/// more than one jvm per process.
23831///
23832#[cfg(feature = "dynlink")]
23833#[allow(clippy::missing_const_for_fn)]
23834pub fn init_dynamic_link(_: *const c_void, _: *const c_void) {
23835    //NOOP, because the dynamic linker already must have preloaded the jvm for linking to succeed.
23836}
23837
23838///
23839/// Returns true if the jvm was loaded by either calling `load_jvm_from_library` or `init_dynamic_link`.
23840///
23841#[cfg(not(feature = "dynlink"))]
23842#[must_use]
23843pub fn is_jvm_loaded() -> bool {
23844    LINK.get().is_some()
23845}
23846
23847///
23848/// Returns true if the jvm was loaded by either calling `load_jvm_from_library` or `init_dynamic_link`.
23849///
23850#[cfg(feature = "dynlink")]
23851#[must_use]
23852#[allow(clippy::missing_const_for_fn)]
23853pub fn is_jvm_loaded() -> bool {
23854    true
23855}
23856
23857///
23858/// Convenience method to load the jvm from a path to libjvm.so or jvm.dll.
23859///
23860/// On success this method does NOT close the handle to the shared object.
23861/// This is usually fine because unloading the jvm is not supported anyway.
23862/// If you do not desire this then use `init_dynamic_link`.
23863///
23864/// # Errors
23865/// if loading the library fails without crashing the process then a String describing the reason why is returned as an error.
23866///
23867/// # Safety
23868/// The Safety of this fn depends on the shared object that will be loaded as a result of this call.
23869///
23870#[cfg(feature = "loadjvm")]
23871#[cfg(not(feature = "dynlink"))]
23872pub unsafe fn load_jvm_from_library(path: &str) -> Result<(), String> {
23873    use std::sync::atomic::{AtomicBool, Ordering};
23874    let latch = AtomicBool::new(false);
23875
23876    LINK.get_or_try_init(|| unsafe {
23877        latch.store(true, Ordering::SeqCst);
23878        let lib = libloading::Library::new(path).map_err(|e| alloc::format!("Failed to load jvm from {path} reason: {e}"))?;
23879
23880        let JNI_CreateJavaVM_ptr = lib
23881            .get::<JNI_CreateJavaVM>(b"JNI_CreateJavaVM\0")
23882            .map_err(|e| alloc::format!("Failed to load jvm from {path} reason: JNI_CreateJavaVM -> {e}"))?
23883            .try_as_raw_ptr()
23884            .ok_or_else(|| alloc::format!("Failed to load jvm from {path} reason: JNI_CreateJavaVM -> failed to get raw ptr"))?;
23885
23886        if JNI_CreateJavaVM_ptr.is_null() {
23887            return Err(alloc::format!("Failed to load jvm from {path} reason: JNI_CreateJavaVM not found"));
23888        }
23889
23890        let JNI_GetCreatedJavaVMs_ptr = lib
23891            .get::<JNI_GetCreatedJavaVMs>(b"JNI_GetCreatedJavaVMs\0")
23892            .map_err(|e| alloc::format!("Failed to load jvm from {path} reason: JNI_GetCreatedJavaVMs -> {e}"))?
23893            .try_as_raw_ptr()
23894            .ok_or_else(|| alloc::format!("Failed to load jvm from {path} reason: JNI_CreateJavaVM -> failed to get raw ptr"))?;
23895
23896        if JNI_GetCreatedJavaVMs_ptr.is_null() {
23897            return Err(alloc::format!("Failed to load jvm from {path} reason: JNI_GetCreatedJavaVMs not found"));
23898        }
23899
23900        //We are good to go!
23901        core::mem::forget(lib);
23902        Ok(JNIDynamicLink::new(JNI_CreateJavaVM_ptr, JNI_GetCreatedJavaVMs_ptr))
23903    })?;
23904
23905    if !latch.load(Ordering::SeqCst) {
23906        return Err("JVM already loaded".to_string());
23907    }
23908
23909    Ok(())
23910}
23911
23912///
23913/// Convenience method to load the jvm from a path to libjvm.so, jvm.dll or libjvm.dylib.
23914///
23915/// On success this method does NOT close the handle to the shared object.
23916/// This is usually fine because unloading the jvm is not supported anyway.
23917/// If you do not desire this then use `init_dynamic_link`.
23918///
23919/// # Errors
23920/// if loading the library fails without crashing the process then a String describing the reason why is returned as an error.
23921///
23922/// # Safety
23923/// The Safety of this fn depends on the shared object that will be loaded as a result of this call.
23924///
23925#[cfg(feature = "loadjvm")]
23926#[cfg(feature = "dynlink")]
23927pub unsafe fn load_jvm_from_library(_: &str) -> Result<(), String> {
23928    Err("JVM already loaded".to_string())
23929}
23930
23931///
23932/// Convenience method to load the jvm from the `JAVA_HOME` environment variable
23933/// that is commonly set on Windows by End-User Java Setups,
23934/// or on linux by distribution package installers.
23935///
23936/// # Errors
23937/// If `JAVA_HOME` is not set or doesn't point to a known layout of a JVM installation or cant be read
23938/// then this function returns an error.
23939///
23940/// # Safety
23941/// The Safety of this fn depends on the shared object that will be loaded as a result of this call.
23942///
23943#[cfg(feature = "loadjvm")]
23944pub unsafe fn load_jvm_from_java_home() -> Result<(), String> {
23945    let java_home = std::env::var("JAVA_HOME").map_err(|_| "JAVA_HOME is not set or invalid".to_string())?;
23946    unsafe { load_jvm_from_java_home_folder(&java_home) }
23947}
23948
23949/// Convinience method to load the jvm from a given path to a java installation.
23950/// Info: The `java_home` parameter should refer to a path of a folder, which directly contains the "bin" or "jre" folder.
23951///
23952/// # Errors
23953/// If `java_home` doesn't refer to a known layout of a JVM installation or cant be read
23954/// then this function returns an error.
23955///
23956/// # Safety
23957/// The Safety of this fn depends on the shared object that will be loaded as a result of this call.
23958#[cfg(feature = "loadjvm")]
23959pub unsafe fn load_jvm_from_java_home_folder(java_home: &str) -> Result<(), String> {
23960    ///All (most) jvm layouts that I am aware of on windows+linux+macos.
23961    const COMMON_LIBJVM_PATHS: &[&[&str]] = &[
23962        &["lib", "server", "libjvm.so"],                   //LINUX JAVA 11+
23963        &["jre", "lib", "amd64", "server", "libjvm.so"],   //LINUX JDK JAVA <= 8 amd64
23964        &["lib", "amd64", "server", "libjvm.so"],          //LINUX JRE JAVA <= 8 amd64
23965        &["jre", "lib", "aarch32", "server", "libjvm.so"], //LINUX JDK JAVA <= 8 arm 32
23966        &["lib", "aarch32", "server", "libjvm.so"],        //LINUX JRE JAVA <= 8 arm 32
23967        &["jre", "lib", "aarch64", "server", "libjvm.so"], //LINUX JDK JAVA <= 8 arm 64
23968        &["lib", "aarch64", "server", "libjvm.so"],        //LINUX JRE JAVA <= 8 arm 64
23969        //
23970        &["jre", "bin", "server", "jvm.dll"], //WINDOWS JDK <= 8
23971        &["bin", "server", "jvm.dll"],        //WINDOWS JRE <= 8 AND WINDOWS JDK/JRE 11+
23972        //
23973        &["jre", "lib", "server", "libjvm.dylib"],                     //MACOS Java <= 8
23974        &["Contents", "Home", "jre", "lib", "server", "libjvm.dylib"], //MACOS Java <= 8
23975        &["lib", "server", "libjvm.dylib"],                            //MACOS Java 11+
23976        &["Contents", "Home", "lib", "server", "libjvm.dylib"],        //MACOS Java 11+
23977    ];
23978
23979    for parts in COMMON_LIBJVM_PATHS {
23980        let mut buf = PathBuf::from(java_home);
23981        for part in *parts {
23982            buf.push(part);
23983        }
23984
23985        if buf.try_exists().unwrap_or(false) {
23986            let full_path = buf.to_str().ok_or_else(|| alloc::format!("JAVA_HOME {java_home} is invalid"))?;
23987
23988            unsafe {
23989                return load_jvm_from_library(full_path);
23990            }
23991        }
23992    }
23993
23994    Err(alloc::format!("JAVA_HOME {java_home} is invalid"))
23995}
23996
23997/// Returns the static dynamic link or panic
23998/// # Panics
23999/// if the dynamic link was not initalized.
24000#[cfg(not(feature = "dynlink"))]
24001fn get_link() -> &'static JNIDynamicLink {
24002    LINK.get().expect("jni_simple::init_dynamic_link not called")
24003}
24004
24005///
24006/// Returns the created `JavaVMs` in the given `vms` slice.
24007/// All remaining elements in the slice are set to None.
24008/// The count of returned `JavaVMs` is returned in the result.
24009///
24010/// If the given slice is smaller than the amount of created `JavaVMs` then
24011/// this function does not error and simply returns the amount
24012/// of space in the slice that would have been needed.
24013///
24014/// If this function returns an Err then the slice is untouched.
24015///
24016/// # Note
24017/// This will probably only ever return 1 (or 0) `JavaVM`s according to Oracle Documentation
24018/// as the hotspot jvm does not support more than 1 JVM per process.
24019///
24020/// # Errors
24021/// JNI implementation specific error constants like `JNI_EINVAL`
24022///
24023/// # Panics
24024/// Will panic if the JVM shared library has not been loaded yet.
24025/// If the JVM's `JNI_GetCreatedJavaVMs` method returns unexpected values
24026///
24027/// # Safety
24028/// The Safety of this fn is implementation dependant.
24029///
24030pub unsafe fn JNI_GetCreatedJavaVMs(vms: &mut [Option<JavaVM>]) -> Result<usize, jint> {
24031    #[cfg(not(feature = "dynlink"))]
24032    let link = get_link().JNI_GetCreatedJavaVMs();
24033    #[cfg(feature = "dynlink")]
24034    let link = dynlink::JNI_GetCreatedJavaVMs;
24035
24036    //NOTE: Oracle spec says this will only ever yield 1 JVM.
24037    //I will worry about this when it actually becomes a problem
24038    let mut buf: [JNIInvPtr; 64] = [SyncMutPtr::null(); 64];
24039    let mut count: jint = 0;
24040    let res = unsafe { link(buf.as_mut_ptr(), 64, &raw mut count) };
24041    if res != JNI_OK {
24042        return Err(res);
24043    }
24044
24045    let count = usize::try_from(count).expect("JNI_GetCreatedJavaVMs did set count to < 0");
24046
24047    for (i, env) in buf.into_iter().enumerate().take(count) {
24048        assert!(!env.is_null(), "JNI_GetCreatedJavaVMs VM #{i} is null! count is {count}");
24049    }
24050
24051    for (i, target) in vms.iter_mut().enumerate() {
24052        if i >= count {
24053            *target = None;
24054            continue;
24055        }
24056
24057        *target = Some(JavaVM { vtable: buf[i] });
24058    }
24059
24060    Ok(count)
24061}
24062///
24063/// Returns the first created `JavaVM` or None in the result.
24064///
24065/// Usually there is only 1 created or 0 created `JavaVM`'s in any given process.
24066/// This function acts as a convenience function that only returns the first and probably only `JavaVM`.
24067///
24068/// # Errors
24069/// JNI implementation specific error constants like `JNI_EINVAL`
24070///
24071/// # Panics
24072/// Will panic if the JVM shared library has not been loaded yet.
24073/// If the JVM's `JNI_GetCreatedJavaVMs` method returns unexpected values
24074///
24075/// # Safety
24076/// The Safety of this fn is implementation dependant.
24077///
24078pub unsafe fn JNI_GetCreatedJavaVMs_first() -> Result<Option<JavaVM>, jint> {
24079    unsafe {
24080        let mut vm = [None];
24081        _ = JNI_GetCreatedJavaVMs(vm.as_mut())?;
24082        Ok(vm[0])
24083    }
24084}
24085
24086///
24087/// Directly calls `JNI_CreateJavaVM` with the provided arguments.
24088///
24089/// # Errors
24090/// JNI implementation specific error constants like `JNI_EINVAL`
24091///
24092/// # Panics
24093/// Will panic if the JVM shared library has not been loaded yet.
24094/// Will panic if the JVM shared library retruned unexpected values.
24095///
24096/// # Safety
24097/// The Safety of this fn is implementation dependant.
24098/// On Hotspot JVM's this fn cannot be called successfully more than once.
24099/// Subsequent calls are undefined behaviour.
24100///
24101pub unsafe fn JNI_CreateJavaVM(arguments: *mut JavaVMInitArgs) -> Result<(JavaVM, JNIEnv), jint> {
24102    #[cfg(feature = "asserts")]
24103    {
24104        assert!(!arguments.is_null(), "JNI_CreateJavaVM arguments must not be null");
24105    }
24106
24107    #[cfg(not(feature = "dynlink"))]
24108    let link = get_link().JNI_CreateJavaVM();
24109    #[cfg(feature = "dynlink")]
24110    let link = dynlink::JNI_CreateJavaVM;
24111
24112    let mut jvm: JNIInvPtr = SyncMutPtr::null();
24113    let mut env: JNIEnv = JNIEnv { vtable: null_mut() };
24114
24115    let res = unsafe { link(&raw mut jvm, &raw mut env, arguments) };
24116    if res != JNI_OK {
24117        return Err(res);
24118    }
24119
24120    assert!(!jvm.is_null(), "JNI_CreateJavaVM returned JNI_OK but the JavaVM pointer is null");
24121
24122    assert!(!env.vtable.is_null(), "JNI_CreateJavaVM returned JNI_OK but the JNIEnv pointer is null");
24123
24124    Ok((JavaVM { vtable: jvm }, env))
24125}
24126
24127///
24128/// Convenience function to call `JNI_CreateJavaVM` with a simple list of String arguments.
24129///
24130/// These arguments are almost identical to the command line arguments used to start the jvm with the java binary.
24131/// Some options differ slightly. Consult the JNI Invocation API documentation for more information.
24132///
24133/// # Errors
24134/// JNI implementation specific error constants like `JNI_EINVAL`
24135///
24136/// # Panics
24137/// Will panic if the JVM shared library has not been loaded yet.
24138/// Will panic if more than `jsize::MAX` arguments are passed to the vm. (The JVM itself is likely to just die earlier)
24139/// If any argument contains a 0 byte in the string.
24140///
24141/// # Safety
24142/// The Safety of this fn is implementation dependant.
24143/// On Hotspot JVM's this fn cannot be called successfully more than once.
24144/// Subsequent calls are undefined behaviour.
24145///
24146/// # Example
24147/// ```rust
24148/// use std::ptr::null_mut;
24149/// use jni_simple::*;
24150///
24151///
24152/// //This example fn is roughly equivalent to "java -Xint -Xmx1G -Djava.class.path={absolute_path_to_jar_file} {main_class}" on the command line.
24153/// unsafe fn launch_jvm(absolute_path_to_jar_file: &str, main_class: &str) -> ! {
24154///     #[cfg(feature = "loadjvm")] //Only needed due to doctest!
24155///     load_jvm_from_java_home().expect("Failed to load jvm");
24156///
24157///     let (vm, env) = JNI_CreateJavaVM_with_string_args(JNI_VERSION_1_8, &[
24158///          "-Xint".to_string(),
24159///          "-Xmx1G".to_string(),
24160///          format!("-Djava.class.path={absolute_path_to_jar_file}")
24161///     ], false).expect("Failed to start jvm");
24162///
24163///     let main_class = env.FindClass(main_class);
24164///     if env.ExceptionCheck() {
24165///         //Main class not found
24166///         env.ExceptionDescribe();
24167///         return std::process::exit(-1);
24168///     }
24169///
24170///     let main_method = env.GetStaticMethodID(main_class, "main","([Ljava/lang/String)V");
24171///     if env.ExceptionCheck() {
24172///         //no static main(String[] args) method in the main class.
24173///         env.ExceptionDescribe();
24174///         return std::process::exit(-1);
24175///     }
24176///
24177///     let string_class = env.FindClass("java/lang/String");
24178///     if env.ExceptionCheck() {
24179///         //Unlikely, java.lang.String not found.
24180///         env.ExceptionDescribe();
24181///         return std::process::exit(-1);
24182///     }
24183///
24184///     let main_method_string_parameter_array = env.NewObjectArray(0, string_class, null_mut());
24185///      if env.ExceptionCheck() {
24186///         //Unlikely jvm ran out of memory when creating "new String[0];"
24187///         env.ExceptionDescribe();
24188///         return std::process::exit(-1);
24189///     }
24190///
24191///     env.CallStaticVoidMethod1(main_class, main_method, main_method_string_parameter_array);
24192///     if env.ExceptionCheck() {
24193///         //Main method threw an exception
24194///         env.ExceptionDescribe();
24195///         return std::process::exit(-1);
24196///     }
24197///
24198///     //Block until all non deamon java threads the main method has started are done.
24199///     vm.DestroyJavaVM();
24200///
24201///     //Exit the process with success.
24202///     std::process::exit(0)
24203/// }
24204/// ```
24205///
24206pub unsafe fn JNI_CreateJavaVM_with_string_args<T: AsRef<str>>(version: jint, arguments: &[T], ignore_unrecognized_options: bool) -> Result<(JavaVM, JNIEnv), jint> {
24207    unsafe {
24208        /// inner helper struct to ensure that the `CStrings` are free'd in any case.
24209        struct DropGuard(*mut c_char);
24210        impl Drop for DropGuard {
24211            fn drop(&mut self) {
24212                unsafe {
24213                    _ = CString::from_raw(self.0);
24214                }
24215            }
24216        }
24217
24218        let mut vm_args: Vec<JavaVMOption> = Vec::with_capacity(arguments.len());
24219        let mut dealloc_list = Vec::with_capacity(arguments.len());
24220        for arg in arguments {
24221            let jvm_arg = CString::new(arg.as_ref()).expect("Argument contains 0 byte").into_raw();
24222            dealloc_list.push(DropGuard(jvm_arg));
24223
24224            vm_args.push(JavaVMOption {
24225                optionString: jvm_arg,
24226                extraInfo: null_mut(),
24227            });
24228        }
24229
24230        let mut args = JavaVMInitArgs {
24231            version,
24232            nOptions: i32::try_from(vm_args.len()).expect("Too many arguments"),
24233            options: vm_args.as_mut_ptr(),
24234            ignoreUnrecognized: u8::from(ignore_unrecognized_options),
24235        };
24236
24237        let result = JNI_CreateJavaVM(&raw mut args);
24238        drop(dealloc_list);
24239        result
24240    }
24241}
24242
24243impl JavaVM {
24244    /// Helper fn to assist with casting of the internal vtable
24245    /// # Safety
24246    /// This fn is only safe if X matches whats in the vtable of index.
24247    #[inline]
24248    unsafe fn ivk<X>(&self, index: usize) -> X {
24249        unsafe { core::mem::transmute_copy(&(self.vtable.inner().read_volatile().add(index).read_volatile())) }
24250    }
24251
24252    ///
24253    /// Attaches the current thread to the JVM as a normal thread.
24254    /// If a thread name is provided then it will be used as the java name of the current thread.
24255    ///
24256    /// # Errors
24257    /// JNI implementation specific error constants like `JNI_EINVAL`
24258    ///
24259    /// # Safety
24260    /// This fn must not be called on a `JavaVM` object that has been destroyed or is in the process of being destroyed.
24261    ///
24262    pub unsafe fn AttachCurrentThread_str(&self, version: jint, thread_name: impl UseCString, thread_group: jobject) -> Result<JNIEnv, jint> {
24263        unsafe {
24264            thread_name.use_as_const_c_char(|thread_name| {
24265                let mut args = JavaVMAttachArgs::new(version, thread_name, thread_group);
24266                self.AttachCurrentThread(&raw mut args)
24267            })
24268        }
24269    }
24270
24271    ///
24272    /// Attaches the current thread to the JVM as a normal thread.
24273    /// If a thread name is provided then it will be used as the java name of the current thread.
24274    ///
24275    /// # Errors
24276    /// JNI implementation specific error constants like `JNI_EINVAL`
24277    ///
24278    /// # Panics
24279    /// If the JVM does not return an error but also does not set the `JNIEnv` ptr.
24280    ///
24281    /// # Safety
24282    /// This fn must not be called on a `JavaVM` object that has been destroyed or is in the process of being destroyed.
24283    ///
24284    pub unsafe fn AttachCurrentThread(&self, args: *mut JavaVMAttachArgs) -> Result<JNIEnv, jint> {
24285        unsafe {
24286            #[cfg(feature = "asserts")]
24287            {
24288                assert!(!args.is_null(), "AttachCurrentThread args must not be null");
24289            }
24290            let mut envptr: JNIEnvVTable = null_mut();
24291
24292            let result = self.ivk::<extern "system" fn(JNIInvPtr, *mut JNIEnvVTable, *mut JavaVMAttachArgs) -> jint>(4)(self.vtable, &raw mut envptr, args);
24293            if result != JNI_OK {
24294                return Err(result);
24295            }
24296
24297            assert!(!envptr.is_null(), "AttachCurrentThread returned JNI_OK but did not set the JNIEnv pointer!");
24298
24299            Ok(JNIEnv { vtable: envptr })
24300        }
24301    }
24302
24303    ///
24304    /// Attaches the current thread to the JVM as a daemon thread.
24305    /// If a thread name is provided then it will be used as the java name of the current thread.
24306    ///
24307    /// # Errors
24308    /// JNI implementation specific error constants like `JNI_EINVAL`
24309    ///
24310    /// # Safety
24311    /// This fn must not be called on a `JavaVM` object that has been destroyed or is in the process of being destroyed.
24312    ///
24313    pub unsafe fn AttachCurrentThreadAsDaemon_str(&self, version: jint, thread_name: impl UseCString, thread_group: jobject) -> Result<JNIEnv, jint> {
24314        unsafe {
24315            thread_name.use_as_const_c_char(|thread_name| {
24316                let mut args = JavaVMAttachArgs::new(version, thread_name, thread_group);
24317                self.AttachCurrentThreadAsDaemon(&raw mut args)
24318            })
24319        }
24320    }
24321
24322    ///
24323    /// Attaches the current thread to the JVM as a daemon thread.
24324    /// If a thread name is provided then it will be used as the java name of the current thread.
24325    ///
24326    /// # Errors
24327    /// JNI implementation specific error constants like `JNI_EINVAL`
24328    ///
24329    /// # Panics
24330    /// If the JVM does not return an error but also does not set the `JNIEnv` ptr.
24331    ///
24332    /// # Safety
24333    /// This fn must not be called on a `JavaVM` object that has been destroyed or is in the process of being destroyed.
24334    ///
24335    pub unsafe fn AttachCurrentThreadAsDaemon(&self, args: *mut JavaVMAttachArgs) -> Result<JNIEnv, jint> {
24336        unsafe {
24337            #[cfg(feature = "asserts")]
24338            {
24339                assert!(!args.is_null(), "AttachCurrentThreadAsDaemon args must not be null");
24340            }
24341            let mut envptr: JNIEnvVTable = null_mut();
24342
24343            let result = self.ivk::<extern "system" fn(JNIInvPtr, *mut JNIEnvVTable, *mut JavaVMAttachArgs) -> jint>(7)(self.vtable, &raw mut envptr, args);
24344
24345            if result != JNI_OK {
24346                return Err(result);
24347            }
24348
24349            assert!(!envptr.is_null(), "AttachCurrentThreadAsDaemon returned JNI_OK but did not set the JNIEnv pointer!");
24350
24351            Ok(JNIEnv { vtable: envptr })
24352        }
24353    }
24354
24355    ///
24356    /// Gets the `JNIEnv` for the current thread.
24357    ///
24358    /// Concerning the generic type `T`. This type must refer to the correct function table for the given `jni_version`:
24359    /// - For ordinary `jni_version` values `T` must be `JNIEnv`.
24360    /// - For jvmti `jni_version` values `T` must be `JVMTIEnv`.
24361    /// - `*mut c_void` is also always a valid type for `T` regardless of the value of `jni_version`!
24362    /// - using `*mut c_void` will return the raw function table.
24363    ///
24364    /// Using the wrong type for `T` is undefined behavior!
24365    /// There is no way to check this as jvmti and jni function tables are completely different!
24366    ///
24367    ///
24368    /// # Safety
24369    /// This fn must not be called on a `JavaVM` object that has been destroyed or is in the process of being destroyed.
24370    /// # Panics
24371    /// If the JVM does not return an error but also does not set the `JNIEnv` ptr.
24372    ///
24373    /// If the asserts feature is enabled and the implementation can detect that `T` is not correct.
24374    /// This is only provided on a best effort basis.
24375    ///
24376    /// # Errors
24377    /// JNI implementation specific error constants like `JNI_EINVAL`
24378    /// # Undefined behavior
24379    /// Using the wrong type `T` for the given `jni_version`. I.e. using `JNIEnv` for `JVMTI` or `JVMTIEnv` for `JNI`.
24380    /// # Example
24381    /// ```rust
24382    /// use std::ffi::c_void;
24383    /// use jni_simple::{JNIEnv, JVMTIEnv, JavaVM, JNI_VERSION_1_8, JVMTI_VERSION_21};
24384    ///
24385    /// unsafe fn some_func(vm: &JavaVM) {
24386    ///     //for 99% use cases this is what you want!
24387    ///     let jni = vm.GetEnv::<JNIEnv>(JNI_VERSION_1_8).expect("Error");
24388    ///
24389    ///     let jni_raw = vm.GetEnv::<*mut c_void>(JNI_VERSION_1_8).expect("Error");
24390    ///     let jvmti = vm.GetEnv::<JVMTIEnv>(JVMTI_VERSION_21).expect("Error");
24391    ///     let jni_raw = vm.GetEnv::<*mut c_void>(JVMTI_VERSION_21).expect("Error");
24392    /// }
24393    /// ```
24394    ///
24395    pub unsafe fn GetEnv<T: SealedEnvVTable>(&self, jni_version: jint) -> Result<T, jint> {
24396        unsafe {
24397            let mut envptr: *mut c_void = null_mut();
24398            #[cfg(feature = "asserts")]
24399            {
24400                assert!(
24401                    jni_version & 0x3000_0000 != 0x3000_0000 || T::can_jvmti(),
24402                    "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."
24403                );
24404
24405                assert!(
24406                    jni_version & 0x3000_0000 != 0x0000_0000 || T::can_jni(),
24407                    "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."
24408                );
24409            }
24410
24411            let result = self.ivk::<extern "system" fn(JNIInvPtr, *mut *mut c_void, jint) -> jint>(6)(self.vtable, &raw mut envptr, jni_version);
24412
24413            if result != JNI_OK {
24414                return Err(result);
24415            }
24416
24417            assert!(!envptr.is_null(), "GetEnv returned JNI_OK but did not set the JNIEnv pointer!");
24418
24419            Ok(T::from(envptr))
24420        }
24421    }
24422
24423    ///
24424    /// Detaches the current thread from the jvm.
24425    /// This should only be called on functions that were attached with `AttachCurrentThread` or `AttachCurrentThreadAsDaemon`.
24426    ///
24427    /// # Safety
24428    /// Detaches the current thread. The `JNIEnv` of the current thread is no longer valid after this call.
24429    /// Any further calls made using it will result in undefined behavior.
24430    ///
24431    #[must_use]
24432    pub unsafe fn DetachCurrentThread(&self) -> jint {
24433        unsafe { self.ivk::<extern "system" fn(JNIInvPtr) -> jint>(5)(self.vtable) }
24434    }
24435
24436    ///
24437    /// This function will block until all java threads have completed and then destroy the JVM.
24438    /// It should not be called from a method that is called from the JVM.
24439    ///
24440    /// # Safety
24441    /// Careful consideration should be taken when this fn is called. As mentioned calling it from
24442    /// a JVM Thread will probably just block the calling thread forever. However, this fn also
24443    /// does stuff internally with the jvm, after/during its return the JVM can no longer be used in
24444    /// any thread. Any existing `JavaVM` object will become invalid. Attempts to obtain a `JNIEnv` after
24445    /// this fn returns by way of calling `AttachThread` will likely lead to undefined behavior.
24446    /// Shutting down a JVM is a "terminal" operation for any Hotspot implementation of the JVM.
24447    /// The current process will never be able to relaunch a hotspot JVM.
24448    ///
24449    /// This fn should therefore only be used if a rust thread needs to "wait" until the JVM is dead to then perform
24450    /// some operations such a cleanup before eventually calling `exit()`
24451    ///
24452    /// Please note that this fn never returns if the `JavaVM` terminates abnormally (e.g. due to a crash),
24453    /// or someone calling Runtime.getRuntime().halt(...) in Java, because that just terminates the Process instantly.
24454    /// Its usefulness to run shutdown code is therefore limited.
24455    ///
24456    ///
24457    pub unsafe fn DestroyJavaVM(&self) {
24458        unsafe {
24459            self.ivk::<extern "system" fn(JNIInvPtr) -> ()>(3)(self.vtable);
24460        }
24461    }
24462}
24463
24464#[cfg(test)]
24465#[test]
24466const fn test_sync() {
24467    static_assertions::assert_impl_all!(JavaVM: Sync);
24468    static_assertions::assert_impl_all!(JavaVM: Send);
24469
24470    static_assertions::assert_impl_all!(jniNativeInterface: Sync);
24471    static_assertions::assert_impl_all!(jniNativeInterface: Send);
24472
24473    static_assertions::assert_not_impl_all!(JNIEnv: Sync);
24474    static_assertions::assert_not_impl_all!(JNIEnv: Send);
24475
24476    static_assertions::assert_impl_all!(JVMTIEnv: Sync);
24477    static_assertions::assert_impl_all!(JVMTIEnv: Send);
24478}
24479
24480#[cfg(doctest)]
24481#[doc = include_str!("../README.md")]
24482struct ReadmeDocTests;