@Override
    public void sawOpcode(final int seen) {

        try {
            stack.precomputation(this);

            if (OpcodeUtils.isInvoke(seen)) {
                String methodSig = getSigConstantOperand();
                List<String> parmTypes = SignatureUtils.getParameterSignatures(methodSig);
                int stackDepth = stack.getStackDepth();
                if (stackDepth >= parmTypes.size()) {
                    for (int i = 0; i < parmTypes.size(); i++) {
                        OpcodeStack.Item itm = stack.getStackItem(i);
                        int reg = itm.getRegisterNumber();
                        removeUselessDefiners(parmTypes.get(parmTypes.size() - i - 1), reg);
                    }
                }

                if ((seen != Const.INVOKESPECIAL) && (seen != Const.INVOKESTATIC)) {
                    if (stackDepth > parmTypes.size()) {
                        OpcodeStack.Item itm = stack.getStackItem(parmTypes.size());
                        int reg = itm.getRegisterNumber();
                        int parm = reg;
                        if (!methodIsStatic) {
                            parm--;
                        }
                        if ((parm >= 0) && (parm < parmCount)) {
                            removeUselessDefiners(reg);
                        }
                    } else {
                        parameterDefiners.clear();
                    }
                }
            } else if ((seen == Const.PUTFIELD) || (seen == Const.GETFIELD) || (seen == Const.PUTSTATIC)
                    || (seen == Const.GETSTATIC) || OpcodeUtils.isAStore(seen)) {
                // Don't check parameters that are aliased
                if (stack.getStackDepth() > 0) {
                    OpcodeStack.Item itm = stack.getStackItem(0);
                    int reg = itm.getRegisterNumber();
                    int parm = reg;
                    if (!methodIsStatic) {
                        parm--;
                    }
                    if ((parm >= 0) && (parm < parmCount)) {
                        parameterDefiners.remove(Integer.valueOf(reg));
                    }
                } else {
                    parameterDefiners.clear();
                }

                if ((seen == Const.GETFIELD) || (seen == Const.PUTFIELD)) {
                    if (stack.getStackDepth() > 1) {
                        OpcodeStack.Item itm = stack.getStackItem(1);
                        int reg = itm.getRegisterNumber();
                        int parm = reg;
                        if (!methodIsStatic) {
                            parm--;
                        }
                        if ((parm >= 0) && (parm < parmCount)) {
                            parameterDefiners.remove(Integer.valueOf(reg));
                        }
                    } else {
                        parameterDefiners.clear();
                    }
                }

            } else if (OpcodeUtils.isALoad(seen)) {
                int reg = RegisterUtils.getALoadReg(this, seen);

                int parm = reg;
                if (!methodIsStatic) {
                    parm--;
                }
                if ((parm >= 0) && (parm < parmCount)) {
                    usedParameters.set(reg);
                }
            } else if (seen == Const.AASTORE) {
                // Don't check parameters that are stored in
                if (stack.getStackDepth() >= 3) {
                    OpcodeStack.Item itm = stack.getStackItem(0);
                    int reg = itm.getRegisterNumber();
                    int parm = reg;
                    if (!methodIsStatic) {
                        parm--;
                    }
                    if ((parm >= 0) && (parm < parmCount)) {
                        parameterDefiners.remove(Integer.valueOf(reg));
                    }
                } else {
                    parameterDefiners.clear();
                }
            } else if (seen == Const.ARETURN) {
                if (stack.getStackDepth() >= 1) {
                    OpcodeStack.Item item = stack.getStackItem(0);
                    int reg = item.getRegisterNumber();
                    int parm = reg;
                    if (!methodIsStatic) {
                        parm--;
                    }

                    if ((parm >= 0) && (parm < parmCount)) {
                        parameterDefiners.remove(Integer.valueOf(reg));
                    }
                } else {
                    parameterDefiners.clear();
                }
            }

            if (parameterDefiners.isEmpty()) {
                throw new StopOpcodeParsingException();
            }
        } finally {
            stack.sawOpcode(this, seen);
        }
    }
