Binary expression in asm compiler

…衆ロ難τιáo~ 提交于 2019-12-24 09:47:17

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!