package js.tinyvm; import java.io.*; import java.util.*; import js.classfile.*; /** * Abstraction for dumped binary. */ public class Binary implements SpecialClassConstants, SpecialSignatureConstants { // State that is written to the binary: final RecordTable iEntireBinary = new Sequence(); // Contents of binary: final MasterRecord iMasterRecord = new MasterRecord (this); final EnumerableSet iClassTable = new EnumerableSet(); final EnumerableSet iConstantTable = new EnumerableSet(); final RecordTable iEntryClassIndices = new Sequence(); final RecordTable iMethodTables = new Sequence(); final RecordTable iInstanceFieldTables = new Sequence(); final RecordTable iStaticFields = new Sequence(); final RecordTable iExceptionTables = new EnumerableSet(); final RecordTable iStaticState = new Sequence (true); final RecordTable iCodeSequences = new Sequence(); final RecordTable iConstantValues = new Sequence(); // Other state: final Hashtable iSpecialSignatures = new Hashtable(); final Hashtable iClasses = new Hashtable(); final HashVector iSignatures = new HashVector(); public void dump (ByteWriter aOut) throws Exception { iEntireBinary.dump (aOut); } public boolean hasMain (String aClassName) { ClassRecord pRec = getClassRecord (aClassName); return pRec.hasMethod (new Signature ("main", "([Ljava/lang/String;)V"), true); } public ClassRecord getClassRecord (String aClassName) { return (ClassRecord) iClasses.get (aClassName); } public int getClassIndex (String aClassName) { return getClassIndex (getClassRecord (aClassName)); } public int getClassIndex (ClassRecord aRec) { if (aRec == null) return -1; return iClassTable.indexOf (aRec); } public int getConstantIndex (ConstantRecord aRec) { if (aRec == null) return -1; return iConstantTable.indexOf (aRec); } public ConstantRecord getConstantRecord (int aIndex) { return (ConstantRecord) iConstantTable.elementAt (aIndex); } public void processClasses (Vector aEntryClasses, ClassPath aClassPath) throws Exception { Vector pInterfaceMethods = new Vector(); // Add special classes first for (int i = 0; i < CLASSES.length; i++) { String pName = CLASSES[i]; ClassRecord pRec = ClassRecord.getClassRecord (pName, aClassPath, this); iClasses.put (pName, pRec); iClassTable.add (pRec); // pRec.useAllMethods(); } // Now add entry classes int pEntrySize = aEntryClasses.size(); for (int i = 0; i < pEntrySize; i++) { String pName = (String) aEntryClasses.elementAt (i); ClassRecord pRec = ClassRecord.getClassRecord (pName, aClassPath, this); iClasses.put (pName, pRec); iClassTable.add (pRec); pRec.useAllMethods(); // Update table of indices to entry classes iEntryClassIndices.add (new EntryClassIndex (this, pName)); } Assertion.trace ("Starting with " + iClassTable.size() + " classes."); // Now add the closure. // Yes, call iClassTable.size() in every pass of the loop. for (int pIndex = 0; pIndex < iClassTable.size(); pIndex++) { ClassRecord pRec = (ClassRecord) iClassTable.elementAt(pIndex); Assertion.verbose (1, "Class " + pIndex + ": " + pRec.iName); pRec.storeReferredClasses (iClasses, iClassTable, aClassPath, pInterfaceMethods); } // Initialize indices and flags int pSize = iClassTable.size(); for (int pIndex = 0; pIndex < pSize; pIndex++) { ClassRecord pRec = (ClassRecord) iClassTable.elementAt(pIndex); for (int i=0; i