How to modify instructions in Java BootstrapMethods using ASM?

北战南征 提交于 2019-12-11 07:29:36

问题


After compiling with Java 8 and dumping the resulting class files with javap, I see this, of which I am only showing the first 2 items:

BootstrapMethods:

  0: #174 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;

    Method arguments:

      #175 (Ljava/lang/Object;)Z

      #179 invokestatic llllll/lallll.lambda$printPersons$0:(Lllllll/lallll;)Z

      #180 (Lllllll/lallll;)Z

  1: #174 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;

    Method arguments:

      #175 (Ljava/lang/Object;)Z

      #191 invokestatic llllll/lallll.lambda$printPersons$1:(Lllllll/lallll;)Z

      #180 (Lllllll/lallll;)Z

  2: #174 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/inv

Can I use ASM to visit the instructions in these bootstrap methods and change, say, the names of the methods being called using invokestatic instructions above?

Apparently these methods are not part of the normal methods of a class, and I haven't had any luck visiting them using standard ASM class and method techniques.

If not using ASM, is it possible to find and modify these instructions using another Java bytecode/class file manipulation framework?

I been reading the standard class file format documents for Java and I am not seeing a direct description of the instructions for the bootstrap methods, though I do see what I will describe as metadata for the bootstrap methods.

thanks,

-David


回答1:


The BootstrapMethods attribute contains references to other methods. There are no bootstrap methods in your class file (usually) and you actually do not want to change the bootstrap method, which is the method metafactory within the class java.lang.invoke.LambdaMetafactory in your example.

What you actually want to do (apparently), is to change the properties of the invokedynamic instruction that will create the instance for a lambda expression or method reference. For this task, ASM does already help you.

When using the Visitor API, you have to override visitInvokeDynamicInsn. At this place, ASM has already decoded the referenced entry of the BootstrapMethods attribute, provides these values to the visit method and will (re)create the appropriate BootstrapMethods attribute when you pass these, possibly changed, values to the visitInvokeDynamicInsn method of the ClassWriter’s method visitor.

Within the overridden visitInvokeDynamicInsn, you first have to verify that this invokedynamic instruction truly is a lambda creation site. The bsm argument must be a Handle whose owner is java/lang/invoke/LambdaMetafactory and the method must be either metafactory or altMetafactory. If not, just pass everything to super.visitInvokeDynamicInsn (delegating to the writer unchanged), as it is a different use of the invokedynamic feature then (e.g., Java 9 will use it for string concatenation).

When it is a lambda creation site, you can interpret the arguments according to the conventions specified in the documentation of LambdaMetafactory. The bsmArgs array corresponds to the attribute you have posted in your question. The array element at index 1 will be the target method, again represented as Handle in ASM. You may change it to a different handle, which seems to be your intended operation. The target functional interface is the return type encoded in the desc argument and the name of the functional interface’s method is provided as name argument (the invokedName name argument of the bootstrap method). For more details, refer to LambdaMetafactory’s comprehensive documentation.



来源:https://stackoverflow.com/questions/47561756/how-to-modify-instructions-in-java-bootstrapmethods-using-asm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!