Home | History | Annotate | Download | only in commons
      1 /***
      2  * ASM: a very small and fast Java bytecode manipulation framework
      3  * Copyright (c) 2000-2005 INRIA, France Telecom
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  * 3. Neither the name of the copyright holders nor the names of its
     15  *    contributors may be used to endorse or promote products derived from
     16  *    this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     28  * THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 package org.objectweb.asm.commons;
     31 
     32 import org.objectweb.asm.ClassAdapter;
     33 import org.objectweb.asm.ClassVisitor;
     34 import org.objectweb.asm.MethodVisitor;
     35 import org.objectweb.asm.Opcodes;
     36 
     37 /**
     38  * A {@link ClassAdapter} that merges clinit methods into a single one.
     39  *
     40  * @author Eric Bruneton
     41  */
     42 public class StaticInitMerger extends ClassAdapter {
     43 
     44     private String name;
     45 
     46     private MethodVisitor clinit;
     47 
     48     private String prefix;
     49 
     50     private int counter;
     51 
     52     public StaticInitMerger(final String prefix, final ClassVisitor cv) {
     53         super(cv);
     54         this.prefix = prefix;
     55     }
     56 
     57     public void visit(
     58         final int version,
     59         final int access,
     60         final String name,
     61         final String signature,
     62         final String superName,
     63         final String[] interfaces)
     64     {
     65         cv.visit(version, access, name, signature, superName, interfaces);
     66         this.name = name;
     67     }
     68 
     69     public MethodVisitor visitMethod(
     70         final int access,
     71         final String name,
     72         final String desc,
     73         final String signature,
     74         final String[] exceptions)
     75     {
     76         MethodVisitor mv;
     77         if (name.equals("<clinit>")) {
     78             int a = Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC;
     79             String n = prefix + counter++;
     80             mv = cv.visitMethod(a, n, desc, signature, exceptions);
     81 
     82             if (clinit == null) {
     83                 clinit = cv.visitMethod(a, name, desc, null, null);
     84             }
     85             clinit.visitMethodInsn(Opcodes.INVOKESTATIC, this.name, n, desc);
     86         } else {
     87             mv = cv.visitMethod(access, name, desc, signature, exceptions);
     88         }
     89         return mv;
     90     }
     91 
     92     public void visitEnd() {
     93         if (clinit != null) {
     94             clinit.visitInsn(Opcodes.RETURN);
     95             clinit.visitMaxs(0, 0);
     96         }
     97         cv.visitEnd();
     98     }
     99 }
    100