shi*_* xu 1 jvm bytecode java-bytecode-asm vm-implementation
JVM有两条指令:( bipush操作数值应介于Byte.MIN_VALUE和之间Byte.MAX_VALUE.)和sipush(操作数值应介于Short.MIN_VALUE和之间Short.MAX_VALUE).相应地,MethodVisitorASM中提供API来操作这两个指令:
public void visitIntInsn(int opcode, int operand)
Run Code Online (Sandbox Code Playgroud)
因此,如何访问ASM中的其他非字节(短)基元?例如,原语long,double,int,boolean,和float数据?这看起来很奇怪,这些数据被封装为Long,Double,Integer.
布尔值只是JVM级别的整数.将0推送为false,将1推送为true.你不需要使用bipush,你可以使用iconst_0和iconst_1.
字节,短路,字符和整数也都是JVM级别的内容.字节码中没有短基元类型的概念,只有截断函数(i2c和co).
如果你想推送int值111,你会使用bipush 111.如果你想推1111,你会用sipush 1111.如果你想推111111,你会使用ldc 111111.它们都只是字节码级别的整数.
对于浮点数,双打数和长数字,在大多数情况下,您必须使用ldc*指令系列.对于0或1常量的特殊情况下,您可以改用lconst_0,dconst_1等等.
您可以ldc使用恰当命名的MethodVisitor.visitLdcInsn在ASM中创建指令.
请注意,ldc常量池中需要空间,限制为65534个插槽.但是,它足够大,你永远不会在实际情况下用完.如果你真的想要,你可以通过使用数学来构造值,而不使用常量池来推送更大的原始值.
例如,int 111111可以由iconst_3 bipush 15 ishl sipush 12807 iadd.生成.Enjarify有代码为每个主要类型执行此操作,甚至是双倍,尽管他们通常需要更多指令来表示,原因很明显.但是,如果您正在使用ASM,那么您可能没有做任何不寻常和复杂的事情来要求这种方法.
| 归档时间: |
|
| 查看次数: |
612 次 |
| 最近记录: |