package IR;
import java.util.*;
+
+import IR.Flat.FlatNode;
import IR.Tree.*;
import java.io.File;
import Main.Main;
public static final String StartupClass="StartupObject";
public static final String TagClass="TagDescriptor";
public static final String ThreadClass="Thread";
+ public static final String TaskClass="Task";
State state;
Hashtable supertable;
Hashtable subclasstable;
BuildIR bir;
+
+ // for interfaces
+ Hashtable<ClassDescriptor, Set<ClassDescriptor>> superIFtbl;
public TypeUtil(State state, BuildIR bir) {
this.state=state;
if (f.exists()) {
try {
ParseNode pn=Main.readSourceFile(state, f.getCanonicalPath());
- bir.buildtree(pn, todo);
+ bir.buildtree(pn, todo,f.getCanonicalPath());
return;
} catch (Exception e) {
throw new Error(e);
//have to find class
addNewClass(classname, todo);
cd=(ClassDescriptor)state.getClassSymbolTable().get(classname);
+ cd.setClassLibrary();
+
System.out.println("Build class:"+cd);
todo.add(cd);
}
supertable.put(cd,cd_super);
}
}
+ if (!superIFtbl.containsKey(cd)) {
+ // add inherited interfaces
+ superIFtbl.put(cd,new HashSet());
+ HashSet hs=(HashSet)superIFtbl.get(cd);
+ Vector<String> superifv = cd.getSuperInterface();
+ for(int i = 0; i < superifv.size(); i++) {
+ String superif = superifv.elementAt(i);
+ ClassDescriptor if_super = getClass(superif, todo);
+ hs.add(if_super);
+ }
+ }
return cd;
}
private void createTables() {
supertable=new Hashtable();
+ superIFtbl = new Hashtable<ClassDescriptor,Set<ClassDescriptor>>();
}
public ClassDescriptor getMainClass() {
throw new Error("Can't find Thread.run");
}
+ public MethodDescriptor getStaticStart() {
+ ClassDescriptor cd=getClass(TypeUtil.ThreadClass);
+ for(Iterator methodit=cd.getMethodTable().getSet("staticStart").iterator(); methodit.hasNext();) {
+ MethodDescriptor md=(MethodDescriptor) methodit.next();
+ if (md.numParameters()!=1||!md.getModifiers().isStatic()||!md.getParamType(0).isClass()||md.getParamType(0).getClassDesc()!=cd)
+ continue;
+ return md;
+ }
+ throw new Error("Can't find Thread.run");
+ }
+
+ public MethodDescriptor getExecute() {
+ ClassDescriptor cd = getClass(TypeUtil.TaskClass);
+
+ if(cd == null && state.DSMTASK)
+ throw new Error("Task.java is not included");
+
+ for(Iterator methodit = cd.getMethodTable().getSet("execute").iterator(); methodit.hasNext();) {
+ MethodDescriptor md = (MethodDescriptor) methodit.next();
+ if (md.numParameters()!=0 || md.getModifiers().isStatic())
+ continue;
+ return md;
+ }
+ throw new Error("Can't find Task.execute");
+ }
+
+
public MethodDescriptor getMain() {
ClassDescriptor cd=getMainClass();
Set mainset=cd.getMethodTable().getSet("main");
if (md1.numParameters()!=md2.numParameters())
throw new Error();
for(int i=0; i<md1.numParameters(); i++) {
- if (!this.isSuperorType(md2.getParamType(i), md1.getParamType(i)))
- return false;
+ if (!this.isSuperorType(md2.getParamType(i), md1.getParamType(i))) {
+ if(((!md1.getParamType(i).isArray() &&
+ (md1.getParamType(i).isInt() || md1.getParamType(i).isLong() || md1.getParamType(i).isDouble() || md1.getParamType(i).isFloat()))
+ && md2.getParamType(i).isClass() && md2.getParamType(i).getClassDesc().getSymbol().equals("Object"))) {
+ // primitive parameters vs Object
+ } else {
+ return false;
+ }
+ }
}
if (md1.getReturnType()==null||md2.getReturnType()==null) {
if (md1.getReturnType()!=md2.getReturnType())
public void createFullTable() {
subclasstable=new Hashtable();
+ HashSet tovisit=new HashSet();
+ HashSet visited=new HashSet();
Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
while(classit.hasNext()) {
+ tovisit.clear();
+ visited.clear();
ClassDescriptor cd=(ClassDescriptor)classit.next();
ClassDescriptor tmp=cd.getSuperDesc();
+
+ // check cd's interface ancestors
+ {
+ Iterator it_sifs = cd.getSuperInterfaces();
+ while(it_sifs.hasNext()) {
+ ClassDescriptor cdt = (ClassDescriptor)it_sifs.next();
+ if(!tovisit.contains(cdt)){
+ tovisit.add(cdt);
+ }
+ }
+ }
while(tmp!=null) {
- if (!subclasstable.containsKey(tmp))
- subclasstable.put(tmp,new HashSet());
- HashSet hs=(HashSet)subclasstable.get(tmp);
- hs.add(cd);
- tmp=tmp.getSuperDesc();
+ if (!subclasstable.containsKey(tmp))
+ subclasstable.put(tmp,new HashSet());
+ HashSet hs=(HashSet)subclasstable.get(tmp);
+ hs.add(cd);
+ // check tmp's interface ancestors
+ Iterator it_sifs = tmp.getSuperInterfaces();
+ while(it_sifs.hasNext()) {
+ ClassDescriptor cdt = (ClassDescriptor)it_sifs.next();
+ if(!tovisit.contains(cdt)){
+ tovisit.add(cdt);
+ }
+ }
+
+ tmp=tmp.getSuperDesc();
+ }
+
+ while(!tovisit.isEmpty()) {
+ ClassDescriptor sif = (ClassDescriptor)tovisit.iterator().next();
+ tovisit.remove(sif);
+
+ if(!visited.contains(sif)) {
+ if(!this.subclasstable.containsKey(sif)) {
+ this.subclasstable.put(sif, new HashSet());
+ }
+ HashSet hs = (HashSet)this.subclasstable.get(sif);
+ hs.add(cd);
+
+ Iterator it_sifs = sif.getSuperInterfaces();
+ while(it_sifs.hasNext()) {
+ ClassDescriptor siftmp = (ClassDescriptor)it_sifs.next();
+ if(!tovisit.contains(siftmp)){
+ tovisit.add(siftmp);
+ }
+ }
+ visited.add(sif);
+ }
}
}
}
public ClassDescriptor getSuper(ClassDescriptor cd) {
return (ClassDescriptor)supertable.get(cd);
}
+
+ public Set<ClassDescriptor> getSuperIFs(ClassDescriptor cd) {
+ return superIFtbl.get(cd);
+ }
public boolean isCastable(TypeDescriptor original, TypeDescriptor casttype) {
if (original.isChar()&&
&&(possiblesuper.getArrayCount()<cd2.getArrayCount()))
return true;
+ //Allow arraytype=null statements
+ if (possiblesuper.isArray()&&cd2.isNull())
+ return true;
+
return false;
}
possiblesuper.isFloat()||possiblesuper.isDouble()))
return true;
if (cd2.isInt()&&(possiblesuper.isInt()||possiblesuper.isLong()||
- possiblesuper.isFloat()||possiblesuper.isDouble()))
+ possiblesuper.isFloat()||possiblesuper.isDouble()
+ ||possiblesuper.isEnum()))
return true;
+ if (cd2.isEnum()&&(possiblesuper.isInt()||possiblesuper.isLong()||
+ possiblesuper.isFloat()||possiblesuper.isDouble()))
+ return true;
+ if(cd2.isEnum()&&possiblesuper.isEnum()&&cd2.class_desc.equals(possiblesuper.class_desc))
+ return true;
if (cd2.isLong()&&(possiblesuper.isLong()||
possiblesuper.isFloat()||possiblesuper.isDouble()))
return true;
throw new Error("Case not handled:"+possiblesuper+" "+cd2);
}
+ public TypeDescriptor mostSpecific(TypeDescriptor td1, TypeDescriptor td2) {
+ if( isSuperorType( td1, td2 ) ) {
+ return td2;
+ }
+ if( isSuperorType( td2, td1 ) ) {
+ return td1;
+ }
+ throw new Error( td1+" and "+td2+" have no superclass relationship" );
+ }
+
+ public TypeDescriptor mostSpecific(TypeDescriptor td1, TypeDescriptor td2, TypeDescriptor td3) {
+ return mostSpecific( td1, mostSpecific( td2, td3 ) );
+ }
public boolean isSuperorType(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
if (possiblesuper==cd2)
}
private boolean isSuper(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
+ HashSet tovisit=new HashSet();
+ HashSet visited=new HashSet();
+
+ {
+ // check cd2's interface ancestors
+ Iterator<ClassDescriptor> it_sifs = getSuperIFs(cd2).iterator();
+ while(it_sifs.hasNext()) {
+ ClassDescriptor cd = it_sifs.next();
+ if(cd == possiblesuper) {
+ return true;
+ } else if(!tovisit.contains(cd)){
+ tovisit.add(cd);
+ }
+ }
+ }
+
while(cd2!=null) {
cd2=getSuper(cd2);
if (cd2==possiblesuper)
return true;
+
+ // check cd2's interface ancestors
+ if(cd2 != null) {
+ Iterator it_sifs = getSuperIFs(cd2).iterator();
+ while(it_sifs.hasNext()) {
+ ClassDescriptor cd = (ClassDescriptor)it_sifs.next();
+ if(cd == possiblesuper) {
+ return true;
+ } else if(!tovisit.contains(cd)){
+ tovisit.add(cd);
+ }
+ }
+ }
+ }
+
+ while(!tovisit.isEmpty()) {
+ ClassDescriptor cd = (ClassDescriptor)tovisit.iterator().next();
+ tovisit.remove(cd);
+
+ if(!visited.contains(cd)) {
+ Iterator it_sifs = getSuperIFs(cd).iterator();
+ while(it_sifs.hasNext()) {
+ ClassDescriptor cdt = (ClassDescriptor)it_sifs.next();
+ if(cdt == possiblesuper) {
+ return true;
+ } else if(!tovisit.contains(cdt)){
+ tovisit.add(cdt);
+ }
+ }
+ visited.add(cd);
+ }
}
return false;
}