-
Notifications
You must be signed in to change notification settings - Fork 154
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
Add Array wrapper types with lifetimes #400
Conversation
e2d4e2c
to
b3ce652
Compare
@argv-minus-one this has a bit of overlap with the kind of thing that was update in #398 and it would be great if you'd be able to take a look over this too if possible |
Nice. My project mostly uses Java byte arrays to move data between Java and Rust, so this is just what I needed. I'll give this a try tomorrow. |
just to add; I had intended to open this as a "draft" PR but just noticed I must have clicked the wrong button in the end when opening the PR. This was a first pass that I did fairly quickly yesterday but wanted to post here to get some initial feedback. Thanks for taking a look. |
Something I had meant to highlight too was that I ended up removing the On the one hand I wanted to remove the owned I currently feel like I think of them more like I could see that it might be desirable to be able to query the link between these and the |
b3ce652
to
9e24b64
Compare
Here are my thoughts so far. Let me know if you'd like me to work on any of them. Merge
|
For reference, I've made a second pass over this now. For now I've tried to use a more consistent lifetime name of I'll look at splitting out the change to add This iteration also ends up making quite a lot of changes to both |
|
Yeah, I was having similar thoughts. I was also pondering whether the API to access elements with a "critical" section should simply be marked as |
ah, thanks for the reminder. I guess I was initially adding |
Ah yep, makes sense. |
9e24b64
to
23b9009
Compare
Yeah, sorry for the distraction - I originally noted this in the PR description. When I first made the PR it was intended to be a draft to test out the feasibility of adding these wrapper types and I just did that based on the branch for #399. I used that branch as a base mainly for the sake of being based on the |
23b9009
to
7215041
Compare
@argv-minus-one I've just added a patch that implements
|
98d1144
to
798f228
Compare
Regarding the idea to try and consolidate That said - I'd be very tempted to rename |
I've changed my project to use these new features, and they work very nicely. I did need to use the bytemuck library to get a |
I remember trying to do that at the time, and in the end deciding that it was simpler / clearer to have just two different impls.
Yes.
Go ahead. I tried to come up with representative names at the time, which is not easy; having |
Okey, not really wanting to bike shed naming but still; @argv-minus-one + @maurolacy can you let me know if you'd be ok with the names Personally I think that the use of The Please react with 🎉 for |
Both work for me, but I tend to stick with 'Array' for historical reasons. |
It could even be worth adding a |
b742a21
to
003dbe1
Compare
Okey, I've rebased on master, squashed the doc fixes and dropped the patch that made Hopefully this is ok to land now @argv-minus-one |
I've pushed two commits to your branch:
I've also added a comment at Everything else looks good to me. |
47dc986
to
36dd212
Compare
Instead of all the array-based APIs being based on sys types like `jbyteArray` (which can easily lead to the use of invalid local references) this introduces types like `JByteArray<'local>` that have a lifetime parameter to ensure the local reference can't be read if it is deleted or goes out of scope. `JByteArray` and `JIntArray` etc are based on a generic `JPrimitiveArray<T>` which takes any of the primitive types that may be put into arrays, like `jbyte` or `jint`. Since types like `JByteArray` are simply aliases for `JPrimitiveArray<T>` there's no need to keep separate `JNIEnv::get_<type>_array_elements` methods since they can all be passed to `JNIEnv::get_array_elements`. `JObjectArray` is handled separately, considering that it can't be used with `AutoArray` or `AutoPrimitiveArray`. The implementations of `AutoArray` and `AutoPrimitiveArray` were updated so they can be created based on a `JPrimitiveAarray`. While updating the lifetime parameters to the `AutoArray` and `AutoPrimitiveArray` APIs numerous implementation inconsistencies were found, even though they should only really differ in how they acquire / release the pointer to array elements. This patch also normalizes the implementation of both of these APIs, so they are easily comparable. It may even be possible to unify these at some point. For now the `test_get_array_elements` tests have been kept at least for the sake of checking the data integrity from updating array elements of different types/sizes, even though they now utilize the same `get_array_elements` code. Closes; jni-rs#396 Closes: jni-rs#41
This is to make it clear that `TypeArray` trait is only intended to implemented internally.
This makes it possible to read and write the elements of a Java array without resorting to unsafe code. Both AutoArray and AutoPrimitiveArray now need to be constructed with a known array length (::new() will query the length and an unsafe ::new_with_len() API could be used in case the length was already known) The `.size()` API has been replace with `.len()` and `.is_empty()` and `.len()` doesn't return a Result since it's no longer possible to create an `Auto[Primitive]Array` without a known length.
So that `JNIEnv::get_array_length()` can be used with `JPrimitiveArray` or `JObjectArray` this adds a `AsJArrayRaw` trait that has a `.as_jarray_raw()` method that is more-or-less equivalent to `JObject::as_raw()` but in addition to returning a `jarray` type pointer the trait serves as a Java type specification so that we know its safe for `.get_array_length()` to assume the reference corresponds to a Java array.
This makes get_primitive_array_critical unsafe because we can't ensure the safety of the critical section just by taking a mutable reference on the environment (to block JNI calls). Users of the API also need to make sure they avoid any system calls that could depend on other threads (which could lead to a deadlock) and should generally be aware of the side effects from temporarily disabling the garbage collector. This also makes get_array_elements unsafe since there is no built-in synchronization to avoid data races (also applies to get_primitive_array_critical)
These names aim to: 1. better highlight the connection between AutoElements and AutoElementsCritical (both give temp. access to array elements) 2. better highlight the difference (AutoElementsCritical is an unsafe alternative which defines a "critical" section with strict rules) 3. better differentiate these from the new JPrimitiveArray API (and type aliases) Accordingly `JNIEnv::get_primitive_array_critical` has been renamed to `JNIEnv::get_array_elements_critical`, consistent with `JNIEnv::get_array_elements` which returns an `AutoArray`.
…toElements` also requires `unsafe`.
36dd212
to
df94446
Compare
JNI only strictly defines two valid values for a `jboolean` and there's no consensus on whether other values greater than one will be interpreted as TRUE in all situations. The safest interpretation is to say that it will lead to undefined behaviour to pass any value besides zero or one as a `jboolean`. Addresses jni-rs/jni-rs#400 Closes #19
Overview
Instead of all the array-based APIs being based on sys types like
jbyteArray
(which can easily lead to the use of invalid localreferences) this introduces types like
JByteArray<'local>
thathave a lifetime parameter to ensure the local reference can't
be read if it is deleted or goes out of scope.
JByteArray
andJIntArray
etc are based on a genericJPrimitiveArray<T>
which takes any of the primitive types thatmay be put into arrays, like
jbyte
orjint
.JObjectArray
is handled separately, considering that it can't be usedwith
AutoArray
orAutoPrimitiveArray
.The implementations of
AutoArray
andAutoPrimitiveArray
were updatedso they can be created based on a
JPrimitiveAarray
.While updating the lifetime parameters to the
AutoArray
andAutoPrimitiveArray
APIs numerous implementation inconsistencies werefound, even though they should only really differ in how they acquire /
release the pointer to array elements. This patch also normalizes the
implementation of both of these APIs, so they are easily comparable. It
may even be possible to unify these at some point.
Closes: #396
Closes #41
Definition of Done