use of com.jopdesign.common.misc.JavaClassFormatError in project jop by jop-devel.
the class JOPModel method getJavaImplementation.
public MethodInfo getJavaImplementation(AppInfo ai, MethodInfo context, Instruction instr) {
ClassInfo receiver = ai.getClassInfo(JVM_CLASS);
String methodName = "f_" + JopInstr.name(getNativeOpCode(context, instr));
Set<MethodInfo> mi = receiver.getMethodByName(methodName);
if (!mi.isEmpty()) {
if (mi.size() > 1) {
throw new JavaClassFormatError("JVM class " + JVM_CLASS + " has more than one implementation of " + methodName);
}
return mi.iterator().next();
}
return null;
}
use of com.jopdesign.common.misc.JavaClassFormatError in project jop by jop-devel.
the class ClinitOrder method findDependencies.
private Set<ClassInfo> findDependencies(MethodInfo method, boolean inRec) {
// System.out.println("find dep. in "+cli.clazz.getClassName()+":"+mi.getMethod().getName());
Set<ClassInfo> depends = new HashSet<ClassInfo>();
if (method.isNative() || method.isAbstract()) {
// subclasses???? :-(
return depends;
}
ClassInfo classInfo = method.getClassInfo();
ConstantPoolGen cpoolgen = method.getConstantPoolGen();
InstructionList il = method.getCode().getInstructionList();
InstructionFinder f = new InstructionFinder(il);
// TODO can we encounter an empty instruction list?
//if(il.getStart() == null) {
// return depends;
//}
// find instructions that access the constant pool
// collect all indices to constants in ClassInfo
String cpInstr = "CPInstruction";
for (Iterator it = f.search(cpInstr); it.hasNext(); ) {
InstructionHandle[] match = (InstructionHandle[]) it.next();
InstructionHandle first = match[0];
CPInstruction ii = (CPInstruction) first.getInstruction();
int idx = ii.getIndex();
Constant co = cpoolgen.getConstant(idx);
ClassRef classRef = null;
Set addDepends = null;
ClassInfo clinfo;
MethodInfo minfo;
switch(co.getTag()) {
case Constants.CONSTANT_Class:
classRef = classInfo.getConstantInfo(co).getClassRef();
clinfo = classRef.getClassInfo();
if (clinfo != null) {
minfo = clinfo.getMethodInfo("<init>()V");
if (minfo != null) {
addDepends = findDependencies(minfo, true);
}
}
break;
case Constants.CONSTANT_Fieldref:
case Constants.CONSTANT_InterfaceMethodref:
classRef = classInfo.getConstantInfo(co).getClassRef();
break;
case Constants.CONSTANT_Methodref:
ConstantMethodInfo mref = (ConstantMethodInfo) classInfo.getConstantInfo(co);
classRef = mref.getClassRef();
minfo = mref.getMethodRef().getMethodInfo();
if (minfo != null) {
addDepends = findDependencies(minfo, true);
}
break;
}
if (classRef != null) {
ClassInfo clinf = classRef.getClassInfo();
if (clinf != null) {
if (clinf.getMethodInfo(clinitSig) != null) {
// don't add myself as dependency
if (!clinf.equals(method.getClassInfo())) {
depends.add(clinf);
}
}
}
}
if (addDepends != null) {
for (Object addDepend : addDepends) {
ClassInfo addCli = (ClassInfo) addDepend;
if (addCli.equals(method.getClassInfo())) {
throw new JavaClassFormatError("cyclic indirect <clinit> dependency");
}
depends.add(addCli);
}
}
}
return depends;
}
use of com.jopdesign.common.misc.JavaClassFormatError in project jop by jop-devel.
the class InvokeSite method getInvokeeRef.
/**
* Get the MethodRef to the referenced method. If the instruction is handled in java, return a reference
* to the method which implements the instruction.
* <p>
* The MethodRef refers to the actual reference. {@link MethodRef#getMethodInfo()} resolves the actual
* MethodInfo, which might be defined in a super class of the referenced method, if the method is inherited.
* For invokespecial, the implementing method might even be defined in a subclass of the referenced method,
* if resolveSuper is set to false, see {@link #isInvokeSuper()} for details.
* </p>
* <p>To find all possible implementations if the invocation is a virtual invoke (see {@link #isVirtual()}),
* use {@link AppInfo#findImplementations(InvokeSite)}.</p>
*
* @see #isInvokeSuper()
* @see AppInfo#findImplementations(InvokeSite)
* @param resolveSuper if true, try to resolve the super method reference (see {@link #isInvokeSuper()}),
* else return a reference to the method as it is defined by the instruction.
* @return a method reference to the invokee method.
*/
public MethodRef getInvokeeRef(boolean resolveSuper) {
Instruction instr = instruction.getInstruction();
AppInfo appInfo = AppInfo.getSingleton();
if (instr instanceof InvokeInstruction) {
MethodRef ref = getReferencedMethod(invoker, (InvokeInstruction) instr);
// need to check isInvokeSpecial here, since it is not checked by isSuperMethod!
if (resolveSuper && isInvokeSpecial() && isSuperMethod(ref)) {
ref = resolveInvokeSuper(ref);
}
return ref;
}
if (appInfo.getProcessorModel().isImplementedInJava(invoker, instr)) {
return appInfo.getProcessorModel().getJavaImplementation(appInfo, invoker, instr).getMethodRef();
}
throw new JavaClassFormatError("InvokeSite handle does not refer to an invoke instruction: " + toString());
}
use of com.jopdesign.common.misc.JavaClassFormatError in project jop by jop-devel.
the class MethodInfo method getImplementations.
/**
* Get all non-abstract methods (including this method if it is not abstract) overriding this method.
* @see AppInfo#findImplementations(CallString)
* @see AppInfo#findImplementations(MethodRef)
* @param checkAccess if false, find all non-abstract methods with same signature even if they do not
* override this method.
* @return a collection of all implementations of this method.
*/
public List<MethodInfo> getImplementations(final boolean checkAccess) {
final List<MethodInfo> implementations = new LinkedList<MethodInfo>();
if (checkAccess && (isPrivate() || isStatic())) {
if (isAbstract()) {
throw new JavaClassFormatError("Method is private or static but abstract!: " + toString());
}
implementations.add(this);
return implementations;
}
if ("<init>".equals(getShortName())) {
if (isAbstract()) {
throw new JavaClassFormatError("Found abstract constructor, this isn't right..: " + toString());
}
implementations.add(this);
return implementations;
}
ClassVisitor visitor = new ClassVisitor() {
public boolean visitClass(ClassInfo classInfo) {
MethodInfo m = classInfo.getMethodInfo(getMethodSignature());
if (m != null) {
if (m.isPrivate() && !isPrivate()) {
// found an overriding method which is private .. this is interesting..
logger.error("Found private method " + m.getMethodSignature() + " in " + classInfo.getClassName() + " overriding non-private method in " + getClassInfo().getClassName());
}
if (!m.isAbstract() && (!checkAccess || m.overrides(MethodInfo.this, false))) {
implementations.add(m);
}
}
return true;
}
public void finishClass(ClassInfo classInfo) {
}
};
new ClassHierarchyTraverser(visitor).traverseDown(getClassInfo());
return implementations;
}
use of com.jopdesign.common.misc.JavaClassFormatError in project jop by jop-devel.
the class AppInfo method tryLoadClass.
private ClassInfo tryLoadClass(String className) throws IOException {
loadLogger.debug("Loading class " + className);
InputStream is = classPath.getInputStream(className);
JavaClass javaClass = new ClassParser(is, className).parse();
is.close();
if (javaClass.getMajor() > 50) {
// instruction (requires patching of BCEL code similar to Classpath and InstructionFinder)
throw new JavaClassFormatError("Classfiles with versions 51.0 (Java 7) and above are currently not supported!");
}
return new ClassInfo(new ClassGen(javaClass));
}
Aggregations