offsets.add(offset);
}
continue lineNumber_loop;
}
}
throw new ClassConstraintException("Code attribute '"+code+"' has a LineNumberTable attribute '"+code.getLineNumberTable()+"' referring to a code offset ('"+lineNumbers[i].getStartPC()+"') that does not exist.");
}
}
///////////////////////////
// LocalVariableTable(s) //
///////////////////////////
/* We cannot use code.getLocalVariableTable() because there could be more
than only one. This is a bug in BCEL. */
Attribute[] atts = code.getAttributes();
for (int a=0; a<atts.length; a++){
if (atts[a] instanceof LocalVariableTable){
LocalVariableTable lvt = (LocalVariableTable) atts[a];
if (lvt != null){
LocalVariable[] localVariables = lvt.getLocalVariableTable();
for (int i=0; i<localVariables.length; i++){
int startpc = localVariables[i].getStartPC();
int length = localVariables[i].getLength();
if (!contains(instructionPositions, startpc)){
throw new ClassConstraintException("Code attribute '"+code+"' has a LocalVariableTable attribute '"+code.getLocalVariableTable()+"' referring to a code offset ('"+startpc+"') that does not exist.");
}
if ( (!contains(instructionPositions, startpc+length)) && (startpc+length != codeLength) ){
throw new ClassConstraintException("Code attribute '"+code+"' has a LocalVariableTable attribute '"+code.getLocalVariableTable()+"' referring to a code offset start_pc+length ('"+(startpc+length)+"') that does not exist.");
}
}
}
}
}
////////////////////
// ExceptionTable //
////////////////////
// In BCEL's "classfile" API, the startPC/endPC-notation is
// inclusive/exclusive as in the Java Virtual Machine Specification.
// WARNING: This is not true for BCEL's "generic" API.
CodeException[] exceptionTable = code.getExceptionTable();
for (int i=0; i<exceptionTable.length; i++){
int startpc = exceptionTable[i].getStartPC();
int endpc = exceptionTable[i].getEndPC();
int handlerpc = exceptionTable[i].getHandlerPC();
if (startpc >= endpc){
throw new ClassConstraintException("Code attribute '"+code+"' has an exception_table entry '"+exceptionTable[i]+"' that has its start_pc ('"+startpc+"') not smaller than its end_pc ('"+endpc+"').");
}
if (!contains(instructionPositions, startpc)){
throw new ClassConstraintException("Code attribute '"+code+"' has an exception_table entry '"+exceptionTable[i]+"' that has a non-existant bytecode offset as its start_pc ('"+startpc+"').");
}
if ( (!contains(instructionPositions, endpc)) && (endpc != codeLength)){
throw new ClassConstraintException("Code attribute '"+code+"' has an exception_table entry '"+exceptionTable[i]+"' that has a non-existant bytecode offset as its end_pc ('"+startpc+"') [that is also not equal to code_length ('"+codeLength+"')].");
}
if (!contains(instructionPositions, handlerpc)){
throw new ClassConstraintException("Code attribute '"+code+"' has an exception_table entry '"+exceptionTable[i]+"' that has a non-existant bytecode offset as its handler_pc ('"+handlerpc+"').");
}
}
}