use of com.jopdesign.common.misc.JavaClassFormatError in project jop by jop-devel.
the class MethodCode method getReferencedClassName.
/**
* Get the classname or array-type name referenced by an invoke- or field instruction in this code.
*
* @param instr the instruction to check, using this methods constantpool.
* @return the referenced classname or array-typename, to be used for a ClassRef or AppInfo getter.
*/
public String getReferencedClassName(FieldOrMethod instr) {
ConstantPoolGen cpg = getConstantPoolGen();
ReferenceType refType = instr.getReferenceType(cpg);
String classname;
if (refType instanceof ObjectType) {
classname = ((ObjectType) refType).getClassName();
} else if (refType instanceof ArrayType) {
// need to call array.<method>, which class should we use? Let's decide later..
String msg = "Calling a method of an array: " + refType.getSignature() + "#" + instr.getName(cpg) + " in " + methodInfo;
logger.debug(msg);
classname = refType.getSignature();
} else {
// Hu??
throw new JavaClassFormatError("Unknown reference type " + refType);
}
return classname;
}
use of com.jopdesign.common.misc.JavaClassFormatError in project jop by jop-devel.
the class ClassInfo method compile.
/**
* Commit all modifications to this ClassInfo and return a BCEL JavaClass for this ClassInfo.
* <p>
* You may want to call {@link #rebuildConstantPool(ConstantPoolRebuilder)} and {@link #rebuildInnerClasses()} first if needed.
* </p>
* @see MethodInfo#compile()
* @see #rebuildInnerClasses()
* @see #rebuildConstantPool(ConstantPoolRebuilder)
* @see #getJavaClass()
* @return a JavaClass representing this ClassInfo.
*/
public JavaClass compile() {
// We could keep a modified flag in both MethodInfo and FieldInfo
// (maybe even ClassInfo), and update only what is needed here
// could make class-writing,.. faster, but makes code more complex
Field[] fList = classGen.getFields();
if (fList.length != fields.size()) {
// should never happen
throw new JavaClassFormatError("Number of fields in classGen of " + getClassName() + " differs from number of FieldInfos!");
}
for (Field f : fList) {
classGen.replaceField(f, fields.get(f.getName()).getField());
}
Method[] mList = classGen.getMethods();
if (mList.length != methods.size()) {
// should never happen
throw new JavaClassFormatError("Number of methods in classGen of " + getClassName() + " differs from number of MethodInfos!");
}
for (int i = 0; i < mList.length; i++) {
MethodInfo method = methods.get(MemberID.getMethodSignature(mList[i].getName(), mList[i].getSignature()));
classGen.setMethodAt(method.compile(), i);
}
return classGen.getJavaClass();
}
use of com.jopdesign.common.misc.JavaClassFormatError in project jop by jop-devel.
the class ConstantInfo method createFromConstant.
/**
* Create a new constantInfo from a BCEL constant.
* If the constantpool contains invalid data, a {@link JavaClassFormatError} is thrown.
*
* @param cp the constantpool used to resolve the index references.
* @param constant the BCEL constant to convert
* @return a new ConstantInfo containing the constant value.
*/
public static ConstantInfo createFromConstant(ConstantPool cp, Constant constant) {
MemberID sig;
MethodRef methodRef;
ConstantNameAndType nRef;
AppInfo appInfo = AppInfo.getSingleton();
byte tag = constant.getTag();
switch(tag) {
case Constants.CONSTANT_Class:
ClassRef classRef = appInfo.getClassRef(((ConstantClass) constant).getBytes(cp).replace('/', '.'));
return new ConstantClassInfo(classRef);
case Constants.CONSTANT_Fieldref:
ConstantFieldref fRef = (ConstantFieldref) constant;
nRef = (ConstantNameAndType) cp.getConstant(fRef.getNameAndTypeIndex());
sig = new MemberID(fRef.getClass(cp), nRef.getName(cp), nRef.getSignature(cp));
FieldRef fieldRef = appInfo.getFieldRef(sig);
return new ConstantFieldInfo(fieldRef);
case Constants.CONSTANT_Methodref:
ConstantMethodref mRef = (ConstantMethodref) constant;
nRef = (ConstantNameAndType) cp.getConstant(mRef.getNameAndTypeIndex());
sig = new MemberID(mRef.getClass(cp), nRef.getName(cp), nRef.getSignature(cp));
methodRef = appInfo.getMethodRef(sig, false);
return new ConstantMethodInfo(methodRef);
case Constants.CONSTANT_InterfaceMethodref:
ConstantInterfaceMethodref imRef = (ConstantInterfaceMethodref) constant;
nRef = (ConstantNameAndType) cp.getConstant(imRef.getNameAndTypeIndex());
sig = new MemberID(imRef.getClass(cp), nRef.getName(cp), nRef.getSignature(cp));
methodRef = appInfo.getMethodRef(sig, true);
return new ConstantMethodInfo(methodRef);
case Constants.CONSTANT_String:
return new ConstantStringInfo(((ConstantString) constant).getBytes(cp), false);
case Constants.CONSTANT_Integer:
return new ConstantIntegerInfo(((ConstantInteger) constant).getBytes());
case Constants.CONSTANT_Float:
return new ConstantFloatInfo(((ConstantFloat) constant).getBytes());
case Constants.CONSTANT_Long:
return new ConstantLongInfo(((ConstantLong) constant).getBytes());
case Constants.CONSTANT_Double:
return new ConstantDoubleInfo(((ConstantDouble) constant).getBytes());
case Constants.CONSTANT_NameAndType:
String name = ((ConstantNameAndType) constant).getName(cp);
String signature = ((ConstantNameAndType) constant).getSignature(cp);
return new ConstantNameAndTypeInfo(new MemberID(name, signature));
case Constants.CONSTANT_Utf8:
return new ConstantStringInfo(((ConstantUtf8) constant).getBytes(), true);
default:
throw new JavaClassFormatError("Invalid byte tag in constant pool: " + tag);
}
}
use of com.jopdesign.common.misc.JavaClassFormatError in project jop by jop-devel.
the class ClinitOrder method findOrder.
/**
* Find a 'correct' oder for the static <clinit>.
* Throws an error on cyclic dependencies.
*
* @return the ordered list of classes
* @throws JavaClassFormatError if a cyclic dependency has been found.
*/
public List<ClassInfo> findOrder() {
printDependency(false);
Set<ClassInfo> cliSet = clinit.keySet();
List<ClassInfo> order = new LinkedList<ClassInfo>();
int maxIter = cliSet.size();
// maximum loop bound detects cyclic dependency
for (int i = 0; i < maxIter && cliSet.size() != 0; ++i) {
Iterator itCliSet = cliSet.iterator();
while (itCliSet.hasNext()) {
ClassInfo clinf = (ClassInfo) itCliSet.next();
Set<ClassInfo> depends = clinit.get(clinf);
if (depends.size() == 0) {
order.add(clinf);
// element (a leave in the dependent tree
for (ClassInfo clinfInner : clinit.keySet()) {
Set<ClassInfo> dep = clinit.get(clinfInner);
dep.remove(clinf);
}
itCliSet.remove();
}
}
}
if (cliSet.size() != 0) {
printDependency(true);
throw new JavaClassFormatError("Cyclic dependency in <clinit>");
}
return order;
}
use of com.jopdesign.common.misc.JavaClassFormatError in project jop by jop-devel.
the class ConstantPoolRebuilder method copyConstant.
public static Constant copyConstant(Map<Integer, Integer> idMap, Constant c) {
if (c instanceof ConstantClass) {
int index = ((ConstantClass) c).getNameIndex();
return new ConstantClass(idMap.get(index));
} else if (c instanceof ConstantFieldref) {
int clsIdx = ((ConstantFieldref) c).getClassIndex();
int nameIdx = ((ConstantFieldref) c).getNameAndTypeIndex();
return new ConstantFieldref(idMap.get(clsIdx), idMap.get(nameIdx));
} else if (c instanceof ConstantMethodref) {
int clsIdx = ((ConstantMethodref) c).getClassIndex();
int nameIdx = ((ConstantMethodref) c).getNameAndTypeIndex();
return new ConstantMethodref(idMap.get(clsIdx), idMap.get(nameIdx));
} else if (c instanceof ConstantInterfaceMethodref) {
int clsIdx = ((ConstantInterfaceMethodref) c).getClassIndex();
int nameIdx = ((ConstantInterfaceMethodref) c).getNameAndTypeIndex();
return new ConstantInterfaceMethodref(idMap.get(clsIdx), idMap.get(nameIdx));
} else if (c instanceof ConstantString) {
int index = ((ConstantString) c).getStringIndex();
return new ConstantString(idMap.get(index));
} else if (c instanceof ConstantInteger) {
return new ConstantInteger((ConstantInteger) c);
} else if (c instanceof ConstantFloat) {
return new ConstantFloat((ConstantFloat) c);
} else if (c instanceof ConstantLong) {
return new ConstantLong((ConstantLong) c);
} else if (c instanceof ConstantDouble) {
return new ConstantDouble((ConstantDouble) c);
} else if (c instanceof ConstantNameAndType) {
int nameIdx = ((ConstantNameAndType) c).getNameIndex();
int sigIdx = ((ConstantNameAndType) c).getSignatureIndex();
return new ConstantNameAndType(idMap.get(nameIdx), idMap.get(sigIdx));
} else if (c instanceof ConstantUtf8) {
return new ConstantUtf8((ConstantUtf8) c);
}
throw new JavaClassFormatError("Unknown constant type " + c);
}
Aggregations