package jqian.sootex.location; import java.util.*; import soot.*; import soot.jimple.*; import soot.jimple.spark.pag.AllocNode; import jqian.sootex.Cache; public class CommonInstObject extends InstanceObject{ private Type _type; private HeapField[] _fieldLocs; CommonInstObject(Object binding,Type type){ super(binding); this._type=type; buildFields(); } /** Only use for override. */ CommonInstObject(){ super(null); } /**Return the corresponding field */ public HeapField getField(final SootField field){ int index = searchField(field); if(index<0) return null; else return _fieldLocs[index]; } public HeapField[] getAllFields(){ return _fieldLocs; } private void buildFields(){ SootClass cls = ((RefType) _type).getSootClass(); Collection<SootField> flds = Cache.v().getAllInstanceFields(cls); _fieldLocs = new HeapField[flds.size()]; int i = 0; for (SootField f : flds) { HeapField heapField = new HeapField(this, f); _fieldLocs[i] = heapField; i++; } Arrays.sort(_fieldLocs,FieldComparator._instance); } public String toString(){ Object alloc = null; SootMethod method = null; if(_binding instanceof AllocNode){ AllocNode node = (AllocNode)_binding; alloc = node.getNewExpr(); method = node.getMethod(); } String str= "("; if(alloc!=null && alloc instanceof AnyNewExpr){ str += "N"; }else{ str += "T"; } str += getNumber()+"#"; //String typename=_type.toString(); //int index=typename.lastIndexOf('.'); //typename=typename.substring(index+1,typename.length()); if(alloc!=null){ //str+=typename; str += "@"; if(method!=null) str+=method.getName(); //if(getAllocUnit()!=null) // str+="_"+SootUtils.getLine(getAllocUnit()); }else{ str+= _type.toString(); } str+=")"; return str; } public Type getType(){ return _type; } private int searchField(final SootField field) { int low = 0; int high = _fieldLocs.length-1; int fieldNum = field.getNumber(); while (low <= high) { int mid = (low + high) >> 1; HeapField midVal = _fieldLocs[mid]; int cmp = midVal._field.getNumber() - fieldNum; if (cmp < 0) low = mid + 1; else if (cmp > 0) high = mid - 1; else return mid; // key found } return -(low + 1); // key not found. } private static class FieldComparator implements Comparator<Object>{ static FieldComparator _instance = new FieldComparator(); public final int compare(Object arg0, Object arg1) { SootField f1 = null; if(arg0 instanceof HeapField){ HeapField n1 = (HeapField)arg0; f1 = n1.getField(); } else{ f1 = (SootField)arg0; } SootField f2 = null; if(arg1 instanceof HeapField){ HeapField n2 = (HeapField)arg1; f2 = n2.getField(); } else{ f2 = (SootField)arg1; } return f1.getNumber()-f2.getNumber(); } } }