Java ASM更改方法参考
我正在更改一个方法,以便调用X.interfaceMethod()而不是调用Xhelper.staticMethod(X); 结果大致如下:Java ASM更改方法参考,java,Java,我正在更改一个方法,以便调用X.interfaceMethod()而不是调用Xhelper.staticMethod(X); 结果大致如下: public static java.lang.String str(batik.TwinMeck$Uberchild); descriptor: (Lbatik/TwinMeck$Uberchild;)Ljava/lang/String; flags: ACC_PUBLIC, ACC_STATIC Code: stack=1, locals=1, a
public static java.lang.String str(batik.TwinMeck$Uberchild);
descriptor: (Lbatik/TwinMeck$Uberchild;)Ljava/lang/String;
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokestatic #19 // InterfaceMethod batik/TwinMeck$Child3helper.str:(Lbatik/TwinMeck$Child3;)Ljava/lang/String;
4: areturn
LineNumberTable:
line 34: 0
但是字节码验证失败
Exception Details:
Location:
batik/TwinMeck$Uberchildhelper.str(Lbatik/TwinMeck$Uberchild;)Ljava/lang/String; @1: invokestatic
Reason:
Constant pool index 19 is invalid
其中常量池索引19==
#19 = InterfaceMethodref #16.#18 // batik/TwinMeck$Child3helper.str(Lbatik/TwinMeck$Child3;)Ljava/lang/String;
但是19不应该是一个接口方法,而应该是一个方法参考。我怎样才能告诉ASM5请将条目设置为MethodRef而不是InterfaceMethodRef?当然是我的错
class InterfaceToHelperRewriter(mv: MethodVisitor) extends MethodVisitor(Opcodes.ASM5, mv) {
override def visitMethodInsn(opcode: Int, owner: String, name: String, desc: String, itf: Boolean) = opcode match {
case INVOKESPECIAL if owner.getInternalClass.isInterface =>
println(s"Messing up $owner $name $desc")
super.visitMethodInsn(INVOKESTATIC, owner + "helper", name, desc.addParam(owner), false) // <-------- i used itf instead of false, now it generates a MethodRef and not a InterfaceMethodRef
case _ =>
super.visitMethodInsn(opcode, owner, name, desc, itf)
}
}
class InterfaceToHelperRewriter(mv:MethodVisitor)扩展了MethodVisitor(Opcodes.ASM5,mv){
重写def visitMethodInsn(操作码:Int,所有者:String,名称:String,描述:String,itf:Boolean)=操作码匹配{
如果owner.getInternalClass.isInterface=>
println(s“弄乱$owner$name$desc”)
super.visitMethodInsn(INVOKESTATIC,owner+“helper”,name,desc.addParam(owner),false)//
super.visitMethodInsn(操作码、所有者、名称、描述、itf)
}
}