169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/* 269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit. 369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2010 Shigeru Chiba. All Rights Reserved. 469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version 669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with 769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License. Alternatively, the contents of this file may be used under 869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later. 969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis, 1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the 1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License. 1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.bytecode; 1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.OutputStream; 1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.DataOutputStream; 2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.ByteArrayOutputStream; 2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.IOException; 2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/** 2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * A quick class-file writer. This is useful when a generated 2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * class file is simple and the code generation should be fast. 2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>Example: 2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <blockquote><pre> 3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * ClassFileWriter cfw = new ClassFileWriter(ClassFile.JAVA_4, 0); 3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * ConstPoolWriter cpw = cfw.getConstPool(); 3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * FieldWriter fw = cfw.getFieldWriter(); 3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * fw.add(AccessFlag.PUBLIC, "value", "I", null); 3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * fw.add(AccessFlag.PUBLIC, "value2", "J", null); 3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * int thisClass = cpw.addClassInfo("sample/Test"); 3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * int superClass = cpw.addClassInfo("java/lang/Object"); 3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * MethodWriter mw = cfw.getMethodWriter(); 4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * mw.begin(AccessFlag.PUBLIC, MethodInfo.nameInit, "()V", null, null); 4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * mw.add(Opcode.ALOAD_0); 4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * mw.add(Opcode.INVOKESPECIAL); 4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * int signature = cpw.addNameAndTypeInfo(MethodInfo.nameInit, "()V"); 4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * mw.add16(cpw.addMethodrefInfo(superClass, signature)); 4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * mw.add(Opcode.RETURN); 4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * mw.codeEnd(1, 1); 4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * mw.end(null, null); 5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * mw.begin(AccessFlag.PUBLIC, "one", "()I", null, null); 5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * mw.add(Opcode.ICONST_1); 5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * mw.add(Opcode.IRETURN); 5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * mw.codeEnd(1, 1); 5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * mw.end(null, null); 5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * byte[] classfile = cfw.end(AccessFlag.PUBLIC, thisClass, superClass, 5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * null, null); 5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </pre></blockquote> 6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>The code above generates the following class: 6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <blockquote><pre> 6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * package sample; 6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * public class Test { 6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * public int value; 6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * public long value2; 6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * public Test() { super(); } 6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * public one() { return 1; } 7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * } 7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </pre></blockquote> 7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @since 3.13 7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class ClassFileWriter { 7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private ByteStream output; 7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private ConstPoolWriter constPool; 7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private FieldWriter fields; 7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private MethodWriter methods; 8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int thisClass, superClass; 8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Constructs a class file writer. 8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param major the major version ({@link ClassFile#JAVA_4}, {@link ClassFile#JAVA_5}, ...). 8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param minor the minor version (0 for JDK 1.3 and later). 8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ClassFileWriter(int major, int minor) { 8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output = new ByteStream(512); 9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeInt(0xCAFEBABE); // magic 9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(minor); 9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(major); 9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal constPool = new ConstPoolWriter(output); 9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal fields = new FieldWriter(constPool); 9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal methods = new MethodWriter(constPool); 9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns a constant pool. 10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ConstPoolWriter getConstPool() { return constPool; } 10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns a filed writer. 10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public FieldWriter getFieldWriter() { return fields; } 10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns a method writer. 11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public MethodWriter getMethodWriter() { return methods; } 11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Ends writing and returns the contents of the class file. 11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param accessFlags access flags. 11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param thisClass this class. an index indicating its <code>CONSTANT_Class_info</code>. 11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param superClass super class. an index indicating its <code>CONSTANT_Class_info</code>. 12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param interfaces implemented interfaces. 12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * index numbers indicating their <code>ClassInfo</code>. 12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * It may be null. 12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param aw attributes of the class file. May be null. 12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see AccessFlag 12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public byte[] end(int accessFlags, int thisClass, int superClass, 12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int[] interfaces, AttributeWriter aw) { 12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal constPool.end(); 13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(accessFlags); 13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(thisClass); 13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(superClass); 13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (interfaces == null) 13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(0); 13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = interfaces.length; 13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(n); 13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < n; i++) 13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(interfaces[i]); 14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.enlarge(fields.dataSize() + methods.dataSize() + 6); 14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(fields.size()); 14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal fields.write(output); 14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(methods.size()); 14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal methods.write(output); 14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (IOException e) {} 15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal writeAttribute(output, aw, 0); 15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return output.toByteArray(); 15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Ends writing and writes the contents of the class file into the 15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * given output stream. 15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param accessFlags access flags. 16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param thisClass this class. an index indicating its <code>CONSTANT_Class_info</code>. 16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param superClass super class. an index indicating its <code>CONSTANT_Class_info</code>. 16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param interfaces implemented interfaces. 16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * index numbers indicating their <code>CONSTATNT_Class_info</code>. 16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * It may be null. 16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param aw attributes of the class file. May be null. 16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see AccessFlag 16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void end(DataOutputStream out, 17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int accessFlags, int thisClass, int superClass, 17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int[] interfaces, AttributeWriter aw) 17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws IOException 17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal constPool.end(); 17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeTo(out); 17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.writeShort(accessFlags); 17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.writeShort(thisClass); 17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.writeShort(superClass); 18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (interfaces == null) 18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.writeShort(0); 18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = interfaces.length; 18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.writeShort(n); 18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < n; i++) 18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.writeShort(interfaces[i]); 18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.writeShort(fields.size()); 19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal fields.write(out); 19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.writeShort(methods.size()); 19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal methods.write(out); 19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (aw == null) 19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.writeShort(0); 19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal out.writeShort(aw.size()); 19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal aw.write(out); 19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * This writes attributes. 20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>For example, the following object writes a synthetic attribute: 20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <pre> 20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * ConstPoolWriter cpw = ...; 20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * final int tag = cpw.addUtf8Info("Synthetic"); 21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * AttributeWriter aw = new AttributeWriter() { 21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * public int size() { 21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * return 1; 21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * } 21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * public void write(DataOutputStream out) throws java.io.IOException { 21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * out.writeShort(tag); 21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * out.writeInt(0); 21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * } 21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * }; 21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </pre> 22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static interface AttributeWriter { 22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the number of attributes that this writer will 22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * write. 22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int size(); 22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Writes all the contents of the attributes. The binary representation 23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * of the contents is an array of <code>attribute_info</code>. 23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void write(DataOutputStream out) throws IOException; 23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static void writeAttribute(ByteStream bs, AttributeWriter aw, int attrCount) { 23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (aw == null) { 23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bs.writeShort(attrCount); 23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return; 23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bs.writeShort(aw.size() + attrCount); 24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal DataOutputStream dos = new DataOutputStream(bs); 24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal aw.write(dos); 24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal dos.flush(); 24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (IOException e) {} 24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Field. 25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static final class FieldWriter { 25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected ByteStream output; 25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected ConstPoolWriter constPool; 25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private int fieldCount; 25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal FieldWriter(ConstPoolWriter cp) { 25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output = new ByteStream(128); 26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal constPool = cp; 26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal fieldCount = 0; 26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 26369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 26469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 26569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Adds a new field. 26669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 26769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param accessFlags access flags. 26869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param name the field name. 26969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param descriptor the field type. 27069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param aw the attributes of the field. may be null. 27169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see AccessFlag 27269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 27369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void add(int accessFlags, String name, String descriptor, AttributeWriter aw) { 27469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int nameIndex = constPool.addUtf8Info(name); 27569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int descIndex = constPool.addUtf8Info(descriptor); 27669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal add(accessFlags, nameIndex, descIndex, aw); 27769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 27869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 27969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 28069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Adds a new field. 28169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 28269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param accessFlags access flags. 28369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param name the field name. an index indicating its <code>CONSTANT_Utf8_info</code>. 28469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param descriptor the field type. an index indicating its <code>CONSTANT_Utf8_info</code>. 28569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param aw the attributes of the field. may be null. 28669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see AccessFlag 28769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 28869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void add(int accessFlags, int name, int descriptor, AttributeWriter aw) { 28969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ++fieldCount; 29069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(accessFlags); 29169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(name); 29269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(descriptor); 29369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal writeAttribute(output, aw, 0); 29469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 29569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 29669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int size() { return fieldCount; } 29769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 29869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int dataSize() { return output.size(); } 29969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 30069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 30169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Writes the added fields. 30269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 30369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal void write(OutputStream out) throws IOException { 30469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeTo(out); 30569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 30669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 30769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 30869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 30969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Method. 31069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 31169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static final class MethodWriter { 31269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected ByteStream output; 31369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected ConstPoolWriter constPool; 31469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private int methodCount; 31569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected int codeIndex; 31669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected int throwsIndex; 31769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected int stackIndex; 31869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 31969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private int startPos; 32069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private boolean isAbstract; 32169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private int catchPos; 32269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private int catchCount; 32369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 32469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal MethodWriter(ConstPoolWriter cp) { 32569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output = new ByteStream(256); 32669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal constPool = cp; 32769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal methodCount = 0; 32869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal codeIndex = 0; 32969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throwsIndex = 0; 33069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stackIndex = 0; 33169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 33269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 33369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 33469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Starts Adding a new method. 33569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 33669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param accessFlags access flags. 33769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param name the method name. 33869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param descriptor the method signature. 33969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param exceptions throws clause. It may be null. 34069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The class names must be the JVM-internal 34169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * representations like <code>java/lang/Exception</code>. 34269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param aw attributes to the <code>Method_info</code>. 34369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 34469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void begin(int accessFlags, String name, String descriptor, 34569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String[] exceptions, AttributeWriter aw) { 34669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int nameIndex = constPool.addUtf8Info(name); 34769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int descIndex = constPool.addUtf8Info(descriptor); 34869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int[] intfs; 34969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (exceptions == null) 35069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal intfs = null; 35169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 35269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal intfs = constPool.addClassInfo(exceptions); 35369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 35469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal begin(accessFlags, nameIndex, descIndex, intfs, aw); 35569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 35669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 35769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 35869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Starts adding a new method. 35969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 36069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param accessFlags access flags. 36169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param name the method name. an index indicating its <code>CONSTANT_Utf8_info</code>. 36269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param descriptor the field type. an index indicating its <code>CONSTANT_Utf8_info</code>. 36369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param exceptions throws clause. indexes indicating <code>CONSTANT_Class_info</code>s. 36469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * It may be null. 36569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param aw attributes to the <code>Method_info</code>. 36669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 36769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void begin(int accessFlags, int name, int descriptor, int[] exceptions, AttributeWriter aw) { 36869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ++methodCount; 36969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(accessFlags); 37069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(name); 37169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(descriptor); 37269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal isAbstract = (accessFlags & AccessFlag.ABSTRACT) != 0; 37369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 37469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int attrCount = isAbstract ? 0 : 1; 37569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (exceptions != null) 37669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ++attrCount; 37769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 37869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal writeAttribute(output, aw, attrCount); 37969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 38069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (exceptions != null) 38169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal writeThrows(exceptions); 38269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 38369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (!isAbstract) { 38469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (codeIndex == 0) 38569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal codeIndex = constPool.addUtf8Info(CodeAttribute.tag); 38669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 38769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal startPos = output.getPos(); 38869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(codeIndex); 38969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeBlank(12); // attribute_length, maxStack, maxLocals, code_lenth 39069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 39169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 39269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catchPos = -1; 39369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catchCount = 0; 39469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 39569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 39669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void writeThrows(int[] exceptions) { 39769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (throwsIndex == 0) 39869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throwsIndex = constPool.addUtf8Info(ExceptionsAttribute.tag); 39969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 40069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(throwsIndex); 40169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeInt(exceptions.length * 2 + 2); 40269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(exceptions.length); 40369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < exceptions.length; i++) 40469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(exceptions[i]); 40569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 40669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 40769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 40869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Appends an 8bit value of bytecode. 40969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 41069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see Opcode 41169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 41269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void add(int b) { 41369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.write(b); 41469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 41569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 41669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 41769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Appends a 16bit value of bytecode. 41869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 41969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void add16(int b) { 42069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(b); 42169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 42269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 42369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 42469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Appends a 32bit value of bytecode. 42569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 42669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void add32(int b) { 42769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeInt(b); 42869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 42969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 43069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 43169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Appends a invokevirtual, inovkespecial, or invokestatic bytecode. 43269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 43369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see Opcode 43469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 43569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void addInvoke(int opcode, String targetClass, String methodName, 43669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String descriptor) { 43769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int target = constPool.addClassInfo(targetClass); 43869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int nt = constPool.addNameAndTypeInfo(methodName, descriptor); 43969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int method = constPool.addMethodrefInfo(target, nt); 44069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal add(opcode); 44169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal add16(method); 44269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 44369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 44469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 44569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Ends appending bytecode. 44669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 44769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void codeEnd(int maxStack, int maxLocals) { 44869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (!isAbstract) { 44969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(startPos + 6, maxStack); 45069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(startPos + 8, maxLocals); 45169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeInt(startPos + 10, output.getPos() - startPos - 14); // code_length 45269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catchPos = output.getPos(); 45369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catchCount = 0; 45469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(0); // number of catch clauses 45569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 45669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 45769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 45869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 45969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Appends an <code>exception_table</code> entry to the 46069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>Code_attribute</code>. This method is available 46169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * only after the <code>codeEnd</code> method is called. 46269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 46369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param catchType an index indicating a <code>CONSTANT_Class_info</code>. 46469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 46569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void addCatch(int startPc, int endPc, int handlerPc, int catchType) { 46669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ++catchCount; 46769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(startPc); 46869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(endPc); 46969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(handlerPc); 47069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(catchType); 47169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 47269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 47369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 47469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Ends adding a new method. The <code>add</code> method must be 47569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * called before the <code>end</code> method is called. 47669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 47769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param smap a stack map table. may be null. 47869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param aw attributes to the <code>Code_attribute</code>. 47969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * may be null. 48069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 48169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void end(StackMapTable.Writer smap, AttributeWriter aw) { 48269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (isAbstract) 48369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return; 48469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 48569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // exception_table_length 48669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(catchPos, catchCount); 48769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 48869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int attrCount = smap == null ? 0 : 1; 48969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal writeAttribute(output, aw, attrCount); 49069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 49169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (smap != null) { 49269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (stackIndex == 0) 49369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stackIndex = constPool.addUtf8Info(StackMapTable.tag); 49469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 49569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(stackIndex); 49669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal byte[] data = smap.toByteArray(); 49769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeInt(data.length); 49869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.write(data); 49969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 50069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 50169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // Code attribute_length 50269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeInt(startPos + 2, output.getPos() - startPos - 6); 50369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 50469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 50569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int size() { return methodCount; } 50669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 50769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int dataSize() { return output.size(); } 50869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 50969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 51069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Writes the added methods. 51169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 51269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal void write(OutputStream out) throws IOException { 51369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeTo(out); 51469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 51569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 51669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 51769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 51869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Constant Pool. 51969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 52069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static final class ConstPoolWriter { 52169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ByteStream output; 52269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected int startPos; 52369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected int num; 52469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 52569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ConstPoolWriter(ByteStream out) { 52669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output = out; 52769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal startPos = out.getPos(); 52869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal num = 1; 52969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(1); // number of entries 53069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 53169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 53269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 53369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Makes <code>CONSTANT_Class_info</code> objects for each class name. 53469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 53569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return an array of indexes indicating <code>CONSTANT_Class_info</code>s. 53669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 53769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int[] addClassInfo(String[] classNames) { 53869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = classNames.length; 53969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int[] result = new int[n]; 54069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < n; i++) 54169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal result[i] = addClassInfo(classNames[i]); 54269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 54369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return result; 54469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 54569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 54669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 54769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Adds a new <code>CONSTANT_Class_info</code> structure. 54869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 54969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This also adds a <code>CONSTANT_Utf8_info</code> structure 55069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for storing the class name. 55169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 55269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param jvmname the JVM-internal representation of a class name. 55369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * e.g. <code>java/lang/Object</code>. 55469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the index of the added entry. 55569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 55669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int addClassInfo(String jvmname) { 55769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int utf8 = addUtf8Info(jvmname); 55869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.write(ClassInfo.tag); 55969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(utf8); 56069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return num++; 56169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 56269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 56369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 56469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Adds a new <code>CONSTANT_Class_info</code> structure. 56569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 56669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param name <code>name_index</code> 56769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the index of the added entry. 56869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 56969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int addClassInfo(int name) { 57069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.write(ClassInfo.tag); 57169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(name); 57269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return num++; 57369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 57469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 57569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 57669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Adds a new <code>CONSTANT_NameAndType_info</code> structure. 57769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 57869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param name <code>name_index</code> 57969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param type <code>descriptor_index</code> 58069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the index of the added entry. 58169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 58269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int addNameAndTypeInfo(String name, String type) { 58369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return addNameAndTypeInfo(addUtf8Info(name), addUtf8Info(type)); 58469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 58569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 58669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 58769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Adds a new <code>CONSTANT_NameAndType_info</code> structure. 58869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 58969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param name <code>name_index</code> 59069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param type <code>descriptor_index</code> 59169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the index of the added entry. 59269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 59369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int addNameAndTypeInfo(int name, int type) { 59469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.write(NameAndTypeInfo.tag); 59569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(name); 59669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(type); 59769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return num++; 59869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 59969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 60069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 60169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Adds a new <code>CONSTANT_Fieldref_info</code> structure. 60269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 60369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param classInfo <code>class_index</code> 60469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param nameAndTypeInfo <code>name_and_type_index</code>. 60569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the index of the added entry. 60669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 60769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int addFieldrefInfo(int classInfo, int nameAndTypeInfo) { 60869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.write(FieldrefInfo.tag); 60969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(classInfo); 61069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(nameAndTypeInfo); 61169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return num++; 61269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 61369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 61469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 61569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Adds a new <code>CONSTANT_Methodref_info</code> structure. 61669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 61769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param classInfo <code>class_index</code> 61869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param nameAndTypeInfo <code>name_and_type_index</code>. 61969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the index of the added entry. 62069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 62169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int addMethodrefInfo(int classInfo, int nameAndTypeInfo) { 62269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.write(MethodrefInfo.tag); 62369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(classInfo); 62469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(nameAndTypeInfo); 62569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return num++; 62669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 62769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 62869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 62969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Adds a new <code>CONSTANT_InterfaceMethodref_info</code> 63069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * structure. 63169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 63269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param classInfo <code>class_index</code> 63369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param nameAndTypeInfo <code>name_and_type_index</code>. 63469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the index of the added entry. 63569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 63669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int addInterfaceMethodrefInfo(int classInfo, 63769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int nameAndTypeInfo) { 63869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.write(InterfaceMethodrefInfo.tag); 63969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(classInfo); 64069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(nameAndTypeInfo); 64169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return num++; 64269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 64369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 64469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 64569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Adds a new <code>CONSTANT_String_info</code> 64669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * structure. 64769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 64869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This also adds a new <code>CONSTANT_Utf8_info</code> 64969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * structure. 65069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 65169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the index of the added entry. 65269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 65369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int addStringInfo(String str) { 65469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int utf8 = addUtf8Info(str); 65569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.write(StringInfo.tag); 65669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(utf8); 65769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return num++; 65869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 65969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 66069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 66169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Adds a new <code>CONSTANT_Integer_info</code> 66269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * structure. 66369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 66469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the index of the added entry. 66569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 66669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int addIntegerInfo(int i) { 66769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.write(IntegerInfo.tag); 66869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeInt(i); 66969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return num++; 67069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 67169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 67269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 67369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Adds a new <code>CONSTANT_Float_info</code> 67469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * structure. 67569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 67669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the index of the added entry. 67769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 67869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int addFloatInfo(float f) { 67969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.write(FloatInfo.tag); 68069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeFloat(f); 68169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return num++; 68269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 68369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 68469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 68569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Adds a new <code>CONSTANT_Long_info</code> 68669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * structure. 68769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 68869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the index of the added entry. 68969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 69069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int addLongInfo(long l) { 69169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.write(LongInfo.tag); 69269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeLong(l); 69369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = num; 69469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal num += 2; 69569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return n; 69669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 69769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 69869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 69969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Adds a new <code>CONSTANT_Double_info</code> 70069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * structure. 70169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 70269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the index of the added entry. 70369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 70469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int addDoubleInfo(double d) { 70569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.write(DoubleInfo.tag); 70669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeDouble(d); 70769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = num; 70869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal num += 2; 70969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return n; 71069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 71169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 71269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 71369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Adds a new <code>CONSTANT_Utf8_info</code> 71469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * structure. 71569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 71669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the index of the added entry. 71769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 71869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int addUtf8Info(String utf8) { 71969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.write(Utf8Info.tag); 72069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeUTF(utf8); 72169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return num++; 72269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 72369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 72469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 72569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Writes the contents of this class pool. 72669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 72769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal void end() { 72869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal output.writeShort(startPos, num); 72969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 73069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 73169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal} 732