1 // ASM: a very small and fast Java bytecode manipulation framework 2 // Copyright (c) 2000-2011 INRIA, France Telecom 3 // All rights reserved. 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions 7 // are met: 8 // 1. Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // 2. Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // 3. Neither the name of the copyright holders nor the names of its 14 // contributors may be used to endorse or promote products derived from 15 // this software without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 // THE POSSIBILITY OF SUCH DAMAGE. 28 package jdk3; 29 30 import java.io.FileOutputStream; 31 import java.io.IOException; 32 import org.objectweb.asm.ClassWriter; 33 import org.objectweb.asm.CodeComment; 34 import org.objectweb.asm.Comment; 35 import org.objectweb.asm.FieldVisitor; 36 import org.objectweb.asm.Label; 37 import org.objectweb.asm.MethodVisitor; 38 import org.objectweb.asm.Opcodes; 39 40 /** 41 * Generates a class with structures, instructions and patterns that cannot be produced by compiling 42 * a Java source file with the javac compiler. This includes: 43 * 44 * <ul> 45 * <li>the class, field and method Synthetic attribute (now replaced with an access flag), 46 * <li>the StackMap attribute (which was used for pre-verification in J2ME CLDC 1.1), 47 * <li>non standard class, field, method and code attributes, 48 * <li>the nop and swap instructions, 49 * <li>some variants of the dup_x2 and dup2_x2 instructions, 50 * <li>several line numbers per bytecode offset, and line numbers equal to 0. 51 * </ul> 52 * 53 * Ideally we should not use ASM to generate this class (which is later used to test ASM), but this 54 * would be hard to do. 55 * 56 * @author Eric Bruneton 57 */ 58 public class DumpArtificialStructures implements Opcodes { 59 main(String[] args)60 public static void main(String[] args) throws IOException { 61 FileOutputStream fileOutputStream = new FileOutputStream("ArtificialStructures.class"); 62 fileOutputStream.write(dump()); 63 fileOutputStream.close(); 64 } 65 dump()66 private static byte[] dump() { 67 ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES); 68 FieldVisitor fieldVisitor; 69 MethodVisitor methodVisitor; 70 71 classWriter.visit( 72 V1_3, ACC_PUBLIC + ACC_SUPER, "jdk3/ArtificialStructures", null, "java/lang/Object", null); 73 74 classWriter.visitSource("ArtificialStructures.java", "source-debug"); 75 76 classWriter.visitAttribute(new Comment()); 77 78 fieldVisitor = classWriter.visitField(ACC_PUBLIC + ACC_SYNTHETIC, "f", "I", null, null); 79 fieldVisitor.visitAttribute(new Comment()); 80 fieldVisitor.visitEnd(); 81 82 methodVisitor = 83 classWriter.visitMethod( 84 ACC_PUBLIC + ACC_SYNTHETIC, "<init>", "(Ljava/lang/String;)V", null, null); 85 methodVisitor.visitAttribute(new Comment()); 86 methodVisitor.visitCode(); 87 methodVisitor.visitVarInsn(ALOAD, 0); 88 methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); 89 methodVisitor.visitInsn(NOP); 90 methodVisitor.visitInsn(RETURN); 91 methodVisitor.visitMaxs(0, 0); 92 methodVisitor.visitAttribute(new CodeComment()); 93 methodVisitor.visitEnd(); 94 95 methodVisitor = classWriter.visitMethod(0, "<init>", "(Z)V", null, null); 96 methodVisitor.visitCode(); 97 methodVisitor.visitVarInsn(ILOAD, 1); 98 methodVisitor.visitVarInsn(ALOAD, 0); 99 methodVisitor.visitInsn(SWAP); 100 Label elseLabel = new Label(); 101 methodVisitor.visitJumpInsn(IFEQ, elseLabel); 102 methodVisitor.visitLdcInsn("1"); 103 Label endIfLabel = new Label(); 104 methodVisitor.visitJumpInsn(GOTO, endIfLabel); 105 methodVisitor.visitLabel(elseLabel); 106 methodVisitor.visitLineNumber(0, elseLabel); 107 methodVisitor.visitLineNumber(3, elseLabel); 108 methodVisitor.visitLdcInsn("0"); 109 methodVisitor.visitLabel(endIfLabel); 110 methodVisitor.visitLineNumber(5, endIfLabel); 111 methodVisitor.visitLineNumber(7, endIfLabel); 112 methodVisitor.visitLineNumber(11, endIfLabel); 113 methodVisitor.visitLineNumber(13, endIfLabel); 114 methodVisitor.visitLineNumber(17, endIfLabel); 115 methodVisitor.visitMethodInsn( 116 INVOKESPECIAL, "jdk3/ArtificialStructures", "<init>", "(Ljava/lang/String;)V", false); 117 methodVisitor.visitInsn(RETURN); 118 methodVisitor.visitMaxs(0, 0); 119 methodVisitor.visitEnd(); 120 121 methodVisitor = classWriter.visitMethod(ACC_STATIC, "dup_x2", "(IJ)V", null, null); 122 methodVisitor.visitCode(); 123 methodVisitor.visitVarInsn(LLOAD, 1); 124 methodVisitor.visitVarInsn(ILOAD, 0); 125 methodVisitor.visitInsn(DUP_X2); 126 methodVisitor.visitInsn(I2L); 127 methodVisitor.visitInsn(LADD); 128 methodVisitor.visitMethodInsn( 129 INVOKESTATIC, "jdk3/ArtificialStructures", "dup_x2", "(IJ)V", false); 130 methodVisitor.visitInsn(RETURN); 131 methodVisitor.visitMaxs(0, 0); 132 methodVisitor.visitEnd(); 133 134 methodVisitor = classWriter.visitMethod(ACC_STATIC, "dup2_x2", "(IIII)V", null, null); 135 methodVisitor.visitCode(); 136 methodVisitor.visitVarInsn(ILOAD, 3); 137 methodVisitor.visitVarInsn(ILOAD, 2); 138 methodVisitor.visitVarInsn(ILOAD, 1); 139 methodVisitor.visitVarInsn(ILOAD, 0); 140 methodVisitor.visitInsn(DUP2_X2); 141 methodVisitor.visitInsn(IADD); 142 methodVisitor.visitInsn(IADD); 143 methodVisitor.visitMethodInsn( 144 INVOKESTATIC, "jdk3/ArtificialStructures", "dup2_x2", "(IIII)V", false); 145 methodVisitor.visitInsn(RETURN); 146 methodVisitor.visitMaxs(0, 0); 147 methodVisitor.visitEnd(); 148 149 methodVisitor = classWriter.visitMethod(ACC_STATIC, "dup2_x2", "(IIJ)V", null, null); 150 methodVisitor.visitCode(); 151 methodVisitor.visitVarInsn(LLOAD, 2); 152 methodVisitor.visitVarInsn(ILOAD, 1); 153 methodVisitor.visitVarInsn(ILOAD, 0); 154 methodVisitor.visitInsn(DUP2_X2); 155 methodVisitor.visitInsn(IADD); 156 methodVisitor.visitInsn(I2L); 157 methodVisitor.visitInsn(LADD); 158 methodVisitor.visitMethodInsn( 159 INVOKESTATIC, "jdk3/ArtificialStructures", "dup2_x2", "(IIJ)V", false); 160 methodVisitor.visitInsn(RETURN); 161 methodVisitor.visitMaxs(0, 0); 162 methodVisitor.visitEnd(); 163 164 methodVisitor = classWriter.visitMethod(ACC_STATIC, "dup2_x2", "(JD)V", null, null); 165 methodVisitor.visitCode(); 166 methodVisitor.visitVarInsn(DLOAD, 2); 167 methodVisitor.visitVarInsn(LLOAD, 0); 168 methodVisitor.visitInsn(DUP2_X2); 169 methodVisitor.visitInsn(L2D); 170 methodVisitor.visitInsn(DADD); 171 methodVisitor.visitMethodInsn( 172 INVOKESTATIC, "jdk3/ArtificialStructures", "dup2_x2", "(JD)V", false); 173 methodVisitor.visitInsn(RETURN); 174 methodVisitor.visitMaxs(0, 0); 175 methodVisitor.visitEnd(); 176 177 classWriter.visitEnd(); 178 return classWriter.toByteArray(); 179 } 180 } 181