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