Example usage for org.objectweb.asm.commons GeneratorAdapter loadArgs

List of usage examples for org.objectweb.asm.commons GeneratorAdapter loadArgs

Introduction

In this page you can find the example usage for org.objectweb.asm.commons GeneratorAdapter loadArgs.

Prototype

public void loadArgs() 

Source Link

Document

Generates the instructions to load all the method arguments on the stack.

Usage

From source file:co.cask.cdap.internal.io.FieldAccessorGenerator.java

License:Apache License

/**
 * Generates the try-catch block that wrap around the given reflection method call.
 * @param method The method to be called within the try-catch block.
 *///w w  w .  j  a  va2 s .com
private void invokeReflection(Method method, String signature) {
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, method, signature, new Type[0], classWriter);
    /**
     * try {
     *   // Call method
     * } catch (IllegalAccessException e) {
     *   throw Throwables.propagate(e);
     * }
     */
    Label beginTry = mg.newLabel();
    Label endTry = mg.newLabel();
    Label catchHandle = mg.newLabel();
    mg.visitTryCatchBlock(beginTry, endTry, catchHandle, Type.getInternalName(IllegalAccessException.class));
    mg.mark(beginTry);
    mg.loadThis();
    mg.getField(Type.getObjectType(className), "field", Type.getType(Field.class));
    mg.loadArgs();
    mg.invokeVirtual(Type.getType(Field.class), method);
    mg.mark(endTry);
    mg.returnValue();
    mg.mark(catchHandle);
    int exception = mg.newLocal(Type.getType(IllegalAccessException.class));
    mg.storeLocal(exception);
    mg.loadLocal(exception);
    mg.invokeStatic(Type.getType(Throwables.class),
            getMethod(RuntimeException.class, "propagate", Throwable.class));
    mg.throwException();
    mg.endMethod();

}

From source file:co.cask.cdap.internal.io.FieldAccessorGenerator.java

License:Apache License

/**
 * Generates the primitive setter (setXXX) based on the field type.
 * @param field The reflection field object.
 *///from   www.j  av  a  2s  .c om
private void primitiveSetter(Field field) {
    String typeName = field.getType().getName();
    String methodName = String.format("set%c%s", Character.toUpperCase(typeName.charAt(0)),
            typeName.substring(1));

    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC,
            getMethod(void.class, methodName, Object.class, field.getType()), null, new Type[0], classWriter);
    if (isPrivate) {
        // set the value using the generic void get(Object, Object) method with boxing the value.
        mg.loadThis();
        mg.loadArgs();
        mg.valueOf(Type.getType(field.getType()));
        mg.invokeVirtual(Type.getObjectType(className),
                getMethod(void.class, "set", Object.class, Object.class));
    } else {
        // Simply access the field.
        mg.loadArg(0);
        mg.checkCast(Type.getType(field.getDeclaringClass()));
        mg.loadArg(1);
        mg.putField(Type.getType(field.getDeclaringClass()), field.getName(), Type.getType(field.getType()));
    }
    mg.returnValue();
    mg.endMethod();

}

From source file:com.changingbits.Builder.java

License:Apache License

/** Build a {@link LongRangeMultiSet} implementation to
 *  lookup intervals for a given point./* www .j a v a 2s  .co  m*/
 *
 *  @param useAsm If true, the tree will be compiled to
 *  java bytecodes using the {@code asm} library; typically
 *  this results in a faster (~3X) implementation. */
