问题
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