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

📄 methodwriter.java

📁 jboss规则引擎
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        for ( int i = 0; i < labels.length; ++i ) {
            labels[i].put( this,
                           this.code,
                           source,
                           true );
        }
    }

    public void visitLookupSwitchInsn(final Label dflt,
                                      final int keys[],
                                      final Label labels[]) {
        if ( this.computeMaxs ) {
            // updates current stack size (max stack size unchanged)
            --this.stackSize;
            // ends current block (with many new successors)
            if ( this.currentBlock != null ) {
                this.currentBlock.maxStackSize = this.maxStackSize;
                addSuccessor( this.stackSize,
                              dflt );
                for ( int i = 0; i < labels.length; ++i ) {
                    addSuccessor( this.stackSize,
                                  labels[i] );
                }
                this.currentBlock = null;
            }
        }
        // adds the instruction to the bytecode of the method
        final int source = this.code.length;
        this.code.putByte( Opcodes.LOOKUPSWITCH );
        while ( this.code.length % 4 != 0 ) {
            this.code.putByte( 0 );
        }
        dflt.put( this,
                  this.code,
                  source,
                  true );
        this.code.putInt( labels.length );
        for ( int i = 0; i < labels.length; ++i ) {
            this.code.putInt( keys[i] );
            labels[i].put( this,
                           this.code,
                           source,
                           true );
        }
    }

    public void visitMultiANewArrayInsn(final String desc,
                                        final int dims) {
        if ( this.computeMaxs ) {
            // updates current stack size (max stack size unchanged because
            // stack size variation always negative or null)
            this.stackSize += 1 - dims;
        }
        // adds the instruction to the bytecode of the method
        this.code.put12( Opcodes.MULTIANEWARRAY,
                         this.cw.newClass( desc ) ).putByte( dims );
    }

    public void visitTryCatchBlock(final Label start,
                                   final Label end,
                                   final Label handler,
                                   final String type) {
        if ( this.computeMaxs ) {
            // pushes handler block onto the stack of blocks to be visited
            if ( !handler.pushed ) {
                handler.beginStackSize = 1;
                handler.pushed = true;
                handler.next = this.blockStack;
                this.blockStack = handler;
            }
        }
        ++this.catchCount;
        final Handler h = new Handler();
        h.start = start;
        h.end = end;
        h.handler = handler;
        h.desc = type;
        h.type = type != null ? this.cw.newClass( type ) : 0;
        if ( this.lastHandler == null ) {
            this.catchTable = h;
        } else {
            this.lastHandler.next = h;
        }
        this.lastHandler = h;
    }

    public void visitLocalVariable(final String name,
                                   final String desc,
                                   final String signature,
                                   final Label start,
                                   final Label end,
                                   final int index) {
        if ( signature != null ) {
            if ( this.localVarType == null ) {
                this.localVarType = new ByteVector();
            }
            ++this.localVarTypeCount;
            this.localVarType.putShort( start.position ).putShort( end.position - start.position ).putShort( this.cw.newUTF8( name ) ).putShort( this.cw.newUTF8( signature ) ).putShort( index );
        }
        if ( this.localVar == null ) {
            this.localVar = new ByteVector();
        }
        ++this.localVarCount;
        this.localVar.putShort( start.position ).putShort( end.position - start.position ).putShort( this.cw.newUTF8( name ) ).putShort( this.cw.newUTF8( desc ) ).putShort( index );
    }

    public void visitLineNumber(final int line,
                                final Label start) {
        if ( this.lineNumber == null ) {
            this.lineNumber = new ByteVector();
        }
        ++this.lineNumberCount;
        this.lineNumber.putShort( start.position );
        this.lineNumber.putShort( line );
    }

    public void visitMaxs(final int maxStack,
                          final int maxLocals) {
        if ( this.computeMaxs ) {
            // true (non relative) max stack size
            int max = 0;
            /*
             * control flow analysis algorithm: while the block stack is not
             * empty, pop a block from this stack, update the max stack size,
             * compute the true (non relative) begin stack size of the
             * successors of this block, and push these successors onto the
             * stack (unless they have already been pushed onto the stack).
             * Note: by hypothesis, the {@link Label#beginStackSize} of the
             * blocks in the block stack are the true (non relative) beginning
             * stack sizes of these blocks.
             */
            Label stack = this.blockStack;
            while ( stack != null ) {
                // pops a block from the stack
                Label l = stack;
                stack = stack.next;
                // computes the true (non relative) max stack size of this block
                final int start = l.beginStackSize;
                final int blockMax = start + l.maxStackSize;
                // updates the global max stack size
                if ( blockMax > max ) {
                    max = blockMax;
                }
                // analyses the successors of the block
                Edge b = l.successors;
                while ( b != null ) {
                    l = b.successor;
                    // if this successor has not already been pushed onto the
                    // stack...
                    if ( !l.pushed ) {
                        // computes the true beginning stack size of this
                        // successor block
                        l.beginStackSize = start + b.stackSize;
                        // pushes this successor onto the stack
                        l.pushed = true;
                        l.next = stack;
                        stack = l;
                    }
                    b = b.next;
                }
            }
            this.maxStack = max;
        } else {
            this.maxStack = maxStack;
            this.maxLocals = maxLocals;
        }
    }

    public void visitEnd() {
    }

    // ------------------------------------------------------------------------
    // Utility methods: control flow analysis algorithm
    // ------------------------------------------------------------------------

    /**
     * Computes the size of the arguments and of the return value of a method.
     * 
     * @param desc the descriptor of a method.
     * @return the size of the arguments of the method (plus one for the
     *         implicit this argument), argSize, and the size of its return
     *         value, retSize, packed into a single int i =
     *         <tt>(argSize << 2) | retSize</tt> (argSize is therefore equal
     *         to <tt>i >> 2</tt>, and retSize to <tt>i & 0x03</tt>).
     */
    private static int getArgumentsAndReturnSizes(final String desc) {
        int n = 1;
        int c = 1;
        while ( true ) {
            char car = desc.charAt( c++ );
            if ( car == ')' ) {
                car = desc.charAt( c );
                return n << 2 | (car == 'V' ? 0 : (car == 'D' || car == 'J' ? 2 : 1));
            } else if ( car == 'L' ) {
                while ( desc.charAt( c++ ) != ';' ) {
                }
                n += 1;
            } else if ( car == '[' ) {
                while ( (car = desc.charAt( c )) == '[' ) {
                    ++c;
                }
                if ( car == 'D' || car == 'J' ) {
                    n -= 1;
                }
            } else if ( car == 'D' || car == 'J' ) {
                n += 2;
            } else {
                n += 1;
            }
        }
    }

    /**
     * Adds a successor to the {@link #currentBlock currentBlock} block.
     * 
     * @param stackSize the current (relative) stack size in the current block.
     * @param successor the successor block to be added to the current block.
     */
    private void addSuccessor(final int stackSize,
                              final Label successor) {
        final Edge b = new Edge();
        // initializes the previous Edge object...
        b.stackSize = stackSize;
        b.successor = successor;
        // ...and adds it to the successor list of the currentBlock block
        b.next = this.currentBlock.successors;
        this.currentBlock.successors = b;
    }

    // ------------------------------------------------------------------------
    // Utility methods: dump bytecode array
    // ------------------------------------------------------------------------

    /**
     * Returns the size of the bytecode of this method.
     * 
     * @return the size of the bytecode of this method.
     */
    final int getSize() {
        if ( this.classReaderOffset != 0 ) {
            return 6 + this.classReaderLength;
        }
        if ( this.resize ) {
            // replaces the temporary jump opcodes introduced by Label.resolve.
            resizeInstructions( new int[0],
                                new int[0],
                                0 );
        }
        int size = 8;
        if ( this.code.length > 0 ) {
            this.cw.newUTF8( "Code" );
            size += 18 + this.code.length + 8 * this.catchCount;
            if ( this.localVar != null ) {
                this.cw.newUTF8( "LocalVariableTable" );
                size += 8 + this.localVar.length;
            }
            if ( this.localVarType != null ) {
                this.cw.newUTF8( "LocalVariableTypeTable" );
                size += 8 + this.localVarType.length;
            }
            if ( this.lineNumber != null ) {
                this.cw.newUTF8( "LineNumberTable" );
                size += 8 + this.lineNumber.length;
            }
            if ( this.cattrs != null ) {
                size += this.cattrs.getSize( this.cw,
                                             this.code.data,
                                             this.code.length,
                                             this.maxStack,
                                             this.maxLocals );
            }
        }
        if ( this.exceptionCount > 0 ) {
            this.cw.newUTF8( "Exceptions" );
            size += 8 + 2 * this.exceptionCount;
        }
        if ( (this.access & Opcodes.ACC_SYNTHETIC) != 0 && (this.cw.version & 0xffff) < Opcodes.V1_5 ) {
            this.cw.newUTF8( "Synthetic" );
            size += 6;
        }
        if ( (this.access & Opcodes.ACC_DEPRECATED) != 0 ) {
            this.cw.newUTF8( "Deprecated" );
            size += 6;
        }
        if ( this.cw.version == Opcodes.V1_4 ) {
            if ( (this.access & Opcodes.ACC_VARARGS) != 0 ) {
                this.cw.newUTF8( "Varargs" );
                size += 6;
            }
            if ( (this.access & Opcodes.ACC_BRIDGE) != 0 ) {
                this.cw.newUTF8( "Bridge" );
                size += 6;
            }
        }
        if ( this.signature != null ) {
            this.cw.newUTF8( "Signature" );
            this.cw.newUTF8( this.signature );
            size += 8;
        }
        if ( this.annd != null ) {
            this.cw.newUTF8( "AnnotationDefault" );
            size += 6 + this.annd.length;
        }
        if ( this.anns != null ) {
            this.cw.newUTF8( "RuntimeVisibleAnnotations" );
            size += 8 + this.anns.getSize();
        }
        if ( this.ianns != null ) {
            this.cw.newUTF8( "RuntimeInvisibleAnnotations" );
            size += 8 + this.ianns.getSize();
        }
        if ( this.panns != null ) {
            this.cw.newUTF8( "RuntimeVisibleParameterAnnotations" );
            size += 7 + 2 * this.panns.length;
            for ( int i = this.panns.length - 1; i >= 0; --i ) {
                size += this.panns[i] == null ? 0 : this.panns[i].getSize();
            }
        }
        if ( this.ipanns != null ) {
            this.cw.newUTF8( "RuntimeInvisibleParameterAnnotations" );
            size += 7 + 2 * this.ipanns.length;
            for ( int i = this.ipanns.length - 1; i >= 0; --i ) {
                size += this.ipanns[i] == null ? 0 : this.ipanns[i].getSize();
            }
        }
        if ( this.attrs != null ) {
            size += this.attrs.getSize( this.cw,
                                        null,

⌨️ 快捷键说明

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