package js.tinyvm;
import java.io.IOException;
import js.tinyvm.io.IByteWriter;
import js.tinyvm.io.IOUtilities;
import org.apache.bcel.classfile.CodeException;
import org.apache.bcel.classfile.ConstantClass;
import org.apache.bcel.classfile.JavaClass;
public class ExceptionRecord implements WritableData
{
CodeException iExcep;
ClassRecord iClassRecord;
Binary iBinary;
public ExceptionRecord (CodeException aExcep, Binary aBinary, JavaClass aCF)
throws Exception
{
iExcep = aExcep;
int pCPIndex = aExcep.getCatchType();
if (pCPIndex == 0)
{
// An index of 0 means ANY.
iClassRecord = aBinary.getClassRecord("java/lang/Throwable");
}
else
{
ConstantClass pCls = (ConstantClass) aCF.getConstantPool()
.getConstant(pCPIndex);
String pName = pCls.getBytes(aCF.getConstantPool());
iClassRecord = aBinary.getClassRecord(pName);
}
if (iClassRecord == null)
{
throw new TinyVMException("Exception not found: " + iExcep);
}
// Probably don't need to do this but it is probably best to be safe...
iClassRecord.markUsed();
iBinary = aBinary;
}
public int getLength ()
{
return IOUtilities.adjustedSize(2 + // start
2 + // end
2 + // handler
1, // class index
2);
}
public void dump (IByteWriter aOut) throws TinyVMException
{
int pStart = iExcep.getStartPC();
int pEnd = iExcep.getEndPC();
int pHandler = iExcep.getHandlerPC();
int pClass = iBinary.getClassIndex(iClassRecord);
if (pStart > TinyVMConstants.MAX_CODE || pEnd > TinyVMConstants.MAX_CODE
|| pHandler > TinyVMConstants.MAX_CODE)
{
throw new TinyVMException("Exception handler with huge PCs");
}
if (pClass < 0)
{
throw new TinyVMException("Exception class record missing");
}
//System.out.println("Sart " + pStart + " end " + pEnd + " class " + pClass + " Handler " + pHandler);
try
{
aOut.writeU2(pStart);
aOut.writeU2(pEnd);
aOut.writeU2(pHandler);
aOut.writeU1(pClass);
IOUtilities.writePadding(aOut, 2);
}
catch (IOException e)
{
throw new TinyVMException(e.getMessage(), e);
}
}
public boolean equals (Object aOther)
{
if (!(aOther instanceof ExceptionRecord))
return false;
return ((ExceptionRecord) aOther).iExcep.equals(iExcep);
}
public int hashCode ()
{
return iExcep.hashCode();
}
}