use of org.apache.bcel.generic.InstructionList 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.InstructionList in project jop by jop-devel.
the class ConstantPoolRebuilder method updateMethodGen.
public void updateMethodGen(MethodInfo methodInfo, MethodGen methodGen) {
methodGen.setConstantPool(newPool);
if (methodInfo.hasCode()) {
// update all instructions
InstructionList il = methodInfo.getCode().getInstructionList();
class InstructionVisitor extends EmptyVisitor {
@Override
public void visitCPInstruction(CPInstruction obj) {
obj.setIndex(mapIndex(obj.getIndex()));
}
}
InstructionVisitor iv = new InstructionVisitor();
for (InstructionHandle ih : il.getInstructionHandles()) {
ih.getInstruction().accept(iv);
}
updateAttributes(methodInfo, methodGen.getCodeAttributes());
}
updateAttributes(methodInfo, methodGen.getAttributes());
}
use of org.apache.bcel.generic.InstructionList 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.InstructionList in project jop by jop-devel.
the class BasicBlock method buildBasicBlocks.
/**
* Create a vector of basic blocks, annotated with flow information
*
* @param methodCode The MethodCode of the method from which basic blocks should be extracted.
* @return A vector of BasicBlocks, which instruction handles annotated with
* flow information.
*/
static List<BasicBlock> buildBasicBlocks(MethodCode methodCode) {
InstructionTargetVisitor itv = new InstructionTargetVisitor(methodCode);
List<BasicBlock> basicBlocks = new LinkedList<BasicBlock>();
// We do want to have the latest code, so we compile any existing, *attached* CFG first.
// However, we do NOT want to remove this CFG, and we do *NOT* want to trigger the onBeforeCodeModify event,
// else we might remove all CFGs for this method, which we want to avoid if we only modify the graph but do not
// compile it (the event will be triggered when CFG#compile() is called).
InstructionList il = methodCode.getInstructionList(true, false);
il.setPositions(true);
/* Step 1: compute flow info */
for (InstructionHandle ih : il.getInstructionHandles()) {
ih.addAttribute(InstrField.FLOW_INFO, itv.getFlowInfo(ih));
}
/* Step 2: create basic blocks */
{
BasicBlock bb = new BasicBlock(methodCode);
InstructionHandle[] handles = il.getInstructionHandles();
for (int i = 0; i < handles.length; i++) {
InstructionHandle ih = handles[i];
bb.addInstruction(ih);
boolean doSplit = getFlowInfo(ih).doSplitAfter();
if (i + 1 < handles.length) {
doSplit |= itv.isTarget(handles[i + 1]);
doSplit |= getFlowInfo(handles[i + 1]).doSplitBefore();
}
if (doSplit) {
bb.setExitFlowInfo(getFlowInfo(ih));
basicBlocks.add(bb);
bb = new BasicBlock(methodCode);
}
ih.removeAttribute(InstrField.FLOW_INFO);
}
if (!bb.getInstructions().isEmpty()) {
// be nice to DFA stuff, and ignore NOPs
for (int i = bb.getInstructions().size() - 1; i >= 0; --i) {
InstructionHandle x = bb.getInstructions().get(i);
if (x.getInstruction().getOpcode() != Constants.NOP) {
throw new AssertionError("[INTERNAL ERROR] Last instruction " + x + " in code does not change control flow - this is impossible");
}
}
}
}
return basicBlocks;
}
use of org.apache.bcel.generic.InstructionList in project jop by jop-devel.
the class InstructionInterpreter method getExitInstruction.
public InstructionHandle getExitInstruction() {
InstructionHandle exit = (InstructionHandle) methodInfo.getCustomValue(KEY_NOP);
if (exit == null) {
exit = new InstructionList().append(new NOP());
methodInfo.setCustomValue(KEY_NOP, exit);
}
return exit;
}
Aggregations