001/*** 002 * ASM: a very small and fast Java bytecode manipulation framework 003 * Copyright (c) 2000-2011 INRIA, France Telecom 004 * All rights reserved. 005 * 006 * Redistribution and use in source and binary forms, with or without 007 * modification, are permitted provided that the following conditions 008 * are met: 009 * 1. Redistributions of source code must retain the above copyright 010 * notice, this list of conditions and the following disclaimer. 011 * 2. Redistributions in binary form must reproduce the above copyright 012 * notice, this list of conditions and the following disclaimer in the 013 * documentation and/or other materials provided with the distribution. 014 * 3. Neither the name of the copyright holders nor the names of its 015 * contributors may be used to endorse or promote products derived from 016 * this software without specific prior written permission. 017 * 018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 021 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 022 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 028 * THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package io.ebean.enhance.asm.commons; 031 032import io.ebean.enhance.asm.ClassVisitor; 033import io.ebean.enhance.asm.MethodVisitor; 034import io.ebean.enhance.asm.Opcodes; 035 036/** 037 * A {@link ClassVisitor} that merges clinit methods into a single one. 038 * 039 * @author Eric Bruneton 040 */ 041public class StaticInitMerger extends ClassVisitor { 042 043 private String name; 044 045 private MethodVisitor clinit; 046 047 private final String prefix; 048 049 private int counter; 050 051 public StaticInitMerger(final String prefix, final ClassVisitor cv) { 052 this(Opcodes.ASM6, prefix, cv); 053 } 054 055 protected StaticInitMerger(final int api, final String prefix, 056 final ClassVisitor cv) { 057 super(api, cv); 058 this.prefix = prefix; 059 } 060 061 @Override 062 public void visit(final int version, final int access, final String name, 063 final String signature, final String superName, 064 final String[] interfaces) { 065 cv.visit(version, access, name, signature, superName, interfaces); 066 this.name = name; 067 } 068 069 @Override 070 public MethodVisitor visitMethod(final int access, final String name, 071 final String desc, final String signature, final String[] exceptions) { 072 MethodVisitor mv; 073 if ("<clinit>".equals(name)) { 074 int a = Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC; 075 String n = prefix + counter++; 076 mv = cv.visitMethod(a, n, desc, signature, exceptions); 077 078 if (clinit == null) { 079 clinit = cv.visitMethod(a, name, desc, null, null); 080 } 081 clinit.visitMethodInsn(Opcodes.INVOKESTATIC, this.name, n, desc, 082 false); 083 } else { 084 mv = cv.visitMethod(access, name, desc, signature, exceptions); 085 } 086 return mv; 087 } 088 089 @Override 090 public void visitEnd() { 091 if (clinit != null) { 092 clinit.visitInsn(Opcodes.RETURN); 093 clinit.visitMaxs(0, 0); 094 } 095 cv.visitEnd(); 096 } 097}