Search in sources :

Example 1 with MethodGen

use of org.apache.bcel.generic.MethodGen in project jop by jop-devel.

the class OldClinitOrder method findDependencies.

private Set findDependencies(OldClassInfo cli, OldMethodInfo mi, boolean inRec) {
    //		System.out.println("find dep. in "+cli.clazz.getClassName()+":"+mi.getMethod().getName());
    Method method = mi.getMethod();
    Set depends = new HashSet();
    if (method.isNative() || method.isAbstract()) {
        // subclasses???? :-(
        return depends;
    }
    ConstantPool cpool = cli.clazz.getConstantPool();
    ConstantPoolGen cpoolgen = new ConstantPoolGen(cpool);
    MethodGen mg = new MethodGen(method, cli.clazz.getClassName(), cpoolgen);
    InstructionList il = mg.getInstructionList();
    InstructionFinder f = new InstructionFinder(il);
    // find instructions that access the constant pool
    // collect all indices to constants in ClassInfo
    String cpInstr = "CPInstruction";
    for (Iterator it = f.search(cpInstr); it.hasNext(); ) {
        InstructionHandle[] match = (InstructionHandle[]) it.next();
        InstructionHandle first = match[0];
        CPInstruction ii = (CPInstruction) first.getInstruction();
        int idx = ii.getIndex();
        Constant co = cpool.getConstant(idx);
        ConstantClass cocl = null;
        Set addDepends = null;
        String clname;
        OldClassInfo clinfo;
        OldMethodInfo minfo;
        switch(co.getTag()) {
            case Constants.CONSTANT_Class:
                cocl = (ConstantClass) co;
                clname = cocl.getBytes(cpool).replace('/', '.');
                clinfo = (OldClassInfo) ai.cliMap.get(clname);
                if (clinfo != null) {
                    minfo = clinfo.getMethodInfo("<init>()V");
                    if (minfo != null) {
                        addDepends = findDependencies(clinfo, minfo, true);
                    }
                }
                break;
            case Constants.CONSTANT_InterfaceMethodref:
                cocl = (ConstantClass) cpool.getConstant(((ConstantInterfaceMethodref) co).getClassIndex());
                break;
            case Constants.CONSTANT_Methodref:
                cocl = (ConstantClass) cpool.getConstant(((ConstantMethodref) co).getClassIndex());
                clname = cocl.getBytes(cpool).replace('/', '.');
                clinfo = (OldClassInfo) ai.cliMap.get(clname);
                int sigidx = ((ConstantMethodref) co).getNameAndTypeIndex();
                ConstantNameAndType signt = (ConstantNameAndType) cpool.getConstant(sigidx);
                String sigstr = signt.getName(cpool) + signt.getSignature(cpool);
                if (clinfo != null) {
                    minfo = clinfo.getMethodInfo(sigstr);
                    if (minfo != null) {
                        addDepends = findDependencies(clinfo, minfo, true);
                    }
                }
                break;
            case Constants.CONSTANT_Fieldref:
                cocl = (ConstantClass) cpool.getConstant(((ConstantFieldref) co).getClassIndex());
                break;
        }
        if (cocl != null) {
            clname = cocl.getBytes(cpool).replace('/', '.');
            OldClassInfo clinf = (OldClassInfo) ai.cliMap.get(clname);
            if (clinf != null) {
                if (clinf.getMethodInfo(OldAppInfo.clinitSig) != null) {
                    // don't add myself as dependency
                    if (clinf != cli) {
                        depends.add(clinf);
                    }
                }
            }
        }
        if (addDepends != null) {
            Iterator itAddDep = addDepends.iterator();
            while (itAddDep.hasNext()) {
                OldClassInfo addCli = (OldClassInfo) itAddDep.next();
                if (addCli == cli) {
                    throw new Error("cyclic indirect <clinit> dependency");
                }
                depends.add(addCli);
            }
        }
    }
    il.dispose();
    return depends;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) InstructionList(org.apache.bcel.generic.InstructionList) Constant(org.apache.bcel.classfile.Constant) Method(org.apache.bcel.classfile.Method) InstructionFinder(org.apache.bcel.util.InstructionFinder) MethodGen(org.apache.bcel.generic.MethodGen) InstructionHandle(org.apache.bcel.generic.InstructionHandle) ConstantNameAndType(org.apache.bcel.classfile.ConstantNameAndType) ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) CPInstruction(org.apache.bcel.generic.CPInstruction) ConstantMethodref(org.apache.bcel.classfile.ConstantMethodref) ConstantPool(org.apache.bcel.classfile.ConstantPool) Iterator(java.util.Iterator) ConstantClass(org.apache.bcel.classfile.ConstantClass) HashSet(java.util.HashSet)

Example 2 with MethodGen

use of org.apache.bcel.generic.MethodGen in project jop by jop-devel.

the class ReplaceAtomicAnnotation method transform.

public static Method transform(Method m, JavaClass clazz, ConstantPoolGen _cp) {
    MethodGen method = new MethodGen(m, clazz.getClassName(), _cp);
    InstructionList oldIl = method.getInstructionList();
    Type returnType = m.getReturnType();
    if (returnType.equals(Type.LONG) || returnType.equals(Type.DOUBLE)) {
        throw new UnsupportedOperationException();
    }
    final int transactionLocals = 2;
    /*
		 * local variable indices:
		 * isNotNestedTransaction is -2+2
		 * result is -2+3
		 * Throwable e is -2+3 
		 */
    final int maxLocals = method.getMaxLocals();
    final int transactionLocalsBaseIndex = maxLocals;
    final int copyBaseIndex = transactionLocalsBaseIndex + transactionLocals;
    SortedSet<Integer> modifiedArguments = getModifiedArguments(method);
    // maps modified arguments indices to copies
    Map<Integer, Integer> modifiedArgumentsCopies = new TreeMap<Integer, Integer>();
    {
        int copyIndex = copyBaseIndex;
        for (Integer i : modifiedArguments) {
            System.out.println("RTTM: method " + method.getClassName() + "." + method.getName() + method.getSignature() + ": saving argument " + i + " to variable " + copyIndex);
            modifiedArgumentsCopies.put(i, copyIndex++);
        }
    }
    InstructionList il = new InstructionList();
    InstructionFactory _factory = new InstructionFactory(_cp);
    method.setInstructionList(il);
    {
        //			InstructionHandle ih_0 = il.append(new PUSH(_cp, -559038737));
        //			il.append(_factory.createStore(Type.INT, transactionLocalsBaseIndex-2+1));
        InstructionHandle ih_3 = il.append(_factory.createFieldAccess("rttm.internal.Utils", "inTransaction", new ArrayType(Type.BOOLEAN, 1), Constants.GETSTATIC));
        il.append(new PUSH(_cp, -122));
        il.append(_factory.createInvoke("com.jopdesign.sys.Native", "rd", Type.INT, new Type[] { Type.INT }, Constants.INVOKESTATIC));
        il.append(InstructionConstants.BALOAD);
        BranchInstruction ifne_12 = InstructionFactory.createBranchInstruction(Constants.IFNE, null);
        il.append(ifne_12);
        il.append(new PUSH(_cp, 1));
        BranchInstruction goto_16 = InstructionFactory.createBranchInstruction(Constants.GOTO, null);
        il.append(goto_16);
        InstructionHandle ih_19 = il.append(new PUSH(_cp, 0));
        InstructionHandle ih_20 = il.append(InstructionFactory.createStore(Type.INT, transactionLocalsBaseIndex - 2 + 2));
        InstructionHandle ih_21 = il.append(InstructionFactory.createLoad(Type.INT, transactionLocalsBaseIndex - 2 + 2));
        BranchInstruction ifeq_22 = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
        il.append(ifeq_22);
        //			InstructionHandle ih_25 = il.append(_factory.createLoad(Type.INT, transactionLocalsBaseIndex-2+0));
        //			il.append(_factory.createStore(Type.INT, transactionLocalsBaseIndex-2+1));
        {
            // only save arguments which might be modified
            for (int i : modifiedArguments) {
                il.append(InstructionFactory.createLoad(Type.INT, i));
                il.append(InstructionFactory.createStore(Type.INT, modifiedArgumentsCopies.get(i)));
            }
        }
        InstructionHandle ih_27 = il.append(new PUSH(_cp, 0));
        il.append(new PUSH(_cp, -128));
        il.append(_factory.createInvoke("com.jopdesign.sys.Native", "wr", Type.VOID, new Type[] { Type.INT, Type.INT }, Constants.INVOKESTATIC));
        InstructionHandle ih_33 = il.append(_factory.createFieldAccess("rttm.internal.Utils", "inTransaction", new ArrayType(Type.BOOLEAN, 1), Constants.GETSTATIC));
        il.append(new PUSH(_cp, -122));
        il.append(_factory.createInvoke("com.jopdesign.sys.Native", "rd", Type.INT, new Type[] { Type.INT }, Constants.INVOKESTATIC));
        il.append(new PUSH(_cp, 1));
        il.append(InstructionConstants.BASTORE);
        // transaction loop
        InstructionHandle ih_43 = il.append(InstructionFactory.createLoad(Type.INT, transactionLocalsBaseIndex - 2 + 2));
        BranchInstruction ifeq_44 = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
        il.append(ifeq_44);
        InstructionHandle ih_47 = il.append(new PUSH(_cp, 1));
        il.append(new PUSH(_cp, Const.MEM_TM_MAGIC));
        il.append(_factory.createInvoke("com.jopdesign.sys.Native", "wrMem", Type.VOID, new Type[] { Type.INT, Type.INT }, Constants.INVOKESTATIC));
        //			InstructionHandle ih_53 = il.append(_factory.createLoad(Type.INT, transactionLocalsBaseIndex-2+0));
        //			il.append(_factory.createInvoke("rttm.swtest.Transaction", "atomicSection", Type.INT, new Type[] { Type.INT }, Constants.INVOKESTATIC));
        //			il.append(_factory.createStore(Type.INT, transactionLocalsBaseIndex-2+3));
        InstructionHandle ih_53 = oldIl.getStart();
        Collection<BranchInstruction> gotos_transactionCommit = new ArrayList<BranchInstruction>();
        {
            // redirect returns
            InstructionFinder f = new InstructionFinder(oldIl);
            String returnInstructionsPattern = "ARETURN|IRETURN|FRETURN|RETURN";
            for (Iterator i = f.search(returnInstructionsPattern); i.hasNext(); ) {
                InstructionHandle oldIh = ((InstructionHandle[]) i.next())[0];
                InstructionList nl = new InstructionList();
                if (!method.getReturnType().equals(Type.VOID)) {
                    nl.append(InstructionFactory.createStore(method.getReturnType(), transactionLocalsBaseIndex - 2 + 3));
                }
                BranchInstruction goto_transactionCommit = InstructionFactory.createBranchInstruction(Constants.GOTO, null);
                nl.append(goto_transactionCommit);
                gotos_transactionCommit.add(goto_transactionCommit);
                InstructionHandle newTarget = nl.getStart();
                oldIl.append(oldIh, nl);
                try {
                    oldIl.delete(oldIh);
                } catch (TargetLostException e) {
                    InstructionHandle[] targets = e.getTargets();
                    for (int k = 0; k < targets.length; k++) {
                        InstructionTargeter[] targeters = targets[k].getTargeters();
                        for (int j = 0; j < targeters.length; j++) {
                            targeters[j].updateTarget(targets[k], newTarget);
                        }
                    }
                }
            }
            il.append(oldIl);
        }
        InstructionHandle ih_58 = il.append(InstructionFactory.createLoad(Type.INT, transactionLocalsBaseIndex - 2 + 2));
        BranchInstruction ifeq_59 = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
        il.append(ifeq_59);
        InstructionHandle ih_62 = il.append(new PUSH(_cp, 0));
        il.append(new PUSH(_cp, Const.MEM_TM_MAGIC));
        il.append(_factory.createInvoke("com.jopdesign.sys.Native", "wrMem", Type.VOID, new Type[] { Type.INT, Type.INT }, Constants.INVOKESTATIC));
        InstructionHandle ih_68 = il.append(_factory.createFieldAccess("rttm.internal.Utils", "inTransaction", new ArrayType(Type.BOOLEAN, 1), Constants.GETSTATIC));
        il.append(new PUSH(_cp, -122));
        il.append(_factory.createInvoke("com.jopdesign.sys.Native", "rd", Type.INT, new Type[] { Type.INT }, Constants.INVOKESTATIC));
        il.append(new PUSH(_cp, 0));
        il.append(InstructionConstants.BASTORE);
        InstructionHandle ih_78 = il.append(new PUSH(_cp, 1));
        il.append(new PUSH(_cp, -128));
        il.append(_factory.createInvoke("com.jopdesign.sys.Native", "wr", Type.VOID, new Type[] { Type.INT, Type.INT }, Constants.INVOKESTATIC));
        //			InstructionHandle ih_84 = il.append(_factory.createLoad(Type.INT, transactionLocalsBaseIndex-2+3));
        //			il.append(_factory.createReturn(Type.INT));
        InstructionHandle ih_84;
        {
            // return
            if (!method.getReturnType().equals(Type.VOID)) {
                ih_84 = il.append(InstructionFactory.createLoad(method.getReturnType(), transactionLocalsBaseIndex - 2 + 3));
                il.append(InstructionFactory.createReturn(method.getReturnType()));
            } else {
                ih_84 = il.append(InstructionFactory.createReturn(method.getReturnType()));
            }
        }
        // catch block
        // variable e has index 3
        // } catch (Throwable e) {
        InstructionHandle nih_86 = il.append(InstructionFactory.createStore(Type.OBJECT, transactionLocalsBaseIndex - 2 + 3));
        // if (isNotNestedTransaction) {
        InstructionHandle nih_87 = il.append(InstructionFactory.createLoad(Type.INT, transactionLocalsBaseIndex - 2 + 2));
        BranchInstruction ifeq_88 = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
        il.append(ifeq_88);
        InstructionHandle nih_91 = il.append(InstructionFactory.createLoad(Type.OBJECT, transactionLocalsBaseIndex - 2 + 3));
        il.append(_factory.createFieldAccess("com.jopdesign.sys.RetryException", "instance", new ObjectType("com.jopdesign.sys.RetryException"), Constants.GETSTATIC));
        BranchInstruction if_acmpne_95 = InstructionFactory.createBranchInstruction(Constants.IF_ACMPNE, null);
        il.append(if_acmpne_95);
        // InstructionHandle nih_98 = il.append(_factory.createLoad(Type.INT,
        // 1));
        // il.append(_factory.createStore(Type.INT, 0));
        {
            for (int i : modifiedArguments) {
                il.append(InstructionFactory.createLoad(Type.INT, modifiedArgumentsCopies.get(i)));
                il.append(InstructionFactory.createStore(Type.INT, i));
            }
        }
        BranchInstruction goto_110 = InstructionFactory.createBranchInstruction(Constants.GOTO, ih_43);
        InstructionHandle ih_110 = il.append(goto_110);
        // exception was manually aborted or a bug triggered
        InstructionHandle nih_103 = il.append(_factory.createFieldAccess("rttm.internal.Utils", "inTransaction", new ArrayType(Type.BOOLEAN, 1), Constants.GETSTATIC));
        il.append(new PUSH(_cp, -122));
        il.append(_factory.createInvoke("com.jopdesign.sys.Native", "rd", Type.INT, new Type[] { Type.INT }, Constants.INVOKESTATIC));
        il.append(new PUSH(_cp, 0));
        il.append(InstructionConstants.BASTORE);
        InstructionHandle nih_113 = il.append(new PUSH(_cp, 1));
        il.append(new PUSH(_cp, -128));
        il.append(_factory.createInvoke("com.jopdesign.sys.Native", "wrMem", Type.VOID, new Type[] { Type.INT, Type.INT }, Constants.INVOKESTATIC));
        InstructionHandle nih_119 = il.append(InstructionFactory.createLoad(Type.OBJECT, transactionLocalsBaseIndex - 2 + 3));
        // il.append(_factory.createCheckCast(new
        // ObjectType("java.lang.RuntimeException")));
        il.append(InstructionConstants.ATHROW);
        // set branch targets			
        ifne_12.setTarget(ih_19);
        goto_16.setTarget(ih_20);
        ifeq_22.setTarget(ih_43);
        ifeq_44.setTarget(ih_53);
        ifeq_59.setTarget(ih_84);
        ifeq_88.setTarget(nih_119);
        if_acmpne_95.setTarget(nih_103);
        {
            for (BranchInstruction b : gotos_transactionCommit) {
                b.setTarget(ih_58);
            }
        }
        // set exception handlers 
        // TODO restrict exception handler
        method.addExceptionHandler(ih_53, ih_84, nih_86, null);
        method.setMaxStack();
        method.setMaxLocals();
    }
    m = method.getMethod();
    oldIl.dispose();
    il.dispose();
    return m;
}
Also used : BranchInstruction(org.apache.bcel.generic.BranchInstruction) InstructionList(org.apache.bcel.generic.InstructionList) InstructionFinder(org.apache.bcel.util.InstructionFinder) TreeMap(java.util.TreeMap) MethodGen(org.apache.bcel.generic.MethodGen) InstructionHandle(org.apache.bcel.generic.InstructionHandle) InstructionFactory(org.apache.bcel.generic.InstructionFactory) ArrayType(org.apache.bcel.generic.ArrayType) ObjectType(org.apache.bcel.generic.ObjectType) Type(org.apache.bcel.generic.Type) ObjectType(org.apache.bcel.generic.ObjectType) ArrayType(org.apache.bcel.generic.ArrayType) Iterator(java.util.Iterator) Collection(java.util.Collection) TargetLostException(org.apache.bcel.generic.TargetLostException) PUSH(org.apache.bcel.generic.PUSH)

Example 3 with MethodGen

use of org.apache.bcel.generic.MethodGen in project jop by jop-devel.

the class ClassInfo method copyMethod.

public MethodInfo copyMethod(String memberSignature, String newName) {
    MethodInfo method = methods.get(memberSignature);
    if (method == null) {
        return null;
    }
    MethodGen methodGen = new MethodGen(method.compile(), getClassName(), cpg);
    methodGen.setName(newName);
    MethodInfo newMethod = new MethodInfo(this, methodGen);
    // TODO copy all the attribute stuff, call manager eventhandler
    methods.put(newMethod.getMethodSignature(), newMethod);
    classGen.addMethod(newMethod.getMethod(false));
    return newMethod;
}
Also used : MethodGen(org.apache.bcel.generic.MethodGen)

Example 4 with MethodGen

use of org.apache.bcel.generic.MethodGen in project core by s4.

the class OverloadDispatcherGenerator method generate.

public Class<Object> generate() {
    Random rand = new Random(System.currentTimeMillis());
    String dispatcherClassName = "OverloadDispatcher" + (Math.abs(rand.nextInt() % 3256));
    String interfaceName = "io.s4.processor.OverloadDispatcher";
    if (forSlot) {
        interfaceName = "io.s4.processor.OverloadDispatcherSlot";
    }
    ClassGen cg = new ClassGen(dispatcherClassName, "java.lang.Object", dispatcherClassName + ".java", Constants.ACC_PUBLIC | Constants.ACC_SUPER, new String[] { interfaceName });
    ConstantPoolGen cp = cg.getConstantPool();
    InstructionFactory instFactory = new InstructionFactory(cg, cp);
    InstructionList il = new InstructionList();
    // build constructor method for new class
    MethodGen constructor = new MethodGen(Constants.ACC_PUBLIC, Type.VOID, Type.NO_ARGS, new String[] {}, "<init>", dispatcherClassName, il, cp);
    il.append(InstructionFactory.createLoad(Type.OBJECT, 0));
    il.append(instFactory.createInvoke("java.lang.Object", "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
    il.append(InstructionFactory.createReturn(Type.VOID));
    constructor.setMaxStack();
    constructor.setMaxLocals();
    cg.addMethod(constructor.getMethod());
    il.dispose();
    // build dispatch method
    il = new InstructionList();
    Type[] dispatchArgumentTypes = null;
    String[] dispatchArgumentNames = null;
    int postArgumentVariableSlot = 3;
    if (forSlot) {
        dispatchArgumentTypes = new Type[] { ObjectType.OBJECT, ObjectType.OBJECT, ObjectType.LONG, abstractWindowingPEType };
        dispatchArgumentNames = new String[] { "slot", "event", "slotTime", "pe" };
        postArgumentVariableSlot = 6;
    } else {
        dispatchArgumentTypes = new Type[] { ObjectType.OBJECT, ObjectType.OBJECT };
        dispatchArgumentNames = new String[] { "pe", "event" };
    }
    MethodGen method = new MethodGen(Constants.ACC_PUBLIC, Type.VOID, dispatchArgumentTypes, dispatchArgumentNames, "dispatch", dispatcherClassName, il, cp);
    List<InstructionHandle> targetInstructions = new ArrayList<InstructionHandle>();
    List<BranchInstruction> branchInstructions = new ArrayList<BranchInstruction>();
    List<BranchInstruction> gotoInstructions = new ArrayList<BranchInstruction>();
    ObjectType peType = new ObjectType(targetClass.getName());
    il.append(InstructionFactory.createLoad(Type.OBJECT, 1));
    il.append(instFactory.createCheckCast(peType));
    il.append(InstructionFactory.createStore(peType, postArgumentVariableSlot));
    for (int i = 0; i < hierarchies.size(); i++) {
        Hierarchy hierarchy = hierarchies.get(i);
        ObjectType hierarchyTop = new ObjectType(hierarchy.getTop().getName());
        InstructionHandle ih = il.append(InstructionFactory.createLoad(Type.OBJECT, 2));
        if (i > 0) {
            targetInstructions.add(ih);
        }
        il.append(new INSTANCEOF(cp.addClass(hierarchyTop)));
        BranchInstruction bi = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
        il.append(bi);
        branchInstructions.add(bi);
        il.append(InstructionFactory.createLoad(peType, postArgumentVariableSlot));
        il.append(InstructionFactory.createLoad(hierarchyTop, 2));
        il.append(instFactory.createCheckCast(hierarchyTop));
        if (forSlot) {
            il.append(InstructionFactory.createLoad(ObjectType.LONG, 3));
            il.append(InstructionFactory.createLoad(abstractWindowingPEType, 5));
        }
        Type[] argumentTypes = null;
        if (forSlot) {
            argumentTypes = new Type[] { hierarchyTop, ObjectType.LONG, abstractWindowingPEType };
        } else {
            argumentTypes = new Type[] { hierarchyTop };
        }
        il.append(instFactory.createInvoke(targetClass.getName(), "processEvent", Type.VOID, argumentTypes, Constants.INVOKEVIRTUAL));
        // no branch needed for last check
        if (i < (hierarchies.size() - 1)) {
            bi = InstructionFactory.createBranchInstruction(Constants.GOTO, null);
            il.append(bi);
            gotoInstructions.add(bi);
        }
    }
    InstructionHandle returnInstruction = il.append(InstructionFactory.createReturn(Type.VOID));
    for (int i = 0; i < targetInstructions.size(); i++) {
        branchInstructions.get(i).setTarget(targetInstructions.get(i));
    }
    branchInstructions.get(branchInstructions.size() - 1).setTarget(returnInstruction);
    for (BranchInstruction gotoInstruction : gotoInstructions) {
        gotoInstruction.setTarget(returnInstruction);
    }
    method.setMaxStack();
    method.setMaxLocals();
    cg.addMethod(method.getMethod());
    il.dispose();
    JavaClass jc = cg.getJavaClass();
    OverloadDispatcherClassLoader cl = new OverloadDispatcherClassLoader();
    // debug
    if (classDumpFile != null) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(classDumpFile);
            fos.write(jc.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fos != null)
                try {
                    fos.close();
                } catch (Exception e) {
                }
        }
    }
    return cl.loadClassFromBytes(dispatcherClassName, jc.getBytes());
}
Also used : INSTANCEOF(org.apache.bcel.generic.INSTANCEOF) BranchInstruction(org.apache.bcel.generic.BranchInstruction) InstructionList(org.apache.bcel.generic.InstructionList) ClassGen(org.apache.bcel.generic.ClassGen) ArrayList(java.util.ArrayList) MethodGen(org.apache.bcel.generic.MethodGen) InstructionHandle(org.apache.bcel.generic.InstructionHandle) InstructionFactory(org.apache.bcel.generic.InstructionFactory) ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) ObjectType(org.apache.bcel.generic.ObjectType) Type(org.apache.bcel.generic.Type) ObjectType(org.apache.bcel.generic.ObjectType) Random(java.util.Random) JavaClass(org.apache.bcel.classfile.JavaClass) FileOutputStream(java.io.FileOutputStream)

Example 5 with MethodGen

use of org.apache.bcel.generic.MethodGen in project core by s4.

the class ClonerGenerator method generate.

public Class generate(Class clazz) {
    String className = clazz.getName();
    Random rand = new Random(System.currentTimeMillis());
    String clonerClassname = "Cloner" + (Math.abs(rand.nextInt() % 3256));
    ClassGen cg = new ClassGen(clonerClassname, "java.lang.Object", clonerClassname + ".java", Constants.ACC_PUBLIC | Constants.ACC_SUPER, new String[] { "io.s4.util.Cloner" });
    ConstantPoolGen cp = cg.getConstantPool();
    InstructionFactory instFactory = new InstructionFactory(cg, cp);
    InstructionList il = new InstructionList();
    // build constructor method for new class
    MethodGen constructor = new MethodGen(Constants.ACC_PUBLIC, Type.VOID, Type.NO_ARGS, new String[] {}, "<init>", clonerClassname, il, cp);
    il.append(InstructionFactory.createLoad(Type.OBJECT, 0));
    il.append(instFactory.createInvoke("java.lang.Object", "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
    il.append(InstructionFactory.createReturn(Type.VOID));
    constructor.setMaxStack();
    constructor.setMaxLocals();
    cg.addMethod(constructor.getMethod());
    il.dispose();
    // build clone method
    il = new InstructionList();
    MethodGen method = new MethodGen(Constants.ACC_PUBLIC, Type.OBJECT, new Type[] { Type.OBJECT }, new String[] { "arg0" }, "clone", clonerClassname, il, cp);
    il.append(InstructionConstants.ACONST_NULL);
    il.append(InstructionFactory.createStore(Type.OBJECT, 2));
    il.append(InstructionFactory.createLoad(Type.OBJECT, 1));
    il.append(new INSTANCEOF(cp.addClass(new ObjectType(className))));
    BranchInstruction ifeq_6 = InstructionFactory.createBranchInstruction(Constants.IFEQ, null);
    il.append(ifeq_6);
    il.append(InstructionFactory.createLoad(Type.OBJECT, 1));
    il.append(instFactory.createCheckCast(new ObjectType(className)));
    il.append(InstructionFactory.createStore(Type.OBJECT, 2));
    InstructionHandle ih_14 = il.append(InstructionFactory.createLoad(Type.OBJECT, 2));
    il.append(new INSTANCEOF(cp.addClass(new ObjectType("java.lang.Cloneable"))));
    BranchInstruction ifne_18 = InstructionFactory.createBranchInstruction(Constants.IFNE, null);
    il.append(ifne_18);
    il.append(instFactory.createFieldAccess("java.lang.System", "out", new ObjectType("java.io.PrintStream"), Constants.GETSTATIC));
    il.append(new PUSH(cp, "Not cloneable!"));
    il.append(instFactory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[] { Type.STRING }, Constants.INVOKEVIRTUAL));
    il.append(InstructionConstants.ACONST_NULL);
    il.append(InstructionFactory.createReturn(Type.OBJECT));
    InstructionHandle ih_31 = il.append(InstructionFactory.createLoad(Type.OBJECT, 2));
    il.append(instFactory.createInvoke(className, "clone", Type.OBJECT, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
    il.append(InstructionFactory.createReturn(Type.OBJECT));
    ifeq_6.setTarget(ih_14);
    ifne_18.setTarget(ih_31);
    method.setMaxStack();
    method.setMaxLocals();
    cg.addMethod(method.getMethod());
    il.dispose();
    JavaClass jc = cg.getJavaClass();
    ClonerClassLoader cl = new ClonerClassLoader();
    return cl.loadClassFromBytes(clonerClassname, jc.getBytes());
}
Also used : INSTANCEOF(org.apache.bcel.generic.INSTANCEOF) BranchInstruction(org.apache.bcel.generic.BranchInstruction) InstructionList(org.apache.bcel.generic.InstructionList) ClassGen(org.apache.bcel.generic.ClassGen) MethodGen(org.apache.bcel.generic.MethodGen) InstructionHandle(org.apache.bcel.generic.InstructionHandle) InstructionFactory(org.apache.bcel.generic.InstructionFactory) ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) ObjectType(org.apache.bcel.generic.ObjectType) Type(org.apache.bcel.generic.Type) ObjectType(org.apache.bcel.generic.ObjectType) Random(java.util.Random) JavaClass(org.apache.bcel.classfile.JavaClass) PUSH(org.apache.bcel.generic.PUSH)

Aggregations

MethodGen (org.apache.bcel.generic.MethodGen)9 InstructionList (org.apache.bcel.generic.InstructionList)7 InstructionHandle (org.apache.bcel.generic.InstructionHandle)6 Iterator (java.util.Iterator)4 ObjectType (org.apache.bcel.generic.ObjectType)4 Type (org.apache.bcel.generic.Type)4 InstructionFinder (org.apache.bcel.util.InstructionFinder)4 JavaClass (org.apache.bcel.classfile.JavaClass)3 BranchInstruction (org.apache.bcel.generic.BranchInstruction)3 CPInstruction (org.apache.bcel.generic.CPInstruction)3 ConstantPoolGen (org.apache.bcel.generic.ConstantPoolGen)3 InstructionFactory (org.apache.bcel.generic.InstructionFactory)3 ArrayList (java.util.ArrayList)2 Random (java.util.Random)2 Constant (org.apache.bcel.classfile.Constant)2 ConstantNameAndType (org.apache.bcel.classfile.ConstantNameAndType)2 Method (org.apache.bcel.classfile.Method)2 ClassGen (org.apache.bcel.generic.ClassGen)2 INSTANCEOF (org.apache.bcel.generic.INSTANCEOF)2 PUSH (org.apache.bcel.generic.PUSH)2