rlm@10: /*** rlm@10: * ASM: a very small and fast Java bytecode manipulation framework rlm@10: * Copyright (c) 2000-2005 INRIA, France Telecom rlm@10: * All rights reserved. rlm@10: * rlm@10: * Redistribution and use in source and binary forms, with or without rlm@10: * modification, are permitted provided that the following conditions rlm@10: * are met: rlm@10: * 1. Redistributions of source code must retain the above copyright rlm@10: * notice, this list of conditions and the following disclaimer. rlm@10: * 2. Redistributions in binary form must reproduce the above copyright rlm@10: * notice, this list of conditions and the following disclaimer in the rlm@10: * documentation and/or other materials provided with the distribution. rlm@10: * 3. Neither the name of the copyright holders nor the names of its rlm@10: * contributors may be used to endorse or promote products derived from rlm@10: * this software without specific prior written permission. rlm@10: * rlm@10: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" rlm@10: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE rlm@10: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE rlm@10: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE rlm@10: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR rlm@10: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF rlm@10: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS rlm@10: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN rlm@10: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) rlm@10: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF rlm@10: * THE POSSIBILITY OF SUCH DAMAGE. rlm@10: */ rlm@10: package clojure.asm.commons; rlm@10: rlm@10: import clojure.asm.ClassAdapter; rlm@10: import clojure.asm.ClassVisitor; rlm@10: import clojure.asm.MethodVisitor; rlm@10: import clojure.asm.Opcodes; rlm@10: rlm@10: /** rlm@10: * A {@link ClassAdapter} that merges clinit methods into a single one. rlm@10: * rlm@10: * @author Eric Bruneton rlm@10: */ rlm@10: public class StaticInitMerger extends ClassAdapter{ rlm@10: rlm@10: private String name; rlm@10: rlm@10: private MethodVisitor clinit; rlm@10: rlm@10: private String prefix; rlm@10: rlm@10: private int counter; rlm@10: rlm@10: public StaticInitMerger(final String prefix, final ClassVisitor cv){ rlm@10: super(cv); rlm@10: this.prefix = prefix; rlm@10: } rlm@10: rlm@10: public void visit( rlm@10: final int version, rlm@10: final int access, rlm@10: final String name, rlm@10: final String signature, rlm@10: final String superName, rlm@10: final String[] interfaces){ rlm@10: cv.visit(version, access, name, signature, superName, interfaces); rlm@10: this.name = name; rlm@10: } rlm@10: rlm@10: public MethodVisitor visitMethod( rlm@10: final int access, rlm@10: final String name, rlm@10: final String desc, rlm@10: final String signature, rlm@10: final String[] exceptions){ rlm@10: MethodVisitor mv; rlm@10: if(name.equals("")) rlm@10: { rlm@10: int a = Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC; rlm@10: String n = prefix + counter++; rlm@10: mv = cv.visitMethod(a, n, desc, signature, exceptions); rlm@10: rlm@10: if(clinit == null) rlm@10: { rlm@10: clinit = cv.visitMethod(a, name, desc, null, null); rlm@10: } rlm@10: clinit.visitMethodInsn(Opcodes.INVOKESTATIC, this.name, n, desc); rlm@10: } rlm@10: else rlm@10: { rlm@10: mv = cv.visitMethod(access, name, desc, signature, exceptions); rlm@10: } rlm@10: return mv; rlm@10: } rlm@10: rlm@10: public void visitEnd(){ rlm@10: if(clinit != null) rlm@10: { rlm@10: clinit.visitInsn(Opcodes.RETURN); rlm@10: clinit.visitMaxs(0, 0); rlm@10: } rlm@10: cv.visitEnd(); rlm@10: } rlm@10: }