Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

simplify public API, only allowing global JVM references #147

Merged
merged 13 commits into from
May 11, 2024

Conversation

nikomatsakis
Copy link
Member

@nikomatsakis nikomatsakis commented May 4, 2024

This makes a number of simplifications to the public API for duchess. The idea is that we focus on "global" references by default. The duchess::Result<T> (for example) embeds a global reference to an exception, and the new default handle is duchess::Java<J>, which is a global reference. The prelude has been extended to include java and Java<T> as well, for convenience.

The to_rust, global, and execute combinators have all been merged. You just invoke execute and then the result depends on the return value: returning a Java<T> will create a global reference (like global used to do), returning a Rust value will invoke the "to rust" conversion (like to_rust used to do).

You can no longer obtain explicit handles to the JVM, preventing panics due to nested Jvm::with invocations (and hence fixing #142). Jvm::with is in fact crate local. This also avoids some potential unsoundness results that would have arisen from nested JVM usage.

Fixes #142

You now just do `execute::<R>` and it produces
Rust values.
Don't need it anymore.
But they really need deeper rework.
We should figure out how to enable testing.
The "execute" name will be reserved for things
that convert to Rust. This is the underlying
JNI operation without any conversion of the
result.
Still pretty bad.
Local did so, tests rely on it.

We should probably write a better impl
though, one that invokes `toString` perhaps?
Rewrite tests a bit to have same effect
without using crate-private method.
Copy link
Contributor

@rcoh rcoh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, had some naming comments on the internal APIs which can defer.

Probably will also need a changelog / update guidance for the next major release.

.unwrap()
.expect("returns ok!");

// This errors out because `try_extract_exception` calls `Jvm::with`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can delete this comment

Suggested change
// This errors out because `try_extract_exception` calls `Jvm::with`.

@@ -39,7 +39,7 @@ This section introduces invariants maintained by Duchess using Rust's type syste

### The `'jvm` lifetime `&mut Jvm<'jvm>` is the innermost scope for local variables

References to Java objects of type `J` are stored in a `Local<'jvm, J>` holder. Local references can come from the arguments to native functions or from `JvmOp::execute_with` calls. `execute_with` calls use the `'jvm`' lifetime found on the `Jvm<'jvm>` argument. This allows the `Local` to be used freely within that scope. It is therefore important that `'jvm` be constrained to the **innermost** valid scope.
References to Java objects of type `J` are stored in a `Local<'jvm, J>` holder. Local references can come from the arguments to native functions or from `JvmOp::do_jni` calls. `do_jni` calls use the `'jvm`' lifetime found on the `Jvm<'jvm>` argument. This allows the `Local` to be used freely within that scope. It is therefore important that `'jvm` be constrained to the **innermost** valid scope.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can delete the below section about Jvm::with now since Jvm::with is pub(crate)

}

fn execute_with<'jvm>(self, jvm: &mut Jvm<'jvm>) -> crate::Result<'jvm, Self::Output<'jvm>>;
/// Internal method
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a slightly more detailed comment would probably be useful for folks working on the project since this is now the fundamental "do a thing" message

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since execute_with converts into Rust vs. do_jni which keeps it in Java maybe we could rename execute_with something that mentioned the conversion into Rust

@@ -313,7 +310,7 @@ impl Driver<'_> {
let pattern = variant.pat();
return Ok(quote_spanned!(self.span() =>
#pattern => {
#binding .jderef().upcast().execute_with(jvm)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when would one call execute_with vs. do_jni? Both are on the JvmOp trait AFAICT and it seems like sometimes we call one or the other?


#[test]
fn nested_jvm_with() {
Jvm::with(|_jvm| {
let err = Jvm::with(|_jvm| Ok(())).expect_err("nested JVMs are illegal");
assert!(matches!(err, duchess::Error::NestedUsage));
assert!(matches!(err, crate::Error::NestedUsage));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this still a useful test since Jvm::with is pub_crate now? I guess for our own internal sake we want to avoid nesting it?

@@ -66,7 +60,7 @@ where
}

impl<'jvm> Error<Local<'jvm, Throwable>> {
pub fn into_global(self, jvm: &mut Jvm<'jvm>) -> Error<Global<Throwable>> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this still be called into_global? It seems we're mostly erradicating the word from the codebase

@@ -101,7 +101,7 @@ pub fn attach_permanently(jvm: JvmPtr) -> GlobalResult<AttachGuard> {
})
}

pub unsafe fn attach<'jvm>(jvm: JvmPtr) -> GlobalResult<AttachGuard> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while we're here we should add a safety section to the docs or make this not pub

@rcoh rcoh added this pull request to the merge queue May 11, 2024
Merged via the queue into duchess-rs:main with commit 424b146 May 11, 2024
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Exceptions don't don't work properly within Jvm::with
2 participants