package IR; import java.util.*; public class TypeUtil { public static final String StringClass="String"; public static final String ObjectClass="Object"; public static final String StartupClass="StartupObject"; public static final String TagClass="TagDescriptor"; public static final String ThreadClass="Thread"; State state; Hashtable supertable; Hashtable subclasstable; public TypeUtil(State state) { this.state=state; createTables(); } public ClassDescriptor getClass(String classname) { ClassDescriptor cd=(ClassDescriptor)state.getClassSymbolTable().get(classname); return cd; } private void createTables() { supertable=new Hashtable(); Iterator classit=state.getClassSymbolTable().getDescriptorsIterator(); while(classit.hasNext()) { ClassDescriptor cd=(ClassDescriptor)classit.next(); String superc=cd.getSuper(); if (superc!=null) { ClassDescriptor cd_super=getClass(superc); if (cd_super==null) { throw new Error("Couldn't find class:"+superc); } supertable.put(cd,cd_super); } } } public ClassDescriptor getMainClass() { return getClass(state.main); } public MethodDescriptor getRun() { ClassDescriptor cd=getClass(TypeUtil.ThreadClass); for(Iterator methodit=cd.getMethodTable().getSet("run").iterator(); methodit.hasNext();) { MethodDescriptor md=(MethodDescriptor) methodit.next(); if (md.numParameters()!=0||md.getModifiers().isStatic()) continue; return md; } throw new Error("Can't find Thread.run"); } public MethodDescriptor getMain() { ClassDescriptor cd=getMainClass(); Set mainset=cd.getMethodTable().getSet("main"); for(Iterator mainit=mainset.iterator(); mainit.hasNext();) { MethodDescriptor md=(MethodDescriptor)mainit.next(); if (md.numParameters()!=1) continue; Descriptor pd=md.getParameter(0); TypeDescriptor tpd=(pd instanceof TagVarDescriptor) ? ((TagVarDescriptor)pd).getType() : ((VarDescriptor)pd) .getType(); if (tpd.getArrayCount()!=1) continue; if (!tpd.getSymbol().equals("String")) continue; if (!md.getModifiers().isStatic()) throw new Error("Error: Non static main"); return md; } throw new Error(cd+" has no main"); } /** Check to see if md1 is more specific than md2... Informally if md2 could always be called given the arguments passed into md1 */ public boolean isMoreSpecific(MethodDescriptor md1, MethodDescriptor md2) { /* Checks if md1 is more specific than md2 */ if (md1.numParameters()!=md2.numParameters()) throw new Error(); for(int i=0; i