我正在使用ASM Java库来替换一些反射.我生成了这个方法的主体:
void set(Object object, int fieldIndex, Object value);
Run Code Online (Sandbox Code Playgroud)
使用此生成的方法,我可以在运行时在不使用反射的情况下在对象上设置字段.它很棒.但是,我发现原始字段失败了.这是我的set方法的相关部分:
for (int i = 0, n = cachedFields.length; i < n; i++) {
mv.visitLabel(labels[i]);
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
mv.visitVarInsn(ALOAD, 1);
mv.visitTypeInsn(CHECKCAST, targetClassName);
mv.visitVarInsn(ALOAD, 3);
Field field = cachedFields[i].field;
Type fieldType = Type.getType(field.getType());
mv.visitFieldInsn(PUTFIELD, targetClassName, field.getName(), fieldType.getDescriptor());
mv.visitInsn(RETURN);
}
Run Code Online (Sandbox Code Playgroud)
此代码为选择生成案例标签.它适用于对象,但对于原语,我收到此错误:
期待在堆栈上找到浮动
好的,这是有道理的,我需要自己进行拆箱.我实现了以下内容:
for (int i = 0, n = cachedFields.length; i < n; i++) {
mv.visitLabel(labels[i]);
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
mv.visitVarInsn(ALOAD, 1);
mv.visitTypeInsn(CHECKCAST, targetClassName);
mv.visitVarInsn(ALOAD, 3);
Field field = …Run Code Online (Sandbox Code Playgroud) 我得到了一些在我的程序中生成的java-byte-code(如此编译的java-source).现在我想将这个字节码加载到当前运行的Java-VM中并运行一个特定的函数.我不知道如何实现这一点,我在Java类加载器中挖掘了一点,但没有找到直接的方法.
我找到了一个解决方案,它在硬盘上采用了一个类文件,但是我得到的字节码是在字节数组中,我不想把它写到磁盘上而是直接使用它.
谢谢!
我想从distutils创建一个只有字节码的发行版(不是真的,我这样做;我知道我在做什么).使用setuptools和bdist_egg命令,您只需提供--exclude-source参数即可.不幸的是,标准命令没有这样的选项.
在设计字节码解释器时,这些天是否有关于堆栈或三种地址格式(或其他什么?)更好的共识?我正在考虑这些考虑因素:
目标语言是一种非常类似于Javascript的动态语言.
性能很重要,但目前开发速度和可移植性更是如此.
因此,实施将严格地作为解释者; 资源许可后,JIT编译器可能会更晚出现.
口译员将用C语言编写.
假设我有一Fraction节课:
class Fraction {
...
/** Invert current fraction */
public Fraction inverse() {
return new Fraction(den,num);
}
...
}
Run Code Online (Sandbox Code Playgroud)
这就是上述方法的字节码结果如下:
0 new #1 <xyzTestes/system/fraction/Fraction>
3 dup
4 aload_0
5 getfield #16 <xyzTestes/system/fraction/Fraction.den>
8 aload_0
9 getfield #14 <xyzTestes/system/fraction/Fraction.num>
12 invokespecial #27 <xyzTestes/system/fraction/Fraction.<init>>
15 areturn
Run Code Online (Sandbox Code Playgroud)
我试图理解为什么第3位的指令首先放在那里.我要说我们只需要做以下工作就可以了:
new #1 <xyzTestes/system/fraction/Fraction>
aload_0
getfield #16 <xyzTestes/system/fraction/Fraction.den>
aload_0
getfield #14 <xyzTestes/system/fraction/Fraction.num>
invokespecial #27 <xyzTestes/system/fraction/Fraction.<init>>
areturn
Run Code Online (Sandbox Code Playgroud)
为什么不是这样?
当使用java反编译器(http://java.decompiler.free.fr/)反编译一个特定的jar时,我得到了一些奇怪的代码,我无法识别它是什么.有人能帮我吗?代码是这样的:
Foo.access$004(Foo.this);
Run Code Online (Sandbox Code Playgroud)
或这个
Bar.access$006(Bar.this);
Run Code Online (Sandbox Code Playgroud)
要不然
Baz.access$102(Baz.this, true)
Run Code Online (Sandbox Code Playgroud)
这些方法是什么access$004,access$006并且access$102?
我正在开发一个业余的JVM实现,我正在努力确保我对规范中的所有操作码都有测试覆盖率.我已经得到它倒在过去的几年,但nop和swap已经躲避我.例如,这是一个可能使用的简单函数swap:
static int do_swap() {
int a = 56;
int b = 32;
return b%a;
}
Run Code Online (Sandbox Code Playgroud)
但是生成的字节码javac 1.6避免了交换代替本地存储:
static int do_swap();
Code:
0: bipush 56
2: istore_0
3: bipush 32
5: istore_1
6: iload_1
7: iload_0
8: irem
9: ireturn
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
编辑2:具有完全object-oriented实现的程序是否具有高性能?大多数framework都是用它的全部功能编写的.然而,reflection也被大量用于实现它,因为AOP和dependency injection.使用reflection会在一定程度上影响性能.
那么,使用它是好的做法reflection吗?是否有一些替代编程语言结构的反射?应该reflection在多大程度上使用?
我正在使用ASM进行在线字节码方法内联优化.我的更改基于示例3.2.6 Inline Method(http://asm.ow2.org/current/asm-transformations.pdf).测试示例(在Caller :: test中内联被调用者的计算(int,int))是:
public class Caller {
final Callee _callee;
public Caller(Callee callee){
_callee = callee;
}
public static void main(String[] args) {
new Caller(new Callee("xu", "shijie")).test(5, 100);
}
public void test(int a, int b){
int t = a;
int p = b;
int r = t+p-_callee.calculate(a, b);
int m = t-p;
System.out.println(t);
}
}
public class Callee {
final String _a;
final String _b;
public Callee(String a, String b){
_a = a;
_b …Run Code Online (Sandbox Code Playgroud) java bytecode inline bytecode-manipulation java-bytecode-asm
我想知道如何修改字节码,然后重新编译该代码,以便我可以在python中使用它作为一个函数?我一直在努力:
a = """
def fact():
a = 8
a = 0
"""
c = compile(a, '<string>', 'exec')
w = c.co_consts[0].co_code
dis(w)
Run Code Online (Sandbox Code Playgroud)
反编译为:
0 LOAD_CONST 1 (1)
3 STORE_FAST 1 (1)
6 LOAD_CONST 2 (2)
9 STORE_FAST 1 (1)
12 LOAD_CONST 0 (0)
15 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
假设我想摆脱第0和第3行,我打电话给:
x = c.co_consts[0].co_code[6:16]
dis(x)
Run Code Online (Sandbox Code Playgroud)
这导致:
0 LOAD_CONST 2 (2)
3 STORE_FAST 1 (1)
6 LOAD_CONST 0 (0)
9 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
我的问题是如何处理x,如果我尝试exec x我得到一个'没有nullbytes的预期字符串,我得到相同的exec w,尝试编译x结果:compile()期望字符串没有空字节.
我不知道最好的方法是什么,除了我可能需要创建某种代码对象,但我不知道如何,但我认为它必须是可能的字节游戏,python汇编程序等
我正在使用python 2.7.10,但如果可能的话,我希望将来兼容(例如python 3).
bytecode ×10
java ×7
python ×2
classloader ×1
coding-style ×1
compilation ×1
decompiling ×1
distutils ×1
inline ×1
interpreter ×1
javac ×1
jvm ×1
opcode ×1
reflection ×1