WALA/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/ssa/AbstractLexicalInvoke.java

163 lines
5.0 KiB
Java

/******************************************************************************
* 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.cast.ir.ssa;
import com.ibm.wala.cast.ir.ssa.AstLexicalAccess.Access;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.ssa.SymbolTable;
/**
* This abstract class adds to invoke instructions the ability to handle lexical uses and definitions during call graph
* construction. The lexical uses and definitions of these objects are initially empty, and get filled in by the
* AstSSAPropagationCallGraphBuilder, particularly its LexicalOperator objects. This class is still abstract since the
* lexical scoping functionality is used by multiple languages, each of which has further specializations of invoke
* instructions.
*
* @author Julian Dolby (dolby@us.ibm.com)
*
*/
public abstract class AbstractLexicalInvoke extends MultiReturnValueInvokeInstruction {
protected Access[] lexicalReads = null;
protected Access[] lexicalWrites = null;
protected AbstractLexicalInvoke(int iindex, int results[], int exception, CallSiteReference site) {
super(iindex, results, exception, site);
}
protected AbstractLexicalInvoke(int iindex, int result, int exception, CallSiteReference site) {
this(iindex, new int[] { result }, exception, site);
}
protected AbstractLexicalInvoke(int iindex, int results[], int exception, CallSiteReference site, Access[] lexicalReads,
Access[] lexicalWrites) {
this(iindex, results, exception, site);
this.lexicalReads = lexicalReads;
this.lexicalWrites = lexicalWrites;
}
public int getNumberOfUses() {
if (lexicalReads == null)
return getNumberOfParameters();
else
return getNumberOfParameters() + lexicalReads.length;
}
public int getNumberOfLexicalWrites(){
if(lexicalWrites == null){
return 0;
} else {
return lexicalWrites.length;
}
}
public int getNumberOfLexicalReads() {
if(lexicalReads == null){
return 0;
} else {
return lexicalReads.length;
}
}
public final int getLastLexicalUse() {
if (lexicalReads == null) {
return -1;
} else {
return getNumberOfParameters() + lexicalReads.length - 1;
}
}
public int getUse(int j) {
assert j >= getNumberOfParameters();
assert lexicalReads != null;
assert lexicalReads[j - getNumberOfParameters()] != null;
return lexicalReads[j - getNumberOfParameters()].valueNumber;
}
public int getNumberOfDefs() {
if (lexicalWrites == null)
return super.getNumberOfDefs();
else
return super.getNumberOfDefs() + lexicalWrites.length;
}
public int getDef(int j) {
if (j < super.getNumberOfDefs())
return super.getDef(j);
else
return lexicalWrites[j - super.getNumberOfDefs()].valueNumber;
}
private Access[] addAccess(Access[] array, Access access) {
if (array == null)
return new Access[] { access };
else {
Access[] result = new Access[array.length + 1];
System.arraycopy(array, 0, result, 0, array.length);
result[array.length] = access;
return result;
}
}
public boolean isLexicalUse(int use) {
return use >= super.getNumberOfUses();
}
public void addLexicalUse(Access use) {
lexicalReads = addAccess(lexicalReads, use);
}
public Access getLexicalUse(int i) {
return lexicalReads[i - getNumberOfParameters()];
}
public boolean isLexicalDef(int def) {
return def >= super.getNumberOfDefs();
}
public void addLexicalDef(Access def) {
lexicalWrites = addAccess(lexicalWrites, def);
}
public Access getLexicalDef(int i) {
return lexicalWrites[i - super.getNumberOfDefs()];
}
public int hashCode() {
return site.hashCode() * 7529;
}
public String toString(SymbolTable symbolTable) {
StringBuffer s = new StringBuffer(super.toString(symbolTable));
if (lexicalReads != null) {
s.append(" (reads:");
for (int i = 0; i < lexicalReads.length; i++) {
s.append(" ").append(lexicalReads[i].variableName).append(":").append(
getValueString(symbolTable, lexicalReads[i].valueNumber));
}
s.append(")");
}
if (lexicalWrites != null) {
s.append(" (writes:");
for (int i = 0; i < lexicalWrites.length; i++) {
s.append(" ").append(lexicalWrites[i].variableName).append(":").append(
getValueString(symbolTable, lexicalWrites[i].valueNumber));
}
s.append(")");
}
return s.toString();
}
}