我正在阅读这篇关于如何将某些代码转换为Java bytecode. 我遇到过这个例子:
Consider the following Java code:
outer:
for (int i = 2; i < 1000; i++) {
for (int j = 2; j < i; j++) {
if (i % j == 0)
continue outer;
}
System.out.println (i);
}
A Java compiler might translate the Java code above into byte code as follows,
assuming the above was put in a method:
0: iconst_2
1: istore_1
2: iload_1
3: sipush 1000
6: if_icmpge 44
9: …Run Code Online (Sandbox Code Playgroud) 我正在将一种简单的语言编译成 JVM 字节码,并且在 Java 对象方法调用方面存在一些问题。验证器给出以下错误
java.lang.VerifyError: (class: Test_1, method: main signature: ()V) Expecting to find object/array on stack
以下是 IntelliJ 从我的字节码生成的 Java 源代码
import java.util.ArrayList;
public final class Test_1 {
public static void main() {
ArrayList var1 = new ArrayList();
var1.add(19);
int var2 = (Integer)var1.get(0);
}
}
Run Code Online (Sandbox Code Playgroud)
这正是我想要做的。创建一个 ArrayList,分配一个值并从中读取。上面的代码对我来说看起来像是一个有效的 Java 代码。
下面是我的字节码
{
public static void main();
descriptor: ()V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=0
0: new #9 // class java/util/ArrayList
3: dup
4: invokespecial #12 // Method java/util/ArrayList."<init>":()V …Run Code Online (Sandbox Code Playgroud) 我尝试使用py_compile来获取一些字节码示例(用于学习需要)。
然而,这就是我得到的
\n文件.py:
\nprint("hello world")\nRun Code Online (Sandbox Code Playgroud)\n文件.pyc:
\n U\n\n\xef\xbf\xbd\xef\xbf\xbdOb \xef\xbf\xbd @ s e d \xef\xbf\xbd dS )zhello worldN)\xef\xbf\xbdprint\xef\xbf\xbd r r \xef\xbf\xbdtest.py\xef\xbf\xbd<module> \xef\xbf\xbd \nRun Code Online (Sandbox Code Playgroud)\n我想我正在做一些非常错误的事情,但我不知道。
\n我的基本脚本是
\nimport py_compile\n\npy_compile.compile('test.py')\nRun Code Online (Sandbox Code Playgroud)\n F_SAME 在 ASM 中到底有什么用?我在Java虚拟机指令集中查找了这个助记符,没有找到任何相关内容。
我了解堆栈映射框架并且它们节省空间。
但是,为什么在跳转目标、异常处理程序或遵循无条件跳转指令的情况下精确使用该助记符?
尽管如此,还是不可能“预测”堆栈内容的类型?
使用这个是强制性的吗?
我对此进行了很多搜索,但几乎在任何地方都找不到与之相关的任何内容。
谢谢你!
我被拉入了类似于以下代码的性能调查:
private void someMethod(String id) {
boolean isHidden = someList.contains(id);
boolean isDisabled = this.checkIfDisabled(id);
if (isHidden && isDisabled) {
// Do something here
}
}
Run Code Online (Sandbox Code Playgroud)
当我开始调查它时,我希望编译后的版本看起来像这样:
private void someMethod(String id) {
if (someList.contains(id) && this.checkIfDisabled(id)) {
// Do something here
}
}
Run Code Online (Sandbox Code Playgroud)
然而,令我惊讶的是,编译后的版本看起来和第一个版本一模一样,带有局部变量,这导致 in 中的方法isDisabled总是被调用,这就是性能问题所在。
我的解决方案是自己内联它,所以该方法现在在 处短路isHidden,但它让我想知道:为什么 Java 编译器在这种情况下不够聪明,无法为我内联这些调用?它真的需要局部变量吗?
谢谢 :)
我有这两个 Java 和 C++ 代码,它们应该做同样的事情。
我的直觉是, 和 的目标代码的大小(以及内容)将R1相同R2。C++ 就是这种情况(如果编译时没有 4 个字节的差异-O1)。Java 字节码有更大的差异(R2更长),这让我感到惊讶。
也许我没有看到正确的东西,我的问题可能不相关,但是Java字节码与源代码如此“接近”是正常的吗?这是否意味着它总是更“高效”/“优化” “将所有内容写在一行中而不是使用局部变量?
C++
int A(int a) { return 0; }
int B(int b) { return 0; }
int C(int c) { return 0; }
int D(int d) { return 0; }
int R1() {
return A(B(C(3)+D(3)));
}
int R2() {
int d = D(3);
int c = C(3);
int b = B(c + d);
return A(b);
}
// Then R1() …Run Code Online (Sandbox Code Playgroud) 我一直在对 Java 应用程序进行逆向工程,并且偶然发现了一些有趣的东西。我发现的字节码似乎违反了规则,因为没有首先在构造函数中初始化超类。
我正在尝试弄清楚这怎么可能。这可能是Java编译器的正常行为,还是某种偷偷摸摸的混淆技术(注:值得一提的是,原始类名尚未被混淆器剥离,这表明混淆过程可能不是很彻底。因此,字节码结构不太可能是故意混淆的结果。)
任何人都可以提供一些关于生成这种非常规字节码的原始代码是什么样子的见解吗?我渴望了解并解开这个谜团。非常感谢!
这是字节码。
final class a/ka$a extends java/lang/Thread {
<ClassVersion=51>
<SourceFile=CLThreadPool.java>
private synthetic a.ka a;
public ka$a(a.ka arg0, java.lang.String arg1, boolean arg2) { // <init> //(La/ka;Ljava/lang/String;Z)V
<localVar:index=0 , name=this , desc=La/ka$a;, sig=null, start=L0, end=L4>
<localVar:index=2 , name=name , desc=Ljava/lang/String;, sig=null, start=L0, end=L4>
<localVar:index=3 , name=daemon , desc=Z, sig=null, start=L0, end=L4>
L0 {
aload 0 // reference to self
aload 1 // reference to arg0
putfield a/ka$a.a:a.ka
}
L1 {
aload 0 // reference to self
aload 1 …Run Code Online (Sandbox Code Playgroud) 是否有可能首先将一组Java源代码文件编译成字节码,然后运行该字节码 - 不是直接运行,而是通过向另一个java程序添加命令 - 这样这个新的java程序(在其各种类/函数中)运行以前编译的java字节码?
如果可以,那么执行此操作所需的命令是什么?
我一直在研究java类文件格式.我一直在研究从字节码创建类.我已经能够从oracle文档和其他Google搜索中找到我需要的大部分信息.但是我无法找出构造函数在类文件中的存储方式和位置.我认为它们可能存储在方法表中,但我不确定,如果它们是我想要它们如何存储的说明.
这是一个非常简单的问题:
当你编译一个java程序时,它被转换为字节代码,因此,错过了.java或.class文件的每个行号(我想是的,可能我错了..).因此,当您打印堆栈跟踪时,它如何设置获取调用堆栈中的所有类名和行号?我想我可能在这里遗漏了一些东西,但我找不到任何与此有关的东西.
bytecode ×10
java ×9
.class-file ×2
jvm ×2
compilation ×1
javac ×1
jvm-bytecode ×1
obfuscation ×1
optimization ×1
performance ×1
python ×1
stack-trace ×1
verifyerror ×1