问题
Iam trying to execute an if statement with logical and symbol '&&'. Here is what iam trying to do: Μy stack in asm byteocode has the values 0 and 1 and i want to get a result with the 'logical and' which in our case it doesn't get into the if statement.
I've tried Opcodes.IFEQ and Opcodes.IFNE instructions but the don't work.Same goes with '||' and '!' logical symbols
Any ideas?
Thanks in advaned.
回答1:
Bytecode patterns for &&
and ||
Think about what a short-circuiting operator like &&
or ||
actually does. You've got some conditional branching. Let's consider &&
. What you're effectively evaluating is:
if (left)
if (right) <do something>
endIf
There is no single bytecode instruction that can describe this behavior. You need need some labels and conditional branching instructions:
.start
<left expression>
IFEQ .endIf // if left evaluates to zero (false), skip to end
<right expression>
IFEQ .endIf // if right evaluates to zero (false), skip to end
.ifTrue
<body of 'if' block>
.endIf
The behavior of the ||
operator is a bit different; in this case, the logic looks something like this:
if (left)
goto .ifTrue
if (!right)
goto .endIf
.ifTrue
<do something>
.endIf
Note how the check on the right operand is inverted to avoid an additional branch when the right operand evaluates to true
. This behavior could be implemented in bytecode like so:
<left operand>
IFNE .ifTrue // if left evaluates true, skip right, enter 'if' body
<right operand>
IFEQ .endIf // if right evaluates false, skip 'if' body
.ifTrue
<do something>
.endIf
When to push your operands
Note that your original question suggested you already have the left and right operands on the stack; that would be bad. You should only evaluate the right operand after the left operand has evaluated to true
(nonzero) for &&
or false
(zero) for ||
. If the right operand causes side effects, evaluating it prematurely would violate the defined behavior of these operators.
回答2:
There are Opcodes.IAND and Opcodes.LAND. You don't mention whether the values on the stack are ints or longs, but I am assuming the former so I think Opcodes.IAND is the one you want.
Similarly, there is Opcodes.IOR for OR. For NOT, javac seems to emit a IFNE and ICONST_1 or ICONST_0 instructions, but if you know the values are either 1 or 0, it seems like you could emit an Opcodes.ICONST_1 followed by Opcodes.IXOR.
See Appendix A of the ASM User Guide, "Bytecode instructions", page 136:
http://download.forge.objectweb.org/asm/asm4-guide.pdf
来源:https://stackoverflow.com/questions/17052001/binary-expression-in-asm-compiler