List of usage examples for org.objectweb.asm.commons Method Method
public Method(final String name, final Type returnType, final Type[] argumentTypes)
From source file:net.wpm.codegen.ExpressionCallStaticSelf.java
License:Apache License
@Override public Type load(Context ctx) { GeneratorAdapter g = ctx.getGeneratorAdapter(); Type ownerType = owner.type(ctx); List<Type> argumentTypes = new ArrayList<Type>(); for (Expression argument : arguments) { argument.load(ctx);//from w w w . j a v a2 s. c om argumentTypes.add(argument.type(ctx)); } Type returnType = type(ctx); g.invokeStatic(ownerType, new Method(methodName, returnType, argumentTypes.toArray(new Type[] {}))); return returnType; }
From source file:org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.java
License:Apache License
/** * Write the methods we need for wovenProxies on the highest supertype *///from www . ja v a 2 s . com private final void writeFinalWovenProxyMethods() { // add private fields for the Callable<Object> dispatcher // and InvocationListener. These aren't static because we can have // multiple instances of the same proxy class. These should not be // serialized, or used in JPA or any other thing we can think of, // so we annotate them as necessary generateField(DISPATCHER_FIELD, Type.getDescriptor(Callable.class)); generateField(LISTENER_FIELD, Type.getDescriptor(InvocationListener.class)); // a general methodAdapter field that we will use to with GeneratorAdapters // to create the methods required to implement WovenProxy GeneratorAdapter methodAdapter; // add a method for unwrapping the dispatcher methodAdapter = getMethodGenerator(PUBLIC_GENERATED_METHOD_ACCESS, new Method("org_apache_aries_proxy_weaving_WovenProxy_unwrap", DISPATCHER_TYPE, NO_ARGS)); // ///////////////////////////////////////////////////// // Implement the method // load this to get the field methodAdapter.loadThis(); // get the dispatcher field and return methodAdapter.getField(typeBeingWoven, DISPATCHER_FIELD, DISPATCHER_TYPE); methodAdapter.returnValue(); methodAdapter.endMethod(); // ///////////////////////////////////////////////////// // add a method for checking if the dispatcher is set methodAdapter = getMethodGenerator(PUBLIC_GENERATED_METHOD_ACCESS, new Method( "org_apache_aries_proxy_weaving_WovenProxy_isProxyInstance", Type.BOOLEAN_TYPE, NO_ARGS)); // ///////////////////////////////////////////////////// // Implement the method // load this to get the field methodAdapter.loadThis(); // make a label for return true Label returnTrueLabel = methodAdapter.newLabel(); // get the dispatcher field for the stack methodAdapter.getField(typeBeingWoven, DISPATCHER_FIELD, DISPATCHER_TYPE); // check if the dispatcher was non-null and goto return true if it was methodAdapter.ifNonNull(returnTrueLabel); methodAdapter.loadThis(); // get the listener field for the stack methodAdapter.getField(typeBeingWoven, LISTENER_FIELD, LISTENER_TYPE); // check if the listener field was non-null and goto return true if it was methodAdapter.ifNonNull(returnTrueLabel); // return false if we haven't jumped anywhere methodAdapter.push(false); methodAdapter.returnValue(); // mark the returnTrueLable methodAdapter.mark(returnTrueLabel); methodAdapter.push(true); methodAdapter.returnValue(); // end the method methodAdapter.endMethod(); // /////////////////////////////////////////////////////// }
From source file:org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.java
License:Apache License
/** * 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.//from w w w. j av a 2 s.c om */ 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); // ///////////////////////////////////////////////////// // Implement the constructor // For the top level supertype we need to invoke a no-args super, on object //if we have to 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(), NLS.MESSAGES.getMessage("type.lacking.no.arg.constructor", 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(); ////////////////////////////////////////////////////////// }
From source file:org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.java
License:Apache License
/** * Create fields and an initialiser for {@link java.lang.reflect.Method} * objects in our class/* w ww. j ava 2s . c o m*/ */ private final void writeStaticInitMethod() { // we create a static field for each method we encounter with a *unique* // random name // since each method needs to be stored individually for (String methodStaticFieldName : transformedMethods.keySet()) { // add a private static field for the method cv.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL | 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(); }
From source file:org.apache.aries.proxy.impl.common.AbstractWovenProxyMethodAdapter.java
License:Apache License
/** * Write out the bytecode instructions necessary to do the dispatch. * We know the dispatcher is non-null, and we need a try/catch around the * invocation and listener calls./* w w w . j a va 2 s .c o m*/ */ protected final void writeDispatcher() { // Setup locals we will use in the dispatch setupLocals(); //Write the try catch block visitTryCatchBlock(beginTry, endTry, endTry, THROWABLE_INAME); mark(beginTry); //Start dispatching, get the target object and store it loadThis(); getField(typeBeingWoven, DISPATCHER_FIELD, DISPATCHER_TYPE); invokeInterface(DISPATCHER_TYPE, new Method("call", OBJECT_TYPE, NO_ARGS)); storeLocal(dispatchTarget); //Pre-invoke, invoke, post-invoke, return writePreInvoke(); //Start the real method push(true); storeLocal(inNormalMethod); //Dispatch the method and store the result (null for void) loadLocal(dispatchTarget); checkCast(methodDeclaringType); loadArgs(); if (isMethodDeclaringTypeInterface && !isDefaultMethod) { invokeInterface(methodDeclaringType, currentTransformMethod); } else { invokeVirtual(methodDeclaringType, currentTransformMethod); } if (isVoid) { visitInsn(ACONST_NULL); } storeLocal(normalResult); // finish the real method and post-invoke push(false); storeLocal(inNormalMethod); writePostInvoke(); //Return, with the return value if necessary if (!!!isVoid) { loadLocal(normalResult); } returnValue(); //End of our try, start of our catch mark(endTry); writeMethodCatchHandler(); }
From source file:org.apache.aries.proxy.impl.common.AbstractWovenProxyMethodAdapter.java
License:Apache License
/** * This method unwraps woven proxy instances for use in the right-hand side * of equals methods/*from w w w .j a v a 2s . co m*/ */ protected final void unwrapEqualsArgument() { //Create and initialize a local for our work int unwrapLocal = newLocal(OBJECT_TYPE); visitInsn(ACONST_NULL); storeLocal(unwrapLocal); Label startUnwrap = newLabel(); mark(startUnwrap); //Load arg and check if it is a WovenProxy instances loadArg(0); instanceOf(WOVEN_PROXY_IFACE_TYPE); Label unwrapFinished = newLabel(); //Jump if zero (false) visitJumpInsn(Opcodes.IFEQ, unwrapFinished); //Arg is a wovenProxy, if it is the same as last time then we're done loadLocal(unwrapLocal); loadArg(0); ifCmp(OBJECT_TYPE, EQ, unwrapFinished); //Not the same, store current arg in unwrapLocal for next loop loadArg(0); storeLocal(unwrapLocal); //So arg is a WovenProxy, but not the same as last time, cast it and store //the result of unwrap.call in the arg loadArg(0); checkCast(WOVEN_PROXY_IFACE_TYPE); //Now unwrap invokeInterface(WOVEN_PROXY_IFACE_TYPE, new Method("org_apache_aries_proxy_weaving_WovenProxy_unwrap", DISPATCHER_TYPE, NO_ARGS)); //Now we may have a Callable to invoke int callable = newLocal(DISPATCHER_TYPE); storeLocal(callable); loadLocal(callable); ifNull(unwrapFinished); loadLocal(callable); invokeInterface(DISPATCHER_TYPE, new Method("call", OBJECT_TYPE, NO_ARGS)); //Store the result and we're done (for this iteration) storeArg(0); goTo(startUnwrap); mark(unwrapFinished); }
From source file:org.apache.aries.proxy.impl.common.AbstractWovenProxyMethodAdapter.java
License:Apache License
/** * A utility method for getting an ASM method from a Class * @param clazz the class to search/* ww w . j a v a 2 s .c om*/ * @param name The method name * @param argTypes The method args * @return */ private static final Method getAsmMethodFromClass(Class<?> clazz, String name, Class<?>... argTypes) { //get the java.lang.reflect.Method to get the types java.lang.reflect.Method ilMethod = null; try { ilMethod = clazz.getMethod(name, argTypes); } catch (Exception e) { //Should be impossible! throw new RuntimeException(NLS.MESSAGES.getMessage("error.finding.invocation.listener.method", name, Arrays.toString(argTypes)), e); } //get the ASM method return new Method(name, Type.getReturnType(ilMethod), Type.getArgumentTypes(ilMethod)); }
From source file:org.apache.aries.proxy.impl.gen.ProxySubclassAdapter.java
License:Apache License
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {/*from w w w . java2 s . com*/ LOGGER.debug(Constants.LOG_ENTRY, "visit", new Object[] { version, access, name, signature, superName, interfaces }); // store the superclass binary name this.superclassBinaryName = name.replaceAll("/", "\\."); try { this.superclassClass = Class.forName(superclassBinaryName, false, loader); } catch (ClassNotFoundException cnfe) { throw new TypeNotPresentException(superclassBinaryName, cnfe); } // keep the same access and signature as the superclass (unless it's abstract) // remove all the superclass interfaces because they will be inherited // from the superclass anyway if ((access & ACC_ABSTRACT) != 0) { //If the super was abstract the subclass should not be! access &= ~ACC_ABSTRACT; } cv.visit(ProxyUtils.getWeavingJavaVersion(), access, newClassName, signature, name, null); // add a private field for the invocation handler // this isn't static in case we have multiple instances of the same // proxy cv.visitField(ACC_PRIVATE, IH_FIELD, Type.getDescriptor(InvocationHandler.class), null, null); // create a static adapter for generating a static initialiser method in // the generated subclass staticAdapter = new GeneratorAdapter(ACC_STATIC, new Method("<clinit>", Type.VOID_TYPE, NO_ARGS), null, null, cv); // add a zero args constructor method Method m = new Method("<init>", Type.VOID_TYPE, NO_ARGS); GeneratorAdapter methodAdapter = new GeneratorAdapter(ACC_PUBLIC, m, null, null, cv); // loadthis methodAdapter.loadThis(); // List the constructors in the superclass. Constructor<?>[] constructors = superclassClass.getDeclaredConstructors(); // Check that we've got at least one constructor, and get the 1st one in the list. if (constructors.length > 0) { // We now need to construct the proxy class as though it is going to invoke the superclasses constructor. // We do this because we can no longer call the java.lang.Object() zero arg constructor as the JVM now throws a VerifyError. // So what we do is build up the calling of the superclasses constructor using nulls and default values. This means that the // class bytes can be verified by the JVM, and then in the ProxySubclassGenerator, we load the class without invoking the // constructor. Method constructor = Method.getMethod(constructors[0]); Type[] argTypes = constructor.getArgumentTypes(); if (argTypes.length == 0) { methodAdapter.invokeConstructor(Type.getType(superclassClass), new Method("<init>", Type.VOID_TYPE, NO_ARGS)); } else { for (Type type : argTypes) { switch (type.getSort()) { case Type.ARRAY: // We need to process any array or multidimentional arrays. String elementDesc = type.getElementType().getDescriptor(); String typeDesc = type.getDescriptor(); // Iterate over the number of arrays and load 0 for each one. Keep a count of the number of // arrays as we will need to run different code fo multi dimentional arrays. int index = 0; while (!elementDesc.equals(typeDesc)) { typeDesc = typeDesc.substring(1); methodAdapter.visitInsn(Opcodes.ICONST_0); index++; } // If we're just a single array, then call the newArray method, otherwise use the MultiANewArray instruction. if (index == 1) { methodAdapter.newArray(type.getElementType()); } else { methodAdapter.visitMultiANewArrayInsn(type.getDescriptor(), index); } break; case Type.BOOLEAN: methodAdapter.push(true); break; case Type.BYTE: methodAdapter.push(Type.VOID_TYPE); break; case Type.CHAR: methodAdapter.push(Type.VOID_TYPE); break; case Type.DOUBLE: methodAdapter.push(0.0); break; case Type.FLOAT: methodAdapter.push(0.0f); break; case Type.INT: methodAdapter.push(0); break; case Type.LONG: methodAdapter.push(0l); break; case Type.SHORT: methodAdapter.push(0); break; default: case Type.OBJECT: methodAdapter.visitInsn(Opcodes.ACONST_NULL); break; } } methodAdapter.invokeConstructor(Type.getType(superclassClass), new Method("<init>", Type.VOID_TYPE, argTypes)); } } methodAdapter.returnValue(); methodAdapter.endMethod(); // add a method for getting the invocation handler Method setter = new Method("setInvocationHandler", Type.VOID_TYPE, new Type[] { IH_TYPE }); m = new Method("getInvocationHandler", IH_TYPE, NO_ARGS); methodAdapter = new GeneratorAdapter(ACC_PUBLIC | ACC_FINAL, m, null, null, cv); // load this to get the field methodAdapter.loadThis(); // get the ih field and return methodAdapter.getField(newClassType, IH_FIELD, IH_TYPE); methodAdapter.returnValue(); methodAdapter.endMethod(); // add a method for setting the invocation handler methodAdapter = new GeneratorAdapter(ACC_PUBLIC | ACC_FINAL, setter, null, null, cv); // load this to put the field methodAdapter.loadThis(); // load the method arguments (i.e. the invocation handler) to the stack methodAdapter.loadArgs(); // set the ih field using the method argument methodAdapter.putField(newClassType, IH_FIELD, IH_TYPE); methodAdapter.returnValue(); methodAdapter.endMethod(); // loop through the class hierarchy to get any needed methods off the // supertypes // start by finding the methods declared on the class of interest (the // superclass of our dynamic subclass) java.lang.reflect.Method[] observedMethods = superclassClass.getDeclaredMethods(); // add the methods to a set of observedMethods ProxySubclassMethodHashSet<String> setOfObservedMethods = new ProxySubclassMethodHashSet<String>( observedMethods.length); setOfObservedMethods.addMethodArray(observedMethods); // get the next superclass in the hierarchy Class<?> nextSuperClass = superclassClass.getSuperclass(); while (nextSuperClass != null) { // set the fields for the current class setCurrentAnalysisClassFields(nextSuperClass); // add a static field and static initializer code to the generated // subclass // for each of the superclasses in the hierarchy addClassStaticField(currentlyAnalysedClassName); LOGGER.debug("Class currently being analysed: {} {}", currentlyAnalysedClassName, currentlyAnalysedClass); // now find the methods declared on the current class and add them // to a set of foundMethods java.lang.reflect.Method[] foundMethods = currentlyAnalysedClass.getDeclaredMethods(); ProxySubclassMethodHashSet<String> setOfFoundMethods = new ProxySubclassMethodHashSet<String>( foundMethods.length); setOfFoundMethods.addMethodArray(foundMethods); // remove from the set of foundMethods any methods we saw on a // subclass // because we want to use the lowest level declaration of a method setOfFoundMethods.removeAll(setOfObservedMethods); try { // read the current class and use a // ProxySubclassHierarchyAdapter // to process only methods on that class that are in the list ClassLoader loader = currentlyAnalysedClass.getClassLoader(); if (loader == null) { loader = this.loader; } ClassReader cr = new ClassReader(loader .getResourceAsStream(currentlyAnalysedClass.getName().replaceAll("\\.", "/") + ".class")); ClassVisitor hierarchyAdapter = new ProxySubclassHierarchyAdapter(this, setOfFoundMethods); cr.accept(hierarchyAdapter, ClassReader.SKIP_DEBUG); } catch (IOException e) { throw new TypeNotPresentException(currentlyAnalysedClassName, e); } // now add the foundMethods to the overall list of observed methods setOfObservedMethods.addAll(setOfFoundMethods); // get the next class up in the hierarchy and go again nextSuperClass = currentlyAnalysedClass.getSuperclass(); } // we've finished looking at the superclass hierarchy // set the fields for the immediate superclass of our dynamic subclass setCurrentAnalysisClassFields(superclassClass); // add the class static field addClassStaticField(currentlyAnalysedClassName); // we do the lowest class last because we are already visiting the class // when in this adapter code // now we are ready to visit all the methods on the lowest class // which will happen by the ASM ClassVisitor implemented in this adapter LOGGER.debug(Constants.LOG_EXIT, "visit"); }
From source file:org.apache.aries.proxy.impl.gen.ProxySubclassAdapter.java
License:Apache License
private void addClassStaticField(String classBinaryName) { LOGGER.debug(Constants.LOG_ENTRY, "addClassStaticField", new Object[] { classBinaryName }); currentClassFieldName = classBinaryName.replaceAll("\\.", "_"); /*/* w w w . jav a2 s. co m*/ * use Class.forName on the superclass so we can reflectively find * methods later * * produces bytecode for retrieving the superclass and storing in a * private static field: private static Class superClass = null; static{ * superClass = Class.forName(superclass, true, TYPE_BEING_PROXIED.class.getClassLoader()); } */ // add a private static field for the superclass Class cv.visitField(ACC_PRIVATE | ACC_STATIC, currentClassFieldName, CLASS_TYPE.getDescriptor(), null, null); // push the String arg for the Class.forName onto the stack staticAdapter.push(classBinaryName); //push the boolean arg for the Class.forName onto the stack staticAdapter.push(true); //get the classloader staticAdapter.push(newClassType); staticAdapter.invokeVirtual(CLASS_TYPE, new Method("getClassLoader", CLASSLOADER_TYPE, NO_ARGS)); // invoke the Class forName putting the Class on the stack staticAdapter.invokeStatic(CLASS_TYPE, new Method("forName", CLASS_TYPE, new Type[] { STRING_TYPE, Type.BOOLEAN_TYPE, CLASSLOADER_TYPE })); // put the Class in the static field staticAdapter.putStatic(newClassType, currentClassFieldName, CLASS_TYPE); LOGGER.debug(Constants.LOG_ENTRY, "addClassStaticField"); }
From source file:org.apache.aries.spifly.weaver.TCCLSetterVisitor.java
License:Apache License
@Override public void visitEnd() { if (!woven) { // if this class wasn't woven, then don't add the synthesized method either. super.visitEnd(); return;//from w w w . j a v a 2 s . c o m } // Add generated static method Set<String> methodNames = new HashSet<String>(); for (WeavingData wd : weavingData) { /* Equivalent to: * private static void $$FCCL$$<className>$<methodName>(Class<?> cls) { * Util.fixContextClassLoader("java.util.ServiceLoader", "load", cls, WovenClass.class.getClassLoader()); * } */ String methodName = getGeneratedMethodName(wd); if (methodNames.contains(methodName)) continue; methodNames.add(methodName); Method method = new Method(methodName, Type.VOID_TYPE, new Type[] { CLASS_TYPE }); GeneratorAdapter mv = new GeneratorAdapter( cv.visitMethod(ACC_PRIVATE + ACC_STATIC, methodName, method.getDescriptor(), null, null), ACC_PRIVATE + ACC_STATIC, methodName, method.getDescriptor()); //Load the strings, method parameter and target mv.visitLdcInsn(wd.getClassName()); mv.visitLdcInsn(wd.getMethodName()); mv.loadArg(0); mv.visitLdcInsn(targetClass); //Change the class on the stack into a classloader mv.invokeVirtual(CLASS_TYPE, new Method("getClassLoader", CLASSLOADER_TYPE, new Type[0])); //Call our util method mv.invokeStatic(UTIL_CLASS, new Method("fixContextClassloader", Type.VOID_TYPE, new Type[] { String_TYPE, String_TYPE, CLASS_TYPE, CLASSLOADER_TYPE })); mv.returnValue(); mv.endMethod(); } super.visitEnd(); }