Java Code Examples for org.apache.bcel.generic.INVOKESTATIC

The following examples show how to use org.apache.bcel.generic.INVOKESTATIC. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: spotbugs   Source File: Hierarchy2.java    License: GNU Lesser General Public License v2.1 6 votes vote down vote up
/**
 * Find the declared exceptions for the method called by given instruction.
 *
 * @param inv
 *            the InvokeInstruction
 * @param cpg
 *            the ConstantPoolGen used by the class the InvokeInstruction
 *            belongs to
 * @return array of ObjectTypes of thrown exceptions, or null if we can't
 *         find the method implementation
 */
public static @CheckForNull ObjectType[] findDeclaredExceptions(InvokeInstruction inv, ConstantPoolGen cpg) {
    XMethod method = findInvocationLeastUpperBound(inv, cpg, inv instanceof INVOKESTATIC ? STATIC_METHOD : INSTANCE_METHOD);

    if (method == null) {
        return null;
    }
    String[] exceptions = method.getThrownExceptions();

    if (exceptions == null) {
        return new ObjectType[0];
    }

    ObjectType[] result = new ObjectType[exceptions.length];
    for (int i = 0; i < exceptions.length; ++i) {
        result[i] = ObjectTypeFactory.getInstance(ClassName.toDottedClassName(exceptions[i]));
    }
    return result;
}
 
Example 2
Source Project: commons-bcel   Source File: Pass3aVerifier.java    License: Apache License 2.0 6 votes vote down vote up
/** Checks if the constraints of operands of the said instruction(s) are satisfied. */
@Override
public void visitINVOKESTATIC(final INVOKESTATIC o) {
    try {
    // INVOKESTATIC is a LoadClass; the Class where the referenced method is declared in,
    // is therefore resolved/verified.
    // INVOKESTATIC is an InvokeInstruction, the argument and return types are resolved/verified,
    // too. So are the allowed method names.
    final String classname = o.getClassName(constantPoolGen);
    final JavaClass jc = Repository.lookupClass(classname);
    final Method m = getMethodRecursive(jc, o);
    if (m == null) {
        constraintViolated(o, "Referenced method '"+o.getMethodName(constantPoolGen)+"' with expected signature '"+
            o.getSignature(constantPoolGen) +"' not found in class '"+jc.getClassName()+"'.");
    } else if (! (m.isStatic())) { // implies it's not abstract, verified in pass 2.
        constraintViolated(o, "Referenced method '"+o.getMethodName(constantPoolGen)+"' has ACC_STATIC unset.");
    }

    } catch (final ClassNotFoundException e) {
    // FIXME: maybe not the best way to handle this
    throw new AssertionViolatedException("Missing class: " + e, e);
    }
}
 
Example 3
Source Project: spotbugs   Source File: SelfCalls.java    License: GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Is the given instruction a self-call?
 */
private Method isSelfCall(InvokeInstruction inv) {
    ConstantPoolGen cpg = classContext.getConstantPoolGen();
    JavaClass jclass = classContext.getJavaClass();

    String calledClassName = inv.getClassName(cpg);

    // FIXME: is it possible we would see a superclass name here?
    // Not a big deal for now, as we are mostly just interested in calls
    // to private methods, for which we will definitely see the right
    // called class name.
    if (!calledClassName.equals(jclass.getClassName())) {
        return null;
    }

    String calledMethodName = inv.getMethodName(cpg);
    String calledMethodSignature = inv.getSignature(cpg);
    boolean isStaticCall = (inv instanceof INVOKESTATIC);

    // Scan methods for one that matches.
    Method[] methods = jclass.getMethods();
    for (Method method : methods) {
        String methodName = method.getName();
        String signature = method.getSignature();
        boolean isStatic = method.isStatic();

        if (methodName.equals(calledMethodName) && signature.equals(calledMethodSignature) && isStatic == isStaticCall) {
            // This method looks like a match.
            return wantCallsFor(method) ? method : null;
        }
    }

    // Hmm...no matching method found.
    // This is almost certainly because the named method
    // was inherited from a superclass.
    LOG.debug("No method found for {}.{} : {}", calledClassName, calledMethodName, calledMethodSignature);
    return null;
}
 
Example 4
/**
 * Use this to screen out methods that do not contain invocations.
 */
public boolean prescreen(ClassContext classContext, Method method) {
    BitSet bytecodeSet = classContext.getBytecodeSet(method);
    return bytecodeSet != null
            && (bytecodeSet.get(Const.INVOKEINTERFACE) || bytecodeSet.get(Const.INVOKEVIRTUAL)
                    || bytecodeSet.get(Const.INVOKESPECIAL) || bytecodeSet.get(Const.INVOKESTATIC) || bytecodeSet
                            .get(Const.INVOKENONVIRTUAL));
}
 
Example 5
@Override
public void visitINVOKESTATIC(INVOKESTATIC obj) {
    if (returnsString(obj)) {
        consumeStack(obj);

        String className = obj.getClassName(getCPG());
        if (Values.DOTTED_JAVA_LANG_STRING.equals(className)) {
            pushValue(dynamicStringTypeInstance);
        } else {
            pushReturnType(obj);
        }
    } else {
        super.visitINVOKESTATIC(obj);
    }
}
 
Example 6
public MethodDescriptor getInvokedMethod(ConstantPoolGen cpg, InvokeInstruction inv) {
    String invoked = inv.getClassName(cpg);
    String methodName = inv.getMethodName(cpg);
    String methodSig = inv.getSignature(cpg);
    MethodDescriptor invokedMethod =
            DescriptorFactory.instance().getMethodDescriptor(ClassName.toSlashedClassName(invoked), methodName, methodSig,
                    inv instanceof INVOKESTATIC);
    return invokedMethod;
}
 
Example 7
private boolean prescreen(ClassContext classContext, Method method) {
    BitSet bytecodeSet = classContext.getBytecodeSet(method);
    if (bytecodeSet == null
            // method must acquire a lock
            || (!bytecodeSet.get(Const.MONITORENTER) && !method.isSynchronized())) {
        return false;
    }

    // and contain a static method invocation
    return bytecodeSet.get(Const.INVOKESTATIC);
}
 
Example 8
private void analyzeMethod(ClassContext classContext, Method method) throws CFGBuilderException, DataflowAnalysisException {
    // System.out.println("Checking " + method);

    CFG cfg = classContext.getCFG(method);
    LockDataflow lockDataflow = classContext.getLockDataflow(method);

    for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) {
        Location location = i.next();
        Instruction ins = location.getHandle().getInstruction();

        if (!(ins instanceof INVOKESTATIC)) {
            continue;
        }

        if (!isSleep((INVOKESTATIC) ins, classContext.getConstantPoolGen())) {
            continue;
        }

        // System.out.println("Found sleep at " + location.getHandle());

        LockSet lockSet = lockDataflow.getFactAtLocation(location);
        if (lockSet.getNumLockedObjects() > 0) {
            bugAccumulator.accumulateBug(
                    new BugInstance(this, "SWL_SLEEP_WITH_LOCK_HELD", NORMAL_PRIORITY).addClassAndMethod(
                            classContext.getJavaClass(), method), classContext, method, location);
        }
    }
    bugAccumulator.reportAccumulatedBugs();
}
 
Example 9
private boolean isSleep(INVOKESTATIC ins, ConstantPoolGen cpg) {
    String className = ins.getClassName(cpg);
    if (!"java.lang.Thread".equals(className)) {
        return false;
    }
    String methodName = ins.getMethodName(cpg);
    String signature = ins.getSignature(cpg);

    return "sleep".equals(methodName) && ("(J)V".equals(signature) || "(JI)V".equals(signature));
}
 
Example 10
@Override
public void visitINVOKESTATIC(INVOKESTATIC ins) {
    // Find calls to System.exit(), since this effectively terminates the
    // basic block.

    String className = ins.getClassName(constPoolGen);
    String methodName = ins.getName(constPoolGen);
    String methodSig = ins.getSignature(constPoolGen);

    if ("java.lang.System".equals(className) && "exit".equals(methodName) && "(I)V".equals(methodSig)) {
        isExit = true;
    }
}
 
Example 11
public void visitInvokeOnException(Instruction obj) {
    if (!REDUNDANT_LOAD_ELIMINATION || !getFrame().hasAvailableLoads()) {
        return;
    }
    if (obj instanceof INVOKEDYNAMIC) {
        killLoadsOfObjectsPassed((INVOKEDYNAMIC) obj);
        return;
    }
    InvokeInstruction inv = (InvokeInstruction) obj;
    if ((inv instanceof INVOKEINTERFACE || inv instanceof INVOKEVIRTUAL)
            && inv.getMethodName(cpg).toLowerCase().indexOf("lock") >= 0) {
        // Don't know what this method invocation is doing.
        // Kill all loads.
        getFrame().killAllLoads();
        return;
    }
    if (inv instanceof INVOKEVIRTUAL && "cast".equals(inv.getMethodName(cpg)) && "java.lang.Class".equals(inv.getClassName(cpg))) {
        // No-op
        return;
    }
    if (inv instanceof INVOKESTATIC) {
        String methodName = inv.getName(cpg);
        if (("forName".equals(methodName) && "java.lang.Class".equals(inv.getClassName(cpg)) || "class$".equals(methodName))
                && "(Ljava/lang/String;)Ljava/lang/Class;".equals(inv.getSignature(cpg))
                || (Hierarchy.isInnerClassAccess((INVOKESTATIC) inv, cpg) && loadedFieldSet.getField(handle) != null)) {
            return;
        }
    }

    killLoadsOfObjectsPassed(inv);
    if (inv instanceof INVOKESTATIC) {
        getFrame().killAllLoadsOf(null);
    }
}
 
Example 12
Source Project: spotbugs   Source File: Hierarchy.java    License: GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Determine if given Instruction is a monitor wait.
 *
 * @param ins
 *            the Instruction
 * @param cpg
 *            the ConstantPoolGen for the Instruction
 *
 * @return true if the instruction is a monitor wait, false if not
 */
public static boolean isMonitorWait(Instruction ins, ConstantPoolGen cpg) {
    if (!(ins instanceof InvokeInstruction)) {
        return false;
    }
    if (ins.getOpcode() == Const.INVOKESTATIC) {
        return false;
    }

    InvokeInstruction inv = (InvokeInstruction) ins;
    String methodName = inv.getMethodName(cpg);
    String methodSig = inv.getSignature(cpg);

    return isMonitorWait(methodName, methodSig);
}
 
Example 13
Source Project: spotbugs   Source File: Hierarchy.java    License: GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Determine if given Instruction is a monitor wait.
 *
 * @param ins
 *            the Instruction
 * @param cpg
 *            the ConstantPoolGen for the Instruction
 *
 * @return true if the instruction is a monitor wait, false if not
 */
public static boolean isMonitorNotify(Instruction ins, ConstantPoolGen cpg) {
    if (!(ins instanceof InvokeInstruction)) {
        return false;
    }
    if (ins.getOpcode() == Const.INVOKESTATIC) {
        return false;
    }

    InvokeInstruction inv = (InvokeInstruction) ins;
    String methodName = inv.getMethodName(cpg);
    String methodSig = inv.getSignature(cpg);

    return isMonitorNotify(methodName, methodSig);
}
 
Example 14
Source Project: spotbugs   Source File: Hierarchy.java    License: GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Get the InnerClassAccess for access method called by given INVOKESTATIC.
 *
 * @param inv
 *            the INVOKESTATIC instruction
 * @param cpg
 *            the ConstantPoolGen for the method
 * @return the InnerClassAccess, or null if the instruction is not an
 *         inner-class access
 */
public static InnerClassAccess getInnerClassAccess(INVOKESTATIC inv, ConstantPoolGen cpg) throws ClassNotFoundException {

    String className = inv.getClassName(cpg);
    String methodName = inv.getName(cpg);
    String methodSig = inv.getSignature(cpg);

    InnerClassAccess access = AnalysisContext.currentAnalysisContext().getInnerClassAccessMap()
            .getInnerClassAccess(className, methodName);
    return (access != null && access.getMethodSignature().equals(methodSig)) ? access : null;
}
 
Example 15
@Override
public void visitINVOKESTATIC(INVOKESTATIC obj) {
    visitInvoke(obj);
}
 
Example 16
private void inspectLocation(JavaClass jclass, ConstantPoolGen cpg, Method method, MethodGen methodGen,
        LinkedList<WarningWithProperties> refComparisonList, LinkedList<WarningWithProperties> stringComparisonList,
        RefComparisonTypeFrameModelingVisitor visitor, TypeDataflow typeDataflow, Location location)
        throws DataflowAnalysisException {
    Instruction ins = location.getHandle().getInstruction();
    short opcode = ins.getOpcode();
    if (opcode == Const.IF_ACMPEQ || opcode == Const.IF_ACMPNE) {
        checkRefComparison(location, jclass, method, methodGen, visitor, typeDataflow, stringComparisonList,
                refComparisonList);
    } else if (ins instanceof InvokeInstruction) {
        InvokeInstruction inv = (InvokeInstruction) ins;
        boolean isStatic = inv instanceof INVOKESTATIC;
        @DottedClassName
        String className = inv.getClassName(cpg);
        String methodName = inv.getMethodName(cpg);
        String methodSig = inv.getSignature(cpg);
        if ("assertSame".equals(methodName) && "(Ljava/lang/Object;Ljava/lang/Object;)V".equals(methodSig)) {
            checkRefComparison(location, jclass, method, methodGen, visitor, typeDataflow, stringComparisonList,
                    refComparisonList);
        } else if ("assertFalse".equals(methodName) && "(Z)V".equals(methodSig)) {
            SourceLineAnnotation lastLocation = bugAccumulator.getLastBugLocation();
            InstructionHandle prevHandle = location.getHandle().getPrev();
            if (lastLocation != null && prevHandle != null && lastLocation.getEndBytecode() == prevHandle.getPosition()) {
                bugAccumulator.forgetLastBug();
                if (DEBUG) {
                    System.out.println("Forgetting last bug due to call to " + className + "." + methodName);
                }
            }

        } else {
            boolean equalsMethod = !isStatic && "equals".equals(methodName) && "(Ljava/lang/Object;)Z".equals(methodSig)
                    || isStatic && "assertEquals".equals(methodName)
                            && "(Ljava/lang/Object;Ljava/lang/Object;)V".equals(methodSig)
                    || isStatic && "equal".equals(methodName) && "(Ljava/lang/Object;Ljava/lang/Object;)Z".equals(methodSig)
                            && "com.google.common.base.Objects".equals(className)
                    || isStatic && "equals".equals(methodName) && "(Ljava/lang/Object;Ljava/lang/Object;)Z".equals(methodSig)
                            && "java.util.Objects".equals(className);

            if (equalsMethod) {
                checkEqualsComparison(location, jclass, method, methodGen, cpg, typeDataflow);
            }
        }
    }

}
 
Example 17
private void checkRefComparison(Location location, JavaClass jclass, Method method, MethodGen methodGen,
        RefComparisonTypeFrameModelingVisitor visitor, TypeDataflow typeDataflow,
        List<WarningWithProperties> stringComparisonList, List<WarningWithProperties> refComparisonList)
        throws DataflowAnalysisException {

    InstructionHandle handle = location.getHandle();

    TypeFrame frame = typeDataflow.getFactAtLocation(location);
    if (frame.getStackDepth() < 2) {
        throw new DataflowAnalysisException("Stack underflow", methodGen, handle);
    }

    int numSlots = frame.getNumSlots();
    Type lhsType = frame.getValue(numSlots - 2);
    Type rhsType = frame.getValue(numSlots - 1);

    if (lhsType instanceof NullType || rhsType instanceof NullType) {
        return;
    }
    if (lhsType instanceof ReferenceType && rhsType instanceof ReferenceType) {
        IncompatibleTypes result = IncompatibleTypes.getPriorityForAssumingCompatible(lhsType, rhsType, true);
        if (result != IncompatibleTypes.SEEMS_OK && result != IncompatibleTypes.UNCHECKED) {
            String sourceFile = jclass.getSourceFileName();

            boolean isAssertSame = handle.getInstruction() instanceof INVOKESTATIC;
            if (isAssertSame) {
                if (testingEnabled) {
                    bugAccumulator.accumulateBug(
                            new BugInstance(this, "TESTING", result.getPriority())
                                    .addClassAndMethod(methodGen, sourceFile)
                                    .addString("Calling assertSame with two distinct objects")
                                    .addFoundAndExpectedType(rhsType, lhsType)
                                    .addSomeSourceForTopTwoStackValues(classContext, method, location),
                            SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, handle));
                }
            } else {
                bugAccumulator.accumulateBug(
                        new BugInstance(this, "EC_UNRELATED_TYPES_USING_POINTER_EQUALITY", result.getPriority())
                                .addClassAndMethod(methodGen, sourceFile).addFoundAndExpectedType(rhsType, lhsType)
                                .addSomeSourceForTopTwoStackValues(classContext, method, location),
                        SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, handle));
            }
            return;
        }
        if (lhsType.equals(Type.OBJECT) && rhsType.equals(Type.OBJECT)) {
            return;
        }
        String lhs = SignatureConverter.convert(lhsType.getSignature());
        String rhs = SignatureConverter.convert(rhsType.getSignature());

        if (Values.DOTTED_JAVA_LANG_STRING.equals(lhs) || Values.DOTTED_JAVA_LANG_STRING.equals(rhs)) {
            handleStringComparison(jclass, method, methodGen, visitor, stringComparisonList, location, lhsType, rhsType);
        } else if (suspiciousSet.contains(lhs)) {
            handleSuspiciousRefComparison(jclass, method, methodGen, refComparisonList, location, lhs,
                    (ReferenceType) lhsType, (ReferenceType) rhsType);
        } else if (suspiciousSet.contains(rhs)) {
            handleSuspiciousRefComparison(jclass, method, methodGen, refComparisonList, location, rhs,
                    (ReferenceType) lhsType, (ReferenceType) rhsType);
        }
    }
}
 
Example 18
/**
 * Determine whether or not the the given method is a getter method. I.e.,
 * if it just returns the value of an instance field.
 *
 * @param classContext
 *            the ClassContext for the class containing the method
 * @param method
 *            the method
 */
public static boolean isGetterMethod(ClassContext classContext, Method method) {
    MethodGen methodGen = classContext.getMethodGen(method);
    if (methodGen == null) {
        return false;
    }
    InstructionList il = methodGen.getInstructionList();
    // System.out.println("Checking getter method: " + method.getName());
    if (il.getLength() > 60) {
        return false;
    }

    int count = 0;
    for (InstructionHandle ih : il) {
        switch (ih.getInstruction().getOpcode()) {
        case Const.GETFIELD:
            count++;
            if (count > 1) {
                return false;
            }
            break;
        case Const.PUTFIELD:
        case Const.BALOAD:
        case Const.CALOAD:
        case Const.DALOAD:
        case Const.FALOAD:
        case Const.IALOAD:
        case Const.LALOAD:
        case Const.SALOAD:
        case Const.AALOAD:
        case Const.BASTORE:
        case Const.CASTORE:
        case Const.DASTORE:
        case Const.FASTORE:
        case Const.IASTORE:
        case Const.LASTORE:
        case Const.SASTORE:
        case Const.AASTORE:
        case Const.PUTSTATIC:
            return false;
        case Const.INVOKESTATIC:
        case Const.INVOKEVIRTUAL:
        case Const.INVOKEINTERFACE:
        case Const.INVOKESPECIAL:
        case Const.GETSTATIC:
            // no-op

        }
    }
    // System.out.println("Found getter method: " + method.getName());
    return true;
}
 
Example 19
public MethodDescriptor(InvokeInstruction iins, ConstantPoolGen cpg) {
    super(ClassName.toSlashedClassName(iins.getClassName(cpg)), iins.getMethodName(cpg), iins.getSignature(cpg), iins instanceof INVOKESTATIC);
}
 
Example 20
@Override
public void visitINVOKESTATIC(INVOKESTATIC inv) {
    handleInvoke(inv);
}
 
Example 21
Source Project: spotbugs   Source File: Hierarchy.java    License: GNU Lesser General Public License v2.1 4 votes vote down vote up
public static @CheckForNull JavaClassAndMethod findInvocationLeastUpperBound(InvokeInstruction inv, ConstantPoolGen cpg,
        JavaClassAndMethodChooser methodChooser) throws ClassNotFoundException {

    if (DEBUG_METHOD_LOOKUP) {
        System.out.println("Find prototype method for " + SignatureConverter.convertMethodSignature(inv, cpg));
    }

    short opcode = inv.getOpcode();

    if (opcode == Const.INVOKESTATIC) {
        if (methodChooser == INSTANCE_METHOD) {
            return null;
        }
    } else {
        if (methodChooser == STATIC_METHOD) {
            return null;
        }
    }

    // Find the method
    if (opcode == Const.INVOKESPECIAL) {
        // Non-virtual dispatch
        return findExactMethod(inv, cpg, methodChooser);
    }
    if (opcode == Const.INVOKEDYNAMIC) {
        return null;
    }
    String className = inv.getClassName(cpg);
    String methodName = inv.getName(cpg);
    String methodSig = inv.getSignature(cpg);
    if (DEBUG_METHOD_LOOKUP) {
        System.out.println("[Class name is " + className + "]");
        System.out.println("[Method name is " + methodName + "]");
        System.out.println("[Method signature is " + methodSig + "]");
    }

    if (className.startsWith(Values.SIG_ARRAY_PREFIX)) {
        // Java 1.5 allows array classes to appear as the class name
        className = Values.DOTTED_JAVA_LANG_OBJECT;
    }

    JavaClass jClass = Repository.lookupClass(className);
    return findInvocationLeastUpperBound(jClass, methodName, methodSig, methodChooser,
            opcode == Const.INVOKEINTERFACE);
}
 
Example 22
Source Project: spotbugs   Source File: Hierarchy.java    License: GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Resolve possible method call targets. This works for both static and
 * instance method calls.
 *
 * @param invokeInstruction
 *            the InvokeInstruction
 * @param typeFrame
 *            the TypeFrame containing the types of stack values
 * @param cpg
 *            the ConstantPoolGen
 * @return Set of methods which might be called
 * @throws DataflowAnalysisException
 * @throws ClassNotFoundException
 */
public static Set<JavaClassAndMethod> resolveMethodCallTargets(InvokeInstruction invokeInstruction, TypeFrame typeFrame,
        ConstantPoolGen cpg) throws DataflowAnalysisException, ClassNotFoundException {

    short opcode = invokeInstruction.getOpcode();

    if (opcode == Const.INVOKESTATIC) {
        HashSet<JavaClassAndMethod> result = new HashSet<>();
        JavaClassAndMethod targetMethod = findInvocationLeastUpperBound(invokeInstruction, cpg, CONCRETE_METHOD);
        if (targetMethod != null) {
            result.add(targetMethod);
        }
        return result;
    }

    if (!typeFrame.isValid()) {
        return new HashSet<>();
    }

    Type receiverType;
    boolean receiverTypeIsExact;

    if (opcode == Const.INVOKESPECIAL) {
        // invokespecial instructions are dispatched to EXACTLY
        // the class specified by the instruction
        receiverType = ObjectTypeFactory.getInstance(invokeInstruction.getClassName(cpg));
        receiverTypeIsExact = false; // Doesn't actually matter
    } else if (opcode == Const.INVOKEDYNAMIC) {
        // XXX handle INVOKEDYNAMIC
        return new HashSet<>();
    } else {
        // For invokevirtual and invokeinterface instructions, we have
        // virtual dispatch. By taking the receiver type (which may be a
        // subtype of the class specified by the instruction),
        // we may get a more precise set of call targets.
        int instanceStackLocation = typeFrame.getInstanceStackLocation(invokeInstruction, cpg);
        receiverType = typeFrame.getStackValue(instanceStackLocation);
        if (!(receiverType instanceof ReferenceType)) {
            return new HashSet<>();
        }
        receiverTypeIsExact = typeFrame.isExact(instanceStackLocation);
    }
    if (DEBUG_METHOD_LOOKUP) {
        System.out.println("[receiver type is " + receiverType + ", " + (receiverTypeIsExact ? "exact]" : " not exact]"));
    }

    return resolveMethodCallTargets((ReferenceType) receiverType, invokeInstruction, cpg, receiverTypeIsExact);
}
 
Example 23
Source Project: spotbugs   Source File: Hierarchy.java    License: GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Resolve possible instance method call targets.
 *
 * @param receiverType
 *            type of the receiver object
 * @param invokeInstruction
 *            the InvokeInstruction
 * @param cpg
 *            the ConstantPoolGen
 * @param receiverTypeIsExact
 *            if true, the receiver type is known exactly, which should
 *            allow a precise result
 * @return Set of methods which might be called
 * @throws ClassNotFoundException
 */
public static Set<JavaClassAndMethod> resolveMethodCallTargets(ReferenceType receiverType,
        InvokeInstruction invokeInstruction, ConstantPoolGen cpg, boolean receiverTypeIsExact) throws ClassNotFoundException {
    HashSet<JavaClassAndMethod> result = new HashSet<>();

    if (invokeInstruction.getOpcode() == Const.INVOKESTATIC) {
        throw new IllegalArgumentException();
    }

    String methodName = invokeInstruction.getName(cpg);
    String methodSig = invokeInstruction.getSignature(cpg);

    // Array method calls aren't virtual.
    // They should just resolve to Object methods.
    if (receiverType instanceof ArrayType) {
        JavaClass javaLangObject = AnalysisContext.currentAnalysisContext().lookupClass(Values.DOTTED_JAVA_LANG_OBJECT);
        JavaClassAndMethod classAndMethod = findMethod(javaLangObject, methodName, methodSig, INSTANCE_METHOD);
        if (classAndMethod != null) {
            result.add(classAndMethod);
        }
        return result;
    }

    if (receiverType instanceof NullType) {
        return Collections.<JavaClassAndMethod>emptySet();
    }
    AnalysisContext analysisContext = AnalysisContext.currentAnalysisContext();

    // Get the receiver class.
    String receiverClassName = ((ObjectType) receiverType).getClassName();
    JavaClass receiverClass = analysisContext.lookupClass(receiverClassName);
    ClassDescriptor receiverDesc = DescriptorFactory.createClassDescriptorFromDottedClassName(receiverClassName);

    // Figure out the upper bound for the method.
    // This is what will be called if this is not a virtual call site.
    JavaClassAndMethod upperBound = findMethod(receiverClass, methodName, methodSig, CONCRETE_METHOD);
    if (upperBound == null) {
        upperBound = findInvocationLeastUpperBound(receiverClass, methodName, methodSig, CONCRETE_METHOD, false);
    }
    if (upperBound != null) {
        if (DEBUG_METHOD_LOOKUP) {
            System.out.println("Adding upper bound: "
                    + SignatureConverter.convertMethodSignature(upperBound.getJavaClass(), upperBound.getMethod()));
        }
        result.add(upperBound);
    }

    // Is this a virtual call site?
    boolean virtualCall = (invokeInstruction.getOpcode() == Const.INVOKEVIRTUAL || invokeInstruction.getOpcode() == Const.INVOKEINTERFACE)
            && (upperBound == null || !upperBound.getJavaClass().isFinal() && !upperBound.getMethod().isFinal())
            && !receiverTypeIsExact;

    if (virtualCall) {
        if (!Values.DOTTED_JAVA_LANG_OBJECT.equals(receiverClassName)) {

            // This is a true virtual call: assume that any concrete
            // subtype method may be called.
            Set<ClassDescriptor> subTypeSet = analysisContext.getSubtypes2().getSubtypes(receiverDesc);
            for (ClassDescriptor subtype : subTypeSet) {
                XMethod concreteSubtypeMethod = findMethod(subtype, methodName, methodSig, false);
                if (concreteSubtypeMethod != null && (concreteSubtypeMethod.getAccessFlags() & Const.ACC_ABSTRACT) == 0) {
                    result.add(new JavaClassAndMethod(concreteSubtypeMethod));
                }
            }
            if (false && subTypeSet.size() > 500) {
                new RuntimeException(receiverClassName + " has " + subTypeSet.size() + " subclasses, " + result.size()
                        + " of which implement " + methodName + methodSig + " " + invokeInstruction)
                                .printStackTrace(System.out);
            }

        }
    }
    return result;
}
 
Example 24
Source Project: spotbugs   Source File: Hierarchy2.java    License: GNU Lesser General Public License v2.1 4 votes vote down vote up
public static @CheckForNull XMethod findInvocationLeastUpperBound(InvokeInstruction inv, ConstantPoolGen cpg,
        JavaClassAndMethodChooser methodChooser) {

    if (DEBUG_METHOD_LOOKUP) {
        System.out.println("Find prototype method for " + SignatureConverter.convertMethodSignature(inv, cpg));
    }

    short opcode = inv.getOpcode();

    if (opcode == Const.INVOKESTATIC) {
        if (methodChooser == INSTANCE_METHOD) {
            return null;
        }
    } else {
        if (methodChooser == STATIC_METHOD) {
            return null;
        }
    }

    // Find the method
    if (opcode == Const.INVOKESPECIAL) {
        // Non-virtual dispatch
        return findExactMethod(inv, cpg, methodChooser);
    } else {
        String className = inv.getClassName(cpg);
        String methodName = inv.getName(cpg);
        String methodSig = inv.getSignature(cpg);
        if (DEBUG_METHOD_LOOKUP) {
            System.out.println("[Class name is " + className + "]");
            System.out.println("[Method name is " + methodName + "]");
            System.out.println("[Method signature is " + methodSig + "]");
        }

        if (className.startsWith(Values.SIG_ARRAY_PREFIX)) {
            // Java 1.5 allows array classes to appear as the class name
            className = Values.DOTTED_JAVA_LANG_OBJECT;
        }

        try {
            return thisOrNothing(
                    findInvocationLeastUpperBound(getXClassFromDottedClassName(className), methodName, methodSig,
                            opcode == Const.INVOKESTATIC, opcode == Const.INVOKEINTERFACE), methodChooser);
        } catch (CheckedAnalysisException e) {
            return null;
        }

    }
}
 
Example 25
Source Project: spotbugs   Source File: Hierarchy2.java    License: GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Resolve possible method call targets. This works for both static and
 * instance method calls.
 *
 * @param invokeInstruction
 *            the InvokeInstruction
 * @param typeFrame
 *            the TypeFrame containing the types of stack values
 * @param cpg
 *            the ConstantPoolGen
 * @return Set of methods which might be called
 * @throws DataflowAnalysisException
 * @throws ClassNotFoundException
 */
public static @Nonnull Set<XMethod> resolveMethodCallTargets(InvokeInstruction invokeInstruction, TypeFrame typeFrame, ConstantPoolGen cpg)
        throws DataflowAnalysisException, ClassNotFoundException {

    short opcode = invokeInstruction.getOpcode();

    if (opcode == Const.INVOKESTATIC) {
        return Util.emptyOrNonnullSingleton(findInvocationLeastUpperBound(invokeInstruction, cpg, STATIC_METHOD));
    }

    if (!typeFrame.isValid()) {
        return Collections.<XMethod>emptySet();
    }

    // XXX handle INVOKEDYNAMIC
    if (opcode == Const.INVOKEDYNAMIC) {
        return Collections.<XMethod>emptySet();
    }

    Type receiverType;
    boolean receiverTypeIsExact;

    if (opcode == Const.INVOKESPECIAL) {
        // invokespecial instructions are dispatched to EXACTLY
        // the class specified by the instruction
        receiverType = ObjectTypeFactory.getInstance(invokeInstruction.getClassName(cpg));
        receiverTypeIsExact = false; // Doesn't actually matter
    } else {
        // For invokevirtual and invokeinterface instructions, we have
        // virtual dispatch. By taking the receiver type (which may be a
        // subtype of the class specified by the instruction),
        // we may get a more precise set of call targets.
        int instanceStackLocation = typeFrame.getInstanceStackLocation(invokeInstruction, cpg);
        receiverType = typeFrame.getStackValue(instanceStackLocation);
        if (!(receiverType instanceof ReferenceType)) {
            return Collections.<XMethod>emptySet();
        }
        receiverTypeIsExact = typeFrame.isExact(instanceStackLocation);
    }
    if (DEBUG_METHOD_LOOKUP) {
        System.out.println("[receiver type is " + receiverType + ", " + (receiverTypeIsExact ? "exact]" : " not exact]"));
    }

    return resolveMethodCallTargets((ReferenceType) receiverType, invokeInstruction, cpg, receiverTypeIsExact);
}
 
Example 26
@Override
public void visitINVOKESTATIC(INVOKESTATIC obj) {
    handleInvoke(obj);
}
 
Example 27
/** @see org.apache.bcel.generic.Visitor */
public void visitINVOKESTATIC(INVOKESTATIC aINVOKESTATIC)
{
    addInvokeReference(
        new InvokeReference(aINVOKESTATIC, mCurrentPoolGen));
}
 
Example 28
/** @see org.apache.bcel.generic.Visitor */
public void visitINVOKESTATIC(INVOKESTATIC aINVOKESTATIC)
{
    addInvokeReference(
        new InvokeReference(aINVOKESTATIC, mCurrentPoolGen));
}
 
Example 29
Source Project: commons-bcel   Source File: ASTFunAppl.java    License: Apache License 2.0 4 votes vote down vote up
/**
   * Fifth pass, produce Java byte code.
   */
  @Override
  public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
    final String     fname = name.getName();
//    Function   f     = function;
    //ASTIdent   fun   = f.getName();
//    ASTIdent[] args  = f.getArgs();
    final String     class_name = method.getClassName();

    if(fname.equals("READ")) {
        il.append(new INVOKESTATIC(cp.addMethodref(class_name,
                                                 "_readInt",
                                                 "()I")));
    } else if(fname.equals("WRITE")) {
      exprs[0].byte_code(il, method, cp);
      ASTFunDecl.pop();
      il.append(new INVOKESTATIC(cp.addMethodref(class_name,
                                                 "_writeInt",
                                                 "(I)I")));
    }
    else { // Normal function
      final int size    = exprs.length;
      Type[] argv = null;

      if(exprs != null) {
        argv = new Type[size];

        for(int i=0; i < size; i++) {
          argv[i] = Type.INT;
          exprs[i].byte_code(il, method, cp);
        }

        //ASTFunDecl.push(size);
      }

      ASTFunDecl.pop(size);

      // Function call
      il.append(new INVOKESTATIC(cp.addMethodref(class_name,
                                                 fname,
                                                 Type.getMethodSignature(Type.INT,
                                                                         argv))));
    }

    ASTFunDecl.push();
  }
 
Example 30
/**
 * Get the inner class access object for given invokestatic instruction.
 * Returns null if the called method is not an inner class access.
 *
 * @param inv
 *            the invokestatic instruction
 * @param cpg
 *            the ConstantPoolGen for the method
 * @return the InnerClassAccess, or null if the call is not an inner class
 *         access
 */
public InnerClassAccess getInnerClassAccess(INVOKESTATIC inv, ConstantPoolGen cpg) throws ClassNotFoundException {
    String methodName = inv.getMethodName(cpg);
    if (methodName.startsWith("access$")) {
        String className = inv.getClassName(cpg);

        return getInnerClassAccess(className, methodName);
    }
    return null;
}