InvokeSpecialTransformer

A Transformer that replaces INVOKESPECIAL instructions in static methods with INVOKEVIRTUAL equivalents.

The client contains some methods in final classes that use INVOKESPECIAL to invoke non-<init> methods on objects of exactly the same type as the containing class. Furthermore, these INVOKESPECIAL instructions are sometimes present in static methods.

As the containing class is final and as the method reference is not a superclass of the containing class, these calls actually end up being treated in the exact same way as an INVOKEVIRTRUAL call.

While these calls are unusual (and probably never generated by a standard Java compiler, as there is no way to express them in Java source code), they are permitted by the JVM specification.

It is likely that this unusual use of INVOKESPECIAL is an optimization (INVOKESPECIAL was originally used as a more generic INVOKENONVIRTUAL instruction, and non-virtual function calls are cheaper than virtual function calls) or an obfuscation technique.

The RemapTransformer moves static methods containing these INVOKESPECIAL instructions to new classes. This change is still permitted by the JVM specification, which does not place any restrictions on the class referenced by the INVOKESPECIAL instruction.

However, the verifier in modern JVMs is stricter and considers non-<init> INVOKESPECIAL instructions referencing classes that are not the containing class or its direct superclass illegal.

This transformer replaces INVOKESPECIAL with equivalent INVOKEVIRTUAL instructions where possible, allowing the RemapTransformer to produce verifiable output.

Constructors

Link copied to clipboard
constructor()

Properties

Link copied to clipboard

Functions

Link copied to clipboard
open fun transform(classPath: ClassPath)