/* * Created on 15 fev. 2005 * */ package fr.lifl.stc.stan.samples.flow; import org.apache.bcel.classfile.Method; import org.apache.bcel.generic.ATHROW; import org.apache.bcel.generic.InstructionHandle; import org.apache.bcel.generic.ReturnInstruction; import org.apache.bcel.generic.BasicType; //import org.apache.bcel.generic.ReferenceType; import org.apache.bcel.generic.Type; //import fr.lifl.rd2p.jits.tools.ea.execution.Interpreter; //import fr.lifl.rd2p.jits.tools.ea.execution.stack.Value; //import fr.lifl.rd2p.jits.tools.ea.analyser.GlobalAnalyser; import fr.lifl.stc.stan.annotation.Annotation; import fr.lifl.stc.stan.execution.Frame; import fr.lifl.stc.stan.execution.MethodInfo; import fr.lifl.stc.stan.execution.stack.JvmType; import fr.lifl.stc.stan.execution.stack.MultiObject; import fr.lifl.stc.stan.execution.stack.Reference; import fr.lifl.stc.stan.link.Link; import fr.lifl.stc.stan.link.TableLink; import fr.lifl.stc.stan.policy.Policy; import fr.lifl.stc.stan.signature.PartialSignature; import fr.lifl.stc.stan.util.Printer; import fr.lifl.stc.stan.link.defaultLink.DefaultLink; /** * @author dorina * */ public class FlowAnnotation implements Annotation { /* (non-Javadoc) * @see fr.lifl.rd2p.jits.tools.ea.annotation.Annotation#update(fr.lifl.rd2p.jits.tools.ea.execution.Frame) */ /** * contains: Excep StaticWorld Flux Arguments ... * Arguments can be: Value or Reference * if Reference && not array, it contains: SecretPart PublicPart */ private JvmType [] jvmTypes; /** * referes to []jvmTypes like this: * deps[i][i] corresponds to jvmTypes[i-1] * deps[0][0] corresponds to Return */ //private Link [][] deps; private TableLink deps; private boolean isStatic; private int returnDeps; Type returnType; public FlowAnnotation (JvmType [] jvm, MethodInfo mi){ Method m = mi.getMethod(); returnType = m.getReturnType(); Type[] args = m.getArgumentTypes(); int n = args.length; isStatic = m.isStatic(); int l = 3; int startArg = 0; if (!isStatic){ n++; startArg =-1; } int dim = n + l; jvmTypes = new JvmType[dim]; returnDeps = 1; deps = new TableLink(dim+1, dim+1); int j = l; for(int i = startArg; i < args.length ; i++ ) { JvmType t = findArgument(i, jvm); if(t!=null) { jvmTypes[j++] = t; } else System.err.println("Argument "+j+" not found!!!"); } for (int i = 0; i < jvm.length; i++){ if(jvm[i] instanceof Reference) { Reference r = (Reference)jvm[i]; if (r.isThrown()){ jvmTypes[0] = r; } else if (r.isFlux()){ jvmTypes[2] = r; } else if (r.isArgument() && r.getId() == -2){ jvmTypes[1] = r; } } } } /** * Returns the argument with the index j (which can be * Value or Reference) * @param j the index of the desired argument * @param r the list of references & values * @return the argument j */ private JvmType findArgument(int j, JvmType [] r){ for(int i = 0; i < r.length; i++) { if(r[i].isArgument() && r[i].getId() == j) { if(r[i] instanceof Reference) { if(((Reference)r[i]).getAll() != null) { return ((Reference)r[i]).getAll(); } } return r[i]; } } return null; } /** * * @param r * @return */ private int convert (JvmType r){ if(r instanceof Reference && ((Reference)r).getAll()!=null) r = ((Reference)r).getAll(); for(int i = 0; i < jvmTypes.length; i++) { if(jvmTypes[i] == r) return i; } return -1; } public TableLink link (Frame a){ TableLink t = new TableLink(jvmTypes.length, jvmTypes.length); for (int i = 0; i < t.getSizeL(); i++){ if(jvmTypes[i] != null) for(int j = 0; j < t.getSizeC(); j++) if (jvmTypes[j]!=null) { Link l = a.getLinkBetween(jvmTypes[i], jvmTypes[j]); if(l!=null) t.set(i, j, l.clone1()); } } return t; } /** * @param t * @return */ private boolean merge (TableLink t){ boolean updated = false; for (int i = 0; i < t.getSizeL(); i++) for (int j = 0; j < t.getSizeC(); j++) { updated = deps.set(i+returnDeps, j+returnDeps, Link.merge(deps.get(i+returnDeps, j+returnDeps), t.get(i,j))) || updated; } return updated; } public boolean update(Frame a,InstructionHandle ih) { boolean updated = false; MultiObject to; // links between references TableLink newtbl = link(a); if (!(ih.getInstruction() instanceof ReturnInstruction || ih.getInstruction() instanceof ATHROW)){ return false; } updated = merge(newtbl); if (ih.getInstruction() instanceof ReturnInstruction) { // if(this._method.getName().equalsIgnoreCase("m1")) { // Printer.println("before: "+a.getStack()); // printLinkValues(); // a.printLinkValues(); // } // linked to the return value ReturnInstruction ri = (ReturnInstruction) ih.getInstruction(); if (ri.getType() != Type.VOID) { to = a.getStack().peek(); int linkType; int returnPart; returnPart = MethodInfo.partType(returnType); if(returnType instanceof BasicType ){ linkType = Link.VALUE_LINK; } else{ linkType = Link.REFERENCE_LINK; } //make direct link JvmType[] to1 = to.content(); for(int j = 0; j < to1.length; j++) { int jj = convert(to1[j]); if(jj!=-1) updated = deps.set(0, jj+returnDeps, Link.merge( deps.get(0, jj+returnDeps),a.createLink(returnPart, to1[j].getPartType(), linkType) )) || updated; } //make pointedBy for(int j = 0; j < to1.length; j++) { MultiObject res = a._pointedBy(to1[j]); JvmType[] res1 = res.content(); int to2 = convert(to1[j]); Link l1 = null; if(to2 < 0) l1 = a.createLink(returnPart, to1[j].getPartType(), linkType); else //l1 = deps[0][to2+returnDeps]; l1 = deps.get(0, to2+returnDeps); for(int i = 0; i < res1.length; i++){ Link l = null; int res2 = convert(res1[i]); if(to2<0) l = a.getLinkBetween(to1[j], res1[i]); else l = deps.get(to2+returnDeps, res2+returnDeps); if(res2!= -1) { updated = this.deps.set(0, res2+returnDeps, Link.makePointedBy( deps.get(0, res2+returnDeps), l1, l )) || updated; } } } //make pointsTo for(int j = 0; j < to1.length; j++) { MultiObject res = a._pointsTo(to1[j]); JvmType[] res1 = res.content(); int to2 = convert(to1[j]); Link l1 = null; if(to2 < 0) l1 = a.createLink(returnPart, to1[j].getPartType(), linkType); else l1 = deps.get(0,to2+returnDeps); for(int i = 0; i< res1.length; i++){ int res2 = convert(res1[i]); Link l = null; if(to2<0) l = a.getLinkBetween(res1[i], to1[j]); else l = deps.get(res2+returnDeps, to2+returnDeps); if(res2!=-1) updated = this.deps.set(res2+returnDeps, 0, Link.makePointsToReturn( deps.get(res2+returnDeps, 0), l, l1, linkType)) || updated; } } } //extends references from static world for(int i = 0; i < deps.getSizeL(); i++) Link.extendPublicReference( deps.get(2, i));//.extendPublicReference(); //Printer.println("after: "+a.getStack()); //printLinkValues(); }else { // ATHROW to = a.getStack().peek(); JvmType[] to1 = to.content(); for(int j = 0; j < to1.length; j++) { MultiObject res = a._pointedBy(to1[j]); JvmType[] res1 = res.content(); int to2 = convert(to1[j]); Link l1 = null; if(to2 < 0) l1 = a.createLink(JvmType.PUBLIC_PART, to1[j].getPartType(), Link.REFERENCE_LINK); else l1 = deps.get(1, to2+returnDeps); for(int i = 0; i < res1.length; i++){ Link l = null; int res2 = convert(res1[i]); if(to2<0) l = a.getLinkBetween(to1[j], res1[i]); else l = deps.get(to2+returnDeps, res2+returnDeps); if(res2!= -1) updated = this.deps.set(1, res2+returnDeps, Link.makePointedBy( deps.get(1, res2+returnDeps), l1, l )); } } } return updated; } /* (non-Javadoc) * @see fr.lifl.rd2p.jits.tools.ea.annotation.Annotation#toHTML() */ public String toHTML() { String res= "

Flow Annotation

\n " ; //int arg1; if(returnDeps == 1 ) res = res + ""; res = res + ""; for (int i = 3; i < jvmTypes.length; i++){ res = res + ""; } res = res+""; // end of first line // lines R E S F String [] t = new String[3+returnDeps]; if(returnDeps == 1 ){ t[0] = "R"; t[1] = "E"; t[2] = "S"; t[3] = "F"; } for (int i = 0; i < t.length; i++){ res = res +""; for (int j = 0; j < deps.getSizeC(); j++){ res = res + ""; //res = res + ""; } res = res + ""; } // other lines for (int i = 3+returnDeps, j = 1; i < deps.getSizeL(); j++,i++){ res = res + ""; for (int k = 0; k < deps.getSizeC(); k++){ res = res + ""; //res = res + ""; } res = res + ""; } return res+"
RESF"+jvmTypes[i]+"
"+t[i]+" "+((deps.get(i,j)!=null) ? deps.get(i,j).toString():"")+""+deps.get(i,j)+"
"+ jvmTypes[i-returnDeps]+" "+((deps.get(i,k)!=null) ? deps.get(i,k).toString():"")+""+deps.get(i,k)+"
"; } public PartialSignature getPartialSignature (){ return new FlowPartialSignature (this.getClass().getName(),deps); } //FIXME public static int getSizeFlowAnnotation(Method m, Policy p, String className) { Type[] args = m.getArgumentTypes(); int n = args.length; if (!m.isStatic()){ n++; } int dim = n + 3; int returnDeps = 1; return returnDeps+dim; } public void addResults (){ } public void printLinkValues(){ //JvmType[] j = interpreter.getRefValues(); Printer.print("\t Ret\t"); for(int i = 0;i < this.jvmTypes.length; i++) { Printer.print(""+jvmTypes[i]); } Printer.println(""); for(int i = 0;i < jvmTypes.length+1; i++) { if(i==0) Printer.print("Ret\t\t"); else Printer.print(jvmTypes[i-1]+"\t"); for(int k = 0;k