public LongRangeMultiSet getMultiSet(boolean useAsm, boolean useArrayImpl) {

    finish(useArrayImpl);

    if (useAsm) {
        StringBuilder sb = new StringBuilder();
        sb.append('\n');
        int count = 0;
        for (LongRange range : ranges) {
            sb.append("// range ");
            sb.append(count++);
            sb.append(": ");
            sb.append(range);
            sb.append('\n');
        }
        sb.append('\n');
        sb.append("int upto = 0;\n");
        buildJavaSource(root, 0, sb);
        String javaSource = sb.toString();
        //System.out.println("java: " + javaSource);

        ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
        classWriter.visit(Opcodes.V1_7,
                Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC,
                COMPILED_TREE_CLASS.replace('.', '/'), null, LONG_RANGE_MULTI_SET_TYPE.getInternalName(), null);
        classWriter.visitSource(javaSource, null);

        Method m = Method.getMethod("void <init> ()");
        GeneratorAdapter constructor = new GeneratorAdapter(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, m, null,
                null, classWriter);
        constructor.loadThis();
        constructor.loadArgs();
        constructor.invokeConstructor(LONG_RANGE_MULTI_SET_TYPE, m);
        constructor.returnValue();
        constructor.endMethod();

        GeneratorAdapter gen = new GeneratorAdapter(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, LOOKUP_METHOD,
                null, null, classWriter);
        //Label labelTop = new Label();
        //Label labelEnd = new Label();
        //gen.visitLabel(labelTop);
        int uptoLocal = gen.newLocal(Type.INT_TYPE);
        //System.out.println("uptoLocal=" + uptoLocal);
        // nocommit is this not needed!?
        //gen.visitLocalVariable("upto", "I", null, labelTop, labelEnd, uptoLocal);
        gen.push(0);
        gen.storeLocal(uptoLocal, Type.INT_TYPE);
        buildAsm(gen, root, uptoLocal);
        // Return upto:
        gen.loadLocal(uptoLocal, Type.INT_TYPE);
        gen.returnValue();
        //gen.visitLabel(labelEnd);
        gen.endMethod();
        classWriter.visitEnd();

        byte[] bytes = classWriter.toByteArray();

        // javap -c /x/tmp/my.class
        /*
        try {
          FileOutputStream fos = new FileOutputStream(new File("/x/tmp/my.class"));
          fos.write(bytes);
          fos.close();
        } catch (Exception e) {
          throw new RuntimeException(e);
        }
        */

        // nocommit allow changing the class loader
        Class<? extends LongRangeMultiSet> treeClass = new Loader(LongRangeMultiSet.class.getClassLoader())
                .define(COMPILED_TREE_CLASS, classWriter.toByteArray());
        try {
            return treeClass.getConstructor().newInstance();
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException
                | InvocationTargetException e) {
            throw new RuntimeException(e);
        }

    } else if (useArrayImpl) {
        return new ArrayLongRangeMultiSet(root);
    } else {
        return new SimpleLongRangeMultiSet(root);
    }
}

From source file:com.changingbits.Builder.java

License:Apache License

