/** Generate code for an instance invoke expression.
* @param expression The instance invoke expression.
*/
protected void _generateInstanceInvokeExpression(
InstanceInvokeExpr expression) {
SootMethod method = expression.getMethod();
SootClass declaringClass = method.getDeclaringClass();
// If the declaring class is an interface extending a method in
// Object, then the first argument to non-static methods will be
// the interface, not Object.
if ((expression instanceof VirtualInvokeExpr)
&& (Scene.v().getSootClass("java.lang.Object")
.declaresMethod(method.getSubSignature()))) {
Type baseType = expression.getBase().getType();
if (baseType instanceof RefType) {
declaringClass = ((RefType) baseType).getSootClass();
}
}
StringBuffer code = new StringBuffer();
expression.getBase().apply(this);
StringBuffer instanceName = _pop();
// We're using the class pointer only for abstract methods.
// We don't do this if the instance is an array.
code = new StringBuffer(instanceName + "->class->methods."
+ CNames.methodNameOf(method));
// Default cast is used only if the declaring class does not seem
// to inherit this method.
String cast = "(" + CNames.instanceNameOf(declaringClass)
+ "/* default cast */)";
Iterator inheritedMethods = MethodListGenerator.getInheritedMethods(
declaringClass).iterator();
while (inheritedMethods.hasNext()) {
SootMethod inheritedMethod = (SootMethod) inheritedMethods.next();
if (inheritedMethod.getSubSignature().equals(
method.getSubSignature())) {
cast = "("
+ CNames.instanceNameOf(inheritedMethod
.getDeclaringClass()) + "/* inherited cast */)";
break;
}
}