From c2a0c089e64a649bb88bc0a0121d148ef23b0bed Mon Sep 17 00:00:00 2001 From: Shell Chen Date: Thu, 7 Dec 2023 18:27:53 +0800 Subject: [PATCH 1/3] sync jni-rs to v0.21.1 --- catch_panic/Cargo.toml | 2 +- catch_panic/testlib/jni-rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/catch_panic/Cargo.toml b/catch_panic/Cargo.toml index bd3d179..b24840e 100644 --- a/catch_panic/Cargo.toml +++ b/catch_panic/Cargo.toml @@ -24,6 +24,6 @@ jni = "0" catch_panic_macros = { version = "1.0.0", path = "../catch_panic_macros" } [dev-dependencies] -jni = { version = "0", features = ["invocation"] } +jni = { version = "0.21.1", features = ["invocation"] } catch_panic = { path = ".", features = ["internal-doctests"] } trybuild = "1.0.63" diff --git a/catch_panic/testlib/jni-rs b/catch_panic/testlib/jni-rs index 2b86700..09a5911 160000 --- a/catch_panic/testlib/jni-rs +++ b/catch_panic/testlib/jni-rs @@ -1 +1 @@ -Subproject commit 2b86700c0dbb2f778f7e664a4094361fcc473ea2 +Subproject commit 09a5911358ffa846b5c85451c050a0e64669e863 From d3d112be55c0cfbce4f2cb40a87b611a0ab35560 Mon Sep 17 00:00:00 2001 From: Shell Chen Date: Fri, 8 Dec 2023 13:05:34 +0800 Subject: [PATCH 2/3] fix JNIEnv breaking on jni-rs 0.21 --- catch_panic/src/handler.rs | 2 +- catch_panic_macros/src/lib.rs | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/catch_panic/src/handler.rs b/catch_panic/src/handler.rs index 2fbf603..cf88b42 100644 --- a/catch_panic/src/handler.rs +++ b/catch_panic/src/handler.rs @@ -26,7 +26,7 @@ where /// `#[catch_panic]`'s default panic handler. This /// will rethrow all caught panics as java `RuntimeException`s /// with the message passed to `panic!`. -pub fn default_handler(env: JNIEnv, err: Box) { +pub fn default_handler(mut env: JNIEnv, err: Box) { let msg = match err.downcast_ref::<&'static str>() { Some(s) => *s, None => match err.downcast_ref::() { diff --git a/catch_panic_macros/src/lib.rs b/catch_panic_macros/src/lib.rs index 2f2da2d..ddbce10 100644 --- a/catch_panic_macros/src/lib.rs +++ b/catch_panic_macros/src/lib.rs @@ -103,7 +103,13 @@ pub fn catch_panic(attr: TokenStream, item: TokenStream) -> TokenStream { TokenStream::from(quote! { #(#attrs)* #vis #sig { - ::catch_panic::handler::__catch_panic(#first_arg_name, #default_value, #handler, move || { + // Safety: one JNIEnv goes to #handler, the other one goes to + // #block closure. __catch_panic() itself do not use JNIEnv so + // any local reference created with JNIEnv must be within #hander + // and/or #block, and these references are guaranteed to be + // discarded when #handler or #block exit. + let __handler_env = unsafe { #first_arg_name.unsafe_clone() }; + ::catch_panic::handler::__catch_panic(__handler_env, #default_value, #handler, move || { #block }) } From 92d4158065e0b8de5169ba5fa6f05a6321d28a8d Mon Sep 17 00:00:00 2001 From: Shell Chen Date: Fri, 8 Dec 2023 14:12:15 +0800 Subject: [PATCH 3/3] fix tests for jni-rs 0.21 --- catch_panic/src/lib.rs | 19 +++++++---- catch_panic/ui_tests/fail/no_jni_env.stderr | 2 +- catch_panic/ui_tests/fail/on_struct.stderr | 2 +- .../ui_tests/fail/wrong_handler_type.stderr | 33 +++++++++++-------- 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/catch_panic/src/lib.rs b/catch_panic/src/lib.rs index 497b9e0..78aab28 100644 --- a/catch_panic/src/lib.rs +++ b/catch_panic/src/lib.rs @@ -40,8 +40,8 @@ //! # //! #[no_mangle] //! #[catch_panic(default = "std::ptr::null_mut()")] -//! pub extern "C" fn Java_com_example_Example_gimmeAnObject(env: JNIEnv) -> jobject { -//! env.alloc_object("java/lang/Object").unwrap().into_inner() +//! pub extern "C" fn Java_com_example_Example_gimmeAnObject(mut env: JNIEnv) -> jobject { +//! env.alloc_object("java/lang/Object").unwrap().into_raw() //! } //! //! # catch_panic::test::check_callback(|env| Java_com_example_Example_gimmeAnObject(env), false); @@ -59,7 +59,7 @@ //! # use jni::JNIEnv; //! # use catch_panic::catch_panic; //! # -//! pub fn enterprise_certified_handler(env: JNIEnv, err: Box) { +//! pub fn enterprise_certified_handler(mut env: JNIEnv, err: Box) { //! let msg = match err.downcast_ref::<&'static str>() { //! Some(s) => *s, //! None => match err.downcast_ref::() { @@ -88,7 +88,7 @@ //! # //! # env.define_class( //! # "com/example/ExampleEnterpriseException", -//! # object_class_loader.try_into().unwrap(), +//! # &object_class_loader.try_into().unwrap(), //! # &src, //! # ) //! # .unwrap(); @@ -120,12 +120,17 @@ pub mod test { pub fn check_callback_with_setup(setup: S, callback: C, should_throw: bool) where - S: FnOnce(JNIEnv), + S: FnOnce(&mut JNIEnv), C: Fn(JNIEnv) -> R, { let env = util::attach_current_thread(); - setup(*env); - callback(*env); + unsafe { + // Safety: cloned env will be dropped before guard drop, and do not + // create local reference crossing local reference frame. + let mut env = env.unsafe_clone(); + setup(&mut env); + callback(env); + } assert_eq!( env.exception_check().expect("Couldn't check if there was an exception"), should_throw, diff --git a/catch_panic/ui_tests/fail/no_jni_env.stderr b/catch_panic/ui_tests/fail/no_jni_env.stderr index ffa4f76..9c09e9d 100644 --- a/catch_panic/ui_tests/fail/no_jni_env.stderr +++ b/catch_panic/ui_tests/fail/no_jni_env.stderr @@ -2,4 +2,4 @@ error: #[catch_panic] requires that this function has at least one argument of t --> ui_tests/fail/no_jni_env.rs:4:1 | 4 | fn no_jni_env() { - | ^^^^^^^^^^^^^^^ + | ^^ diff --git a/catch_panic/ui_tests/fail/on_struct.stderr b/catch_panic/ui_tests/fail/on_struct.stderr index af91a2e..a824820 100644 --- a/catch_panic/ui_tests/fail/on_struct.stderr +++ b/catch_panic/ui_tests/fail/on_struct.stderr @@ -2,4 +2,4 @@ error: #[catch_panic] can only be applied to functions --> ui_tests/fail/on_struct.rs:4:1 | 4 | pub struct PanicDonationBox; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ diff --git a/catch_panic/ui_tests/fail/wrong_handler_type.stderr b/catch_panic/ui_tests/fail/wrong_handler_type.stderr index 12829b1..dcb618f 100644 --- a/catch_panic/ui_tests/fail/wrong_handler_type.stderr +++ b/catch_panic/ui_tests/fail/wrong_handler_type.stderr @@ -1,17 +1,22 @@ error[E0631]: type mismatch in function arguments - --> ui_tests/fail/wrong_handler_type.rs:9:25 - | -4 | pub fn trust_me(_env: JNIEnv, err: String) { - | ------------------------------------------ found signature of `for<'r> fn(JNIEnv<'r>, String) -> _` + --> ui_tests/fail/wrong_handler_type.rs:9:25 + | +4 | pub fn trust_me(_env: JNIEnv, err: String) { + | ------------------------------------------ found signature defined here ... -9 | #[catch_panic(handler = "trust_me")] - | ------------------------^^^^^^^^^^-- - | | | - | | expected signature of `for<'r> fn(JNIEnv<'r>, Box<(dyn Any + Send + 'static)>) -> _` - | required by a bound introduced by this call - | +9 | #[catch_panic(handler = "trust_me")] + | ------------------------^^^^^^^^^^-- + | | | + | | expected due to this + | required by a bound introduced by this call + | + = note: expected function signature `for<'a> fn(JNIEnv<'a>, Box<(dyn Any + Send + 'static)>) -> _` + found function signature `for<'a> fn(JNIEnv<'a>, String) -> _` note: required by a bound in `__catch_panic` - --> src/handler.rs - | - | H: FnOnce(JNIEnv, Box), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `__catch_panic` + --> src/handler.rs + | + | pub fn __catch_panic(env: JNIEnv, default: R, handler: H, f: F) -> R + | ------------- required by a bound in this function +... + | H: FnOnce(JNIEnv, Box), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `__catch_panic`