From 19ebaddd6db74eea3fa747634a1a383506b561ec Mon Sep 17 00:00:00 2001 From: alemi Date: Sat, 21 Sep 2024 18:48:30 +0200 Subject: [PATCH] feat: impl JniToolboxError, allow returning ptr --- Cargo.toml | 1 + macro/macro.rs | 28 +++++++++++++++++++++------- src/lib.rs | 6 ++++++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8c483c9..267dd9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,4 @@ edition = "2021" [dependencies] jni-toolbox-macro = "0.1.1" +jni = "0.21" diff --git a/macro/macro.rs b/macro/macro.rs index edccc56..24a866d 100644 --- a/macro/macro.rs +++ b/macro/macro.rs @@ -30,6 +30,7 @@ fn generate_jni_wrapper(attrs: TokenStream, input: TokenStream) -> Result Result what_next = WhatNext::Package, "class" => what_next = WhatNext::Class, "exception" => what_next = WhatNext::Exception, + "ptr" => return_pointer = true, _ => return Err(syn::Error::new(Span::call_site(), "unexpected attribute on macro: {attr}")), } } @@ -118,7 +120,7 @@ fn generate_jni_wrapper(attrs: TokenStream, input: TokenStream) -> Result Result(#incoming) #ret_type { use jni_toolbox::JniToolboxError; match #fn_name_inner(#forwarding) { Ok(ret) => ret, Err(e) => match #env_ident.throw_new(#exception, format!("{e:?}")) { - Ok(_) => return 0, + Ok(_) => return #return_expr, Err(e) => panic!("error throwing java exception: {e}"), } } @@ -151,18 +160,22 @@ fn generate_jni_wrapper(attrs: TokenStream, input: TokenStream) -> Result(#incoming) #ret_type { use jni_toolbox::JniToolboxError; + // NOTE: this is SAFE! the cloned env reference lives less than the actual one, we just lack a + // way to get it back from the called function and thus resort to unsafe cloning + let mut env_copy = unsafe { #env_ident.unsafe_clone() }; match #fn_name_inner(#forwarding) { - Err(e) => match #env_ident.find_class(e.jclass()) { + Err(e) => match env_copy.find_class(e.jclass()) { Err(e) => panic!("error throwing Java exception -- failed resolving error class: {e}"), - Ok(class) => match #env_ident.new_string(format!("{e:?}")) { + Ok(class) => match env_copy.new_string(format!("{e:?}")) { Err(e) => panic!("error throwing Java exception -- failed creating error string: {e}"), - Ok(msg) => match #env_ident.new_object(class, "(Ljava/lang/String;)V", &[jni::objects::JValueGen::Object(&msg)]) { + Ok(msg) => match env_copy.new_object(class, "(Ljava/lang/String;)V", &[jni::objects::JValueGen::Object(&msg)]) { Err(e) => panic!("error throwing Java exception -- failed creating object: {e}"), - Ok(obj) => match #env_ident.throw(obj) { + Ok(obj) => match env_copy.throw(jni::objects::JThrowable::from(obj)) { Err(e) => panic!("error throwing Java exception -- failed throwing: {e}"), - Ok(_) => return 0, + Ok(_) => return #return_expr, }, }, }, @@ -177,6 +190,7 @@ fn generate_jni_wrapper(attrs: TokenStream, input: TokenStream) -> Result(#incoming) #ret_type { #fn_name_inner(#forwarding) } diff --git a/src/lib.rs b/src/lib.rs index 9fe78bf..5af925d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,3 +3,9 @@ pub use jni_toolbox_macro::jni; pub trait JniToolboxError: std::error::Error { fn jclass(&self) -> String; } + +impl JniToolboxError for jni::errors::Error { + fn jclass(&self) -> String { + "java/lang/RuntimeException".to_string() + } +}