public LongRangeCounter getCounter(boolean useAsm) {
    finish(false);/*from   w  w w .  j  av  a 2 s  .  c  om*/
    if (useAsm) {
        StringBuilder sb = new StringBuilder();
        sb.append('\n');
        int count = 0;
        for (LongRange range : ranges) {
            sb.append("// range ");
            sb.append(count++);
            sb.append(": ");
            sb.append(range);
            sb.append('\n');
        }
        sb.append('\n');
        buildJavaCounterSource(root, 0, sb, false);
        String javaSource = sb.toString();
        //System.out.println("javaSource:\n" + javaSource);

        ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
        classWriter.visit(Opcodes.V1_7,
                Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC,
                COMPILED_COUNTER_CLASS.replace('.', '/'), null, BASE_LONG_RANGE_COUNTER_TYPE.getInternalName(),
                null);
        classWriter.visitSource(javaSource, null);
        Method m = Method.getMethod("void <init> (com.changingbits.Node, int, int)");
        GeneratorAdapter constructor = new GeneratorAdapter(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, m, null,
                null, classWriter);
        constructor.loadThis();
        constructor.loadArgs();
        constructor.invokeConstructor(Type.getType(BaseLongRangeCounter.class), m);
        constructor.returnValue();
        constructor.endMethod();

        GeneratorAdapter gen = new GeneratorAdapter(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, ADD_METHOD,
                null, null, classWriter);
        buildCounterAsm(gen, root, false);
        gen.returnValue();
        gen.endMethod();
        classWriter.visitEnd();

        byte[] bytes = classWriter.toByteArray();

        // javap -c /x/tmp/my.class
        /*
        try {
          FileOutputStream fos = new FileOutputStream(new File("/x/tmp/counter.class"));
          fos.write(bytes);
          fos.close();
        } catch (Exception e) {
          throw new RuntimeException(e);
        }
        */

        // nocommit allow changing the class loader
        Class<? extends LongRangeCounter> cl = new CounterLoader(LongRangeCounter.class.getClassLoader())
                .define(COMPILED_COUNTER_CLASS, classWriter.toByteArray());
        try {
            return cl.getConstructor(Node.class, int.class, int.class).newInstance(root,
                    elementaryIntervals.size(), ranges.length);
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException
                | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    } else {
        return new SimpleLongRangeCounter(root, elementaryIntervals, ranges.length);
    }
}

From source file:com.chiralbehaviors.janus.CompositeClassGenerator.java

License:Open Source License

protected void visitMethod(Type mixIn, String fieldName, int access, String name, String desc, String signature,
        String[] exceptions) {//from  ww  w .ja  va 2  s.c  om
    Type[] exceptionTypes;
    if (exceptions != null) {
        exceptionTypes = new Type[exceptions.length];
        int i = 0;
        for (String exception : exceptions) {
            exceptionTypes[i++] = Type.getObjectType(exception);
        }
    } else {
        exceptionTypes = new Type[0];
    }
    access = access ^ ACC_ABSTRACT;
    Method method = new Method(name, desc);
    GeneratorAdapter gen = new GeneratorAdapter(access, method, null, exceptionTypes, writer);
    gen.visitCode();
    gen.loadThis();
    gen.getField(generatedType, fieldName, mixIn);
    gen.loadArgs();
    gen.invokeInterface(mixIn, method);
    gen.returnValue();
    gen.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.//  w w  w.j  av  a  2 s  .c  o m
 */
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.gen.ProxySubclassAdapter.java

License:Apache License

public void visit(int version, int access, String name, String signature, String superName,
        String[] interfaces) {//ww w. j  a  va  2 s . c  o  m
    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.commons.weaver.privilizer.ActionGenerator.java

License:Apache License

/**
 * We must add special methods for inner classes to invoke their owners' methods, according to the scheme "access$n"
 * where n is the index into this (ordered) map. Additionally we will prefix the whole thing like we usually do
 * (__privileged_)://from w w w .j a v  a2 s  .com
 */
private void generateHelper() {
    owner.privilizer().env.debug("Generating static helper method %s.%s to call %s",
            owner.target.getClassName(), helper, impl);
    final GeneratorAdapter mgen = new GeneratorAdapter(Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC, helper, null,
            exceptions, owner);

    mgen.visitCode();
    mgen.loadArgs();
    if (implIsStatic) {
        mgen.invokeStatic(owner.target, impl);
    } else {
        mgen.invokeVirtual(owner.target, impl);
    }
    mgen.returnValue();
    mgen.endMethod();
}

From source file:org.apache.deltaspike.partialbean.impl.proxy.AsmProxyClassGenerator.java

License:Apache License

private static void defineMethod(ClassWriter cw, java.lang.reflect.Method method, Type proxyType,
        Type invocationHandlerType, Type superType, boolean callInvocationHandler) {
    Type methodType = Type.getType(method);
    Type[] exceptionTypes = getTypes(method.getExceptionTypes());

    // push the method definition
    int modifiers = (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED) & method.getModifiers();
    Method asmMethod = Method.getMethod(method);
    GeneratorAdapter mg = new GeneratorAdapter(modifiers, asmMethod, null, exceptionTypes, cw);

    // copy annotations
    for (Annotation annotation : method.getDeclaredAnnotations()) {
        mg.visitAnnotation(Type.getDescriptor(annotation.annotationType()), true).visitEnd();
    }/*from   w ww. j a v  a  2 s.  com*/

    mg.visitCode();

    Label tryBlockStart = mg.mark();

    mg.loadThis();
    loadCurrentMethod(mg, method, methodType);
    loadArguments(mg, method, methodType);

    // invoke our ProxyInvocationHandler
    mg.invokeStatic(Type.getType(ManualInvocationHandler.class),
            Method.getMethod("Object staticInvoke(Object, java.lang.reflect.Method, Object[])"));

    // cast the result
    mg.unbox(methodType.getReturnType());

    Label tryBlockEnd = mg.mark();

    // push return
    mg.returnValue();

    boolean throwableCatched = false;

    // catch ProceedOriginalRuntimeException
    Label proceedOriginal = mg.mark();
    if (callInvocationHandler) {
        // call stored InvocationHandler
        mg.loadThis();
        mg.getField(proxyType, FIELDNAME_HANDLER, invocationHandlerType);
        mg.loadThis();
        loadCurrentMethod(mg, method, methodType);
        loadArguments(mg, method, methodType);
        mg.invokeVirtual(invocationHandlerType,
                Method.getMethod("Object invoke(Object, java.lang.reflect.Method, Object[])"));
        mg.unbox(methodType.getReturnType());
        mg.returnValue();
    } else {
        // call super method
        mg.loadThis();
        mg.loadArgs();
        mg.visitMethodInsn(Opcodes.INVOKESPECIAL, superType.getInternalName(), method.getName(),
                Type.getMethodDescriptor(method), false);
        mg.returnValue();
    }
    mg.visitTryCatchBlock(tryBlockStart, tryBlockEnd, proceedOriginal,
            Type.getInternalName(ProceedOriginalMethodException.class));

    // catch declared exceptions
    if (exceptionTypes.length > 0) {
        Label rethrow = mg.mark();
        mg.visitVarInsn(Opcodes.ASTORE, 1);
        mg.visitVarInsn(Opcodes.ALOAD, 1);
        mg.throwException();

        // catch declared exceptions and rethrow it...
        for (Type exceptionType : exceptionTypes) {
            if (exceptionType.getClassName().equals(Throwable.class.getName())) {
                throwableCatched = true;
            }
            mg.visitTryCatchBlock(tryBlockStart, tryBlockEnd, rethrow, exceptionType.getInternalName());
        }
    }

    if (!throwableCatched) {
        // catch Throwable and wrap it with a UndeclaredThrowableException
        Type uteType = Type.getType(UndeclaredThrowableException.class);
        Label wrapAndRethrow = mg.mark();

        mg.visitVarInsn(Opcodes.ASTORE, 1);
        mg.newInstance(uteType);
        mg.dup();
        mg.visitVarInsn(Opcodes.ALOAD, 1);
        mg.invokeConstructor(uteType, Method.getMethod("void <init>(java.lang.Throwable)"));
        mg.throwException();

        mg.visitTryCatchBlock(tryBlockStart, tryBlockEnd, wrapAndRethrow,
                Type.getInternalName(Throwable.class));
    }

    // finish the method
    mg.endMethod();
    mg.visitMaxs(10, 10);
    mg.visitEnd();
}

From source file:org.apache.deltaspike.proxy.impl.AsmDeltaSpikeProxyClassGenerator.java

License:Apache License

private static void defineSuperAccessorMethod(ClassWriter cw, java.lang.reflect.Method method, Type superType,
        String superAccessorMethodSuffix) {
    Method originalAsmMethod = Method.getMethod(method);
    Method newAsmMethod = new Method(method.getName() + superAccessorMethodSuffix,
            originalAsmMethod.getReturnType(), originalAsmMethod.getArgumentTypes());
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, newAsmMethod, null, null, cw);

    mg.visitCode();//from   w w w.  j a v a  2  s .c  o m

    // call super method
    mg.loadThis();
    mg.loadArgs();
    mg.visitMethodInsn(Opcodes.INVOKESPECIAL, superType.getInternalName(), method.getName(),
            Type.getMethodDescriptor(method), false);
    mg.returnValue();

    // finish the method
    mg.endMethod();
    mg.visitMaxs(10, 10);
    mg.visitEnd();
}