|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object org.objectweb.fractal.julia.asm.MetaCodeGenerator
public abstract class MetaCodeGenerator
A CodeGenerator
to generate interception code that
reifies method calls. This abstract code generator can
be used to easily generate interceptors of the following form, without
knowing the Java bytecode instructions and ASM:
Figure 1: an interceptor and an associated controller object (see also here)
where the interceptor calls a void handleMethodCall (Method m, Object[] args) method on the controller object at each intercepted method. This abstract code generator can be configured in many ways:
getControllerInterfaceName
method.getHandleMethodCallMethodName
method. This method must be defined in the C class. It can also be
declared in the T interface, but this is not mandatory.reifyInterfaceName
method, so that it returns true. The handleMethodCall
method must then have an additional parameter of type String:
Object handleMethodCall (String itf, Method m, Object[] args).reifyTargetObject
method, so that it
returns true. The handleMethodCall method must then have an
additional parameter of type Object: Object handleMethodCall
(Object target, Method m, Object[] args) (if the previous option is also
enabled, the parameters must be placed in the following order: Object
handleMethodCall (String itf, Object target, Method m, Object[] args)).
intercept
method can be overriden to intercept
only some specific methods, while leaving the other unchanged.The code adapters returned by the generateInterceptionCode
method (see CodeGenerator
)
transform the original methods into methods of the following form:
method-signature { return (...)delegate.handleMethodCall( _Mid, new Object[] { ... }); }
The _Mid static fields are initialized by a static initializer whose code is generated by this code generator. This initializer has the following form:
static { _M0 = Class.forName(...).getMethod(... , new Class[] { ... }); _M1 = Class.forName(...).getMethod(... , new Class[] { ... }); ... }
The generateInitCode
method adds a
delegate field to the interceptor class, and adds a code fragment of
the following form to the generated generateInitCode
method (recall that N can be configured with the
getControllerInterfaceName
method):
delegate = (...)ic.getFcInterface(N);Finally this code generator takes into account the Julia optimizations options. So, for example, if the interceptors and controller objects are merged, the delegate field is not generated, and this is used instead. Moreover, if the content, the controller and the interceptor classes are merged, then the interception code that is generated takes the following form:
method-signature { if (!isReflectedCall()) { return (...)handleMethodCall( _Mid, new Object[] { ... }); } else { // original method code } }The first time this method is called the isReflectedCall method (which must be provided by the associated controller object) must return false. The call is therefore reifed and passed to the handleMethodCall method. This method will then call the method back, through the Java Reflection API, and this time the isReflectedCall must return true, so that the original method code is executed. The name of the isReflectedCall method can be configured with the
getIsReflectedCallMethodName
method.
Field Summary |
---|
Fields inherited from interface org.objectweb.fractal.julia.asm.CodeGenerator |
---|
IN, IN_OUT, OUT |
Constructor Summary | |
---|---|
MetaCodeGenerator()
|
Method Summary | |
---|---|
void |
close()
Closes this code generator. |
void |
generateCloneCode(MethodVisitor cv)
Generates the cloning code for this code generator. |
void |
generateInitCode(MethodVisitor cv)
Generates the initialization code for this code generator. |
MethodVisitor |
generateInterceptionCode(Method m,
MethodVisitor cv)
Generates the interception code for the given method. |
static void |
generateMethodInitializerCode(Method m,
String owner,
String field,
ClassVisitor cv,
MethodVisitor mv)
Generates code to initialize a static field containing the Method object. |
static void |
generateParameterReifierCode(Method m,
MethodVisitor cv)
Generates the code to reify the arguments of the given method. |
static void |
generateReturnCode(Method m,
MethodVisitor cv)
Generates the code to unreify the result of the given method. |
protected abstract String |
getControllerInterfaceName()
Returns the name of the interface provided by the controller object to be associated to the interceptor. |
protected abstract String |
getHandleMethodCallMethodName()
Returns the name of the method to be called on the associated controller object, for each intercepted call. |
List |
getImplementedInterfaces()
Returns the list of interfaces to be added to be implemented by the generated interceptor. |
protected abstract String |
getIsReflectedCallMethodName()
Returns the name of the method to be called on the associated controller object to identify reflected calls. |
int |
init(InterceptorClassGenerator icg)
Initializes this code generator. |
void |
initialize(Tree args)
Initializes this object with the given arguments. |
protected boolean |
intercept(Method m)
Returns true if this code generator must generate interception code for the given method. |
protected boolean |
reifyInterfaceName()
Returns true if the target interface name must be passed as argument to the handleMethodCall method. |
protected boolean |
reifyTargetObject()
Returns true if the target object must be passed as argument to the handleMethodCall method. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Constructor Detail |
---|
public MetaCodeGenerator()
Method Detail |
---|
public void initialize(Tree args)
Initializable
initialize
in interface Initializable
args
- the arguments to be used to initialize this object. The format
of these arguments depends on the class of this object.public int init(InterceptorClassGenerator icg)
CodeGenerator
init
in interface CodeGenerator
icg
- the interceptor class generator to which this code generator
belongs.
IN
,
OUT
or IN_OUT
.public void generateInitCode(MethodVisitor cv) throws ClassGenerationException
CodeGenerator
initFcController
method by the interceptor class generator that calls this
method. By hypothesis, the stack is empty at the beginning of the generated
code. Moreover, the stack must also be empty at the end of the code
generated by this method.
generateInitCode
in interface CodeGenerator
cv
- the method visitor to be used to generate the initialization
code.
ClassGenerationException
- if a problem occurs.public MethodVisitor generateInterceptionCode(Method m, MethodVisitor cv)
CodeGenerator
generateInterceptionCode
in interface CodeGenerator
m
- the method for which the interception code must be generated.cv
- the method visitor to be used to generate the interception code.
CodeAdapter
, that should add the
interception code to the visited code on the fly. See CodeGenerator
.public void generateCloneCode(MethodVisitor cv)
CodeGenerator
clone
method by the interceptor class generator that calls this method. By
hypothesis, the stack is empty at the beginning of the generated code.
Moreover, the stack must also be empty at the end of the code generated by
this method.
generateCloneCode
in interface CodeGenerator
cv
- the method visitor to be used to generate the cloning code.public void close()
CodeGenerator
close
in interface CodeGenerator
protected abstract String getControllerInterfaceName()
protected boolean intercept(Method m)
m
- a method object.
protected abstract String getHandleMethodCallMethodName()
protected boolean reifyInterfaceName()
protected boolean reifyTargetObject()
protected abstract String getIsReflectedCallMethodName()
public static void generateMethodInitializerCode(Method m, String owner, String field, ClassVisitor cv, MethodVisitor mv)
m
- the static field's value.owner
- the internal name of the owner class of the static field.field
- the static field's name.cv
- the class visitor to be used to generate the static field.mv
- the code visitor to be used to generate the static field's
initialization code.public static void generateParameterReifierCode(Method m, MethodVisitor cv)
m
- a method object.cv
- the code visitor to be used to generate the bytecode.public static void generateReturnCode(Method m, MethodVisitor cv)
m
- a method object.cv
- the code visitor to be used to generate the bytecode.public List getImplementedInterfaces() throws ClassGenerationException
This method provides an empty implementation, returning an empty List.
Subclasses which need to add interfaces to be implemented by the generated interceptor should override this method.
getImplementedInterfaces
in interface CodeGenerator
ClassGenerationException
- if a problem occurs.CodeGenerator.getImplementedInterfaces()
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |