Package org.drools.asm.util.attrs

Source Code of org.drools.asm.util.attrs.ASMStackMapTableAttribute

/**
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2005 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
*    contributors may be used to endorse or promote products derived from
*    this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.drools.asm.util.attrs;

import java.util.List;
import java.util.Map;

import org.drools.asm.Attribute;
import org.drools.asm.ClassReader;
import org.drools.asm.Label;
import org.drools.asm.attrs.StackMapFrame;
import org.drools.asm.attrs.StackMapTableAttribute;
import org.drools.asm.attrs.StackMapType;

/**
* An {@link ASMifiable} {@link StackMapTableAttribute} sub class.
*
* @author Eugene Kuleshov
*/
public class ASMStackMapTableAttribute extends StackMapTableAttribute
    implements
    ASMifiable,
    Traceable {
    /**
     * Length of the attribute used for comparison
     */
    private int len;

    public ASMStackMapTableAttribute() {
        super();
    }

    public ASMStackMapTableAttribute(final List frames,
                                     final int len) {
        super( frames );
        this.len = len;
    }

    protected Attribute read(final ClassReader cr,
                             final int off,
                             final int len,
                             final char[] buf,
                             final int codeOff,
                             final Label[] labels) {
        final StackMapTableAttribute attr = (StackMapTableAttribute) super.read( cr,
                                                                                 off,
                                                                                 len,
                                                                                 buf,
                                                                                 codeOff,
                                                                                 labels );

        return new ASMStackMapTableAttribute( attr.getFrames(),
                                              len );
    }

    public void asmify(final StringBuffer buf,
                       final String varName,
                       final Map labelNames) {
        final List frames = getFrames();
        if ( frames.size() == 0 ) {
            buf.append( "List frames = Collections.EMPTY_LIST;\n" );
        } else {
            buf.append( "List frames = new ArrayList();\n" );
            for ( int i = 0; i < frames.size(); i++ ) {
                buf.append( "{\n" );
                final StackMapFrame f = (StackMapFrame) frames.get( i );
                declareLabel( buf,
                              labelNames,
                              f.label );

                final String frameVar = varName + "frame" + i;
                asmifyTypeInfo( buf,
                                frameVar,
                                labelNames,
                                f.locals,
                                "locals" );
                asmifyTypeInfo( buf,
                                frameVar,
                                labelNames,
                                f.stack,
                                "stack" );

                buf.append( "StackMapFrame " ).append( frameVar ).append( " = new StackMapFrame(" ).append( labelNames.get( f.label ) ).append( ", locals, stack);\n" );
                buf.append( "frames.add(" ).append( frameVar ).append( ");\n" );
                buf.append( "}\n" );
            }
        }
        buf.append( "StackMapTableAttribute " ).append( varName );
        buf.append( " = new StackMapTableAttribute(frames);\n" );
    }

    void asmifyTypeInfo(final StringBuffer buf,
                        final String varName,
                        final Map labelNames,
                        final List infos,
                        final String field) {
        if ( infos.size() == 0 ) {
            buf.append( "List " ).append( field ).append( " = Collections.EMPTY_LIST;\n" );
        } else {
            buf.append( "List " ).append( field ).append( " = new ArrayList();\n" );
            buf.append( "{\n" );
            for ( int i = 0; i < infos.size(); i++ ) {
                final StackMapType typeInfo = (StackMapType) infos.get( i );
                final String localName = varName + "Info" + i;
                final int type = typeInfo.getType();
                buf.append( "StackMapType " ).append( localName ).append( " = StackMapType.getTypeInfo( StackMapType.ITEM_" ).append( StackMapType.ITEM_NAMES[type] ).append( ");\n" );

                switch ( type ) {
                    case StackMapType.ITEM_Object : //
                        buf.append( localName ).append( ".setObject(\"" ).append( typeInfo.getObject() ).append( "\");\n" );
                        break;

                    case StackMapType.ITEM_Uninitialized : //
                        declareLabel( buf,
                                      labelNames,
                                      typeInfo.getLabel() );
                        buf.append( localName ).append( ".setLabel(" ).append( labelNames.get( typeInfo.getLabel() ) ).append( ");\n" );
                        break;
                }
                buf.append( field ).append( ".add(" ).append( localName ).append( ");\n" );
            }
            buf.append( "}\n" );
        }
    }

    static void declareLabel(final StringBuffer buf,
                             final Map labelNames,
                             final Label l) {
        String name = (String) labelNames.get( l );
        if ( name == null ) {
            name = "l" + labelNames.size();
            labelNames.put( l,
                            name );
            buf.append( "Label " ).append( name ).append( " = new Label();\n" );
        }
    }

    public void trace(final StringBuffer buf,
                      final Map labelNames) {
        final List frames = getFrames();
        buf.append( "[\n" );
        for ( int i = 0; i < frames.size(); i++ ) {
            final StackMapFrame f = (StackMapFrame) frames.get( i );

            buf.append( "    Frame:" );
            appendLabel( buf,
                         labelNames,
                         f.label );

            buf.append( " locals[" );
            traceTypeInfo( buf,
                           labelNames,
                           f.locals );
            buf.append( "]" );
            buf.append( " stack[" );
            traceTypeInfo( buf,
                           labelNames,
                           f.stack );
            buf.append( "]\n" );
        }
        buf.append( "  ] length:" ).append( this.len ).append( "\n" );
    }

    private void traceTypeInfo(final StringBuffer buf,
                               final Map labelNames,
                               final List infos) {
        String sep = "";
        for ( int i = 0; i < infos.size(); i++ ) {
            final StackMapType t = (StackMapType) infos.get( i );

            buf.append( sep ).append( StackMapType.ITEM_NAMES[t.getType()] );
            sep = ", ";
            if ( t.getType() == StackMapType.ITEM_Object ) {
                buf.append( ":" ).append( t.getObject() );
            }
            if ( t.getType() == StackMapType.ITEM_Uninitialized ) {
                buf.append( ":" );
                appendLabel( buf,
                             labelNames,
                             t.getLabel() );
            }
        }
    }

    protected void appendLabel(final StringBuffer buf,
                               final Map labelNames,
                               final Label l) {
        String name = (String) labelNames.get( l );
        if ( name == null ) {
            name = "L" + labelNames.size();
            labelNames.put( l,
                            name );
        }
        buf.append( name );
    }

}
TOP

Related Classes of org.drools.asm.util.attrs.ASMStackMapTableAttribute

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.