use of org.objectweb.asm.commons.Method in project aries by apache.
the class AbstractWovenProxyAdapter method visitMethod.
/**
* This method is called on each method implemented on this object (but not
* for superclass methods) Each of these methods is visited in turn and the
* code here generates the byte code for the calls to the InovcationListener
* around the existing method
*/
public final MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
LOGGER.debug(Constants.LOG_ENTRY, "visitMethod", new Object[] { access, name, desc, signature, exceptions });
Method currentMethod = new Method(name, desc);
getKnownMethods().add(currentMethod);
MethodVisitor methodVisitorToReturn = null;
// compiler generated ones.
if ((access & (ACC_STATIC | ACC_PRIVATE | ACC_SYNTHETIC | ACC_NATIVE | ACC_BRIDGE)) == 0 && !!!name.equals("<init>") && !!!name.equals("<clinit>")) {
// found a method we should weave
// Create a field name and store it for later
String methodStaticFieldName = "methodField" + getSanitizedUUIDString();
transformedMethods.put(methodStaticFieldName, new TypeMethod(currentMethodDeclaringType, currentMethod));
// Surround the MethodVisitor with our weaver so we can manipulate the code
methodVisitorToReturn = getWeavingMethodVisitor(access, name, desc, signature, exceptions, currentMethod, methodStaticFieldName, currentMethodDeclaringType, currentMethodDeclaringTypeIsInterface);
} else if (name.equals("<clinit>")) {
// there is an existing clinit method, change the fields we use
// to write our init code to static_init_UUID instead
staticInitMethod = new Method("static_init_" + UU_ID, Type.VOID_TYPE, NO_ARGS);
staticInitMethodFlags = staticInitMethodFlags | ACC_FINAL;
methodVisitorToReturn = new AdviceAdapter(Opcodes.ASM9, cv.visitMethod(access, name, desc, signature, exceptions), access, name, desc) {
@Override
protected void onMethodEnter() {
// add into the <clinit> a call to our synthetic static_init_UUID
invokeStatic(typeBeingWoven, staticInitMethod);
super.onMethodEnter();
}
};
} else {
if (currentMethod.getArgumentTypes().length == 0 && name.equals("<init>"))
hasNoArgsConstructor = true;
// This isn't a method we want to weave, so just get the default visitor
methodVisitorToReturn = cv.visitMethod(access, name, desc, signature, exceptions);
}
LOGGER.debug(Constants.LOG_EXIT, "visitMethod", methodVisitorToReturn);
return methodVisitorToReturn;
}
use of org.objectweb.asm.commons.Method in project aries by apache.
the class AbstractWovenProxyAdapter method writeCreateNewProxyInstanceAndConstructor.
/**
* We write createNewProxyInstance separately because it isn't final, and is
* overridden on each class, we also write a constructor for this method to
* use if we don't have one.
*/
private final void writeCreateNewProxyInstanceAndConstructor() {
GeneratorAdapter methodAdapter = getMethodGenerator(ACC_PUBLIC, new Method("org_apache_aries_proxy_weaving_WovenProxy_createNewProxyInstance", WOVEN_PROXY_IFACE_TYPE, DISPATCHER_LISTENER_METHOD_ARGS));
// /////////////////////////////////////////////////////
// Implement the method
// Create and instantiate a new instance, then return it
methodAdapter.newInstance(typeBeingWoven);
methodAdapter.dup();
methodAdapter.loadArgs();
methodAdapter.invokeConstructor(typeBeingWoven, new Method("<init>", Type.VOID_TYPE, DISPATCHER_LISTENER_METHOD_ARGS));
methodAdapter.returnValue();
methodAdapter.endMethod();
// ////////////////////////////////////////////////////////
// Write a protected no-args constructor for this class
methodAdapter = getMethodGenerator(ACC_PROTECTED | ACC_SYNTHETIC, ARGS_CONSTRUCTOR);
if (implementWovenProxy) {
methodAdapter.loadThis();
if (superHasNoArgsConstructor)
methodAdapter.invokeConstructor(superType, NO_ARGS_CONSTRUCTOR);
else {
if (hasNoArgsConstructor)
methodAdapter.invokeConstructor(typeBeingWoven, NO_ARGS_CONSTRUCTOR);
else
throw new RuntimeException(new UnableToProxyException(typeBeingWoven.getClassName(), String.format("The class %s and its superclass %s do not have no-args constructors and cannot be woven.", typeBeingWoven.getClassName(), superType.getClassName())));
}
methodAdapter.loadThis();
methodAdapter.loadArg(0);
methodAdapter.putField(typeBeingWoven, DISPATCHER_FIELD, DISPATCHER_TYPE);
methodAdapter.loadThis();
methodAdapter.loadArg(1);
methodAdapter.putField(typeBeingWoven, LISTENER_FIELD, LISTENER_TYPE);
} else {
// We just invoke the super with args
methodAdapter.loadThis();
methodAdapter.loadArgs();
methodAdapter.invokeConstructor(superType, ARGS_CONSTRUCTOR);
}
// Throw an NPE if the dispatcher is null, return otherwise
methodAdapter.loadArg(0);
Label returnValue = methodAdapter.newLabel();
methodAdapter.ifNonNull(returnValue);
methodAdapter.newInstance(NPE_TYPE);
methodAdapter.dup();
methodAdapter.push("The dispatcher must never be null!");
methodAdapter.invokeConstructor(NPE_TYPE, NPE_CONSTRUCTOR);
methodAdapter.throwException();
methodAdapter.mark(returnValue);
methodAdapter.returnValue();
methodAdapter.endMethod();
// ////////////////////////////////////////////////////////
}
use of org.objectweb.asm.commons.Method in project aries by apache.
the class AbstractWovenProxyAdapter method writeStaticInitMethod.
/**
* Create fields and an initialiser for {@link java.lang.reflect.Method}
* objects in our class
*/
private final void writeStaticInitMethod() {
for (String methodStaticFieldName : transformedMethods.keySet()) {
// add a private static field for the method
cv.visitField(ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, methodStaticFieldName, METHOD_TYPE.getDescriptor(), null, null).visitEnd();
}
GeneratorAdapter staticAdapter = new GeneratorAdapter(staticInitMethodFlags, staticInitMethod, null, null, cv);
for (Entry<String, TypeMethod> entry : transformedMethods.entrySet()) {
// Add some more code to the static initializer
TypeMethod m = entry.getValue();
Type[] targetMethodParameters = m.method.getArgumentTypes();
String methodStaticFieldName = entry.getKey();
Label beginPopulate = staticAdapter.newLabel();
Label endPopulate = staticAdapter.newLabel();
Label catchHandler = staticAdapter.newLabel();
staticAdapter.visitTryCatchBlock(beginPopulate, endPopulate, catchHandler, THROWABLE_INAME);
staticAdapter.mark(beginPopulate);
staticAdapter.push(m.declaringClass);
// push the method name string arg onto the stack
staticAdapter.push(m.method.getName());
// create an array of the method parm class[] arg
staticAdapter.push(targetMethodParameters.length);
staticAdapter.newArray(CLASS_TYPE);
int index = 0;
for (Type t : targetMethodParameters) {
staticAdapter.dup();
staticAdapter.push(index);
staticAdapter.push(t);
staticAdapter.arrayStore(CLASS_TYPE);
index++;
}
// invoke the getMethod
staticAdapter.invokeVirtual(CLASS_TYPE, new Method("getDeclaredMethod", METHOD_TYPE, new Type[] { STRING_TYPE, CLASS_ARRAY_TYPE }));
// store the reflected method in the static field
staticAdapter.putStatic(typeBeingWoven, methodStaticFieldName, METHOD_TYPE);
Label afterCatch = staticAdapter.newLabel();
staticAdapter.mark(endPopulate);
staticAdapter.goTo(afterCatch);
staticAdapter.mark(catchHandler);
// We don't care about the exception, so pop it off
staticAdapter.pop();
// store the reflected method in the static field
staticAdapter.visitInsn(ACONST_NULL);
staticAdapter.putStatic(typeBeingWoven, methodStaticFieldName, METHOD_TYPE);
staticAdapter.mark(afterCatch);
}
staticAdapter.returnValue();
staticAdapter.endMethod();
}
Aggregations