Search in sources :

Example 41 with Method

use of org.apache.bcel.classfile.Method in project narchy by automenta.

the class ClassVisitor method visitJavaClass.

@Override
public void visitJavaClass(JavaClass jc) {
    jc.getConstantPool().accept(this);
    Method[] methods = jc.getMethods();
    for (Method method : methods) {
        method.accept(this);
        if (jc.isInterface()) {
            graph.register(jc, method);
        }
    }
}
Also used : Method(org.apache.bcel.classfile.Method)

Example 42 with Method

use of org.apache.bcel.classfile.Method in project jop by jop-devel.

the class ReplaceAtomicAnnotation method visitJavaClass.

public void visitJavaClass(JavaClass clazz) {
    super.visitJavaClass(clazz);
    Method[] methods = clazz.getMethods();
    for (int i = 0; i < methods.length; i++) {
        for (Attribute a : methods[i].getAttributes()) {
            if (a instanceof AnnotationAttribute) {
                if (((AnnotationAttribute) a).hasAtomicAnnotation()) {
                    ConstantPoolGen cpoolgen = new ConstantPoolGen(clazz.getConstantPool());
                    Method nm = transform(methods[i], clazz, cpoolgen);
                    OldMethodInfo mi = getCli().getMethodInfo(nm.getName() + nm.getSignature());
                    // set new method also in MethodInfo
                    mi.setMethod(nm);
                    methods[i] = nm;
                    clazz.setConstantPool(cpoolgen.getFinalConstantPool());
                    System.out.println("RTTM: transformed atomic method " + clazz.getClassName() + "." + nm.getName() + nm.getSignature());
                }
            }
        }
    }
}
Also used : ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) Attribute(org.apache.bcel.classfile.Attribute) AnnotationAttribute(com.jopdesign.common.bcel.AnnotationAttribute) Method(org.apache.bcel.classfile.Method) AnnotationAttribute(com.jopdesign.common.bcel.AnnotationAttribute)

Example 43 with Method

use of org.apache.bcel.classfile.Method in project jop by jop-devel.

the class ReplaceNativeAndCPIdx method replace.

private Method replace(Method method) {
    MethodGen mg = new MethodGen(method, clazz.getClassName(), cpoolgen);
    InstructionList il = mg.getInstructionList();
    InstructionFinder f = new InstructionFinder(il);
    String methodId = method.getName() + method.getSignature();
    OldMethodInfo mi = getCli().getMethodInfo(methodId);
    // find invokes first and replace call to Native by
    // JOP native instructions.
    String invokeStr = "InvokeInstruction";
    for (Iterator i = f.search(invokeStr); i.hasNext(); ) {
        InstructionHandle[] match = (InstructionHandle[]) i.next();
        InstructionHandle first = match[0];
        InvokeInstruction ii = (InvokeInstruction) first.getInstruction();
        if (ii.getClassName(cpoolgen).equals(JOPizer.nativeClass)) {
            short opid = (short) JopInstr.getNative(ii.getMethodName(cpoolgen));
            if (opid == -1) {
                System.err.println(method.getName() + ": cannot locate " + ii.getMethodName(cpoolgen) + ". Replacing with NOP.");
                first.setInstruction(new NOP());
            } else {
                first.setInstruction(new NativeInstruction(opid, (short) 1));
                ((JOPizer) ai).outTxt.println("\t" + first.getPosition());
                // then we remove pc+2 and pc+1 from the MGCI info
                if (JOPizer.dumpMgci) {
                    il.setPositions();
                    int pc = first.getPosition();
                    // important: take the high one first
                    GCRTMethodInfo.removePC(pc + 2, mi);
                    GCRTMethodInfo.removePC(pc + 1, mi);
                }
            }
        }
        if (ii instanceof INVOKESPECIAL) {
            // not an initializer
            if (!ii.getMethodName(cpoolgen).equals("<init>")) {
                // check if this is a super invoke
                // TODO this is just a hack, use InvokeSite.isInvokeSuper() when this is ported to the new framework!
                boolean isSuper = false;
                String declaredType = ii.getClassName(cpoolgen);
                JopClassInfo cls = getCli();
                OldClassInfo superClass = cls.superClass;
                while (superClass != null) {
                    if (superClass.clazz.getClassName().equals(declaredType)) {
                        isSuper = true;
                        break;
                    }
                    if ("java.lang.Object".equals(superClass.clazz.getClassName())) {
                        break;
                    }
                    superClass = superClass.superClass;
                }
                if (isSuper) {
                    Integer idx = ii.getIndex();
                    int new_index = getCli().cpoolUsed.indexOf(idx) + 1;
                    first.setInstruction(new JOPSYS_INVOKESUPER((short) new_index));
                // System.err.println("invokesuper "+ii.getClassName(cpoolgen)+"."+ii.getMethodName(cpoolgen));
                }
            }
        }
    }
    if (JOPizer.CACHE_INVAL) {
        f = new InstructionFinder(il);
        // find volatile reads and insert cache invalidation bytecode
        String fieldInstr = "GETFIELD|GETSTATIC|PUTFIELD|PUTSTATIC";
        for (Iterator i = f.search(fieldInstr); i.hasNext(); ) {
            InstructionHandle[] match = (InstructionHandle[]) i.next();
            InstructionHandle ih = match[0];
            FieldInstruction fi = (FieldInstruction) ih.getInstruction();
            JavaClass jc = JOPizer.jz.cliMap.get(fi.getClassName(cpoolgen)).clazz;
            Field field = null;
            while (field == null) {
                Field[] fields = jc.getFields();
                for (int k = 0; k < fields.length; k++) {
                    if (fields[k].getName().equals(fi.getFieldName(cpoolgen))) {
                        field = fields[k];
                        break;
                    }
                }
                if (field == null) {
                    try {
                        jc = jc.getSuperClass();
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                        throw new Error();
                    }
                }
            }
            if (field.isVolatile()) {
                if (field.getType().getSize() < 2) {
                    if (fi instanceof GETFIELD || fi instanceof GETSTATIC) {
                        ih.setInstruction(new InvalidateInstruction());
                        ih = il.append(ih, fi);
                    }
                } else {
                    // this only works because we do not throw a
                    // NullPointerException for monitorenter/-exit!
                    ih.setInstruction(new ACONST_NULL());
                    ih = il.append(ih, new MONITORENTER());
                    ih = il.append(ih, fi);
                    ih = il.append(ih, new ACONST_NULL());
                    ih = il.append(ih, new MONITOREXIT());
                }
            }
        }
    }
    f = new InstructionFinder(il);
    // find instructions that access the constant pool
    // and replace the index by the new value from ClassInfo
    String cpInstr = "CPInstruction";
    for (Iterator it = f.search(cpInstr); it.hasNext(); ) {
        InstructionHandle[] match = (InstructionHandle[]) it.next();
        InstructionHandle ih = match[0];
        CPInstruction cpii = (CPInstruction) ih.getInstruction();
        int index = cpii.getIndex();
        // we have to grab the information before we change
        // the CP index.
        FieldInstruction fi = null;
        Type ft = null;
        if (cpii instanceof FieldInstruction) {
            fi = (FieldInstruction) ih.getInstruction();
            ft = fi.getFieldType(cpoolgen);
        }
        Integer idx = new Integer(index);
        // pos is the new position in the reduced constant pool
        // idx is the position in the 'original' unresolved cpool
        int pos = getCli().cpoolUsed.indexOf(idx);
        int new_index = pos + 1;
        // and putfield and by address for getstatic and putstatic
        if (cpii instanceof GETFIELD || cpii instanceof PUTFIELD || cpii instanceof GETSTATIC || cpii instanceof PUTSTATIC) {
            // we use the offset instead of the CP index
            new_index = getFieldOffset(cp, index);
        } else {
            if (pos == -1) {
                System.out.println("Error: constant " + index + " " + cpoolgen.getConstant(index) + " not found");
                System.out.println("new cpool: " + getCli().cpoolUsed);
                System.out.println("original cpool: " + cpoolgen);
                System.exit(-1);
            }
        }
        // set new index, position starts at
        // 1 as cp points to the length of the pool
        cpii.setIndex(new_index);
        if (cpii instanceof FieldInstruction) {
            boolean isRef = ft instanceof ReferenceType;
            boolean isLong = ft == BasicType.LONG || ft == BasicType.DOUBLE;
            if (fi instanceof GETSTATIC) {
                if (isRef) {
                    ih.setInstruction(new GETSTATIC_REF((short) new_index));
                } else if (isLong) {
                    ih.setInstruction(new GETSTATIC_LONG((short) new_index));
                }
            } else if (fi instanceof PUTSTATIC) {
                if (isRef) {
                    if (!com.jopdesign.build.JOPizer.USE_RTTM) {
                        ih.setInstruction(new PUTSTATIC_REF((short) new_index));
                    }
                } else if (isLong) {
                    ih.setInstruction(new PUTSTATIC_LONG((short) new_index));
                }
            } else if (fi instanceof GETFIELD) {
                if (isRef) {
                    ih.setInstruction(new GETFIELD_REF((short) new_index));
                } else if (isLong) {
                    ih.setInstruction(new GETFIELD_LONG((short) new_index));
                }
            } else if (fi instanceof PUTFIELD) {
                if (isRef) {
                    if (!com.jopdesign.build.JOPizer.USE_RTTM) {
                        ih.setInstruction(new PUTFIELD_REF((short) new_index));
                    }
                } else if (isLong) {
                    ih.setInstruction(new PUTFIELD_LONG((short) new_index));
                }
            }
        }
    }
    Method m = mg.getMethod();
    il.dispose();
    return m;
}
Also used : InstructionList(org.apache.bcel.generic.InstructionList) InstructionFinder(org.apache.bcel.util.InstructionFinder) MONITORENTER(org.apache.bcel.generic.MONITORENTER) MethodGen(org.apache.bcel.generic.MethodGen) InstructionHandle(org.apache.bcel.generic.InstructionHandle) ReferenceType(org.apache.bcel.generic.ReferenceType) PUTSTATIC(org.apache.bcel.generic.PUTSTATIC) Field(org.apache.bcel.classfile.Field) CPInstruction(org.apache.bcel.generic.CPInstruction) Iterator(java.util.Iterator) MONITOREXIT(org.apache.bcel.generic.MONITOREXIT) ACONST_NULL(org.apache.bcel.generic.ACONST_NULL) PUTFIELD(org.apache.bcel.generic.PUTFIELD) Method(org.apache.bcel.classfile.Method) INVOKESPECIAL(org.apache.bcel.generic.INVOKESPECIAL) NOP(org.apache.bcel.generic.NOP) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) GETFIELD(org.apache.bcel.generic.GETFIELD) ReferenceType(org.apache.bcel.generic.ReferenceType) Type(org.apache.bcel.generic.Type) BasicType(org.apache.bcel.generic.BasicType) ConstantNameAndType(org.apache.bcel.classfile.ConstantNameAndType) JavaClass(org.apache.bcel.classfile.JavaClass) FieldInstruction(org.apache.bcel.generic.FieldInstruction) GETSTATIC(org.apache.bcel.generic.GETSTATIC)

