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)) {
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)) {
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<currmd.numParameters(); i++) {
- fm.addParameterTemp(getTempforParam(currmd.getParameter(i)));
+ rnflat.addNext(fe);
+ } else if (np.getEnd()!=null) {
+ if( spliceInImplicitMain ) {
+ FlatReturnNode rnflat=(FlatReturnNode)np.getEnd();
+ np.getEnd().addNext(spliceExit);
+ spliceExit.addNext(fe);
}
-
- state.addFlatCode(currmd,fm);
}
+ if( spliceInImplicitMain ) {
+ spliceSESE.addNext(fn);
+ fn=spliceSESE;
+ }
+ 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<currmd.numParameters(); i++) {
+ fm.addParameterTemp(getTempforParam(currmd.getParameter(i)));
+ }
+ state.addFlatCode(currmd,fm);
}
private NodePair flattenBlockNode(BlockNode bn) {
} else if (isNode(decl,"block")) {
} else if (isNode(decl,"location_order_declaration")) {
parseLocationOrder(cn,decl.getChild("location_order_list"));
- } else throw new Error();
+ } else throw new Error();
}
}
}
if(isNode(loc,"location_property")){
String spinLoc=loc.getChildren().elementAt(0).getLabel();
spinLocSet.add(spinLoc);
- }else{
+ } else {
String lowerLoc=loc.getChildren().elementAt(0).getLabel();
String higherLoc= loc.getChildren().elementAt(1).getLabel();
locOrder.put(higherLoc, lowerLoc);
package IR.Tree;
-
import IR.*;
+import IR.Tree.*;
+import IR.Flat.*;
+import java.util.*;
+import java.io.*;
+import Util.Pair;
public class JavaBuilder {
State state;
+ HashSet<Descriptor> checkedDesc=new HashSet<Descriptor>();
+ HashMap<ClassDescriptor, Integer> classStatus=new HashMap<ClassDescriptor, Integer>();
+ public final int CDNONE=0;
+ public final int CDINIT=1;
+ public final int CDINSTANTIATED=2;
+ BuildIR bir;
+ TypeUtil tu;
+ SemanticCheck sc;
+ BuildFlat bf;
+ Stack<MethodDescriptor> toprocess=new Stack<MethodDescriptor>();
+ HashSet<MethodDescriptor> discovered=new HashSet<MethodDescriptor>();
+
+ /* Maps class/interfaces to all instantiated classes that extend or
+ * implement those classes or interfaces */
+
+ HashMap<ClassDescriptor, Set<ClassDescriptor>> implementationMap=new HashMap<ClassDescriptor, Set<ClassDescriptor>>();
+
+ /* Maps methods to the methods they call */
+
+ HashMap<MethodDescriptor, Set<MethodDescriptor>> callMap=new HashMap<MethodDescriptor, Set<MethodDescriptor>>();
+
+ /* Invocation map */
+ HashMap<ClassDescriptor, Set<Pair<MethodDescriptor, MethodDescriptor>>> invocationMap=new HashMap<ClassDescriptor, Set<Pair<MethodDescriptor, MethodDescriptor>>>();
+
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<String> sourcefiles) {
- BuildIR bir=new BuildIR(state);
- TypeUtil tu=new TypeUtil(state, bir);
+ public BuildFlat getBuildFlat() {
+ return bf;
+ }
- for(int i=0;i<sourcefiles.size();i++)
- loadClass(bir, sourcefiles.get(i));
+ public void build() {
+ ClassDescriptor mainClass=sc.getClass(null, state.main, SemanticCheck.INIT);
+ MethodDescriptor mainMethod=tu.getMain();
+ toprocess.push(mainMethod);
+ computeFixPoint();
+ }
-
+ void checkMethod(MethodDescriptor md) {
+ try {
+ sc.checkMethodBody(md.getClassDesc(), md);
+ } catch( Error e ) {
+ System.out.println( "Error in "+md );
+ throw e;
+ }
+ }
+
+ void initClassDesc(ClassDescriptor cd) {
+ if (classStatus.get(cd)==null) {
+ classStatus.put(cd, CDINIT);
+ //TODO...LOOK FOR STATIC INITIALIZERS
+ }
+ }
+
+ void computeFixPoint() {
+ while(!toprocess.isEmpty()) {
+ MethodDescriptor md=toprocess.pop();
+ checkMethod(md);
+ initClassDesc(md.getClassDesc());
+ bf.flattenMethod(md.getClassDesc(), md);
+ processFlatMethod(md);
+ }
+ }
+
+ void processCall(MethodDescriptor md, FlatCall fcall) {
+ MethodDescriptor callmd=fcall.getMethod();
+
+ //First handle easy cases...
+ if (callmd.isStatic()||callmd.isConstructor()) {
+ if (!discovered.contains(callmd)) {
+ discovered.add(callmd);
+ toprocess.push(callmd);
+ }
+ callMap.get(md).add(callmd);
+ return;
+ }
- BuildFlat bf=new BuildFlat(state,tu);
- bf.buildFlat();
+ //Otherwise, handle virtual dispatch...
+ ClassDescriptor cn=callmd.getClassDesc();
+ Set<ClassDescriptor> impSet=implementationMap.get(cn);
+ if (!invocationMap.containsKey(cn))
+ invocationMap.put(cn, new HashSet<Pair<MethodDescriptor,MethodDescriptor>>());
+ invocationMap.get(cn).add(new Pair<MethodDescriptor, MethodDescriptor>(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<ClassDescriptor> tovisit=new Stack<ClassDescriptor>();
+ tovisit.add(cdnew);
+
+ while(!tovisit.isEmpty()) {
+ ClassDescriptor cdcurr=tovisit.pop();
+ if (!implementationMap.containsKey(cdcurr))
+ implementationMap.put(cdcurr, new HashSet<ClassDescriptor>());
+ if (implementationMap.get(cdcurr).add(cdnew)) {
+ //new implementation...see if it affects implementationmap
+ if (invocationMap.containsKey(cdcurr)) {
+ for(Pair<MethodDescriptor, MethodDescriptor> 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<MethodDescriptor>());
+
+ 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) {
}
}
- 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);
TypeUtil typeutil;
Stack loopstack;
HashSet toanalyze;
- HashSet completed;
+ HashMap<ClassDescriptor, Integer> 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<ClassDescriptor, Integer>();
+ 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)<fullcheck) {
+ int oldstatus=completed.containsKey(cd)?completed.get(cd):0;
+ completed.put(cd, fullcheck);
- //Set superclass link up
- if (cd.getSuper()!=null) {
- cd.setSuper(getClass(cd.getSuper()));
- if(cd.getSuperDesc().isInterface()) {
- throw new Error("Error! Class " + cd.getSymbol() + " extends interface " + cd.getSuper());
- }
- // Link together Field, Method, and Flag tables so classes
- // inherit these from their superclasses
- cd.getFieldTable().setParent(cd.getSuperDesc().getFieldTable());
- cd.getMethodTable().setParent(cd.getSuperDesc().getMethodTable());
- cd.getFlagTable().setParent(cd.getSuperDesc().getFlagTable());
- }
- // Link together Field, Method tables do classes inherit these from
- // their ancestor interfaces
- Vector<String> 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<REFERENCE) {
+ //Set superclass link up
+ if (cd.getSuper()!=null) {
+ cd.setSuper(getClass(cd, cd.getSuper(), fullcheck));
+ if(cd.getSuperDesc().isInterface()) {
+ throw new Error("Error! Class " + cd.getSymbol() + " extends interface " + cd.getSuper());
+ }
+ // Link together Field, Method, and Flag tables so classes
+ // inherit these from their superclasses
+ cd.getFieldTable().setParent(cd.getSuperDesc().getFieldTable());
+ cd.getMethodTable().setParent(cd.getSuperDesc().getMethodTable());
+ cd.getFlagTable().setParent(cd.getSuperDesc().getFlagTable());
+ }
+ // Link together Field, Method tables do classes inherit these from
+ // their ancestor interfaces
+ Vector<String> 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&&fullcheck>=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);
+ }
}
}
}
} 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 {
}
}
- public void checkTypeDescriptor(TypeDescriptor td) {
+ private void checkTypeDescriptor(ClassDescriptor cd, TypeDescriptor td) {
if (td.isPrimitive())
return; /* Done */
else if (td.isClass()) {
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);
}
public void checkField(ClassDescriptor cd, FieldDescriptor fd) {
- checkTypeDescriptor(fd.getType());
+ checkTypeDescriptor(cd, fd.getType());
}
public void checkConstraintCheck(TaskDescriptor td, SymbolTable nametable, Vector ccs) {
for(int i=0; i<td.numParameters(); i++) {
/* Check that parameter is well typed */
TypeDescriptor param_type=td.getParamType(i);
- checkTypeDescriptor(param_type);
+ checkTypeDescriptor(null, param_type);
/* Check the parameter's flag expression is well formed */
FlagExpressionNode fen=td.getFlag(td.getParameter(i));
/* Check return type */
if (!md.isConstructor() && !md.isStaticBlock())
- if (!md.getReturnType().isVoid())
- checkTypeDescriptor(md.getReturnType());
-
+ if (!md.getReturnType().isVoid()) {
+ checkTypeDescriptor(cd, md.getReturnType());
+ }
for(int i=0; i<md.numParameters(); i++) {
TypeDescriptor param_type=md.getParamType(i);
- checkTypeDescriptor(param_type);
+ checkTypeDescriptor(cd, param_type);
}
/* Link the naming environments */
if (!md.isStatic()) /* Fields aren't accessible directly in a static method, so don't link in this table */
VarDescriptor thisvd=new VarDescriptor(new TypeDescriptor(cd),"this");
md.setThis(thisvd);
}
+ 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);
+ }
}
public void checkMethodBody(ClassDescriptor cd, MethodDescriptor md) {
void checkDeclarationNode(Descriptor md, SymbolTable nametable, DeclarationNode dn) {
VarDescriptor vd=dn.getVarDescriptor();
- checkTypeDescriptor(vd.getType());
+ checkTypeDescriptor(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null), vd.getType());
Descriptor d=nametable.get(vd.getSymbol());
if ((d==null)||
(d instanceof FieldDescriptor)) {
}
void checkClassTypeNode(Descriptor md, SymbolTable nametable, ClassTypeNode tn, TypeDescriptor td) {
- checkTypeDescriptor(tn.getType());
+ checkTypeDescriptor(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null), tn.getType());
}
void checkCastNode(Descriptor md, SymbolTable nametable, CastNode cn, TypeDescriptor td) {
/* Get type descriptor */
if (cn.getType()==null) {
NameDescriptor typenamed=cn.getTypeName().getName();
- String typename=getFullName(typenamed.toString());
- TypeDescriptor ntd=new TypeDescriptor(getClass(typename));
+ TypeDescriptor ntd=new TypeDescriptor(getClass(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null), typenamed.toString()));
cn.setType(ntd);
}
/* Check the type descriptor */
TypeDescriptor cast_type=cn.getType();
- checkTypeDescriptor(cast_type);
+ checkTypeDescriptor(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null),cast_type);
/* Type check */
if (td!=null) {
} else if (o instanceof Character) {
ln.setType(new TypeDescriptor(TypeDescriptor.CHAR));
} else if (o instanceof String) {
- ln.setType(new TypeDescriptor(getClass(TypeUtil.StringClass)));
+ ln.setType(new TypeDescriptor(getClass(null, TypeUtil.StringClass)));
}
if (td!=null)
if(varname.equals("this")) {
throw new Error("Error: access this obj in a static block");
}
- cd=getClass(getFullName(varname));
+ cd=getClass(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null), varname);
if(cd != null) {
// this is a class name
nn.setClassDesc(cd);
throw new Error("Name "+varname+" should not be used in " + md);
}
}
- cd=getClass(varname);
+ cd=getClass(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null), varname);
if(cd != null) {
// this is a class name
nn.setClassDesc(cd);
void checkOffsetNode(Descriptor md, SymbolTable nameTable, OffsetNode ofn, TypeDescriptor td) {
TypeDescriptor ltd=ofn.td;
- checkTypeDescriptor(ltd);
+ checkTypeDescriptor(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null),ltd);
String fieldname = ofn.fieldname;
FieldDescriptor fd=null;
if (td!=null&&!td.isBoolean())
throw new Error("Expecting type "+td+"for instanceof expression");
- checkTypeDescriptor(tn.getExprType());
+ checkTypeDescriptor(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null), tn.getExprType());
checkExpressionNode(md, nametable, tn.getExpr(), null);
}
if (an.getDest().getType().isString()&&an.getOperation().getOp()==AssignOperation.PLUSEQ) {
//String add
- ClassDescriptor stringcl=getClass(TypeUtil.StringClass);
+ ClassDescriptor stringcl=getClass(null, TypeUtil.StringClass);
TypeDescriptor stringtd=new TypeDescriptor(stringcl);
NameDescriptor nd=new NameDescriptor("String");
NameDescriptor valuend=new NameDescriptor(nd, "valueOf");
}
TypeDescriptor typetolookin = con.getType();
- checkTypeDescriptor(typetolookin);
+ checkTypeDescriptor(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null), typetolookin);
if (td != null && !typeutil.isSuperorType(td, typetolookin))
throw new Error(typetolookin + " isn't a " + td);
//we have a type
ClassDescriptor cd = null;
//if (min.getBaseName().getSymbol().equals("System.out"))
- cd=getClass("System");
+ cd=getClass(null, "System");
/*else {
cd=getClass(min.getBaseName().getSymbol());
}*/
case Operation.ADD:
if (ltd.isString()||rtd.isString()) {
- ClassDescriptor stringcl=getClass(TypeUtil.StringClass);
+ ClassDescriptor stringcl=getClass(null, TypeUtil.StringClass);
TypeDescriptor stringtd=new TypeDescriptor(stringcl);
NameDescriptor nd=new NameDescriptor("String");
NameDescriptor valuend=new NameDescriptor(nd, "valueOf");
}
}
- public String getFullName(String classIn) {
- return (String) ((this.classnameMappings.containsKey(classIn))?classnameMappings.get(classIn):classIn);
- }
}
import IR.Tree.ParseNode;
import IR.Tree.BuildIR;
+import IR.Tree.JavaBuilder;
import IR.Tree.SemanticCheck;
import IR.Flat.BuildCodeMultiCore;
import IR.Flat.BuildCodeMGC;
State.logEvent("Done Parsing Commands");
SSJavaAnalysis ssjava=new SSJavaAnalysis(state);
- BuildIR bir=new BuildIR(state);
- TypeUtil tu=new TypeUtil(state, bir);
- SemanticCheck sc=new SemanticCheck(state,tu);
+ TypeUtil tu;
+ BuildFlat bf;
- for(int i=0;i<sourcefiles.size();i++)
- loadClass(state, bir, sourcefiles.get(i));
-
- //Stuff the runtime wants to see
-
- if (state.TASK) {
- sc.getClass("TagDescriptor");
+ if (true) {
+ BuildIR bir=new BuildIR(state);
+ tu=new TypeUtil(state, bir);
+ SemanticCheck sc=new SemanticCheck(state,tu);
+
+ for(int i=0;i<sourcefiles.size();i++)
+ loadClass(state, bir, sourcefiles.get(i));
+
+ //Stuff the runtime wants to see
+
+ if (state.TASK) {
+ sc.getClass(null, "TagDescriptor");
+ }
+
+ sc.semanticCheck();
+ State.logEvent("Done Semantic Checking");
+
+ tu.createFullTable();
+ State.logEvent("Done Creating TypeUtil");
+
+ bf=new BuildFlat(state,tu);
+ bf.buildFlat();
+ State.logEvent("Done Building Flat");
+ } else {
+ JavaBuilder jb=new JavaBuilder(state);
+ jb.build();
+ tu=jb.getTypeUtil();
+ bf=jb.getBuildFlat();
}
-
- sc.semanticCheck();
- State.logEvent("Done Semantic Checking");
-
- tu.createFullTable();
- State.logEvent("Done Creating TypeUtil");
-
- BuildFlat bf=new BuildFlat(state,tu);
- bf.buildFlat();
- State.logEvent("Done Building Flat");
-
+
SafetyAnalysis sa=null;
PrefetchAnalysis pa=null;
OoOJavaAnalysis oooa=null;