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

📄 adviceadapter.java

📁 jboss规则引擎
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
                case IRETURN :
                case FRETURN :
                case ARETURN :
                case LRETURN :
                case DRETURN :
                case ATHROW :
                    onMethodExit( opcode );
                    break;
            }
        }
        this.mv.visitInsn( opcode );
    }

    public void visitVarInsn(final int opcode,
                             final int var) {
        super.visitVarInsn( opcode,
                            var );

        if ( this.constructor ) {
            switch ( opcode ) {
                case ILOAD :
                case FLOAD :
                    pushValue( AdviceAdapter.OTHER );
                    break;
                case LLOAD :
                case DLOAD :
                    pushValue( AdviceAdapter.OTHER );
                    pushValue( AdviceAdapter.OTHER );
                    break;
                case ALOAD :
                    pushValue( var == 0 ? AdviceAdapter.THIS : AdviceAdapter.OTHER );
                    break;
                case ASTORE :
                case ISTORE :
                case FSTORE :
                    popValue();
                    break;
                case LSTORE :
                case DSTORE :
                    popValue();
                    popValue();
                    break;
            }
        }
    }

    public void visitFieldInsn(final int opcode,
                               final String owner,
                               final String name,
                               final String desc) {
        this.mv.visitFieldInsn( opcode,
                                owner,
                                name,
                                desc );

        if ( this.constructor ) {
            final char c = desc.charAt( 0 );
            final boolean longOrDouble = c == 'J' || c == 'D';
            switch ( opcode ) {
                case GETSTATIC :
                    pushValue( AdviceAdapter.OTHER );
                    if ( longOrDouble ) {
                        pushValue( AdviceAdapter.OTHER );
                    }
                    break;
                case PUTSTATIC :
                    popValue();
                    if ( longOrDouble ) {
                        popValue();
                    }
                    break;
                case PUTFIELD :
                    popValue();
                    if ( longOrDouble ) {
                        popValue();
                        popValue();
                    }
                    break;
                // case GETFIELD:
                default :
                    if ( longOrDouble ) {
                        pushValue( AdviceAdapter.OTHER );
                    }
            }
        }
    }

    public void visitIntInsn(final int opcode,
                             final int operand) {
        this.mv.visitIntInsn( opcode,
                              operand );

        if ( this.constructor ) {
            switch ( opcode ) {
                case BIPUSH :
                case SIPUSH :
                    pushValue( AdviceAdapter.OTHER );
            }
        }
    }

    public void visitLdcInsn(final Object cst) {
        this.mv.visitLdcInsn( cst );

        if ( this.constructor ) {
            pushValue( AdviceAdapter.OTHER );
            if ( cst instanceof Double || cst instanceof Long ) {
                pushValue( AdviceAdapter.OTHER );
            }
        }
    }

    public void visitMultiANewArrayInsn(final String desc,
                                        final int dims) {
        this.mv.visitMultiANewArrayInsn( desc,
                                         dims );

        if ( this.constructor ) {
            for ( int i = 0; i < dims; i++ ) {
                popValue();
            }
            pushValue( AdviceAdapter.OTHER );
        }
    }

    public void visitTypeInsn(final int opcode,
                              final String name) {
        this.mv.visitTypeInsn( opcode,
                               name );

        // ANEWARRAY, CHECKCAST or INSTANCEOF don't change stack
        if ( this.constructor && opcode == Opcodes.NEW ) {
            pushValue( AdviceAdapter.OTHER );
        }
    }

    public void visitMethodInsn(final int opcode,
                                final String owner,
                                final String name,
                                final String desc) {
        this.mv.visitMethodInsn( opcode,
                                 owner,
                                 name,
                                 desc );

        if ( this.constructor ) {
            final Type[] types = Type.getArgumentTypes( desc );
            for ( int i = 0; i < types.length; i++ ) {
                popValue();
                if ( types[i].getSize() == 2 ) {
                    popValue();
                }
            }
            switch ( opcode ) {
                // case INVOKESTATIC:
                // break;

                case INVOKEINTERFACE :
                case INVOKEVIRTUAL :
                    popValue(); // objectref
                    break;

                case INVOKESPECIAL :
                    final Object type = popValue(); // objectref
                    if ( type == AdviceAdapter.THIS && !this.superInitialized ) {
                        onMethodEnter();
                        this.superInitialized = true;
                        // once super has been initialized it is no longer 
                        // necessary to keep track of stack state                        
                        this.constructor = false;
                    }
                    break;
            }

            final Type returnType = Type.getReturnType( desc );
            if ( returnType != Type.VOID_TYPE ) {
                pushValue( AdviceAdapter.OTHER );
                if ( returnType.getSize() == 2 ) {
                    pushValue( AdviceAdapter.OTHER );
                }
            }
        }
    }

    public void visitJumpInsn(final int opcode,
                              final Label label) {
        this.mv.visitJumpInsn( opcode,
                               label );

        if ( this.constructor ) {
            switch ( opcode ) {
                case IFEQ :
                case IFNE :
                case IFLT :
                case IFGE :
                case IFGT :
                case IFLE :
                case IFNULL :
                case IFNONNULL :
                    popValue();
                    break;

                case IF_ICMPEQ :
                case IF_ICMPNE :
                case IF_ICMPLT :
                case IF_ICMPGE :
                case IF_ICMPGT :
                case IF_ICMPLE :
                case IF_ACMPEQ :
                case IF_ACMPNE :
                    popValue();
                    popValue();
                    break;

                case JSR :
                    pushValue( AdviceAdapter.OTHER );
                    break;
            }
            addBranch( label );
        }
    }

    public void visitLookupSwitchInsn(final Label dflt,
                                      final int[] keys,
                                      final Label[] labels) {
        this.mv.visitLookupSwitchInsn( dflt,
                                       keys,
                                       labels );

        if ( this.constructor ) {
            popValue();
            addBranches( dflt,
                         labels );
        }
    }

    public void visitTableSwitchInsn(final int min,
                                     final int max,
                                     final Label dflt,
                                     final Label[] labels) {
        this.mv.visitTableSwitchInsn( min,
                                      max,
                                      dflt,
                                      labels );

        if ( this.constructor ) {
            popValue();
            addBranches( dflt,
                         labels );
        }
    }

    private void addBranches(final Label dflt,
                             final Label[] labels) {
        addBranch( dflt );
        for ( int i = 0; i < labels.length; i++ ) {
            addBranch( labels[i] );
        }
    }

    private void addBranch(final Label label) {
        if ( this.branches.containsKey( label ) ) {
            return;
        }
        final ArrayList frame = new ArrayList();
        frame.addAll( this.stackFrame );
        this.branches.put( label,
                           frame );
    }

    private Object popValue() {
        return this.stackFrame.remove( this.stackFrame.size() - 1 );
    }

    private Object peekValue() {
        return this.stackFrame.get( this.stackFrame.size() - 1 );
    }

    private void pushValue(final Object o) {
        this.stackFrame.add( o );
    }

    /**
     * Called at the beginning of the method or after super 
     * class class call in the constructor.
     * <br><br>
     * 
     * <i>Custom code can use or change all the local variables,
     * but should not change state of the stack.</i>
     */
    protected abstract void onMethodEnter();

    /**
     * Called before explicit exit from the method using either
     * return or throw. Top element on the stack contains the 
     * return value or exception instance. For example:
     * 
     * <pre>
     *   public void onMethodExit(int opcode) {
     *     if(opcode==RETURN) {
     *         visitInsn(ACONST_NULL);
     *     } else if(opcode==ARETURN || opcode==ATHROW) {
     *         dup();
     *     } else {
     *         if(opcode==LRETURN || opcode==DRETURN) {
     *             dup2();
     *         } else {
     *             dup();
     *         }
     *         box(Type.getReturnType(this.methodDesc));
     *     }
     *     visitIntInsn(SIPUSH, opcode);
     *     visitMethodInsn(INVOKESTATIC, owner, "onExit", "(Ljava/lang/Object;I)V");
     *   }
     *
     *   // an actual call back method
     *   public static void onExit(int opcode, Object param) {
     *     ...
     * </pre>
     * 
     * <br><br>
     * 
     * <i>Custom code can use or change all the local variables,
     * but should not change state of the stack.</i>
     * 
     * @param opcode one of the RETURN, IRETURN, FRETURN, 
     *   ARETURN, LRETURN, DRETURN or ATHROW
     * 
     */
    protected abstract void onMethodExit(int opcode);

    // TODO onException, onMethodCall

}

⌨️ 快捷键说明

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