@ Override public void sawOpcode ( final int seen ) { try { stack . precomputation ( this ) ; if ( OpcodeUtils . isInvoke ( seen ) ) { String methodSig = getSigConstantOperand ( ) ; List < String > parmTypes = SignatureUtils . getParameterSignatures ( methodSig ) ; int stackDepth = stack . getStackDepth ( ) ; if ( stackDepth >= parmTypes . size ( ) ) { for ( int i = 0 ; i < parmTypes . size ( ) ; i ++ ) { OpcodeStack . Item itm = stack . getStackItem ( i ) ; int reg = itm . getRegisterNumber ( ) ; removeUselessDefiners ( parmTypes . get ( parmTypes . size ( ) - i - 1 ) , reg ) ; } } if ( ( seen != Const . INVOKESPECIAL ) && ( seen != Const . INVOKESTATIC ) ) { if ( stackDepth > parmTypes . size ( ) ) { OpcodeStack . Item itm = stack . getStackItem ( parmTypes . size ( ) ) ; int reg = itm . getRegisterNumber ( ) ; int parm = reg ; if ( ! methodIsStatic ) { parm -- ; } if ( ( parm >= 0 ) && ( parm < parmCount ) ) { removeUselessDefiners ( reg ) ; } } else { parameterDefiners . clear ( ) ; } } } else if ( ( seen == Const . PUTFIELD ) || ( seen == Const . GETFIELD ) || ( seen == Const . PUTSTATIC ) || ( seen == Const . GETSTATIC ) || OpcodeUtils . isAStore ( seen ) ) { if ( stack . getStackDepth ( ) > 0 ) { OpcodeStack . Item itm = stack . getStackItem ( 0 ) ; int reg = itm . getRegisterNumber ( ) ; int parm = reg ; if ( ! methodIsStatic ) { parm -- ; } if ( ( parm >= 0 ) && ( parm < parmCount ) ) { parameterDefiners . remove ( Integer . valueOf ( reg ) ) ; } } else { parameterDefiners . clear ( ) ; } if ( ( seen == Const . GETFIELD ) || ( seen == Const . PUTFIELD ) ) { if ( stack . getStackDepth ( ) > 1 ) { OpcodeStack . Item itm = stack . getStackItem ( 1 ) ; int reg = itm . getRegisterNumber ( ) ; int parm = reg ; if ( ! methodIsStatic ) { parm -- ; } if ( ( parm >= 0 ) && ( parm < parmCount ) ) { parameterDefiners . remove ( Integer . valueOf ( reg ) ) ; } } else { parameterDefiners . clear ( ) ; } } } else if ( OpcodeUtils . isALoad ( seen ) ) { int reg = RegisterUtils . getALoadReg ( this , seen ) ; int parm = reg ; if ( ! methodIsStatic ) { parm -- ; } if ( ( parm >= 0 ) && ( parm < parmCount ) ) { usedParameters . set ( reg ) ; } } else if ( seen == Const . AASTORE ) { if ( stack . getStackDepth ( ) >= 3 ) { OpcodeStack . Item itm = stack . getStackItem ( 0 ) ; int reg = itm . getRegisterNumber ( ) ; int parm = reg ; if ( ! methodIsStatic ) { parm -- ; } if ( ( parm >= 0 ) && ( parm < parmCount ) ) { parameterDefiners . remove ( Integer . valueOf ( reg ) ) ; } } else { parameterDefiners . clear ( ) ; } } else if ( seen == Const . ARETURN ) { if ( stack . getStackDepth ( ) >= 1 ) { OpcodeStack . Item item = stack . getStackItem ( 0 ) ; int reg = item . getRegisterNumber ( ) ; int parm = reg ; if ( ! methodIsStatic ) { parm -- ; } if ( ( parm >= 0 ) && ( parm < parmCount ) ) { parameterDefiners . remove ( Integer . valueOf ( reg ) ) ; } } else { parameterDefiners . clear ( ) ; } } if ( parameterDefiners . isEmpty ( ) ) { throw new StopOpcodeParsingException ( ) ; } } finally { stack . sawOpcode ( this , seen ) ; } }
implements the visitor to filter out parameter use where the actual defined
type of the method declaration is needed. What remains could be more
abstractly defined.

@param seen the currently parsed opcode