Invoke Special Transformer
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.