From c7ea3079645c75bbddc4b27b2d7d2f9f888362ed Mon Sep 17 00:00:00 2001 From: bdemsky Date: Wed, 20 Apr 2011 22:39:55 +0000 Subject: [PATCH] changes to make sure that i don't step on stephen's work on imports... --- .../src/Analysis/CallGraph/BaseCallGraph.java | 2 - Robust/src/IR/Flat/BuildFlat.java | 213 +++++++++--------- Robust/src/IR/Tree/BuildIR.java | 4 +- Robust/src/IR/Tree/JavaBuilder.java | 196 +++++++++++++++- Robust/src/IR/Tree/SemanticCheck.java | 172 +++++++------- Robust/src/Main/Main.java | 53 +++-- 6 files changed, 418 insertions(+), 222 deletions(-) diff --git a/Robust/src/Analysis/CallGraph/BaseCallGraph.java b/Robust/src/Analysis/CallGraph/BaseCallGraph.java index 5859300a..aa5e9e49 100644 --- a/Robust/src/Analysis/CallGraph/BaseCallGraph.java +++ b/Robust/src/Analysis/CallGraph/BaseCallGraph.java @@ -93,7 +93,6 @@ public class BaseCallGraph implements CallGraph { possInterfaces.add((ClassDescriptor)supit.next()); } Set possiblematches=IFdesc.getMethodTable().getSet(md.getSymbol()); - boolean foundmatch=false; for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) { MethodDescriptor matchmd=(MethodDescriptor)matchit.next(); if (md.matches(matchmd)) { @@ -109,7 +108,6 @@ public class BaseCallGraph implements CallGraph { ClassDescriptor superdesc=cn.getSuperDesc(); if (superdesc!=null) { Set possiblematches=superdesc.getMethodTable().getSet(md.getSymbol()); - boolean foundmatch=false; for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) { MethodDescriptor matchmd=(MethodDescriptor)matchit.next(); if (md.matches(matchmd)) { diff --git a/Robust/src/IR/Flat/BuildFlat.java b/Robust/src/IR/Flat/BuildFlat.java index ffc9e382..a1d53b80 100644 --- a/Robust/src/IR/Flat/BuildFlat.java +++ b/Robust/src/IR/Flat/BuildFlat.java @@ -161,127 +161,122 @@ public class BuildFlat { Iterator methodit=cn.getMethods(); while(methodit.hasNext()) { currmd=(MethodDescriptor)methodit.next(); - - // if OOOJava is on, splice a special SESE in to - // enclose the main method - boolean spliceInImplicitMain = - state.OOOJAVA && - currmd.equals( typeutil.getMain() ); - - FlatSESEEnterNode spliceSESE = null; - FlatSESEExitNode spliceExit = null; - - if( spliceInImplicitMain ) { - SESENode mainTree = new SESENode( "main" ); - spliceSESE = new FlatSESEEnterNode( mainTree ); - spliceExit = new FlatSESEExitNode ( mainTree ); - spliceSESE.setFlatExit ( spliceExit ); - spliceExit.setFlatEnter( spliceSESE ); - spliceSESE.setIsMainSESE(); - } - - - fe=new FlatExit(); - - BlockNode bn=state.getMethodBody(currmd); + flattenMethod(cn, currmd); + } + } + + public void flattenMethod(ClassDescriptor cn, MethodDescriptor currmd) { + // if OOOJava is on, splice a special SESE in to + // enclose the main method + boolean spliceInImplicitMain = state.OOOJAVA && currmd.equals( typeutil.getMain() ); + + FlatSESEEnterNode spliceSESE = null; + FlatSESEExitNode spliceExit = null; + + if( spliceInImplicitMain ) { + SESENode mainTree = new SESENode( "main" ); + spliceSESE = new FlatSESEEnterNode( mainTree ); + spliceExit = new FlatSESEExitNode ( mainTree ); + spliceSESE.setFlatExit ( spliceExit ); + spliceExit.setFlatEnter( spliceSESE ); + spliceSESE.setIsMainSESE(); + } + + fe=new FlatExit(); + BlockNode bn=state.getMethodBody(currmd); - if (state.DSM&&currmd.getModifiers().isAtomic()) { - FlatAtomicEnterNode faen=new FlatAtomicEnterNode(); - faen.setNumLine(bn.getNumLine()); - curran = faen; - } else - curran=null; - if ((state.THREAD||state.MGC)&&currmd.getModifiers().isSynchronized()) { - TempDescriptor thistd = null; - if(currmd.getModifiers().isStatic()) { - // need to lock the Class object - thistd=new TempDescriptor("classobj", cn); - } else { - // lock this object - thistd=getTempforVar(currmd.getThis()); - } - if(!this.lockStack.isEmpty()) { - throw new Error("The lock stack for synchronized blocks/methods is not empty!"); - } - this.lockStack.push(thistd); + if (state.DSM&&currmd.getModifiers().isAtomic()) { + FlatAtomicEnterNode faen=new FlatAtomicEnterNode(); + faen.setNumLine(bn.getNumLine()); + curran = faen; + } else + curran=null; + if ((state.THREAD||state.MGC)&&currmd.getModifiers().isSynchronized()) { + TempDescriptor thistd = null; + if(currmd.getModifiers().isStatic()) { + // need to lock the Class object + thistd=new TempDescriptor("classobj", cn); + } else { + // lock this object + thistd=getTempforVar(currmd.getThis()); } - NodePair np=flattenBlockNode(bn); - FlatNode fn=np.getBegin(); - if ((state.THREAD||state.MGC)&&currmd.getModifiers().isSynchronized()) { - MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter"); - FlatNode first = null; - FlatNode end = null; - - { - if (lockStack.size()!=1) { - throw new Error("TOO MANY THINGS ON LOCKSTACK"); - } - TempDescriptor thistd = this.lockStack.elementAt(0); + if(!this.lockStack.isEmpty()) { + throw new Error("The lock stack for synchronized blocks/methods is not empty!"); + } + this.lockStack.push(thistd); + } + NodePair np=flattenBlockNode(bn); + FlatNode fn=np.getBegin(); + if ((state.THREAD||state.MGC)&&currmd.getModifiers().isSynchronized()) { + MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter"); + FlatNode first = null; + FlatNode end = null; + + { + if (lockStack.size()!=1) { + throw new Error("TOO MANY THINGS ON LOCKSTACK"); + } + TempDescriptor thistd = this.lockStack.elementAt(0); FlatCall fc = new FlatCall(memd, null, thistd, new TempDescriptor[0]); fc.setNumLine(bn.getNumLine()); first = end = fc; + } + + end.addNext(fn); + fn=first; + end = np.getEnd(); + if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) { + MethodDescriptor memdex=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit"); + while(!this.lockStack.isEmpty()) { + TempDescriptor thistd = this.lockStack.pop(); + FlatCall fcunlock = new FlatCall(memdex, null, thistd, new TempDescriptor[0]); + fcunlock.setNumLine(bn.getNumLine()); + end.addNext(fcunlock); + end = fcunlock; } - - end.addNext(fn); - fn=first; - end = np.getEnd(); - if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) { - MethodDescriptor memdex=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit"); - while(!this.lockStack.isEmpty()) { - TempDescriptor thistd = this.lockStack.pop(); - FlatCall fcunlock = new FlatCall(memdex, null, thistd, new TempDescriptor[0]); - fcunlock.setNumLine(bn.getNumLine()); - end.addNext(fcunlock); - end = fcunlock; - } - FlatNode rnflat=spliceReturn(end); - rnflat.addNext(fe); - } else { - this.lockStack.clear(); - } - } else if (state.DSM&&currmd.getModifiers().isAtomic()) { - curran.addNext(fn); - fn=curran; - if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) { - FlatAtomicExitNode aen=new FlatAtomicExitNode(curran); - np.getEnd().addNext(aen); - FlatNode rnflat=spliceReturn(aen); - rnflat.addNext(fe); - } - - } else if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) { - FlatNode rnflat=null; - if( spliceInImplicitMain ) { - np.getEnd().addNext(spliceExit); - rnflat=spliceReturn(spliceExit); - } else { - rnflat=spliceReturn(np.getEnd()); - } + FlatNode rnflat=spliceReturn(end); rnflat.addNext(fe); - } else if (np.getEnd()!=null) { - if( spliceInImplicitMain ) { - FlatReturnNode rnflat=(FlatReturnNode)np.getEnd(); - np.getEnd().addNext(spliceExit); - spliceExit.addNext(fe); - } + } else { + this.lockStack.clear(); } - + } else if (state.DSM&&currmd.getModifiers().isAtomic()) { + curran.addNext(fn); + fn=curran; + if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) { + FlatAtomicExitNode aen=new FlatAtomicExitNode(curran); + np.getEnd().addNext(aen); + FlatNode rnflat=spliceReturn(aen); + rnflat.addNext(fe); + } + } else if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) { + FlatNode rnflat=null; if( spliceInImplicitMain ) { - spliceSESE.addNext(fn); - fn=spliceSESE; + np.getEnd().addNext(spliceExit); + rnflat=spliceReturn(spliceExit); + } else { + rnflat=spliceReturn(np.getEnd()); } - - FlatMethod fm=new FlatMethod(currmd, fe); - fm.setNumLine(bn.getNumLine()); - fm.addNext(fn); - if (!currmd.isStatic()) - fm.addParameterTemp(getTempforParam(currmd.getThis())); - for(int i=0; i checkedDesc=new HashSet(); + HashMap classStatus=new HashMap(); + public final int CDNONE=0; + public final int CDINIT=1; + public final int CDINSTANTIATED=2; + BuildIR bir; + TypeUtil tu; + SemanticCheck sc; + BuildFlat bf; + Stack toprocess=new Stack(); + HashSet discovered=new HashSet(); + + /* Maps class/interfaces to all instantiated classes that extend or + * implement those classes or interfaces */ + + HashMap> implementationMap=new HashMap>(); + + /* Maps methods to the methods they call */ + + HashMap> callMap=new HashMap>(); + + /* Invocation map */ + HashMap>> invocationMap=new HashMap>>(); + public JavaBuilder(State state) { this.state=state; + bir=new BuildIR(state); + tu=new TypeUtil(state, bir); + sc=new SemanticCheck(state, tu, false); + bf=new BuildFlat(state,tu); } + public TypeUtil getTypeUtil() { + return tu; + } - public void build(Vector sourcefiles) { - BuildIR bir=new BuildIR(state); - TypeUtil tu=new TypeUtil(state, bir); + public BuildFlat getBuildFlat() { + return bf; + } - for(int i=0;i impSet=implementationMap.get(cn); + if (!invocationMap.containsKey(cn)) + invocationMap.put(cn, new HashSet>()); + invocationMap.get(cn).add(new Pair(md, callmd)); + + for(ClassDescriptor cdactual:impSet) { + searchimp: + while(cdactual!=null) { + Set possiblematches=cdactual.getMethodTable().getSetFromSameScope(callmd.getSymbol()); + + for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) { + MethodDescriptor matchmd=(MethodDescriptor)matchit.next(); + if (callmd.matches(matchmd)) { + //Found the method that will be called + if (!discovered.contains(matchmd)) { + discovered.add(matchmd); + toprocess.push(matchmd); + } + callMap.get(md).add(matchmd); + + break searchimp; + } + } + + //Didn't find method...look in super class + cdactual=cdactual.getSuperDesc(); + } + } + } + + void processNew(FlatNew fnew) { + TypeDescriptor tdnew=fnew.getType(); + if (!tdnew.isClass()) + return; + ClassDescriptor cdnew=tdnew.getClassDesc(); + Stack tovisit=new Stack(); + tovisit.add(cdnew); + + while(!tovisit.isEmpty()) { + ClassDescriptor cdcurr=tovisit.pop(); + if (!implementationMap.containsKey(cdcurr)) + implementationMap.put(cdcurr, new HashSet()); + if (implementationMap.get(cdcurr).add(cdnew)) { + //new implementation...see if it affects implementationmap + if (invocationMap.containsKey(cdcurr)) { + for(Pair mdpair:invocationMap.get(cdcurr)) { + MethodDescriptor md=mdpair.getFirst(); + MethodDescriptor callmd=mdpair.getSecond(); + ClassDescriptor cdactual=cdnew; + + searchimp: + while(cdactual!=null) { + Set possiblematches=cdactual.getMethodTable().getSetFromSameScope(callmd.getSymbol()); + for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) { + MethodDescriptor matchmd=(MethodDescriptor)matchit.next(); + if (callmd.matches(matchmd)) { + //Found the method that will be called + if (!discovered.contains(matchmd)) { + discovered.add(matchmd); + toprocess.push(matchmd); + } + callMap.get(md).add(matchmd); + break searchimp; + } + } + + //Didn't find method...look in super class + cdactual=cdactual.getSuperDesc(); + } + } + } + } + if (cdcurr.getSuperDesc()!=null) + tovisit.push(cdcurr.getSuperDesc()); + for(Iterator interit=cdcurr.getSuperInterfaces();interit.hasNext();) { + ClassDescriptor cdinter=(ClassDescriptor) interit.next(); + tovisit.push(cdinter); + } + } + } + + void processFlatMethod(MethodDescriptor md) { + if (!callMap.containsKey(md)) + callMap.put(md, new HashSet()); + + FlatMethod fm=state.getMethodFlat(md); + for(FlatNode fn:fm.getNodeSet()) { + switch(fn.kind()) { + case FKind.FlatCall: { + FlatCall fcall=(FlatCall)fn; + processCall(md, fcall); + break; + } + case FKind.FlatNew: { + FlatNew fnew=(FlatNew)fn; + processNew(fnew); + break; + } + } + } } public static ParseNode readSourceFile(State state, String sourcefile) { @@ -51,7 +227,7 @@ public class JavaBuilder { } } - public static void loadClass(BuildIR bir, String sourcefile) { + public void loadClass(BuildIR bir, String sourcefile) { try { ParseNode pn=readSourceFile(state, sourcefile); bir.buildtree(pn, null,sourcefile); diff --git a/Robust/src/IR/Tree/SemanticCheck.java b/Robust/src/IR/Tree/SemanticCheck.java index 4c3a00df..1c934579 100644 --- a/Robust/src/IR/Tree/SemanticCheck.java +++ b/Robust/src/IR/Tree/SemanticCheck.java @@ -9,73 +9,86 @@ public class SemanticCheck { TypeUtil typeutil; Stack loopstack; HashSet toanalyze; - HashSet completed; + HashMap completed; - //This is the class mappings for a particular file based - //on the import names. Maps class to canonical class name. - Hashtable classnameMappings; - + public static final int NOCHECK=0; + public static final int REFERENCE=1; + public static final int INIT=2; + + boolean checkAll; public SemanticCheck(State state, TypeUtil tu) { + this(state, tu, true); + } + + public SemanticCheck(State state, TypeUtil tu, boolean checkAll) { this.state=state; this.typeutil=tu; this.loopstack=new Stack(); this.toanalyze=new HashSet(); - this.completed=new HashSet(); + this.completed=new HashMap(); + this.checkAll=checkAll; } - public ClassDescriptor getClass(String classname) { + public ClassDescriptor getClass(ClassDescriptor context, String classname) { + return getClass(context, classname, INIT); + } + + public ClassDescriptor getClass(ClassDescriptor context, String classname, int fullcheck) { + if (context!=null) { + Hashtable remaptable=context.getSingleImportMappings(); + classname=remaptable.containsKey(classname)?((String)remaptable.get(classname)):classname; + } ClassDescriptor cd=typeutil.getClass(classname, toanalyze); - checkClass(cd); + checkClass(cd, fullcheck); return cd; } private void checkClass(ClassDescriptor cd) { - if (!completed.contains(cd)) { - completed.add(cd); + checkClass(cd, INIT); + } + + private void checkClass(ClassDescriptor cd, int fullcheck) { + if (!completed.containsKey(cd)||completed.get(cd) sifv = cd.getSuperInterface(); - for(int i = 0; i < sifv.size(); i++) { - ClassDescriptor superif = getClass(sifv.elementAt(i)); - if(!superif.isInterface()) { - throw new Error("Error! Class " + cd.getSymbol() + " implements non-interface " + superif.getSymbol()); + if (fullcheck>=REFERENCE&&oldstatus sifv = cd.getSuperInterface(); + for(int i = 0; i < sifv.size(); i++) { + ClassDescriptor superif = getClass(cd, sifv.elementAt(i), fullcheck); + if(!superif.isInterface()) { + throw new Error("Error! Class " + cd.getSymbol() + " implements non-interface " + superif.getSymbol()); + } + cd.addSuperInterfaces(superif); + cd.getFieldTable().addParentIF(superif.getFieldTable()); + cd.getMethodTable().addParentIF(superif.getMethodTable()); } - cd.addSuperInterfaces(superif); - cd.getFieldTable().addParentIF(superif.getFieldTable()); - cd.getMethodTable().addParentIF(superif.getMethodTable()); - } - - /* Check to see that fields are well typed */ - for(Iterator field_it=cd.getFields(); field_it.hasNext();) { - FieldDescriptor fd=(FieldDescriptor)field_it.next(); - checkField(cd,fd); } - - for(Iterator method_it=cd.getMethods(); method_it.hasNext();) { - MethodDescriptor md=(MethodDescriptor)method_it.next(); - checkMethod(cd,md); - if(md.isDefaultConstructor() && (cd.getSuperDesc() != null)) { - // add the construction of it super class, can only be super() - NameDescriptor nd=new NameDescriptor("super"); - MethodInvokeNode min=new MethodInvokeNode(nd); - BlockExpressionNode ben=new BlockExpressionNode(min); - BlockNode bn = state.getMethodBody(md); - bn.addFirstBlockStatement(ben); - } + if (oldstatus=INIT) { + /* Check to see that fields are well typed */ + for(Iterator field_it=cd.getFields(); field_it.hasNext();) { + FieldDescriptor fd=(FieldDescriptor)field_it.next(); + checkField(cd,fd); + } + for(Iterator method_it=cd.getMethods(); method_it.hasNext();) { + MethodDescriptor md=(MethodDescriptor)method_it.next(); + checkMethod(cd,md); + } } } } @@ -100,12 +113,10 @@ public class SemanticCheck { } else { ClassDescriptor cd = (ClassDescriptor) obj; toanalyze.remove(cd); - //set the class mappings based on imports. - classnameMappings = cd.getSingleImportMappings(); // need to initialize typeutil object here...only place we can // get class descriptors without first calling getclass - getClass(cd.getSymbol()); + getClass(cd, cd.getSymbol()); for (Iterator method_it = cd.getMethods(); method_it.hasNext();) { MethodDescriptor md = (MethodDescriptor) method_it.next(); try { @@ -119,7 +130,7 @@ public class SemanticCheck { } } - public void checkTypeDescriptor(TypeDescriptor td) { + private void checkTypeDescriptor(ClassDescriptor cd, TypeDescriptor td) { if (td.isPrimitive()) return; /* Done */ else if (td.isClass()) { @@ -128,7 +139,8 @@ public class SemanticCheck { if(index != -1) { name = name.substring(index+1); } - ClassDescriptor field_cd=getClass(getFullName(name)); + ClassDescriptor field_cd=checkAll?getClass(cd, name):getClass(cd, name, REFERENCE); + if (field_cd==null) throw new Error("Undefined class "+name); td.setClassDescriptor(field_cd); @@ -140,7 +152,7 @@ public class SemanticCheck { } public void checkField(ClassDescriptor cd, FieldDescriptor fd) { - checkTypeDescriptor(fd.getType()); + checkTypeDescriptor(cd, fd.getType()); } public void checkConstraintCheck(TaskDescriptor td, SymbolTable nametable, Vector ccs) { @@ -203,7 +215,7 @@ public class SemanticCheck { for(int i=0; i