157 lines
4.4 KiB
Java
157 lines
4.4 KiB
Java
/*******************************************************************************
|
|
* Copyright (c) 2007 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.ssa.SSAIndirectionData.Name;
|
|
import com.ibm.wala.types.FieldReference;
|
|
import com.ibm.wala.types.TypeReference;
|
|
import com.ibm.wala.util.debug.Assertions;
|
|
|
|
/**
|
|
* An {@link SSAAddressOfInstruction} represents storing the address of some "source" level entity (@see {@link Name}) into an SSA
|
|
* value number.
|
|
*/
|
|
public class SSAAddressOfInstruction extends SSAInstruction {
|
|
|
|
/**
|
|
* The value number which is def'ed ... this instruction assigns this value to hold an address.
|
|
*/
|
|
private final int lval;
|
|
|
|
/**
|
|
* The SSA value number that represents the entity whose address is being taken.
|
|
*
|
|
* If we're taking the address of a local variable, this is the value number representing that local variable immediately before
|
|
* this instruction.
|
|
*
|
|
* If we're taking the address of an array element or a field of an object, then this is the base pointer.
|
|
*/
|
|
private final int addressVal;
|
|
|
|
/**
|
|
* If we're taking the address of an array element, this is the array index. Otherwise, this is -1.
|
|
*/
|
|
private final int indexVal;
|
|
|
|
/**
|
|
* If we're taking the address of a field, this is the field reference. Otherwise, this is null.
|
|
*/
|
|
private final FieldReference field;
|
|
|
|
private final TypeReference pointeeType;
|
|
|
|
/**
|
|
* Use this constructor when taking the address of a local variable.
|
|
*/
|
|
public SSAAddressOfInstruction(int index, int lval, int local, TypeReference pointeeType) {
|
|
super(index);
|
|
if (local <= 0) {
|
|
throw new IllegalArgumentException("Invalid local address load of " + local);
|
|
}
|
|
this.lval = lval;
|
|
this.addressVal = local;
|
|
this.indexVal = -1;
|
|
this.field = null;
|
|
this.pointeeType = pointeeType;
|
|
}
|
|
|
|
/**
|
|
* Use this constructor when taking the address of an array element.
|
|
*/
|
|
public SSAAddressOfInstruction(int index, int lval, int basePointer, int indexVal, TypeReference pointeeType) {
|
|
super(index);
|
|
this.lval = lval;
|
|
this.addressVal = basePointer;
|
|
this.indexVal = indexVal;
|
|
this.field = null;
|
|
this.pointeeType = pointeeType;
|
|
}
|
|
|
|
/**
|
|
* Use this constructor when taking the address of a field in an object.
|
|
*/
|
|
public SSAAddressOfInstruction(int index, int lval, int basePointer, FieldReference field, TypeReference pointeeType) {
|
|
super(index);
|
|
this.lval = lval;
|
|
this.addressVal = basePointer;
|
|
this.indexVal = -1;
|
|
this.field = field;
|
|
this.pointeeType = pointeeType;
|
|
}
|
|
|
|
public TypeReference getType() {
|
|
return pointeeType;
|
|
}
|
|
|
|
@Override
|
|
public SSAInstruction copyForSSA(SSAInstructionFactory insts, int[] defs, int[] uses) {
|
|
Assertions.UNREACHABLE("not yet implemented. to be nuked");
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return lval * 99701 + addressVal;
|
|
}
|
|
|
|
@Override
|
|
public boolean isFallThrough() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public String toString(SymbolTable symbolTable) {
|
|
return getValueString(symbolTable, lval)
|
|
+ " (" + pointeeType.getName() + ") "
|
|
+ " = &"
|
|
+ getValueString(symbolTable, addressVal)
|
|
+ ((indexVal != -1) ? "[" + getValueString(symbolTable, indexVal) + "]" : (field != null) ? "."
|
|
+ field.getName().toString() : "");
|
|
}
|
|
|
|
@Override
|
|
public void visit(IVisitor v) {
|
|
assert (v instanceof IVisitorWithAddresses) : "expected an instance of IVisitorWithAddresses";
|
|
((IVisitorWithAddresses) v).visitAddressOf(this);
|
|
}
|
|
|
|
@Override
|
|
public int getNumberOfDefs() {
|
|
return 1;
|
|
}
|
|
|
|
@Override
|
|
public int getDef(int i) {
|
|
assert i == 0;
|
|
return lval;
|
|
}
|
|
|
|
@Override
|
|
public int getDef() {
|
|
return lval;
|
|
}
|
|
|
|
@Override
|
|
public int getNumberOfUses() {
|
|
return (indexVal == -1) ? 1 : 2;
|
|
}
|
|
|
|
@Override
|
|
public int getUse(int i) {
|
|
assert i == 0 || (i == 1 && indexVal != -1);
|
|
if (i == 0) {
|
|
return addressVal;
|
|
} else {
|
|
return indexVal;
|
|
}
|
|
}
|
|
}
|