Creating JVM bytecode for unary non-expression

Say you are writing a Java compiler (or a subset of Java) and you want to generate bytecode for a unary non-expression,! !E You passed a type check so that you know that E is of type boolean , that is, it will push 1 or 0 on the operand stack.

One way to do this is with something like (in Jasmin syntax):

 E ifeq truelabel iconst_0 goto stoplabel truelabel: iconst_1 stoplabel: 

i.e. if there is 0 on the stack, press 1, otherwise press 0. Another way to do this is by using the fact that a boolean is just an int with a value of 1 or 0 , means !E = (E + 1) % 2 and generate

 E iconst_1 iadd iconst_2 irem 

Is there an advantage to using one over the other? Or something else?

+7
source share
3 answers

I would not count on the following definition, which should be true at the bytecode level.

 true == 1 

At the binary level (and its near linguistic independence), a logical value is usually defined as

 false == 0 true != 0 

The javac compiler apparently also follows this definition (all the checks in the javac byte codec that I saw always check ZERO again, never against ONE).

And it makes sense to use this definition for boolean instead of treating only 1 as true, C also defines it that way (true is simple! = 0, not just 1), and in the assembly code this convention is also widely used. Thus, java also uses this definition, allowing you to receive / pass java Booleans to other code without any special conversions.

I suspect your first code example (with ifeq) is the only way to correctly implement a non-operator for booleans. ^ 1-method (xor with 1) will not be executed if the logical value is not represented as 0/1. Any other int value will cause the expression to work incorrectly.

+4
source

I once tried to write a Java decompiler, so I knew which javac code was generated. As far as I remember, javac 1.0.x used !E = E ? false : true !E = E ? false : true while javac 1.1 used !E = E ^ 1 (bitwise XOR).

+5
source

I heard that module operations can be very slow. I have no source for this, but that makes sense, given how much easier it is to add than to share. Again, it may happen that the program counter overloads too much, in which case the if / else approach will not work too well.

With that said, I would suggest that Neil E ^ 1 is the fastest, but it's just a hunch. All you have to do is pass the number through one logic circuit, and you're done! Only one operation, not a handful.

0
source

All Articles