⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 controlflowgraph.java

📁 该开源工具主要用于class文件的操作
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		/**		 * Does the actual merging (vmspec2, page 146).		 * Returns true IFF this.inFrame was changed in course of merging with inFrame.		 */		private boolean mergeInFrames(Frame inFrame){			// TODO: Can be performance-improved.			Frame inF = (Frame) inFrames.get(lastExecutionJSR());			OperandStack oldstack = inF.getStack().getClone();			LocalVariables oldlocals = inF.getLocals().getClone();			try{				inF.getStack().merge(inFrame.getStack());				inF.getLocals().merge(inFrame.getLocals());			}			catch (StructuralCodeConstraintException sce){				extendMessageWithFlow(sce);				throw sce;			}			if (	oldstack.equals(inF.getStack()) &&						oldlocals.equals(inF.getLocals()) ){				return false;			}			else{				return true;			}		}		/**		 * Returns the control flow execution chain. This is built		 * while execute(Frame, ArrayList)-ing the code represented		 * by the surrounding ControlFlowGraph.		 */		private String getExecutionChain(){			String s = this.toString();			for (int i=executionPredecessors.size()-1; i>=0; i--){				s = executionPredecessors.get(i)+"\n" + s;			}			return s;		}		/**		 * Extends the StructuralCodeConstraintException ("e") object with an at-the-end-extended message.		 * This extended message will then reflect the execution flow needed to get to the constraint		 * violation that triggered the throwing of the "e" object.		 */		private void extendMessageWithFlow(StructuralCodeConstraintException e){			String s = "Execution flow:\n";			e.extendMessage("", s+getExecutionChain());		}		/*		 * Fulfils the contract of InstructionContext.getInstruction().		 */		public InstructionHandle getInstruction(){			return instruction;		}		/**		 * Returns the InstructionContextImpl with an JSR/JSR_W		 * that was last in the ExecutionChain, without		 * a corresponding RET, i.e.		 * we were called by this one.		 * Returns null if we were called from the top level.		 */		private InstructionContextImpl lastExecutionJSR(){						int size = executionPredecessors.size();			int retcount = 0;						for (int i=size-1; i>=0; i--){				InstructionContextImpl current = (InstructionContextImpl) (executionPredecessors.get(i));				Instruction currentlast = current.getInstruction().getInstruction();				if (currentlast instanceof RET) retcount++;				if (currentlast instanceof JsrInstruction){					retcount--;					if (retcount == -1) return current;				}			}			return null;		}		/* Satisfies InstructionContext.getSuccessors(). */		public InstructionContext[] getSuccessors(){			return contextsOf(_getSuccessors());		}		/**		 * A utility method that calculates the successors of a given InstructionHandle		 * That means, a RET does have successors as defined here.		 * A JsrInstruction has its target as its successor		 * (opposed to its physical successor) as defined here.		 */// TODO: implement caching!		private InstructionHandle[] _getSuccessors(){			final InstructionHandle[] empty = new InstructionHandle[0];			final InstructionHandle[] single = new InstructionHandle[1];			final InstructionHandle[] pair = new InstructionHandle[2];					Instruction inst = getInstruction().getInstruction();					if (inst instanceof RET){				Subroutine s = subroutines.subroutineOf(getInstruction());				if (s==null){ //return empty; // RET in dead code. "empty" would be the correct answer, but we know something about the surrounding project...					throw new AssertionViolatedException("Asking for successors of a RET in dead code?!");				}//TODO: removethrow new AssertionViolatedException("DID YOU REALLY WANT TO ASK FOR RET'S SUCCS?");/*				InstructionHandle[] jsrs = s.getEnteringJsrInstructions();				InstructionHandle[] ret = new InstructionHandle[jsrs.length];				for (int i=0; i<jsrs.length; i++){					ret[i] = jsrs[i].getNext();				}				return ret;*/			}					// Terminates method normally.			if (inst instanceof ReturnInstruction){				return empty;			}					// Terminates method abnormally, because JustIce mandates			// subroutines not to be protected by exception handlers.			if (inst instanceof ATHROW){				return empty;			}					// See method comment.			if (inst instanceof JsrInstruction){				single[0] = ((JsrInstruction) inst).getTarget();				return single;			}			if (inst instanceof GotoInstruction){				single[0] = ((GotoInstruction) inst).getTarget();				return single;			}			if (inst instanceof BranchInstruction){				if (inst instanceof Select){					// BCEL's getTargets() returns only the non-default targets,					// thanks to Eli Tilevich for reporting.					InstructionHandle[] matchTargets = ((Select) inst).getTargets();					InstructionHandle[] ret = new InstructionHandle[matchTargets.length+1];					ret[0] = ((Select) inst).getTarget();					System.arraycopy(matchTargets, 0, ret, 1, matchTargets.length);					return ret;				}				else{					pair[0] = getInstruction().getNext();					pair[1] = ((BranchInstruction) inst).getTarget();					return pair;				}			}			// default case: Fall through.					single[0] = getInstruction().getNext();			return single;		}	} // End Inner InstructionContextImpl Class.	/** The MethofGen object we're working on. */	private final MethodGen method_gen;	/** The Subroutines object for the method whose control flow is represented by this ControlFlowGraph. */	private final Subroutines subroutines;	/** The ExceptionHandlers object for the method whose control flow is represented by this ControlFlowGraph. */	private final ExceptionHandlers exceptionhandlers;	/** All InstructionContext instances of this ControlFlowGraph. */	private Hashtable instructionContexts = new Hashtable(); //keys: InstructionHandle, values: InstructionContextImpl	/** 	 * A Control Flow Graph.	 */	public ControlFlowGraph(MethodGen method_gen){		subroutines = new Subroutines(method_gen);		exceptionhandlers = new ExceptionHandlers(method_gen);		InstructionHandle[] instructionhandles = method_gen.getInstructionList().getInstructionHandles();		for (int i=0; i<instructionhandles.length; i++){			instructionContexts.put(instructionhandles[i], new InstructionContextImpl(instructionhandles[i]));		}				this.method_gen = method_gen;	}	/**	 * Returns the InstructionContext of a given instruction.	 */	public InstructionContext contextOf(InstructionHandle inst){		InstructionContext ic = (InstructionContext) instructionContexts.get(inst);		if (ic == null){			throw new AssertionViolatedException("InstructionContext requested for an InstructionHandle that's not known!");		}		return ic;	}	/**	 * Returns the InstructionContext[] of a given InstructionHandle[],	 * in a naturally ordered manner.	 */	public InstructionContext[] contextsOf(InstructionHandle[] insts){		InstructionContext[] ret = new InstructionContext[insts.length];		for (int i=0; i<insts.length; i++){			ret[i] = contextOf(insts[i]);		}		return ret;	}	/**	 * Returns an InstructionContext[] with all the InstructionContext instances	 * for the method whose control flow is represented by this ControlFlowGraph	 * <B>(NOT ORDERED!)</B>.	 */	public InstructionContext[] getInstructionContexts(){		InstructionContext[] ret = new InstructionContext[instructionContexts.values().size()];		return (InstructionContext[]) instructionContexts.values().toArray(ret);	}	/**	 * Returns true, if and only if the said instruction is not reachable; that means,	 * if it not part of this ControlFlowGraph.	 */	public boolean isDead(InstructionHandle i){		return instructionContexts.containsKey(i);	}	 }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -