TypedValue base = (TypedValue)values.get(0);
if (methodChecker != null)
{
OperationSideEffect sideEffect = methodChecker.isMethodSafe(sig, base, args);
if (sideEffect == OperationSideEffect.UNSAFE)
throw new AnalyzerException(insn, "Unknown method " + sig + " encountered");
else if (sideEffect == OperationSideEffect.SAFE)
sideEffects.add(new MethodSideEffectCall(sig, base, args));
}
MethodCallValue.VirtualMethodCallValue toReturn;
toReturn = new MethodCallValue.VirtualMethodCallValue(methodInsn.owner, methodInsn.name, methodInsn.desc, args, base);
if (toReturn.isConstructor() && linkedFrame != null)
linkedFrame.replaceValues(base, toReturn);
else if (methodChecker != null && methodChecker.isFluentChaining(sig))
linkedFrame.replaceValues(base, toReturn);
return toReturn;
}
else
{
if (methodChecker != null)
{
OperationSideEffect sideEffect = methodChecker.isStaticMethodSafe(sig);
if (sideEffect == OperationSideEffect.UNSAFE)
throw new AnalyzerException(insn, "Unknown method " + sig + " encountered");
else if (sideEffect == OperationSideEffect.SAFE)
sideEffects.add(new MethodSideEffectCall(sig, null, args));
}
return new MethodCallValue.StaticMethodCallValue(methodInsn.owner, methodInsn.name, methodInsn.desc, args);
}
}
case INVOKEDYNAMIC:
{
assert(insn instanceof InvokeDynamicInsnNode);
InvokeDynamicInsnNode invokeInsn = (InvokeDynamicInsnNode)insn;
if (!"java/lang/invoke/LambdaMetafactory".equals(invokeInsn.bsm.getOwner())
|| !"altMetafactory".equals(invokeInsn.bsm.getName())
|| !"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;".equals(invokeInsn.bsm.getDesc()))
throw new AnalyzerException(insn, "Unknown invokedynamic " + invokeInsn.bsm + " encountered");
// Return the Lambda creation result
Handle lambdaMethod = (Handle)invokeInsn.bsmArgs[1];
Type functionalInterface = Type.getReturnType(invokeInsn.desc);
return new LambdaFactory(functionalInterface, lambdaMethod, new ArrayList<>((List<TypedValue>)values));
}
case MULTIANEWARRAY:
default:
throw new AnalyzerException(insn, "Unhandled bytecode instruction");
}
}