我想知道我是否可以直接创建一个MethodNode然后分析它。因此,我编写以下代码进行测试:
ClassNode classNode = new ClassNode(Opcodes.ASM5);
classNode.visit(V1_8, ACC_PUBLIC + ACC_SUPER, className, null, Type.getInternalName(BaseTemplate.class), null);
constructClass(classNode, className);
//THREAD SAFE but looks badly.
if(_node == null){
synchronized(this){
if(_node==null){
MethodType tmpType = MethodType.methodType(int.class);
_node = (MethodNode) classNode.visitMethod(ACC_PUBLIC, Constants.INVOKE_EXACT, tmpType.toMethodDescriptorString(),
null, new String[] { "java/lang/Throwable" });
_node.visitCode();
_node.visitInsn(ICONST_0);
_node.visitInsn(IRETURN);
//_node.visitMaxs(-1, -1);
_node.visitEnd();
Analyzer _analyzer = new Analyzer(new SourceInterpreter());
try {
_analyzer.analyze(className, _node);
} catch (AnalyzerException e) {
e.printStackTrace();
}
}
}
}
不幸的是,调用时抛出异常_analyzer.analyze()
:
java.lang.IndexOutOfBoundsException: Trying to access an inexistant local variable 0
at org.objectweb.asm.tree.analysis.Frame.setLocal(Frame.java:175) ~[na:5.0.3]
at org.objectweb.asm.tree.analysis.Analyzer.analyze(Analyzer.java:165) ~[na:5.0.3]
at java.lang.invoke.MethodHandle.compile(MethodHandle.java:1222) ~[na:na]
我相信这是由 and 的未设置引起maxStack
的maxLocals
。看来我必须计算正确maxStack
and maxLocals
,然后visitMax()
在这里调用。有没有其他方法不计算这两个值?
我之前使用的另一种方法是一些代码,例如:
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, className, null, Type.getInternalName(BaseTemplate.class), null);
constructClass(cw, className);
//THREAD SAFE but looks badly.
if(_node == null){
synchronized(this){
if(_node==null){
_node = new MethodNode(ACC_PUBLIC, Constants.INVOKE_EXACT, type.toMethodDescriptorString(),
null, new String[] { "java/lang/Throwable" });
generateMethod(_node, className);
}
}
}
_node.accept(cw);
cw.visitEnd();
ClassNode classNode = new ClassNode(ASM5);
ClassReader reader = new ClassReader(new ByteArrayInputStream(cw.toByteArray()));
reader.accept(classNode, 0);
//Then extract MethodNode from ClassNode and make analyzation.
这可行,但我不喜欢它,因为它包括对 MethodNode 的多次访问。
目的:
我想为每个类实例生成一个 MethodNode,并且每个实例都保留对生成的实例的引用。在第一个代码中,我的想法是直接创建一个ClassNode和目标MethodNode,在此期间让_node
指针直接指向目标MethodNode。这样整个ClassNode就只有1次访问,即在ClassNode创建过程中获取MethodNode。
对于第二部分代码,使用 ClassWriter 并访问它。之后cw.visitEnd()
,我必须再次访问它以获得ClassNode,即reader.accept(classNode, 0);
。该班有两次来访。