On Fri, Aug 17, 2018 at 7:25 PM, Aleksey Shipilev <sh...@redhat.com> wrote: > On 08/17/2018 05:12 PM, Volker Simonis wrote: >> The offending code in Console_md.c looks as follows: >> >> #define ECHO 8 >> >> JNIEXPORT jboolean JNICALL >> Java_java_io_Console_echo(...) { >> >> jboolean old; >> ... >> old = (tio.c_lflag & ECHO); >> ... >> return old; >> } >> >> The intention of this code is to return "true" if the ECHO flag was >> set but it really returns the value of ECHO (which is defined as '8' >> in a system header). >> >> The question now is, if a Java SE compatible VM guarantees that any >> arbitrary, non-zero valued jboolean will be interpreted as "JNI_TRUE" >> and only a zero valued jboolean will be interpreted as "JNI_FALSE"? >> >> Or, the other way round, is the normalization performed by the HotSpot >> result handlers necessary (i.e. enforced by the specification) or just >> a convenience to fix broken code like the above from Console.echo()? > > I think this is intentional aftermath of boolean value normalization: > https://bugs.openjdk.java.net/browse/JDK-8161720 >
OMG - I'm getting old :) Thanks for the link to JDK-8161720! Funny enough I was one of the reviewers of JDK-8161720 and almost exactly two years ago I already asked the exactly same question [1]: "And I have a question about JNI: is it only a convention that JNI functions should return JNI_TRUE/JNI_FALSE or is this required by the specification?" Zoltan answered to that question by citing an excerpt from the JNI Programmer's Guide & Specification [2]: "A |jboolean| is an 8-bit unsigned C type that can store values from 0 to 255. The value 0 corresponds to the constant |JNI_FALSE|, and the values from 1 to 255 correspond to |JNI_TRUE|." But the "JNI Programmer's Guide & Specification" is from 1999 and it only contains the cited sentence in its "Traps and Pitfalls" section and not in the "Specification" part. The latest JNI Specification [3] doesn't seem to contain such a rule. So to summarize, my current view on this topic is: - JNI functions returning a jboolean are only allowed to return JNI_TRUE/JNI_FALSE (or 1/0) according to the current JNI spcification. - to code in Java_java_io_Console_echo() should be fixed (as confirmed by Sherman later in this thread) - normalization of native, off-heap 8-bit values to Java booleans as currently implemented in the HotSpot (and fixed by JDK-8161720) is (1) only for convenience to simply access to off-heap data in Unsafe, (2) to implement better Java/Native integration in projects like Panama and (3) to fix legacy JNI code which was developed under the assumption that the advice in the "JNI Programmer's Guide & Specification" book is specification relevant. Do you agree? Thank you and best regards, Volker [1] http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2016-August/024192.html [2] https://web.archive.org/web/20120626012047/http://java.sun.com/docs/books/jni/html/pitfalls.html#30066 [3] https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/jniTOC.html > So, Java_java_io_Console_echo looks broken and needs to be fixed, by e.g.: > > - old = (tio.c_lflag & ECHO); > + old = (tio.c_lflag & ECHO) != 0; > > Thanks, > -Aleksey >