public boolean isStreamClose( BasicBlock basicBlock, InstructionHandle handle, ConstantPoolGen cpg, ResourceValueFrame frame, RepositoryLookupFailureCallback lookupFailureCallback) { if (!mightCloseStream(basicBlock, handle, cpg)) return false; Instruction ins = handle.getInstruction(); if ((ins instanceof INVOKEVIRTUAL) || (ins instanceof INVOKEINTERFACE)) { // Does this instruction close the stream? InvokeInstruction inv = (InvokeInstruction) ins; if (!frame.isValid() || !getInstanceValue(frame, inv, cpg).isInstance()) return false; // It's a close if the invoked class is any subtype of the stream // base class. // (Basically, we may not see the exact original stream class, // even though it's the same instance.) try { String classClosed = inv.getClassName(cpg); return Hierarchy.isSubtype(classClosed, streamBase) || Hierarchy.isSubtype(streamBase, classClosed); } catch (ClassNotFoundException e) { lookupFailureCallback.reportMissingClass(e); return false; } } return false; }
public boolean isStreamOpen( BasicBlock basicBlock, InstructionHandle handle, ConstantPoolGen cpg, ResourceValueFrame frame) { if (isOpenOnCreation) return false; Instruction ins = handle.getInstruction(); if (!(ins instanceof INVOKESPECIAL)) return false; // Does this instruction open the stream? INVOKESPECIAL inv = (INVOKESPECIAL) ins; return frame.isValid() && getInstanceValue(frame, inv, cpg).isInstance() && matchMethod(inv, cpg, this.getResourceClass(), "<init>"); }
private ResourceValue getInstanceValue( ResourceValueFrame frame, InvokeInstruction inv, ConstantPoolGen cpg) { int numConsumed = inv.consumeStack(cpg); if (numConsumed == Constants.UNPREDICTABLE) throw new IllegalStateException(); return frame.getValue(frame.getNumSlots() - numConsumed); }