Java Code Examples for org.apache.bcel.Const#INVOKEDYNAMIC

The following examples show how to use org.apache.bcel.Const#INVOKEDYNAMIC . 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 File: RepeatedConditionals.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
private boolean hasSideEffect(int seen) {
    if (seen == Const.INVOKEVIRTUAL || seen == Const.INVOKESPECIAL || seen == Const.INVOKEINTERFACE || seen == Const.INVOKESTATIC) {
        return noSideEffectMethods.is(getMethodDescriptorOperand(), MethodSideEffectStatus.SE, MethodSideEffectStatus.OBJ);
    }
    return isRegisterStore() || isReturn(seen) || isSwitch(seen) || seen == Const.INVOKEDYNAMIC || seen == Const.PUTFIELD
            || seen == Const.PUTSTATIC;
}
 
Example 2
Source File: InstructionFactory.java    From commons-bcel with Apache License 2.0 5 votes vote down vote up
/** Create an invoke instruction. (Except for invokedynamic.)
 *
 * @param class_name name of the called class
 * @param name name of the called method
 * @param ret_type return type of method
 * @param arg_types argument types of method
 * @param kind how to invoke: INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, or INVOKESPECIAL
 * @param use_interface force use of InterfaceMethodref
 * @return A new InvokeInstruction.
 * @since 6.5.0
 */
public InvokeInstruction createInvoke( final String class_name, final String name, final Type ret_type,
    final Type[] arg_types, final short kind, final boolean use_interface) {
    if (kind != Const.INVOKESPECIAL && kind != Const.INVOKEVIRTUAL && kind != Const.INVOKESTATIC
        && kind != Const.INVOKEINTERFACE && kind != Const.INVOKEDYNAMIC) {
        throw new IllegalArgumentException("Unknown invoke kind: " + kind);
    }
    int index;
    int nargs = 0;
    final String signature = Type.getMethodSignature(ret_type, arg_types);
    for (final Type arg_type : arg_types) {
        nargs += arg_type.getSize();
    }
    if (use_interface) {
        index = cp.addInterfaceMethodref(class_name, name, signature);
    } else {
        index = cp.addMethodref(class_name, name, signature);
    }
    switch (kind) {
    case Const.INVOKESPECIAL:
        return new INVOKESPECIAL(index);
    case Const.INVOKEVIRTUAL:
        return new INVOKEVIRTUAL(index);
    case Const.INVOKESTATIC:
        return new INVOKESTATIC(index);
    case Const.INVOKEINTERFACE:
        return new INVOKEINTERFACE(index, nargs + 1);
    case Const.INVOKEDYNAMIC:
        return new INVOKEDYNAMIC(index);
    default:
        // Can't happen
        throw new IllegalStateException("Unknown invoke kind: " + kind);
    }
}
 
Example 3
Source File: InvokeInstruction.java    From commons-bcel with Apache License 2.0 5 votes vote down vote up
/**
 * Also works for instructions whose stack effect depends on the
 * constant pool entry they reference.
 * @return Number of words consumed from stack by this instruction
 */
@Override
public int consumeStack( final ConstantPoolGen cpg ) {
    int sum;
    if ((super.getOpcode() == Const.INVOKESTATIC) || (super.getOpcode() == Const.INVOKEDYNAMIC)) {
        sum = 0;
    } else {
        sum = 1; // this reference
    }

    final String signature = getSignature(cpg);
    sum += Type.getArgumentTypesSize(signature);
    return sum;
}
 
Example 4
Source File: FindNoSideEffectMethods.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public void sawOpcode(int seen) {
    if (!allowedFields.isEmpty() && seen == Const.PUTFIELD) {
        Item objItem = getStack().getStackItem(1);
        if (objItem.getRegisterNumber() == 0) {
            if (allowedFields.contains(getFieldDescriptorOperand())) {
                Item valueItem = getStack().getStackItem(0);
                if (!isNew(valueItem) && !valueItem.isNull()) {
                    allowedFields.remove(getFieldDescriptorOperand());
                }
            }
        }
    }
    if (status == SideEffectStatus.SIDE_EFFECT && allowedFields.isEmpty()) {
        // Nothing to do: skip the rest of the method
        throw new EarlyExitException();
    }
    if (status == SideEffectStatus.SIDE_EFFECT) {
        return;
    }
    switch (seen) {
    case Const.ASTORE:
    case Const.ASTORE_0:
    case Const.ASTORE_1:
    case Const.ASTORE_2:
    case Const.ASTORE_3:
        if (finallyTargets.contains(getPC())) {
            finallyExceptionRegisters.add(getRegisterOperand());
        }
        break;
    case Const.ATHROW: {
        Item exceptionItem = getStack().getStackItem(0);
        if (!finallyExceptionRegisters.remove(exceptionItem.getRegisterNumber())) {
            uselessVoidCandidate = false;
            try {
                JavaClass javaClass = exceptionItem.getJavaClass();
                if (javaClass != null && ALLOWED_EXCEPTIONS.contains(javaClass.getClassName())) {
                    break;
                }
            } catch (ClassNotFoundException e) {
            }
            status = SideEffectStatus.SIDE_EFFECT;
        }
        break;
    }
    case Const.PUTSTATIC:
        if (classInit) {
            if (getClassConstantOperand().equals(getClassName())) {
                break;
            }
        }
        status = SideEffectStatus.SIDE_EFFECT;
        break;
    case Const.INVOKEDYNAMIC:
        status = SideEffectStatus.SIDE_EFFECT;
        break;
    case Const.PUTFIELD:
        sawCall(getMethodCall(FIELD_STORE_STUB_METHOD), false);
        break;
    case Const.AASTORE:
    case Const.DASTORE:
    case Const.CASTORE:
    case Const.BASTORE:
    case Const.IASTORE:
    case Const.LASTORE:
    case Const.FASTORE:
    case Const.SASTORE:
        sawCall(getMethodCall(ARRAY_STORE_STUB_METHOD), false);
        break;
    case Const.INVOKESTATIC:
        if (changesOnlyNewObjects(getMethodDescriptorOperand())) {
            break;
        }
        sawCall(new MethodCall(getMethodDescriptorOperand(), TARGET_OTHER), false);
        break;
    case Const.INVOKESPECIAL:
    case Const.INVOKEINTERFACE:
    case Const.INVOKEVIRTUAL: {
        XMethod xMethodOperand = getXMethodOperand();
        MethodDescriptor methodDescriptorOperand = xMethodOperand == null ? getMethodDescriptorOperand()
                : xMethodOperand
                        .getMethodDescriptor();
        if (changesOnlyNewObjects(getMethodDescriptorOperand())) {
            break;
        }
        MethodCall methodCall = getMethodCall(methodDescriptorOperand);
        sawCall(methodCall, false);
        break;
    }
    default:
        break;
    }
}
 
Example 5
Source File: Hierarchy.java    From spotbugs with 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 6
Source File: Hierarchy.java    From spotbugs with 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 7
Source File: Hierarchy2.java    From spotbugs with 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 8
Source File: INVOKEDYNAMIC.java    From commons-bcel with Apache License 2.0 4 votes vote down vote up
public INVOKEDYNAMIC(final int index) {
    super(Const.INVOKEDYNAMIC, index);
}