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

📄 analyzer.java

📁 jboss规则引擎
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
                                   current,
                                   subroutine );
                        }
                    } else if ( insnOpcode == Opcodes.RET ) {
                        if ( subroutine == null ) {
                            throw new AnalyzerException( "RET instruction outside of a sub routine" );
                        }
                        for ( int i = 0; i < subroutine.callers.size(); ++i ) {
                            final int caller = this.indexes.get( subroutine.callers.get( i ) );
                            merge( caller + 1,
                                   this.frames[caller],
                                   current,
                                   this.subroutines[caller],
                                   subroutine.access );
                        }
                    } else if ( insnOpcode != Opcodes.ATHROW && (insnOpcode < Opcodes.IRETURN || insnOpcode > Opcodes.RETURN) ) {
                        if ( subroutine != null ) {
                            if ( insnNode instanceof VarInsnNode ) {
                                final int var = ((VarInsnNode) insnNode).var;
                                subroutine.access[var] = true;
                                if ( insnOpcode == Opcodes.LLOAD || insnOpcode == Opcodes.DLOAD || insnOpcode == Opcodes.LSTORE || insnOpcode == Opcodes.DSTORE ) {
                                    subroutine.access[var + 1] = true;
                                }
                            } else if ( insnNode instanceof IincInsnNode ) {
                                final int var = ((IincInsnNode) insnNode).var;
                                subroutine.access[var] = true;
                            }
                        }
                        merge( insn + 1,
                               current,
                               subroutine );
                    }
                }

                final List insnHandlers = this.handlers[insn];
                if ( insnHandlers != null ) {
                    for ( int i = 0; i < insnHandlers.size(); ++i ) {
                        final TryCatchBlockNode tcb = (TryCatchBlockNode) insnHandlers.get( i );
                        Type type;
                        if ( tcb.type == null ) {
                            type = Type.getType( "Ljava/lang/Throwable;" );
                        } else {
                            type = Type.getType( "L" + tcb.type + ";" );
                        }
                        handler.init( f );
                        handler.clearStack();
                        handler.push( this.interpreter.newValue( type ) );
                        merge( this.indexes.get( tcb.handler ),
                               handler,
                               subroutine );
                    }
                }
            } catch ( final AnalyzerException e ) {
                throw new AnalyzerException( "Error at instruction " + insn + ": " + e.getMessage(),
                                             e );
            } catch ( final Exception e ) {
                throw new AnalyzerException( "Error at instruction " + insn + ": " + e.getMessage(),
                                             e );
            }
        }

        return this.frames;
    }

    /**
     * Returns the symbolic stack frame for each instruction of the last
     * recently analyzed method.
     * 
     * @return the symbolic state of the execution stack frame at each bytecode
     *         instruction of the method. The size of the returned array is
     *         equal to the number of instructions (and labels) of the method. A
     *         given frame is <tt>null</tt> if the corresponding instruction
     *         cannot be reached, or if an error occured during the analysis of
     *         the method.
     */
    public Frame[] getFrames() {
        return this.frames;
    }

    /**
     * Returns the index of the given instruction.
     * 
     * @param insn a {@link Label} or {@link AbstractInsnNode} of the last
     *        recently analyzed method.
     * @return the index of the given instruction of the last recently analyzed
     *         method.
     */
    public int getIndex(final Object insn) {
        return this.indexes.get( insn );
    }

    /**
     * Returns the exception handlers for the given instruction.
     * 
     * @param insn the index of an instruction of the last recently analyzed
     *        method.
     * @return a list of {@link TryCatchBlockNode} objects.
     */
    public List getHandlers(final int insn) {
        return this.handlers[insn];
    }

    /**
     * Constructs a new frame with the given size.
     * 
     * @param nLocals the maximum number of local variables of the frame.
     * @param nStack the maximum stack size of the frame.
     * @return the created frame.
     */
    protected Frame newFrame(final int nLocals,
                             final int nStack) {
        return new Frame( nLocals,
                          nStack );
    }

    /**
     * Constructs a new frame that is identical to the given frame.
     * 
     * @param src a frame.
     * @return the created frame.
     */
    protected Frame newFrame(final Frame src) {
        return new Frame( src );
    }

    /**
     * Creates a control flow graph edge. The default implementation of this
     * method does nothing. It can be overriden in order to construct the
     * control flow graph of a method (this method is called by the
     * {@link #analyze analyze} method during its visit of the method's code).
     * 
     * @param frame the frame corresponding to an instruction.
     * @param successor the frame corresponding to a successor instruction.
     */
    protected void newControlFlowEdge(final Frame frame,
                                      final Frame successor) {
    }

    // -------------------------------------------------------------------------

    private void merge(final int insn,
                       final Frame frame,
                       final Subroutine subroutine) throws AnalyzerException {
        if ( insn > this.n - 1 ) {
            throw new AnalyzerException( "Execution can fall off end of the code" );
        }

        final Frame oldFrame = this.frames[insn];
        final Subroutine oldSubroutine = this.subroutines[insn];
        boolean changes = false;

        if ( oldFrame == null ) {
            this.frames[insn] = newFrame( frame );
            changes = true;
        } else {
            changes |= oldFrame.merge( frame,
                                       this.interpreter );
        }

        newControlFlowEdge( frame,
                            oldFrame );

        if ( oldSubroutine == null ) {
            if ( subroutine != null ) {
                this.subroutines[insn] = subroutine.copy();
                changes = true;
            }
        } else {
            if ( subroutine != null ) {
                changes |= oldSubroutine.merge( subroutine,
                                                !this.jsr );
            }
        }
        if ( changes && !this.queued[insn] ) {
            this.queued[insn] = true;
            this.queue[this.top++] = insn;
        }
    }

    private void merge(final int insn,
                       final Frame beforeJSR,
                       final Frame afterRET,
                       final Subroutine subroutineBeforeJSR,
                       final boolean[] access) throws AnalyzerException {
        if ( insn > this.n - 1 ) {
            throw new AnalyzerException( "Execution can fall off end of the code" );
        }

        final Frame oldFrame = this.frames[insn];
        final Subroutine oldSubroutine = this.subroutines[insn];
        boolean changes = false;

        afterRET.merge( beforeJSR,
                        access );

        if ( oldFrame == null ) {
            this.frames[insn] = newFrame( afterRET );
            changes = true;
        } else {
            changes |= oldFrame.merge( afterRET,
                                       access );
        }

        newControlFlowEdge( afterRET,
                            oldFrame );

        if ( oldSubroutine == null ) {
            if ( subroutineBeforeJSR != null ) {
                this.subroutines[insn] = subroutineBeforeJSR.copy();
                changes = true;
            }
        } else {
            if ( subroutineBeforeJSR != null ) {
                changes |= oldSubroutine.merge( subroutineBeforeJSR,
                                                !this.jsr );
            }
        }
        if ( changes && !this.queued[insn] ) {
            this.queued[insn] = true;
            this.queue[this.top++] = insn;
        }
    }
}

⌨️ 快捷键说明

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