Reads annotation inner data.
Invocation replacer class adapter.
Invocation replacer method adapter.
Resolves method signature and holds all information.
Various ASM utilities used by
Proxetta class builder.
Destination ctor builder
Reads info from target class.
Holds various information about the current process of making proxy.
This package assembles proxy classes. You will probably like to keep out from this code:)
During creation of proxy methods, several replacement and modification happens in order to produce valid proxy subclass. Here is the list of all such rules.
Proxy subclass must contain all constructors as target subclass. New constructors simply delegates invocation to the super class. All constructor annotations are copied.
Last method in proxy chain is the one that simply delegates the invocation to the target method in super class.
Proxy subclass must contain all type annotations as the target one.
Proxy methods must contain all type annotations as the target one.
Offset of all local variables has to be incremented by the size of target method argument list.
Size of arguments list is the number of 32bit words used by arguments on stack, which means that
all types has length of 1 word, except
Double that weight 2 words
(or one dword).
Here is the order of local variables:
Therefore, index 0 is left as it is and offset will not be added to it.
ProxyTarget.argsCount() has to be replaces with hardcoded arguments count.
Method call is simply replaces with appropriate load instruction:
iload_n where n is in [0. 5];
bipush n where n is in byte range; or
sipush n when n is in integer range.
ProxyTarget.getArgType(int ) has to be replaces with hardcoded argument Class, where argument
index is provided as an argument for
Method call is replaced with
getClass() call on specified argument. If argument is an primitive
then method is replaced with reading the
TYPE attribute of appropriate wrapper.
One caveat: opcode for pushing argument offset to stack is not removed from the bytecode, due to performance issues of class creation. Instead, this value is poped from the stack before method call is replaced. It is assumed that this value is an integer.
ProxyTarget.getArg(int ) has to be replaces with hardcoded argument value, where
index is provided as an argument for
If argument is a primitive, its wrapper object will be created.
ProxyTarget.setArg(Object, int ) has to be replaces with hardcoded setting of the argument value,
where index is provided as an argument for
ProxyTarget.setArg(Object, int ).
If argument is a primitive, its wrapper object must be provided.
ProxyTarget.createArgsArray() has to be replaces with hardcoded creation of an object array,
where elements are target method arguments. Primitive arguments are wrapped.
ProxyTarget.invokeAndGetResult() has to be replaced with call to super target method. Since target methods
may have one or more arguments, it is required to push all arguments to the stack prior to call of super target method.
aload_0 is always the first instruction (load
this), no matter how many arguments there are.
Situation here is a bit more complicated since return value must be provided, so the following fixes has to be applied, too.
ProxyTarget.invoke() is invoked without assignment,
is added afterwards, to remove the value from the stack. For targets that do not return void, this opcode
has to be fixed, i.e. removed. (Fact is that targets that return void, do not have POP:).
ProxyTarget.invoke() is invoked with assignment,
is added afterwards, to assign return value to a local variable. Therefore, it has to be loaded again on stack
Creates all return values, performs casting for small types.
Returns the target class.
Returns target method name.
Returns return type of the target method or
null if metod returns void.
Access to advice's fields has to be replaced with access to local fields. In relation with [A5].
All fields from advice has to be copied to proxy, with proxy index added to the name, to prevent duplicate names.
Static block of an advice should be copied to the proxy, with fixed field access (see F5).
Advice's constructor will be copied to regular methods, except first two instructions (calling super constructor) will be ignored. Field access will be fixed (see F5).
Copyright © 2003-present Jodd Team