📄 frame.java
字号:
* * @param ins * the method invocation instruction * @param cpg * the ConstantPoolGen for the class containing the method * @return number of arguments; note that this excludes the object instance * for instance methods * @throws DataflowAnalysisException */ public int getNumArguments(InvokeInstruction ins, ConstantPoolGen cpg) throws DataflowAnalysisException { SignatureParser parser = new SignatureParser(ins.getSignature(cpg)); return parser.getNumParameters(); } /** * Get the number of arguments passed to given method invocation, including * the object instance if the call is to an instance method. * * @param ins * the method invocation instruction * @param cpg * the ConstantPoolGen for the class containing the method * @return number of arguments, including object instance if appropriate * @throws DataflowAnalysisException */ public int getNumArgumentsIncludingObjectInstance(InvokeInstruction ins, ConstantPoolGen cpg) throws DataflowAnalysisException { int numConsumed = ins.consumeStack(cpg); if (numConsumed == Constants.UNPREDICTABLE) throw new DataflowAnalysisException( "Unpredictable stack consumption in " + ins); return numConsumed; } /** * Get the <i>i</i>th argument passed to given method invocation. * * @param ins * the method invocation instruction * @param cpg * the ConstantPoolGen for the class containing the method * @param i * index of the argument; 0 for the first argument, etc. * @param numArguments * total number of arguments to the method * @return the <i>i</i>th argument * @throws DataflowAnalysisException */ @Deprecated public ValueType getArgument(InvokeInstruction ins, ConstantPoolGen cpg, int i, int numArguments) throws DataflowAnalysisException { SignatureParser sigParser = new SignatureParser(ins.getSignature(cpg)); return getArgument(ins, cpg, i, sigParser ); } /** * Get the <i>i</i>th argument passed to given method invocation. * * @param ins * the method invocation instruction * @param cpg * the ConstantPoolGen for the class containing the method * @param i * index of the argument; 0 for the first argument, etc. * @return the <i>i</i>th argument * @throws DataflowAnalysisException */ public ValueType getArgument(InvokeInstruction ins, ConstantPoolGen cpg, int i, SignatureParser sigParser) throws DataflowAnalysisException { if (i >= sigParser.getNumParameters()) throw new IllegalArgumentException("requesting parameter # " + i + " of " + sigParser); return getStackValue(sigParser.getSlotsFromTopOfStackForParameter(i)); } /** * Get the stack slot that will contain given method argument. Assumes that * this frame is at the location (just before) a method invocation * instruction. * * @param i * the argument index: 0 for first arg, etc. * @param numArguments * total number of arguments to the called method * @return slot containing the argument value */ public int getArgumentSlot(int i, int numArguments) { if (i >= numArguments) throw new IllegalArgumentException(); return (slotList.size() - numArguments) + i; } /** * Get the <i>i</i>th operand used by given instruction. * * @param ins * the instruction, which must be a StackConsumer * @param cpg * the ConstantPoolGen * @param i * index of operand to get: 0 for the first operand, etc. * @return the <i>i</i>th operand used by the given instruction * @throws DataflowAnalysisException */ public ValueType getOperand(StackConsumer ins, ConstantPoolGen cpg, int i) throws DataflowAnalysisException { int numOperands = ins.consumeStack(cpg); if (numOperands == Constants.UNPREDICTABLE) throw new DataflowAnalysisException( "Unpredictable stack consumption in " + ins); return getStackValue((numOperands - 1) - i); } /** * Get set of arguments passed to a method invocation which match given * predicate. * * @param invokeInstruction * the InvokeInstruction * @param cpg * the ConstantPoolGen * @param chooser * predicate to choose which argument values should be in the * returned set * @return BitSet specifying which arguments match the predicate, indexed by * argument number (starting from 0) * @throws DataflowAnalysisException */ public BitSet getArgumentSet(InvokeInstruction invokeInstruction, ConstantPoolGen cpg, DataflowValueChooser<ValueType> chooser) throws DataflowAnalysisException { BitSet chosenArgSet = new BitSet(); SignatureParser sigParser = new SignatureParser(invokeInstruction.getSignature(cpg)); for (int i = 0; i < sigParser.getNumParameters(); ++i) { ValueType value = getArgument(invokeInstruction, cpg, i, sigParser); if (chooser.choose(value)) chosenArgSet.set(i); } return chosenArgSet; } /** * Clear the Java operand stack. Only local variable slots will remain in * the frame. */ public void clearStack() { if (!isValid()) throw new IllegalStateException("accessing top or bottom frame"); assert slotList.size() >= numLocals; if (slotList.size() > numLocals) slotList.subList(numLocals, slotList.size()).clear(); } /** * Get the depth of the Java operand stack. */ public int getStackDepth() { return slotList.size() - numLocals; } /** * Get the number of locals. */ public int getNumLocals() { return numLocals; } /** * Get the number of slots (locals plus stack values). */ public int getNumSlots() { return slotList.size(); } /** * Get the value at the <i>n</i>th slot. * * @param n * the slot to get the value of * @return the value in the slot */ public ValueType getValue(int n) { if (!isValid()) throw new IllegalStateException("accessing top or bottom frame"); return slotList.get(n); } /** * Set the value at the <i>n</i>th slot. * * @param n * the slot in which to set a new value * @param value * the value to set */ public void setValue(int n, ValueType value) { if (VERIFY_INTEGRITY && value == null) throw new IllegalArgumentException(); if (!isValid()) throw new IllegalStateException("accessing top or bottom frame"); slotList.set(n, value); } /** * Return true if this stack frame is the same as the one given as a * parameter. * * @param other * the other Frame * @return true if the frames are the same, false otherwise */ public boolean sameAs(Frame<ValueType> other) { if (isTop != other.isTop) return false; if (isTop && other.isTop) return true; if (isBottom != other.isBottom) return false; if (isBottom && other.isBottom) return true; if (getNumSlots() != other.getNumSlots()) return false; for (int i = 0; i < getNumSlots(); ++i) if (!getValue(i).equals(other.getValue(i))) return false; return true; } /** * Make this Frame exactly the same as the one given as a parameter. * * @param other * the Frame to make this object the same as */ public void copyFrom(Frame<ValueType> other) { lastUpdateTimestamp = other.lastUpdateTimestamp; int size = slotList.size(); if (size == other.slotList.size()) { for (int i = 0; i < size; i++) slotList.set(i, other.slotList.get(i)); } else { slotList.clear(); for (ValueType v : other.slotList) slotList.add(v); } isTop = other.isTop; isBottom = other.isBottom; } private static final boolean STACK_ONLY = SystemProperties .getBoolean("dataflow.stackonly"); /** * Convert to string. */ @Override public String toString() { if (isTop()) return "[TOP]"; if (isBottom()) return "[BOTTOM]"; StringBuffer buf = new StringBuffer(); buf.append('['); int numSlots = getNumSlots(); int start = STACK_ONLY ? getNumLocals() : 0; for (int i = start; i < numSlots; ++i) { if (!STACK_ONLY && i == getNumLocals()) { // Use a "|" character to visually separate locals from // the operand stack. int last = buf.length() - 1; if (last >= 0) { if (buf.charAt(last) == ',') buf.deleteCharAt(last); } buf.append('|'); } String value = valueToString(getValue(i)); if (i == numSlots - 1 && value.endsWith(",")) value = value.substring(0, value.length() - 1); buf.append(value); // buf.append(' '); } buf.append(']'); return buf.toString(); } /** * Subclasses may override this if they want to do something special to * convert Value objects to Strings. By default, we just call toString() on * the values. */ protected String valueToString(ValueType value) { return value.toString(); } /** * @return an unmodifiable Collection of the local variable and operand stack slots */ public Collection<ValueType> allSlots() { if (slotList == null) return Collections.EMPTY_LIST; return Collections.unmodifiableCollection(slotList); } /** * @param lastUpdateTimestamp * The lastUpdateTimestamp to set. */ public void setLastUpdateTimestamp(int lastUpdateTimestamp) { this.lastUpdateTimestamp = lastUpdateTimestamp; } /** * @return Returns the lastUpdateTimestamp. */ public int getLastUpdateTimestamp() { return lastUpdateTimestamp; }}// vim:ts=4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -