Search in sources :

Example 6 with MethodRef

use of com.jopdesign.common.type.MethodRef in project jop by jop-devel.

the class CallGraph method findImplementationContexts.

/**
     * For a given non-empty callstring, find all implementations which might get called by the last
     * invocation in the callstring, i.e. find all methods which might appear in the next entry of the
     * callstring.
     * <p>
     * This is only a lookup in the callgraph, and does not check if the invocation is a special invoke,
     * so if callstring length of the callgraph is zero, the results are not correct. Instead use
     * {@link AppInfo#findImplementations(CallString)} which handles all special cases and falls back
     * to the default callgraph.
     * </p>
     *
     * @param cs callstring of the invocation, must contain at least one invokesite.
     * @return a list of all methods which might get invoked by the top invocation of the callstring,
     *         with their callstrings.
     */
public Set<ExecutionContext> findImplementationContexts(CallString cs) {
    if (cs.length() == 0) {
        throw new AssertionError("findImplementationContexts: callstring must not be empty!");
    }
    InvokeSite invoke = cs.top();
    Set<ExecutionContext> methods = new LinkedHashSet<ExecutionContext>();
    MethodRef invokeeRef = invoke.getInvokeeRef();
    // if the invoke is not virtual, should we look it up in the graph anyway?
    // We could just return new ExecutionContext(invokee, cs);
    // But that's what AppInfo#findImplementations() is for, here we only lookup the callgraph,
    // but then we cannot have different callgraphs and perform precise lookups on all of them,
    // since that method only looks into the default callgraph (but why would we want multiple
    // graphs anyway?)
    // find all instances of possible invokers
    Set<ExecutionContext> invoker = getNodes(invoke.getInvoker());
    for (ExecutionContext invokeNode : invoker) {
        for (ContextEdge outEdge : callGraph.outgoingEdgesOf(invokeNode)) {
            CallString cgString = outEdge.getTarget().getCallString();
            // check if the target callstring matches the given callstring
            if (cgString.isEmpty()) {
                // target has no callstring, must at least override the invoked method
                if (invokeeRef.isInterfaceMethod() == Ternary.TRUE) {
                    // check if the receiver implements the interface..
                    if (outEdge.getTarget().getMethodInfo().implementsMethod(invokeeRef)) {
                        methods.add(outEdge.getTarget());
                    }
                } else {
                    if (outEdge.getTarget().getMethodInfo().overrides(invokeeRef, true)) {
                        methods.add(outEdge.getTarget());
                    }
                }
            } else {
                // if one of the callstrings is a suffix of the other, this context is a possible invocation
                if (cs.matches(cgString)) {
                    methods.add(outEdge.getTarget());
                }
            }
        }
    }
    return methods;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) MethodRef(com.jopdesign.common.type.MethodRef)

Example 7 with MethodRef

use of com.jopdesign.common.type.MethodRef in project jop by jop-devel.

the class InvokeSite method canInvoke.

/**
     * @param methodInfo a possible invokee
     * @return true if this invokeSite may invoke the method. Does not use the callgraph to check.
     *   For interface invoke sites this can return UNKNOWN if the class of the given method implementation
     *   does not implement the referenced interface.
     */
public Ternary canInvoke(MethodInfo methodInfo) {
    assert methodInfo != null;
    MethodRef invokeeRef = getInvokeeRef();
    MethodInfo method = invokeeRef.getMethodInfo();
    if (methodInfo.equals(method)) {
        return Ternary.TRUE;
    }
    if (!isVirtual()) {
        // and therefore cannot be invoked
        return Ternary.FALSE;
    }
    if (method == null) {
        return Ternary.UNKNOWN;
    }
    if (!methodInfo.getClassInfo().isSubclassOf(invokeeRef.getClassInfo())) {
        if (isInvokeInterface() && !methodInfo.getClassInfo().isInterface()) {
            // check the signature..
            if (!invokeeRef.getMethodSignature().equals(methodInfo.getMethodSignature())) {
                return Ternary.FALSE;
            }
            return Ternary.UNKNOWN;
        }
        return Ternary.FALSE;
    }
    return Ternary.valueOf(methodInfo.overrides(method, true));
}
Also used : MethodRef(com.jopdesign.common.type.MethodRef) MethodInfo(com.jopdesign.common.MethodInfo)

Example 8 with MethodRef

use of com.jopdesign.common.type.MethodRef in project jop by jop-devel.

the class UsedCodeFinder method visitReferences.

private void visitReferences(Set<String> refs) {
    for (String id : refs) {
        // The member IDs returned by the reference finder use a syntax which is
        // always unique, so if in doubt, we need to interpret it as a classname, not a fieldname
        MemberID sig = MemberID.parse(id, false);
        // find/load the corresponding classInfo
        ClassInfo cls = getClassInfo(sig);
        // class has been excluded from loading, skip this class
        if (cls == null) {
            continue;
        }
        // referenced class is used, visit it if it has not yet been visited, but skip its class members
        // Note that this class might be different than the class containing the class member
        markUsedMembers(cls, false);
        // check if this id specifies a class member (or just a class, in this case we are done)
        if (sig.hasMethodSignature()) {
            // It's a method! mark the method as used (implementations are marked later)
            MethodRef ref = appInfo.getMethodRef(sig);
            MethodInfo method = ref.getMethodInfo();
            // we keep the declarations. We mark it without following it and make it abstract later.
            if (method != null) {
                setMark(method, false);
            }
        } else if (sig.hasMemberName()) {
            // It's a field! No need to look in subclasses, fields are not virtual
            FieldRef ref = appInfo.getFieldRef(sig);
            FieldInfo field = ref.getFieldInfo();
            if (field != null) {
                markUsedMembers(field);
            }
        }
    }
}
Also used : MemberID(com.jopdesign.common.type.MemberID) MethodRef(com.jopdesign.common.type.MethodRef) FieldRef(com.jopdesign.common.type.FieldRef) MethodInfo(com.jopdesign.common.MethodInfo) FieldInfo(com.jopdesign.common.FieldInfo) ClassInfo(com.jopdesign.common.ClassInfo)

Example 9 with MethodRef

use of com.jopdesign.common.type.MethodRef in project jop by jop-devel.

the class RelinkInvokesuper method relinkInvokeSuper.

private void relinkInvokeSuper(InvokeSite is) {
    // this already resolves to the correct method..
    MethodRef invokee = is.getInvokeeRef();
    MethodInfo target = invokee.getMethodInfo();
    if (target == null) {
        // .. or not (class or method excluded or unknown)
        logger.warn("Cannot try to relink invokespecial to unknown super method " + invokee);
        return;
    }
    // now simply relink instruction (no need to check if it changes)
    int index = is.getInvoker().getClassInfo().addConstantInfo(new ConstantMethodInfo(invokee));
    if (!(is.getInvokeInstruction() instanceof INVOKESPECIAL)) {
        throw new JavaClassFormatError("Invokesuper is not an invokespecial instruction!");
    }
    is.getInvokeInstruction().setIndex(index);
}
Also used : ConstantMethodInfo(com.jopdesign.common.type.ConstantMethodInfo) MethodRef(com.jopdesign.common.type.MethodRef) JavaClassFormatError(com.jopdesign.common.misc.JavaClassFormatError) MethodInfo(com.jopdesign.common.MethodInfo) ConstantMethodInfo(com.jopdesign.common.type.ConstantMethodInfo) INVOKESPECIAL(org.apache.bcel.generic.INVOKESPECIAL)

Aggregations

MethodRef (com.jopdesign.common.type.MethodRef)9 MethodInfo (com.jopdesign.common.MethodInfo)6 FieldRef (com.jopdesign.common.type.FieldRef)4 Instruction (org.apache.bcel.generic.Instruction)4 InvokeInstruction (org.apache.bcel.generic.InvokeInstruction)4 FieldInfo (com.jopdesign.common.FieldInfo)3 ClassInfo (com.jopdesign.common.ClassInfo)2 MethodCode (com.jopdesign.common.MethodCode)2 InvokeSite (com.jopdesign.common.code.InvokeSite)2 AppInfoError (com.jopdesign.common.misc.AppInfoError)2 JavaClassFormatError (com.jopdesign.common.misc.JavaClassFormatError)2 MemberID (com.jopdesign.common.type.MemberID)2 LinkedHashSet (java.util.LinkedHashSet)2 ConstantPushInstruction (org.apache.bcel.generic.ConstantPushInstruction)2 FieldInstruction (org.apache.bcel.generic.FieldInstruction)2 InstructionHandle (org.apache.bcel.generic.InstructionHandle)2 LocalVariableInstruction (org.apache.bcel.generic.LocalVariableInstruction)2 AppInfo (com.jopdesign.common.AppInfo)1 CallString (com.jopdesign.common.code.CallString)1 MissingClassError (com.jopdesign.common.misc.MissingClassError)1