Example 44 with Method

use of org.apache.bcel.classfile.Method in project jop by jop-devel.

the class ClassInfo method lookupMethodInfo.

/**
 * Get the index of the given method in the class method array, or -1 if not found.
 *
 * @param memberSignature name and descriptor of the method to find.
 * @return the index in the methods array or -1 if not found.
 */
public int lookupMethodInfo(String memberSignature) {
    Method[] methods = classGen.getMethods();
    for (int i = 0; i < methods.length; i++) {
        Method m = methods[i];
        String s = MemberID.getMethodSignature(m.getName(), m.getSignature());
        if (s.equals(memberSignature)) {
            return i;
        }
    }
    return -1;
}
Also used : Method(org.apache.bcel.classfile.Method)

Example 45 with Method

use of org.apache.bcel.classfile.Method in project jop by jop-devel.

the class ClassInfo method compile.

/**
 * Commit all modifications to this ClassInfo and return a BCEL JavaClass for this ClassInfo.
 * <p>
 * You may want to call {@link #rebuildConstantPool(ConstantPoolRebuilder)} and {@link #rebuildInnerClasses()} first if needed.
 * </p>
 * @see MethodInfo#compile()
 * @see #rebuildInnerClasses()
 * @see #rebuildConstantPool(ConstantPoolRebuilder)
 * @see #getJavaClass()
 * @return a JavaClass representing this ClassInfo.
 */
public JavaClass compile() {
    // We could keep a modified flag in both MethodInfo and FieldInfo
    // (maybe even ClassInfo), and update only what is needed here
    // could make class-writing,.. faster, but makes code more complex
    Field[] fList = classGen.getFields();
    if (fList.length != fields.size()) {
        // should never happen
        throw new JavaClassFormatError("Number of fields in classGen of " + getClassName() + " differs from number of FieldInfos!");
    }
    for (Field f : fList) {
        classGen.replaceField(f, fields.get(f.getName()).getField());
    }
    Method[] mList = classGen.getMethods();
    if (mList.length != methods.size()) {
        // should never happen
        throw new JavaClassFormatError("Number of methods in classGen of " + getClassName() + " differs from number of MethodInfos!");
    }
    for (int i = 0; i < mList.length; i++) {
        MethodInfo method = methods.get(MemberID.getMethodSignature(mList[i].getName(), mList[i].getSignature()));
        classGen.setMethodAt(method.compile(), i);
    }
    return classGen.getJavaClass();
}
Also used : Field(org.apache.bcel.classfile.Field) JavaClassFormatError(com.jopdesign.common.misc.JavaClassFormatError) Method(org.apache.bcel.classfile.Method)

Aggregations

Method (org.apache.bcel.classfile.Method)79 JavaClass (org.apache.bcel.classfile.JavaClass)28 BugInstance (edu.umd.cs.findbugs.BugInstance)20 ToString (com.mebigfatguy.fbcontrib.utils.ToString)12 StopOpcodeParsingException (com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException)11 FQMethod (com.mebigfatguy.fbcontrib.utils.FQMethod)7 HashMap (java.util.HashMap)7 HashSet (java.util.HashSet)7 Field (org.apache.bcel.classfile.Field)6 Type (org.apache.bcel.generic.Type)6 AnnotationEntry (org.apache.bcel.classfile.AnnotationEntry)5 ExceptionTable (org.apache.bcel.classfile.ExceptionTable)5 OpcodeStack (edu.umd.cs.findbugs.OpcodeStack)4 SourceLineAnnotation (edu.umd.cs.findbugs.SourceLineAnnotation)4 ArrayList (java.util.ArrayList)4 Map (java.util.Map)4 ConstantPoolGen (org.apache.bcel.generic.ConstantPoolGen)4 BugType (com.mebigfatguy.fbcontrib.utils.BugType)3 QMethod (com.mebigfatguy.fbcontrib.utils.QMethod)3 XMethod (edu.umd.cs.findbugs.ba.XMethod)3