给定Java类A的.class文件,有没有办法(例如用BCEL,ASM等)提取给定的字节码序列(假设它是一个基本块),将它放在一个单独的位置,并且然后再执行那个字节码序列?
实施例: 源代码有线... a + = b; b + = 21; 。
我只能访问字节码表示。我想提取那些字节码并将它们视为黑盒子。在A类的指令中,而不是源行'a + = b;'我希望它指向这个外部黑盒子X,它保存了适当的缺失字节码序列。我想在堆栈帧上提供黑盒子所有必要的变量(例如,a,b的当前值,可能是在黑盒子X中使用的方法参数......)然后,在执行字节码序列之后,黑匣子将控制权返回到原始的A类以及新更新的帧变量...
感谢任何想法。
编辑:
如下所示,黑盒最合理的是存根类文件中的存根方法。接下来的问题是,如何从这个指令序列中最合理地创建这个格式良好的存根类和方法,以及如何从原始类A转移控制。理想情况下,这将在编译时“离线”完成时间。
答案 0 :(得分:2)
在符合JVM规范的Java实现上执行字节码的唯一方法是将字节码放入(格式良好的)类文件中并加载该文件。 (这意味着字节码需要包装在类文件的“方法”中,因为这是字节码可以去的唯一地方。)
此外,字节码必须遵守字节码验证器强制执行的所有安全规则。这将限制你执行任意序列的能力。
如果你只想弄清楚字节码序列的作用,你最好手动执行它,或使用某种字节码模拟器。
答案 1 :(得分:1)
棘手的部分是如何识别您的指令序列。我可以想到在序列的开头和结尾通过行号或一些标记方法调用来做到这一点。
当你完成整理后,可以使用ASM的分析包来计算局部变量和堆栈槽的类型,并将它们作为复制字节码序列的某种方法的参数公开。
我的article from AOSD'07应该为您提供ASM的良好起点。替换描述转换的方法主体和内联方法部分非常类似于您可能需要使用的部分。