use of org.apache.bcel.generic.ConstantPoolGen in project jop by jop-devel.
the class InlineHelper method checkJVMCall.
private boolean checkJVMCall(InvokeSite invokeSite, MethodInfo invokee) {
if (!invokeSite.isJVMCall()) {
return true;
}
if (inlineConfig.doInlineJVMCalls() == JVMInline.NONE) {
return false;
}
if (inlineConfig.doInlineJVMCalls() == JVMInline.ALL) {
return true;
}
// Check if params and return type match what is expected on the stack due to the instruction to replace
ConstantPoolGen cpg = invokeSite.getInvoker().getConstantPoolGen();
Instruction instr = invokeSite.getInstructionHandle().getInstruction();
if (!TypeHelper.canAssign(StackHelper.consumeStack(cpg, instr), invokee.getArgumentTypes())) {
return false;
}
if (!invokee.getType().equals(Type.VOID)) {
if (!TypeHelper.canAssign(new Type[] { invokee.getType() }, StackHelper.produceStack(cpg, instr))) {
return false;
}
}
return true;
}
use of org.apache.bcel.generic.ConstantPoolGen 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 org.apache.bcel.generic.ConstantPoolGen in project jop by jop-devel.
the class ConstantPoolRebuilder method createNewConstantPool.
public ConstantPoolGen createNewConstantPool(ConstantPoolGen oldPool, Set<Integer> usedIndices) {
// We add all used entries to the new pool in the same order as in the old pool
// to avoid indices getting larger than before
Integer[] ids = new ArrayList<Integer>(usedIndices).toArray(new Integer[usedIndices.size()]);
Arrays.sort(ids);
// First thing we need is a map, since we need to relink the constantpool entries
idMap.clear();
// Note that index 0 is not valid, so skip it
List<Constant> constants = new ArrayList<Constant>(usedIndices.size() + 1);
constants.add(null);
int newPos = 1;
for (int id : ids) {
Constant c = oldPool.getConstant(id);
// we cannot use newPool.addConstant here, because this would add all referenced constants too,
// and we do not want that..
constants.add(c);
idMap.put(id, newPos++);
if (c instanceof ConstantLong || c instanceof ConstantDouble) {
// reserve an additional slot for those
constants.add(null);
newPos++;
}
}
// now we create new constants and map the references
Constant[] newConstants = new Constant[constants.size()];
for (int i = 1; i < constants.size(); i++) {
Constant c = constants.get(i);
if (c == null)
continue;
newConstants[i] = copyConstant(idMap, c);
}
newPool = new ConstantPoolGen(newConstants);
return newPool;
}
use of org.apache.bcel.generic.ConstantPoolGen in project jop by jop-devel.
the class DFATool method buildPrologue.
private MethodInfo buildPrologue(MethodInfo mainMethod, List<InstructionHandle> statements, Flow flow, List<ClassInfo> clinits) {
// we use a prologue sequence for startup
InstructionList prologue = new InstructionList();
ConstantPoolGen prologueCP = mainMethod.getConstantPoolGen();
Instruction instr;
int idx;
// add magic initializers to prologue sequence
if (!analyzeBootMethod) {
instr = new ICONST(0);
prologue.append(instr);
instr = new ICONST(0);
prologue.append(instr);
idx = prologueCP.addMethodref("com.jopdesign.sys.GC", "init", "(II)V");
instr = new INVOKESTATIC(idx);
prologue.append(instr);
}
// add class initializers
for (ClassInfo clinit : clinits) {
MemberID cSig = appInfo.getClinitSignature(clinit.getClassName());
idx = prologueCP.addMethodref(cSig.getClassName(), cSig.getMemberName(), cSig.getDescriptor().toString());
instr = new INVOKESTATIC(idx);
prologue.append(instr);
}
if (analyzeBootMethod) {
// Let's just analyze the full boot method, so that the callgraph-builder is happy.
// Doing this after clinit, so that we have DFA infos on fields in JVMHelp.init()
idx = prologueCP.addMethodref("com.jopdesign.sys.Startup", "boot", "()V");
instr = new INVOKESTATIC(idx);
prologue.append(instr);
}
// add main method
instr = new ACONST_NULL();
prologue.append(instr);
idx = prologueCP.addMethodref(mainMethod.getClassName(), mainMethod.getShortName(), mainMethod.getDescriptor().toString());
instr = new INVOKESTATIC(idx);
prologue.append(instr);
// // invoke startMission() to ensure analysis of threads
// idx = prologueCP.addMethodref("joprt.RtThread", "startMission", "()V");
// instr = new INVOKESTATIC(idx);
// prologue.append(instr);
instr = new NOP();
prologue.append(instr);
prologue.setPositions(true);
// add prologue to program structure
for (Iterator l = prologue.iterator(); l.hasNext(); ) {
InstructionHandle handle = (InstructionHandle) l.next();
statements.add(handle);
if (handle.getInstruction() instanceof GOTO) {
GOTO g = (GOTO) handle.getInstruction();
flow.addEdge(new FlowEdge(handle, g.getTarget(), FlowEdge.NORMAL_EDGE));
} else if (handle.getNext() != null) {
flow.addEdge(new FlowEdge(handle, handle.getNext(), FlowEdge.NORMAL_EDGE));
}
}
MemberID pSig = new MemberID(prologueName, Descriptor.parse(prologueSig));
MethodInfo mi = mainMethod.getClassInfo().createMethod(pSig, null, prologue);
mi.setAccessType(AccessType.ACC_PRIVATE);
return mi;
}
use of org.apache.bcel.generic.ConstantPoolGen in project jop by jop-devel.
the class DescendingClassTraverser method visitConstantPool.
///////////////////////////////////////////////////////////////////
// Other methods to visit only parts of a class
///////////////////////////////////////////////////////////////////
public void visitConstantPool(ClassInfo classInfo) {
ConstantPoolGen cpg = classInfo.getConstantPoolGen();
if (visitor.visitConstantPoolGen(classInfo, cpg)) {
bcelVisitor.setClassInfo(classInfo);
for (int i = 1; i < cpg.getSize(); i++) {
Constant c = cpg.getConstant(i);
// Some entries might be null (continuation of previous entry)
if (c == null)
continue;
c.accept(bcelVisitor);
}
visitor.finishConstantPoolGen(classInfo, cpg);
}
}
Aggregations