问题标签 [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.
java - 为什么在常量池中对字符串、整数、浮点数等使用单独的标签
在常量池定义中,根据规范,为什么需要将 CONSTANT_String, CONSTANT_Integer, ... 作为单独且唯一的标签?
为什么这些标签不能像所有其他类一样被视为 CONSTANT_Class 标签?
仅仅是因为这些是系统类吗?但如果是这样,除了提到的之外,还有其他系统类。
在这里阅读:https ://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4
lambda - Null 或空 lambda 作为默认值
哪种解决方案更好?使用可为空的 lambda 或将空 lambda 作为默认参数传递?kotlin 会以某种方式优化空 lambda,还是创建一个什么都不做的新实例?
class Test1(val action: () -> Unit = {})
不幸的是,我不理解生成的字节码。我们来分析一下
val test11 = Test1()
反编译后给我们:
private static final Test1 test11 = new Test1((Function0)null, 1, (DefaultConstructorMarker)null);
最后,当传递一个 lambda 时,如下所示:
var1 = (Function0)null.INSTANCE;
编辑:隐藏的问题是:Kotlin 如何将空 lambda 视为默认值?
java - ASM 不能将“Type.INT_TYPE”作为常量引导方法参数传递
考虑以下旨在invokedynamic
使用 ASM 生成指令的代码:
使用 ASMifier 反编译生成的类时,相关行变为
如您所见,Type.INT_TYPE
已变成对名为 的引用类型的字面引用I
。由于这不存在,JVM 在运行时抱怨java.lang.BootstrapMethodError: java.lang.NoClassDefFoundError: I
.
相反,我想做的是将int.class
(Class
原始类型的实例int
,或Integer.TYPE
常量的值)传递给我的bootstrap
方法作为someClass
. 但是,ASM 似乎没有正确理解或支持这一点。
这是否可以被视为 ASM 错误,是否有解决方法?
java - Java中参数的内存分配
以下语句中的数据将存储为自动内存分配,还是动态内存分配,或两者兼而有之
谢谢你!
bytecode - ASM 访问者删除无法访问的代码
我正在尝试一种检测死代码并使用 ASM 从字节码中删除它的方法。我正在关注ASM 4 Guide,并且在第 119 页中声明了一个死代码删除访问者,如下所示:
另外,我正在尝试使用以下代码调用此访问者:
我正在使用的代码示例是:
理论上,该行throw new RuntimeException("true is not true");
可以被认为是不可访问的代码,因为它永远不会被执行。这种方法的问题是语句mn.instructions.remove(insns[i])
永远不会被触及。我不知道原因,因为我们对该方法有一个无法访问的声明。你们看到这种方法有什么问题吗?
java - 使用 Unsafe.defineClass 在运行时定义多个类
我正在为我的自定义编程语言开发 REPL。它在编译器之上实现,用于生成输入的字节码并使用该方法将其转换为Class<?>
实例。sun.misc.Unsafe.defineClass(String, byte[], int, int, ClassLoader, ProtectionDomain)
相关代码如下所示(省略异常处理等无关部分):
假设输入需要编译和加载多个类。
compilables
列表有内容
该类repl.Result_0$A
依赖于repl.Result_0$A$0
(匿名)类和repl.Result_0$B
类,并在字节码中引用它们的名称。使用 定义时Unsafe
,会出现以下错误:
我知道这可以通过重新排序列表并repl.Result_0$A$B
首先定义来解决,但这不是一个通用的解决方案,因为也可以引用B -> A
。
有没有一种方法可以定义和加载多个类,Unsafe.defineClass
而不会导致未解析的类出现验证错误?
java - 使用 asm java 时出现验证错误
所以基本上我试图System.out.println("hey");
在方法的末尾添加一个简单的。我使用了树 API。但是,我确实不断收到此错误:
java.lang.VerifyError:在分支目标 38 处期望堆栈图帧
这是我的代码:
这是我的班级节点:
这就是我“注入”代码的方式(我直接从 jar 加载它,这就是它使用 zipFile 的原因)
就像我说的那样,当我运行它时,我会收到验证错误,有什么方法可以解决它,或者有什么更聪明的方法可以让我“注入”该代码?
java - 如何计算 MethodVariableAccess 中的局部变量索引?
根据 [1],在方法框架中,局部变量数组包含对被调用实例的引用、参数以及最后在方法代码中使用的任何其他变量。此外,long
和double
值占用两个局部变量。
当使用 Byte Buddy 通过堆栈操作生成方法的代码时,MethodVariableAccess.OffsetLoading
索引long
和double
值是否会成为单个索引,或者是否需要像直接使用 ASM 那样考虑这些类型的值来计算本地 var 索引?
[1] https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.6.1
java - 如何使用 ByteBuddy 创建动态代理
在 Java 中,可以使用InvocationHandler
. 尽管 JVM 进行了优化,但使用反射调用方法总是会有一些开销。
为了尝试解决这个问题,我尝试使用 ByteBuddy 在运行时创建代理类,但是文档在这方面似乎不够清楚。
如何创建一个MethodCallProxy
以便将方法调用转发到某个类实例?
编辑:
为了更好地澄清我的问题,我提供了一个我想要实现的示例:
我正在构建一个 RPC 系统。在方法调用的每一端,我都有一个定义契约的接口(当调用者/被调用者都在 JVM 下运行时)。
在调用站点,我注入了一个代理,它拦截所有方法调用并将它们转发给被调用者。
最后,在被调用方,我有几个处理程序,每个服务方法一个,负责解组调用参数并将它们转发到服务实现。
我可以使用代码生成来解决这个问题,但是生成的jar
文件可能会变得非常大。因此,我想创建这些处理程序的通用版本,并在每个实例中附加一个代理,该代理拦截每个方法调用ISomeService
并将它们转发到SomeServiceImpl
.
java - Unsed 局部变量 Java 8 - java.lang.VerifyError: Inconsistent stackmap frames
我最近将我的项目从 1.7 升级到 Java 1.8。
对于我的一个类中的方法,我得到了一个不一致的堆栈映射异常。
在方法中初始化一些未分配的局部变量解决了它,但是有人可以解释为什么在 Java 8 中使用未读变量会引发异常,谢谢。
很可能与正在使用的 Eclipse 版本(Kepler SR 2 20140224-0627)有关,只是好奇。
解决方法
在修复错误代码之前,以前使用过“--xxSplitVerifier”(在 1.7 中)或“-noVerify”Jvm 参数。
如果使用选项“保留未使用的局部变量”未选中 Eclipse 工作区中的编译器首选项,则它可以使用 java 8 正常编译
方法:
无法发布完整的方法,因为我所在公司的代码非常庞大且受限制。
堆栈帧:
原因:java.lang.VerifyError:分支目标 2079 处的堆栈图帧不一致
异常详细信息:位置:someClass.setData(someClass/Data)I @2079:iload_3
原因:类型 top(当前帧,locals[4])不可分配给 'java/lang/StringBuffer'(堆栈映射,locals[4])
当前帧:bci:@98 标志:{ } locals:{ 'someClass/setData', 'someClass/Data', 'someClass/Data', integer, top, top } stack: { 'someClass/Data' }
Stackmap Frame: bci: @2079 flags: { } locals: { 'someClass/setData', 'someClass/Data', 'someClass/Data', integer, 'java/lang/StringBuffer', 'java/lang/String' }堆栈:{}字节码:0x0000000:2bb6 032b 4d03 3e06 bd01 3e59 0313 032f 0x0000010:5359 0413 0331 5359 0513 0333 533a 0606