Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jvm 如何将不同的基元数据加载到操作数堆栈_Jvm_Bytecode_Java Bytecode Asm_Vm Implementation - Fatal编程技术网

Jvm 如何将不同的基元数据加载到操作数堆栈

Jvm 如何将不同的基元数据加载到操作数堆栈,jvm,bytecode,java-bytecode-asm,vm-implementation,Jvm,Bytecode,Java Bytecode Asm,Vm Implementation,JVM有两条指令:bipush(操作数值应介于Byte.MIN\u值和Byte.MAX\u值)和sipush(操作数值应介于Short.MIN\u值和Short.MAX\u值之间)。相应地,ASM中的MethodVisitor提供了操作这两条指令的API: public void visitIntInsn(int opcode, int operand) 因此,如何访问ASM中的其他非字节(短)原语?例如,原语long、double、int、boolean和float数据?看起来很

JVM有两条指令:
bipush
(操作数值应介于
Byte.MIN\u值
Byte.MAX\u值
)和
sipush
(操作数值应介于
Short.MIN\u值
Short.MAX\u值
之间)。相应地,ASM中的
MethodVisitor
提供了操作这两条指令的API:

      public void visitIntInsn(int opcode, int operand)

因此,如何访问ASM中的其他非字节(短)原语?例如,原语
long
double
int
boolean
float
数据?看起来很奇怪,这些数据被包装为
Long
Double
Integer
,布尔值只是JVM级别的整数。按0表示错误,按1表示正确。您不需要使用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

您可以在ASM中使用适当命名的创建
ldc
指令

请注意,
ldc
需要常量池中的空间,该池限制为65534个插槽。然而,它足够大,在实际情况下你永远不会用完。如果确实需要,可以通过使用数学构造值来推送较大的原语值,而无需使用常量池


例如,int 111111可以由iconst_3 bipush 15 ishl sipush 12807 iadd生成。Enjarify为每种灵长类动物都编写了这样的代码,即使是双倍的,尽管出于明显的原因,它们通常需要更多的指令来表示。但是,如果您使用的是ASM,那么您可能没有做任何不寻常和复杂到需要这种方法的事情。

布尔值只是JVM级别的整数。按0表示错误,按1表示正确。您不需要使用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

您可以在ASM中使用适当命名的创建
ldc
指令

请注意,
ldc
需要常量池中的空间,该池限制为65534个插槽。然而,它足够大,在实际情况下你永远不会用完。如果确实需要,可以通过使用数学构造值来推送较大的原语值,而无需使用常量池


例如,int 111111可以由iconst_3 bipush 15 ishl sipush 12807 iadd生成。Enjarify为每种灵长类动物都编写了这样的代码,即使是双倍的,尽管出于明显的原因,它们通常需要更多的指令来表示。但是,如果您使用的是ASM,您可能没有做任何异常和复杂到需要这种方法的事情。

请注意,在ASM中,
push(0)
push(false)
将自动生成
iconst\u 0
指令,而不是
bipush 0
,因此,您的抽象级别稍微高一点。我不会将复杂的指令序列用于
111111
,尤其是因为它不小于常量池中所需的空间。但是,使用类似于
iconst_5,i2l
的方法来推动
long
常量
5L
是合理的,imho.@Holger,这是专门针对常量池中空间耗尽的情况。正如我所说,这不是一种正常的情况。我想,如果您用完了常量池项的最大数量,您可能会达到其他限制,例如最大代码大小或最大方法数。但另一方面,将int常量扩展为long或double是合理的,如
iconst\n;i2l
iconst;i2d不仅在常量池中保存九个字节,在实际方法的代码中甚至保存一个字节。即使使用
bipush n,i2…
,与等效的
ldc2\u w
指令具有相同的代码大小(同时仍将九个字节保存在池中)…请注意,在ASM中,
push(0)
push(false)
将自动生成
iconst\u 0
指令,而不是
bipush 0
,因此,您的抽象级别稍微高一点。我不会将复杂的指令序列用于
111111
,尤其是因为它不小于常量池中所需的空间。但是,使用类似于
iconst_5,i2l
的方法来推动
long
常量
5L
是合理的,imho.@Holger,这是专门针对常量池中空间耗尽的情况。就像我说的,这不是一个正常的现象。我想,如果你用完了最大数量的固定池项目,你会