问题标签 [jvm-bytecode]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
631 浏览

java - 如何使用 asm 将简单的调用语句添加到类文件

考虑我有这个java程序。

现在我有一个 ASM 代码可以遍历方法节点,并且可以访问方法中的指令。假设我添加了调用方法和用于添加简单打印语句的 ldc。[![在此处输入图片描述][1]][1]

这有助于打印语句...假设如果我有一个 ALOAD 语句,即有一个变量用法,我想调用编码函数调用,以便在使用过程中对变量进行编码。所以我的计划是添加编码在 ALOAD 语句之后调用 stmt。如何做到这一点?

0 投票
1 回答
729 浏览

java - 什么是引导方法参数 - Java 字节码

具有 3 个方法参数的引导方法:

具有单个参数的引导方法:

我已经开始研究 Java 字节码并想知道:

  • 什么是引导方法参数?
  • 第一个实例的第二个参数似乎引用了 lamda 表达式。那是什么?

注意: 这不是关于如何确定对象是 lambda。我只想通过检查字节码来了解什么是引导方法参数,以及它与 lambda 表达式的相关性。

0 投票
1 回答
273 浏览

java - 在 java 字节码中创建一个 char 数组会产生一个 Object

我碰壁了,试图用 Java 编写一个简单的编译器,使用 ASM。基本上,我正在尝试将字符串添加在一起,但无法弄清楚为什么我的代码无法这样做。问题在于以下代码行的编译方式:

其中 i 是一个已初始化的数组。行p = "Hi"; 编译为:

请注意,我故意将字符串“Hi”视为 char 数组,而不是直接视为 String 对象。反编译的时候是这样的:

因此,由于 {'H', 'i'} 不是 Object 的正确构造函数,因此程序不会执行。现在,我的困惑,以及我来到stackoverflow的原因是当行p = p + i[0]; 从程序中删除,或替换为不使用数组的,例如p = p + 5;, 行p = "Hi"; 再次以完全相同的方式编译:

反编译时,同一行内容如下:

程序运行得很好。我完全不知道这里发生了什么,也不知道如何解决它。为了反编译 .class 文件,我使用了这个反编译器。我想知道为什么在这两种情况下完全相同的字节码反编译不同。

0 投票
2 回答
153 浏览

java - 如何在编译时未知的索引处从局部变量加载引用?

据我了解 JVM 字节码规范, aload index将找到的引用推index送到当前堆栈帧上。就我而言,我需要aload在存储在局部变量中的索引处找到一个引用 - 像这样:aload (iload 2).

(这怎么可能?

0 投票
1 回答
529 浏览

java - 如果在 ClassWriter 中设置了 COMPUTE_FRAMES,ASM 会跳过类

我一直在研究与 maven-surfire-plugin 一起运行的 Java 代理。代理应该能够在三个不同的点将使用 ASM 库的方法调用注入到加载的方法中: 1) 在每个方法的开头;2) 在每个方法结束时;3) 在某些行(见下文)。为此,我实现了一个 premain 方法,它为 Java 工具添加了一个新的转换器。然后,transform 方法为它应该转换的每个类创建一个新的 ClassWriter 和 ClassVisitor(属于 ASM 库)。

不幸的是,我遇到了一些麻烦。如果设置了COMPUTE_FRAMES标志ClassWriter,我不会收到任何错误,但是代理会跳过某些类并且不会对其进行转换。经过一番研究,我发现造成这种情况的原因(很可能)是getCommonSuperClassClassWriter 的方法,它预先加载了类。

如果我不设置COMPUTE_FRAMES标志,我会收到Expected stackmap frame at this location无法解决的错误。

有人有解决这个问题的方法吗?

0 投票
1 回答
474 浏览

java - Java 11 类文件规范

我正在尝试查找 Java 11 的类文件规范,以便找出 11 和 8 LTS 版本之间的差异。

我发现它适用于 Java 版本 8、9 和 10,但不适用于 11:https ://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html

我还在较新的 OpenJDK 站点上尝试过:http: //openjdk.java.net/projects/jdk/11/spec/

0 投票
2 回答
140 浏览

java - 为什么只为 *const_n JVM 指令定义了这样的常量范围?

根据 JVM规范,有几条指令针对使用一组特定的常量进行了优化。谁能解释为什么只定义了这个常数范围?

  • iconst_n:压入整数常量 n,0 ≤ n ≤ 5
  • lconst_n:推长常量n,0≤n≤1
  • fconst_n:推送浮点常量 n,0 ≤ n ≤ 2
  • dconst_n:push double 常数 n,0 ≤ n ≤ 1

我认为这是由于使用这些常数的频率,但我找不到我的想法或任何其他有关它的信息的确认。

0 投票
1 回答
1104 浏览

java - 使用“invokedynamic” - 引擎盖下发生了什么?

背景

我目前正在用 C# 编写一个 JVM,纯粹是为了学术目的(将来可能会构建一个混合的 .NET 和 Java/Scala 应用程序)。

语境

我编写了简单的JAVA类:

并将其编译成test.class. 当我用我的反编译器(我作为 JVM 的一部分编写的)反编译它时,我看到了这个方法的以下说明:

在常量池中查看 index 处的常量时2,我​​看到一个 InvokeDynamic-Constant 条目,其中包含以下数据:

我想这是有道理的(我更像是 .NET 用户而不是 JAVA 用户)。

hello_world使用参数执行我的方法时1,在执行之前我有以下堆栈invokedynamic 2

问题

我的问题是:我该如何使用invokedynamic
我无法解析该方法makeConcatWithConstants,因为 InvokeDynamic-Constant 没有给我任何提示,makeConcatWithConstants可能位于何处(请参阅文档)。
堆栈也不包含对堆的引用,指示该方法makeConcatWithConstants可以与哪个实例类型相关联。

我通读invokedynamic文档,但我不明白(也许我被 .NET-Framework 严重“损坏”了)。

有人可以给我举一些例子,说明在执行这三个指令时 JVM 引擎盖下发生了什么?(被调用者invokedynamic期望什么等)?

我已经invokestatic在我的 JVM 中实现了……但我目前无法理解invokedynamic

0 投票
2 回答
2133 浏览

java - 构造函数字节码

ASM 指南讨论了构造函数:

Bean 类还有一个由编译器生成的默认公共构造函数,因为程序员没有定义显式构造函数。此默认公共构造函数生成为 Bean() { super(); }. 此构造函数的字节码如下:

第一条指令压this入操作数堆栈。第二条指令从堆栈中弹出这个值,并调用类中<init> 定义的方法Object。这对应于super() 调用,即对超类的构造函数的调用Object。您可以在这里看到,构造函数在编译类和源类中的命名不同:在编译类中它们总是命名为<init>,而在源类中它们具有定义它们的类的名称。最后最后一条指令返回给调用者。

this在构造函数的第一条指令之前,JVM 已经知道的值如何?

0 投票
1 回答
484 浏览

java - ASM:visitLabel 生成太多标签和 nop 指令

ASM 文档说标签代表一个基本块,它是控制图中的一个节点。所以我visitLabel在这个简单的例子上测试了这个方法:

对于该visitLabel方法,我使用本机 API: 对其进行检测setID(int id),其中 id 是增量的。在此示例中,CFG 应具有 3 个节点:一个位于开头,一个用于 if 语句的每个分支。所以我希望setID会在 3 个位置被调用。但是,它被调用了5次,并且有很多nop指令。有人可以为我解释为什么吗?

这是上述程序的检测字节码。

我不明白为什么label每条istore指令前都有一个。没有分支使其成为 CFG 中的新节点。