method_number = mn;
break;
}
}
if (method_number < 0){ // Mmmmh. Can we be sure BCEL does not sometimes instantiate new objects?
throw new AssertionViolatedException("Could not find a known BCEL Method object in the corresponding BCEL JavaClass object.");
}
localVariablesInfos[method_number] = new LocalVariablesInfo(obj.getMaxLocals());
int num_of_lvt_attribs = 0;
// Now iterate through the attributes the Code attribute has.
Attribute[] atts = obj.getAttributes();
for (int a=0; a<atts.length; a++){
if ((! (atts[a] instanceof LineNumberTable)) &&
(! (atts[a] instanceof LocalVariableTable))){
addMessage("Attribute '"+tostring(atts[a])+"' as an attribute of Code attribute '"+tostring(obj)+"' (method '"+m+"') is unknown and will therefore be ignored.");
}
else{// LineNumberTable or LocalVariableTable
addMessage("Attribute '"+tostring(atts[a])+"' as an attribute of Code attribute '"+tostring(obj)+"' (method '"+m+"') will effectively be ignored and is only useful for debuggers and such.");
}
//LocalVariableTable check (partially delayed to Pass3a).
//Here because its easier to collect the information of the
//(possibly more than one) LocalVariableTables belonging to
//one certain Code attribute.
if (atts[a] instanceof LocalVariableTable){ // checks conforming to vmspec2 4.7.9
LocalVariableTable lvt = (LocalVariableTable) atts[a];
checkIndex(lvt, lvt.getNameIndex(), CONST_Utf8);
String lvtname = ((ConstantUtf8) cp.getConstant(lvt.getNameIndex())).getBytes();
if (! lvtname.equals("LocalVariableTable")){
throw new ClassConstraintException("The LocalVariableTable attribute '"+tostring(lvt)+"' is not correctly named 'LocalVariableTable' but '"+lvtname+"'.");
}
Code code = obj;
//In JustIce, the check for correct offsets into the code array is delayed to Pass 3a.
LocalVariable[] localvariables = lvt.getLocalVariableTable();
for (int i=0; i<localvariables.length; i++){
checkIndex(lvt, localvariables[i].getNameIndex(), CONST_Utf8);
String localname = ((ConstantUtf8) cp.getConstant(localvariables[i].getNameIndex())).getBytes();
if (!validJavaIdentifier(localname)){
throw new ClassConstraintException("LocalVariableTable '"+tostring(lvt)+"' references a local variable by the name '"+localname+"' which is not a legal Java simple name.");
}
checkIndex(lvt, localvariables[i].getSignatureIndex(), CONST_Utf8);
String localsig = ((ConstantUtf8) (cp.getConstant(localvariables[i].getSignatureIndex()))).getBytes(); // Local signature(=descriptor)
Type t;
try{
t = Type.getType(localsig);
}
catch (ClassFormatException cfe){
throw new ClassConstraintException("Illegal descriptor (==signature) '"+localsig+"' used by LocalVariable '"+tostring(localvariables[i])+"' referenced by '"+tostring(lvt)+"'.");
}
int localindex = localvariables[i].getIndex();
if ( ( (t==Type.LONG || t==Type.DOUBLE)? localindex+1:localindex) >= code.getMaxLocals()){
throw new ClassConstraintException("LocalVariableTable attribute '"+tostring(lvt)+"' references a LocalVariable '"+tostring(localvariables[i])+"' with an index that exceeds the surrounding Code attribute's max_locals value of '"+code.getMaxLocals()+"'.");
}
try{
localVariablesInfos[method_number].add(localindex, localname, localvariables[i].getStartPC(), localvariables[i].getLength(), t);
}
catch(LocalVariableInfoInconsistentException lviie){
throw new ClassConstraintException("Conflicting information in LocalVariableTable '"+tostring(lvt)+"' found in Code attribute '"+tostring(obj)+"' (method '"+tostring(m)+"'). "+lviie.getMessage());
}
}// for all local variables localvariables[i] in the LocalVariableTable attribute atts[a] END
num_of_lvt_attribs++;
if (num_of_lvt_attribs > obj.getMaxLocals()){
throw new ClassConstraintException("Number of LocalVariableTable attributes of Code attribute '"+tostring(obj)+"' (method '"+tostring(m)+"') exceeds number of local variable slots '"+obj.getMaxLocals()+"' ('There may be no more than one LocalVariableTable attribute per local variable in the Code attribute.').");
}
}// if atts[a] instanceof LocalVariableTable END
}// for all attributes atts[a] END
} catch (ClassNotFoundException e) {
// FIXME: this might not be the best way to handle missing classes.
throw new AssertionViolatedException("Missing class: " + e.toString());
}
}// visitCode(Code) END