/******************************************************************************* * Copyright (c) 2002 - 2006 IBM Corporation. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package com.ibm.wala.ssa; import com.ibm.wala.classLoader.CallSiteReference; import com.ibm.wala.shrikeBT.IInvokeInstruction; import com.ibm.wala.types.MethodReference; import com.ibm.wala.types.TypeReference; /** * A Call instruction. * * Note that different languages have different notions of what a call is. This is an abstract superclass which encapsulates the * common functionality that all languages share, so far. */ public abstract class SSAAbstractInvokeInstruction extends SSAInstruction { /** * The value number which represents the exception object which the call may throw. */ protected final int exception; /** * The call site, containing the program counter location and the method being called. */ protected final CallSiteReference site; /** * @param exception The value number which represents the exception object which the call may throw. * @param site The call site, containing the program counter location and the method being called. */ protected SSAAbstractInvokeInstruction(int iindex, int exception, CallSiteReference site) { super(iindex); this.exception = exception; this.site = site; } /** * @return The call site, containing the program counter location and the method being called. */ public CallSiteReference getCallSite() { return site; } /** * Is this a 'static' call? (invokestatic in Java) */ public boolean isStatic() { return getCallSite().isStatic(); } /** * Might this call dispatch to one of several possible methods? i.e., in Java, is it an invokeinterface or invokevirtual */ public boolean isDispatch() { return getCallSite().isDispatch(); } /** * Is this a 'special' call? (invokespecial in Java) */ public boolean isSpecial() { return getCallSite().isSpecial(); } /** * @return the value number of the receiver of a virtual call */ public int getReceiver() { assert site.getInvocationCode() != IInvokeInstruction.Dispatch.STATIC : toString(); return getUse(0); } /** * @return the program counter (index into the method's bytecode) for this call site. */ public int getProgramCounter() { return site.getProgramCounter(); } /* * @see com.ibm.wala.ssa.SSAInstruction#getNumberOfDefs() */ @Override public int getNumberOfDefs() { return getNumberOfReturnValues() + 1; } /* * @see com.ibm.wala.ssa.SSAInstruction#getDef(int) */ @Override public int getDef(int i) { if (getNumberOfReturnValues() == 0) { assert i == 0; return exception; } else { if (i == 0) { return getReturnValue(0); } else if (i == 1) { return exception; } else { return getReturnValue(i - 1); } } } /** * Return the value number which is def'fed by this call instruction if the call returns exceptionally. */ public int getException() { return exception; } /* * @see com.ibm.wala.ssa.SSAInstruction#hasDef() */ @Override public boolean hasDef() { return getNumberOfReturnValues() > 0; } /* * @see com.ibm.wala.ssa.SSAInstruction#getDef() */ @Override public int getDef() { return getReturnValue(0); } /** * How many parameters does this call specify? */ public abstract int getNumberOfParameters(); /** * How many distinct values does this call return? */ public abstract int getNumberOfReturnValues(); /** * What is the the value number of the ith value returned by this call */ public abstract int getReturnValue(int i); /** * What is the declared return type of the called method */ public TypeReference getDeclaredResultType() { return site.getDeclaredTarget().getReturnType(); } /** * What method is the declared callee? */ public MethodReference getDeclaredTarget() { return site.getDeclaredTarget(); } /** * @see com.ibm.wala.classLoader.CallSiteReference#getInvocationCode() */ public IInvokeInstruction.IDispatch getInvocationCode() { return site.getInvocationCode(); } /* * @see com.ibm.wala.ssa.Instruction#isPEI() */ @Override public boolean isPEI() { return true; } /* * @see com.ibm.wala.ssa.Instruction#isFallThrough() */ @Override public boolean isFallThrough() { return true; } @Override public String toString(SymbolTable symbolTable) { String code = site.getInvocationString(); StringBuffer s = new StringBuffer(); if (hasDef()) { s.append(getValueString(symbolTable, getDef())).append(" = "); } s.append("invoke").append(code); s.append(" "); s.append(site.getDeclaredTarget().toString()); if (getNumberOfParameters() > 0) { s.append(" ").append(getValueString(symbolTable, getUse(0))); for (int i = 1; i < getNumberOfParameters(); i++) { s.append(",").append(getValueString(symbolTable, getUse(i))); } } s.append(" @"); s.append(site.getProgramCounter()); if (exception == -1) { s.append(" exception: NOT MODELED"); } else { s.append(" exception:").append(getValueString(symbolTable, exception)); } return s.toString(); } }