While looking at jni-rs/jni-rs#400 it was noted that there's a risk that code can easily cause undefined behaviour for the JVM by setting boolean array elements to values other than 0
or 1
.
This isn't something that's specific to array elements though; anywhere that Rust returns a jboolean
to Java it needs to ensure the byte value is either 0
or 1
.
Since jboolean
is currently simply an alias for u8
(pub type jboolean = u8;
) then it's very easy to return arbitrary invalid boolean values to the JVM.
My initial thought was that we could represent a jboolean
as:
#[repr(u8)]
enum jboolean {
False=0,
True=1
}
and it was then also noted by @argv-minus-one that this is essentially how the Rust Reference defines bool
: https://doc.rust-lang.org/reference/types/boolean.html
My initial reservation with simply defining jboolean
as an alias for bool
is that Rust doesn't generally guarantee much in terms of stable ABI and I wouldn't like to potentially depending on an implementation detail. e.g. the Rust Reference says "this book is not normative. It may include details that are specific to rustc itself, and should not be taken as a specification for the Rust language."
It looks like historically bool
was assumed to be defined in terms of the C _Bool
type (and several FFI projects have made that assumption) which wouldn't technically guarantee that bool
were one byte on all platforms, ref: https://internals.rust-lang.org/t/rusts-stability-story-should-apply-to-bool-in-ffi/6305/8
Considering the follow up discussion here: rust-lang/rust#46176 it looks like the consensus was that bool
is defined to be the same as C's _Bool
but it was also noted that that means it's one byte one all platforms supported by Rust.
A bool
is also explicitly documented as being one byte here: https://doc.rust-lang.org/std/mem/fn.size_of.html
I think it's fair to conclude that Rust's bool type is basically guaranteed to always be 1 byte and to also use the values 1
and 0
for true and false - which is what we want for jboolean