Search in sources :

Example 1 with JavaClassFormatError

use of com.jopdesign.common.misc.JavaClassFormatError in project jop by jop-devel.

the class JOPModel method getJavaImplementation.

public MethodInfo getJavaImplementation(AppInfo ai, MethodInfo context, Instruction instr) {
    ClassInfo receiver = ai.getClassInfo(JVM_CLASS);
    String methodName = "f_" + JopInstr.name(getNativeOpCode(context, instr));
    Set<MethodInfo> mi = receiver.getMethodByName(methodName);
    if (!mi.isEmpty()) {
        if (mi.size() > 1) {
            throw new JavaClassFormatError("JVM class " + JVM_CLASS + " has more than one implementation of " + methodName);
        }
        return mi.iterator().next();
    }
    return null;
}
Also used : JavaClassFormatError(com.jopdesign.common.misc.JavaClassFormatError) MethodInfo(com.jopdesign.common.MethodInfo) ClassInfo(com.jopdesign.common.ClassInfo)

Example 2 with JavaClassFormatError

use of com.jopdesign.common.misc.JavaClassFormatError in project jop by jop-devel.

the class ClinitOrder method findDependencies.

private Set<ClassInfo> findDependencies(MethodInfo method, boolean inRec) {
    //		System.out.println("find dep. in "+cli.clazz.getClassName()+":"+mi.getMethod().getName());
    Set<ClassInfo> depends = new HashSet<ClassInfo>();
    if (method.isNative() || method.isAbstract()) {
        // subclasses???? :-(
        return depends;
    }
    ClassInfo classInfo = method.getClassInfo();
    ConstantPoolGen cpoolgen = method.getConstantPoolGen();
    InstructionList il = method.getCode().getInstructionList();
    InstructionFinder f = new InstructionFinder(il);
    // TODO can we encounter an empty instruction list?
    //if(il.getStart() == null) {
    //    return depends;
    //}
    // 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 = cpoolgen.getConstant(idx);
        ClassRef classRef = null;
        Set addDepends = null;
        ClassInfo clinfo;
        MethodInfo minfo;
        switch(co.getTag()) {
            case Constants.CONSTANT_Class:
                classRef = classInfo.getConstantInfo(co).getClassRef();
                clinfo = classRef.getClassInfo();
                if (clinfo != null) {
                    minfo = clinfo.getMethodInfo("<init>()V");
                    if (minfo != null) {
                        addDepends = findDependencies(minfo, true);
                    }
                }
                break;
            case Constants.CONSTANT_Fieldref:
            case Constants.CONSTANT_InterfaceMethodref:
                classRef = classInfo.getConstantInfo(co).getClassRef();
                break;
            case Constants.CONSTANT_Methodref:
                ConstantMethodInfo mref = (ConstantMethodInfo) classInfo.getConstantInfo(co);
                classRef = mref.getClassRef();
                minfo = mref.getMethodRef().getMethodInfo();
                if (minfo != null) {
                    addDepends = findDependencies(minfo, true);
                }
                break;
        }
        if (classRef != null) {
            ClassInfo clinf = classRef.getClassInfo();
            if (clinf != null) {
                if (clinf.getMethodInfo(clinitSig) != null) {
                    // don't add myself as dependency
                    if (!clinf.equals(method.getClassInfo())) {
                        depends.add(clinf);
                    }
                }
            }
        }
        if (addDepends != null) {
            for (Object addDepend : addDepends) {
                ClassInfo addCli = (ClassInfo) addDepend;
                if (addCli.equals(method.getClassInfo())) {
                    throw new JavaClassFormatError("cyclic indirect <clinit> dependency");
                }
                depends.add(addCli);
            }
        }
    }
    return depends;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) ClassRef(com.jopdesign.common.type.ClassRef) InstructionList(org.apache.bcel.generic.InstructionList) Constant(org.apache.bcel.classfile.Constant) InstructionFinder(org.apache.bcel.util.InstructionFinder) InstructionHandle(org.apache.bcel.generic.InstructionHandle) ConstantMethodInfo(com.jopdesign.common.type.ConstantMethodInfo) ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) CPInstruction(org.apache.bcel.generic.CPInstruction) JavaClassFormatError(com.jopdesign.common.misc.JavaClassFormatError) Iterator(java.util.Iterator) MethodInfo(com.jopdesign.common.MethodInfo) ConstantMethodInfo(com.jopdesign.common.type.ConstantMethodInfo) HashSet(java.util.HashSet) ClassInfo(com.jopdesign.common.ClassInfo)

Example 3 with JavaClassFormatError

use of com.jopdesign.common.misc.JavaClassFormatError in project jop by jop-devel.

the class InvokeSite method getInvokeeRef.

/**
     * Get the MethodRef to the referenced method. If the instruction is handled in java, return a reference
     * to the method which implements the instruction.
     * <p>
     * The MethodRef refers to the actual reference. {@link MethodRef#getMethodInfo()} resolves the actual
     * MethodInfo, which might be defined in a super class of the referenced method, if the method is inherited.
     * For invokespecial, the implementing method might even be defined in a subclass of the referenced method,
     * if resolveSuper is set to false, see {@link #isInvokeSuper()} for details.
     * </p>
     * <p>To find all possible implementations if the invocation is a virtual invoke (see {@link #isVirtual()}),
     * use {@link AppInfo#findImplementations(InvokeSite)}.</p>
     *
     * @see #isInvokeSuper()
     * @see AppInfo#findImplementations(InvokeSite)
     * @param resolveSuper if true, try to resolve the super method reference (see {@link #isInvokeSuper()}),
     *                     else return a reference to the method as it is defined by the instruction.
     * @return a method reference to the invokee method.
     */
public MethodRef getInvokeeRef(boolean resolveSuper) {
    Instruction instr = instruction.getInstruction();
    AppInfo appInfo = AppInfo.getSingleton();
    if (instr instanceof InvokeInstruction) {
        MethodRef ref = getReferencedMethod(invoker, (InvokeInstruction) instr);
        // need to check isInvokeSpecial here, since it is not checked by isSuperMethod!
        if (resolveSuper && isInvokeSpecial() && isSuperMethod(ref)) {
            ref = resolveInvokeSuper(ref);
        }
        return ref;
    }
    if (appInfo.getProcessorModel().isImplementedInJava(invoker, instr)) {
        return appInfo.getProcessorModel().getJavaImplementation(appInfo, invoker, instr).getMethodRef();
    }
    throw new JavaClassFormatError("InvokeSite handle does not refer to an invoke instruction: " + toString());
}
Also used : InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) MethodRef(com.jopdesign.common.type.MethodRef) JavaClassFormatError(com.jopdesign.common.misc.JavaClassFormatError) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) Instruction(org.apache.bcel.generic.Instruction) AppInfo(com.jopdesign.common.AppInfo)

Example 4 with JavaClassFormatError

use of com.jopdesign.common.misc.JavaClassFormatError in project jop by jop-devel.

the class MethodInfo method getImplementations.

/**
     * Get all non-abstract methods (including this method if it is not abstract) overriding this method.
     * @see AppInfo#findImplementations(CallString)
     * @see AppInfo#findImplementations(MethodRef)
     * @param checkAccess if false, find all non-abstract methods with same signature even if they do not
     *        override this method.
     * @return a collection of all implementations of this method.
     */
public List<MethodInfo> getImplementations(final boolean checkAccess) {
    final List<MethodInfo> implementations = new LinkedList<MethodInfo>();
    if (checkAccess && (isPrivate() || isStatic())) {
        if (isAbstract()) {
            throw new JavaClassFormatError("Method is private or static but abstract!: " + toString());
        }
        implementations.add(this);
        return implementations;
    }
    if ("<init>".equals(getShortName())) {
        if (isAbstract()) {
            throw new JavaClassFormatError("Found abstract constructor, this isn't right..: " + toString());
        }
        implementations.add(this);
        return implementations;
    }
    ClassVisitor visitor = new ClassVisitor() {

        public boolean visitClass(ClassInfo classInfo) {
            MethodInfo m = classInfo.getMethodInfo(getMethodSignature());
            if (m != null) {
                if (m.isPrivate() && !isPrivate()) {
                    // found an overriding method which is private .. this is interesting..
                    logger.error("Found private method " + m.getMethodSignature() + " in " + classInfo.getClassName() + " overriding non-private method in " + getClassInfo().getClassName());
                }
                if (!m.isAbstract() && (!checkAccess || m.overrides(MethodInfo.this, false))) {
                    implementations.add(m);
                }
            }
            return true;
        }

        public void finishClass(ClassInfo classInfo) {
        }
    };
    new ClassHierarchyTraverser(visitor).traverseDown(getClassInfo());
    return implementations;
}
Also used : JavaClassFormatError(com.jopdesign.common.misc.JavaClassFormatError) ClassHierarchyTraverser(com.jopdesign.common.graphutils.ClassHierarchyTraverser) ClassVisitor(com.jopdesign.common.graphutils.ClassVisitor) LinkedList(java.util.LinkedList)

Example 5 with JavaClassFormatError

use of com.jopdesign.common.misc.JavaClassFormatError in project jop by jop-devel.

the class AppInfo method tryLoadClass.

private ClassInfo tryLoadClass(String className) throws IOException {
    loadLogger.debug("Loading class " + className);
    InputStream is = classPath.getInputStream(className);
    JavaClass javaClass = new ClassParser(is, className).parse();
    is.close();
    if (javaClass.getMajor() > 50) {
        //      instruction (requires patching of BCEL code similar to Classpath and InstructionFinder)
        throw new JavaClassFormatError("Classfiles with versions 51.0 (Java 7) and above are currently not supported!");
    }
    return new ClassInfo(new ClassGen(javaClass));
}
Also used : JavaClass(org.apache.bcel.classfile.JavaClass) InputStream(java.io.InputStream) JavaClassFormatError(com.jopdesign.common.misc.JavaClassFormatError) ClassGen(org.apache.bcel.generic.ClassGen) ClassParser(org.apache.bcel.classfile.ClassParser)

Aggregations

JavaClassFormatError (com.jopdesign.common.misc.JavaClassFormatError)16 ClassInfo (com.jopdesign.common.ClassInfo)4 MethodInfo (com.jopdesign.common.MethodInfo)3 Iterator (java.util.Iterator)3 LinkedList (java.util.LinkedList)3 InstructionHandle (org.apache.bcel.generic.InstructionHandle)3 AppInfo (com.jopdesign.common.AppInfo)2 CallString (com.jopdesign.common.code.CallString)2 ClassHierarchyTraverser (com.jopdesign.common.graphutils.ClassHierarchyTraverser)2 ClassVisitor (com.jopdesign.common.graphutils.ClassVisitor)2 ConstantMethodInfo (com.jopdesign.common.type.ConstantMethodInfo)2 MethodRef (com.jopdesign.common.type.MethodRef)2 LinkedHashSet (java.util.LinkedHashSet)2 ConstantClass (org.apache.bcel.classfile.ConstantClass)2 ConstantFieldref (org.apache.bcel.classfile.ConstantFieldref)2 ConstantInterfaceMethodref (org.apache.bcel.classfile.ConstantInterfaceMethodref)2 ConstantMethodref (org.apache.bcel.classfile.ConstantMethodref)2 ConstantNameAndType (org.apache.bcel.classfile.ConstantNameAndType)2 ConstantString (org.apache.bcel.classfile.ConstantString)2 ConstantPoolGen (org.apache.bcel.generic.ConstantPoolGen)2